feat(player): watched controls, compact layout, description popover
- Watched: an explicit toggle in the modal (Mark watched / Watched→unmark) plus
auto-mark when playback reaches the end (within 10s, or on the ended event).
- Compact layout: drop the header bar and the redundant 'Open on YouTube' button
(the embed's own YouTube logo already jumps out); Close moves to the title row,
channel + meta share one line — fits without a scrollbar at higher zoom.
- Card actions reflect status: watched shows a double-check, saved a filled
bookmark, with matching tooltips.
- Description: new GET /api/videos/{id} exposes the already-stored description,
shown in a popover when hovering the modal title (fetched lazily).
This commit is contained in:
parent
99dfa7691c
commit
fcb77ac2e1
5 changed files with 161 additions and 60 deletions
|
|
@ -47,6 +47,12 @@ export interface Video {
|
|||
watch_url: string;
|
||||
}
|
||||
|
||||
export interface VideoDetail {
|
||||
id: string;
|
||||
description: string | null;
|
||||
like_count: number | null;
|
||||
}
|
||||
|
||||
export interface FeedResponse {
|
||||
items: Video[];
|
||||
has_more: boolean;
|
||||
|
|
@ -214,6 +220,7 @@ export const api = {
|
|||
req(`/api/feed/count?${feedQuery(f, 0, 0)}`),
|
||||
setState: (id: string, status: string) =>
|
||||
req(`/api/videos/${id}/state`, { method: "POST", body: JSON.stringify({ status }) }),
|
||||
videoDetail: (id: string): Promise<VideoDetail> => req(`/api/videos/${id}`),
|
||||
pauseSync: () => req("/api/sync/pause", { method: "POST" }),
|
||||
resumeSync: () => req("/api/sync/resume", { method: "POST" }),
|
||||
savePrefs: (p: Record<string, any>) =>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue