mirror of
https://github.com/antebudimir/feishin.git
synced 2025-12-31 10:03:33 +00:00
refactor api controller to internalize server fetch
This commit is contained in:
parent
8dbaec3943
commit
c7a473d864
79 changed files with 904 additions and 399 deletions
|
|
@ -2,18 +2,19 @@ import i18n from '/@/i18n/i18n';
|
|||
import { JellyfinController } from '/@/renderer/api/jellyfin/jellyfin-controller';
|
||||
import { NavidromeController } from '/@/renderer/api/navidrome/navidrome-controller';
|
||||
import { SubsonicController } from '/@/renderer/api/subsonic/subsonic-controller';
|
||||
import { useAuthStore } from '/@/renderer/store';
|
||||
import { getServerById, useAuthStore } from '/@/renderer/store';
|
||||
import { toast } from '/@/shared/components/toast/toast';
|
||||
import {
|
||||
AuthenticationResponse,
|
||||
ControllerEndpoint,
|
||||
InternalControllerEndpoint,
|
||||
ServerType,
|
||||
} from '/@/shared/types/domain-types';
|
||||
|
||||
type ApiController = {
|
||||
jellyfin: ControllerEndpoint;
|
||||
navidrome: ControllerEndpoint;
|
||||
subsonic: ControllerEndpoint;
|
||||
jellyfin: InternalControllerEndpoint;
|
||||
navidrome: InternalControllerEndpoint;
|
||||
subsonic: InternalControllerEndpoint;
|
||||
};
|
||||
|
||||
const endpoints: ApiController = {
|
||||
|
|
@ -25,7 +26,7 @@ const endpoints: ApiController = {
|
|||
const apiController = <K extends keyof ControllerEndpoint>(
|
||||
endpoint: K,
|
||||
type?: ServerType,
|
||||
): NonNullable<ControllerEndpoint[K]> => {
|
||||
): NonNullable<InternalControllerEndpoint[K]> => {
|
||||
const serverType = type || useAuthStore.getState().currentServer?.type;
|
||||
|
||||
if (!serverType) {
|
||||
|
|
@ -68,129 +69,580 @@ export interface GeneralController extends Omit<Required<ControllerEndpoint>, 'a
|
|||
|
||||
export const controller: GeneralController = {
|
||||
addToPlaylist(args) {
|
||||
return apiController('addToPlaylist', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: addToPlaylist`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'addToPlaylist',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
authenticate(url, body, type) {
|
||||
return apiController('authenticate', type)(url, body);
|
||||
},
|
||||
createFavorite(args) {
|
||||
return apiController('createFavorite', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: createFavorite`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'createFavorite',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
createPlaylist(args) {
|
||||
return apiController('createPlaylist', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: createPlaylist`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'createPlaylist',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
deleteFavorite(args) {
|
||||
return apiController('deleteFavorite', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: deleteFavorite`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'deleteFavorite',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
deletePlaylist(args) {
|
||||
return apiController('deletePlaylist', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: deletePlaylist`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'deletePlaylist',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getAlbumArtistDetail(args) {
|
||||
return apiController('getAlbumArtistDetail', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getAlbumArtistDetail`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getAlbumArtistDetail',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getAlbumArtistList(args) {
|
||||
return apiController('getAlbumArtistList', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getAlbumArtistList`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getAlbumArtistList',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getAlbumArtistListCount(args) {
|
||||
return apiController('getAlbumArtistListCount', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getAlbumArtistListCount`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getAlbumArtistListCount',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getAlbumDetail(args) {
|
||||
return apiController('getAlbumDetail', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getAlbumDetail`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getAlbumDetail',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getAlbumInfo(args) {
|
||||
return apiController('getAlbumInfo', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getAlbumInfo`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getAlbumInfo',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getAlbumList(args) {
|
||||
return apiController('getAlbumList', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getAlbumList`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getAlbumList',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getAlbumListCount(args) {
|
||||
return apiController('getAlbumListCount', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getAlbumListCount`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getAlbumListCount',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getArtistList(args) {
|
||||
return apiController('getArtistList', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getArtistList`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getArtistList',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getArtistListCount(args) {
|
||||
return apiController('getArtistListCount', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getArtistListCount`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getArtistListCount',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getDownloadUrl(args) {
|
||||
return apiController('getDownloadUrl', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getDownloadUrl`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getDownloadUrl',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getGenreList(args) {
|
||||
return apiController('getGenreList', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getGenreList`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getGenreList',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getLyrics(args) {
|
||||
return apiController('getLyrics', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getLyrics`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getLyrics',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getMusicFolderList(args) {
|
||||
return apiController('getMusicFolderList', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getMusicFolderList`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getMusicFolderList',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getPlaylistDetail(args) {
|
||||
return apiController('getPlaylistDetail', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getPlaylistDetail`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getPlaylistDetail',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getPlaylistList(args) {
|
||||
return apiController('getPlaylistList', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getPlaylistList`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getPlaylistList',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getPlaylistListCount(args) {
|
||||
return apiController('getPlaylistListCount', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getPlaylistListCount`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getPlaylistListCount',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getPlaylistSongList(args) {
|
||||
return apiController('getPlaylistSongList', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getPlaylistSongList`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getPlaylistSongList',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getRandomSongList(args) {
|
||||
return apiController('getRandomSongList', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getRandomSongList`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getRandomSongList',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getRoles(args) {
|
||||
return apiController('getRoles', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getRoles`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getRoles',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getServerInfo(args) {
|
||||
return apiController('getServerInfo', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getServerInfo`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getServerInfo',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getSimilarSongs(args) {
|
||||
return apiController('getSimilarSongs', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getSimilarSongs`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getSimilarSongs',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getSongDetail(args) {
|
||||
return apiController('getSongDetail', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getSongDetail`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getSongDetail',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getSongList(args) {
|
||||
return apiController('getSongList', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getSongList`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getSongList',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getSongListCount(args) {
|
||||
return apiController('getSongListCount', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getSongListCount`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getSongListCount',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getStructuredLyrics(args) {
|
||||
return apiController('getStructuredLyrics', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getStructuredLyrics`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getStructuredLyrics',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getTags(args) {
|
||||
return apiController('getTags', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getTags`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getTags',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getTopSongs(args) {
|
||||
return apiController('getTopSongs', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getTopSongs`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getTopSongs',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getTranscodingUrl(args) {
|
||||
return apiController('getTranscodingUrl', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getTranscodingUrl`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getTranscodingUrl',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
getUserList(args) {
|
||||
return apiController('getUserList', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getUserList`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'getUserList',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
movePlaylistItem(args) {
|
||||
return apiController('movePlaylistItem', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: movePlaylistItem`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'movePlaylistItem',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
removeFromPlaylist(args) {
|
||||
return apiController('removeFromPlaylist', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: removeFromPlaylist`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'removeFromPlaylist',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
scrobble(args) {
|
||||
return apiController('scrobble', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: scrobble`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'scrobble',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
search(args) {
|
||||
return apiController('search', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: search`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'search',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
setRating(args) {
|
||||
return apiController('setRating', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: setRating`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'setRating',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
shareItem(args) {
|
||||
return apiController('shareItem', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: shareItem`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'shareItem',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
updatePlaylist(args) {
|
||||
return apiController('updatePlaylist', args.apiClientProps.server?.type)?.(args);
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: updatePlaylist`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
'updatePlaylist',
|
||||
server.type,
|
||||
)?.({ ...args, apiClientProps: { ...args.apiClientProps, server } });
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import { authenticationFailure } from '/@/renderer/api/utils';
|
|||
import { useAuthStore } from '/@/renderer/store';
|
||||
import { jfType } from '/@/shared/api/jellyfin/jellyfin-types';
|
||||
import { getClientType } from '/@/shared/api/utils';
|
||||
import { ServerListItem } from '/@/shared/types/domain-types';
|
||||
import { ServerListItemWithCredential } from '/@/shared/types/domain-types';
|
||||
|
||||
const c = initContract();
|
||||
|
||||
|
|
@ -359,7 +359,7 @@ export const createAuthHeader = (): string => {
|
|||
};
|
||||
|
||||
export const jfApiClient = (args: {
|
||||
server: null | ServerListItem;
|
||||
server: null | ServerListItemWithCredential;
|
||||
signal?: AbortSignal;
|
||||
url?: string;
|
||||
}) => {
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ import { getFeatures, hasFeature, VersionInfo } from '/@/shared/api/utils';
|
|||
import {
|
||||
albumArtistListSortMap,
|
||||
albumListSortMap,
|
||||
ControllerEndpoint,
|
||||
genreListSortMap,
|
||||
InternalControllerEndpoint,
|
||||
LibraryItem,
|
||||
Played,
|
||||
playlistListSortMap,
|
||||
|
|
@ -40,7 +40,7 @@ const VERSION_INFO: VersionInfo = [
|
|||
['10.0.0', { [ServerFeature.TAGS]: [1] }],
|
||||
];
|
||||
|
||||
export const JellyfinController: ControllerEndpoint = {
|
||||
export const JellyfinController: InternalControllerEndpoint = {
|
||||
addToPlaylist: async (args) => {
|
||||
const { apiClientProps, body, query } = args;
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import { useAuthStore } from '/@/renderer/store';
|
|||
import { ndType } from '/@/shared/api/navidrome/navidrome-types';
|
||||
import { resultWithHeaders } from '/@/shared/api/utils';
|
||||
import { toast } from '/@/shared/components/toast/toast';
|
||||
import { ServerListItem } from '/@/shared/types/domain-types';
|
||||
import { ServerListItemWithCredential } from '/@/shared/types/domain-types';
|
||||
|
||||
const localSettings = isElectron() ? window.api.localSettings : null;
|
||||
|
||||
|
|
@ -379,7 +379,7 @@ axiosClient.interceptors.response.use(
|
|||
);
|
||||
|
||||
export const ndApiClient = (args: {
|
||||
server: null | ServerListItem;
|
||||
server: null | ServerListItemWithCredential;
|
||||
signal?: AbortSignal;
|
||||
url?: string;
|
||||
}) => {
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@ import {
|
|||
albumArtistListSortMap,
|
||||
albumListSortMap,
|
||||
AuthenticationResponse,
|
||||
ControllerEndpoint,
|
||||
genreListSortMap,
|
||||
InternalControllerEndpoint,
|
||||
playlistListSortMap,
|
||||
PlaylistSongListArgs,
|
||||
PlaylistSongListResponse,
|
||||
ServerListItem,
|
||||
ServerListItemWithCredential,
|
||||
Song,
|
||||
songListSortMap,
|
||||
sortOrderMap,
|
||||
|
|
@ -47,7 +47,11 @@ const NAVIDROME_ROLES: Array<string | { label: string; value: string }> = [
|
|||
|
||||
const EXCLUDED_TAGS = new Set<string>(['disctotal', 'genre', 'tracktotal']);
|
||||
|
||||
const excludeMissing = (server: null | ServerListItem) => {
|
||||
const excludeMissing = (server?: null | ServerListItemWithCredential) => {
|
||||
if (!server) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (hasFeature(server, ServerFeature.BFR)) {
|
||||
return { missing: false };
|
||||
}
|
||||
|
|
@ -55,10 +59,10 @@ const excludeMissing = (server: null | ServerListItem) => {
|
|||
return undefined;
|
||||
};
|
||||
|
||||
const getArtistSongKey = (server: null | ServerListItem) =>
|
||||
const getArtistSongKey = (server: null | ServerListItemWithCredential) =>
|
||||
hasFeature(server, ServerFeature.TRACK_ALBUM_ARTIST_SEARCH) ? 'artists_id' : 'album_artist_id';
|
||||
|
||||
export const NavidromeController: ControllerEndpoint = {
|
||||
export const NavidromeController: InternalControllerEndpoint = {
|
||||
addToPlaylist: async (args) => {
|
||||
const { apiClientProps, body, query } = args;
|
||||
|
||||
|
|
@ -156,7 +160,7 @@ export const NavidromeController: ControllerEndpoint = {
|
|||
throw new Error('Failed to get album artist detail');
|
||||
}
|
||||
|
||||
if (!apiClientProps.server) {
|
||||
if (!apiClientProps.serverId) {
|
||||
throw new Error('Server is required');
|
||||
}
|
||||
|
||||
|
|
@ -431,7 +435,7 @@ export const NavidromeController: ControllerEndpoint = {
|
|||
getPlaylistSongList: async (args: PlaylistSongListArgs): Promise<PlaylistSongListResponse> => {
|
||||
const { apiClientProps, query } = args;
|
||||
|
||||
const res = await ndApiClient(apiClientProps).getPlaylistSongList({
|
||||
const res = await ndApiClient(apiClientProps as any).getPlaylistSongList({
|
||||
params: {
|
||||
id: query.id,
|
||||
},
|
||||
|
|
@ -481,7 +485,7 @@ export const NavidromeController: ControllerEndpoint = {
|
|||
|
||||
return {
|
||||
features,
|
||||
id: apiClientProps.server?.id,
|
||||
id: apiClientProps.serverId,
|
||||
version: ping.body.serverVersion!,
|
||||
};
|
||||
},
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { z } from 'zod';
|
|||
import i18n from '/@/i18n/i18n';
|
||||
import { ssType } from '/@/shared/api/subsonic/subsonic-types';
|
||||
import { toast } from '/@/shared/components/toast/toast';
|
||||
import { ServerListItem } from '/@/shared/types/domain-types';
|
||||
import { ServerListItemWithCredential } from '/@/shared/types/domain-types';
|
||||
|
||||
const c = initContract();
|
||||
|
||||
|
|
@ -288,7 +288,7 @@ const silentlyTransformResponse = (data: any) => {
|
|||
};
|
||||
|
||||
export const ssApiClient = (args: {
|
||||
server: null | ServerListItem;
|
||||
server: null | ServerListItemWithCredential;
|
||||
signal?: AbortSignal;
|
||||
silent?: boolean;
|
||||
url?: string;
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ import {
|
|||
} from '/@/shared/api/subsonic/subsonic-types';
|
||||
import {
|
||||
AlbumListSort,
|
||||
ControllerEndpoint,
|
||||
GenreListSort,
|
||||
InternalControllerEndpoint,
|
||||
LibraryItem,
|
||||
PlaylistListSort,
|
||||
Song,
|
||||
|
|
@ -51,7 +51,7 @@ const MAX_SUBSONIC_ITEMS = 500;
|
|||
// A trick to skip ahead 10x
|
||||
const SUBSONIC_FAST_BATCH_SIZE = MAX_SUBSONIC_ITEMS * 10;
|
||||
|
||||
export const SubsonicController: ControllerEndpoint = {
|
||||
export const SubsonicController: InternalControllerEndpoint = {
|
||||
addToPlaylist: async ({ apiClientProps, body, query }) => {
|
||||
const res = await ssApiClient(apiClientProps).updatePlaylist({
|
||||
query: {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import {
|
|||
gaplessHandler,
|
||||
} from '/@/renderer/components/audio-player/utils/list-handlers';
|
||||
import { useWebAudio } from '/@/renderer/features/player/hooks/use-webaudio';
|
||||
import { getServerById, TranscodingConfig, usePlaybackSettings, useSpeed } from '/@/renderer/store';
|
||||
import { TranscodingConfig, usePlaybackSettings, useSpeed } from '/@/renderer/store';
|
||||
import { useSettingsStore, useSettingsStoreActions } from '/@/renderer/store/settings.store';
|
||||
import { toast } from '/@/shared/components/toast/toast';
|
||||
import { PlaybackStyle, PlayerStatus } from '/@/shared/types/types';
|
||||
|
|
@ -76,7 +76,7 @@ const useSongUrl = (transcode: TranscodingConfig, current: boolean, song?: Song)
|
|||
|
||||
const result = api.controller.getTranscodingUrl({
|
||||
apiClientProps: {
|
||||
server: getServerById(song.serverId),
|
||||
serverId: song.serverId,
|
||||
},
|
||||
query: {
|
||||
base: song.streamUrl,
|
||||
|
|
|
|||
|
|
@ -142,19 +142,19 @@ export const SwiperGridCarousel = ({
|
|||
const { id, isFavorite, itemType, serverId } = options;
|
||||
if (isFavorite) {
|
||||
deleteFavoriteMutation.mutate({
|
||||
apiClientProps: { serverId },
|
||||
query: {
|
||||
id,
|
||||
type: itemType,
|
||||
},
|
||||
serverId,
|
||||
});
|
||||
} else {
|
||||
createFavoriteMutation.mutate({
|
||||
apiClientProps: { serverId },
|
||||
query: {
|
||||
id,
|
||||
type: itemType,
|
||||
},
|
||||
serverId,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -15,11 +15,11 @@ export const FavoriteCell = ({ data, node, value }: ICellRendererParams) => {
|
|||
if (newFavoriteValue) {
|
||||
createMutation.mutate(
|
||||
{
|
||||
apiClientProps: { serverId: data.serverId },
|
||||
query: {
|
||||
id: [data.id],
|
||||
type: data.itemType,
|
||||
},
|
||||
serverId: data.serverId,
|
||||
},
|
||||
{
|
||||
onSuccess: () => {
|
||||
|
|
@ -30,11 +30,11 @@ export const FavoriteCell = ({ data, node, value }: ICellRendererParams) => {
|
|||
} else {
|
||||
deleteMutation.mutate(
|
||||
{
|
||||
apiClientProps: { serverId: data.serverId },
|
||||
query: {
|
||||
id: [data.id],
|
||||
type: data.itemType,
|
||||
},
|
||||
serverId: data.serverId,
|
||||
},
|
||||
{
|
||||
onSuccess: () => {
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ export const RatingCell = ({ node, value }: ICellRendererParams) => {
|
|||
const handleUpdateRating = (rating: number) => {
|
||||
updateRatingMutation.mutate(
|
||||
{
|
||||
apiClientProps: { serverId: value?.serverId || '' },
|
||||
query: {
|
||||
item: [value],
|
||||
rating,
|
||||
},
|
||||
serverId: value?.serverId,
|
||||
},
|
||||
{
|
||||
onSuccess: () => {
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ export const useVirtualTable = <TFilter extends BaseQuery<any>>({
|
|||
queryFn: async ({ signal }) => {
|
||||
const res = await queryFn!({
|
||||
apiClientProps: {
|
||||
server,
|
||||
serverId: server?.id || '',
|
||||
signal,
|
||||
},
|
||||
query: {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,11 @@ import { Icon } from '/@/shared/components/icon/icon';
|
|||
import { ScrollArea } from '/@/shared/components/scroll-area/scroll-area';
|
||||
import { Stack } from '/@/shared/components/stack/stack';
|
||||
import { Text } from '/@/shared/components/text/text';
|
||||
import { ServerListItem, ServerType } from '/@/shared/types/domain-types';
|
||||
import {
|
||||
ServerListItem,
|
||||
ServerListItemWithCredential,
|
||||
ServerType,
|
||||
} from '/@/shared/types/domain-types';
|
||||
|
||||
const localSettings = isElectron() ? window.api.localSettings : null;
|
||||
|
||||
|
|
@ -69,7 +73,7 @@ function ServerSelector() {
|
|||
const currentServer = useCurrentServer();
|
||||
const { setCurrentServer } = useAuthStoreActions();
|
||||
|
||||
const handleSetCurrentServer = (server: ServerListItem) => {
|
||||
const handleSetCurrentServer = (server: ServerListItemWithCredential) => {
|
||||
navigate(AppRoute.HOME);
|
||||
setCurrentServer(server);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import { ServerRequired } from '/@/renderer/features/action-required/components/
|
|||
import { ServerList } from '/@/renderer/features/servers/components/server-list';
|
||||
import { AnimatedPage } from '/@/renderer/features/shared/components/animated-page';
|
||||
import { AppRoute } from '/@/renderer/router/routes';
|
||||
import { useCurrentServer } from '/@/renderer/store';
|
||||
import { useCurrentServerWithCredential } from '/@/renderer/store';
|
||||
import { Button } from '/@/shared/components/button/button';
|
||||
import { Center } from '/@/shared/components/center/center';
|
||||
import { Group } from '/@/shared/components/group/group';
|
||||
|
|
@ -18,7 +18,7 @@ import { Stack } from '/@/shared/components/stack/stack';
|
|||
|
||||
const ActionRequiredRoute = () => {
|
||||
const { t } = useTranslation();
|
||||
const currentServer = useCurrentServer();
|
||||
const currentServer = useCurrentServerWithCredential();
|
||||
const isServerRequired = !currentServer;
|
||||
const isCredentialRequired = currentServer && !currentServer.credential;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import { queryOptions } from '@tanstack/react-query';
|
|||
import { api } from '/@/renderer/api';
|
||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import { QueryHookArgs } from '/@/renderer/lib/react-query';
|
||||
import { getServerById } from '/@/renderer/store';
|
||||
import { AlbumDetailQuery, AlbumListQuery, ListCountQuery } from '/@/shared/types/domain-types';
|
||||
|
||||
export const albumQueries = {
|
||||
|
|
@ -11,7 +10,7 @@ export const albumQueries = {
|
|||
return queryOptions({
|
||||
queryFn: ({ signal }) => {
|
||||
return api.controller.getAlbumDetail({
|
||||
apiClientProps: { server: getServerById(args.serverId), signal },
|
||||
apiClientProps: { serverId: args.serverId, signal },
|
||||
query: args.query,
|
||||
});
|
||||
},
|
||||
|
|
@ -23,7 +22,7 @@ export const albumQueries = {
|
|||
return queryOptions({
|
||||
queryFn: ({ signal }) => {
|
||||
return api.controller.getAlbumList({
|
||||
apiClientProps: { server: getServerById(args.serverId), signal },
|
||||
apiClientProps: { serverId: args.serverId, signal },
|
||||
query: args.query,
|
||||
});
|
||||
},
|
||||
|
|
@ -39,7 +38,7 @@ export const albumQueries = {
|
|||
return queryOptions({
|
||||
queryFn: ({ signal }) => {
|
||||
return api.controller.getAlbumListCount({
|
||||
apiClientProps: { server: getServerById(args.serverId), signal },
|
||||
apiClientProps: { serverId: args.serverId, signal },
|
||||
query: args.query,
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -290,19 +290,19 @@ export const AlbumDetailContent = ({ background, tableRef }: AlbumDetailContentP
|
|||
|
||||
if (detailQuery.data.userFavorite) {
|
||||
deleteFavoriteMutation.mutate({
|
||||
apiClientProps: { serverId: detailQuery.data.serverId },
|
||||
query: {
|
||||
id: [detailQuery.data.id],
|
||||
type: LibraryItem.ALBUM,
|
||||
},
|
||||
serverId: detailQuery.data.serverId,
|
||||
});
|
||||
} else {
|
||||
createFavoriteMutation.mutate({
|
||||
apiClientProps: { serverId: detailQuery.data.serverId },
|
||||
query: {
|
||||
id: [detailQuery.data.id],
|
||||
type: LibraryItem.ALBUM,
|
||||
},
|
||||
serverId: detailQuery.data.serverId,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -118,11 +118,11 @@ export const AlbumDetailHeader = forwardRef(
|
|||
if (!detailQuery?.data) return;
|
||||
|
||||
updateRatingMutation.mutate({
|
||||
apiClientProps: { serverId: detailQuery.data.serverId },
|
||||
query: {
|
||||
item: [detailQuery.data],
|
||||
rating,
|
||||
},
|
||||
serverId: detailQuery.data.serverId,
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ export const AlbumListGridView = ({ gridRef, itemCount }: any) => {
|
|||
const scrollOffset = searchParams.get('scrollOffset');
|
||||
const initialScrollOffset = Number(id ? scrollOffset : grid?.scrollOffset) || 0;
|
||||
|
||||
const handleFavorite = useHandleFavorite({ gridRef, server });
|
||||
const handleFavorite = useHandleFavorite({ gridRef });
|
||||
|
||||
const cardRows = useMemo(() => {
|
||||
const rows: CardRow<Album>[] = [ALBUM_CARD_ROWS.name];
|
||||
|
|
@ -177,7 +177,7 @@ export const AlbumListGridView = ({ gridRef, itemCount }: any) => {
|
|||
queryFn: async ({ signal }) =>
|
||||
controller.getAlbumList({
|
||||
apiClientProps: {
|
||||
server,
|
||||
serverId: server?.id || '',
|
||||
signal,
|
||||
},
|
||||
query,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { genresQueries } from '/@/renderer/features/genres/api/genres-api';
|
|||
import { sharedQueries } from '/@/renderer/features/shared/api/shared-api';
|
||||
import {
|
||||
AlbumListFilter,
|
||||
getServerById,
|
||||
useCurrentServer,
|
||||
useListStoreActions,
|
||||
useListStoreByKey,
|
||||
} from '/@/renderer/store';
|
||||
|
|
@ -53,7 +53,7 @@ export const NavidromeAlbumFilters = ({
|
|||
const { t } = useTranslation();
|
||||
const { filter } = useListStoreByKey<AlbumListQuery>({ key: pageKey });
|
||||
const { setFilter } = useListStoreActions();
|
||||
const server = getServerById(serverId);
|
||||
const server = useCurrentServer();
|
||||
|
||||
const genreListQuery = useQuery(
|
||||
genresQueries.list({
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ const AlbumListRoute = () => {
|
|||
const albumListRes = await queryClient.fetchQuery({
|
||||
queryFn: ({ signal }) => {
|
||||
return api.controller.getAlbumList({
|
||||
apiClientProps: { server, signal },
|
||||
apiClientProps: { serverId: server?.id || '', signal },
|
||||
query,
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -42,9 +42,8 @@ const DummyAlbumDetailRoute = () => {
|
|||
const queryKey = queryKeys.songs.detail(server?.id || '', albumId);
|
||||
const detailQuery = useQuery({
|
||||
queryFn: ({ signal }) => {
|
||||
if (!server) throw new Error('Server not found');
|
||||
return api.controller.getSongDetail({
|
||||
apiClientProps: { server, signal },
|
||||
apiClientProps: { serverId: server?.id || '', signal },
|
||||
query: { id: albumId },
|
||||
});
|
||||
},
|
||||
|
|
@ -70,19 +69,19 @@ const DummyAlbumDetailRoute = () => {
|
|||
try {
|
||||
if (wasFavorite) {
|
||||
await deleteFavoriteMutation.mutateAsync({
|
||||
apiClientProps: { serverId: detailQuery.data.serverId },
|
||||
query: {
|
||||
id: [detailQuery.data.id],
|
||||
type: LibraryItem.SONG,
|
||||
},
|
||||
serverId: detailQuery.data.serverId,
|
||||
});
|
||||
} else {
|
||||
await createFavoriteMutation.mutateAsync({
|
||||
apiClientProps: { serverId: detailQuery.data.serverId },
|
||||
query: {
|
||||
id: [detailQuery.data.id],
|
||||
type: LibraryItem.SONG,
|
||||
},
|
||||
serverId: detailQuery.data.serverId,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import { queryOptions } from '@tanstack/react-query';
|
|||
import { api } from '/@/renderer/api';
|
||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import { QueryHookArgs } from '/@/renderer/lib/react-query';
|
||||
import { getServerById } from '/@/renderer/store';
|
||||
import {
|
||||
AlbumArtistDetailQuery,
|
||||
AlbumArtistListQuery,
|
||||
|
|
@ -17,11 +16,11 @@ export const artistsQueries = {
|
|||
return queryOptions({
|
||||
queryFn: ({ signal }) => {
|
||||
return api.controller.getAlbumArtistDetail({
|
||||
apiClientProps: { server: getServerById(args.serverId), signal },
|
||||
apiClientProps: { serverId: args.serverId, signal },
|
||||
query: args.query,
|
||||
});
|
||||
},
|
||||
queryKey: queryKeys.albumArtists.detail(args.serverId || '', args.query),
|
||||
queryKey: queryKeys.albumArtists.detail(args.serverId, args.query),
|
||||
...args.options,
|
||||
});
|
||||
},
|
||||
|
|
@ -29,11 +28,11 @@ export const artistsQueries = {
|
|||
return queryOptions({
|
||||
queryFn: ({ signal }) => {
|
||||
return api.controller.getAlbumArtistList({
|
||||
apiClientProps: { server: getServerById(args.serverId), signal },
|
||||
apiClientProps: { serverId: args.serverId, signal },
|
||||
query: args.query,
|
||||
});
|
||||
},
|
||||
queryKey: queryKeys.albumArtists.list(args.serverId || '', args.query),
|
||||
queryKey: queryKeys.albumArtists.list(args.serverId, args.query),
|
||||
...args.options,
|
||||
});
|
||||
},
|
||||
|
|
@ -41,12 +40,12 @@ export const artistsQueries = {
|
|||
return queryOptions({
|
||||
queryFn: ({ signal }) => {
|
||||
return api.controller.getAlbumArtistListCount({
|
||||
apiClientProps: { server: getServerById(args.serverId), signal },
|
||||
apiClientProps: { serverId: args.serverId, signal },
|
||||
query: args.query,
|
||||
});
|
||||
},
|
||||
queryKey: queryKeys.albumArtists.count(
|
||||
args.serverId || '',
|
||||
args.serverId,
|
||||
Object.keys(args.query).length === 0 ? undefined : args.query,
|
||||
),
|
||||
...args.options,
|
||||
|
|
@ -56,12 +55,12 @@ export const artistsQueries = {
|
|||
return queryOptions({
|
||||
queryFn: ({ signal }) => {
|
||||
return api.controller.getArtistListCount({
|
||||
apiClientProps: { server: getServerById(args.serverId), signal },
|
||||
apiClientProps: { serverId: args.serverId, signal },
|
||||
query: args.query,
|
||||
});
|
||||
},
|
||||
queryKey: queryKeys.albumArtists.count(
|
||||
args.serverId || '',
|
||||
args.serverId,
|
||||
Object.keys(args.query).length === 0 ? undefined : args.query,
|
||||
),
|
||||
...args.options,
|
||||
|
|
@ -71,11 +70,11 @@ export const artistsQueries = {
|
|||
return queryOptions({
|
||||
queryFn: ({ signal }) => {
|
||||
return api.controller.getTopSongs({
|
||||
apiClientProps: { server: getServerById(args.serverId), signal },
|
||||
apiClientProps: { serverId: args.serverId, signal },
|
||||
query: args.query,
|
||||
});
|
||||
},
|
||||
queryKey: queryKeys.albumArtists.topSongs(args.serverId || '', args.query),
|
||||
queryKey: queryKeys.albumArtists.topSongs(args.serverId, args.query),
|
||||
...args.options,
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -311,19 +311,19 @@ export const AlbumArtistDetailContent = ({ background }: AlbumArtistDetailConten
|
|||
|
||||
if (detailQuery.data.userFavorite) {
|
||||
deleteFavoriteMutation.mutate({
|
||||
apiClientProps: { serverId: detailQuery.data.serverId },
|
||||
query: {
|
||||
id: [detailQuery.data.id],
|
||||
type: LibraryItem.ALBUM_ARTIST,
|
||||
},
|
||||
serverId: detailQuery.data.serverId,
|
||||
});
|
||||
} else {
|
||||
createFavoriteMutation.mutate({
|
||||
apiClientProps: { serverId: detailQuery.data.serverId },
|
||||
query: {
|
||||
id: [detailQuery.data.id],
|
||||
type: LibraryItem.ALBUM_ARTIST,
|
||||
},
|
||||
serverId: detailQuery.data.serverId,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -71,11 +71,11 @@ export const AlbumArtistDetailHeader = forwardRef(
|
|||
if (!detailQuery?.data) return;
|
||||
|
||||
updateRatingMutation.mutate({
|
||||
apiClientProps: { serverId: detailQuery?.data.serverId },
|
||||
query: {
|
||||
item: [detailQuery.data],
|
||||
rating,
|
||||
},
|
||||
serverId: detailQuery?.data.serverId,
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ export const AlbumArtistListGridView = ({ gridRef, itemCount }: AlbumArtistListG
|
|||
const { pageKey } = useListContext();
|
||||
const { display, filter, grid } = useListStoreByKey<AlbumArtistListQuery>({ key: pageKey });
|
||||
const { setGrid } = useListStoreActions();
|
||||
const handleFavorite = useHandleFavorite({ gridRef, server });
|
||||
const handleFavorite = useHandleFavorite({ gridRef });
|
||||
|
||||
const fetchInitialData = useCallback(() => {
|
||||
const query: Omit<AlbumArtistListQuery, 'limit' | 'startIndex'> = {
|
||||
|
|
@ -89,7 +89,7 @@ export const AlbumArtistListGridView = ({ gridRef, itemCount }: AlbumArtistListG
|
|||
queryFn: async ({ signal }) =>
|
||||
api.controller.getAlbumArtistList({
|
||||
apiClientProps: {
|
||||
server,
|
||||
serverId: server?.id || '',
|
||||
signal,
|
||||
},
|
||||
query,
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ export const AlbumArtistListHeaderFilters = ({
|
|||
queryFn: async ({ signal }) =>
|
||||
api.controller.getAlbumArtistList({
|
||||
apiClientProps: {
|
||||
server,
|
||||
serverId: server?.id || '',
|
||||
signal,
|
||||
},
|
||||
query: {
|
||||
|
|
@ -220,7 +220,7 @@ export const AlbumArtistListHeaderFilters = ({
|
|||
queryFn: async ({ signal }) =>
|
||||
api.controller.getAlbumArtistList({
|
||||
apiClientProps: {
|
||||
server,
|
||||
serverId: server?.id || '',
|
||||
signal,
|
||||
},
|
||||
query: {
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ export const ArtistListGridView = ({ gridRef, itemCount }: ArtistListGridViewPro
|
|||
const { pageKey } = useListContext();
|
||||
const { display, filter, grid } = useListStoreByKey<ArtistListQuery>({ key: pageKey });
|
||||
const { setGrid } = useListStoreActions();
|
||||
const handleFavorite = useHandleFavorite({ gridRef, server });
|
||||
const handleFavorite = useHandleFavorite({ gridRef });
|
||||
|
||||
const fetchInitialData = useCallback(() => {
|
||||
const query: Omit<ArtistListQuery, 'limit' | 'startIndex'> = {
|
||||
|
|
@ -90,7 +90,7 @@ export const ArtistListGridView = ({ gridRef, itemCount }: ArtistListGridViewPro
|
|||
queryFn: async ({ signal }) =>
|
||||
api.controller.getArtistList({
|
||||
apiClientProps: {
|
||||
server,
|
||||
serverId: server?.id || '',
|
||||
signal,
|
||||
},
|
||||
query,
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ export const ArtistListHeaderFilters = ({ gridRef, tableRef }: ArtistListHeaderF
|
|||
queryFn: async ({ signal }) =>
|
||||
api.controller.getArtistList({
|
||||
apiClientProps: {
|
||||
server,
|
||||
serverId: server?.id || '',
|
||||
signal,
|
||||
},
|
||||
query: {
|
||||
|
|
@ -227,7 +227,7 @@ export const ArtistListHeaderFilters = ({ gridRef, tableRef }: ArtistListHeaderF
|
|||
queryFn: async ({ signal }) =>
|
||||
api.controller.getArtistList({
|
||||
apiClientProps: {
|
||||
server,
|
||||
serverId: server?.id || '',
|
||||
signal,
|
||||
},
|
||||
query: {
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ import { useDeleteFavorite } from '/@/renderer/features/shared/mutations/delete-
|
|||
import { useSetRating } from '/@/renderer/features/shared/mutations/set-rating-mutation';
|
||||
import { AppRoute } from '/@/renderer/router/routes';
|
||||
import {
|
||||
getServerById,
|
||||
useAuthStore,
|
||||
useCurrentServer,
|
||||
usePlayerStore,
|
||||
|
|
@ -260,7 +259,7 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
|
|||
const handleDeletePlaylist = useCallback(() => {
|
||||
for (const item of ctx.data) {
|
||||
deletePlaylistMutation?.mutate(
|
||||
{ query: { id: item.id }, serverId: item.serverId },
|
||||
{ apiClientProps: { serverId: item.serverId }, query: { id: item.id } },
|
||||
{
|
||||
onError: (err) => {
|
||||
toast.error({
|
||||
|
|
@ -330,11 +329,11 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
|
|||
|
||||
createFavoriteMutation.mutate(
|
||||
{
|
||||
apiClientProps: { serverId },
|
||||
query: {
|
||||
id: items.map((item) => item.id),
|
||||
type: ctx.type,
|
||||
},
|
||||
serverId,
|
||||
},
|
||||
{
|
||||
onError: (err) => {
|
||||
|
|
@ -369,11 +368,11 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
|
|||
|
||||
createFavoriteMutation.mutate(
|
||||
{
|
||||
apiClientProps: { serverId },
|
||||
query: {
|
||||
id: items.map((item: AnyLibraryItem) => item.id),
|
||||
type: ctx.type,
|
||||
},
|
||||
serverId,
|
||||
},
|
||||
{
|
||||
onError: (err) => {
|
||||
|
|
@ -408,11 +407,11 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
|
|||
const idsToUnfavorite = nodesByServerId[serverId].map((node) => node.data.id);
|
||||
deleteFavoriteMutation.mutate(
|
||||
{
|
||||
apiClientProps: { serverId },
|
||||
query: {
|
||||
id: idsToUnfavorite,
|
||||
type: ctx.type,
|
||||
},
|
||||
serverId,
|
||||
},
|
||||
{
|
||||
onSuccess: () => {
|
||||
|
|
@ -441,11 +440,11 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
|
|||
(item: AnyLibraryItem) => item.id,
|
||||
);
|
||||
deleteFavoriteMutation.mutate({
|
||||
apiClientProps: { serverId },
|
||||
query: {
|
||||
id: idsToUnfavorite,
|
||||
type: ctx.type,
|
||||
},
|
||||
serverId,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -529,11 +528,11 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
|
|||
const confirm = () => {
|
||||
removeFromPlaylistMutation.mutate(
|
||||
{
|
||||
apiClientProps: { serverId: ctx.data?.[0]?.serverId },
|
||||
query: {
|
||||
id: ctx.context.playlistId,
|
||||
songId: songId || [],
|
||||
},
|
||||
serverId: ctx.data?.[0]?.serverId,
|
||||
},
|
||||
{
|
||||
onError: (err) => {
|
||||
|
|
@ -604,11 +603,11 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
|
|||
|
||||
updateRatingMutation.mutate(
|
||||
{
|
||||
apiClientProps: { serverId },
|
||||
query: {
|
||||
item: items,
|
||||
rating: ratingToSet,
|
||||
},
|
||||
serverId,
|
||||
},
|
||||
{
|
||||
onSuccess: () => {
|
||||
|
|
@ -719,7 +718,7 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
|
|||
const item = ctx.data[0];
|
||||
const songs = await controller.getSimilarSongs({
|
||||
apiClientProps: {
|
||||
server: getServerById(item.serverId),
|
||||
serverId: item.serverId,
|
||||
signal: undefined,
|
||||
},
|
||||
query: { albumArtistIds: item.albumArtistIds, songId: item.id },
|
||||
|
|
@ -732,7 +731,7 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
|
|||
const handleDownload = useCallback(() => {
|
||||
const item = ctx.data[0];
|
||||
const url = api.controller.getDownloadUrl({
|
||||
apiClientProps: { server },
|
||||
apiClientProps: { serverId: item.serverId },
|
||||
query: { id: item.id },
|
||||
});
|
||||
|
||||
|
|
@ -741,7 +740,7 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
|
|||
} else {
|
||||
window.open(url, '_blank');
|
||||
}
|
||||
}, [ctx.data, server]);
|
||||
}, [ctx.data]);
|
||||
|
||||
const handleGoToAlbum = useCallback(() => {
|
||||
const item = ctx.data[0];
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import { controller } from '/@/renderer/api/controller';
|
|||
import {
|
||||
DiscordDisplayType,
|
||||
DiscordLinkType,
|
||||
getServerById,
|
||||
useAppStore,
|
||||
useDiscordSettings,
|
||||
useGeneralSettings,
|
||||
|
|
@ -123,11 +122,9 @@ export const useDiscordRpc = () => {
|
|||
if (song.serverType === ServerType.JELLYFIN && song.imageUrl) {
|
||||
activity.largeImageKey = song.imageUrl;
|
||||
} else if (song.serverType === ServerType.NAVIDROME) {
|
||||
const server = getServerById(song.serverId);
|
||||
|
||||
try {
|
||||
const info = await controller.getAlbumInfo({
|
||||
apiClientProps: { server },
|
||||
apiClientProps: { serverId: song.serverId },
|
||||
query: { id: song.albumId },
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import { queryOptions } from '@tanstack/react-query';
|
|||
import { api } from '/@/renderer/api';
|
||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import { QueryHookArgs } from '/@/renderer/lib/react-query';
|
||||
import { getServerById } from '/@/renderer/store';
|
||||
import { GenreListQuery } from '/@/shared/types/domain-types';
|
||||
|
||||
export const genresQueries = {
|
||||
|
|
@ -11,14 +10,12 @@ export const genresQueries = {
|
|||
return queryOptions({
|
||||
gcTime: 1000 * 5,
|
||||
queryFn: ({ signal }) => {
|
||||
const server = getServerById(args.serverId);
|
||||
if (!server) throw new Error('Server not found');
|
||||
return api.controller.getGenreList({
|
||||
apiClientProps: { server, signal },
|
||||
apiClientProps: { serverId: args.serverId, signal },
|
||||
query: args.query,
|
||||
});
|
||||
},
|
||||
queryKey: queryKeys.genres.list(args.serverId || '', args.query),
|
||||
queryKey: queryKeys.genres.list(args.serverId, args.query),
|
||||
...args.options,
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ export const GenreListGridView = ({ gridRef, itemCount }: any) => {
|
|||
queryFn: async ({ signal }) => {
|
||||
return api.controller.getGenreList({
|
||||
apiClientProps: {
|
||||
server,
|
||||
serverId: server?.id || '',
|
||||
signal,
|
||||
},
|
||||
query,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import { queryOptions } from '@tanstack/react-query';
|
|||
import { api } from '/@/renderer/api';
|
||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import { QueryHookArgs } from '/@/renderer/lib/react-query';
|
||||
import { getServerById } from '/@/renderer/store';
|
||||
import { AlbumListQuery, AlbumListSort, SortOrder } from '/@/shared/types/domain-types';
|
||||
|
||||
export const homeQueries = {
|
||||
|
|
@ -18,14 +17,12 @@ export const homeQueries = {
|
|||
|
||||
return queryOptions({
|
||||
queryFn: ({ signal }) => {
|
||||
const server = getServerById(args.serverId);
|
||||
if (!server) throw new Error('Server not found');
|
||||
return api.controller.getAlbumList({
|
||||
apiClientProps: { server, signal },
|
||||
apiClientProps: { serverId: args.serverId, signal },
|
||||
query: requestQuery,
|
||||
});
|
||||
},
|
||||
queryKey: queryKeys.albums.list(args.serverId || '', requestQuery),
|
||||
queryKey: queryKeys.albums.list(args.serverId, requestQuery),
|
||||
...args.options,
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -87,11 +87,11 @@ export const lyricsQueries = {
|
|||
// This should only be called for Jellyfin. Return null to ignore errors
|
||||
if (server.type !== ServerType.JELLYFIN) return null;
|
||||
return api.controller.getLyrics({
|
||||
apiClientProps: { server, signal },
|
||||
apiClientProps: { serverId: args.serverId, signal },
|
||||
query: args.query,
|
||||
});
|
||||
},
|
||||
queryKey: queryKeys.songs.lyrics(args.serverId || '', args.query),
|
||||
queryKey: queryKeys.songs.lyrics(args.serverId, args.query),
|
||||
...args.options,
|
||||
});
|
||||
},
|
||||
|
|
@ -111,7 +111,7 @@ export const lyricsQueries = {
|
|||
if (hasFeature(server, ServerFeature.LYRICS_MULTIPLE_STRUCTURED)) {
|
||||
const subsonicLyrics = await api.controller
|
||||
.getStructuredLyrics({
|
||||
apiClientProps: { server, signal },
|
||||
apiClientProps: { serverId: args.serverId, signal },
|
||||
query: { songId: song.id },
|
||||
})
|
||||
.catch(console.error);
|
||||
|
|
@ -122,7 +122,7 @@ export const lyricsQueries = {
|
|||
} else if (hasFeature(server, ServerFeature.LYRICS_SINGLE_STRUCTURED)) {
|
||||
const jfLyrics = await api.controller
|
||||
.getLyrics({
|
||||
apiClientProps: { server, signal },
|
||||
apiClientProps: { serverId: args.serverId, signal },
|
||||
query: { songId: song.id },
|
||||
})
|
||||
.catch((err) => console.error(err));
|
||||
|
|
@ -175,7 +175,7 @@ export const lyricsQueries = {
|
|||
|
||||
return null;
|
||||
},
|
||||
queryKey: queryKeys.songs.lyrics(args.serverId || '', args.query),
|
||||
queryKey: queryKeys.songs.lyrics(args.serverId, args.query),
|
||||
staleTime: Infinity,
|
||||
...args.options,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -62,11 +62,11 @@ export const RightControls = () => {
|
|||
if (!song?.id) return;
|
||||
|
||||
addToFavoritesMutation.mutate({
|
||||
apiClientProps: { serverId: song?.serverId || '' },
|
||||
query: {
|
||||
id: [song.id],
|
||||
type: LibraryItem.SONG,
|
||||
},
|
||||
serverId: song?.serverId,
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -74,11 +74,11 @@ export const RightControls = () => {
|
|||
if (!currentSong) return;
|
||||
|
||||
updateRatingMutation.mutate({
|
||||
apiClientProps: { serverId: currentSong?.serverId || '' },
|
||||
query: {
|
||||
item: [currentSong],
|
||||
rating,
|
||||
},
|
||||
serverId: currentSong?.serverId,
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -86,11 +86,11 @@ export const RightControls = () => {
|
|||
if (!song?.id) return;
|
||||
|
||||
removeFromFavoritesMutation.mutate({
|
||||
apiClientProps: { serverId: song?.serverId || '' },
|
||||
query: {
|
||||
id: [song.id],
|
||||
type: LibraryItem.SONG,
|
||||
},
|
||||
serverId: song?.serverId,
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -163,16 +163,17 @@ export const RightControls = () => {
|
|||
remote.requestFavorite((_event, { favorite, id, serverId }) => {
|
||||
const mutator = favorite ? addToFavoritesMutation : removeFromFavoritesMutation;
|
||||
mutator.mutate({
|
||||
apiClientProps: { serverId },
|
||||
query: {
|
||||
id: [id],
|
||||
type: LibraryItem.SONG,
|
||||
},
|
||||
serverId,
|
||||
});
|
||||
});
|
||||
|
||||
remote.requestRating((_event, { id, rating, serverId }) => {
|
||||
updateRatingMutation.mutate({
|
||||
apiClientProps: { serverId },
|
||||
query: {
|
||||
item: [
|
||||
{
|
||||
|
|
@ -183,7 +184,6 @@ export const RightControls = () => {
|
|||
],
|
||||
rating,
|
||||
},
|
||||
serverId,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ export const ShuffleAllModal = ({
|
|||
queryFn: ({ signal }) =>
|
||||
api.controller.getRandomSongList({
|
||||
apiClientProps: {
|
||||
server,
|
||||
serverId: server?.id || '',
|
||||
signal,
|
||||
},
|
||||
query: {
|
||||
|
|
@ -257,7 +257,7 @@ export const openShuffleAllModal = async (
|
|||
queryFn: ({ signal }) =>
|
||||
api.controller.getGenreList({
|
||||
apiClientProps: {
|
||||
server,
|
||||
serverId: server?.id || '',
|
||||
signal,
|
||||
},
|
||||
query: {
|
||||
|
|
@ -275,7 +275,7 @@ export const openShuffleAllModal = async (
|
|||
queryFn: ({ signal }) =>
|
||||
api.controller.getMusicFolderList({
|
||||
apiClientProps: {
|
||||
server,
|
||||
serverId: server?.id || '',
|
||||
signal,
|
||||
},
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -39,22 +39,18 @@ export const useMediaSession = ({
|
|||
}
|
||||
|
||||
mediaSession.setActionHandler('nexttrack', () => {
|
||||
console.log('nexttrack');
|
||||
handleNextTrack();
|
||||
});
|
||||
|
||||
mediaSession.setActionHandler('pause', () => {
|
||||
console.log('pause');
|
||||
handlePause();
|
||||
});
|
||||
|
||||
mediaSession.setActionHandler('play', () => {
|
||||
console.log('play');
|
||||
handlePlay();
|
||||
});
|
||||
|
||||
mediaSession.setActionHandler('previoustrack', () => {
|
||||
console.log('previoustrack');
|
||||
handlePrevTrack();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -75,13 +75,13 @@ export const useScrobble = () => {
|
|||
currentSong?.serverType === ServerType.JELLYFIN ? currentTime * 1e7 : undefined;
|
||||
|
||||
sendScrobble.mutate({
|
||||
apiClientProps: { serverId: currentSong?.serverId || '' },
|
||||
query: {
|
||||
event: 'timeupdate',
|
||||
id: currentSong.id,
|
||||
position,
|
||||
submission: false,
|
||||
},
|
||||
serverId: currentSong?.serverId,
|
||||
});
|
||||
},
|
||||
[isScrobbleEnabled, isPrivateModeEnabled, sendScrobble],
|
||||
|
|
@ -149,12 +149,12 @@ export const useScrobble = () => {
|
|||
: undefined;
|
||||
|
||||
sendScrobble.mutate({
|
||||
apiClientProps: { serverId: previousSong?.serverId || '' },
|
||||
query: {
|
||||
id: previousSong.id,
|
||||
position,
|
||||
submission: true,
|
||||
},
|
||||
serverId: previousSong?.serverId,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -173,13 +173,13 @@ export const useScrobble = () => {
|
|||
// Send start scrobble when song changes and the new song is playing
|
||||
if (currentStatus === PlayerStatus.PLAYING && currentSong?.id) {
|
||||
sendScrobble.mutate({
|
||||
apiClientProps: { serverId: currentSong?.serverId || '' },
|
||||
query: {
|
||||
event: 'start',
|
||||
id: currentSong.id,
|
||||
position: 0,
|
||||
submission: false,
|
||||
},
|
||||
serverId: currentSong?.serverId,
|
||||
});
|
||||
|
||||
if (currentSong?.serverType === ServerType.JELLYFIN) {
|
||||
|
|
@ -228,13 +228,13 @@ export const useScrobble = () => {
|
|||
// Whenever the player is restarted, send a 'start' scrobble
|
||||
if (currentStatus === PlayerStatus.PLAYING) {
|
||||
sendScrobble.mutate({
|
||||
apiClientProps: { serverId: currentSong?.serverId || '' },
|
||||
query: {
|
||||
event: 'unpause',
|
||||
id: currentSong.id,
|
||||
position,
|
||||
submission: false,
|
||||
},
|
||||
serverId: currentSong?.serverId,
|
||||
});
|
||||
|
||||
if (currentSong?.serverType === ServerType.JELLYFIN) {
|
||||
|
|
@ -253,13 +253,13 @@ export const useScrobble = () => {
|
|||
// Jellyfin is the only one that needs to send a 'pause' event to the server
|
||||
} else if (currentSong?.serverType === ServerType.JELLYFIN) {
|
||||
sendScrobble.mutate({
|
||||
apiClientProps: { serverId: currentSong?.serverId || '' },
|
||||
query: {
|
||||
event: 'pause',
|
||||
id: currentSong.id,
|
||||
position,
|
||||
submission: false,
|
||||
},
|
||||
serverId: currentSong?.serverId,
|
||||
});
|
||||
|
||||
if (progressIntervalId.current) {
|
||||
|
|
@ -287,11 +287,11 @@ export const useScrobble = () => {
|
|||
|
||||
if (!isCurrentSongScrobbled && shouldSubmitScrobble) {
|
||||
sendScrobble.mutate({
|
||||
apiClientProps: { serverId: currentSong?.serverId || '' },
|
||||
query: {
|
||||
id: currentSong.id,
|
||||
submission: true,
|
||||
},
|
||||
serverId: currentSong?.serverId,
|
||||
});
|
||||
|
||||
setIsCurrentSongScrobbled(true);
|
||||
|
|
@ -332,24 +332,24 @@ export const useScrobble = () => {
|
|||
|
||||
if (!isCurrentSongScrobbled && shouldSubmitScrobble) {
|
||||
sendScrobble.mutate({
|
||||
apiClientProps: { serverId: currentSong?.serverId || '' },
|
||||
query: {
|
||||
id: currentSong.id,
|
||||
position,
|
||||
submission: true,
|
||||
},
|
||||
serverId: currentSong?.serverId,
|
||||
});
|
||||
}
|
||||
|
||||
if (currentSong?.serverType === ServerType.JELLYFIN) {
|
||||
sendScrobble.mutate({
|
||||
apiClientProps: { serverId: currentSong?.serverId || '' },
|
||||
query: {
|
||||
event: 'start',
|
||||
id: currentSong.id,
|
||||
position: 0,
|
||||
submission: false,
|
||||
},
|
||||
serverId: currentSong?.serverId,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { AxiosError } from 'axios';
|
|||
|
||||
import { api } from '/@/renderer/api';
|
||||
import { MutationOptions } from '/@/renderer/lib/react-query';
|
||||
import { getServerById, useIncrementQueuePlayCount } from '/@/renderer/store';
|
||||
import { useIncrementQueuePlayCount } from '/@/renderer/store';
|
||||
import { usePlayEvent } from '/@/renderer/store/event.store';
|
||||
import { ScrobbleArgs, ScrobbleResponse } from '/@/shared/types/domain-types';
|
||||
|
||||
|
|
@ -11,16 +11,12 @@ export const useSendScrobble = (options?: MutationOptions) => {
|
|||
const incrementPlayCount = useIncrementQueuePlayCount();
|
||||
const sendPlayEvent = usePlayEvent();
|
||||
|
||||
return useMutation<
|
||||
ScrobbleResponse,
|
||||
AxiosError,
|
||||
Omit<ScrobbleArgs, 'apiClientProps' | 'server'>,
|
||||
null
|
||||
>({
|
||||
return useMutation<ScrobbleResponse, AxiosError, ScrobbleArgs, null>({
|
||||
mutationFn: (args) => {
|
||||
const server = getServerById(args.serverId);
|
||||
if (!server) throw new Error('Server not found');
|
||||
return api.controller.scrobble({ ...args, apiClientProps: { server } });
|
||||
return api.controller.scrobble({
|
||||
...args,
|
||||
apiClientProps: { serverId: args.apiClientProps.serverId },
|
||||
});
|
||||
},
|
||||
onSuccess: (_data, variables) => {
|
||||
// Manually increment the play count for the song in the queue if scrobble was submitted
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ export const getPlaylistSongsById = async (args: {
|
|||
queryFn: async ({ signal }) =>
|
||||
api.controller.getPlaylistSongList({
|
||||
apiClientProps: {
|
||||
server,
|
||||
serverId: server?.id || '',
|
||||
signal,
|
||||
},
|
||||
query: queryFilter,
|
||||
|
|
@ -77,7 +77,7 @@ export const getAlbumSongsById = async (args: {
|
|||
queryFn: async ({ signal }) =>
|
||||
api.controller.getSongList({
|
||||
apiClientProps: {
|
||||
server,
|
||||
serverId: server?.id || '',
|
||||
signal,
|
||||
},
|
||||
query: queryFilter,
|
||||
|
|
@ -119,7 +119,7 @@ export const getGenreSongsById = async (args: {
|
|||
queryFn: async ({ signal }) =>
|
||||
api.controller.getSongList({
|
||||
apiClientProps: {
|
||||
server,
|
||||
serverId: server?.id || '',
|
||||
signal,
|
||||
},
|
||||
query: queryFilter,
|
||||
|
|
@ -161,7 +161,7 @@ export const getAlbumArtistSongsById = async (args: {
|
|||
queryFn: async ({ signal }) =>
|
||||
api.controller.getSongList({
|
||||
apiClientProps: {
|
||||
server,
|
||||
serverId: server?.id || '',
|
||||
signal,
|
||||
},
|
||||
query: queryFilter,
|
||||
|
|
@ -196,7 +196,7 @@ export const getArtistSongsById = async (args: {
|
|||
queryFn: async ({ signal }) =>
|
||||
api.controller.getSongList({
|
||||
apiClientProps: {
|
||||
server,
|
||||
serverId: server?.id || '',
|
||||
signal,
|
||||
},
|
||||
query: queryFilter,
|
||||
|
|
@ -229,7 +229,7 @@ export const getSongsByQuery = async (args: {
|
|||
queryFn: async ({ signal }) => {
|
||||
return api.controller.getSongList({
|
||||
apiClientProps: {
|
||||
server,
|
||||
serverId: server?.id || '',
|
||||
signal,
|
||||
},
|
||||
query: queryFilter,
|
||||
|
|
@ -258,7 +258,7 @@ export const getSongById = async (args: {
|
|||
queryFn: async ({ signal }) =>
|
||||
api.controller.getSongDetail({
|
||||
apiClientProps: {
|
||||
server,
|
||||
serverId: server?.id || '',
|
||||
signal,
|
||||
},
|
||||
query: queryFilter,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import { queryOptions } from '@tanstack/react-query';
|
|||
import { api } from '/@/renderer/api';
|
||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import { QueryHookArgs } from '/@/renderer/lib/react-query';
|
||||
import { getServerById } from '/@/renderer/store';
|
||||
import {
|
||||
PlaylistDetailQuery,
|
||||
PlaylistListQuery,
|
||||
|
|
@ -14,14 +13,12 @@ export const playlistsQueries = {
|
|||
detail: (args: QueryHookArgs<PlaylistDetailQuery>) => {
|
||||
return queryOptions({
|
||||
queryFn: ({ signal }) => {
|
||||
const server = getServerById(args.serverId);
|
||||
if (!server) throw new Error('Server not found');
|
||||
return api.controller.getPlaylistDetail({
|
||||
apiClientProps: { server, signal },
|
||||
apiClientProps: { serverId: args.serverId, signal },
|
||||
query: args.query,
|
||||
});
|
||||
},
|
||||
queryKey: queryKeys.playlists.detail(args.serverId || '', args.query.id, args.query),
|
||||
queryKey: queryKeys.playlists.detail(args.serverId, args.query.id, args.query),
|
||||
...args.options,
|
||||
});
|
||||
},
|
||||
|
|
@ -29,10 +26,8 @@ export const playlistsQueries = {
|
|||
return queryOptions({
|
||||
gcTime: 1000 * 60 * 60,
|
||||
queryFn: ({ signal }) => {
|
||||
const server = getServerById(args.serverId);
|
||||
if (!server) throw new Error('Server not found');
|
||||
return api.controller.getPlaylistList({
|
||||
apiClientProps: { server, signal },
|
||||
apiClientProps: { serverId: args.serverId, signal },
|
||||
query: args.query,
|
||||
});
|
||||
},
|
||||
|
|
@ -43,10 +38,8 @@ export const playlistsQueries = {
|
|||
songList: (args: QueryHookArgs<PlaylistSongListQuery>) => {
|
||||
return queryOptions({
|
||||
queryFn: ({ signal }) => {
|
||||
const server = getServerById(args.serverId);
|
||||
if (!server) throw new Error('Server not found');
|
||||
return api.controller.getPlaylistSongList({
|
||||
apiClientProps: { server, signal },
|
||||
apiClientProps: { serverId: args.serverId, signal },
|
||||
query: args.query,
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ export const AddToPlaylistContextModal = ({
|
|||
queryFn: ({ signal }) => {
|
||||
if (!server) throw new Error('No server');
|
||||
return api.controller.getSongList({
|
||||
apiClientProps: { server, signal },
|
||||
apiClientProps: { serverId: server?.id || '', signal },
|
||||
query,
|
||||
});
|
||||
},
|
||||
|
|
@ -147,7 +147,7 @@ export const AddToPlaylistContextModal = ({
|
|||
queryFn: ({ signal }) => {
|
||||
if (!server) throw new Error('No server');
|
||||
return api.controller.getSongList({
|
||||
apiClientProps: { server, signal },
|
||||
apiClientProps: { serverId: server?.id || '', signal },
|
||||
query,
|
||||
});
|
||||
},
|
||||
|
|
@ -203,7 +203,7 @@ export const AddToPlaylistContextModal = ({
|
|||
for (const playlist of values.newPlaylists) {
|
||||
try {
|
||||
const response = await api.controller.createPlaylist({
|
||||
apiClientProps: { server },
|
||||
apiClientProps: { serverId: server?.id || '' },
|
||||
body: {
|
||||
name: playlist,
|
||||
public: false,
|
||||
|
|
@ -238,7 +238,7 @@ export const AddToPlaylistContextModal = ({
|
|||
);
|
||||
return api.controller.getPlaylistSongList({
|
||||
apiClientProps: {
|
||||
server,
|
||||
serverId: server?.id || '',
|
||||
signal,
|
||||
},
|
||||
query: {
|
||||
|
|
@ -266,9 +266,9 @@ export const AddToPlaylistContextModal = ({
|
|||
}
|
||||
addToPlaylistMutation.mutate(
|
||||
{
|
||||
apiClientProps: { serverId: server.id },
|
||||
body: { songId: values.skipDuplicates ? uniqueSongIds : allSongIds },
|
||||
query: { id: playlistId },
|
||||
serverId: server?.id,
|
||||
},
|
||||
{
|
||||
onError: (err) => {
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ export const CreatePlaylistForm = ({ onCancel }: CreatePlaylistFormProps) => {
|
|||
|
||||
mutation.mutate(
|
||||
{
|
||||
apiClientProps: { serverId: server.id },
|
||||
body: {
|
||||
...values,
|
||||
_custom: {
|
||||
|
|
@ -75,7 +76,6 @@ export const CreatePlaylistForm = ({ onCancel }: CreatePlaylistFormProps) => {
|
|||
},
|
||||
},
|
||||
},
|
||||
serverId: server.id,
|
||||
},
|
||||
{
|
||||
onError: (err) => {
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ export const PlaylistDetailSongListContent = ({ songs, tableRef }: PlaylistDetai
|
|||
try {
|
||||
await api.controller.movePlaylistItem({
|
||||
apiClientProps: {
|
||||
server,
|
||||
serverId: server?.id || '',
|
||||
},
|
||||
query: {
|
||||
endingIndex: e.overIndex,
|
||||
|
|
|
|||
|
|
@ -376,7 +376,10 @@ export const PlaylistDetailSongListHeaderFilters = ({
|
|||
const handleDeletePlaylist = useCallback(() => {
|
||||
if (!detailQuery.data) return;
|
||||
deletePlaylistMutation?.mutate(
|
||||
{ query: { id: detailQuery.data.id }, serverId: detailQuery.data.serverId },
|
||||
{
|
||||
apiClientProps: { serverId: detailQuery.data.serverId },
|
||||
query: { id: detailQuery.data.id },
|
||||
},
|
||||
{
|
||||
onError: (err) => {
|
||||
toast.error({
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ export const PlaylistListGridView = ({ gridRef, itemCount }: PlaylistListGridVie
|
|||
const handlePlayQueueAdd = usePlayQueueAdd();
|
||||
const { display, filter, grid } = useListStoreByKey<PlaylistListQuery>({ key: pageKey });
|
||||
const { setGrid } = useListStoreActions();
|
||||
const handleFavorite = useHandleFavorite({ gridRef, server });
|
||||
const handleFavorite = useHandleFavorite({ gridRef });
|
||||
|
||||
const cardRows = useMemo(() => {
|
||||
const rows: CardRow<Playlist>[] = [PLAYLIST_CARD_ROWS.nameFull];
|
||||
|
|
@ -126,7 +126,7 @@ export const PlaylistListGridView = ({ gridRef, itemCount }: PlaylistListGridVie
|
|||
queryFn: async ({ signal }) =>
|
||||
controller.getPlaylistList({
|
||||
apiClientProps: {
|
||||
server,
|
||||
serverId: server?.id || '',
|
||||
signal,
|
||||
},
|
||||
query,
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ export const PlaylistListHeaderFilters = ({
|
|||
queryFn: async ({ signal }) =>
|
||||
api.controller.getPlaylistList({
|
||||
apiClientProps: {
|
||||
server,
|
||||
serverId: server?.id || '',
|
||||
signal,
|
||||
},
|
||||
query,
|
||||
|
|
@ -213,7 +213,7 @@ export const PlaylistListHeaderFilters = ({
|
|||
queryFn: async ({ signal }) =>
|
||||
api.controller.getPlaylistList({
|
||||
apiClientProps: {
|
||||
server,
|
||||
serverId: server?.id || '',
|
||||
signal,
|
||||
},
|
||||
query: {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ interface SaveAsPlaylistFormProps {
|
|||
body: Partial<CreatePlaylistBody>;
|
||||
onCancel: () => void;
|
||||
onSuccess: (data: CreatePlaylistResponse) => void;
|
||||
serverId: string | undefined;
|
||||
serverId?: string;
|
||||
}
|
||||
|
||||
export const SaveAsPlaylistForm = ({
|
||||
|
|
@ -50,7 +50,7 @@ export const SaveAsPlaylistForm = ({
|
|||
|
||||
const handleSubmit = form.onSubmit((values) => {
|
||||
mutation.mutate(
|
||||
{ body: values, serverId },
|
||||
{ apiClientProps: { serverId: serverId || '' }, body: values },
|
||||
{
|
||||
onError: (err) => {
|
||||
toast.error({
|
||||
|
|
|
|||
|
|
@ -65,9 +65,9 @@ export const UpdatePlaylistForm = ({ body, onCancel, query, users }: UpdatePlayl
|
|||
const handleSubmit = form.onSubmit((values) => {
|
||||
mutation.mutate(
|
||||
{
|
||||
apiClientProps: { serverId: server?.id || '' },
|
||||
body: values,
|
||||
query,
|
||||
serverId: server?.id,
|
||||
},
|
||||
{
|
||||
onError: (err) => {
|
||||
|
|
@ -174,7 +174,10 @@ export const openUpdatePlaylistModal = async (args: {
|
|||
? await queryClient
|
||||
.fetchQuery({
|
||||
queryFn: ({ signal }) =>
|
||||
api.controller.getUserList({ apiClientProps: { server, signal }, query }),
|
||||
api.controller.getUserList({
|
||||
apiClientProps: { serverId: server?.id || '', signal },
|
||||
query,
|
||||
}),
|
||||
queryKey: queryKeys.users.list(server?.id || '', query),
|
||||
})
|
||||
.catch((error) => {
|
||||
|
|
|
|||
|
|
@ -4,26 +4,22 @@ import { AxiosError } from 'axios';
|
|||
import { api } from '/@/renderer/api';
|
||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import { MutationHookArgs } from '/@/renderer/lib/react-query';
|
||||
import { getServerById } from '/@/renderer/store';
|
||||
import { AddToPlaylistArgs, AddToPlaylistResponse } from '/@/shared/types/domain-types';
|
||||
|
||||
export const useAddToPlaylist = (args: MutationHookArgs) => {
|
||||
const { options } = args || {};
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<
|
||||
AddToPlaylistResponse,
|
||||
AxiosError,
|
||||
Omit<AddToPlaylistArgs, 'apiClientProps' | 'server'>,
|
||||
null
|
||||
>({
|
||||
return useMutation<AddToPlaylistResponse, AxiosError, AddToPlaylistArgs, null>({
|
||||
mutationFn: (args) => {
|
||||
const server = getServerById(args.serverId);
|
||||
if (!server) throw new Error('Server not found');
|
||||
return api.controller.addToPlaylist({ ...args, apiClientProps: { server } });
|
||||
return api.controller.addToPlaylist({
|
||||
...args,
|
||||
apiClientProps: { serverId: args.apiClientProps.serverId },
|
||||
});
|
||||
},
|
||||
onSuccess: (_data, variables) => {
|
||||
const { serverId } = variables;
|
||||
const { apiClientProps } = variables;
|
||||
const serverId = apiClientProps.serverId;
|
||||
|
||||
if (!serverId) return;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,32 +4,24 @@ import { AxiosError } from 'axios';
|
|||
import { api } from '/@/renderer/api';
|
||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import { MutationHookArgs } from '/@/renderer/lib/react-query';
|
||||
import { getServerById } from '/@/renderer/store';
|
||||
import { CreatePlaylistArgs, CreatePlaylistResponse } from '/@/shared/types/domain-types';
|
||||
|
||||
export const useCreatePlaylist = (args: MutationHookArgs) => {
|
||||
const { options } = args || {};
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<
|
||||
CreatePlaylistResponse,
|
||||
AxiosError,
|
||||
Omit<CreatePlaylistArgs, 'apiClientProps' | 'server'>,
|
||||
null
|
||||
>({
|
||||
return useMutation<CreatePlaylistResponse, AxiosError, CreatePlaylistArgs, null>({
|
||||
mutationFn: (args) => {
|
||||
const server = getServerById(args.serverId);
|
||||
if (!server) throw new Error('Server not found');
|
||||
return api.controller.createPlaylist({ ...args, apiClientProps: { server } });
|
||||
return api.controller.createPlaylist({
|
||||
...args,
|
||||
apiClientProps: { serverId: args.apiClientProps.serverId },
|
||||
});
|
||||
},
|
||||
onSuccess: (_args, variables) => {
|
||||
const server = getServerById(variables.serverId);
|
||||
if (server) {
|
||||
queryClient.invalidateQueries({
|
||||
exact: false,
|
||||
queryKey: queryKeys.playlists.list(server.id),
|
||||
});
|
||||
}
|
||||
queryClient.invalidateQueries({
|
||||
exact: false,
|
||||
queryKey: queryKeys.playlists.list(variables.apiClientProps.serverId),
|
||||
});
|
||||
},
|
||||
...options,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -4,33 +4,29 @@ import { AxiosError } from 'axios';
|
|||
import { api } from '/@/renderer/api';
|
||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import { MutationHookArgs } from '/@/renderer/lib/react-query';
|
||||
import { getServerById, useCurrentServer } from '/@/renderer/store';
|
||||
import { DeletePlaylistArgs, DeletePlaylistResponse } from '/@/shared/types/domain-types';
|
||||
|
||||
export const useDeletePlaylist = (args: MutationHookArgs) => {
|
||||
const { options } = args || {};
|
||||
const queryClient = useQueryClient();
|
||||
const server = useCurrentServer();
|
||||
|
||||
return useMutation<
|
||||
DeletePlaylistResponse,
|
||||
AxiosError,
|
||||
Omit<DeletePlaylistArgs, 'apiClientProps' | 'server'>,
|
||||
null
|
||||
>({
|
||||
return useMutation<DeletePlaylistResponse, AxiosError, DeletePlaylistArgs, null>({
|
||||
mutationFn: (args) => {
|
||||
const server = getServerById(args.serverId);
|
||||
if (!server) throw new Error('Server not found');
|
||||
return api.controller.deletePlaylist({ ...args, apiClientProps: { server } });
|
||||
return api.controller.deletePlaylist({
|
||||
...args,
|
||||
apiClientProps: { serverId: args.apiClientProps.serverId },
|
||||
});
|
||||
},
|
||||
onMutate: () => {
|
||||
queryClient.cancelQueries({ queryKey: queryKeys.playlists.list(server?.id || '') });
|
||||
onMutate: (variables) => {
|
||||
queryClient.cancelQueries({
|
||||
queryKey: queryKeys.playlists.list(variables.apiClientProps.serverId),
|
||||
});
|
||||
return null;
|
||||
},
|
||||
onSuccess: () => {
|
||||
onSuccess: (_data, variables) => {
|
||||
queryClient.invalidateQueries({
|
||||
exact: false,
|
||||
queryKey: queryKeys.playlists.list(server?.id || ''),
|
||||
queryKey: queryKeys.playlists.list(variables.apiClientProps.serverId),
|
||||
});
|
||||
},
|
||||
...options,
|
||||
|
|
|
|||
|
|
@ -4,25 +4,21 @@ import { AxiosError } from 'axios';
|
|||
import { api } from '/@/renderer/api';
|
||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import { MutationOptions } from '/@/renderer/lib/react-query';
|
||||
import { getServerById } from '/@/renderer/store';
|
||||
import { RemoveFromPlaylistArgs, RemoveFromPlaylistResponse } from '/@/shared/types/domain-types';
|
||||
|
||||
export const useRemoveFromPlaylist = (options?: MutationOptions) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<
|
||||
RemoveFromPlaylistResponse,
|
||||
AxiosError,
|
||||
Omit<RemoveFromPlaylistArgs, 'apiClientProps' | 'server'>,
|
||||
null
|
||||
>({
|
||||
return useMutation<RemoveFromPlaylistResponse, AxiosError, RemoveFromPlaylistArgs, null>({
|
||||
mutationFn: (args) => {
|
||||
const server = getServerById(args.serverId);
|
||||
if (!server) throw new Error('Server not found');
|
||||
return api.controller.removeFromPlaylist({ ...args, apiClientProps: { server } });
|
||||
return api.controller.removeFromPlaylist({
|
||||
...args,
|
||||
apiClientProps: { serverId: args.apiClientProps.serverId },
|
||||
});
|
||||
},
|
||||
onSuccess: (_data, variables) => {
|
||||
const { serverId } = variables;
|
||||
const { apiClientProps } = variables;
|
||||
const serverId = apiClientProps.serverId;
|
||||
|
||||
if (!serverId) return;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,26 +4,22 @@ import { AxiosError } from 'axios';
|
|||
import { api } from '/@/renderer/api';
|
||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import { MutationHookArgs } from '/@/renderer/lib/react-query';
|
||||
import { getServerById } from '/@/renderer/store';
|
||||
import { UpdatePlaylistArgs, UpdatePlaylistResponse } from '/@/shared/types/domain-types';
|
||||
|
||||
export const useUpdatePlaylist = (args: MutationHookArgs) => {
|
||||
const { options } = args || {};
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<
|
||||
UpdatePlaylistResponse,
|
||||
AxiosError,
|
||||
Omit<UpdatePlaylistArgs, 'apiClientProps' | 'server'>,
|
||||
null
|
||||
>({
|
||||
return useMutation<UpdatePlaylistResponse, AxiosError, UpdatePlaylistArgs, null>({
|
||||
mutationFn: (args) => {
|
||||
const server = getServerById(args.serverId);
|
||||
if (!server) throw new Error('Server not found');
|
||||
return api.controller.updatePlaylist({ ...args, apiClientProps: { server } });
|
||||
return api.controller.updatePlaylist({
|
||||
...args,
|
||||
apiClientProps: { serverId: args.apiClientProps.serverId },
|
||||
});
|
||||
},
|
||||
onSuccess: (_data, variables) => {
|
||||
const { query, serverId } = variables;
|
||||
const { apiClientProps, query } = variables;
|
||||
const serverId = apiClientProps.serverId;
|
||||
|
||||
if (!serverId) return;
|
||||
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ const PlaylistDetailSongListRoute = () => {
|
|||
|
||||
createPlaylistMutation.mutate(
|
||||
{
|
||||
apiClientProps: { serverId: detailQuery?.data?.serverId },
|
||||
body: {
|
||||
_custom: {
|
||||
navidrome: {
|
||||
|
|
@ -69,7 +70,6 @@ const PlaylistDetailSongListRoute = () => {
|
|||
name: detailQuery?.data?.name,
|
||||
public: detailQuery?.data?.public || false,
|
||||
},
|
||||
serverId: detailQuery?.data?.serverId,
|
||||
},
|
||||
{
|
||||
onSuccess: (data) => {
|
||||
|
|
@ -83,8 +83,8 @@ const PlaylistDetailSongListRoute = () => {
|
|||
},
|
||||
);
|
||||
deletePlaylistMutation.mutate({
|
||||
apiClientProps: { serverId: detailQuery?.data?.serverId },
|
||||
query: { id: playlistId },
|
||||
serverId: detailQuery?.data?.serverId,
|
||||
});
|
||||
},
|
||||
},
|
||||
|
|
@ -124,7 +124,7 @@ const PlaylistDetailSongListRoute = () => {
|
|||
}),
|
||||
)
|
||||
}
|
||||
serverId={detailQuery?.data?.serverId}
|
||||
serverId={detailQuery?.data?.serverId || ''}
|
||||
/>
|
||||
),
|
||||
title: t('common.saveAs', { postProcess: 'sentenceCase' }),
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import { queryOptions } from '@tanstack/react-query';
|
|||
import { api } from '/@/renderer/api';
|
||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import { QueryHookArgs } from '/@/renderer/lib/react-query';
|
||||
import { getServerById } from '/@/renderer/store';
|
||||
import { SearchQuery } from '/@/shared/types/domain-types';
|
||||
|
||||
export const searchQueries = {
|
||||
|
|
@ -11,11 +10,11 @@ export const searchQueries = {
|
|||
return queryOptions({
|
||||
queryFn: ({ signal }) => {
|
||||
return api.controller.search({
|
||||
apiClientProps: { server: getServerById(args.serverId), signal },
|
||||
apiClientProps: { serverId: args.serverId, signal },
|
||||
query: args.query,
|
||||
});
|
||||
},
|
||||
queryKey: queryKeys.search.list(args.serverId || '', args.query),
|
||||
queryKey: queryKeys.search.list(args.serverId, args.query),
|
||||
...args.options,
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { Command, CommandPalettePages } from '/@/renderer/features/search/compon
|
|||
import { ServerList } from '/@/renderer/features/servers/components/server-list';
|
||||
import { AppRoute } from '/@/renderer/router/routes';
|
||||
import { useAuthStoreActions, useServerList } from '/@/renderer/store';
|
||||
import { ServerListItem } from '/@/shared/types/domain-types';
|
||||
import { ServerListItemWithCredential } from '/@/shared/types/domain-types';
|
||||
|
||||
interface ServerCommandsProps {
|
||||
handleClose: () => void;
|
||||
|
|
@ -32,7 +32,7 @@ export const ServerCommands = ({ handleClose, setPages, setQuery }: ServerComman
|
|||
}, [handleClose, setPages, setQuery, t]);
|
||||
|
||||
const handleSelectServer = useCallback(
|
||||
(server: ServerListItem) => {
|
||||
(server: ServerListItemWithCredential) => {
|
||||
navigate(AppRoute.HOME);
|
||||
setCurrentServer(server);
|
||||
handleClose();
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import { Stack } from '/@/shared/components/stack/stack';
|
|||
import { TextInput } from '/@/shared/components/text-input/text-input';
|
||||
import { Text } from '/@/shared/components/text/text';
|
||||
import { toast } from '/@/shared/components/toast/toast';
|
||||
import { AuthenticationResponse, ServerListItem } from '/@/shared/types/domain-types';
|
||||
import { AuthenticationResponse, ServerListItemWithCredential } from '/@/shared/types/domain-types';
|
||||
import { DiscoveredServerItem, ServerType, toServerType } from '/@/shared/types/types';
|
||||
|
||||
const autodiscover = isElectron() ? window.api.autodiscover : null;
|
||||
|
|
@ -152,7 +152,7 @@ export const AddServerForm = ({ onCancel }: AddServerFormProps) => {
|
|||
});
|
||||
}
|
||||
|
||||
const serverItem: ServerListItem = {
|
||||
const serverItem: ServerListItemWithCredential = {
|
||||
credential: data.credential,
|
||||
id: nanoid(),
|
||||
name: values.name,
|
||||
|
|
|
|||
|
|
@ -18,7 +18,12 @@ import { Stack } from '/@/shared/components/stack/stack';
|
|||
import { TextInput } from '/@/shared/components/text-input/text-input';
|
||||
import { toast } from '/@/shared/components/toast/toast';
|
||||
import { Tooltip } from '/@/shared/components/tooltip/tooltip';
|
||||
import { AuthenticationResponse, ServerListItem, ServerType } from '/@/shared/types/domain-types';
|
||||
import {
|
||||
AuthenticationResponse,
|
||||
ServerListItem,
|
||||
ServerListItemWithCredential,
|
||||
ServerType,
|
||||
} from '/@/shared/types/domain-types';
|
||||
|
||||
const localSettings = isElectron() ? window.api.localSettings : null;
|
||||
|
||||
|
|
@ -86,7 +91,7 @@ export const EditServerForm = ({ isUpdate, onCancel, password, server }: EditSer
|
|||
});
|
||||
}
|
||||
|
||||
const serverItem: ServerListItem = {
|
||||
const serverItem: ServerListItemWithCredential = {
|
||||
credential: data.credential,
|
||||
id: server.id,
|
||||
name: values.name,
|
||||
|
|
|
|||
|
|
@ -3,28 +3,25 @@ import { queryOptions } from '@tanstack/react-query';
|
|||
import { api } from '/@/renderer/api';
|
||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import { QueryHookArgs } from '/@/renderer/lib/react-query';
|
||||
import { getServerById } from '/@/renderer/store';
|
||||
import { MusicFolderListQuery, TagQuery, UserListQuery } from '/@/shared/types/domain-types';
|
||||
|
||||
export const sharedQueries = {
|
||||
musicFolders: (args: QueryHookArgs<MusicFolderListQuery>) => {
|
||||
return queryOptions({
|
||||
queryFn: ({ signal }) => {
|
||||
const server = getServerById(args.serverId);
|
||||
if (!server) throw new Error('Server not found');
|
||||
return api.controller.getMusicFolderList({ apiClientProps: { server, signal } });
|
||||
return api.controller.getMusicFolderList({
|
||||
apiClientProps: { serverId: args.serverId, signal },
|
||||
});
|
||||
},
|
||||
queryKey: queryKeys.musicFolders.list(args.serverId || ''),
|
||||
queryKey: queryKeys.musicFolders.list(args.serverId),
|
||||
...args.options,
|
||||
});
|
||||
},
|
||||
roles: (args: QueryHookArgs<object>) => {
|
||||
return queryOptions({
|
||||
queryFn: ({ signal }) => {
|
||||
const server = getServerById(args.serverId);
|
||||
if (!server) throw new Error('Server not found');
|
||||
return api.controller.getRoles({
|
||||
apiClientProps: { server, signal },
|
||||
apiClientProps: { serverId: args.serverId, signal },
|
||||
});
|
||||
},
|
||||
queryKey: queryKeys.roles.list(args.serverId || ''),
|
||||
|
|
@ -35,10 +32,8 @@ export const sharedQueries = {
|
|||
return queryOptions({
|
||||
gcTime: 1000 * 60,
|
||||
queryFn: ({ signal }) => {
|
||||
const server = getServerById(args.serverId);
|
||||
if (!server) throw new Error('Server not found');
|
||||
return api.controller.getTags({
|
||||
apiClientProps: { server, signal },
|
||||
apiClientProps: { serverId: args.serverId, signal },
|
||||
query: args.query,
|
||||
});
|
||||
},
|
||||
|
|
@ -49,10 +44,8 @@ export const sharedQueries = {
|
|||
users: (args: QueryHookArgs<UserListQuery>) => {
|
||||
return queryOptions({
|
||||
queryFn: ({ signal }) => {
|
||||
const server = getServerById(args.serverId);
|
||||
if (!server) throw new Error('Server not found');
|
||||
return api.controller.getUserList({
|
||||
apiClientProps: { server, signal },
|
||||
apiClientProps: { serverId: args.serverId, signal },
|
||||
query: args.query,
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3,17 +3,17 @@ import { MutableRefObject, useCallback } from 'react';
|
|||
import { VirtualInfiniteGridRef } from '/@/renderer/components/virtual-grid/virtual-infinite-grid';
|
||||
import { useCreateFavorite } from '/@/renderer/features/shared/mutations/create-favorite-mutation';
|
||||
import { useDeleteFavorite } from '/@/renderer/features/shared/mutations/delete-favorite-mutation';
|
||||
import { useCurrentServerId } from '/@/renderer/store';
|
||||
import { LibraryItem } from '/@/shared/types/domain-types';
|
||||
import { ServerListItem } from '/@/shared/types/types';
|
||||
|
||||
interface HandleFavoriteProps {
|
||||
gridRef: MutableRefObject<null | VirtualInfiniteGridRef>;
|
||||
server: null | ServerListItem;
|
||||
}
|
||||
|
||||
export const useHandleFavorite = ({ gridRef, server }: HandleFavoriteProps) => {
|
||||
export const useHandleFavorite = ({ gridRef }: HandleFavoriteProps) => {
|
||||
const createFavoriteMutation = useCreateFavorite({});
|
||||
const deleteFavoriteMutation = useDeleteFavorite({});
|
||||
const serverId = useCurrentServerId();
|
||||
|
||||
const handleFavorite = useCallback(
|
||||
async (options: { id: string[]; isFavorite: boolean; itemType: LibraryItem }) => {
|
||||
|
|
@ -21,19 +21,19 @@ export const useHandleFavorite = ({ gridRef, server }: HandleFavoriteProps) => {
|
|||
try {
|
||||
if (isFavorite) {
|
||||
await deleteFavoriteMutation.mutateAsync({
|
||||
apiClientProps: { serverId },
|
||||
query: {
|
||||
id,
|
||||
type: itemType,
|
||||
},
|
||||
serverId: server?.id,
|
||||
});
|
||||
} else {
|
||||
await createFavoriteMutation.mutateAsync({
|
||||
apiClientProps: { serverId },
|
||||
query: {
|
||||
id,
|
||||
type: itemType,
|
||||
},
|
||||
serverId: server?.id,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -50,7 +50,7 @@ export const useHandleFavorite = ({ gridRef, server }: HandleFavoriteProps) => {
|
|||
console.error(error);
|
||||
}
|
||||
},
|
||||
[createFavoriteMutation, deleteFavoriteMutation, gridRef, server?.id],
|
||||
[createFavoriteMutation, deleteFavoriteMutation, gridRef, serverId],
|
||||
);
|
||||
|
||||
return handleFavorite;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import isElectron from 'is-electron';
|
|||
import { api } from '/@/renderer/api';
|
||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import { MutationHookArgs } from '/@/renderer/lib/react-query';
|
||||
import { getServerById, useSetAlbumListItemDataById, useSetQueueFavorite } from '/@/renderer/store';
|
||||
import { useSetAlbumListItemDataById, useSetQueueFavorite } from '/@/renderer/store';
|
||||
import { useFavoriteEvent } from '/@/renderer/store/event.store';
|
||||
import {
|
||||
AlbumArtistDetailResponse,
|
||||
|
|
@ -24,19 +24,16 @@ export const useCreateFavorite = (args: MutationHookArgs) => {
|
|||
const setQueueFavorite = useSetQueueFavorite();
|
||||
const setFavoriteEvent = useFavoriteEvent();
|
||||
|
||||
return useMutation<
|
||||
FavoriteResponse,
|
||||
AxiosError,
|
||||
Omit<FavoriteArgs, 'apiClientProps' | 'server'>,
|
||||
null
|
||||
>({
|
||||
return useMutation<FavoriteResponse, AxiosError, FavoriteArgs, null>({
|
||||
mutationFn: (args) => {
|
||||
const server = getServerById(args.serverId);
|
||||
if (!server) throw new Error('Server not found');
|
||||
return api.controller.createFavorite({ ...args, apiClientProps: { server } });
|
||||
return api.controller.createFavorite({
|
||||
...args,
|
||||
apiClientProps: { serverId: args.apiClientProps.serverId },
|
||||
});
|
||||
},
|
||||
onSuccess: (_data, variables) => {
|
||||
const { serverId } = variables;
|
||||
const { apiClientProps } = variables;
|
||||
const serverId = apiClientProps.serverId;
|
||||
|
||||
if (!serverId) return;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import isElectron from 'is-electron';
|
|||
import { api } from '/@/renderer/api';
|
||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import { MutationHookArgs } from '/@/renderer/lib/react-query';
|
||||
import { getServerById, useSetAlbumListItemDataById, useSetQueueFavorite } from '/@/renderer/store';
|
||||
import { useSetAlbumListItemDataById, useSetQueueFavorite } from '/@/renderer/store';
|
||||
import { useFavoriteEvent } from '/@/renderer/store/event.store';
|
||||
import {
|
||||
AlbumArtistDetailResponse,
|
||||
|
|
@ -24,21 +24,16 @@ export const useDeleteFavorite = (args: MutationHookArgs) => {
|
|||
const setQueueFavorite = useSetQueueFavorite();
|
||||
const setFavoriteEvent = useFavoriteEvent();
|
||||
|
||||
return useMutation<
|
||||
FavoriteResponse,
|
||||
AxiosError,
|
||||
Omit<FavoriteArgs, 'apiClientProps' | 'server'>,
|
||||
null
|
||||
>({
|
||||
return useMutation<FavoriteResponse, AxiosError, FavoriteArgs, null>({
|
||||
mutationFn: (args) => {
|
||||
const server = getServerById(args.serverId);
|
||||
if (!server) throw new Error('Server not found');
|
||||
return api.controller.deleteFavorite({ ...args, apiClientProps: { server } });
|
||||
return api.controller.deleteFavorite({
|
||||
...args,
|
||||
apiClientProps: { serverId: args.apiClientProps.serverId },
|
||||
});
|
||||
},
|
||||
onSuccess: (_data, variables) => {
|
||||
const { serverId } = variables;
|
||||
|
||||
if (!serverId) return;
|
||||
const { apiClientProps } = variables;
|
||||
const serverId = apiClientProps.serverId;
|
||||
|
||||
for (const id of variables.query.id) {
|
||||
// Set the userFavorite property to false for the album in the album list data store
|
||||
|
|
@ -55,7 +50,9 @@ export const useDeleteFavorite = (args: MutationHookArgs) => {
|
|||
|
||||
// We only need to set if we're already on the album detail page
|
||||
if (variables.query.type === LibraryItem.ALBUM && variables.query.id.length === 1) {
|
||||
const queryKey = queryKeys.albums.detail(serverId, { id: variables.query.id[0] });
|
||||
const queryKey = queryKeys.albums.detail(serverId, {
|
||||
id: variables.query.id[0],
|
||||
});
|
||||
const previous = queryClient.getQueryData<AlbumDetailResponse>(queryKey);
|
||||
|
||||
if (previous) {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import isElectron from 'is-electron';
|
|||
import { api } from '/@/renderer/api';
|
||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import { MutationHookArgs } from '/@/renderer/lib/react-query';
|
||||
import { getServerById, useSetAlbumListItemDataById, useSetQueueRating } from '/@/renderer/store';
|
||||
import { useSetAlbumListItemDataById, useSetQueueRating } from '/@/renderer/store';
|
||||
import { useRatingEvent } from '/@/renderer/store/event.store';
|
||||
import {
|
||||
Album,
|
||||
|
|
@ -30,13 +30,14 @@ export const useSetRating = (args: MutationHookArgs) => {
|
|||
return useMutation<
|
||||
RatingResponse,
|
||||
AxiosError,
|
||||
Omit<SetRatingArgs, 'apiClientProps' | 'server'>,
|
||||
SetRatingArgs,
|
||||
{ previous: undefined | { items: AnyLibraryItems } }
|
||||
>({
|
||||
mutationFn: (args) => {
|
||||
const server = getServerById(args.serverId);
|
||||
if (!server) throw new Error('Server not found');
|
||||
return api.controller.setRating({ ...args, apiClientProps: { server } });
|
||||
return api.controller.setRating({
|
||||
...args,
|
||||
apiClientProps: { serverId: args.apiClientProps.serverId },
|
||||
});
|
||||
},
|
||||
onError: (_error, _variables, context) => {
|
||||
for (const item of context?.previous?.items || []) {
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ export const ShareItemContextModal = ({
|
|||
const handleSubmit = form.onSubmit(async (values) => {
|
||||
shareItemMutation.mutate(
|
||||
{
|
||||
apiClientProps: { serverId: server?.id || '' },
|
||||
body: {
|
||||
description: values.description,
|
||||
downloadable: values.allowDownloading,
|
||||
|
|
@ -55,7 +56,6 @@ export const ShareItemContextModal = ({
|
|||
resourceIds: itemIds.join(),
|
||||
resourceType,
|
||||
},
|
||||
serverId: server?.id,
|
||||
},
|
||||
{
|
||||
onError: () => {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import { AxiosError } from 'axios';
|
|||
|
||||
import { api } from '/@/renderer/api';
|
||||
import { MutationHookArgs } from '/@/renderer/lib/react-query';
|
||||
import { getServerById } from '/@/renderer/store';
|
||||
import { AnyLibraryItems, ShareItemArgs, ShareItemResponse } from '/@/shared/types/domain-types';
|
||||
|
||||
export const useShareItem = (args: MutationHookArgs) => {
|
||||
|
|
@ -12,13 +11,14 @@ export const useShareItem = (args: MutationHookArgs) => {
|
|||
return useMutation<
|
||||
ShareItemResponse,
|
||||
AxiosError,
|
||||
Omit<ShareItemArgs, 'apiClientProps' | 'server'>,
|
||||
ShareItemArgs,
|
||||
{ previous: undefined | { items: AnyLibraryItems } }
|
||||
>({
|
||||
mutationFn: (args) => {
|
||||
const server = getServerById(args.serverId);
|
||||
if (!server) throw new Error('Server not found');
|
||||
return api.controller.shareItem({ ...args, apiClientProps: { server } });
|
||||
return api.controller.shareItem({
|
||||
...args,
|
||||
apiClientProps: { serverId: args.apiClientProps.serverId },
|
||||
});
|
||||
},
|
||||
...options,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -4,36 +4,31 @@ import { api } from '/@/renderer/api';
|
|||
import { controller } from '/@/renderer/api/controller';
|
||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import { QueryHookArgs } from '/@/renderer/lib/react-query';
|
||||
import { getServerById } from '/@/renderer/store';
|
||||
import { ListCountQuery, SimilarSongsQuery, SongListQuery } from '/@/shared/types/domain-types';
|
||||
|
||||
export const songsQueries = {
|
||||
list: (args: QueryHookArgs<SongListQuery>, imageSize?: number) => {
|
||||
return queryOptions({
|
||||
queryFn: ({ signal }) => {
|
||||
const server = getServerById(args.serverId);
|
||||
if (!server) throw new Error('Server not found');
|
||||
return controller.getSongList({
|
||||
apiClientProps: { server, signal },
|
||||
apiClientProps: { serverId: args.serverId, signal },
|
||||
query: { ...args.query, imageSize },
|
||||
});
|
||||
},
|
||||
queryKey: queryKeys.songs.list(args.serverId || '', { ...args.query, imageSize }),
|
||||
queryKey: queryKeys.songs.list(args.serverId, { ...args.query, imageSize }),
|
||||
...args.options,
|
||||
});
|
||||
},
|
||||
listCount: (args: QueryHookArgs<ListCountQuery<SongListQuery>>) => {
|
||||
return queryOptions({
|
||||
queryFn: ({ signal }) => {
|
||||
const server = getServerById(args.serverId);
|
||||
if (!server) throw new Error('Server not found');
|
||||
return api.controller.getSongListCount({
|
||||
apiClientProps: { server, signal },
|
||||
apiClientProps: { serverId: args.serverId, signal },
|
||||
query: args.query,
|
||||
});
|
||||
},
|
||||
queryKey: queryKeys.songs.count(
|
||||
args.serverId || '',
|
||||
args.serverId,
|
||||
Object.keys(args.query).length === 0 ? undefined : args.query,
|
||||
),
|
||||
...args.options,
|
||||
|
|
@ -42,10 +37,8 @@ export const songsQueries = {
|
|||
similar: (args: QueryHookArgs<SimilarSongsQuery>) => {
|
||||
return queryOptions({
|
||||
queryFn: ({ signal }) => {
|
||||
const server = getServerById(args.serverId);
|
||||
if (!server) throw new Error('Server not found');
|
||||
return api.controller.getSimilarSongs({
|
||||
apiClientProps: { server, signal },
|
||||
apiClientProps: { serverId: args.serverId, signal },
|
||||
query: {
|
||||
albumArtistIds: args.query.albumArtistIds,
|
||||
count: args.query.count ?? 50,
|
||||
|
|
@ -53,7 +46,7 @@ export const songsQueries = {
|
|||
},
|
||||
});
|
||||
},
|
||||
queryKey: queryKeys.songs.similar(args.serverId || '', args.query),
|
||||
queryKey: queryKeys.songs.similar(args.serverId, args.query),
|
||||
...args.options,
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ import {
|
|||
import { genresQueries } from '/@/renderer/features/genres/api/genres-api';
|
||||
import { sharedQueries } from '/@/renderer/features/shared/api/shared-api';
|
||||
import {
|
||||
getServerById,
|
||||
SongListFilter,
|
||||
useCurrentServer,
|
||||
useListFilterByKey,
|
||||
useListStoreActions,
|
||||
} from '/@/renderer/store';
|
||||
|
|
@ -42,7 +42,7 @@ export const NavidromeSongFilters = ({
|
|||
const { t } = useTranslation();
|
||||
const { setFilter } = useListStoreActions();
|
||||
const filter = useListFilterByKey<SongListQuery>({ key: pageKey });
|
||||
const server = getServerById(serverId);
|
||||
const server = useCurrentServer();
|
||||
|
||||
const isGenrePage = customFilters?.genreIds !== undefined;
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ export const SongListGridView = ({ gridRef, itemCount }: SongListGridViewProps)
|
|||
const scrollOffset = searchParams.get('scrollOffset');
|
||||
const initialScrollOffset = Number(id ? scrollOffset : grid?.scrollOffset) || 0;
|
||||
|
||||
const handleFavorite = useHandleFavorite({ gridRef, server });
|
||||
const handleFavorite = useHandleFavorite({ gridRef });
|
||||
|
||||
useEffect(() => {
|
||||
const unSub = useEventStore.subscribe((state) => {
|
||||
|
|
@ -189,7 +189,7 @@ export const SongListGridView = ({ gridRef, itemCount }: SongListGridViewProps)
|
|||
queryFn: async ({ signal }) =>
|
||||
controller.getSongList({
|
||||
apiClientProps: {
|
||||
server,
|
||||
serverId: server?.id || '',
|
||||
signal,
|
||||
},
|
||||
query,
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import {
|
|||
import { DropdownMenu } from '/@/shared/components/dropdown-menu/dropdown-menu';
|
||||
import { Icon } from '/@/shared/components/icon/icon';
|
||||
import { toast } from '/@/shared/components/toast/toast';
|
||||
import { ServerListItem, ServerType } from '/@/shared/types/domain-types';
|
||||
import { ServerListItemWithCredential, ServerType } from '/@/shared/types/domain-types';
|
||||
|
||||
const browser = isElectron() ? window.api.browser : null;
|
||||
const localSettings = isElectron() ? window.api.localSettings : null;
|
||||
|
|
@ -35,12 +35,12 @@ export const AppMenu = () => {
|
|||
const { privateMode } = useAppStore();
|
||||
const { setPrivateMode, setSideBar } = useAppStoreActions();
|
||||
|
||||
const handleSetCurrentServer = (server: ServerListItem) => {
|
||||
const handleSetCurrentServer = (server: ServerListItemWithCredential) => {
|
||||
navigate(AppRoute.HOME);
|
||||
setCurrentServer(server);
|
||||
};
|
||||
|
||||
const handleCredentialsModal = async (server: ServerListItem) => {
|
||||
const handleCredentialsModal = async (server: ServerListItemWithCredential) => {
|
||||
let password: null | string = null;
|
||||
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ export const useListFilterRefresh = ({
|
|||
queryFn: async ({ signal }) => {
|
||||
return queryFn({
|
||||
apiClientProps: {
|
||||
server,
|
||||
serverId: server?.id || '',
|
||||
signal,
|
||||
},
|
||||
query,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { debounce } from 'lodash';
|
|||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
||||
import { api } from '/@/renderer/api';
|
||||
import { useAuthStoreActions, useCurrentServer } from '/@/renderer/store';
|
||||
import { getServerById, useAuthStoreActions, useCurrentServer } from '/@/renderer/store';
|
||||
import { toast } from '/@/shared/components/toast/toast';
|
||||
import { SongListSort, SortOrder } from '/@/shared/types/domain-types';
|
||||
import { AuthState, ServerListItem, ServerType } from '/@/shared/types/types';
|
||||
|
|
@ -26,7 +26,7 @@ export const useServerAuthenticated = () => {
|
|||
// making one request first
|
||||
try {
|
||||
await api.controller.getSongList({
|
||||
apiClientProps: { server },
|
||||
apiClientProps: { serverId: server?.id || '' },
|
||||
query: {
|
||||
limit: 1,
|
||||
sortBy: SongListSort.NAME,
|
||||
|
|
@ -59,11 +59,12 @@ export const useServerAuthenticated = () => {
|
|||
|
||||
useEffect(() => {
|
||||
if (priorServerId.current !== server?.id) {
|
||||
const serverWithAuth = getServerById(server!.id);
|
||||
priorServerId.current = server?.id || '';
|
||||
|
||||
if (server?.type === ServerType.NAVIDROME) {
|
||||
setReady(AuthState.LOADING);
|
||||
debouncedAuth(server);
|
||||
debouncedAuth(serverWithAuth!);
|
||||
} else {
|
||||
setReady(AuthState.VALID);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ export const useServerVersion = () => {
|
|||
queryFn: async ({ signal }) => {
|
||||
return controller.getServerInfo({
|
||||
apiClientProps: {
|
||||
server,
|
||||
serverId: server?.id || '',
|
||||
signal,
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,27 +2,28 @@ import merge from 'lodash/merge';
|
|||
import { nanoid } from 'nanoid/non-secure';
|
||||
import { devtools, persist } from 'zustand/middleware';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
import { shallow } from 'zustand/shallow';
|
||||
import { createWithEqualityFn } from 'zustand/traditional';
|
||||
|
||||
import { useAlbumArtistListDataStore } from '/@/renderer/store/album-artist-list-data.store';
|
||||
import { useAlbumListDataStore } from '/@/renderer/store/album-list-data.store';
|
||||
import { useListStore } from '/@/renderer/store/list.store';
|
||||
import { ServerListItem } from '/@/shared/types/domain-types';
|
||||
import { ServerListItem, ServerListItemWithCredential } from '/@/shared/types/domain-types';
|
||||
|
||||
export interface AuthSlice extends AuthState {
|
||||
actions: {
|
||||
addServer: (args: ServerListItem) => void;
|
||||
addServer: (args: ServerListItemWithCredential) => void;
|
||||
deleteServer: (id: string) => void;
|
||||
getServer: (id: string) => null | ServerListItem;
|
||||
setCurrentServer: (server: null | ServerListItem) => void;
|
||||
updateServer: (id: string, args: Partial<ServerListItem>) => void;
|
||||
getServer: (id: string) => null | ServerListItemWithCredential;
|
||||
setCurrentServer: (server: null | ServerListItemWithCredential) => void;
|
||||
updateServer: (id: string, args: Partial<ServerListItemWithCredential>) => void;
|
||||
};
|
||||
}
|
||||
|
||||
export interface AuthState {
|
||||
currentServer: null | ServerListItem;
|
||||
currentServer: null | ServerListItemWithCredential;
|
||||
deviceId: string;
|
||||
serverList: Record<string, ServerListItem>;
|
||||
serverList: Record<string, ServerListItemWithCredential>;
|
||||
}
|
||||
|
||||
export const useAuthStore = createWithEqualityFn<AuthSlice>()(
|
||||
|
|
@ -92,7 +93,23 @@ export const useAuthStore = createWithEqualityFn<AuthSlice>()(
|
|||
export const useCurrentServerId = () => useAuthStore((state) => state.currentServer)?.id || '';
|
||||
|
||||
export const useCurrentServer = () =>
|
||||
useAuthStore((state) => state.currentServer) as ServerListItem;
|
||||
useAuthStore((state) => {
|
||||
return {
|
||||
features: state.currentServer?.features,
|
||||
id: state.currentServer?.id,
|
||||
name: state.currentServer?.name,
|
||||
preferInstantMix: state.currentServer?.preferInstantMix,
|
||||
savePassword: state.currentServer?.savePassword,
|
||||
type: state.currentServer?.type,
|
||||
url: state.currentServer?.url,
|
||||
userId: state.currentServer?.userId,
|
||||
username: state.currentServer?.username,
|
||||
version: state.currentServer?.version,
|
||||
};
|
||||
}, shallow) as ServerListItem;
|
||||
|
||||
export const useCurrentServerWithCredential = () =>
|
||||
useAuthStore((state) => state.currentServer) as ServerListItemWithCredential;
|
||||
|
||||
export const useServerList = () => useAuthStore((state) => state.serverList);
|
||||
|
||||
|
|
|
|||
|
|
@ -914,7 +914,6 @@ export const useSettingsStore = createWithEqualityFn<SettingsSlice>()(
|
|||
merge: mergeOverridingColumns,
|
||||
migrate(persistedState, version) {
|
||||
const state = persistedState as SettingsSlice;
|
||||
console.log('migrate: ', version);
|
||||
|
||||
if (version === 8) {
|
||||
state.general.sidebarItems = state.general.sidebarItems.filter(
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import type { PlayerData, QueueSong } from '/@/shared/types/domain-types';
|
|||
import isElectron from 'is-electron';
|
||||
|
||||
import { api } from '/@/renderer/api';
|
||||
import { getServerById, useSettingsStore } from '/@/renderer/store';
|
||||
import { useSettingsStore } from '/@/renderer/store';
|
||||
|
||||
const mpvPlayer = isElectron() ? window.api.mpvPlayer : null;
|
||||
|
||||
|
|
@ -12,7 +12,7 @@ const modifyUrl = (song: QueueSong): string => {
|
|||
if (transcode.enabled) {
|
||||
const streamUrl = api.controller.getTranscodingUrl({
|
||||
apiClientProps: {
|
||||
server: getServerById(song.serverId),
|
||||
serverId: song.serverId,
|
||||
},
|
||||
query: {
|
||||
base: song.streamUrl,
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ const getArtists = (
|
|||
|
||||
const normalizeSong = (
|
||||
item: z.infer<typeof ndType._response.playlistSong> | z.infer<typeof ndType._response.song>,
|
||||
server: null | ServerListItem,
|
||||
server?: null | ServerListItem,
|
||||
imageSize?: number,
|
||||
): Song => {
|
||||
let id;
|
||||
|
|
@ -222,7 +222,7 @@ const normalizeAlbum = (
|
|||
item: z.infer<typeof ndType._response.album> & {
|
||||
songs?: z.infer<typeof ndType._response.songList>;
|
||||
},
|
||||
server: null | ServerListItem,
|
||||
server?: null | ServerListItem,
|
||||
imageSize?: number,
|
||||
): Album => {
|
||||
const imageUrl = getCoverArtUrl({
|
||||
|
|
@ -293,7 +293,7 @@ const normalizeAlbumArtist = (
|
|||
item: z.infer<typeof ndType._response.albumArtist> & {
|
||||
similarArtists?: z.infer<typeof ssType._response.artistInfo>['artistInfo']['similarArtist'];
|
||||
},
|
||||
server: null | ServerListItem,
|
||||
server?: null | ServerListItem,
|
||||
): AlbumArtist => {
|
||||
let imageUrl = getImageUrl({ url: item?.largeImageUrl || null });
|
||||
|
||||
|
|
@ -358,7 +358,7 @@ const normalizeAlbumArtist = (
|
|||
|
||||
const normalizePlaylist = (
|
||||
item: z.infer<typeof ndType._response.playlist>,
|
||||
server: null | ServerListItem,
|
||||
server?: null | ServerListItem,
|
||||
imageSize?: number,
|
||||
): Playlist => {
|
||||
const imageUrl = getCoverArtUrl({
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import {
|
|||
Playlist,
|
||||
QueueSong,
|
||||
RelatedArtist,
|
||||
ServerListItem,
|
||||
ServerListItemWithCredential,
|
||||
ServerType,
|
||||
} from '/@/shared/types/domain-types';
|
||||
|
||||
|
|
@ -117,7 +117,7 @@ const getGenres = (
|
|||
|
||||
const normalizeSong = (
|
||||
item: z.infer<typeof ssType._response.song>,
|
||||
server: null | ServerListItem,
|
||||
server?: null | ServerListItemWithCredential,
|
||||
size?: number,
|
||||
): QueueSong => {
|
||||
const imageUrl =
|
||||
|
|
@ -200,7 +200,7 @@ const normalizeAlbumArtist = (
|
|||
item:
|
||||
| z.infer<typeof ssType._response.albumArtist>
|
||||
| z.infer<typeof ssType._response.artistListEntry>,
|
||||
server: null | ServerListItem,
|
||||
server?: null | ServerListItemWithCredential,
|
||||
imageSize?: number,
|
||||
): AlbumArtist => {
|
||||
const imageUrl =
|
||||
|
|
@ -235,7 +235,7 @@ const normalizeAlbumArtist = (
|
|||
|
||||
const normalizeAlbum = (
|
||||
item: z.infer<typeof ssType._response.album> | z.infer<typeof ssType._response.albumListEntry>,
|
||||
server: null | ServerListItem,
|
||||
server?: null | ServerListItemWithCredential,
|
||||
imageSize?: number,
|
||||
): Album => {
|
||||
const imageUrl =
|
||||
|
|
@ -294,7 +294,7 @@ const normalizePlaylist = (
|
|||
item:
|
||||
| z.infer<typeof ssType._response.playlist>
|
||||
| z.infer<typeof ssType._response.playlistListEntry>,
|
||||
server: null | ServerListItem,
|
||||
server?: null | ServerListItemWithCredential,
|
||||
): Playlist => {
|
||||
return {
|
||||
description: item.comment || null,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { Omit } from 'lodash';
|
||||
import orderBy from 'lodash/orderBy';
|
||||
import reverse from 'lodash/reverse';
|
||||
import shuffle from 'lodash/shuffle';
|
||||
|
|
@ -84,11 +85,9 @@ export type QueueSong = Song & {
|
|||
};
|
||||
|
||||
export type ServerListItem = {
|
||||
credential: string;
|
||||
features?: ServerFeatures;
|
||||
id: string;
|
||||
name: string;
|
||||
ndCredential?: string;
|
||||
preferInstantMix?: boolean;
|
||||
savePassword?: boolean;
|
||||
type: ServerType;
|
||||
|
|
@ -98,6 +97,11 @@ export type ServerListItem = {
|
|||
version?: string;
|
||||
};
|
||||
|
||||
export type ServerListItemWithCredential = ServerListItem & {
|
||||
credential: string;
|
||||
ndCredential?: string;
|
||||
};
|
||||
|
||||
export type User = {
|
||||
createdAt: null | string;
|
||||
email: null | string;
|
||||
|
|
@ -372,7 +376,8 @@ export type Song = {
|
|||
|
||||
type BaseEndpointArgs = {
|
||||
apiClientProps: {
|
||||
server: null | ServerListItem;
|
||||
server?: null | ServerListItemWithCredential;
|
||||
serverId: string;
|
||||
signal?: AbortSignal;
|
||||
};
|
||||
};
|
||||
|
|
@ -829,7 +834,6 @@ export enum PlaylistListSort {
|
|||
export type AddToPlaylistArgs = BaseEndpointArgs & {
|
||||
body: AddToPlaylistBody;
|
||||
query: AddToPlaylistQuery;
|
||||
serverId?: string;
|
||||
};
|
||||
|
||||
export type AddToPlaylistBody = {
|
||||
|
|
@ -843,7 +847,7 @@ export type AddToPlaylistQuery = {
|
|||
// Add to playlist
|
||||
export type AddToPlaylistResponse = null | undefined;
|
||||
|
||||
export type CreatePlaylistArgs = BaseEndpointArgs & { body: CreatePlaylistBody; serverId?: string };
|
||||
export type CreatePlaylistArgs = BaseEndpointArgs & { body: CreatePlaylistBody };
|
||||
|
||||
export type CreatePlaylistBody = {
|
||||
_custom?: {
|
||||
|
|
@ -864,7 +868,6 @@ export type CreatePlaylistResponse = undefined | { id: string };
|
|||
|
||||
export type DeletePlaylistArgs = BaseEndpointArgs & {
|
||||
query: DeletePlaylistQuery;
|
||||
serverId?: string;
|
||||
};
|
||||
|
||||
export type DeletePlaylistQuery = { id: string };
|
||||
|
|
@ -872,7 +875,7 @@ export type DeletePlaylistQuery = { id: string };
|
|||
// Delete Playlist
|
||||
export type DeletePlaylistResponse = null | undefined;
|
||||
|
||||
export type FavoriteArgs = BaseEndpointArgs & { query: FavoriteQuery; serverId?: string };
|
||||
export type FavoriteArgs = BaseEndpointArgs & { query: FavoriteQuery };
|
||||
|
||||
export type FavoriteQuery = {
|
||||
id: string[];
|
||||
|
|
@ -909,7 +912,6 @@ export type RatingResponse = null | undefined;
|
|||
|
||||
export type RemoveFromPlaylistArgs = BaseEndpointArgs & {
|
||||
query: RemoveFromPlaylistQuery;
|
||||
serverId?: string;
|
||||
};
|
||||
|
||||
export type RemoveFromPlaylistQuery = {
|
||||
|
|
@ -920,9 +922,9 @@ export type RemoveFromPlaylistQuery = {
|
|||
// Remove from playlist
|
||||
export type RemoveFromPlaylistResponse = null | undefined;
|
||||
|
||||
export type SetRatingArgs = BaseEndpointArgs & { query: RatingQuery; serverId?: string };
|
||||
export type SetRatingArgs = BaseEndpointArgs & { query: RatingQuery };
|
||||
|
||||
export type ShareItemArgs = BaseEndpointArgs & { body: ShareItemBody; serverId?: string };
|
||||
export type ShareItemArgs = BaseEndpointArgs & { body: ShareItemBody };
|
||||
|
||||
export type ShareItemBody = {
|
||||
description: string;
|
||||
|
|
@ -938,7 +940,6 @@ export type ShareItemResponse = undefined | { id: string };
|
|||
export type UpdatePlaylistArgs = BaseEndpointArgs & {
|
||||
body: UpdatePlaylistBody;
|
||||
query: UpdatePlaylistQuery;
|
||||
serverId?: string;
|
||||
};
|
||||
|
||||
export type UpdatePlaylistBody = {
|
||||
|
|
@ -1135,7 +1136,6 @@ export type RandomSongListResponse = SongListResponse;
|
|||
|
||||
export type ScrobbleArgs = BaseEndpointArgs & {
|
||||
query: ScrobbleQuery;
|
||||
serverId?: string;
|
||||
};
|
||||
|
||||
export type ScrobbleQuery = {
|
||||
|
|
@ -1279,6 +1279,85 @@ export type FontData = {
|
|||
style: string;
|
||||
};
|
||||
|
||||
export type InternalControllerEndpoint = {
|
||||
addToPlaylist: (
|
||||
args: ReplaceApiClientProps<AddToPlaylistArgs>,
|
||||
) => Promise<AddToPlaylistResponse>;
|
||||
authenticate: (
|
||||
url: string,
|
||||
body: { legacy?: boolean; password: string; username: string },
|
||||
) => Promise<AuthenticationResponse>;
|
||||
createFavorite: (args: ReplaceApiClientProps<FavoriteArgs>) => Promise<FavoriteResponse>;
|
||||
createPlaylist: (
|
||||
args: ReplaceApiClientProps<CreatePlaylistArgs>,
|
||||
) => Promise<CreatePlaylistResponse>;
|
||||
deleteFavorite: (args: ReplaceApiClientProps<FavoriteArgs>) => Promise<FavoriteResponse>;
|
||||
deletePlaylist: (
|
||||
args: ReplaceApiClientProps<DeletePlaylistArgs>,
|
||||
) => Promise<DeletePlaylistResponse>;
|
||||
getAlbumArtistDetail: (
|
||||
args: ReplaceApiClientProps<AlbumArtistDetailArgs>,
|
||||
) => Promise<AlbumArtistDetailResponse>;
|
||||
getAlbumArtistList: (
|
||||
args: ReplaceApiClientProps<AlbumArtistListArgs>,
|
||||
) => Promise<AlbumArtistListResponse>;
|
||||
getAlbumArtistListCount: (
|
||||
args: ReplaceApiClientProps<AlbumArtistListCountArgs>,
|
||||
) => Promise<number>;
|
||||
getAlbumDetail: (args: ReplaceApiClientProps<AlbumDetailArgs>) => Promise<AlbumDetailResponse>;
|
||||
getAlbumInfo?: (args: ReplaceApiClientProps<AlbumDetailArgs>) => Promise<AlbumInfo>;
|
||||
getAlbumList: (args: ReplaceApiClientProps<AlbumListArgs>) => Promise<AlbumListResponse>;
|
||||
getAlbumListCount: (args: ReplaceApiClientProps<AlbumListCountArgs>) => Promise<number>;
|
||||
// getArtistInfo?: (args: any) => void;
|
||||
getArtistList: (args: ReplaceApiClientProps<ArtistListArgs>) => Promise<ArtistListResponse>;
|
||||
getArtistListCount: (args: ReplaceApiClientProps<ArtistListCountArgs>) => Promise<number>;
|
||||
getDownloadUrl: (args: ReplaceApiClientProps<DownloadArgs>) => string;
|
||||
getGenreList: (args: ReplaceApiClientProps<GenreListArgs>) => Promise<GenreListResponse>;
|
||||
getLyrics?: (args: ReplaceApiClientProps<LyricsArgs>) => Promise<LyricsResponse>;
|
||||
getMusicFolderList: (
|
||||
args: ReplaceApiClientProps<MusicFolderListArgs>,
|
||||
) => Promise<MusicFolderListResponse>;
|
||||
getPlaylistDetail: (
|
||||
args: ReplaceApiClientProps<PlaylistDetailArgs>,
|
||||
) => Promise<PlaylistDetailResponse>;
|
||||
getPlaylistList: (
|
||||
args: ReplaceApiClientProps<PlaylistListArgs>,
|
||||
) => Promise<PlaylistListResponse>;
|
||||
getPlaylistListCount: (args: ReplaceApiClientProps<PlaylistListCountArgs>) => Promise<number>;
|
||||
getPlaylistSongList: (
|
||||
args: ReplaceApiClientProps<PlaylistSongListArgs>,
|
||||
) => Promise<SongListResponse>;
|
||||
getRandomSongList: (
|
||||
args: ReplaceApiClientProps<RandomSongListArgs>,
|
||||
) => Promise<SongListResponse>;
|
||||
getRoles: (
|
||||
args: ReplaceApiClientProps<BaseEndpointArgs>,
|
||||
) => Promise<Array<string | { label: string; value: string }>>;
|
||||
getServerInfo: (args: ReplaceApiClientProps<ServerInfoArgs>) => Promise<ServerInfo>;
|
||||
getSimilarSongs: (args: ReplaceApiClientProps<SimilarSongsArgs>) => Promise<Song[]>;
|
||||
getSongDetail: (args: ReplaceApiClientProps<SongDetailArgs>) => Promise<SongDetailResponse>;
|
||||
getSongList: (args: ReplaceApiClientProps<SongListArgs>) => Promise<SongListResponse>;
|
||||
getSongListCount: (args: ReplaceApiClientProps<SongListCountArgs>) => Promise<number>;
|
||||
getStructuredLyrics?: (
|
||||
args: ReplaceApiClientProps<StructuredLyricsArgs>,
|
||||
) => Promise<StructuredLyric[]>;
|
||||
getTags?: (args: ReplaceApiClientProps<TagArgs>) => Promise<TagResponses>;
|
||||
getTopSongs: (args: ReplaceApiClientProps<TopSongListArgs>) => Promise<TopSongListResponse>;
|
||||
getTranscodingUrl: (args: ReplaceApiClientProps<TranscodingArgs>) => string;
|
||||
getUserList?: (args: ReplaceApiClientProps<UserListArgs>) => Promise<UserListResponse>;
|
||||
movePlaylistItem?: (args: ReplaceApiClientProps<MoveItemArgs>) => Promise<void>;
|
||||
removeFromPlaylist: (
|
||||
args: ReplaceApiClientProps<RemoveFromPlaylistArgs>,
|
||||
) => Promise<RemoveFromPlaylistResponse>;
|
||||
scrobble: (args: ReplaceApiClientProps<ScrobbleArgs>) => Promise<ScrobbleResponse>;
|
||||
search: (args: ReplaceApiClientProps<SearchArgs>) => Promise<SearchResponse>;
|
||||
setRating?: (args: ReplaceApiClientProps<SetRatingArgs>) => Promise<RatingResponse>;
|
||||
shareItem?: (args: ReplaceApiClientProps<ShareItemArgs>) => Promise<ShareItemResponse>;
|
||||
updatePlaylist: (
|
||||
args: ReplaceApiClientProps<UpdatePlaylistArgs>,
|
||||
) => Promise<UpdatePlaylistResponse>;
|
||||
};
|
||||
|
||||
export type LyricGetQuery = {
|
||||
remoteSongId: string;
|
||||
remoteSource: LyricSource;
|
||||
|
|
@ -1305,6 +1384,8 @@ export type MoveItemQuery = {
|
|||
trackId: string;
|
||||
};
|
||||
|
||||
export type ReplaceApiClientProps<T> = BaseEndpointArgsWithServer & Omit<T, 'apiClientProps'>;
|
||||
|
||||
export type ServerInfo = {
|
||||
features: ServerFeatures;
|
||||
id?: string;
|
||||
|
|
@ -1370,6 +1451,14 @@ export type TranscodingQuery = {
|
|||
format?: string;
|
||||
};
|
||||
|
||||
type BaseEndpointArgsWithServer = {
|
||||
apiClientProps: {
|
||||
server: null | ServerListItemWithCredential;
|
||||
serverId: string;
|
||||
signal?: AbortSignal;
|
||||
};
|
||||
};
|
||||
|
||||
export const sortAlbumList = (albums: Album[], sortBy: AlbumListSort, sortOrder: SortOrder) => {
|
||||
let results = albums;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue