use client-side shuffle for listquery random playback (#1247)

This commit is contained in:
jeffvli
2025-12-07 21:24:17 -08:00
parent cd2d8ae3c9
commit 7f540472da
@@ -23,6 +23,7 @@ import { songsQueries } from '/@/renderer/features/songs/api/songs-api';
import { AddToQueueType, usePlayerActions, useSettingsStore } from '/@/renderer/store'; import { AddToQueueType, usePlayerActions, useSettingsStore } from '/@/renderer/store';
import { LogCategory, logFn } from '/@/renderer/utils/logger'; import { LogCategory, logFn } from '/@/renderer/utils/logger';
import { logMsg } from '/@/renderer/utils/logger-message'; import { logMsg } from '/@/renderer/utils/logger-message';
import { shuffle as shuffleArray } from '/@/renderer/utils/shuffle';
import { sortSongsByFetchedOrder } from '/@/shared/api/utils'; import { sortSongsByFetchedOrder } from '/@/shared/api/utils';
import { Checkbox } from '/@/shared/components/checkbox/checkbox'; import { Checkbox } from '/@/shared/components/checkbox/checkbox';
import { ConfirmModal } from '/@/shared/components/modal/modal'; import { ConfirmModal } from '/@/shared/components/modal/modal';
@@ -31,6 +32,7 @@ import { Text } from '/@/shared/components/text/text';
import { toast } from '/@/shared/components/toast/toast'; import { toast } from '/@/shared/components/toast/toast';
import { useLocalStorage } from '/@/shared/hooks/use-local-storage'; import { useLocalStorage } from '/@/shared/hooks/use-local-storage';
import { import {
AlbumListSort,
instanceOfCancellationError, instanceOfCancellationError,
LibraryItem, LibraryItem,
PlaylistSongListResponse, PlaylistSongListResponse,
@@ -338,11 +340,18 @@ export const PlayerProvider = ({ children }: { children: React.ReactNode }) => {
}); });
try { try {
// Get total count first
let totalCount = 0; let totalCount = 0;
let listQueryFn: any; let listQueryFn: any;
let listCountQueryFn: any; let listCountQueryFn: any;
// Special handling for albums with random sort: fetch in name order, then shuffle client-side
const isAlbumRandomSort =
itemType === LibraryItem.ALBUM && query.sortBy === AlbumListSort.RANDOM;
const fetchQuery = isAlbumRandomSort
? { ...query, sortBy: AlbumListSort.NAME }
: query;
switch (itemType) { switch (itemType) {
case LibraryItem.ALBUM: { case LibraryItem.ALBUM: {
listQueryFn = albumQueries.list; listQueryFn = albumQueries.list;
@@ -377,7 +386,7 @@ export const PlayerProvider = ({ children }: { children: React.ReactNode }) => {
// Get total count // Get total count
const countResult = (await queryClient.fetchQuery({ const countResult = (await queryClient.fetchQuery({
...listCountQueryFn({ ...listCountQueryFn({
query: { ...query }, query: { ...fetchQuery },
serverId, serverId,
}), }),
gcTime: 0, gcTime: 0,
@@ -431,7 +440,7 @@ export const PlayerProvider = ({ children }: { children: React.ReactNode }) => {
while (startIndex < totalCount) { while (startIndex < totalCount) {
const pageQuery = { const pageQuery = {
...query, ...fetchQuery,
limit: pageSize, limit: pageSize,
startIndex, startIndex,
}; };
@@ -472,10 +481,16 @@ export const PlayerProvider = ({ children }: { children: React.ReactNode }) => {
toast.hide(toastId); toast.hide(toastId);
} }
// Shuffle album IDs client-side if this was a random sort request
let finalResults = allResults;
if (isAlbumRandomSort && itemType === LibraryItem.ALBUM) {
finalResults = shuffleArray(allResults as string[]) as typeof allResults;
}
if (itemType === LibraryItem.SONG) { if (itemType === LibraryItem.SONG) {
addToQueueByData(allResults as Song[], type); addToQueueByData(finalResults as Song[], type);
} else { } else {
await addToQueueByFetch(serverId, allResults as string[], itemType, type); await addToQueueByFetch(serverId, finalResults as string[], itemType, type);
} }
} catch (err: any) { } catch (err: any) {
if (instanceOfCancellationError(err)) { if (instanceOfCancellationError(err)) {