mirror of
https://github.com/R0m1k3/FlowReader.git
synced 2026-10-21 14:18:06 +02:00
feat(web): redesign — three-pane desktop, mobile tab bar, search
Implements the approved design proposal across every screen. - Layout: feeds · list · reader panes on desktop (≥1280px), list + reader with the feeds in a drawer on tablets, one column with a bottom tab bar (À lire, Focus, Favoris, Flux) on phones. - List: dense rows with an unread dot, feed initial and square thumbnail instead of large cards; touch swipe reveals the action (→ lu, ← favori). The magazine grid stays available as a view toggle. - Reader: inline pane on desktop, full screen on phones with a bottom action bar (favori, partager, original, Suivant); collapsible "Résumé IA" block; "Aa" settings become a bottom sheet on phones. - Search: the existing /articles/search endpoint gets a UI — ⌘K / "/" palette on desktop, full screen on phones, with recent searches. - Mobile "Mes flux" screen: views, subscriptions with errors, theme, OPML import/export, logout. - Focus mode: progress bar, counter and labelled buttons. - Tokens: new paper / deep-forest palette (all text ≥4.5:1), Newsreader + Inter replace Playfair + Lora (two families instead of four), shared Icon and FeedAvatar components. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UPyU2LbJ2rTrsgZqQKhH3j
This commit is contained in:
38 files changed
+2019
-963
No files matched your search
@@ -0,0 +1,22 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { feedsApi } from '../api/feeds';
|
||||
import type { Scope } from '../stores/uiStore';
|
||||
|
||||
/** The feed list (shared cache with every screen that shows counters). */
|
||||
export function useFeeds() {
|
||||
return useQuery({ queryKey: ['feeds'], queryFn: () => feedsApi.list() });
|
||||
}
|
||||
|
||||
/** Total unread articles across all feeds. */
|
||||
export function useTotalUnread() {
|
||||
const { data } = useFeeds();
|
||||
return (data ?? []).reduce((n, f) => n + (f.unread_count ?? 0), 0);
|
||||
}
|
||||
|
||||
/** Human name of what the list shows. */
|
||||
export function useScopeLabel(scope: Scope) {
|
||||
const { data } = useFeeds();
|
||||
if (scope === null) return 'À lire';
|
||||
if (scope === 'favorites') return 'Favoris';
|
||||
return data?.find((f) => f.id === scope)?.title ?? 'Flux';
|
||||
}
|
||||
Reference in new issue
Block a user