fix(qbzd): route ALL playback and queue calls through commandRouter
playbackService.ts: v2_play_track and v2_stop_playback now route to daemon HTTP API when in remote mode. 9 views: bulk queue operations (add_tracks_to_queue, add_tracks_to_queue_next) now use cmdAddTracksToQueue/cmdAddTracksToQueueNext instead of direct invoke(). 14 call sites total. This was the root cause of 'connects but nothing plays' — the play/queue commands were always going to local Tauri, never to the remote daemon. cc
This commit is contained in:
10 files changed
+57
-36
No files matched your search
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { onMount, tick } from 'svelte';
|
||||
import { invoke, convertFileSrc } from '@tauri-apps/api/core';
|
||||
import { cmdAddTracksToQueue, cmdAddTracksToQueueNext } from '$lib/services/commandRouter';
|
||||
import { open, save } from '@tauri-apps/plugin-dialog';
|
||||
import { openUrl } from '@tauri-apps/plugin-opener';
|
||||
import { t, locale } from 'svelte-i18n';
|
||||
@@ -237,13 +238,13 @@
|
||||
|
||||
async function handleBulkPlayNext() {
|
||||
const selected = album.tracks.filter(track => multiSelectedIds.has(track.id));
|
||||
await invoke('v2_add_tracks_to_queue_next', { tracks: buildAlbumQueueTracks(selected) });
|
||||
await cmdAddTracksToQueueNext(buildAlbumQueueTracks(selected));
|
||||
multiSelectMode = false; multiSelectedIds = new Set();
|
||||
}
|
||||
|
||||
async function handleBulkPlayLater() {
|
||||
const selected = album.tracks.filter(track => multiSelectedIds.has(track.id));
|
||||
await invoke('v2_add_tracks_to_queue', { tracks: buildAlbumQueueTracks(selected) });
|
||||
await cmdAddTracksToQueue(buildAlbumQueueTracks(selected));
|
||||
multiSelectMode = false; multiSelectedIds = new Set();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { invoke, convertFileSrc } from '@tauri-apps/api/core';
|
||||
import { cmdAddTracksToQueue, cmdAddTracksToQueueNext } from '$lib/services/commandRouter';
|
||||
import { open, save } from '@tauri-apps/plugin-dialog';
|
||||
import { openUrl } from '@tauri-apps/plugin-opener';
|
||||
import { setCustomImage, removeCustomImage as removeCustomImageFromStore } from '$lib/stores/customArtistImageStore';
|
||||
@@ -444,13 +445,13 @@
|
||||
|
||||
async function handleBulkPlayNext() {
|
||||
const selected = visibleTracks.filter(trk => multiSelectedIds.has(trk.id));
|
||||
await invoke('v2_add_tracks_to_queue_next', { tracks: buildArtistQueueTracks(selected) });
|
||||
await cmdAddTracksToQueueNext(buildArtistQueueTracks(selected));
|
||||
multiSelectMode = false; multiSelectedIds = new Set();
|
||||
}
|
||||
|
||||
async function handleBulkPlayLater() {
|
||||
const selected = visibleTracks.filter(trk => multiSelectedIds.has(trk.id));
|
||||
await invoke('v2_add_tracks_to_queue', { tracks: buildArtistQueueTracks(selected) });
|
||||
await cmdAddTracksToQueue(buildArtistQueueTracks(selected));
|
||||
multiSelectMode = false; multiSelectedIds = new Set();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import { cmdAddTracksToQueue, cmdAddTracksToQueueNext } from '$lib/services/commandRouter';
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import { ArrowLeft, CloudDownload, Heart, Info, ListPlus, Play, RefreshCw, Search, Shuffle, X, SquareCheckBig } from 'lucide-svelte';
|
||||
import PlaylistModal from '$lib/components/PlaylistModal.svelte';
|
||||
@@ -121,13 +122,13 @@
|
||||
|
||||
async function handleBulkPlayNext() {
|
||||
const selected = filteredTracks.filter(trk => multiSelectedIds.has(trk.id));
|
||||
await invoke('v2_add_tracks_to_queue_next', { tracks: buildQueueTracks(selected) });
|
||||
await cmdAddTracksToQueueNext(buildQueueTracks(selected));
|
||||
multiSelectMode = false; multiSelectedIds = new Set();
|
||||
}
|
||||
|
||||
async function handleBulkPlayLater() {
|
||||
const selected = filteredTracks.filter(trk => multiSelectedIds.has(trk.id));
|
||||
await invoke('v2_add_tracks_to_queue', { tracks: buildQueueTracks(selected) });
|
||||
await cmdAddTracksToQueue(buildQueueTracks(selected));
|
||||
multiSelectMode = false; multiSelectedIds = new Set();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import { cmdAddTracksToQueue, cmdAddTracksToQueueNext } from '$lib/services/commandRouter';
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import { ArrowLeft, CloudDownload, Heart, Info, ListPlus, Play, RefreshCw, Search, Shuffle, X, SquareCheckBig } from 'lucide-svelte';
|
||||
import PlaylistModal from '$lib/components/PlaylistModal.svelte';
|
||||
@@ -122,13 +123,13 @@
|
||||
|
||||
async function handleBulkPlayNext() {
|
||||
const selected = filteredTracks.filter(trk => multiSelectedIds.has(trk.id));
|
||||
await invoke('v2_add_tracks_to_queue_next', { tracks: buildQueueTracks(selected) });
|
||||
await cmdAddTracksToQueueNext(buildQueueTracks(selected));
|
||||
multiSelectMode = false; multiSelectedIds = new Set();
|
||||
}
|
||||
|
||||
async function handleBulkPlayLater() {
|
||||
const selected = filteredTracks.filter(trk => multiSelectedIds.has(trk.id));
|
||||
await invoke('v2_add_tracks_to_queue', { tracks: buildQueueTracks(selected) });
|
||||
await cmdAddTracksToQueue(buildQueueTracks(selected));
|
||||
multiSelectMode = false; multiSelectedIds = new Set();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import { cmdAddTracksToQueue, cmdAddTracksToQueueNext } from '$lib/services/commandRouter';
|
||||
import { getUserInfo } from '$lib/stores/authStore';
|
||||
import { resolveArtistImage } from '$lib/stores/customArtistImageStore';
|
||||
import { onMount, tick } from 'svelte';
|
||||
@@ -271,7 +272,7 @@
|
||||
async function handleBulkPlayNext() {
|
||||
const selected = filteredTracks.filter(trk => selectedTrackIds.has(trk.id));
|
||||
const tracks = buildFavoritesQueueTracks(selected);
|
||||
await invoke('v2_add_tracks_to_queue_next', { tracks });
|
||||
await cmdAddTracksToQueueNext(tracks);
|
||||
trackSelectMode = false;
|
||||
selectedTrackIds = new Set();
|
||||
}
|
||||
@@ -279,7 +280,7 @@
|
||||
async function handleBulkPlayLater() {
|
||||
const selected = filteredTracks.filter(trk => selectedTrackIds.has(trk.id));
|
||||
const tracks = buildFavoritesQueueTracks(selected);
|
||||
await invoke('v2_add_tracks_to_queue', { tracks });
|
||||
await cmdAddTracksToQueue(tracks);
|
||||
trackSelectMode = false;
|
||||
selectedTrackIds = new Set();
|
||||
}
|
||||
@@ -1298,7 +1299,7 @@
|
||||
|
||||
try {
|
||||
const queueTracks = buildFavoritesQueueTracks(filteredTracks);
|
||||
await invoke('v2_add_tracks_to_queue_next', { tracks: queueTracks });
|
||||
await cmdAddTracksToQueueNext(queueTracks);
|
||||
} catch (err) {
|
||||
console.error('Failed to add tracks next:', err);
|
||||
}
|
||||
@@ -1309,7 +1310,7 @@
|
||||
|
||||
try {
|
||||
const queueTracks = buildFavoritesQueueTracks(filteredTracks);
|
||||
await invoke('v2_add_tracks_to_queue', { tracks: queueTracks });
|
||||
await cmdAddTracksToQueue(queueTracks);
|
||||
} catch (err) {
|
||||
console.error('Failed to add tracks to queue:', err);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import { cmdAddTracksToQueue, cmdAddTracksToQueueNext } from '$lib/services/commandRouter';
|
||||
import { resolveArtistImage } from '$lib/stores/customArtistImageStore';
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import { ArrowLeft, Disc3, Play, Music, Ellipsis, Heart, User, ChevronDown, ChevronUp, SquareCheckBig } from 'lucide-svelte';
|
||||
@@ -221,13 +222,13 @@
|
||||
|
||||
async function handleBulkPlayNext() {
|
||||
const selected = visibleTracks.filter(trk => multiSelectedIds.has(trk.id));
|
||||
await invoke('v2_add_tracks_to_queue_next', { tracks: buildTopTracksQueue(selected) });
|
||||
await cmdAddTracksToQueueNext(buildTopTracksQueue(selected));
|
||||
multiSelectMode = false; multiSelectedIds = new Set();
|
||||
}
|
||||
|
||||
async function handleBulkPlayLater() {
|
||||
const selected = visibleTracks.filter(trk => multiSelectedIds.has(trk.id));
|
||||
await invoke('v2_add_tracks_to_queue', { tracks: buildTopTracksQueue(selected) });
|
||||
await cmdAddTracksToQueue(buildTopTracksQueue(selected));
|
||||
multiSelectMode = false; multiSelectedIds = new Set();
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
import ViewTransition from '../ViewTransition.svelte';
|
||||
import { writeText } from '@tauri-apps/plugin-clipboard-manager';
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import { cmdAddTracksToQueue, cmdAddTracksToQueueNext } from '$lib/services/commandRouter';
|
||||
import { open, ask } from '@tauri-apps/plugin-dialog';
|
||||
import TrackRow from '../TrackRow.svelte';
|
||||
import PlaylistSuggestions from '../PlaylistSuggestions.svelte';
|
||||
@@ -1183,7 +1184,7 @@
|
||||
async function handleBulkPlayNext() {
|
||||
const selected = displayTracks.filter(trk => multiSelectedKeys.has(getTrackKey(trk)));
|
||||
const { queueTracks } = buildQueueTracks(selected);
|
||||
await invoke('v2_add_tracks_to_queue_next', { tracks: queueTracks });
|
||||
await cmdAddTracksToQueueNext(queueTracks);
|
||||
multiSelectedKeys = new Set();
|
||||
multiSelectMode = false;
|
||||
}
|
||||
@@ -1191,7 +1192,7 @@
|
||||
async function handleBulkPlayLater() {
|
||||
const selected = displayTracks.filter(trk => multiSelectedKeys.has(getTrackKey(trk)));
|
||||
const { queueTracks } = buildQueueTracks(selected);
|
||||
await invoke('v2_add_tracks_to_queue', { tracks: queueTracks });
|
||||
await cmdAddTracksToQueue(queueTracks);
|
||||
multiSelectedKeys = new Set();
|
||||
multiSelectMode = false;
|
||||
}
|
||||
@@ -1968,7 +1969,7 @@
|
||||
}));
|
||||
|
||||
try {
|
||||
await invoke('v2_add_tracks_to_queue_next', { tracks: queueTracks });
|
||||
await cmdAddTracksToQueueNext(queueTracks);
|
||||
|
||||
// Tell parent about local tracks added to queue
|
||||
if (localIds.length > 0) {
|
||||
@@ -2013,7 +2014,7 @@
|
||||
.map(trk => Math.abs(trk.id));
|
||||
|
||||
try {
|
||||
await invoke('v2_add_tracks_to_queue', { tracks: queueTracks });
|
||||
await cmdAddTracksToQueue(queueTracks);
|
||||
|
||||
// Tell parent about local tracks added to queue
|
||||
if (localIds.length > 0) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import { cmdAddTracksToQueue, cmdAddTracksToQueueNext } from '$lib/services/commandRouter';
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import { ArrowLeft, Info, ListPlus, Play, RefreshCw, Search, Shuffle, X, SquareCheckBig } from 'lucide-svelte';
|
||||
import PlaylistModal from '$lib/components/PlaylistModal.svelte';
|
||||
@@ -137,13 +138,13 @@
|
||||
|
||||
async function handleBulkPlayNext() {
|
||||
const selected = filteredTracks.filter(trk => multiSelectedIds.has(trk.id));
|
||||
await invoke('v2_add_tracks_to_queue_next', { tracks: buildQueueTracks(selected) });
|
||||
await cmdAddTracksToQueueNext(buildQueueTracks(selected));
|
||||
multiSelectMode = false; multiSelectedIds = new Set();
|
||||
}
|
||||
|
||||
async function handleBulkPlayLater() {
|
||||
const selected = filteredTracks.filter(trk => multiSelectedIds.has(trk.id));
|
||||
await invoke('v2_add_tracks_to_queue', { tracks: buildQueueTracks(selected) });
|
||||
await cmdAddTracksToQueue(buildQueueTracks(selected));
|
||||
multiSelectMode = false; multiSelectedIds = new Set();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import { cmdAddTracksToQueue, cmdAddTracksToQueueNext } from '$lib/services/commandRouter';
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import { ArrowLeft, CloudDownload, Heart, Info, ListPlus, Play, Search, Shuffle, X, SquareCheckBig } from 'lucide-svelte';
|
||||
import PlaylistModal from '$lib/components/PlaylistModal.svelte';
|
||||
@@ -117,13 +118,13 @@
|
||||
|
||||
async function handleBulkPlayNext() {
|
||||
const selected = filteredTracks.filter(trk => multiSelectedIds.has(trk.id));
|
||||
await invoke('v2_add_tracks_to_queue_next', { tracks: buildQueueTracks(selected) });
|
||||
await cmdAddTracksToQueueNext(buildQueueTracks(selected));
|
||||
multiSelectMode = false; multiSelectedIds = new Set();
|
||||
}
|
||||
|
||||
async function handleBulkPlayLater() {
|
||||
const selected = filteredTracks.filter(trk => multiSelectedIds.has(trk.id));
|
||||
await invoke('v2_add_tracks_to_queue', { tracks: buildQueueTracks(selected) });
|
||||
await cmdAddTracksToQueue(buildQueueTracks(selected));
|
||||
multiSelectMode = false; multiSelectedIds = new Set();
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import { get } from 'svelte/store';
|
||||
import { t } from '$lib/i18n';
|
||||
import { cmdStop, cmdPlayTrack } from '$lib/services/commandRouter';
|
||||
import { getTarget } from '$lib/stores/playbackTargetStore';
|
||||
import { remotePost } from '$lib/services/remoteApi';
|
||||
import { getUserItem, setUserItem } from '$lib/utils/userStorage';
|
||||
import {
|
||||
isPlaybackSourceLocal,
|
||||
@@ -192,7 +195,7 @@ export async function playTrack(
|
||||
// Stop any leftover local playback so the active remote renderer owns the session.
|
||||
if (!isCasting()) {
|
||||
try {
|
||||
await invoke('v2_stop_playback');
|
||||
await cmdStop();
|
||||
} catch {
|
||||
// Ignore errors - player might not be playing locally
|
||||
}
|
||||
@@ -204,7 +207,7 @@ export async function playTrack(
|
||||
if (!isCasting()) {
|
||||
// Stop current playback immediately
|
||||
try {
|
||||
await invoke('v2_stop_playback');
|
||||
await cmdStop();
|
||||
} catch {
|
||||
// Ignore errors - player might not be playing
|
||||
}
|
||||
@@ -250,19 +253,28 @@ export async function playTrack(
|
||||
} else if (isLocal) {
|
||||
await invoke('v2_library_play_track', { trackId: track.id });
|
||||
} else {
|
||||
const result = await invoke<PlayTrackResult>('v2_play_track', {
|
||||
trackId: track.id,
|
||||
quality: effectiveQuality(track),
|
||||
durationSecs: track.duration ? Math.round(track.duration) : null,
|
||||
forceLowestQuality: forceLowestQuality || null
|
||||
});
|
||||
// Route to daemon or local based on playback target
|
||||
const target = getTarget();
|
||||
if (target.type === 'qbzd') {
|
||||
await remotePost('/api/playback/play-track', {
|
||||
track_id: track.id,
|
||||
quality: effectiveQuality(track),
|
||||
});
|
||||
} else {
|
||||
const result = await invoke<PlayTrackResult>('v2_play_track', {
|
||||
trackId: track.id,
|
||||
quality: effectiveQuality(track),
|
||||
durationSecs: track.duration ? Math.round(track.duration) : null,
|
||||
forceLowestQuality: forceLowestQuality || null
|
||||
});
|
||||
|
||||
// Update track format based on actual stream format_id from Qobuz
|
||||
const actualFormat = formatIdToString(result.format_id);
|
||||
if (actualFormat) {
|
||||
track.format = actualFormat;
|
||||
// Re-set current track to update the UI with actual format
|
||||
setCurrentTrack(track);
|
||||
// Update track format based on actual stream format_id from Qobuz
|
||||
const actualFormat = formatIdToString(result.format_id);
|
||||
if (actualFormat) {
|
||||
track.format = actualFormat;
|
||||
// Re-set current track to update the UI with actual format
|
||||
setCurrentTrack(track);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user