feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
import { useCallback, useEffect, useState, useSyncExternalStore } from "react";
|
feat(m5a): channel manager, tabbed settings panel, per-user sync status
Backend: /api/channels (list + PATCH priority/hidden + attach/detach user tags),
user-tag CRUD on /api/tags, /api/sync/my-status (per-user channel sync counts).
Frontend: feed|channels page nav (URL-synced) from the account menu; a slide-in
tabbed Settings panel (Appearance, Notifications=6b sound+duration, Sync status +
actions + admin pause/resume, Account); a channel manager with priority, hide,
per-channel user tags, sync badges and 'view in feed'. Notifications now honor the
configurable sound + auto-dismiss settings.
2026-06-11 20:45:48 +02:00
|
|
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
|
|
|
import { Bell, Monitor, Pause, Play, RefreshCw, User, X } from "lucide-react";
|
|
|
|
|
import { SCHEMES, type Scheme, type ThemePrefs } from "../lib/theme";
|
|
|
|
|
import { api, type Me } from "../lib/api";
|
|
|
|
|
import {
|
|
|
|
|
configureNotifications,
|
|
|
|
|
getNotifSettings,
|
|
|
|
|
notify,
|
|
|
|
|
type NotifSettings,
|
|
|
|
|
} from "../lib/notifications";
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
import { hintsEnabled, setHintsEnabled, subscribeHints } from "../lib/hints";
|
|
|
|
|
import Tooltip from "./Tooltip";
|
feat(m5a): channel manager, tabbed settings panel, per-user sync status
Backend: /api/channels (list + PATCH priority/hidden + attach/detach user tags),
user-tag CRUD on /api/tags, /api/sync/my-status (per-user channel sync counts).
Frontend: feed|channels page nav (URL-synced) from the account menu; a slide-in
tabbed Settings panel (Appearance, Notifications=6b sound+duration, Sync status +
actions + admin pause/resume, Account); a channel manager with priority, hide,
per-channel user tags, sync badges and 'view in feed'. Notifications now honor the
configurable sound + auto-dismiss settings.
2026-06-11 20:45:48 +02:00
|
|
|
|
|
|
|
|
type TabId = "appearance" | "notifications" | "sync" | "account";
|
|
|
|
|
const TABS: { id: TabId; label: string; icon: typeof Monitor }[] = [
|
|
|
|
|
{ id: "appearance", label: "Appearance", icon: Monitor },
|
|
|
|
|
{ id: "notifications", label: "Notifications", icon: Bell },
|
|
|
|
|
{ id: "sync", label: "Sync", icon: RefreshCw },
|
|
|
|
|
{ id: "account", label: "Account", icon: User },
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
export default function SettingsPanel({
|
|
|
|
|
me,
|
|
|
|
|
theme,
|
|
|
|
|
setTheme,
|
|
|
|
|
view,
|
|
|
|
|
setView,
|
|
|
|
|
onClose,
|
|
|
|
|
}: {
|
|
|
|
|
me: Me;
|
|
|
|
|
theme: ThemePrefs;
|
|
|
|
|
setTheme: (t: ThemePrefs) => void;
|
|
|
|
|
view: "grid" | "list";
|
|
|
|
|
setView: (v: "grid" | "list") => void;
|
|
|
|
|
onClose: () => void;
|
|
|
|
|
}) {
|
|
|
|
|
const [tab, setTab] = useState<TabId>("appearance");
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
const [closing, setClosing] = useState(false);
|
|
|
|
|
|
|
|
|
|
const close = useCallback(() => {
|
|
|
|
|
setClosing(true);
|
|
|
|
|
setTimeout(onClose, 190);
|
|
|
|
|
}, [onClose]);
|
feat(m5a): channel manager, tabbed settings panel, per-user sync status
Backend: /api/channels (list + PATCH priority/hidden + attach/detach user tags),
user-tag CRUD on /api/tags, /api/sync/my-status (per-user channel sync counts).
Frontend: feed|channels page nav (URL-synced) from the account menu; a slide-in
tabbed Settings panel (Appearance, Notifications=6b sound+duration, Sync status +
actions + admin pause/resume, Account); a channel manager with priority, hide,
per-channel user tags, sync badges and 'view in feed'. Notifications now honor the
configurable sound + auto-dismiss settings.
2026-06-11 20:45:48 +02:00
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
function onKey(e: KeyboardEvent) {
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
if (e.key === "Escape") close();
|
feat(m5a): channel manager, tabbed settings panel, per-user sync status
Backend: /api/channels (list + PATCH priority/hidden + attach/detach user tags),
user-tag CRUD on /api/tags, /api/sync/my-status (per-user channel sync counts).
Frontend: feed|channels page nav (URL-synced) from the account menu; a slide-in
tabbed Settings panel (Appearance, Notifications=6b sound+duration, Sync status +
actions + admin pause/resume, Account); a channel manager with priority, hide,
per-channel user tags, sync badges and 'view in feed'. Notifications now honor the
configurable sound + auto-dismiss settings.
2026-06-11 20:45:48 +02:00
|
|
|
}
|
|
|
|
|
document.addEventListener("keydown", onKey);
|
|
|
|
|
return () => document.removeEventListener("keydown", onKey);
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
}, [close]);
|
feat(m5a): channel manager, tabbed settings panel, per-user sync status
Backend: /api/channels (list + PATCH priority/hidden + attach/detach user tags),
user-tag CRUD on /api/tags, /api/sync/my-status (per-user channel sync counts).
Frontend: feed|channels page nav (URL-synced) from the account menu; a slide-in
tabbed Settings panel (Appearance, Notifications=6b sound+duration, Sync status +
actions + admin pause/resume, Account); a channel manager with priority, hide,
per-channel user tags, sync badges and 'view in feed'. Notifications now honor the
configurable sound + auto-dismiss settings.
2026-06-11 20:45:48 +02:00
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="fixed inset-0 z-40 flex justify-end">
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
<div
|
|
|
|
|
className={`absolute inset-0 bg-black/40 ${
|
|
|
|
|
closing ? "animate-[overlayOut_0.19s_ease_forwards]" : "animate-[overlayIn_0.2s_ease]"
|
|
|
|
|
}`}
|
|
|
|
|
onClick={close}
|
|
|
|
|
/>
|
|
|
|
|
<div
|
2026-06-11 21:30:25 +02:00
|
|
|
className={`glass relative self-start m-3 w-[min(94vw,520px)] max-h-[calc(100vh-1.5rem)] rounded-2xl overflow-hidden flex flex-col ${
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
closing
|
|
|
|
|
? "animate-[panelOut_0.19s_ease-in_forwards]"
|
|
|
|
|
: "animate-[panelIn_0.26s_cubic-bezier(0.22,1,0.36,1)]"
|
|
|
|
|
}`}
|
|
|
|
|
>
|
|
|
|
|
<div className="flex items-center justify-between px-4 h-14 border-b border-border/60 shrink-0">
|
feat(m5a): channel manager, tabbed settings panel, per-user sync status
Backend: /api/channels (list + PATCH priority/hidden + attach/detach user tags),
user-tag CRUD on /api/tags, /api/sync/my-status (per-user channel sync counts).
Frontend: feed|channels page nav (URL-synced) from the account menu; a slide-in
tabbed Settings panel (Appearance, Notifications=6b sound+duration, Sync status +
actions + admin pause/resume, Account); a channel manager with priority, hide,
per-channel user tags, sync badges and 'view in feed'. Notifications now honor the
configurable sound + auto-dismiss settings.
2026-06-11 20:45:48 +02:00
|
|
|
<div className="text-base font-semibold">Settings</div>
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
<button
|
|
|
|
|
onClick={close}
|
|
|
|
|
className="p-2 rounded-lg text-muted hover:text-fg hover:bg-card/60 transition"
|
|
|
|
|
>
|
feat(m5a): channel manager, tabbed settings panel, per-user sync status
Backend: /api/channels (list + PATCH priority/hidden + attach/detach user tags),
user-tag CRUD on /api/tags, /api/sync/my-status (per-user channel sync counts).
Frontend: feed|channels page nav (URL-synced) from the account menu; a slide-in
tabbed Settings panel (Appearance, Notifications=6b sound+duration, Sync status +
actions + admin pause/resume, Account); a channel manager with priority, hide,
per-channel user tags, sync badges and 'view in feed'. Notifications now honor the
configurable sound + auto-dismiss settings.
2026-06-11 20:45:48 +02:00
|
|
|
<X className="w-5 h-5" />
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
|
2026-06-11 21:30:25 +02:00
|
|
|
<div className="flex flex-1 min-h-0">
|
|
|
|
|
{/* Vertical tab rail — never wraps; active is a clear accent pill. */}
|
|
|
|
|
<nav className="w-32 sm:w-36 shrink-0 border-r border-border/60 p-2 flex flex-col gap-1">
|
|
|
|
|
{TABS.map((t) => {
|
|
|
|
|
const active = tab === t.id;
|
|
|
|
|
return (
|
|
|
|
|
<button
|
|
|
|
|
key={t.id}
|
|
|
|
|
onClick={() => setTab(t.id)}
|
|
|
|
|
className={`flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-left transition ${
|
|
|
|
|
active
|
|
|
|
|
? "bg-accent text-accent-fg font-medium shadow-md shadow-accent/20"
|
|
|
|
|
: "text-muted hover:text-fg hover:bg-card/60"
|
|
|
|
|
}`}
|
|
|
|
|
>
|
|
|
|
|
<t.icon className="w-4 h-4 shrink-0" />
|
|
|
|
|
{t.label}
|
|
|
|
|
</button>
|
|
|
|
|
);
|
|
|
|
|
})}
|
|
|
|
|
</nav>
|
|
|
|
|
|
|
|
|
|
{/* All tabs stacked in one grid cell so the panel sizes to the tallest tab
|
|
|
|
|
(stable height, no jump on switch); the active one is shown on top. */}
|
|
|
|
|
<div className="grid flex-1 overflow-y-auto">
|
|
|
|
|
{TABS.map((t) => (
|
|
|
|
|
<div
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
key={t.id}
|
2026-06-11 21:30:25 +02:00
|
|
|
className={`[grid-area:1/1] p-4 ${
|
|
|
|
|
tab === t.id ? "" : "invisible pointer-events-none"
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
}`}
|
|
|
|
|
>
|
2026-06-11 21:30:25 +02:00
|
|
|
{t.id === "appearance" && (
|
|
|
|
|
<Appearance theme={theme} setTheme={setTheme} view={view} setView={setView} />
|
|
|
|
|
)}
|
|
|
|
|
{t.id === "notifications" && <Notifications />}
|
|
|
|
|
{t.id === "sync" && <Sync me={me} />}
|
|
|
|
|
{t.id === "account" && <Account me={me} />}
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
feat(m5a): channel manager, tabbed settings panel, per-user sync status
Backend: /api/channels (list + PATCH priority/hidden + attach/detach user tags),
user-tag CRUD on /api/tags, /api/sync/my-status (per-user channel sync counts).
Frontend: feed|channels page nav (URL-synced) from the account menu; a slide-in
tabbed Settings panel (Appearance, Notifications=6b sound+duration, Sync status +
actions + admin pause/resume, Account); a channel manager with priority, hide,
per-channel user tags, sync badges and 'view in feed'. Notifications now honor the
configurable sound + auto-dismiss settings.
2026-06-11 20:45:48 +02:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function Section({ title, children }: { title: string; children: React.ReactNode }) {
|
|
|
|
|
return (
|
|
|
|
|
<div className="mb-6">
|
|
|
|
|
<div className="text-xs uppercase tracking-wide text-muted mb-2">{title}</div>
|
|
|
|
|
{children}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
function Row({
|
|
|
|
|
label,
|
|
|
|
|
hint,
|
|
|
|
|
children,
|
|
|
|
|
}: {
|
|
|
|
|
label: string;
|
|
|
|
|
hint?: string;
|
|
|
|
|
children: React.ReactNode;
|
|
|
|
|
}) {
|
feat(m5a): channel manager, tabbed settings panel, per-user sync status
Backend: /api/channels (list + PATCH priority/hidden + attach/detach user tags),
user-tag CRUD on /api/tags, /api/sync/my-status (per-user channel sync counts).
Frontend: feed|channels page nav (URL-synced) from the account menu; a slide-in
tabbed Settings panel (Appearance, Notifications=6b sound+duration, Sync status +
actions + admin pause/resume, Account); a channel manager with priority, hide,
per-channel user tags, sync badges and 'view in feed'. Notifications now honor the
configurable sound + auto-dismiss settings.
2026-06-11 20:45:48 +02:00
|
|
|
return (
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
<div className="flex items-center justify-between gap-3 py-1.5 text-sm">
|
|
|
|
|
<Tooltip hint={hint ?? ""}>
|
|
|
|
|
<span
|
|
|
|
|
className={
|
|
|
|
|
hint ? "underline decoration-dotted decoration-muted/40 underline-offset-4 cursor-help" : ""
|
|
|
|
|
}
|
|
|
|
|
>
|
|
|
|
|
{label}
|
|
|
|
|
</span>
|
|
|
|
|
</Tooltip>
|
feat(m5a): channel manager, tabbed settings panel, per-user sync status
Backend: /api/channels (list + PATCH priority/hidden + attach/detach user tags),
user-tag CRUD on /api/tags, /api/sync/my-status (per-user channel sync counts).
Frontend: feed|channels page nav (URL-synced) from the account menu; a slide-in
tabbed Settings panel (Appearance, Notifications=6b sound+duration, Sync status +
actions + admin pause/resume, Account); a channel manager with priority, hide,
per-channel user tags, sync badges and 'view in feed'. Notifications now honor the
configurable sound + auto-dismiss settings.
2026-06-11 20:45:48 +02:00
|
|
|
{children}
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
</div>
|
feat(m5a): channel manager, tabbed settings panel, per-user sync status
Backend: /api/channels (list + PATCH priority/hidden + attach/detach user tags),
user-tag CRUD on /api/tags, /api/sync/my-status (per-user channel sync counts).
Frontend: feed|channels page nav (URL-synced) from the account menu; a slide-in
tabbed Settings panel (Appearance, Notifications=6b sound+duration, Sync status +
actions + admin pause/resume, Account); a channel manager with priority, hide,
per-channel user tags, sync badges and 'view in feed'. Notifications now honor the
configurable sound + auto-dismiss settings.
2026-06-11 20:45:48 +02:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function Switch({ checked, onChange }: { checked: boolean; onChange: (v: boolean) => void }) {
|
|
|
|
|
return (
|
|
|
|
|
<button
|
|
|
|
|
type="button"
|
|
|
|
|
onClick={() => onChange(!checked)}
|
|
|
|
|
className={`w-9 h-5 rounded-full transition relative shrink-0 ${checked ? "bg-accent" : "bg-border"}`}
|
|
|
|
|
>
|
|
|
|
|
<span
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
className={`absolute top-0.5 w-4 h-4 rounded-full bg-white shadow transition-all ${
|
feat(m5a): channel manager, tabbed settings panel, per-user sync status
Backend: /api/channels (list + PATCH priority/hidden + attach/detach user tags),
user-tag CRUD on /api/tags, /api/sync/my-status (per-user channel sync counts).
Frontend: feed|channels page nav (URL-synced) from the account menu; a slide-in
tabbed Settings panel (Appearance, Notifications=6b sound+duration, Sync status +
actions + admin pause/resume, Account); a channel manager with priority, hide,
per-channel user tags, sync badges and 'view in feed'. Notifications now honor the
configurable sound + auto-dismiss settings.
2026-06-11 20:45:48 +02:00
|
|
|
checked ? "left-[18px]" : "left-0.5"
|
|
|
|
|
}`}
|
|
|
|
|
/>
|
|
|
|
|
</button>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const PERF_KEY = "subfeed.perfMode";
|
|
|
|
|
|
|
|
|
|
function Appearance({
|
|
|
|
|
theme,
|
|
|
|
|
setTheme,
|
|
|
|
|
view,
|
|
|
|
|
setView,
|
|
|
|
|
}: {
|
|
|
|
|
theme: ThemePrefs;
|
|
|
|
|
setTheme: (t: ThemePrefs) => void;
|
|
|
|
|
view: "grid" | "list";
|
|
|
|
|
setView: (v: "grid" | "list") => void;
|
|
|
|
|
}) {
|
|
|
|
|
const [perf, setPerf] = useState(() => localStorage.getItem(PERF_KEY) === "1");
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
const hints = useSyncExternalStore(subscribeHints, hintsEnabled, hintsEnabled);
|
|
|
|
|
|
feat(m5a): channel manager, tabbed settings panel, per-user sync status
Backend: /api/channels (list + PATCH priority/hidden + attach/detach user tags),
user-tag CRUD on /api/tags, /api/sync/my-status (per-user channel sync counts).
Frontend: feed|channels page nav (URL-synced) from the account menu; a slide-in
tabbed Settings panel (Appearance, Notifications=6b sound+duration, Sync status +
actions + admin pause/resume, Account); a channel manager with priority, hide,
per-channel user tags, sync badges and 'view in feed'. Notifications now honor the
configurable sound + auto-dismiss settings.
2026-06-11 20:45:48 +02:00
|
|
|
useEffect(() => {
|
|
|
|
|
document.documentElement.dataset.perf = perf ? "1" : "";
|
|
|
|
|
}, [perf]);
|
|
|
|
|
function togglePerf(v: boolean) {
|
|
|
|
|
setPerf(v);
|
|
|
|
|
localStorage.setItem(PERF_KEY, v ? "1" : "0");
|
|
|
|
|
api.savePrefs({ performanceMode: v }).catch(() => {});
|
|
|
|
|
}
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
function toggleHints(v: boolean) {
|
|
|
|
|
setHintsEnabled(v);
|
|
|
|
|
api.savePrefs({ hints: v }).catch(() => {});
|
|
|
|
|
}
|
feat(m5a): channel manager, tabbed settings panel, per-user sync status
Backend: /api/channels (list + PATCH priority/hidden + attach/detach user tags),
user-tag CRUD on /api/tags, /api/sync/my-status (per-user channel sync counts).
Frontend: feed|channels page nav (URL-synced) from the account menu; a slide-in
tabbed Settings panel (Appearance, Notifications=6b sound+duration, Sync status +
actions + admin pause/resume, Account); a channel manager with priority, hide,
per-channel user tags, sync badges and 'view in feed'. Notifications now honor the
configurable sound + auto-dismiss settings.
2026-06-11 20:45:48 +02:00
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<Section title="Color scheme">
|
|
|
|
|
<div className="grid grid-cols-4 gap-2">
|
|
|
|
|
{SCHEMES.map((s) => (
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
<Tooltip key={s.id} hint={s.name}>
|
|
|
|
|
<button
|
|
|
|
|
onClick={() => setTheme({ ...theme, scheme: s.id as Scheme })}
|
|
|
|
|
className={`h-9 w-full rounded-lg border-2 transition ${
|
|
|
|
|
theme.scheme === s.id ? "border-fg" : "border-transparent"
|
|
|
|
|
}`}
|
|
|
|
|
style={{ background: s.swatch }}
|
|
|
|
|
/>
|
|
|
|
|
</Tooltip>
|
feat(m5a): channel manager, tabbed settings panel, per-user sync status
Backend: /api/channels (list + PATCH priority/hidden + attach/detach user tags),
user-tag CRUD on /api/tags, /api/sync/my-status (per-user channel sync counts).
Frontend: feed|channels page nav (URL-synced) from the account menu; a slide-in
tabbed Settings panel (Appearance, Notifications=6b sound+duration, Sync status +
actions + admin pause/resume, Account); a channel manager with priority, hide,
per-channel user tags, sync badges and 'view in feed'. Notifications now honor the
configurable sound + auto-dismiss settings.
2026-06-11 20:45:48 +02:00
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
</Section>
|
|
|
|
|
|
|
|
|
|
<Section title="Display">
|
|
|
|
|
<Row label="Dark mode">
|
|
|
|
|
<Switch
|
|
|
|
|
checked={theme.mode === "dark"}
|
|
|
|
|
onChange={(v) => setTheme({ ...theme, mode: v ? "dark" : "light" })}
|
|
|
|
|
/>
|
|
|
|
|
</Row>
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
<Row label="List view" hint="Show the feed as a compact list instead of a grid of cards.">
|
feat(m5a): channel manager, tabbed settings panel, per-user sync status
Backend: /api/channels (list + PATCH priority/hidden + attach/detach user tags),
user-tag CRUD on /api/tags, /api/sync/my-status (per-user channel sync counts).
Frontend: feed|channels page nav (URL-synced) from the account menu; a slide-in
tabbed Settings panel (Appearance, Notifications=6b sound+duration, Sync status +
actions + admin pause/resume, Account); a channel manager with priority, hide,
per-channel user tags, sync badges and 'view in feed'. Notifications now honor the
configurable sound + auto-dismiss settings.
2026-06-11 20:45:48 +02:00
|
|
|
<Switch checked={view === "list"} onChange={(v) => setView(v ? "list" : "grid")} />
|
|
|
|
|
</Row>
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
<Row
|
|
|
|
|
label="Performance mode"
|
|
|
|
|
hint="Turns off the translucent glass blur and soft shadows for snappier rendering on slower machines."
|
|
|
|
|
>
|
feat(m5a): channel manager, tabbed settings panel, per-user sync status
Backend: /api/channels (list + PATCH priority/hidden + attach/detach user tags),
user-tag CRUD on /api/tags, /api/sync/my-status (per-user channel sync counts).
Frontend: feed|channels page nav (URL-synced) from the account menu; a slide-in
tabbed Settings panel (Appearance, Notifications=6b sound+duration, Sync status +
actions + admin pause/resume, Account); a channel manager with priority, hide,
per-channel user tags, sync badges and 'view in feed'. Notifications now honor the
configurable sound + auto-dismiss settings.
2026-06-11 20:45:48 +02:00
|
|
|
<Switch checked={perf} onChange={togglePerf} />
|
|
|
|
|
</Row>
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
<Row
|
|
|
|
|
label="Show hints"
|
|
|
|
|
hint="These little hover explanations. Turn them off once you know your way around."
|
|
|
|
|
>
|
|
|
|
|
<Switch checked={hints} onChange={toggleHints} />
|
|
|
|
|
</Row>
|
feat(m5a): channel manager, tabbed settings panel, per-user sync status
Backend: /api/channels (list + PATCH priority/hidden + attach/detach user tags),
user-tag CRUD on /api/tags, /api/sync/my-status (per-user channel sync counts).
Frontend: feed|channels page nav (URL-synced) from the account menu; a slide-in
tabbed Settings panel (Appearance, Notifications=6b sound+duration, Sync status +
actions + admin pause/resume, Account); a channel manager with priority, hide,
per-channel user tags, sync badges and 'view in feed'. Notifications now honor the
configurable sound + auto-dismiss settings.
2026-06-11 20:45:48 +02:00
|
|
|
</Section>
|
|
|
|
|
|
|
|
|
|
<Section title="Text size">
|
|
|
|
|
<input
|
|
|
|
|
type="range"
|
|
|
|
|
min={0.9}
|
|
|
|
|
max={1.3}
|
|
|
|
|
step={0.02}
|
|
|
|
|
value={theme.fontScale}
|
|
|
|
|
onChange={(e) => setTheme({ ...theme, fontScale: Number(e.target.value) })}
|
|
|
|
|
className="w-full accent-accent"
|
|
|
|
|
/>
|
|
|
|
|
<div className="text-right text-xs text-muted">{Math.round(theme.fontScale * 100)}%</div>
|
|
|
|
|
</Section>
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function Notifications() {
|
|
|
|
|
const [cfg, setCfg] = useState<NotifSettings>(() => getNotifSettings());
|
|
|
|
|
function update(p: Partial<NotifSettings>) {
|
|
|
|
|
const next = { ...cfg, ...p };
|
|
|
|
|
setCfg(next);
|
|
|
|
|
configureNotifications(next);
|
|
|
|
|
api.savePrefs({ notifications: next }).catch(() => {});
|
|
|
|
|
}
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
const autoOn = cfg.durationMs > 0;
|
|
|
|
|
|
feat(m5a): channel manager, tabbed settings panel, per-user sync status
Backend: /api/channels (list + PATCH priority/hidden + attach/detach user tags),
user-tag CRUD on /api/tags, /api/sync/my-status (per-user channel sync counts).
Frontend: feed|channels page nav (URL-synced) from the account menu; a slide-in
tabbed Settings panel (Appearance, Notifications=6b sound+duration, Sync status +
actions + admin pause/resume, Account); a channel manager with priority, hide,
per-channel user tags, sync badges and 'view in feed'. Notifications now honor the
configurable sound + auto-dismiss settings.
2026-06-11 20:45:48 +02:00
|
|
|
return (
|
|
|
|
|
<Section title="Notifications">
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
<Row
|
|
|
|
|
label="Sound on alerts"
|
|
|
|
|
hint="Play a short tone when a notification needs your attention (e.g. errors, prompts)."
|
|
|
|
|
>
|
feat(m5a): channel manager, tabbed settings panel, per-user sync status
Backend: /api/channels (list + PATCH priority/hidden + attach/detach user tags),
user-tag CRUD on /api/tags, /api/sync/my-status (per-user channel sync counts).
Frontend: feed|channels page nav (URL-synced) from the account menu; a slide-in
tabbed Settings panel (Appearance, Notifications=6b sound+duration, Sync status +
actions + admin pause/resume, Account); a channel manager with priority, hide,
per-channel user tags, sync badges and 'view in feed'. Notifications now honor the
configurable sound + auto-dismiss settings.
2026-06-11 20:45:48 +02:00
|
|
|
<Switch checked={cfg.sound} onChange={(v) => update({ sound: v })} />
|
|
|
|
|
</Row>
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
<Row
|
|
|
|
|
label="Auto-dismiss toasts"
|
|
|
|
|
hint="When off, pop-up toasts stay until you close them. When on, they fade after the set time."
|
|
|
|
|
>
|
|
|
|
|
<Switch checked={autoOn} onChange={(v) => update({ durationMs: v ? 6000 : 0 })} />
|
|
|
|
|
</Row>
|
|
|
|
|
{autoOn && (
|
|
|
|
|
<div className="py-1.5 text-sm">
|
|
|
|
|
<div className="flex items-center justify-between">
|
|
|
|
|
<span className="text-muted text-xs">Dismiss after</span>
|
|
|
|
|
<span className="text-muted text-xs">{(cfg.durationMs / 1000).toFixed(0)}s</span>
|
|
|
|
|
</div>
|
|
|
|
|
<input
|
|
|
|
|
type="range"
|
|
|
|
|
min={2000}
|
|
|
|
|
max={15000}
|
|
|
|
|
step={1000}
|
|
|
|
|
value={cfg.durationMs}
|
|
|
|
|
onChange={(e) => update({ durationMs: Number(e.target.value) })}
|
|
|
|
|
className="w-full accent-accent mt-1"
|
|
|
|
|
/>
|
feat(m5a): channel manager, tabbed settings panel, per-user sync status
Backend: /api/channels (list + PATCH priority/hidden + attach/detach user tags),
user-tag CRUD on /api/tags, /api/sync/my-status (per-user channel sync counts).
Frontend: feed|channels page nav (URL-synced) from the account menu; a slide-in
tabbed Settings panel (Appearance, Notifications=6b sound+duration, Sync status +
actions + admin pause/resume, Account); a channel manager with priority, hide,
per-channel user tags, sync badges and 'view in feed'. Notifications now honor the
configurable sound + auto-dismiss settings.
2026-06-11 20:45:48 +02:00
|
|
|
</div>
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
)}
|
feat(m5a): channel manager, tabbed settings panel, per-user sync status
Backend: /api/channels (list + PATCH priority/hidden + attach/detach user tags),
user-tag CRUD on /api/tags, /api/sync/my-status (per-user channel sync counts).
Frontend: feed|channels page nav (URL-synced) from the account menu; a slide-in
tabbed Settings panel (Appearance, Notifications=6b sound+duration, Sync status +
actions + admin pause/resume, Account); a channel manager with priority, hide,
per-channel user tags, sync badges and 'view in feed'. Notifications now honor the
configurable sound + auto-dismiss settings.
2026-06-11 20:45:48 +02:00
|
|
|
<button
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
onClick={() =>
|
|
|
|
|
notify({
|
|
|
|
|
level: "info",
|
|
|
|
|
title: "Test notification",
|
|
|
|
|
message: "This is what a notification looks like.",
|
2026-06-11 21:30:25 +02:00
|
|
|
sound: true,
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
})
|
|
|
|
|
}
|
feat(m5a): channel manager, tabbed settings panel, per-user sync status
Backend: /api/channels (list + PATCH priority/hidden + attach/detach user tags),
user-tag CRUD on /api/tags, /api/sync/my-status (per-user channel sync counts).
Frontend: feed|channels page nav (URL-synced) from the account menu; a slide-in
tabbed Settings panel (Appearance, Notifications=6b sound+duration, Sync status +
actions + admin pause/resume, Account); a channel manager with priority, hide,
per-channel user tags, sync badges and 'view in feed'. Notifications now honor the
configurable sound + auto-dismiss settings.
2026-06-11 20:45:48 +02:00
|
|
|
className="mt-2 text-sm text-accent hover:underline"
|
|
|
|
|
>
|
|
|
|
|
Send a test notification
|
|
|
|
|
</button>
|
|
|
|
|
</Section>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function Sync({ me }: { me: Me }) {
|
|
|
|
|
const qc = useQueryClient();
|
|
|
|
|
const status = useQuery({ queryKey: ["my-status"], queryFn: api.myStatus });
|
|
|
|
|
const s = status.data;
|
|
|
|
|
const syncSubs = useMutation({
|
|
|
|
|
mutationFn: () => api.syncSubscriptions(),
|
|
|
|
|
onSuccess: (r: { subscriptions?: number }) => {
|
|
|
|
|
qc.invalidateQueries({ queryKey: ["my-status"] });
|
|
|
|
|
qc.invalidateQueries({ queryKey: ["channels"] });
|
|
|
|
|
notify({ level: "success", message: `Synced ${r.subscriptions ?? 0} subscriptions` });
|
|
|
|
|
},
|
|
|
|
|
onError: () => notify({ level: "error", message: "Sync failed" }),
|
|
|
|
|
});
|
|
|
|
|
const pauseResume = useMutation({
|
|
|
|
|
mutationFn: (paused: boolean) => (paused ? api.resumeSync() : api.pauseSync()),
|
|
|
|
|
onSuccess: () => qc.invalidateQueries({ queryKey: ["my-status"] }),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<Section title="My sync status">
|
|
|
|
|
{s ? (
|
|
|
|
|
<div className="space-y-1.5 text-sm">
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
<Row label="Channels" hint="How many channels you're subscribed to.">
|
|
|
|
|
{s.channels_total}
|
|
|
|
|
</Row>
|
|
|
|
|
<Row
|
|
|
|
|
label="Recent synced"
|
|
|
|
|
hint="Channels whose recent uploads (~last year) are already in the local database, so they show in your feed."
|
|
|
|
|
>
|
|
|
|
|
{`${s.channels_recent_synced}/${s.channels_total}`}
|
|
|
|
|
</Row>
|
|
|
|
|
<Row
|
|
|
|
|
label="Full history"
|
|
|
|
|
hint="Channels whose entire back-catalog has been fetched. The rest backfill gradually (opt in per channel)."
|
|
|
|
|
>
|
|
|
|
|
{`${s.channels_deep_done}/${s.channels_total}`}
|
|
|
|
|
</Row>
|
|
|
|
|
<Row label="My videos" hint="Total videos available to you across your subscribed channels.">
|
|
|
|
|
{s.my_videos.toLocaleString()}
|
|
|
|
|
</Row>
|
|
|
|
|
<Row
|
|
|
|
|
label="Quota left today"
|
|
|
|
|
hint="Shared YouTube API budget remaining today (resets midnight US Pacific). Backfill yields to it."
|
|
|
|
|
>
|
|
|
|
|
{s.quota_remaining_today.toLocaleString()}
|
|
|
|
|
</Row>
|
feat(m5a): channel manager, tabbed settings panel, per-user sync status
Backend: /api/channels (list + PATCH priority/hidden + attach/detach user tags),
user-tag CRUD on /api/tags, /api/sync/my-status (per-user channel sync counts).
Frontend: feed|channels page nav (URL-synced) from the account menu; a slide-in
tabbed Settings panel (Appearance, Notifications=6b sound+duration, Sync status +
actions + admin pause/resume, Account); a channel manager with priority, hide,
per-channel user tags, sync badges and 'view in feed'. Notifications now honor the
configurable sound + auto-dismiss settings.
2026-06-11 20:45:48 +02:00
|
|
|
</div>
|
|
|
|
|
) : (
|
|
|
|
|
<div className="text-muted text-sm">Loading…</div>
|
|
|
|
|
)}
|
|
|
|
|
</Section>
|
|
|
|
|
|
|
|
|
|
<Section title="Actions">
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
<Tooltip hint="Re-import your YouTube subscriptions and pull in any newly-followed channels.">
|
|
|
|
|
<button
|
|
|
|
|
onClick={() => syncSubs.mutate()}
|
|
|
|
|
disabled={syncSubs.isPending}
|
|
|
|
|
className="glass-card glass-hover flex items-center gap-2 px-3 py-2 rounded-xl text-sm disabled:opacity-50 transition"
|
|
|
|
|
>
|
|
|
|
|
<RefreshCw className={`w-4 h-4 ${syncSubs.isPending ? "animate-spin" : ""}`} />
|
|
|
|
|
Sync subscriptions
|
|
|
|
|
</button>
|
|
|
|
|
</Tooltip>
|
feat(m5a): channel manager, tabbed settings panel, per-user sync status
Backend: /api/channels (list + PATCH priority/hidden + attach/detach user tags),
user-tag CRUD on /api/tags, /api/sync/my-status (per-user channel sync counts).
Frontend: feed|channels page nav (URL-synced) from the account menu; a slide-in
tabbed Settings panel (Appearance, Notifications=6b sound+duration, Sync status +
actions + admin pause/resume, Account); a channel manager with priority, hide,
per-channel user tags, sync badges and 'view in feed'. Notifications now honor the
configurable sound + auto-dismiss settings.
2026-06-11 20:45:48 +02:00
|
|
|
</Section>
|
|
|
|
|
|
|
|
|
|
{me.role === "admin" && s && (
|
|
|
|
|
<Section title="Admin">
|
feat(ui): liquid-glass design system, settings polish, hints, notif fixes
- Add a theme-aware glass surface system (.glass/.glass-card + ambient backdrop,
performance-mode opt-out) and apply it across panels, popovers, toasts, cards,
sidebar widgets, channel rows, video cards and login.
- SettingsPanel: slide in/out animation, glass styling, wrapping pill tabs (no
horizontal scrollbar) with a prominent active state.
- Notifications: auto-dismiss can be switched off (stays until closed); the test
notification now also triggers the alert sound; resume a suspended AudioContext.
- Add an app-wide, toggleable hint/tooltip system (lib/hints + Tooltip) and wire
hints across the settings and channel-manager surfaces; persisted per account.
2026-06-11 21:08:35 +02:00
|
|
|
<Tooltip hint="Pause or resume the background sync for the whole app (all users).">
|
|
|
|
|
<button
|
|
|
|
|
onClick={() => pauseResume.mutate(s.paused)}
|
|
|
|
|
className="glass-card glass-hover flex items-center gap-2 px-3 py-2 rounded-xl text-sm transition"
|
|
|
|
|
>
|
|
|
|
|
{s.paused ? <Play className="w-4 h-4" /> : <Pause className="w-4 h-4" />}
|
|
|
|
|
{s.paused ? "Resume background sync" : "Pause background sync"}
|
|
|
|
|
</button>
|
|
|
|
|
</Tooltip>
|
feat(m5a): channel manager, tabbed settings panel, per-user sync status
Backend: /api/channels (list + PATCH priority/hidden + attach/detach user tags),
user-tag CRUD on /api/tags, /api/sync/my-status (per-user channel sync counts).
Frontend: feed|channels page nav (URL-synced) from the account menu; a slide-in
tabbed Settings panel (Appearance, Notifications=6b sound+duration, Sync status +
actions + admin pause/resume, Account); a channel manager with priority, hide,
per-channel user tags, sync badges and 'view in feed'. Notifications now honor the
configurable sound + auto-dismiss settings.
2026-06-11 20:45:48 +02:00
|
|
|
</Section>
|
|
|
|
|
)}
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function Account({ me }: { me: Me }) {
|
|
|
|
|
return (
|
|
|
|
|
<Section title="Account">
|
|
|
|
|
<div className="flex items-center gap-3 mb-3">
|
|
|
|
|
{me.avatar_url ? (
|
|
|
|
|
<img src={me.avatar_url} alt="" className="w-12 h-12 rounded-full" />
|
|
|
|
|
) : (
|
|
|
|
|
<div className="w-12 h-12 rounded-full bg-card grid place-items-center font-semibold">
|
|
|
|
|
{(me.display_name?.[0] ?? me.email[0] ?? "?").toUpperCase()}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
<div className="min-w-0">
|
|
|
|
|
<div className="font-semibold truncate">{me.display_name ?? me.email.split("@")[0]}</div>
|
|
|
|
|
<div className="text-xs text-muted truncate">{me.email}</div>
|
|
|
|
|
<div className="text-xs text-muted capitalize">{me.role}</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<p className="text-xs text-muted leading-relaxed">
|
|
|
|
|
Playlist editing & YouTube export, and the admin approval queue, arrive in the next
|
|
|
|
|
phases of this milestone.
|
|
|
|
|
</p>
|
|
|
|
|
</Section>
|
|
|
|
|
);
|
|
|
|
|
}
|