diff --git a/web/src/features/history/history-page.tsx b/web/src/features/history/history-page.tsx index af4d41f..245d0c6 100644 --- a/web/src/features/history/history-page.tsx +++ b/web/src/features/history/history-page.tsx @@ -48,7 +48,7 @@ function HistoryRow({ record, compact, connected, playing }: { record: PlayRecor /> { historyStore.removePlay(record) diff --git a/web/src/features/queue/queue-page.tsx b/web/src/features/queue/queue-page.tsx index bd2481a..c2921be 100644 --- a/web/src/features/queue/queue-page.tsx +++ b/web/src/features/queue/queue-page.tsx @@ -74,8 +74,8 @@ export function QueuePage({ compact = false }: { compact?: boolean }) { [ - { icon: Heart, label: `点赞${bookTitle(song.title)}`, disabled: !connected, run: () => likeEntry(song.key, song.title) }, - { icon: Trash2, label: `移除${bookTitle(song.title)}`, disabled: !connected, run: () => removeEntry(song.key, song.title) }, + { icon: Heart, label: `点赞${bookTitle(song.title)}`, disabled: !connected, secondary: true, run: () => likeEntry(song.key, song.title) }, + { icon: Trash2, label: `移除${bookTitle(song.title)}`, disabled: !connected, secondary: true, run: () => removeEntry(song.key, song.title) }, ]} /> ) diff --git a/web/src/shared/ui/song-list.tsx b/web/src/shared/ui/song-list.tsx index 160931e..4afd0bb 100644 --- a/web/src/shared/ui/song-list.tsx +++ b/web/src/shared/ui/song-list.tsx @@ -24,6 +24,8 @@ export interface SongAction { icon: LucideIcon label: string disabled?: boolean + // 次要操作只在鼠标移到这一行时出现。 + secondary?: boolean run: () => Promise } @@ -47,7 +49,7 @@ export function SongList({ songs, actions }: { songs: SongItem[], actions: (song {song.album} {song.durationMs > 0 ? formatDuration(song.durationMs) : ''} {actions(song, index).map(action => ( - + ))} ))} diff --git a/web/src/shared/ui/ui.css b/web/src/shared/ui/ui.css index 2037b8a..dd1ec23 100644 --- a/web/src/shared/ui/ui.css +++ b/web/src/shared/ui/ui.css @@ -62,6 +62,11 @@ .song-action:hover:not(:disabled), .song-action:focus-visible:not(:disabled) { color: var(--color-brand); background: transparent; } .song-action:active:not(:disabled) { color: var(--color-brand); background: transparent; transform: none; } .song-action[aria-busy='true'] { cursor: progress; opacity: .7; color: var(--color-brand); } +/* 触屏没有悬停,按钮要一直显示。占位不变,出现时这一行的文字不会跳动。 */ +@media (hover: hover) { + .song-action-secondary { opacity: 0; transition: opacity 120ms ease; } + .song-row:hover .song-action-secondary, .song-row:focus-within .song-action-secondary, .song-action-secondary[aria-busy='true'] { opacity: 1; } +} .song-index { width: 22px; flex-shrink: 0; } .song-copy { display: flex; flex-direction: column; min-width: 0; gap: 3px; flex: 1; } .song-title { display: flex; align-items: center; gap: 8px; min-width: 0; }