This repository has been archived on 2026-07-21. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
cloud-reader/docs/frontend/mobile-search-spec.md
T

4.2 KiB

Mobile Book Search & Discovery — Spec

Overview

Enhance the existing book search experience with mobile-first features: voice search via the Web Speech API, real-time autocomplete suggestions, and touch-optimized responsive layout.

Prerequisites

  • Backend endpoints already exist (from docs/backend/search-discovery-spec.md):
    • GET /api/books/?q=...&genre=...&author=...&reading_status=... — paginated search
    • GET /api/books/{id}/ — book detail
    • GET /api/books/genres/ — genre discovery
    • GET /api/books/authors/ — author discovery
  • Frontend LibraryPage and BookDetailPage components exist but lacked API client methods and types (fixed in this PR).

Frontend API Client Additions

frontend/src/types/book.ts — New exports

export interface BookSearchParams {
  q?: string;
  genre?: string;
  author?: string;
  reading_status?: string;
  ordering?: string;
  page?: number;
  page_size?: number;
}

export const READING_STATUS_OPTIONS: { value: string; label: string }[] = [
  { value: "", label: "All Statuses" },
  { value: "want_to_read", label: "Want to Read" },
  { value: "reading", label: "Reading" },
  { value: "finished", label: "Finished" },
  { value: "dnf", label: "Did Not Finish" },
];

frontend/src/api/books.ts — New methods on booksApi

Method Endpoint Returns
searchBooks(params) GET /api/books/ { count, results: BookListItem[] }
getBook(id) GET /api/books/{id}/ BookDetail
getGenres() GET /api/books/genres/ string[]
getAuthors() GET /api/books/authors/ string[]

Mobile Features

  • Hook: useVoiceSearch in frontend/src/hooks/useVoiceSearch.ts
  • Uses the Web Speech API (SpeechRecognition / webkitSpeechRecognition)
  • Returns: { isListening, transcript, isSupported, startListening, stopListening, hasError }
  • Renders a microphone icon button next to the search input
  • On mobile, tapping the mic icon triggers the native speech recognition prompt
  • On success, populates the search input with the transcript and triggers a search
  • Graceful degradation: if SpeechRecognition API is unavailable, the mic button is hidden

2. Real-Time Suggestions (Autocomplete)

  • Component: SearchSuggestions rendered as a dropdown below the search input
  • On each keystroke (debounced 200ms), fetches GET /api/books/?q=...&page_size=5 for suggestions
  • Shows up to 5 book title/author suggestions in a styled dropdown list
  • Clicking a suggestion navigates directly to /books/{id}
  • Clicking outside or pressing Escape dismisses the dropdown
  • Combines with existing full search results — suggestions are fast previews, not the main result list

3. Mobile-Responsive Enhancements

  • Filters panel is collapsed by default on mobile, toggleable via a "Filters" button
  • Touch targets minimum 44px (WCAG 2.1)
  • Results grid switches to single column below 600px viewport width
  • Search input and filters panel stack vertically on small screens
  • Add CSS breakpoints via inline styles and a useMediaQuery hook
  • Bottom navigation-style action buttons on mobile (Add Book, Bookmarks, Settings become icon-only)

Component Hierarchy

LibraryPage
├── Header (title, count, action buttons)
├── SearchInput
│   ├── TextInput (debounced 300ms)
│   ├── VoiceSearchButton (microphone icon)
│   └── SearchSuggestions (dropdown, debounced 200ms)
├── FiltersButton (mobile: toggle; desktop: always visible)
├── FiltersPanel (collapsible on mobile)
│   ├── GenreSelect
│   ├── AuthorSelect
│   ├── StatusSelect
│   └── ClearFiltersButton
├── LoadingState (skeleton grid)
├── ErrorState (message + retry button)
├── EmptyState (no results / no books)
└── ResultsGrid (responsive: auto-fill vs single column)

Mobile-First CSS Strategy

  • Use inline styles with @media queries in a shared breakpoints.ts utility
  • Breakpoints: sm = 480px, md = 768px, lg = 1024px
  • Base styles are mobile-first (single column, full width)
  • Media queries expand to multi-column grid and horizontal layout on larger screens