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.
This commit is contained in:
parent
a178279674
commit
bf54b4b5a5
11 changed files with 1063 additions and 45 deletions
|
|
@ -133,6 +133,35 @@ export interface SyncStatus {
|
|||
is_admin: boolean;
|
||||
}
|
||||
|
||||
export interface MyStatus {
|
||||
channels_total: number;
|
||||
channels_details_synced: number;
|
||||
channels_recent_synced: number;
|
||||
channels_deep_done: number;
|
||||
channels_recent_pending: number;
|
||||
channels_deep_pending: number;
|
||||
my_videos: number;
|
||||
quota_used_today: number;
|
||||
quota_remaining_today: number;
|
||||
paused: boolean;
|
||||
}
|
||||
|
||||
export interface ManagedChannel {
|
||||
id: string;
|
||||
title: string | null;
|
||||
handle: string | null;
|
||||
thumbnail_url: string | null;
|
||||
subscriber_count: number | null;
|
||||
video_count: number | null;
|
||||
stored_videos: number;
|
||||
priority: number;
|
||||
hidden: boolean;
|
||||
tag_ids: number[];
|
||||
details_synced: boolean;
|
||||
recent_synced: boolean;
|
||||
backfill_done: boolean;
|
||||
}
|
||||
|
||||
export const api = {
|
||||
me: (): Promise<Me> => req("/api/me"),
|
||||
tags: (): Promise<Tag[]> => req("/api/tags"),
|
||||
|
|
@ -147,6 +176,24 @@ export const api = {
|
|||
resumeSync: () => req("/api/sync/resume", { method: "POST" }),
|
||||
savePrefs: (p: Record<string, any>) =>
|
||||
req("/api/me/preferences", { method: "PUT", body: JSON.stringify(p) }),
|
||||
|
||||
// --- channel manager ---
|
||||
myStatus: (): Promise<MyStatus> => req("/api/sync/my-status"),
|
||||
channels: (): Promise<ManagedChannel[]> => req("/api/channels"),
|
||||
updateChannel: (id: string, patch: { priority?: number; hidden?: boolean }) =>
|
||||
req(`/api/channels/${id}`, { method: "PATCH", body: JSON.stringify(patch) }),
|
||||
attachChannelTag: (id: string, tagId: number) =>
|
||||
req(`/api/channels/${id}/tags`, { method: "POST", body: JSON.stringify({ tag_id: tagId }) }),
|
||||
detachChannelTag: (id: string, tagId: number) =>
|
||||
req(`/api/channels/${id}/tags/${tagId}`, { method: "DELETE" }),
|
||||
syncSubscriptions: () => req("/api/sync/subscriptions", { method: "POST" }),
|
||||
|
||||
// --- user tags ---
|
||||
createTag: (t: { name: string; color?: string; category?: string }) =>
|
||||
req("/api/tags", { method: "POST", body: JSON.stringify(t) }),
|
||||
updateTag: (id: number, patch: { name?: string; color?: string }) =>
|
||||
req(`/api/tags/${id}`, { method: "PATCH", body: JSON.stringify(patch) }),
|
||||
deleteTag: (id: number) => req(`/api/tags/${id}`, { method: "DELETE" }),
|
||||
};
|
||||
|
||||
export { HttpError };
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue