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