feat(web): match track kebab to Android + add it to full-screen Now Playing
test-web / test (push) Failing after 32s
test-web / test (push) Failing after 32s
Bring the web TrackMenu to parity with Android's canonical TrackActionsSheet so the kebab reads the same on both clients: - Reorder to Android's groups: queue → like/add-to-playlist/start-radio → go-to-album/artist → hide. - Drop the duplicate "Flag this track…" item — it opened the very same FlagPopover as "Hide" (Android folds flag into a single Hide). - Align icons (ListVideo / ListMusic / ListPlus / Disc3 / User). - Admin-only "Remove from library" stays as a web superset (Android has no surface for it), past its own divider. Mount the kebab on the full-screen /now-playing route with hideQueueActions, mirroring Android's NowPlayingScreen — Start radio / Add to playlist / Hide were previously unreachable there (only like + volume + queue existed). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,15 +1,14 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {
|
import {
|
||||||
MoreVertical,
|
MoreVertical,
|
||||||
ListPlus,
|
ListVideo,
|
||||||
Plus,
|
ListMusic,
|
||||||
Radio,
|
|
||||||
Heart,
|
Heart,
|
||||||
HeartOff,
|
HeartOff,
|
||||||
ListMusic,
|
ListPlus,
|
||||||
Album,
|
Radio,
|
||||||
Disc3,
|
Disc3,
|
||||||
Flag,
|
User,
|
||||||
EyeOff,
|
EyeOff,
|
||||||
Eye,
|
Eye,
|
||||||
Trash2
|
Trash2
|
||||||
@@ -125,11 +124,6 @@
|
|||||||
goto(`/artists/${track.artist_id}`);
|
goto(`/artists/${track.artist_id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onFlag() {
|
|
||||||
menuOpen = false;
|
|
||||||
flagOpen = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onRemoveOpen() {
|
function onRemoveOpen() {
|
||||||
menuOpen = false;
|
menuOpen = false;
|
||||||
removeOpen = true;
|
removeOpen = true;
|
||||||
@@ -167,46 +161,46 @@
|
|||||||
onclick={(e) => e.stopPropagation()}
|
onclick={(e) => e.stopPropagation()}
|
||||||
onkeydown={(e) => { e.stopPropagation(); if (e.key === 'Escape') menuOpen = false; }}
|
onkeydown={(e) => { e.stopPropagation(); if (e.key === 'Escape') menuOpen = false; }}
|
||||||
>
|
>
|
||||||
|
<!-- Item set + order mirror Android's canonical TrackActionsSheet so
|
||||||
|
the kebab reads the same on both clients: queue group → like /
|
||||||
|
add-to-playlist / start-radio group → navigation group → hide.
|
||||||
|
"Start radio" is shown even under hideQueueActions (reseeding a
|
||||||
|
station from the current track is meaningful where play-next /
|
||||||
|
add-to-queue are not). The admin-only "Remove from library" is a
|
||||||
|
web superset Android has no surface for — kept past the divider. -->
|
||||||
{#if !hideQueueActions}
|
{#if !hideQueueActions}
|
||||||
<TrackMenuItem icon={ListPlus} label="Play next" onclick={onPlayNext} />
|
<TrackMenuItem icon={ListVideo} label="Play next" onclick={onPlayNext} />
|
||||||
<TrackMenuItem icon={Plus} label="Add to queue" onclick={onAddToQueue} />
|
<TrackMenuItem icon={ListMusic} label="Add to queue" onclick={onAddToQueue} />
|
||||||
|
|
||||||
<TrackMenuDivider />
|
<TrackMenuDivider />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<!-- Start radio is always offered, even on the now-playing surfaces
|
|
||||||
(hideQueueActions) — reseeding the queue as a radio station from
|
|
||||||
the current track is meaningful where "play next" / "add to queue"
|
|
||||||
are not. Mirrors TrackRow's inline 📻 button via playRadio(). -->
|
|
||||||
<TrackMenuItem icon={Radio} label="Start radio" onclick={onStartRadio} />
|
|
||||||
|
|
||||||
<TrackMenuDivider />
|
|
||||||
|
|
||||||
<TrackMenuItem
|
<TrackMenuItem
|
||||||
icon={liked ? HeartOff : Heart}
|
icon={liked ? HeartOff : Heart}
|
||||||
label={liked ? 'Unlike' : 'Like'}
|
label={liked ? 'Unlike' : 'Like'}
|
||||||
onclick={onToggleLike}
|
onclick={onToggleLike}
|
||||||
/>
|
/>
|
||||||
<TrackMenuItem
|
<TrackMenuItem
|
||||||
icon={ListMusic}
|
icon={ListPlus}
|
||||||
label="Add to playlist…"
|
label="Add to playlist…"
|
||||||
onclick={() => { addOpen = true; menuOpen = false; }}
|
onclick={() => { addOpen = true; menuOpen = false; }}
|
||||||
/>
|
/>
|
||||||
|
<TrackMenuItem icon={Radio} label="Start radio" onclick={onStartRadio} />
|
||||||
|
|
||||||
<TrackMenuDivider />
|
<TrackMenuDivider />
|
||||||
|
|
||||||
<TrackMenuItem icon={Album} label="Go to album" onclick={onGoToAlbum} />
|
<TrackMenuItem icon={Disc3} label="Go to album" onclick={onGoToAlbum} />
|
||||||
<TrackMenuItem icon={Disc3} label="Go to artist" onclick={onGoToArtist} />
|
<TrackMenuItem icon={User} label="Go to artist" onclick={onGoToArtist} />
|
||||||
|
|
||||||
<TrackMenuDivider />
|
<TrackMenuDivider />
|
||||||
|
|
||||||
<TrackMenuItem icon={Flag} label="Flag this track…" onclick={onFlag} />
|
|
||||||
<TrackMenuItem
|
<TrackMenuItem
|
||||||
icon={hidden ? Eye : EyeOff}
|
icon={hidden ? Eye : EyeOff}
|
||||||
label={hidden ? 'Unhide' : 'Hide'}
|
label={hidden ? 'Unhide' : 'Hide'}
|
||||||
onclick={onToggleHide}
|
onclick={onToggleHide}
|
||||||
/>
|
/>
|
||||||
{#if isAdmin}
|
{#if isAdmin}
|
||||||
|
<TrackMenuDivider />
|
||||||
<TrackMenuItem
|
<TrackMenuItem
|
||||||
icon={Trash2}
|
icon={Trash2}
|
||||||
label="Remove from library"
|
label="Remove from library"
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
import { FALLBACK_COVER, coverUrl } from '$lib/media/covers';
|
import { FALLBACK_COVER, coverUrl } from '$lib/media/covers';
|
||||||
import { useSmoothPosition } from '$lib/player/smoothPosition.svelte';
|
import { useSmoothPosition } from '$lib/player/smoothPosition.svelte';
|
||||||
import LikeButton from '$lib/components/LikeButton.svelte';
|
import LikeButton from '$lib/components/LikeButton.svelte';
|
||||||
|
import TrackMenu from '$lib/components/TrackMenu.svelte';
|
||||||
import QueueList from '$lib/components/QueueList.svelte';
|
import QueueList from '$lib/components/QueueList.svelte';
|
||||||
import { pageTitle } from '$lib/branding';
|
import { pageTitle } from '$lib/branding';
|
||||||
|
|
||||||
@@ -78,6 +79,15 @@
|
|||||||
<ArrowLeft size={22} strokeWidth={1.5} />
|
<ArrowLeft size={22} strokeWidth={1.5} />
|
||||||
</button>
|
</button>
|
||||||
<div class="ml-2 text-xs uppercase tracking-wide text-text-secondary">Now playing</div>
|
<div class="ml-2 text-xs uppercase tracking-wide text-text-secondary">Now playing</div>
|
||||||
|
<!-- Full-screen Now Playing carries the same kebab as Android's
|
||||||
|
NowPlayingScreen (hideQueueActions — the menu's track IS the one
|
||||||
|
playing), so Start radio / Add to playlist / Hide etc. are reachable
|
||||||
|
here, not just from the mini-player bar. -->
|
||||||
|
{#if current}
|
||||||
|
<div class="ml-auto">
|
||||||
|
<TrackMenu track={current} hideQueueActions />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
{#if !current}
|
{#if !current}
|
||||||
|
|||||||
Reference in New Issue
Block a user