fix: context menu Play Now playback and resize behaviour (#1174)

* fix(playlist): play the playlist from the context menu Play Now action

The Playlists-page context menu 'Play Now' only navigated to the playlist
detail page instead of starting playback. It now loads the playlist's songs
and plays them via the shared playPlaylistAll action (same path as the detail
page 'Play All' button), with a guard against load failures.

* fix(ui): close the context menu on window resize

The context menu is absolutely positioned at fixed coordinates, so resizing
the window left it stranded and drifting off-screen. Whether a resize closed
it was inconsistent across setups (it stayed open on some Windows and Linux
environments). Always close it on resize so the behaviour is the same
everywhere.

* docs(changelog): context menu Play Now and resize fixes (#1174)

* docs(changelog): credit the reporter for the context menu fixes
This commit is contained in:
Psychotoxical
2026-06-24 21:19:04 +02:00
committed by GitHub
parent 58e6efc68c
commit 9bbe69e7e7
4 changed files with 48 additions and 3 deletions
+12
View File
@@ -132,6 +132,18 @@ export default function ContextMenu() {
}
}, [contextMenu.isOpen, contextMenu.x, contextMenu.y]);
// Close on any window resize. The menu is absolutely positioned at fixed
// coordinates, so a resize would otherwise leave it stranded and drifting
// off-screen. Whether a resize closed the menu was inconsistent across
// setups (it stayed open on some Windows and Linux environments); always
// closing it here makes the behaviour the same everywhere.
useEffect(() => {
if (!contextMenu.isOpen) return;
const onResize = () => closeContextMenu();
window.addEventListener('resize', onResize);
return () => window.removeEventListener('resize', onResize);
}, [contextMenu.isOpen, closeContextMenu]);
useEffect(() => {
if (contextMenu.isOpen) {
previousFocusRef.current = document.activeElement as HTMLElement | null;
@@ -1,6 +1,5 @@
import { useTranslation } from 'react-i18next';
import { Play, ChevronRight, FolderTree, ListMusic, Trash2 } from 'lucide-react';
import { useNavigate } from 'react-router-dom';
import type { SubsonicPlaylist } from '../../api/subsonicTypes';
import { usePlaylistStore } from '../../store/playlistStore';
import { MultiPlaylistToPlaylistSubmenu, SinglePlaylistToPlaylistSubmenu } from './PlaylistToPlaylistSubmenus';
@@ -16,7 +15,6 @@ export default function PlaylistContextItems(props: ContextMenuItemsProps) {
offlinePolicy,
} = props;
const { t } = useTranslation();
const navigate = useNavigate();
return (
<>
@@ -24,7 +22,14 @@ export default function PlaylistContextItems(props: ContextMenuItemsProps) {
const playlist = item as SubsonicPlaylist;
return (
<>
<div className="context-menu-item" onClick={() => handleAction(() => navigate(`/playlists/${playlist.id}`))}>
<div className="context-menu-item" onClick={() => handleAction(async () => {
const { playPlaylistById } = await import('../../utils/playlist/playPlaylistById');
try {
await playPlaylistById(playlist.id);
} catch {
// Network/load failure — leave playback untouched rather than crash.
}
})}>
<Play size={14} /> {t('contextMenu.playNow')}
</div>
<div className="context-menu-divider" />