mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-06 20:10:12 +02:00
convert EN localization to use proper casing, remove postprocessing from renderer
This commit is contained in:
+943
-943
File diff suppressed because it is too large
Load Diff
+63
-183
@@ -34,10 +34,8 @@ const apiController = <K extends keyof ControllerEndpoint>(
|
||||
|
||||
if (!serverType) {
|
||||
toast.error({
|
||||
message: i18n.t('error.serverNotSelectedError', {
|
||||
postProcess: 'sentenceCase',
|
||||
}) as string,
|
||||
title: i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' }) as string,
|
||||
message: i18n.t('error.serverNotSelectedError') as string,
|
||||
title: i18n.t('error.apiRouteError') as string,
|
||||
});
|
||||
throw new Error(`No server selected`);
|
||||
}
|
||||
@@ -47,13 +45,13 @@ const apiController = <K extends keyof ControllerEndpoint>(
|
||||
if (typeof controllerFn !== 'function') {
|
||||
toast.error({
|
||||
message: `Endpoint ${endpoint} is not implemented for ${serverType}`,
|
||||
title: i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' }) as string,
|
||||
title: i18n.t('error.apiRouteError') as string,
|
||||
});
|
||||
|
||||
throw new Error(
|
||||
i18n.t('error.endpointNotImplementedError', {
|
||||
endpoint,
|
||||
postProcess: 'sentenceCase',
|
||||
|
||||
serverType,
|
||||
}) as string,
|
||||
);
|
||||
@@ -92,9 +90,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: addToPlaylist`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: addToPlaylist`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -109,9 +105,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: createFavorite`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: createFavorite`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -123,9 +117,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: createInternetRadioStation`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: createInternetRadioStation`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -137,9 +129,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: createPlaylist`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: createPlaylist`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -151,9 +141,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: deleteArtistImage`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: deleteArtistImage`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -165,9 +153,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: deleteFavorite`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: deleteFavorite`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -179,9 +165,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: deleteInternetRadioStation`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: deleteInternetRadioStation`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -193,9 +177,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: deleteInternetRadioStationImage`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: deleteInternetRadioStationImage`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -207,9 +189,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: deletePlaylist`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: deletePlaylist`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -221,9 +201,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: deletePlaylistImage`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: deletePlaylistImage`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -235,9 +213,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getAlbumArtistDetail`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getAlbumArtistDetail`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -261,9 +237,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getAlbumArtistList`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getAlbumArtistList`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -281,9 +255,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getAlbumArtistListCount`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getAlbumArtistListCount`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -301,9 +273,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getAlbumDetail`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getAlbumDetail`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -315,9 +285,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getAlbumInfo`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getAlbumInfo`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -329,9 +297,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getAlbumList`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getAlbumList`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -349,9 +315,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getAlbumListCount`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getAlbumListCount`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -369,9 +333,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getAlbumRadio`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getAlbumRadio`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -383,9 +345,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getArtistList`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getArtistList`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -403,9 +363,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getArtistListCount`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getArtistListCount`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -423,9 +381,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getArtistRadio`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getArtistRadio`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -437,9 +393,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getDownloadUrl`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getDownloadUrl`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -451,9 +405,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getFolder`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getFolder`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -471,9 +423,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getGenreList`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getGenreList`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -529,9 +479,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getInternetRadioStations`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getInternetRadioStations`);
|
||||
}
|
||||
return apiController(
|
||||
'getInternetRadioStations',
|
||||
@@ -542,9 +490,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getLyrics`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getLyrics`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -556,9 +502,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getMusicFolderList`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getMusicFolderList`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -570,9 +514,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getPlaylistDetail`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getPlaylistDetail`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -584,9 +526,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getPlaylistList`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getPlaylistList`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -598,9 +538,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getPlaylistListCount`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getPlaylistListCount`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -612,9 +550,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getPlaylistSongList`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getPlaylistSongList`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -626,9 +562,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getPlayQueue`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getPlayQueue`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -640,9 +574,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getRandomSongList`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getRandomSongList`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -660,9 +592,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getRoles`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getRoles`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -674,9 +604,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getServerInfo`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getServerInfo`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -688,9 +616,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getSimilarSongs`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getSimilarSongs`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -708,9 +634,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getSongDetail`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getSongDetail`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -722,9 +646,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getSongList`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getSongList`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -742,9 +664,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getSongListCount`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getSongListCount`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -762,9 +682,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getStreamUrl`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getStreamUrl`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -776,9 +694,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getStructuredLyrics`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getStructuredLyrics`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -790,9 +706,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getTags`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getTags`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -804,9 +718,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getTopSongs`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getTopSongs`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -818,9 +730,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getUserInfo`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getUserInfo`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -832,9 +742,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: getUserList`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: getUserList`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -846,9 +754,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: movePlaylistItem`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: movePlaylistItem`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -860,9 +766,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: removeFromPlaylist`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: removeFromPlaylist`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -874,9 +778,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: replacePlaylist`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: replacePlaylist`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -888,9 +790,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: savePlayQueue`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: savePlayQueue`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -902,9 +802,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: scrobble`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: scrobble`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -916,9 +814,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: search`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: search`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -936,9 +832,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: setPlaylistSongs`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: setPlaylistSongs`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -950,9 +844,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: setRating`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: setRating`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -964,9 +856,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: shareItem`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: shareItem`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -978,9 +868,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: updateInternetRadioStation`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: updateInternetRadioStation`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -992,9 +880,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: updatePlaylist`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: updatePlaylist`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -1006,9 +892,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: uploadArtistImage`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: uploadArtistImage`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -1020,9 +904,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: uploadInternetRadioStationImage`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: uploadInternetRadioStationImage`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
@@ -1034,9 +916,7 @@ export const controller: GeneralController = {
|
||||
const server = getServerById(args.apiClientProps.serverId);
|
||||
|
||||
if (!server) {
|
||||
throw new Error(
|
||||
`${i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' })}: uploadPlaylistImage`,
|
||||
);
|
||||
throw new Error(`${i18n.t('error.apiRouteError')}: uploadPlaylistImage`);
|
||||
}
|
||||
|
||||
return apiController(
|
||||
|
||||
@@ -447,11 +447,7 @@ export const jfApiClient = (args: {
|
||||
} catch (e: any | AxiosError | Error) {
|
||||
if (isAxiosError(e)) {
|
||||
if (e.code === 'ERR_NETWORK') {
|
||||
throw new Error(
|
||||
i18n.t('error.networkError', {
|
||||
postProcess: 'sentenceCase',
|
||||
}) as string,
|
||||
);
|
||||
throw new Error(i18n.t('error.networkError') as string);
|
||||
}
|
||||
|
||||
const error = e as AxiosError;
|
||||
|
||||
@@ -405,12 +405,8 @@ axiosClient.interceptors.response.use(
|
||||
|
||||
if (res.status === 429) {
|
||||
toast.error({
|
||||
message: i18n.t('error.loginRateError', {
|
||||
postProcess: 'sentenceCase',
|
||||
}) as string,
|
||||
title: i18n.t('error.sessionExpiredError', {
|
||||
postProcess: 'sentenceCase',
|
||||
}) as string,
|
||||
message: i18n.t('error.loginRateError') as string,
|
||||
title: i18n.t('error.sessionExpiredError') as string,
|
||||
});
|
||||
|
||||
const serverId = currentServer.id;
|
||||
@@ -425,11 +421,7 @@ axiosClient.interceptors.response.use(
|
||||
throw TIMEOUT_ERROR;
|
||||
}
|
||||
if (res.status !== 200) {
|
||||
throw new Error(
|
||||
i18n.t('error.authenticatedFailed', {
|
||||
postProcess: 'sentenceCase',
|
||||
}) as string,
|
||||
);
|
||||
throw new Error(i18n.t('error.authenticatedFailed') as string);
|
||||
}
|
||||
|
||||
const newCredential = res.data.token;
|
||||
@@ -522,11 +514,7 @@ export const ndApiClient = (args: {
|
||||
} catch (e: any | AxiosError | Error) {
|
||||
if (isAxiosError(e)) {
|
||||
if (e.code === 'ERR_NETWORK') {
|
||||
throw new Error(
|
||||
i18n.t('error.networkError', {
|
||||
postProcess: 'sentenceCase',
|
||||
}) as string,
|
||||
);
|
||||
throw new Error(i18n.t('error.networkError') as string);
|
||||
}
|
||||
|
||||
const error = e as AxiosError;
|
||||
|
||||
@@ -361,7 +361,7 @@ axiosClient.interceptors.response.use(
|
||||
if (data['subsonic-response'].error.code !== 0) {
|
||||
toast.error({
|
||||
message: data['subsonic-response'].error.message,
|
||||
title: i18n.t('error.genericError', { postProcess: 'sentenceCase' }) as string,
|
||||
title: i18n.t('error.genericError') as string,
|
||||
});
|
||||
|
||||
// Since we do status === 200, override this value with the error code
|
||||
@@ -523,11 +523,7 @@ export const ssApiClient = (args: {
|
||||
} catch (e: any | AxiosError | Error) {
|
||||
if (isAxiosError(e)) {
|
||||
if (e.code === 'ERR_NETWORK') {
|
||||
throw new Error(
|
||||
i18n.t('error.networkError', {
|
||||
postProcess: 'sentenceCase',
|
||||
}) as string,
|
||||
);
|
||||
throw new Error(i18n.t('error.networkError') as string);
|
||||
}
|
||||
|
||||
const error = e as AxiosError;
|
||||
|
||||
+4
-8
@@ -313,12 +313,10 @@ const PlaylistReorderColumnBase = (props: ItemTableListInnerColumn) => {
|
||||
<>
|
||||
<Stack gap="xs" justify="center">
|
||||
<Text fw={500} ta="center">
|
||||
{t('action.moveUp', { postProcess: 'sentenceCase' })}
|
||||
{t('action.moveUp')}
|
||||
</Text>
|
||||
<Text fw={500} isMuted size="xs" ta="center">
|
||||
{t('action.holdToMoveToTop', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('action.holdToMoveToTop')}
|
||||
</Text>
|
||||
</Stack>
|
||||
</>
|
||||
@@ -336,12 +334,10 @@ const PlaylistReorderColumnBase = (props: ItemTableListInnerColumn) => {
|
||||
<>
|
||||
<Stack gap="xs" justify="center">
|
||||
<Text fw={500} ta="center">
|
||||
{t('action.moveDown', { postProcess: 'sentenceCase' })}
|
||||
{t('action.moveDown')}
|
||||
</Text>
|
||||
<Text fw={500} isMuted size="xs" ta="center">
|
||||
{t('action.holdToMoveToBottom', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('action.holdToMoveToBottom')}
|
||||
</Text>
|
||||
</Stack>
|
||||
</>
|
||||
|
||||
@@ -17,7 +17,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'start',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.albumGroup', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.albumGroup'),
|
||||
pinned: 'left',
|
||||
value: TableColumn.ALBUM_GROUP,
|
||||
width: 200,
|
||||
@@ -26,7 +26,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.rowIndex', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.rowIndex'),
|
||||
pinned: null,
|
||||
value: TableColumn.ROW_INDEX,
|
||||
width: 60,
|
||||
@@ -35,7 +35,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.image', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.image'),
|
||||
pinned: null,
|
||||
value: TableColumn.IMAGE,
|
||||
width: 70,
|
||||
@@ -44,7 +44,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'start',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.title', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.title'),
|
||||
pinned: null,
|
||||
value: TableColumn.TITLE,
|
||||
width: 300,
|
||||
@@ -53,7 +53,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'start',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.titleCombined', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.titleCombined'),
|
||||
pinned: null,
|
||||
value: TableColumn.TITLE_COMBINED,
|
||||
width: 300,
|
||||
@@ -62,7 +62,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'start',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.titleArtist', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.titleArtist'),
|
||||
pinned: null,
|
||||
value: TableColumn.TITLE_ARTIST,
|
||||
width: 300,
|
||||
@@ -71,7 +71,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.duration', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.duration'),
|
||||
pinned: null,
|
||||
value: TableColumn.DURATION,
|
||||
width: 100,
|
||||
@@ -80,7 +80,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'start',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.album', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.album'),
|
||||
pinned: null,
|
||||
value: TableColumn.ALBUM,
|
||||
width: 300,
|
||||
@@ -89,7 +89,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'start',
|
||||
autoSize: true,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.albumArtist', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.albumArtist'),
|
||||
pinned: null,
|
||||
value: TableColumn.ALBUM_ARTIST,
|
||||
width: 300,
|
||||
@@ -98,7 +98,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'start',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.artist', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.artist'),
|
||||
pinned: null,
|
||||
value: TableColumn.ARTIST,
|
||||
width: 300,
|
||||
@@ -107,7 +107,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'start',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.composer', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.composer'),
|
||||
pinned: null,
|
||||
value: TableColumn.COMPOSER,
|
||||
width: 300,
|
||||
@@ -116,7 +116,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'start',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.genre', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.genre'),
|
||||
pinned: null,
|
||||
value: TableColumn.GENRE,
|
||||
width: 300,
|
||||
@@ -125,7 +125,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'start',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.genreBadge', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.genreBadge'),
|
||||
pinned: null,
|
||||
value: TableColumn.GENRE_BADGE,
|
||||
width: 300,
|
||||
@@ -134,7 +134,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.year', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.year'),
|
||||
pinned: null,
|
||||
value: TableColumn.YEAR,
|
||||
width: 200,
|
||||
@@ -143,7 +143,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.releaseDate', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.releaseDate'),
|
||||
pinned: null,
|
||||
value: TableColumn.RELEASE_DATE,
|
||||
width: 240,
|
||||
@@ -152,7 +152,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.discNumber', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.discNumber'),
|
||||
pinned: null,
|
||||
value: TableColumn.DISC_NUMBER,
|
||||
width: 100,
|
||||
@@ -161,7 +161,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.trackNumber', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.trackNumber'),
|
||||
pinned: null,
|
||||
value: TableColumn.TRACK_NUMBER,
|
||||
width: 100,
|
||||
@@ -170,7 +170,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.bitDepth', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.bitDepth'),
|
||||
pinned: null,
|
||||
value: TableColumn.BIT_DEPTH,
|
||||
width: 100,
|
||||
@@ -179,7 +179,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.bitrate', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.bitrate'),
|
||||
pinned: null,
|
||||
value: TableColumn.BIT_RATE,
|
||||
width: 100,
|
||||
@@ -188,7 +188,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.codec', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.codec'),
|
||||
pinned: null,
|
||||
value: TableColumn.CODEC,
|
||||
width: 100,
|
||||
@@ -197,7 +197,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.sampleRate', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.sampleRate'),
|
||||
pinned: null,
|
||||
value: TableColumn.SAMPLE_RATE,
|
||||
width: 100,
|
||||
@@ -206,7 +206,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.lastPlayed', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.lastPlayed'),
|
||||
pinned: null,
|
||||
value: TableColumn.LAST_PLAYED,
|
||||
width: 150,
|
||||
@@ -215,7 +215,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'start',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.note', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.note'),
|
||||
pinned: null,
|
||||
value: TableColumn.COMMENT,
|
||||
width: 300,
|
||||
@@ -224,7 +224,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.channels', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.channels'),
|
||||
pinned: null,
|
||||
value: TableColumn.CHANNELS,
|
||||
width: 100,
|
||||
@@ -233,7 +233,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.bpm', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.bpm'),
|
||||
pinned: null,
|
||||
value: TableColumn.BPM,
|
||||
width: 100,
|
||||
@@ -242,7 +242,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.dateAdded', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.dateAdded'),
|
||||
pinned: null,
|
||||
value: TableColumn.DATE_ADDED,
|
||||
width: 120,
|
||||
@@ -251,7 +251,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'start',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.path', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.path'),
|
||||
pinned: null,
|
||||
value: TableColumn.PATH,
|
||||
width: 300,
|
||||
@@ -260,7 +260,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.playCount', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.playCount'),
|
||||
pinned: null,
|
||||
value: TableColumn.PLAY_COUNT,
|
||||
width: 100,
|
||||
@@ -269,7 +269,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.size', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.size'),
|
||||
pinned: null,
|
||||
value: TableColumn.SIZE,
|
||||
width: 100,
|
||||
@@ -278,7 +278,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.favorite', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.favorite'),
|
||||
pinned: null,
|
||||
value: TableColumn.USER_FAVORITE,
|
||||
width: 60,
|
||||
@@ -287,7 +287,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.rating', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.rating'),
|
||||
pinned: null,
|
||||
value: TableColumn.USER_RATING,
|
||||
width: 100,
|
||||
@@ -296,7 +296,7 @@ export const SONG_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.actions', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.actions'),
|
||||
pinned: null,
|
||||
value: TableColumn.ACTIONS,
|
||||
width: 60,
|
||||
@@ -310,7 +310,7 @@ export const ALBUM_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.rowIndex', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.rowIndex'),
|
||||
pinned: null,
|
||||
value: TableColumn.ROW_INDEX,
|
||||
width: 60,
|
||||
@@ -319,7 +319,7 @@ export const ALBUM_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.image', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.image'),
|
||||
pinned: null,
|
||||
value: TableColumn.IMAGE,
|
||||
width: 70,
|
||||
@@ -328,7 +328,7 @@ export const ALBUM_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'start',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.title', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.title'),
|
||||
pinned: null,
|
||||
value: TableColumn.TITLE,
|
||||
width: 300,
|
||||
@@ -337,7 +337,7 @@ export const ALBUM_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'start',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.titleCombined', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.titleCombined'),
|
||||
pinned: null,
|
||||
value: TableColumn.TITLE_COMBINED,
|
||||
width: 300,
|
||||
@@ -346,7 +346,7 @@ export const ALBUM_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'start',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.titleArtist', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.titleArtist'),
|
||||
pinned: null,
|
||||
value: TableColumn.TITLE_ARTIST,
|
||||
width: 300,
|
||||
@@ -355,7 +355,7 @@ export const ALBUM_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.duration', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.duration'),
|
||||
pinned: null,
|
||||
value: TableColumn.DURATION,
|
||||
width: 100,
|
||||
@@ -364,7 +364,7 @@ export const ALBUM_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'start',
|
||||
autoSize: true,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.albumArtist', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.albumArtist'),
|
||||
pinned: null,
|
||||
value: TableColumn.ALBUM_ARTIST,
|
||||
width: 300,
|
||||
@@ -373,7 +373,7 @@ export const ALBUM_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'start',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.artist', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.artist'),
|
||||
pinned: null,
|
||||
value: TableColumn.ARTIST,
|
||||
width: 300,
|
||||
@@ -382,7 +382,7 @@ export const ALBUM_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'start',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.composer', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.composer'),
|
||||
pinned: null,
|
||||
value: TableColumn.COMPOSER,
|
||||
width: 300,
|
||||
@@ -391,7 +391,7 @@ export const ALBUM_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.songCount', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.songCount'),
|
||||
pinned: null,
|
||||
value: TableColumn.SONG_COUNT,
|
||||
width: 100,
|
||||
@@ -400,7 +400,7 @@ export const ALBUM_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'start',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.genre', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.genre'),
|
||||
pinned: null,
|
||||
value: TableColumn.GENRE,
|
||||
width: 300,
|
||||
@@ -409,7 +409,7 @@ export const ALBUM_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'start',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.genreBadge', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.genreBadge'),
|
||||
pinned: null,
|
||||
value: TableColumn.GENRE_BADGE,
|
||||
width: 300,
|
||||
@@ -418,7 +418,7 @@ export const ALBUM_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.year', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.year'),
|
||||
pinned: null,
|
||||
value: TableColumn.YEAR,
|
||||
width: 200,
|
||||
@@ -427,7 +427,7 @@ export const ALBUM_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.releaseDate', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.releaseDate'),
|
||||
pinned: null,
|
||||
value: TableColumn.RELEASE_DATE,
|
||||
width: 240,
|
||||
@@ -436,7 +436,7 @@ export const ALBUM_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.lastPlayed', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.lastPlayed'),
|
||||
pinned: null,
|
||||
value: TableColumn.LAST_PLAYED,
|
||||
width: 150,
|
||||
@@ -445,7 +445,7 @@ export const ALBUM_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.dateAdded', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.dateAdded'),
|
||||
pinned: null,
|
||||
value: TableColumn.DATE_ADDED,
|
||||
width: 120,
|
||||
@@ -454,7 +454,7 @@ export const ALBUM_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.playCount', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.playCount'),
|
||||
pinned: null,
|
||||
value: TableColumn.PLAY_COUNT,
|
||||
width: 100,
|
||||
@@ -463,7 +463,7 @@ export const ALBUM_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.favorite', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.favorite'),
|
||||
pinned: null,
|
||||
value: TableColumn.USER_FAVORITE,
|
||||
width: 60,
|
||||
@@ -472,7 +472,7 @@ export const ALBUM_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.rating', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.rating'),
|
||||
pinned: null,
|
||||
value: TableColumn.USER_RATING,
|
||||
width: 100,
|
||||
@@ -481,7 +481,7 @@ export const ALBUM_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.actions', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.actions'),
|
||||
pinned: null,
|
||||
value: TableColumn.ACTIONS,
|
||||
width: 60,
|
||||
@@ -493,7 +493,7 @@ export const ALBUM_ARTIST_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.rowIndex', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.rowIndex'),
|
||||
pinned: null,
|
||||
value: TableColumn.ROW_INDEX,
|
||||
width: 60,
|
||||
@@ -502,7 +502,7 @@ export const ALBUM_ARTIST_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.image', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.image'),
|
||||
pinned: null,
|
||||
value: TableColumn.IMAGE,
|
||||
width: 70,
|
||||
@@ -511,7 +511,7 @@ export const ALBUM_ARTIST_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'start',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.title', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.title'),
|
||||
pinned: null,
|
||||
value: TableColumn.TITLE,
|
||||
width: 300,
|
||||
@@ -520,7 +520,7 @@ export const ALBUM_ARTIST_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.duration', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.duration'),
|
||||
pinned: null,
|
||||
value: TableColumn.DURATION,
|
||||
width: 100,
|
||||
@@ -529,7 +529,7 @@ export const ALBUM_ARTIST_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'start',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.biography', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.biography'),
|
||||
pinned: null,
|
||||
value: TableColumn.BIOGRAPHY,
|
||||
width: 300,
|
||||
@@ -538,7 +538,7 @@ export const ALBUM_ARTIST_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'start',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.genre', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.genre'),
|
||||
pinned: null,
|
||||
value: TableColumn.GENRE,
|
||||
width: 300,
|
||||
@@ -547,7 +547,7 @@ export const ALBUM_ARTIST_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.lastPlayed', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.lastPlayed'),
|
||||
pinned: null,
|
||||
value: TableColumn.LAST_PLAYED,
|
||||
width: 150,
|
||||
@@ -556,7 +556,7 @@ export const ALBUM_ARTIST_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.playCount', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.playCount'),
|
||||
pinned: null,
|
||||
value: TableColumn.PLAY_COUNT,
|
||||
width: 100,
|
||||
@@ -565,7 +565,7 @@ export const ALBUM_ARTIST_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('filter.albumCount', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('filter.albumCount'),
|
||||
pinned: null,
|
||||
value: TableColumn.ALBUM_COUNT,
|
||||
width: 100,
|
||||
@@ -574,7 +574,7 @@ export const ALBUM_ARTIST_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.songCount', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.songCount'),
|
||||
pinned: null,
|
||||
value: TableColumn.SONG_COUNT,
|
||||
width: 100,
|
||||
@@ -583,7 +583,7 @@ export const ALBUM_ARTIST_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.favorite', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.favorite'),
|
||||
pinned: null,
|
||||
value: TableColumn.USER_FAVORITE,
|
||||
width: 60,
|
||||
@@ -592,7 +592,7 @@ export const ALBUM_ARTIST_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.rating', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.rating'),
|
||||
pinned: null,
|
||||
value: TableColumn.USER_RATING,
|
||||
width: 100,
|
||||
@@ -601,7 +601,7 @@ export const ALBUM_ARTIST_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.actions', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.actions'),
|
||||
pinned: null,
|
||||
value: TableColumn.ACTIONS,
|
||||
width: 60,
|
||||
@@ -613,7 +613,7 @@ export const PLAYLIST_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.rowIndex', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.rowIndex'),
|
||||
pinned: null,
|
||||
value: TableColumn.ROW_INDEX,
|
||||
width: 60,
|
||||
@@ -622,7 +622,7 @@ export const PLAYLIST_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.image', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.image'),
|
||||
pinned: null,
|
||||
value: TableColumn.IMAGE,
|
||||
width: 70,
|
||||
@@ -631,7 +631,7 @@ export const PLAYLIST_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'start',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.title', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.title'),
|
||||
pinned: null,
|
||||
value: TableColumn.TITLE,
|
||||
width: 300,
|
||||
@@ -640,7 +640,7 @@ export const PLAYLIST_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'start',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.titleCombined', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.titleCombined'),
|
||||
pinned: null,
|
||||
value: TableColumn.TITLE_COMBINED,
|
||||
width: 300,
|
||||
@@ -649,7 +649,7 @@ export const PLAYLIST_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.duration', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.duration'),
|
||||
pinned: null,
|
||||
value: TableColumn.DURATION,
|
||||
width: 100,
|
||||
@@ -658,7 +658,7 @@ export const PLAYLIST_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.owner', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.owner'),
|
||||
pinned: null,
|
||||
value: TableColumn.OWNER,
|
||||
width: 150,
|
||||
@@ -667,7 +667,7 @@ export const PLAYLIST_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.songCount', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.songCount'),
|
||||
pinned: null,
|
||||
value: TableColumn.SONG_COUNT,
|
||||
width: 100,
|
||||
@@ -676,7 +676,7 @@ export const PLAYLIST_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.actions', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.actions'),
|
||||
pinned: null,
|
||||
value: TableColumn.ACTIONS,
|
||||
width: 60,
|
||||
@@ -688,7 +688,7 @@ export const GENRE_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.rowIndex', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.rowIndex'),
|
||||
pinned: null,
|
||||
value: TableColumn.ROW_INDEX,
|
||||
width: 60,
|
||||
@@ -697,7 +697,7 @@ export const GENRE_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'start',
|
||||
autoSize: true,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.title', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.title'),
|
||||
pinned: null,
|
||||
value: TableColumn.TITLE,
|
||||
width: 300,
|
||||
@@ -706,7 +706,7 @@ export const GENRE_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.songCount', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.songCount'),
|
||||
pinned: null,
|
||||
value: TableColumn.SONG_COUNT,
|
||||
width: 100,
|
||||
@@ -715,7 +715,7 @@ export const GENRE_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: true,
|
||||
label: i18n.t('table.config.label.albumCount', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.albumCount'),
|
||||
pinned: null,
|
||||
value: TableColumn.ALBUM_COUNT,
|
||||
width: 100,
|
||||
@@ -724,7 +724,7 @@ export const GENRE_TABLE_COLUMNS: DefaultTableColumn[] = [
|
||||
align: 'center',
|
||||
autoSize: false,
|
||||
isEnabled: false,
|
||||
label: i18n.t('table.config.label.actions', { postProcess: 'titleCase' }),
|
||||
label: i18n.t('table.config.label.actions'),
|
||||
pinned: null,
|
||||
value: TableColumn.ACTIONS,
|
||||
width: 60,
|
||||
|
||||
@@ -22,17 +22,17 @@ const controls = [
|
||||
{
|
||||
control1: <Kbd>CTRL</Kbd>,
|
||||
control2: <Kbd>A</Kbd>,
|
||||
label: i18n.t('action.selectAll', { postProcess: 'sentenceCase' }),
|
||||
label: i18n.t('action.selectAll'),
|
||||
},
|
||||
{
|
||||
control1: <Kbd>CTRL</Kbd>,
|
||||
control2: <Icon fill="default" icon="mouseLeftClick" />,
|
||||
label: i18n.t('action.addOrRemoveFromSelection', { postProcess: 'sentenceCase' }),
|
||||
label: i18n.t('action.addOrRemoveFromSelection'),
|
||||
},
|
||||
{
|
||||
control1: <Kbd>SHIFT</Kbd>,
|
||||
control2: <Icon fill="default" icon="mouseLeftClick" />,
|
||||
label: i18n.t('action.selectRangeOfItems', { postProcess: 'sentenceCase' }),
|
||||
label: i18n.t('action.selectRangeOfItems'),
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -79,14 +79,12 @@ export const QueryBuilder = ({
|
||||
{
|
||||
label: t('form.queryEditor.input', {
|
||||
context: 'optionMatchAll',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
value: 'all',
|
||||
},
|
||||
{
|
||||
label: t('form.queryEditor.input', {
|
||||
context: 'optionMatchAny',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
value: 'any',
|
||||
},
|
||||
@@ -146,9 +144,7 @@ export const QueryBuilder = ({
|
||||
leftSection={<Icon icon="add" />}
|
||||
onClick={handleAddRuleGroup}
|
||||
>
|
||||
{t('form.queryEditor.addRuleGroup', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('form.queryEditor.addRuleGroup')}
|
||||
</DropdownMenu.Item>
|
||||
|
||||
{level > 0 && (
|
||||
@@ -156,9 +152,7 @@ export const QueryBuilder = ({
|
||||
leftSection={<Icon icon="delete" />}
|
||||
onClick={handleDeleteRuleGroup}
|
||||
>
|
||||
{t('form.queryEditor.removeRuleGroup', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('form.queryEditor.removeRuleGroup')}
|
||||
</DropdownMenu.Item>
|
||||
)}
|
||||
{level === 0 && (
|
||||
@@ -169,18 +163,14 @@ export const QueryBuilder = ({
|
||||
leftSection={<Icon color="error" icon="refresh" />}
|
||||
onClick={onResetFilters}
|
||||
>
|
||||
{t('form.queryEditor.resetToDefault', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('form.queryEditor.resetToDefault')}
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Item
|
||||
isDanger
|
||||
leftSection={<Icon color="error" icon="delete" />}
|
||||
onClick={onClearFilters}
|
||||
>
|
||||
{t('form.queryEditor.clearFilters', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('form.queryEditor.clearFilters')}
|
||||
</DropdownMenu.Item>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -28,11 +28,7 @@ export const SelectWithInvalidData = ({ data, defaultValue, ...props }: SelectPr
|
||||
<Select
|
||||
data={fullData}
|
||||
defaultValue={defaultValue}
|
||||
error={
|
||||
hasError
|
||||
? t('error.badValue', { postProcess: 'sentenceCase', value: defaultValue })
|
||||
: undefined
|
||||
}
|
||||
error={hasError ? t('error.badValue', { value: defaultValue }) : undefined}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
@@ -74,10 +70,7 @@ export const MultiSelectWithInvalidData = ({
|
||||
}, [data, currentValue]);
|
||||
|
||||
const error = useMemo(
|
||||
() =>
|
||||
missing.length
|
||||
? t('error.badValue', { postProcess: 'sentenceCase', value: missing })
|
||||
: undefined,
|
||||
() => (missing.length ? t('error.badValue', { value: missing }) : undefined),
|
||||
[missing, t],
|
||||
);
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ function ServerSelector() {
|
||||
/>
|
||||
),
|
||||
size: 'sm',
|
||||
title: t('form.updateServer.title', { postProcess: 'titleCase' }),
|
||||
title: t('form.updateServer.title'),
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -31,12 +31,12 @@ const ActionRequiredRoute = () => {
|
||||
const checks = [
|
||||
{
|
||||
component: <ServerCredentialRequired />,
|
||||
title: t('error.credentialsRequired', { postProcess: 'sentenceCase' }),
|
||||
title: t('error.credentialsRequired'),
|
||||
valid: !isCredentialRequired,
|
||||
},
|
||||
{
|
||||
component: <ServerRequired />,
|
||||
title: t('error.serverRequired', { postProcess: 'serverRequired' }),
|
||||
title: t('error.serverRequired'),
|
||||
valid: !isServerRequired,
|
||||
},
|
||||
];
|
||||
@@ -47,7 +47,7 @@ const ActionRequiredRoute = () => {
|
||||
const handleManageServersModal = () => {
|
||||
openModal({
|
||||
children: <ServerList />,
|
||||
title: t('page.appMenu.manageServers', { postProcess: 'sentenceCase' }),
|
||||
title: t('page.appMenu.manageServers'),
|
||||
});
|
||||
};
|
||||
|
||||
@@ -79,9 +79,7 @@ const ActionRequiredRoute = () => {
|
||||
onClick={handleManageServersModal}
|
||||
variant="filled"
|
||||
>
|
||||
{t('page.appMenu.manageServers', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.appMenu.manageServers')}
|
||||
</Button>
|
||||
</Group>
|
||||
)}
|
||||
|
||||
@@ -21,9 +21,7 @@ const InvalidRoute = () => {
|
||||
<Stack>
|
||||
<Group justify="center" wrap="nowrap">
|
||||
<Icon color="warn" icon="error" />
|
||||
<Text size="xl">
|
||||
{t('error.apiRouteError', { postProcess: 'sentenceCase' })}
|
||||
</Text>
|
||||
<Text size="xl">{t('error.apiRouteError')}</Text>
|
||||
</Group>
|
||||
<Text>{location.pathname}</Text>
|
||||
<ActionIcon icon="arrowLeftS" onClick={() => navigate(-1)} variant="filled" />
|
||||
|
||||
@@ -28,12 +28,10 @@ const NoNetworkRoute = () => {
|
||||
<Icon icon="wifiOff" size="4rem" />
|
||||
<Stack gap="md">
|
||||
<Text size="xl" weight={600}>
|
||||
{t('error.noNetwork', { postProcess: 'sentenceCase' })}
|
||||
{t('error.noNetwork')}
|
||||
</Text>
|
||||
<Text c="dimmed" size="sm">
|
||||
{t('error.noNetworkDescription', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('error.noNetworkDescription')}
|
||||
</Text>
|
||||
</Stack>
|
||||
<Button
|
||||
@@ -41,7 +39,7 @@ const NoNetworkRoute = () => {
|
||||
onClick={handleRetry}
|
||||
variant="filled"
|
||||
>
|
||||
{t('common.retry', { postProcess: 'sentenceCase' })}
|
||||
{t('common.retry')}
|
||||
</Button>
|
||||
</Stack>
|
||||
</Center>
|
||||
|
||||
@@ -127,9 +127,7 @@ const AlbumMetadataTags = ({ album }: AlbumMetadataTagsProps) => {
|
||||
...releaseTypes,
|
||||
{
|
||||
id: 'isCompilation',
|
||||
value: album?.isCompilation
|
||||
? t('filter.isCompilation', { postProcess: 'sentenceCase' })
|
||||
: undefined,
|
||||
value: album?.isCompilation ? t('filter.isCompilation') : undefined,
|
||||
},
|
||||
...releaseCountries,
|
||||
...releaseStatuses,
|
||||
@@ -137,9 +135,9 @@ const AlbumMetadataTags = ({ album }: AlbumMetadataTagsProps) => {
|
||||
id: 'explicitStatus',
|
||||
value:
|
||||
album.explicitStatus === ExplicitStatus.EXPLICIT
|
||||
? t('common.explicit', { postProcess: 'sentenceCase' })
|
||||
? t('common.explicit')
|
||||
: album.explicitStatus === ExplicitStatus.CLEAN
|
||||
? t('common.clean', { postProcess: 'sentenceCase' })
|
||||
? t('common.clean')
|
||||
: undefined,
|
||||
},
|
||||
);
|
||||
@@ -210,15 +208,12 @@ const AlbumMetadataTags = ({ album }: AlbumMetadataTagsProps) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<MetadataPillGroup
|
||||
items={defaultTagItems}
|
||||
title={t('common.tags', { postProcess: 'sentenceCase' })}
|
||||
/>
|
||||
<MetadataPillGroup items={defaultTagItems} title={t('common.tags')} />
|
||||
|
||||
{recordLabels.length > 0 && (
|
||||
<Stack align="center" className={styles.metadataPillGroup} gap="xs">
|
||||
<Text fw={600} isNoSelect size="sm" tt="uppercase">
|
||||
{t('common.recordLabel', { postProcess: 'sentenceCase' })}
|
||||
{t('common.recordLabel')}
|
||||
</Text>
|
||||
<div className={styles['pill-group-wrapper']}>
|
||||
<Pill.Group>
|
||||
@@ -242,15 +237,12 @@ const AlbumMetadataTags = ({ album }: AlbumMetadataTagsProps) => {
|
||||
</Stack>
|
||||
)}
|
||||
|
||||
<MetadataPillGroup
|
||||
items={moodTagItems}
|
||||
title={t('common.mood', { postProcess: 'sentenceCase' })}
|
||||
/>
|
||||
<MetadataPillGroup items={moodTagItems} title={t('common.mood')} />
|
||||
|
||||
{groupingItems.length > 0 && (
|
||||
<Stack align="center" className={styles.metadataPillGroup} gap="xs">
|
||||
<Text fw={600} isNoSelect size="sm" tt="uppercase">
|
||||
{t('common.grouping', { postProcess: 'sentenceCase' })}
|
||||
{t('common.grouping')}
|
||||
</Text>
|
||||
<div className={styles['pill-group-wrapper']}>
|
||||
<Pill.Group>
|
||||
@@ -402,9 +394,7 @@ const AlbumMetadataExternalLinks = ({
|
||||
return (
|
||||
<Stack gap="xs">
|
||||
<Text fw={600} isNoSelect size="sm" tt="uppercase">
|
||||
{t('common.externalLinks', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('common.externalLinks')}
|
||||
</Text>
|
||||
<Group className={styles.externalLinksGroup} gap="xs">
|
||||
{lastFM && (
|
||||
@@ -634,7 +624,7 @@ const DiscGroupRow = ({ discGroup, groupItems, internalState, t }: DiscGroupRowP
|
||||
id={`disc-${discGroup.discNumber}`}
|
||||
label={
|
||||
<Text component="label" size="sm" truncate>
|
||||
{t('common.disc', { postProcess: 'sentenceCase' })} {discGroup.discNumber}
|
||||
{t('common.disc')} {discGroup.discNumber}
|
||||
{discGroup.discSubtitle && ` - ${discGroup.discSubtitle}`}
|
||||
</Text>
|
||||
}
|
||||
@@ -691,7 +681,7 @@ function AlbumDetailCarousels({ data }: { data: Album }) {
|
||||
rowCount: 1,
|
||||
sortBy: AlbumListSort.YEAR,
|
||||
sortOrder: SortOrder.DESC,
|
||||
title: t('page.albumDetail.moreFromArtist', { postProcess: 'sentenceCase' }),
|
||||
title: t('page.albumDetail.moreFromArtist'),
|
||||
uniqueId: moreFromArtistUniqueId,
|
||||
},
|
||||
...genreCarousels,
|
||||
@@ -878,7 +868,7 @@ const AlbumDetailSongsTable = ({ songs }: AlbumDetailSongsTableProps) => {
|
||||
flex={1}
|
||||
leftSection={<Icon icon="search" />}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
placeholder={t('common.search', { postProcess: 'sentenceCase' })}
|
||||
placeholder={t('common.search')}
|
||||
radius="xl"
|
||||
ref={searchInputRef}
|
||||
rightSection={
|
||||
|
||||
@@ -138,12 +138,10 @@ export const AlbumDetailHeader = forwardRef<HTMLDivElement>((_props, ref) => {
|
||||
|
||||
const playCount = album?.playCount;
|
||||
|
||||
const releasePrefix = originalDifferentFromRelease
|
||||
? t('page.albumDetail.released', { postProcess: 'sentenceCase' })
|
||||
: '♫';
|
||||
const releasePrefix = originalDifferentFromRelease ? t('page.albumDetail.released') : '♫';
|
||||
|
||||
const releaseYearPrefix = originalYearDifferentFromRelease
|
||||
? t('page.albumDetail.released', { postProcess: 'sentenceCase' })
|
||||
? t('page.albumDetail.released')
|
||||
: '♫';
|
||||
|
||||
if (album.originalDate) {
|
||||
|
||||
@@ -38,8 +38,8 @@ export const AlbumListHeaderFilters = ({ toggleGenreTarget }: { toggleGenreTarge
|
||||
|
||||
const choice = useMemo(() => {
|
||||
return target === GenreTarget.ALBUM
|
||||
? t('entity.album', { count: 2, postProcess: 'titleCase' })
|
||||
: t('entity.track', { count: 2, postProcess: 'titleCase' });
|
||||
? t('entity.album', { count: 2 })
|
||||
: t('entity.track', { count: 2 });
|
||||
}, [target, t]);
|
||||
|
||||
const handleToggleGenreTarget = useCallback(() => {
|
||||
|
||||
@@ -55,7 +55,7 @@ const AlbumListHeaderBadge = () => {
|
||||
const PageTitle = ({ title }: { title?: string }) => {
|
||||
const { t } = useTranslation();
|
||||
const { pageKey } = useListContext();
|
||||
const pageTitle = title || t('page.albumList.title', { postProcess: 'titleCase' });
|
||||
const pageTitle = title || t('page.albumList.title');
|
||||
|
||||
switch (pageKey) {
|
||||
case ItemListKey.ALBUM_ARTIST_ALBUM:
|
||||
|
||||
@@ -80,7 +80,7 @@ export const JellyfinAlbumFilters = ({
|
||||
const yesNoFilter = useMemo(() => {
|
||||
const filters = [
|
||||
{
|
||||
label: t('filter.isFavorited', { postProcess: 'sentenceCase' }),
|
||||
label: t('filter.isFavorited'),
|
||||
onChange: (favoriteValue?: boolean) => {
|
||||
setFavorite(favoriteValue ?? null);
|
||||
},
|
||||
@@ -90,7 +90,7 @@ export const JellyfinAlbumFilters = ({
|
||||
|
||||
if (query.artistIds?.length) {
|
||||
filters.push({
|
||||
label: t('filter.isCompilation', { postProcess: 'sentenceCase' }),
|
||||
label: t('filter.isCompilation'),
|
||||
onChange: (compilationValue?: boolean) => {
|
||||
setCompilation(compilationValue ?? null);
|
||||
},
|
||||
@@ -228,16 +228,16 @@ export const JellyfinAlbumFilters = ({
|
||||
return (
|
||||
<Group gap="xs" justify="space-between" w="100%">
|
||||
<Text fw={500} size="sm">
|
||||
{t('entity.artist', { count: 2, postProcess: 'sentenceCase' })}
|
||||
{t('entity.artist', { count: 2 })}
|
||||
</Text>
|
||||
<SegmentedControl
|
||||
data={[
|
||||
{
|
||||
label: t('common.filter_single', { postProcess: 'titleCase' }),
|
||||
label: t('common.filter_single'),
|
||||
value: 'single',
|
||||
},
|
||||
{
|
||||
label: t('common.filter_multiple', { postProcess: 'titleCase' }),
|
||||
label: t('common.filter_multiple'),
|
||||
value: 'multi',
|
||||
},
|
||||
]}
|
||||
@@ -253,16 +253,16 @@ export const JellyfinAlbumFilters = ({
|
||||
return (
|
||||
<Group gap="xs" justify="space-between" w="100%">
|
||||
<Text fw={500} size="sm">
|
||||
{t('entity.genre', { count: 2, postProcess: 'sentenceCase' })}
|
||||
{t('entity.genre', { count: 2 })}
|
||||
</Text>
|
||||
<SegmentedControl
|
||||
data={[
|
||||
{
|
||||
label: t('common.filter_single', { postProcess: 'titleCase' }),
|
||||
label: t('common.filter_single'),
|
||||
value: 'single',
|
||||
},
|
||||
{
|
||||
label: t('common.filter_multiple', { postProcess: 'titleCase' }),
|
||||
label: t('common.filter_multiple'),
|
||||
value: 'multi',
|
||||
},
|
||||
]}
|
||||
@@ -320,7 +320,7 @@ export const JellyfinAlbumFilters = ({
|
||||
<Group grow>
|
||||
<NumberInput
|
||||
hideControls={false}
|
||||
label={t('filter.fromYear', { postProcess: 'sentenceCase' })}
|
||||
label={t('filter.fromYear')}
|
||||
max={2300}
|
||||
min={1700}
|
||||
onChange={(e) => debouncedHandleMinYearFilter(e)}
|
||||
@@ -329,7 +329,7 @@ export const JellyfinAlbumFilters = ({
|
||||
/>
|
||||
<NumberInput
|
||||
hideControls={false}
|
||||
label={t('filter.toYear', { postProcess: 'sentenceCase' })}
|
||||
label={t('filter.toYear')}
|
||||
max={2300}
|
||||
min={1700}
|
||||
onChange={(e) => debouncedHandleMaxYearFilter(e)}
|
||||
|
||||
@@ -101,15 +101,15 @@ export const NavidromeAlbumFilters = ({
|
||||
const segmentedControlData = useMemo(
|
||||
() => [
|
||||
{
|
||||
label: t('common.none', { postProcess: 'titleCase' }),
|
||||
label: t('common.none'),
|
||||
value: 'none',
|
||||
},
|
||||
{
|
||||
label: t('common.yes', { postProcess: 'titleCase' }),
|
||||
label: t('common.yes'),
|
||||
value: 'true',
|
||||
},
|
||||
{
|
||||
label: t('common.no', { postProcess: 'titleCase' }),
|
||||
label: t('common.no'),
|
||||
value: 'false',
|
||||
},
|
||||
],
|
||||
@@ -119,7 +119,7 @@ export const NavidromeAlbumFilters = ({
|
||||
const toggleFilters = useMemo(
|
||||
() => [
|
||||
{
|
||||
label: t('filter.isRecentlyPlayed', { postProcess: 'sentenceCase' }),
|
||||
label: t('filter.isRecentlyPlayed'),
|
||||
onChange: (e: ChangeEvent<HTMLInputElement>) => {
|
||||
const recentlyPlayed = e.currentTarget.checked ? true : undefined;
|
||||
setRecentlyPlayed(recentlyPlayed ?? null);
|
||||
@@ -239,16 +239,16 @@ export const NavidromeAlbumFilters = ({
|
||||
return (
|
||||
<Group gap="xs" justify="space-between" w="100%">
|
||||
<Text fw={500} size="sm">
|
||||
{t('entity.artist', { count: 2, postProcess: 'sentenceCase' })}
|
||||
{t('entity.artist', { count: 2 })}
|
||||
</Text>
|
||||
<SegmentedControl
|
||||
data={[
|
||||
{
|
||||
label: t('common.filter_single', { postProcess: 'titleCase' }),
|
||||
label: t('common.filter_single'),
|
||||
value: 'single',
|
||||
},
|
||||
{
|
||||
label: t('common.filter_multiple', { postProcess: 'titleCase' }),
|
||||
label: t('common.filter_multiple'),
|
||||
value: 'multi',
|
||||
},
|
||||
]}
|
||||
@@ -264,16 +264,16 @@ export const NavidromeAlbumFilters = ({
|
||||
return (
|
||||
<Group gap="xs" justify="space-between" w="100%">
|
||||
<Text fw={500} size="sm">
|
||||
{t('entity.genre', { count: 2, postProcess: 'sentenceCase' })}
|
||||
{t('entity.genre', { count: 2 })}
|
||||
</Text>
|
||||
<SegmentedControl
|
||||
data={[
|
||||
{
|
||||
label: t('common.filter_single', { postProcess: 'titleCase' }),
|
||||
label: t('common.filter_single'),
|
||||
value: 'single',
|
||||
},
|
||||
{
|
||||
label: t('common.filter_multiple', { postProcess: 'titleCase' }),
|
||||
label: t('common.filter_multiple'),
|
||||
value: 'multi',
|
||||
},
|
||||
]}
|
||||
@@ -289,7 +289,7 @@ export const NavidromeAlbumFilters = ({
|
||||
<Stack px="md" py="md">
|
||||
<Stack gap="xs">
|
||||
<Text size="sm" weight={500}>
|
||||
{t('filter.isFavorited', { postProcess: 'sentenceCase' })}
|
||||
{t('filter.isFavorited')}
|
||||
</Text>
|
||||
<SegmentedControl
|
||||
data={segmentedControlData}
|
||||
@@ -303,7 +303,7 @@ export const NavidromeAlbumFilters = ({
|
||||
</Stack>
|
||||
<Stack gap="xs">
|
||||
<Text size="sm" weight={500}>
|
||||
{t('filter.isRated', { postProcess: 'sentenceCase' })}
|
||||
{t('filter.isRated')}
|
||||
</Text>
|
||||
<SegmentedControl
|
||||
data={segmentedControlData}
|
||||
@@ -317,7 +317,7 @@ export const NavidromeAlbumFilters = ({
|
||||
</Stack>
|
||||
<Stack gap="xs">
|
||||
<Text size="sm" weight={500}>
|
||||
{t('filter.isCompilation', { postProcess: 'sentenceCase' })}
|
||||
{t('filter.isCompilation')}
|
||||
</Text>
|
||||
<SegmentedControl
|
||||
data={segmentedControlData}
|
||||
@@ -370,7 +370,7 @@ export const NavidromeAlbumFilters = ({
|
||||
<Divider my="md" />
|
||||
<NumberInput
|
||||
hideControls={false}
|
||||
label={t('common.year', { postProcess: 'titleCase' })}
|
||||
label={t('common.year')}
|
||||
max={5000}
|
||||
min={0}
|
||||
onChange={(e) => debouncedHandleYearFilter(e)}
|
||||
|
||||
@@ -137,7 +137,7 @@ export const SubsonicAlbumFilters = ({
|
||||
const genreFilterLabel = useMemo(() => {
|
||||
return (
|
||||
<Text fw={500} size="sm">
|
||||
{t('entity.genre', { count: 1, postProcess: 'sentenceCase' })}
|
||||
{t('entity.genre', { count: 1 })}
|
||||
</Text>
|
||||
);
|
||||
}, [t]);
|
||||
@@ -145,7 +145,7 @@ export const SubsonicAlbumFilters = ({
|
||||
const toggleFilters = useMemo(
|
||||
() => [
|
||||
{
|
||||
label: t('filter.isFavorited', { postProcess: 'sentenceCase' }),
|
||||
label: t('filter.isFavorited'),
|
||||
onChange: (e: ChangeEvent<HTMLInputElement>) => {
|
||||
if (isFavoriteDisabled && e.target.checked) return; // Prevent setting if disabled
|
||||
const favoriteValue = e.target.checked ? true : undefined;
|
||||
@@ -229,16 +229,16 @@ export const SubsonicAlbumFilters = ({
|
||||
return (
|
||||
<Group gap="xs" justify="space-between" w="100%">
|
||||
<Text fw={500} size="sm">
|
||||
{t('entity.artist', { count: 2, postProcess: 'sentenceCase' })}
|
||||
{t('entity.artist', { count: 2 })}
|
||||
</Text>
|
||||
<SegmentedControl
|
||||
data={[
|
||||
{
|
||||
label: t('common.filter_single', { postProcess: 'titleCase' }),
|
||||
label: t('common.filter_single'),
|
||||
value: 'single',
|
||||
},
|
||||
{
|
||||
label: t('common.filter_multiple', { postProcess: 'titleCase' }),
|
||||
label: t('common.filter_multiple'),
|
||||
value: 'multi',
|
||||
},
|
||||
]}
|
||||
@@ -302,7 +302,7 @@ export const SubsonicAlbumFilters = ({
|
||||
<NumberInput
|
||||
disabled={isYearDisabled}
|
||||
hideControls={false}
|
||||
label={t('filter.fromYear', { postProcess: 'sentenceCase' })}
|
||||
label={t('filter.fromYear')}
|
||||
max={5000}
|
||||
min={0}
|
||||
onChange={(e) => debouncedHandleMinYearFilter(e)}
|
||||
@@ -311,7 +311,7 @@ export const SubsonicAlbumFilters = ({
|
||||
<NumberInput
|
||||
disabled={isYearDisabled}
|
||||
hideControls={false}
|
||||
label={t('filter.toYear', { postProcess: 'sentenceCase' })}
|
||||
label={t('filter.toYear')}
|
||||
max={5000}
|
||||
min={0}
|
||||
onChange={(e) => debouncedHandleMaxYearFilter(e)}
|
||||
|
||||
@@ -234,7 +234,7 @@ const DummyAlbumDetailRoute = () => {
|
||||
<Group mr={5}>
|
||||
<Icon fill="error" icon="error" size={30} />
|
||||
</Group>
|
||||
<h2>{t('error.badAlbum', { postProcess: 'sentenceCase' })}</h2>
|
||||
<h2>{t('error.badAlbum')}</h2>
|
||||
</Center>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
@@ -142,11 +142,7 @@ const AlbumArtistActionButtons = ({
|
||||
size="compact-md"
|
||||
variant="transparent"
|
||||
>
|
||||
{String(
|
||||
t('player.artistRadio', {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
).toUpperCase()}
|
||||
{String(t('player.artistRadio')).toUpperCase()}
|
||||
</Button>
|
||||
)}
|
||||
</Group>
|
||||
@@ -414,9 +410,7 @@ const AlbumArtistMetadataTopSongsContent = ({
|
||||
<div className={styles.albumSectionTitle}>
|
||||
<Group>
|
||||
<TextTitle fw={700} order={3}>
|
||||
{t('page.albumArtistDetail.topSongs', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.albumArtistDetail.topSongs')}
|
||||
</TextTitle>
|
||||
{!isLoading && <Badge>{songs.length}</Badge>}
|
||||
</Group>
|
||||
@@ -431,9 +425,7 @@ const AlbumArtistMetadataTopSongsContent = ({
|
||||
uppercase
|
||||
variant="subtle"
|
||||
>
|
||||
{t('page.albumArtistDetail.viewAll', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.albumArtistDetail.viewAll')}
|
||||
</Button>
|
||||
{songs.length > 0 && (
|
||||
<ActionIconGroup>
|
||||
@@ -485,9 +477,7 @@ const AlbumArtistMetadataTopSongsContent = ({
|
||||
flex={1}
|
||||
leftSection={<Icon icon="search" />}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
placeholder={t('common.search', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
placeholder={t('common.search')}
|
||||
radius="xl"
|
||||
rightSection={
|
||||
searchTerm ? (
|
||||
@@ -510,15 +500,11 @@ const AlbumArtistMetadataTopSongsContent = ({
|
||||
<SegmentedControl
|
||||
data={[
|
||||
{
|
||||
label: t('page.albumArtistDetail.topSongsCommunity', {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
label: t('page.albumArtistDetail.topSongsCommunity'),
|
||||
value: 'community',
|
||||
},
|
||||
{
|
||||
label: t('page.albumArtistDetail.topSongsPersonal', {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
label: t('page.albumArtistDetail.topSongsPersonal'),
|
||||
value: 'personal',
|
||||
},
|
||||
]}
|
||||
@@ -716,9 +702,7 @@ const AlbumArtistMetadataFavoriteSongs = ({
|
||||
<div className={styles.albumSectionTitle}>
|
||||
<Group>
|
||||
<TextTitle fw={700} order={3}>
|
||||
{t('page.albumArtistDetail.favoriteSongs', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.albumArtistDetail.favoriteSongs')}
|
||||
</TextTitle>
|
||||
{!isLoading && <Badge>{songs.length}</Badge>}
|
||||
</Group>
|
||||
@@ -736,9 +720,7 @@ const AlbumArtistMetadataFavoriteSongs = ({
|
||||
uppercase
|
||||
variant="subtle"
|
||||
>
|
||||
{t('page.albumArtistDetail.viewAll', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.albumArtistDetail.viewAll')}
|
||||
</Button>
|
||||
{songs.length > 0 && (
|
||||
<ActionIconGroup>
|
||||
@@ -790,9 +772,7 @@ const AlbumArtistMetadataFavoriteSongs = ({
|
||||
flex={1}
|
||||
leftSection={<Icon icon="search" />}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
placeholder={t('common.search', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
placeholder={t('common.search')}
|
||||
radius="xl"
|
||||
rightSection={
|
||||
searchTerm ? (
|
||||
@@ -941,9 +921,7 @@ const AlbumArtistMetadataExternalLinks = ({
|
||||
<Grid.Col order={order} span={12}>
|
||||
<Stack gap="xs">
|
||||
<Text fw={600} isNoSelect size="sm" tt="uppercase">
|
||||
{t('common.externalLinks', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('common.externalLinks')}
|
||||
</Text>
|
||||
<Group gap="xs">
|
||||
{lastFM && (
|
||||
@@ -1092,9 +1070,7 @@ const AlbumArtistMetadataSimilarArtists = ({
|
||||
() => (
|
||||
<div className={styles.similarArtistsTitle}>
|
||||
<TextTitle fw={700} order={3}>
|
||||
{t('page.albumArtistDetail.relatedArtists', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.albumArtistDetail.relatedArtists')}
|
||||
</TextTitle>
|
||||
<div className={styles.albumSectionDividerContainer}>
|
||||
<div className={styles.albumSectionDivider} />
|
||||
@@ -1432,7 +1408,7 @@ const AlbumSection = memo(function AlbumSection({
|
||||
{hasMoreAlbums && !showAll && (
|
||||
<Group justify="center" w="100%">
|
||||
<Button onClick={() => setShowAll(true)} variant="subtle">
|
||||
{t('action.viewMore', { postProcess: 'sentenceCase' })}
|
||||
{t('action.viewMore')}
|
||||
</Button>
|
||||
</Group>
|
||||
)}
|
||||
@@ -1521,7 +1497,7 @@ const ArtistAlbums = ({ albumsQuery, order }: ArtistAlbumsProps) => {
|
||||
flex={1}
|
||||
leftSection={<Icon icon="search" />}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
placeholder={t('common.search', { postProcess: 'sentenceCase' })}
|
||||
placeholder={t('common.search')}
|
||||
radius="xl"
|
||||
ref={searchInputRef}
|
||||
rightSection={
|
||||
@@ -1585,17 +1561,13 @@ function GroupingTypeSelector() {
|
||||
isSelected={groupingType === 'all'}
|
||||
onClick={() => setAlbumArtistDetailGroupingType('all')}
|
||||
>
|
||||
{t('page.albumArtistDetail.groupingTypeAll', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.albumArtistDetail.groupingTypeAll')}
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Item
|
||||
isSelected={groupingType === 'primary'}
|
||||
onClick={() => setAlbumArtistDetailGroupingType('primary')}
|
||||
>
|
||||
{t('page.albumArtistDetail.groupingTypePrimary', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.albumArtistDetail.groupingTypePrimary')}
|
||||
</DropdownMenu.Item>
|
||||
</DropdownMenu.Dropdown>
|
||||
</DropdownMenu>
|
||||
|
||||
+1
-4
@@ -24,10 +24,7 @@ export const AlbumArtistDetailFavoriteSongsListHeader = ({
|
||||
<LibraryHeaderBar ignoreMaxWidth>
|
||||
<LibraryHeaderBar.PlayButton itemType={LibraryItem.SONG} songs={data} />
|
||||
<LibraryHeaderBar.Title order={2}>
|
||||
{t('page.albumArtistDetail.favoriteSongsFrom', {
|
||||
postProcess: 'titleCase',
|
||||
title,
|
||||
})}
|
||||
{t('page.albumArtistDetail.favoriteSongsFrom', { title })}
|
||||
</LibraryHeaderBar.Title>
|
||||
<Badge>
|
||||
{itemCount === null || itemCount === undefined ? <SpinnerIcon /> : itemCount}
|
||||
|
||||
+1
-4
@@ -24,10 +24,7 @@ export const AlbumArtistDetailTopSongsListHeader = ({
|
||||
<LibraryHeaderBar ignoreMaxWidth>
|
||||
<LibraryHeaderBar.PlayButton itemType={LibraryItem.SONG} songs={data} />
|
||||
<LibraryHeaderBar.Title order={2}>
|
||||
{t('page.albumArtistDetail.topSongsFrom', {
|
||||
postProcess: 'titleCase',
|
||||
title,
|
||||
})}
|
||||
{t('page.albumArtistDetail.topSongsFrom', { title })}
|
||||
</LibraryHeaderBar.Title>
|
||||
<Badge>
|
||||
{itemCount === null || itemCount === undefined ? <SpinnerIcon /> : itemCount}
|
||||
|
||||
@@ -19,7 +19,7 @@ interface AlbumArtistListHeaderProps {
|
||||
export const AlbumArtistListHeader = ({ title }: AlbumArtistListHeaderProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const pageTitle = title || t('page.albumArtistList.title', { postProcess: 'titleCase' });
|
||||
const pageTitle = title || t('page.albumArtistList.title');
|
||||
|
||||
return (
|
||||
<Stack gap={0}>
|
||||
|
||||
@@ -19,7 +19,7 @@ interface ArtistListHeaderProps {
|
||||
export const ArtistListHeader = ({ title }: ArtistListHeaderProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const pageTitle = title || t('entity.artist', { count: 2, postProcess: 'titleCase' });
|
||||
const pageTitle = title || t('entity.artist', { count: 2 });
|
||||
|
||||
return (
|
||||
<Stack gap={0}>
|
||||
|
||||
@@ -182,77 +182,43 @@ export const getArtistAlbumsGrouped = (
|
||||
const getDisplayNameForType = (releaseType: string): string => {
|
||||
switch (releaseType) {
|
||||
case 'album':
|
||||
return t('releaseType.primary.album', {
|
||||
postProcess: 'sentenceCase',
|
||||
});
|
||||
return t('releaseType.primary.album');
|
||||
case 'appears-on':
|
||||
return t('page.albumArtistDetail.appearsOn', {
|
||||
postProcess: 'sentenceCase',
|
||||
});
|
||||
return t('page.albumArtistDetail.appearsOn');
|
||||
case 'audiobook':
|
||||
return t('releaseType.secondary.audiobook', {
|
||||
postProcess: 'sentenceCase',
|
||||
});
|
||||
return t('releaseType.secondary.audiobook');
|
||||
case 'audio drama':
|
||||
return t('releaseType.secondary.audioDrama', {
|
||||
postProcess: 'sentenceCase',
|
||||
});
|
||||
return t('releaseType.secondary.audioDrama');
|
||||
case 'broadcast':
|
||||
return t('releaseType.primary.broadcast', {
|
||||
postProcess: 'sentenceCase',
|
||||
});
|
||||
return t('releaseType.primary.broadcast');
|
||||
case 'compilation':
|
||||
return t('releaseType.secondary.compilation', {
|
||||
postProcess: 'sentenceCase',
|
||||
});
|
||||
return t('releaseType.secondary.compilation');
|
||||
case 'demo':
|
||||
return t('releaseType.secondary.demo', {
|
||||
postProcess: 'sentenceCase',
|
||||
});
|
||||
return t('releaseType.secondary.demo');
|
||||
case 'dj-mix':
|
||||
return t('releaseType.secondary.djMix', {
|
||||
postProcess: 'sentenceCase',
|
||||
});
|
||||
return t('releaseType.secondary.djMix');
|
||||
case 'ep':
|
||||
return t('releaseType.primary.ep', {
|
||||
postProcess: 'upperCase',
|
||||
});
|
||||
case 'field recording':
|
||||
return t('releaseType.secondary.fieldRecording', {
|
||||
postProcess: 'sentenceCase',
|
||||
});
|
||||
return t('releaseType.secondary.fieldRecording');
|
||||
case 'interview':
|
||||
return t('releaseType.secondary.interview', {
|
||||
postProcess: 'sentenceCase',
|
||||
});
|
||||
return t('releaseType.secondary.interview');
|
||||
case 'live':
|
||||
return t('releaseType.secondary.live', {
|
||||
postProcess: 'sentenceCase',
|
||||
});
|
||||
return t('releaseType.secondary.live');
|
||||
case 'mixtape/street':
|
||||
return t('releaseType.secondary.mixtape', {
|
||||
postProcess: 'sentenceCase',
|
||||
});
|
||||
return t('releaseType.secondary.mixtape');
|
||||
case 'other':
|
||||
return t('releaseType.primary.other', {
|
||||
postProcess: 'sentenceCase',
|
||||
});
|
||||
return t('releaseType.primary.other');
|
||||
case 'remix':
|
||||
return t('releaseType.secondary.remix', {
|
||||
postProcess: 'sentenceCase',
|
||||
});
|
||||
return t('releaseType.secondary.remix');
|
||||
case 'single':
|
||||
return t('releaseType.primary.single', {
|
||||
postProcess: 'sentenceCase',
|
||||
});
|
||||
return t('releaseType.primary.single');
|
||||
case 'soundtrack':
|
||||
return t('releaseType.secondary.soundtrack', {
|
||||
postProcess: 'sentenceCase',
|
||||
});
|
||||
return t('releaseType.secondary.soundtrack');
|
||||
case 'spokenword':
|
||||
return t('releaseType.secondary.spokenWord', {
|
||||
postProcess: 'sentenceCase',
|
||||
});
|
||||
return t('releaseType.secondary.spokenWord');
|
||||
default:
|
||||
return titleCase(releaseType);
|
||||
}
|
||||
|
||||
@@ -203,10 +203,7 @@ export const AddToPlaylistAction = ({ items, itemType }: AddToPlaylistActionProp
|
||||
|
||||
if (allSongIds.length === 0) {
|
||||
toast.info({
|
||||
message: t('form.addToPlaylist.noneAdded', {
|
||||
playlist: playlistName,
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
message: t('form.addToPlaylist.noneAdded', { playlist: playlistName }),
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -245,10 +242,7 @@ export const AddToPlaylistAction = ({ items, itemType }: AddToPlaylistActionProp
|
||||
|
||||
if (songsToAdd.length === 0) {
|
||||
toast.info({
|
||||
message: t('form.addToPlaylist.noneAdded', {
|
||||
playlist: playlistName,
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
message: t('form.addToPlaylist.noneAdded', { playlist: playlistName }),
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -267,7 +261,7 @@ export const AddToPlaylistAction = ({ items, itemType }: AddToPlaylistActionProp
|
||||
onError: (err) => {
|
||||
toast.error({
|
||||
message: err.message,
|
||||
title: t('error.genericError', { postProcess: 'sentenceCase' }),
|
||||
title: t('error.genericError'),
|
||||
});
|
||||
},
|
||||
onSuccess: () => {},
|
||||
@@ -278,13 +272,12 @@ export const AddToPlaylistAction = ({ items, itemType }: AddToPlaylistActionProp
|
||||
message: t('form.addToPlaylist.success', {
|
||||
message: songsToAdd.length,
|
||||
numOfPlaylists: 1,
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
});
|
||||
} catch (error) {
|
||||
toast.error({
|
||||
message: (error as Error).message,
|
||||
title: t('error.genericError', { postProcess: 'sentenceCase' }),
|
||||
title: t('error.genericError'),
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -347,7 +340,7 @@ export const AddToPlaylistAction = ({ items, itemType }: AddToPlaylistActionProp
|
||||
},
|
||||
modal: 'addToPlaylist',
|
||||
size: 'lg',
|
||||
title: t('page.contextMenu.addToPlaylist', { postProcess: 'sentenceCase' }),
|
||||
title: t('page.contextMenu.addToPlaylist'),
|
||||
});
|
||||
}, [itemType, items, t]);
|
||||
|
||||
@@ -361,12 +354,11 @@ export const AddToPlaylistAction = ({ items, itemType }: AddToPlaylistActionProp
|
||||
onKeyDown={(e) => e.stopPropagation()}
|
||||
onPointerDown={(e) => e.stopPropagation()}
|
||||
pb="xs"
|
||||
placeholder={t('common.search', { postProcess: 'sentenceCase' })}
|
||||
placeholder={t('common.search')}
|
||||
rightSection={
|
||||
<Tooltip
|
||||
label={t('form.addToPlaylist.input', {
|
||||
context: 'skipDuplicates',
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
>
|
||||
<Checkbox
|
||||
@@ -393,7 +385,7 @@ export const AddToPlaylistAction = ({ items, itemType }: AddToPlaylistActionProp
|
||||
onSelect={handleOpenModal}
|
||||
rightIcon="arrowRightS"
|
||||
>
|
||||
{t('page.contextMenu.addToPlaylist', { postProcess: 'sentenceCase' })}
|
||||
{t('page.contextMenu.addToPlaylist')}
|
||||
</ContextMenu.Item>
|
||||
</ContextMenu.SubmenuTarget>
|
||||
<ContextMenu.SubmenuContent stickyContent={searchInput}>
|
||||
@@ -403,9 +395,7 @@ export const AddToPlaylistAction = ({ items, itemType }: AddToPlaylistActionProp
|
||||
</ContextMenu.Item>
|
||||
)}
|
||||
{playlistsQuery.isError && (
|
||||
<ContextMenu.Item disabled>
|
||||
{t('error.genericError', { postProcess: 'sentenceCase' })}
|
||||
</ContextMenu.Item>
|
||||
<ContextMenu.Item disabled>{t('error.genericError')}</ContextMenu.Item>
|
||||
)}
|
||||
{recentPlaylist && (
|
||||
<>
|
||||
@@ -421,9 +411,7 @@ export const AddToPlaylistAction = ({ items, itemType }: AddToPlaylistActionProp
|
||||
</>
|
||||
)}
|
||||
{filteredPlaylists.length === 0 && !playlistsQuery.isLoading && (
|
||||
<ContextMenu.Item disabled>
|
||||
{t('common.noResultsFromQuery', { postProcess: 'sentenceCase' })}
|
||||
</ContextMenu.Item>
|
||||
<ContextMenu.Item disabled>{t('common.noResultsFromQuery')}</ContextMenu.Item>
|
||||
)}
|
||||
{filteredPlaylists.map((playlist) => (
|
||||
<ContextMenu.Item
|
||||
|
||||
@@ -38,12 +38,12 @@ export const DeletePlaylistAction = ({ disabled, items }: DeletePlaylistActionPr
|
||||
|
||||
navigate(AppRoute.PLAYLISTS, { replace: true });
|
||||
toast.success({
|
||||
message: t('action.deletePlaylist', { postProcess: 'sentenceCase' }),
|
||||
message: t('action.deletePlaylist'),
|
||||
});
|
||||
} catch (err: any) {
|
||||
toast.error({
|
||||
message: err.message,
|
||||
title: t('error.genericError', { postProcess: 'sentenceCase' }),
|
||||
title: t('error.genericError'),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -56,10 +56,10 @@ export const DeletePlaylistAction = ({ disabled, items }: DeletePlaylistActionPr
|
||||
openModal({
|
||||
children: (
|
||||
<ConfirmModal onConfirm={handleDeletePlaylist}>
|
||||
<Text>{t('common.areYouSure', { postProcess: 'sentenceCase' })}</Text>
|
||||
<Text>{t('common.areYouSure')}</Text>
|
||||
</ConfirmModal>
|
||||
),
|
||||
title: t('form.deletePlaylist.title', { postProcess: 'sentenceCase' }),
|
||||
title: t('form.deletePlaylist.title'),
|
||||
});
|
||||
}, [handleDeletePlaylist, items.length, t]);
|
||||
|
||||
@@ -67,7 +67,7 @@ export const DeletePlaylistAction = ({ disabled, items }: DeletePlaylistActionPr
|
||||
|
||||
return (
|
||||
<ContextMenu.Item disabled={disabled} leftIcon="remove" onSelect={openDeletePlaylistModal}>
|
||||
{t('action.deletePlaylist', { postProcess: 'sentenceCase' })}
|
||||
{t('action.deletePlaylist')}
|
||||
</ContextMenu.Item>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -37,7 +37,7 @@ export const DownloadAction = ({ ids }: DownloadActionProps) => {
|
||||
|
||||
return (
|
||||
<ContextMenu.Item disabled={ids.length > 1} leftIcon="download" onSelect={onSelect}>
|
||||
{t('page.contextMenu.download', { postProcess: 'sentenceCase' })}
|
||||
{t('page.contextMenu.download')}
|
||||
</ContextMenu.Item>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -27,7 +27,7 @@ export const EditPlaylistAction = ({ disabled, items }: EditPlaylistActionProps)
|
||||
|
||||
return (
|
||||
<ContextMenu.Item disabled={disabled} leftIcon="edit" onSelect={handleEditPlaylist}>
|
||||
{t('action.editPlaylist', { postProcess: 'sentenceCase' })}
|
||||
{t('action.editPlaylist')}
|
||||
</ContextMenu.Item>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -35,15 +35,14 @@ export const GetInfoAction = ({ disabled, items }: GetInfoActionProps) => {
|
||||
},
|
||||
title:
|
||||
filteredItems.length === 1
|
||||
? filteredItems[0]?.name ||
|
||||
t('page.contextMenu.showDetails', { postProcess: 'sentenceCase' })
|
||||
: t('page.contextMenu.showDetails', { postProcess: 'sentenceCase' }),
|
||||
? filteredItems[0]?.name || t('page.contextMenu.showDetails')
|
||||
: t('page.contextMenu.showDetails'),
|
||||
});
|
||||
}, [items, server, t]);
|
||||
|
||||
return (
|
||||
<ContextMenu.Item disabled={disabled} leftIcon="info" onSelect={onSelect}>
|
||||
{t('page.contextMenu.showDetails', { postProcess: 'sentenceCase' })}
|
||||
{t('page.contextMenu.showDetails')}
|
||||
</ContextMenu.Item>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -72,13 +72,13 @@ export const GoToAction = ({ items }: GoToActionProps) => {
|
||||
onSelect={(e) => e.preventDefault()}
|
||||
rightIcon="arrowRightS"
|
||||
>
|
||||
{t('page.contextMenu.goTo', { postProcess: 'sentenceCase' })}
|
||||
{t('page.contextMenu.goTo')}
|
||||
</ContextMenu.Item>
|
||||
</ContextMenu.SubmenuTarget>
|
||||
<ContextMenu.SubmenuContent>
|
||||
{hasAlbum && (
|
||||
<ContextMenu.Item leftIcon="album" onSelect={handleGoToAlbum}>
|
||||
{t('page.contextMenu.goToAlbum', { postProcess: 'sentenceCase' })}
|
||||
{t('page.contextMenu.goToAlbum')}
|
||||
</ContextMenu.Item>
|
||||
)}
|
||||
{albumArtists.map((albumArtist) => (
|
||||
@@ -87,7 +87,7 @@ export const GoToAction = ({ items }: GoToActionProps) => {
|
||||
leftIcon="artist"
|
||||
onSelect={() => handleGoToAlbumArtist(albumArtist.id)}
|
||||
>
|
||||
{`${t('page.contextMenu.goTo', { postProcess: 'sentenceCase' })} ${albumArtist.name}`}
|
||||
{`${t('page.contextMenu.goTo')} ${albumArtist.name}`}
|
||||
</ContextMenu.Item>
|
||||
))}
|
||||
</ContextMenu.SubmenuContent>
|
||||
|
||||
@@ -33,18 +33,18 @@ export const MoveQueueItemsAction = ({ items }: MoveQueueItemsActionProps) => {
|
||||
onSelect={(e) => e.preventDefault()}
|
||||
rightIcon="arrowRightS"
|
||||
>
|
||||
{t('page.contextMenu.moveItems', { postProcess: 'sentenceCase' })}
|
||||
{t('page.contextMenu.moveItems')}
|
||||
</ContextMenu.Item>
|
||||
</ContextMenu.SubmenuTarget>
|
||||
<ContextMenu.SubmenuContent>
|
||||
<ContextMenu.Item leftIcon="arrowUpToLine" onSelect={handleMoveToTop}>
|
||||
{t('page.contextMenu.moveToTop', { postProcess: 'sentenceCase' })}
|
||||
{t('page.contextMenu.moveToTop')}
|
||||
</ContextMenu.Item>
|
||||
<ContextMenu.Item leftIcon="mediaPlayNext" onSelect={handleMoveToNext}>
|
||||
{t('page.contextMenu.moveToNext', { postProcess: 'sentenceCase' })}
|
||||
{t('page.contextMenu.moveToNext')}
|
||||
</ContextMenu.Item>
|
||||
<ContextMenu.Item leftIcon="arrowDownToLine" onSelect={handleMoveToBottom}>
|
||||
{t('page.contextMenu.moveToBottom', { postProcess: 'sentenceCase' })}
|
||||
{t('page.contextMenu.moveToBottom')}
|
||||
</ContextMenu.Item>
|
||||
</ContextMenu.SubmenuContent>
|
||||
</ContextMenu.Submenu>
|
||||
|
||||
@@ -75,28 +75,28 @@ export const PlayAction = ({ ids, itemType, songs }: PlayActionProps) => {
|
||||
onSelect={defaultPlayAction}
|
||||
rightIcon="arrowRightS"
|
||||
>
|
||||
{t('player.play', { postProcess: 'sentenceCase' })}
|
||||
{t('player.play')}
|
||||
</ContextMenu.Item>
|
||||
</ContextMenu.SubmenuTarget>
|
||||
<ContextMenu.SubmenuContent>
|
||||
<ContextMenu.Item leftIcon="mediaPlay" onSelect={handlePlayNow}>
|
||||
{t('player.play', { postProcess: 'sentenceCase' })}
|
||||
{t('player.play')}
|
||||
</ContextMenu.Item>
|
||||
<ContextMenu.Item leftIcon="mediaPlayNext" onSelect={handlePlayNext}>
|
||||
{t('player.addNext', { postProcess: 'sentenceCase' })}
|
||||
{t('player.addNext')}
|
||||
</ContextMenu.Item>
|
||||
<ContextMenu.Item leftIcon="mediaPlayLast" onSelect={handlePlayLast}>
|
||||
{t('player.addLast', { postProcess: 'sentenceCase' })}
|
||||
{t('player.addLast')}
|
||||
</ContextMenu.Item>
|
||||
<ContextMenu.Divider />
|
||||
<ContextMenu.Item leftIcon="mediaShuffle" onSelect={handlePlayShuffled}>
|
||||
{t('player.shuffle', { postProcess: 'sentenceCase' })}
|
||||
{t('player.shuffle')}
|
||||
</ContextMenu.Item>
|
||||
<ContextMenu.Item leftIcon="mediaPlayNext" onSelect={handlePlayNextShuffled}>
|
||||
{t('player.addNextShuffled', { postProcess: 'sentenceCase' })}
|
||||
{t('player.addNextShuffled')}
|
||||
</ContextMenu.Item>
|
||||
<ContextMenu.Item leftIcon="mediaPlayLast" onSelect={handlePlayLastShuffled}>
|
||||
{t('player.addLastShuffled', { postProcess: 'sentenceCase' })}
|
||||
{t('player.addLastShuffled')}
|
||||
</ContextMenu.Item>
|
||||
</ContextMenu.SubmenuContent>
|
||||
</ContextMenu.Submenu>
|
||||
|
||||
@@ -73,18 +73,18 @@ export const PlayAlbumRadioAction = ({ album, disabled }: PlayAlbumRadioActionPr
|
||||
onSelect={defaultPlayAlbumRadioAction}
|
||||
rightIcon="arrowRightS"
|
||||
>
|
||||
{t('player.albumRadio', { postProcess: 'sentenceCase' })}
|
||||
{t('player.albumRadio')}
|
||||
</ContextMenu.Item>
|
||||
</ContextMenu.SubmenuTarget>
|
||||
<ContextMenu.SubmenuContent>
|
||||
<ContextMenu.Item leftIcon="mediaPlay" onSelect={handlePlayAlbumRadioNow}>
|
||||
{t('player.play', { postProcess: 'sentenceCase' })}
|
||||
{t('player.play')}
|
||||
</ContextMenu.Item>
|
||||
<ContextMenu.Item leftIcon="mediaPlayNext" onSelect={handlePlayAlbumRadioNext}>
|
||||
{t('player.addNext', { postProcess: 'sentenceCase' })}
|
||||
{t('player.addNext')}
|
||||
</ContextMenu.Item>
|
||||
<ContextMenu.Item leftIcon="mediaPlayLast" onSelect={handlePlayAlbumRadioLast}>
|
||||
{t('player.addLast', { postProcess: 'sentenceCase' })}
|
||||
{t('player.addLast')}
|
||||
</ContextMenu.Item>
|
||||
</ContextMenu.SubmenuContent>
|
||||
</ContextMenu.Submenu>
|
||||
|
||||
@@ -73,18 +73,18 @@ export const PlayArtistRadioAction = ({ artist, disabled }: PlayArtistRadioActio
|
||||
onSelect={defaultPlayArtistRadioAction}
|
||||
rightIcon="arrowRightS"
|
||||
>
|
||||
{t('player.artistRadio', { postProcess: 'sentenceCase' })}
|
||||
{t('player.artistRadio')}
|
||||
</ContextMenu.Item>
|
||||
</ContextMenu.SubmenuTarget>
|
||||
<ContextMenu.SubmenuContent>
|
||||
<ContextMenu.Item leftIcon="mediaPlay" onSelect={handlePlayArtistRadioNow}>
|
||||
{t('player.play', { postProcess: 'sentenceCase' })}
|
||||
{t('player.play')}
|
||||
</ContextMenu.Item>
|
||||
<ContextMenu.Item leftIcon="mediaPlayNext" onSelect={handlePlayArtistRadioNext}>
|
||||
{t('player.addNext', { postProcess: 'sentenceCase' })}
|
||||
{t('player.addNext')}
|
||||
</ContextMenu.Item>
|
||||
<ContextMenu.Item leftIcon="mediaPlayLast" onSelect={handlePlayArtistRadioLast}>
|
||||
{t('player.addLast', { postProcess: 'sentenceCase' })}
|
||||
{t('player.addLast')}
|
||||
</ContextMenu.Item>
|
||||
</ContextMenu.SubmenuContent>
|
||||
</ContextMenu.Submenu>
|
||||
|
||||
@@ -72,18 +72,18 @@ export const PlayTrackRadioAction = ({ disabled, song }: PlayTrackRadioActionPro
|
||||
onSelect={defaultPlayTrackRadioAction}
|
||||
rightIcon="arrowRightS"
|
||||
>
|
||||
{t('player.trackRadio', { postProcess: 'sentenceCase' })}
|
||||
{t('player.trackRadio')}
|
||||
</ContextMenu.Item>
|
||||
</ContextMenu.SubmenuTarget>
|
||||
<ContextMenu.SubmenuContent>
|
||||
<ContextMenu.Item leftIcon="mediaPlay" onSelect={handlePlayTrackRadioNow}>
|
||||
{t('player.play', { postProcess: 'sentenceCase' })}
|
||||
{t('player.play')}
|
||||
</ContextMenu.Item>
|
||||
<ContextMenu.Item leftIcon="mediaPlayNext" onSelect={handlePlayTrackRadioNext}>
|
||||
{t('player.addNext', { postProcess: 'sentenceCase' })}
|
||||
{t('player.addNext')}
|
||||
</ContextMenu.Item>
|
||||
<ContextMenu.Item leftIcon="mediaPlayLast" onSelect={handlePlayTrackRadioLast}>
|
||||
{t('player.addLast', { postProcess: 'sentenceCase' })}
|
||||
{t('player.addLast')}
|
||||
</ContextMenu.Item>
|
||||
</ContextMenu.SubmenuContent>
|
||||
</ContextMenu.Submenu>
|
||||
|
||||
@@ -39,12 +39,12 @@ export const RemoveFromPlaylistAction = ({ items }: RemoveFromPlaylistActionProp
|
||||
});
|
||||
|
||||
toast.success({
|
||||
message: t('action.removeFromPlaylist', { postProcess: 'sentenceCase' }),
|
||||
message: t('action.removeFromPlaylist'),
|
||||
});
|
||||
} catch (err: any) {
|
||||
toast.error({
|
||||
message: err.message,
|
||||
title: t('error.genericError', { postProcess: 'sentenceCase' }),
|
||||
title: t('error.genericError'),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -57,10 +57,10 @@ export const RemoveFromPlaylistAction = ({ items }: RemoveFromPlaylistActionProp
|
||||
openModal({
|
||||
children: (
|
||||
<ConfirmModal onConfirm={handleRemoveFromPlaylist}>
|
||||
<Text>{t('common.areYouSure', { postProcess: 'sentenceCase' })}</Text>
|
||||
<Text>{t('common.areYouSure')}</Text>
|
||||
</ConfirmModal>
|
||||
),
|
||||
title: t('action.removeFromPlaylist', { postProcess: 'sentenceCase' }),
|
||||
title: t('action.removeFromPlaylist'),
|
||||
});
|
||||
}, [handleRemoveFromPlaylist, ids, playlistId, t]);
|
||||
|
||||
@@ -68,7 +68,7 @@ export const RemoveFromPlaylistAction = ({ items }: RemoveFromPlaylistActionProp
|
||||
|
||||
return (
|
||||
<ContextMenu.Item leftIcon="remove" onSelect={openRemoveFromPlaylistModal}>
|
||||
{t('action.removeFromPlaylist', { postProcess: 'sentenceCase' })}
|
||||
{t('action.removeFromPlaylist')}
|
||||
</ContextMenu.Item>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -19,7 +19,7 @@ export const RemoveFromQueueAction = ({ items }: RemoveFromQueueActionProps) =>
|
||||
|
||||
return (
|
||||
<ContextMenu.Item leftIcon="remove" onSelect={onSelect}>
|
||||
{t('action.removeFromQueue', { postProcess: 'sentenceCase' })}
|
||||
{t('action.removeFromQueue')}
|
||||
</ContextMenu.Item>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -51,15 +51,15 @@ export const SetFavoriteAction = ({ ids, itemType }: SetFavoriteActionProps) =>
|
||||
onSelect={(e) => e.preventDefault()}
|
||||
rightIcon="arrowRightS"
|
||||
>
|
||||
{t('common.favorite', { postProcess: 'sentenceCase' })}
|
||||
{t('common.favorite')}
|
||||
</ContextMenu.Item>
|
||||
</ContextMenu.SubmenuTarget>
|
||||
<ContextMenu.SubmenuContent>
|
||||
<ContextMenu.Item leftIcon="favorite" onSelect={handleAddToFavorites}>
|
||||
{t('action.addToFavorites', { postProcess: 'sentenceCase' })}
|
||||
{t('action.addToFavorites')}
|
||||
</ContextMenu.Item>
|
||||
<ContextMenu.Item leftIcon="unfavorite" onSelect={handleRemoveFromFavorites}>
|
||||
{t('action.removeFromFavorites', { postProcess: 'sentenceCase' })}
|
||||
{t('action.removeFromFavorites')}
|
||||
</ContextMenu.Item>
|
||||
</ContextMenu.SubmenuContent>
|
||||
</ContextMenu.Submenu>
|
||||
|
||||
@@ -41,7 +41,7 @@ export const SetRatingAction = ({ ids, itemType }: SetRatingActionProps) => {
|
||||
onSelect={(e) => e.preventDefault()}
|
||||
rightIcon="arrowRightS"
|
||||
>
|
||||
{t('action.setRating', { postProcess: 'sentenceCase' })}
|
||||
{t('action.setRating')}
|
||||
</ContextMenu.Item>
|
||||
</ContextMenu.SubmenuTarget>
|
||||
<ContextMenu.SubmenuContent>
|
||||
|
||||
@@ -37,13 +37,13 @@ export const ShareAction = ({ ids, itemType }: ShareActionProps) => {
|
||||
resourceType,
|
||||
},
|
||||
modal: 'shareItem',
|
||||
title: t('page.contextMenu.shareItem', { postProcess: 'titleCase' }),
|
||||
title: t('page.contextMenu.shareItem'),
|
||||
});
|
||||
}, [ids, resourceType, t]);
|
||||
|
||||
return (
|
||||
<ContextMenu.Item leftIcon="share" onSelect={onSelect}>
|
||||
{t('page.contextMenu.shareItem', { postProcess: 'sentenceCase' })}
|
||||
{t('page.contextMenu.shareItem')}
|
||||
</ContextMenu.Item>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -30,9 +30,7 @@ export const ShowInFileExplorerAction = ({ items }: ShowInFileExplorerActionProp
|
||||
} catch (error) {
|
||||
toast.error({
|
||||
message: (error as Error).message,
|
||||
title: t('error.openError', {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
title: t('error.openError'),
|
||||
});
|
||||
}
|
||||
}, [items, t]);
|
||||
@@ -47,7 +45,7 @@ export const ShowInFileExplorerAction = ({ items }: ShowInFileExplorerActionProp
|
||||
|
||||
return (
|
||||
<ContextMenu.Item disabled={isDisabled} leftIcon="folder" onSelect={onSelect}>
|
||||
{t('page.itemDetail.openFile', { postProcess: 'sentenceCase' })}
|
||||
{t('page.itemDetail.openFile')}
|
||||
</ContextMenu.Item>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -29,15 +29,15 @@ export const ShuffleItemsAction = ({ items }: ShuffleItemsActionProps) => {
|
||||
onSelect={(e) => e.preventDefault()}
|
||||
rightIcon="arrowRightS"
|
||||
>
|
||||
{t('action.shuffle', { postProcess: 'sentenceCase' })}
|
||||
{t('action.shuffle')}
|
||||
</ContextMenu.Item>
|
||||
</ContextMenu.SubmenuTarget>
|
||||
<ContextMenu.SubmenuContent>
|
||||
<ContextMenu.Item onSelect={handleShuffleSelected}>
|
||||
{t('action.shuffleSelected', { postProcess: 'sentenceCase' })}
|
||||
{t('action.shuffleSelected')}
|
||||
</ContextMenu.Item>
|
||||
<ContextMenu.Item onSelect={handleShuffleAll}>
|
||||
{t('action.shuffleAll', { postProcess: 'sentenceCase' })}
|
||||
{t('action.shuffleAll')}
|
||||
</ContextMenu.Item>
|
||||
</ContextMenu.SubmenuContent>
|
||||
</ContextMenu.Submenu>
|
||||
|
||||
@@ -79,9 +79,7 @@ export const FavoritesHeader = ({ itemType }: FavoritesHeaderProps) => {
|
||||
<Stack gap={0} style={{ cursor: 'pointer' }}>
|
||||
<Group>
|
||||
<TextTitle isNoSelect order={3}>
|
||||
{t('page.favorites.title', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.favorites.title')}
|
||||
</TextTitle>
|
||||
<Icon icon="dropdown" size="xl" />
|
||||
</Group>
|
||||
@@ -89,17 +87,14 @@ export const FavoritesHeader = ({ itemType }: FavoritesHeaderProps) => {
|
||||
{itemType === LibraryItem.ALBUM &&
|
||||
t('entity.album', {
|
||||
count: 2,
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{itemType === LibraryItem.ALBUM_ARTIST &&
|
||||
t('entity.artist', {
|
||||
count: 2,
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{itemType === LibraryItem.SONG &&
|
||||
t('entity.track', {
|
||||
count: 2,
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</Text>
|
||||
</Stack>
|
||||
@@ -112,7 +107,6 @@ export const FavoritesHeader = ({ itemType }: FavoritesHeaderProps) => {
|
||||
>
|
||||
{t('entity.track', {
|
||||
count: 2,
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Item
|
||||
@@ -122,7 +116,6 @@ export const FavoritesHeader = ({ itemType }: FavoritesHeaderProps) => {
|
||||
>
|
||||
{t('entity.album', {
|
||||
count: 2,
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Item
|
||||
@@ -134,7 +127,6 @@ export const FavoritesHeader = ({ itemType }: FavoritesHeaderProps) => {
|
||||
>
|
||||
{t('entity.artist', {
|
||||
count: 2,
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</DropdownMenu.Item>
|
||||
</DropdownMenu.Dropdown>
|
||||
|
||||
@@ -56,7 +56,7 @@ export const FolderListHeaderFilters = () => {
|
||||
onClick: () => void;
|
||||
}> = [];
|
||||
|
||||
const homeLabel = t('common.home', { postProcess: 'titleCase' });
|
||||
const homeLabel = t('common.home');
|
||||
items.push({
|
||||
fullLabel: homeLabel,
|
||||
id: 'folder-root',
|
||||
|
||||
@@ -18,7 +18,7 @@ interface FolderListHeaderProps {
|
||||
export const FolderListHeader = ({ title }: FolderListHeaderProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const pageTitle = title || t('page.folderList.title', { postProcess: 'titleCase' });
|
||||
const pageTitle = title || t('page.folderList.title');
|
||||
|
||||
return (
|
||||
<Stack gap={0}>
|
||||
|
||||
@@ -23,7 +23,7 @@ export const GenreDetailHeader = ({ title }: GenreDetailHeaderProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { itemCount } = useListContext();
|
||||
const pageTitle = title || t('page.genreList.title', { postProcess: 'titleCase' });
|
||||
const pageTitle = title || t('page.genreList.title');
|
||||
|
||||
const genreTarget = useGenreTarget();
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ interface GenreListHeaderProps {
|
||||
export const GenreListHeader = ({ title }: GenreListHeaderProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const pageTitle = title || t('page.genreList.title', { postProcess: 'titleCase' });
|
||||
const pageTitle = title || t('page.genreList.title');
|
||||
|
||||
return (
|
||||
<Stack gap={0}>
|
||||
|
||||
@@ -120,7 +120,7 @@ export const FeaturedGenres = () => {
|
||||
<>
|
||||
<Group align="flex-end" justify="space-between">
|
||||
<TextTitle fw={700} isNoSelect order={3}>
|
||||
{t('entity.genre', { count: 2, postProcess: 'titleCase' })}
|
||||
{t('entity.genre', { count: 2 })}
|
||||
</TextTitle>
|
||||
<Button
|
||||
component={Link}
|
||||
@@ -128,7 +128,7 @@ export const FeaturedGenres = () => {
|
||||
to={AppRoute.LIBRARY_GENRES}
|
||||
variant="subtle"
|
||||
>
|
||||
{t('action.viewMore', { postProcess: 'sentenceCase' })}
|
||||
{t('action.viewMore')}
|
||||
</Button>
|
||||
</Group>
|
||||
<div className={styles.grid}>
|
||||
|
||||
@@ -50,35 +50,35 @@ const HomeRoute = () => {
|
||||
itemType: isJellyfin ? LibraryItem.SONG : LibraryItem.ALBUM,
|
||||
sortBy: isJellyfin ? SongListSort.PLAY_COUNT : AlbumListSort.PLAY_COUNT,
|
||||
sortOrder: SortOrder.DESC,
|
||||
title: t('page.home.mostPlayed', { postProcess: 'sentenceCase' }),
|
||||
title: t('page.home.mostPlayed'),
|
||||
},
|
||||
[HomeItem.RANDOM]: {
|
||||
enableRefresh: true,
|
||||
itemType: LibraryItem.ALBUM,
|
||||
sortBy: AlbumListSort.RANDOM,
|
||||
sortOrder: SortOrder.ASC,
|
||||
title: t('page.home.explore', { postProcess: 'sentenceCase' }),
|
||||
title: t('page.home.explore'),
|
||||
},
|
||||
[HomeItem.RECENTLY_ADDED]: {
|
||||
enableRefresh: true,
|
||||
itemType: LibraryItem.ALBUM,
|
||||
sortBy: AlbumListSort.RECENTLY_ADDED,
|
||||
sortOrder: SortOrder.DESC,
|
||||
title: t('page.home.newlyAdded', { postProcess: 'sentenceCase' }),
|
||||
title: t('page.home.newlyAdded'),
|
||||
},
|
||||
[HomeItem.RECENTLY_PLAYED]: {
|
||||
enableRefresh: true,
|
||||
itemType: isJellyfin ? LibraryItem.SONG : LibraryItem.ALBUM,
|
||||
sortBy: isJellyfin ? SongListSort.RECENTLY_PLAYED : AlbumListSort.RECENTLY_PLAYED,
|
||||
sortOrder: SortOrder.DESC,
|
||||
title: t('page.home.recentlyPlayed', { postProcess: 'sentenceCase' }),
|
||||
title: t('page.home.recentlyPlayed'),
|
||||
},
|
||||
[HomeItem.RECENTLY_RELEASED]: {
|
||||
enableRefresh: true,
|
||||
itemType: LibraryItem.ALBUM,
|
||||
sortBy: AlbumListSort.RELEASE_DATE,
|
||||
sortOrder: SortOrder.DESC,
|
||||
title: t('page.home.recentlyReleased', { postProcess: 'sentenceCase' }),
|
||||
title: t('page.home.recentlyReleased'),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -98,9 +98,7 @@ const HomeRoute = () => {
|
||||
backgroundColor: 'var(--theme-colors-background)',
|
||||
children: (
|
||||
<LibraryHeaderBar>
|
||||
<LibraryHeaderBar.Title>
|
||||
{t('page.home.title', { postProcess: 'titleCase' })}
|
||||
</LibraryHeaderBar.Title>
|
||||
<LibraryHeaderBar.Title>{t('page.home.title')}</LibraryHeaderBar.Title>
|
||||
</LibraryHeaderBar>
|
||||
),
|
||||
offset: 200,
|
||||
|
||||
@@ -155,9 +155,9 @@ const AlbumPropertyMapping: ItemDetailRow<Album>[] = [
|
||||
label: 'filter.explicitStatus',
|
||||
render: (album, t) =>
|
||||
album.explicitStatus === ExplicitStatus.EXPLICIT
|
||||
? t('common.explicit', { postProcess: 'sentenceCase' })
|
||||
? t('common.explicit')
|
||||
: album.explicitStatus === ExplicitStatus.CLEAN
|
||||
? t('common.clean', { postProcess: 'sentenceCase' })
|
||||
? t('common.clean')
|
||||
: null,
|
||||
},
|
||||
{ label: 'filter.isCompilation', render: (album) => BoolField(album.isCompilation || false) },
|
||||
@@ -309,9 +309,9 @@ const SongPropertyMapping: ItemDetailRow<Song>[] = [
|
||||
label: 'filter.explicitStatus',
|
||||
render: (song, t) =>
|
||||
song.explicitStatus === ExplicitStatus.EXPLICIT
|
||||
? t('common.explicit', { postProcess: 'sentenceCase' })
|
||||
? t('common.explicit')
|
||||
: song.explicitStatus === ExplicitStatus.CLEAN
|
||||
? t('common.clean', { postProcess: 'sentenceCase' })
|
||||
? t('common.clean')
|
||||
: null,
|
||||
},
|
||||
{ count: 2, label: 'entity.genre', render: FormatGenre },
|
||||
@@ -379,7 +379,7 @@ const handleTags = (item: Album | Song, t: TFunction) => {
|
||||
if (tags.length) {
|
||||
return [
|
||||
<Table.Tr key="tags">
|
||||
<Table.Th>{t('common.tags', { postProcess: 'sentenceCase' })}</Table.Th>
|
||||
<Table.Th>{t('common.tags')}</Table.Th>
|
||||
<Table.Td>{tags.length}</Table.Td>
|
||||
</Table.Tr>,
|
||||
].concat(tags);
|
||||
@@ -406,11 +406,7 @@ const handleParticipants = (item: Album | Song, t: TFunction) => {
|
||||
if (participants.length) {
|
||||
return [
|
||||
<Table.Tr key="participants">
|
||||
<Table.Th>
|
||||
{t('common.additionalParticipants', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</Table.Th>
|
||||
<Table.Th>{t('common.additionalParticipants')}</Table.Th>
|
||||
<Table.Td>{participants.length}</Table.Td>
|
||||
</Table.Tr>,
|
||||
].concat(participants);
|
||||
@@ -431,9 +427,7 @@ export const ItemDetailsModal = ({ item, items }: ItemDetailsModalProps) => {
|
||||
|
||||
const selectData = useMemo(() => {
|
||||
return allItems.map((it, index) => ({
|
||||
label:
|
||||
it.name ||
|
||||
`${t('common.item', { defaultValue: 'Item', postProcess: 'sentenceCase' })} ${index + 1}`,
|
||||
label: it.name || `${t('common.item', { defaultValue: 'Item' })} ${index + 1}`,
|
||||
value: String(index),
|
||||
}));
|
||||
}, [allItems, t]);
|
||||
|
||||
@@ -27,9 +27,7 @@ export const SongPath = ({ path }: SongPathProps) => {
|
||||
<Tooltip
|
||||
label={t(
|
||||
copied ? 'page.itemDetail.copiedPath' : 'page.itemDetail.copyPath',
|
||||
{
|
||||
postProcess: 'sentenceCase',
|
||||
},
|
||||
{},
|
||||
)}
|
||||
withinPortal
|
||||
>
|
||||
@@ -40,19 +38,14 @@ export const SongPath = ({ path }: SongPathProps) => {
|
||||
)}
|
||||
</CopyButton>
|
||||
{util && (
|
||||
<Tooltip
|
||||
label={t('page.itemDetail.openFile', { postProcess: 'sentenceCase' })}
|
||||
withinPortal
|
||||
>
|
||||
<Tooltip label={t('page.itemDetail.openFile')} withinPortal>
|
||||
<ActionIcon
|
||||
icon="externalLink"
|
||||
onClick={() => {
|
||||
util.openItem(path).catch((error) => {
|
||||
toast.error({
|
||||
message: (error as Error).message,
|
||||
title: t('error.openError', {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
title: t('error.openError'),
|
||||
});
|
||||
});
|
||||
}}
|
||||
|
||||
@@ -115,12 +115,8 @@ const LoginRoute = () => {
|
||||
<PageHeader />
|
||||
<Center style={{ height: '100%', width: '100vw' }}>
|
||||
<Stack>
|
||||
<TextTitle fw={600}>
|
||||
{t('error.genericError', { postProcess: 'sentenceCase' })}
|
||||
</TextTitle>
|
||||
<Text fw={500}>
|
||||
{t('error.serverNotSelectedError', { postProcess: 'sentenceCase' })}
|
||||
</Text>
|
||||
<TextTitle fw={600}>{t('error.genericError')}</TextTitle>
|
||||
<Text fw={500}>{t('error.serverNotSelectedError')}</Text>
|
||||
<Code block>{JSON.stringify(config, null, 2)}</Code>
|
||||
</Stack>
|
||||
</Center>
|
||||
@@ -133,7 +129,7 @@ const LoginRoute = () => {
|
||||
|
||||
if (!authFunction) {
|
||||
return toast.error({
|
||||
message: t('error.invalidServer', { postProcess: 'sentenceCase' }),
|
||||
message: t('error.invalidServer'),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -151,7 +147,7 @@ const LoginRoute = () => {
|
||||
|
||||
if (!data) {
|
||||
return toast.error({
|
||||
message: t('error.authenticationFailed', { postProcess: 'sentenceCase' }),
|
||||
message: t('error.authenticationFailed'),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -195,7 +191,7 @@ const LoginRoute = () => {
|
||||
}
|
||||
|
||||
toast.success({
|
||||
message: t('form.addServer.success', { postProcess: 'sentenceCase' }),
|
||||
message: t('form.addServer.success'),
|
||||
});
|
||||
|
||||
if (localSettings && values.password) {
|
||||
@@ -204,7 +200,6 @@ const LoginRoute = () => {
|
||||
toast.error({
|
||||
message: t('form.addServer.error', {
|
||||
context: 'savePassword',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
});
|
||||
}
|
||||
@@ -250,7 +245,6 @@ const LoginRoute = () => {
|
||||
data-autofocus
|
||||
label={t('form.addServer.input', {
|
||||
context: 'username',
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
required
|
||||
variant="filled"
|
||||
@@ -259,7 +253,6 @@ const LoginRoute = () => {
|
||||
<PasswordInput
|
||||
label={t('form.addServer.input', {
|
||||
context: 'password',
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
required
|
||||
variant="filled"
|
||||
@@ -277,7 +270,6 @@ const LoginRoute = () => {
|
||||
>
|
||||
{t('common.login', {
|
||||
defaultValue: 'Login',
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
</Button>
|
||||
</Stack>
|
||||
|
||||
@@ -85,7 +85,6 @@ ${contents}
|
||||
data-autofocus
|
||||
label={t('form.lyricsExport.input', {
|
||||
context: 'synced',
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
{...form.getInputProps('synced', { type: 'checkbox' })}
|
||||
/>
|
||||
@@ -93,7 +92,6 @@ ${contents}
|
||||
data-autofocus
|
||||
label={t('form.lyricsExport.input', {
|
||||
context: 'offset',
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
{...form.getInputProps('offsetMs')}
|
||||
/>
|
||||
@@ -104,10 +102,10 @@ ${contents}
|
||||
<Divider />
|
||||
<Group justify="flex-end">
|
||||
<Button onClick={() => closeAllModals()} variant="default">
|
||||
{t('common.close', { postProcess: 'titleCase' })}
|
||||
{t('common.close')}
|
||||
</Button>
|
||||
<Button onClick={exportLyrics} variant="filled">
|
||||
{t('form.lyricsExport.export', { postProcess: 'titleCase' })}
|
||||
{t('form.lyricsExport.export')}
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
@@ -123,6 +121,6 @@ export const openLyricsExportModal = ({ lyrics, offsetMs, synced }: LyricsExport
|
||||
height: '600px',
|
||||
},
|
||||
},
|
||||
title: i18n.t('form.lyricSearch.title', { postProcess: 'titleCase' }) as string,
|
||||
title: i18n.t('form.lyricSearch.title') as string,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -57,17 +57,13 @@ const SearchResult = ({ data, isSelected, onClick }: SearchResultProps) => {
|
||||
|
||||
const syncStatus = useMemo(() => {
|
||||
if (isSync === true) {
|
||||
return t('page.fullscreenPlayer.config.synchronized', {
|
||||
postProcess: 'sentenceCase',
|
||||
});
|
||||
return t('page.fullscreenPlayer.config.synchronized');
|
||||
}
|
||||
if (isSync === false) {
|
||||
return t('page.fullscreenPlayer.config.unsynchronized', {
|
||||
postProcess: 'sentenceCase',
|
||||
});
|
||||
return t('page.fullscreenPlayer.config.unsynchronized');
|
||||
}
|
||||
|
||||
return t('common.unknown', { postProcess: 'titleCase' });
|
||||
return t('common.unknown');
|
||||
}, [isSync, t]);
|
||||
|
||||
return (
|
||||
@@ -186,7 +182,6 @@ export const LyricsSearchForm = ({ artist, name, onSearchOverride }: LyricSearch
|
||||
data-autofocus
|
||||
label={t('form.lyricSearch.input', {
|
||||
context: 'name',
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
rightSection={
|
||||
form.values.name ? (
|
||||
@@ -203,7 +198,6 @@ export const LyricsSearchForm = ({ artist, name, onSearchOverride }: LyricSearch
|
||||
<TextInput
|
||||
label={t('form.lyricSearch.input', {
|
||||
context: 'artist',
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
rightSection={
|
||||
form.values.artist ? (
|
||||
@@ -288,11 +282,7 @@ export const LyricsSearchForm = ({ artist, name, onSearchOverride }: LyricSearch
|
||||
</div>
|
||||
) : (
|
||||
<Center>
|
||||
<Text isMuted>
|
||||
{t('page.fullscreenPlayer.noLyrics', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</Text>
|
||||
<Text isMuted>{t('page.fullscreenPlayer.noLyrics')}</Text>
|
||||
</Center>
|
||||
)}
|
||||
</ScrollArea>
|
||||
@@ -302,17 +292,17 @@ export const LyricsSearchForm = ({ artist, name, onSearchOverride }: LyricSearch
|
||||
<Divider />
|
||||
<Group justify="flex-end">
|
||||
<Button onClick={() => closeAllModals()} variant="default">
|
||||
{t('common.cancel', { postProcess: 'titleCase' })}
|
||||
{t('common.cancel')}
|
||||
</Button>
|
||||
<Button
|
||||
disabled={!selectedResult || !previewData}
|
||||
onClick={handleExport}
|
||||
variant="default"
|
||||
>
|
||||
{t('form.lyricsExport.export', { postProcess: 'titleCase' })}
|
||||
{t('form.lyricsExport.export')}
|
||||
</Button>
|
||||
<Button disabled={!selectedResult} onClick={handleApply} variant="filled">
|
||||
{t('common.confirm', { postProcess: 'titleCase' })}
|
||||
{t('common.confirm')}
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
@@ -330,6 +320,6 @@ export const openLyricSearchModal = ({ artist, name, onSearchOverride }: LyricSe
|
||||
height: '600px',
|
||||
},
|
||||
},
|
||||
title: i18n.t('form.lyricSearch.title', { postProcess: 'titleCase' }) as string,
|
||||
title: i18n.t('form.lyricSearch.title') as string,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -79,7 +79,6 @@ export const LyricsSettingsForm = ({ settingsKey }: LyricsSettingsFormProps) =>
|
||||
description: '',
|
||||
title: t(
|
||||
`${t('page.fullscreenPlayer.config.lyricSize')} (${t('page.fullscreenPlayer.config.synchronized')})`,
|
||||
{ postProcess: 'sentenceCase' },
|
||||
),
|
||||
},
|
||||
{
|
||||
@@ -102,7 +101,6 @@ export const LyricsSettingsForm = ({ settingsKey }: LyricsSettingsFormProps) =>
|
||||
description: '',
|
||||
title: t(
|
||||
`${t('page.fullscreenPlayer.config.lyricSize')} (${t('page.fullscreenPlayer.config.unsynchronized')})`,
|
||||
{ postProcess: 'sentenceCase' },
|
||||
),
|
||||
},
|
||||
{
|
||||
@@ -125,7 +123,6 @@ export const LyricsSettingsForm = ({ settingsKey }: LyricsSettingsFormProps) =>
|
||||
description: '',
|
||||
title: t(
|
||||
`${t('page.fullscreenPlayer.config.lyricGap')} (${t('page.fullscreenPlayer.config.synchronized')})`,
|
||||
{ postProcess: 'sentenceCase' },
|
||||
),
|
||||
},
|
||||
{
|
||||
@@ -148,19 +145,18 @@ export const LyricsSettingsForm = ({ settingsKey }: LyricsSettingsFormProps) =>
|
||||
description: '',
|
||||
title: t(
|
||||
`${t('page.fullscreenPlayer.config.lyricGap')} (${t('page.fullscreenPlayer.config.unsynchronized')})`,
|
||||
{ postProcess: 'sentenceCase' },
|
||||
),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
<SegmentedControl
|
||||
data={[
|
||||
{ label: t('common.left', { postProcess: 'titleCase' }), value: 'left' },
|
||||
{ label: t('common.left'), value: 'left' },
|
||||
{
|
||||
label: t('common.center', { postProcess: 'titleCase' }),
|
||||
label: t('common.center'),
|
||||
value: 'center',
|
||||
},
|
||||
{ label: t('common.right', { postProcess: 'titleCase' }), value: 'right' },
|
||||
{ label: t('common.right'), value: 'right' },
|
||||
]}
|
||||
onChange={(value) =>
|
||||
updateLyricsSetting({ alignment: value as 'center' | 'left' | 'right' })
|
||||
@@ -169,9 +165,7 @@ export const LyricsSettingsForm = ({ settingsKey }: LyricsSettingsFormProps) =>
|
||||
/>
|
||||
),
|
||||
description: '',
|
||||
title: t('page.fullscreenPlayer.config.lyricAlignment', {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
title: t('page.fullscreenPlayer.config.lyricAlignment'),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
@@ -182,9 +176,7 @@ export const LyricsSettingsForm = ({ settingsKey }: LyricsSettingsFormProps) =>
|
||||
/>
|
||||
),
|
||||
description: '',
|
||||
title: t('page.fullscreenPlayer.config.followCurrentLyric', {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
title: t('page.fullscreenPlayer.config.followCurrentLyric'),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
@@ -203,9 +195,7 @@ export const LyricsSettingsForm = ({ settingsKey }: LyricsSettingsFormProps) =>
|
||||
/>
|
||||
),
|
||||
description: '',
|
||||
title: t(`${t('page.fullscreenPlayer.config.lyricOpacityNonActive')}`, {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
title: t(`${t('page.fullscreenPlayer.config.lyricOpacityNonActive')}`, {}),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
@@ -224,9 +214,7 @@ export const LyricsSettingsForm = ({ settingsKey }: LyricsSettingsFormProps) =>
|
||||
/>
|
||||
),
|
||||
description: '',
|
||||
title: t(`${t('page.fullscreenPlayer.config.lyricScaleNonActive')}`, {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
title: t(`${t('page.fullscreenPlayer.config.lyricScaleNonActive')}`, {}),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
@@ -237,9 +225,7 @@ export const LyricsSettingsForm = ({ settingsKey }: LyricsSettingsFormProps) =>
|
||||
/>
|
||||
),
|
||||
description: '',
|
||||
title: t('page.fullscreenPlayer.config.showLyricMatch', {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
title: t('page.fullscreenPlayer.config.showLyricMatch'),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
@@ -250,9 +236,7 @@ export const LyricsSettingsForm = ({ settingsKey }: LyricsSettingsFormProps) =>
|
||||
/>
|
||||
),
|
||||
description: '',
|
||||
title: t('page.fullscreenPlayer.config.showLyricProvider', {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
title: t('page.fullscreenPlayer.config.showLyricProvider'),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -269,10 +253,9 @@ export const LyricsSettingsForm = ({ settingsKey }: LyricsSettingsFormProps) =>
|
||||
),
|
||||
description: t('setting.preferLocalLyrics', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: !isElectron(),
|
||||
title: t('setting.preferLocalLyrics', { postProcess: 'sentenceCase' }),
|
||||
title: t('setting.preferLocalLyrics'),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
@@ -284,10 +267,9 @@ export const LyricsSettingsForm = ({ settingsKey }: LyricsSettingsFormProps) =>
|
||||
),
|
||||
description: t('setting.lyricFetch', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: !isElectron(),
|
||||
title: t('setting.lyricFetch', { postProcess: 'sentenceCase' }),
|
||||
title: t('setting.lyricFetch'),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
@@ -305,10 +287,9 @@ export const LyricsSettingsForm = ({ settingsKey }: LyricsSettingsFormProps) =>
|
||||
),
|
||||
description: t('setting.lyricFetchProvider', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: !isElectron(),
|
||||
title: t('setting.lyricFetchProvider', { postProcess: 'sentenceCase' }),
|
||||
title: t('setting.lyricFetchProvider'),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
@@ -324,10 +305,9 @@ export const LyricsSettingsForm = ({ settingsKey }: LyricsSettingsFormProps) =>
|
||||
),
|
||||
description: t('setting.neteaseTranslation', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: !isElectron(),
|
||||
title: t('setting.neteaseTranslation', { postProcess: 'sentenceCase' }),
|
||||
title: t('setting.neteaseTranslation'),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
@@ -343,10 +323,9 @@ export const LyricsSettingsForm = ({ settingsKey }: LyricsSettingsFormProps) =>
|
||||
),
|
||||
description: t('setting.lyricOffset', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: !isElectron(),
|
||||
title: t('setting.lyricOffset', { postProcess: 'sentenceCase' }),
|
||||
title: t('setting.lyricOffset'),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
@@ -360,10 +339,9 @@ export const LyricsSettingsForm = ({ settingsKey }: LyricsSettingsFormProps) =>
|
||||
),
|
||||
description: t('setting.translationTargetLanguage', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: !isElectron(),
|
||||
title: t('setting.translationTargetLanguage', { postProcess: 'sentenceCase' }),
|
||||
title: t('setting.translationTargetLanguage'),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
@@ -378,10 +356,9 @@ export const LyricsSettingsForm = ({ settingsKey }: LyricsSettingsFormProps) =>
|
||||
),
|
||||
description: t('setting.translationApiProvider', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: !isElectron(),
|
||||
title: t('setting.translationApiProvider', { postProcess: 'sentenceCase' }),
|
||||
title: t('setting.translationApiProvider'),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
@@ -394,10 +371,9 @@ export const LyricsSettingsForm = ({ settingsKey }: LyricsSettingsFormProps) =>
|
||||
),
|
||||
description: t('setting.translationApiKey', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: !isElectron(),
|
||||
title: t('setting.translationApiKey', { postProcess: 'sentenceCase' }),
|
||||
title: t('setting.translationApiKey'),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
@@ -411,19 +387,18 @@ export const LyricsSettingsForm = ({ settingsKey }: LyricsSettingsFormProps) =>
|
||||
),
|
||||
description: t('setting.enableAutoTranslation', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: !isElectron(),
|
||||
title: t('setting.enableAutoTranslation', { postProcess: 'sentenceCase' }),
|
||||
title: t('setting.enableAutoTranslation'),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Stack gap="md" p="md">
|
||||
<Fieldset legend={t('page.setting.lyricsDisplay', { postProcess: 'sentenceCase' })}>
|
||||
<Fieldset legend={t('page.setting.lyricsDisplay')}>
|
||||
<SettingsSection options={displayOptions} />
|
||||
</Fieldset>
|
||||
<Fieldset legend={t('page.setting.lyrics', { postProcess: 'sentenceCase' })}>
|
||||
<Fieldset legend={t('page.setting.lyrics')}>
|
||||
<SettingsSection options={lyricOptions} />
|
||||
</Fieldset>
|
||||
</Stack>
|
||||
|
||||
@@ -70,7 +70,7 @@ export const LyricsActions = ({
|
||||
uppercase
|
||||
variant="subtle"
|
||||
>
|
||||
{t('form.lyricsExport.export', { postProcess: 'sentenceCase ' })}
|
||||
{t('form.lyricsExport.export')}
|
||||
</Button>
|
||||
</Center>
|
||||
)}
|
||||
@@ -89,7 +89,7 @@ export const LyricsActions = ({
|
||||
uppercase
|
||||
variant="subtle"
|
||||
>
|
||||
{t('common.search', { postProcess: 'titleCase' })}
|
||||
{t('common.search')}
|
||||
</Button>
|
||||
) : null}
|
||||
<ActionIcon
|
||||
@@ -97,15 +97,12 @@ export const LyricsActions = ({
|
||||
icon="minus"
|
||||
onClick={() => handleLyricOffset(offsetMs - 50)}
|
||||
tooltip={{
|
||||
label: t('common.slower', { postProcess: 'sentenceCase' }),
|
||||
label: t('common.slower'),
|
||||
openDelay: 0,
|
||||
}}
|
||||
variant="subtle"
|
||||
/>
|
||||
<Tooltip
|
||||
label={t('setting.lyricOffset', { postProcess: 'sentenceCase' })}
|
||||
openDelay={0}
|
||||
>
|
||||
<Tooltip label={t('setting.lyricOffset')} openDelay={0}>
|
||||
<NumberInput
|
||||
aria-label="Lyric offset"
|
||||
onChange={handleLyricOffset}
|
||||
@@ -119,7 +116,7 @@ export const LyricsActions = ({
|
||||
icon="plus"
|
||||
onClick={() => handleLyricOffset(offsetMs + 50)}
|
||||
tooltip={{
|
||||
label: t('common.faster', { postProcess: 'sentenceCase' }),
|
||||
label: t('common.faster'),
|
||||
openDelay: 0,
|
||||
}}
|
||||
variant="subtle"
|
||||
@@ -131,9 +128,7 @@ export const LyricsActions = ({
|
||||
uppercase
|
||||
variant="subtle"
|
||||
>
|
||||
{hasLyrics
|
||||
? t('common.clear', { postProcess: 'sentenceCase' })
|
||||
: t('common.refresh', { postProcess: 'sentenceCase' })}
|
||||
{hasLyrics ? t('common.clear') : t('common.refresh')}
|
||||
</Button>
|
||||
) : null}
|
||||
</Group>
|
||||
@@ -146,7 +141,7 @@ export const LyricsActions = ({
|
||||
uppercase
|
||||
variant="subtle"
|
||||
>
|
||||
{t('common.translation', { postProcess: 'sentenceCase' })}
|
||||
{t('common.translation')}
|
||||
</Button>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
@@ -318,9 +318,7 @@ export const Lyrics = ({ fadeOutNoLyricsMessage = true, settingsKey = 'default'
|
||||
>
|
||||
<Group>
|
||||
<Text fw={500} isMuted isNoSelect>
|
||||
{t('page.fullscreenPlayer.noLyrics', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.fullscreenPlayer.noLyrics')}
|
||||
</Text>
|
||||
</Group>
|
||||
</motion.div>
|
||||
|
||||
@@ -19,7 +19,7 @@ export const openLyricsSettingsModal = (settingsKey: string = 'default') => {
|
||||
width: '100%',
|
||||
},
|
||||
},
|
||||
title: i18n.t('common.setting', { count: 2, postProcess: 'titleCase' }),
|
||||
title: i18n.t('common.setting', { count: 2 }),
|
||||
transitionProps: {
|
||||
transition: 'pop',
|
||||
},
|
||||
|
||||
@@ -9,9 +9,7 @@ export const NowPlayingHeader = () => {
|
||||
return (
|
||||
<PageHeader>
|
||||
<LibraryHeaderBar ignoreMaxWidth>
|
||||
<LibraryHeaderBar.Title>
|
||||
{t('page.sidebar.nowPlaying', { postProcess: 'titleCase' })}
|
||||
</LibraryHeaderBar.Title>
|
||||
<LibraryHeaderBar.Title>{t('page.sidebar.nowPlaying')}</LibraryHeaderBar.Title>
|
||||
</LibraryHeaderBar>
|
||||
</PageHeader>
|
||||
);
|
||||
|
||||
@@ -108,21 +108,21 @@ const QueuePlaybackIcons = ({ tableRef }: { tableRef: RefObject<ItemListHandle |
|
||||
icon="mediaShuffle"
|
||||
iconProps={{ size: 'lg' }}
|
||||
onClick={handleShuffleQueue}
|
||||
tooltip={{ label: t('player.shuffle', { postProcess: 'sentenceCase' }) }}
|
||||
tooltip={{ label: t('player.shuffle') }}
|
||||
variant="subtle"
|
||||
/>
|
||||
<ActionIcon
|
||||
icon="x"
|
||||
iconProps={{ size: 'lg' }}
|
||||
onClick={handleClearQueue}
|
||||
tooltip={{ label: t('action.clearQueue', { postProcess: 'sentenceCase' }) }}
|
||||
tooltip={{ label: t('action.clearQueue') }}
|
||||
variant="subtle"
|
||||
/>
|
||||
<ActionIcon
|
||||
icon="goToItem"
|
||||
iconProps={{ size: 'lg' }}
|
||||
onClick={handleJumpToCurrent}
|
||||
tooltip={{ label: t('action.goToCurrent', { postProcess: 'sentenceCase' }) }}
|
||||
tooltip={{ label: t('action.goToCurrent') }}
|
||||
variant="subtle"
|
||||
/>
|
||||
</>
|
||||
@@ -152,9 +152,7 @@ const QueueRestoreActions = () => {
|
||||
loading={isSavingQueue}
|
||||
onClick={() => handleSaveQueue()}
|
||||
tooltip={{
|
||||
label: t('player.saveQueueToServer', {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
label: t('player.saveQueueToServer'),
|
||||
}}
|
||||
variant="subtle"
|
||||
/>
|
||||
@@ -165,9 +163,7 @@ const QueueRestoreActions = () => {
|
||||
loading={Boolean(isFetching)}
|
||||
onClick={handleRestoreQueue}
|
||||
tooltip={{
|
||||
label: t('player.restoreQueueFromServer', {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
label: t('player.restoreQueueFromServer'),
|
||||
}}
|
||||
variant="subtle"
|
||||
/>
|
||||
|
||||
@@ -51,7 +51,7 @@ export const PopoverPlayQueue = ({
|
||||
onClick={handleToggle}
|
||||
size="sm"
|
||||
tooltip={{
|
||||
label: t('player.viewQueue', { postProcess: 'titleCase' }),
|
||||
label: t('player.viewQueue'),
|
||||
openDelay: 0,
|
||||
}}
|
||||
variant="subtle"
|
||||
|
||||
@@ -313,7 +313,7 @@ const PanelReorderControls = ({ panelType }: { panelType: 'lyrics' | 'visualizer
|
||||
onClick={handleMoveUp}
|
||||
size="xs"
|
||||
tooltip={{
|
||||
label: t('action.moveUp', { postProcess: 'sentenceCase' }),
|
||||
label: t('action.moveUp'),
|
||||
}}
|
||||
variant="subtle"
|
||||
/>
|
||||
@@ -324,7 +324,7 @@ const PanelReorderControls = ({ panelType }: { panelType: 'lyrics' | 'visualizer
|
||||
onClick={handleMoveDown}
|
||||
size="xs"
|
||||
tooltip={{
|
||||
label: t('action.moveDown', { postProcess: 'sentenceCase' }),
|
||||
label: t('action.moveDown'),
|
||||
}}
|
||||
variant="subtle"
|
||||
/>
|
||||
@@ -334,7 +334,7 @@ const PanelReorderControls = ({ panelType }: { panelType: 'lyrics' | 'visualizer
|
||||
onClick={handleClose}
|
||||
size="xs"
|
||||
tooltip={{
|
||||
label: t('common.close', { postProcess: 'sentenceCase' }),
|
||||
label: t('common.close'),
|
||||
}}
|
||||
variant="subtle"
|
||||
/>
|
||||
|
||||
@@ -35,7 +35,7 @@ export const useMainPlayerListener = () => {
|
||||
toast.error({
|
||||
id: 'mpv-error',
|
||||
message,
|
||||
title: t('error.playbackError', { postProcess: 'sentenceCase' }) as string,
|
||||
title: t('error.playbackError') as string,
|
||||
});
|
||||
mediaPause();
|
||||
mpvPlayer!.pause();
|
||||
|
||||
@@ -464,7 +464,7 @@ export function WebPlayer() {
|
||||
const handleOnErrorPause = useCallback(() => {
|
||||
mediaPause();
|
||||
toast.error({
|
||||
message: t('error.playbackPausedDueToError', { postProcess: 'sentenceCase' }),
|
||||
message: t('error.playbackPausedDueToError'),
|
||||
});
|
||||
}, [mediaPause, t]);
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ const RadioStopButton = ({ disabled }: { disabled?: boolean }) => {
|
||||
icon={<Icon fill="default" icon="mediaStop" size={buttonSize - 2} />}
|
||||
onClick={stop}
|
||||
tooltip={{
|
||||
label: t('player.stop', { postProcess: 'sentenceCase' }),
|
||||
label: t('player.stop'),
|
||||
openDelay: 0,
|
||||
}}
|
||||
variant="tertiary"
|
||||
@@ -114,7 +114,7 @@ const StopButton = ({ disabled }: { disabled?: boolean }) => {
|
||||
icon={<Icon fill="default" icon="mediaStop" size={buttonSize - 2} />}
|
||||
onClick={() => mediaStop()}
|
||||
tooltip={{
|
||||
label: t('player.stop', { postProcess: 'sentenceCase' }),
|
||||
label: t('player.stop'),
|
||||
openDelay: 0,
|
||||
}}
|
||||
variant="tertiary"
|
||||
@@ -145,9 +145,8 @@ const ShuffleButton = ({ disabled }: { disabled?: boolean }) => {
|
||||
shuffle === PlayerShuffle.NONE
|
||||
? t('player.shuffle', {
|
||||
context: 'off',
|
||||
postProcess: 'sentenceCase',
|
||||
})
|
||||
: t('player.shuffle', { postProcess: 'sentenceCase' }),
|
||||
: t('player.shuffle'),
|
||||
openDelay: 0,
|
||||
}}
|
||||
variant="tertiary"
|
||||
@@ -166,7 +165,7 @@ const PreviousButton = ({ disabled }: { disabled?: boolean }) => {
|
||||
icon={<Icon fill="default" icon="mediaPrevious" size={buttonSize} />}
|
||||
onClick={mediaPrevious}
|
||||
tooltip={{
|
||||
label: t('player.previous', { postProcess: 'sentenceCase' }),
|
||||
label: t('player.previous'),
|
||||
openDelay: 0,
|
||||
}}
|
||||
variant="secondary"
|
||||
@@ -187,7 +186,6 @@ const SkipBackwardButton = ({ disabled }: { disabled?: boolean }) => {
|
||||
tooltip={{
|
||||
label: t('player.skip', {
|
||||
context: 'back',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
openDelay: 0,
|
||||
}}
|
||||
@@ -224,7 +222,6 @@ const SkipForwardButton = ({ disabled }: { disabled?: boolean }) => {
|
||||
tooltip={{
|
||||
label: t('player.skip', {
|
||||
context: 'forward',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
openDelay: 0,
|
||||
}}
|
||||
@@ -244,7 +241,7 @@ const NextButton = ({ disabled }: { disabled?: boolean }) => {
|
||||
icon={<Icon fill="default" icon="mediaNext" size={buttonSize} />}
|
||||
onClick={mediaNext}
|
||||
tooltip={{
|
||||
label: t('player.next', { postProcess: 'sentenceCase' }),
|
||||
label: t('player.next'),
|
||||
openDelay: 0,
|
||||
}}
|
||||
variant="secondary"
|
||||
@@ -279,16 +276,13 @@ const RepeatButton = ({ disabled }: { disabled?: boolean }) => {
|
||||
repeat === PlayerRepeat.NONE
|
||||
? t('player.repeat', {
|
||||
context: 'off',
|
||||
postProcess: 'sentenceCase',
|
||||
})
|
||||
: repeat === PlayerRepeat.ALL
|
||||
? t('player.repeat', {
|
||||
context: 'all',
|
||||
postProcess: 'sentenceCase',
|
||||
})
|
||||
: t('player.repeat', {
|
||||
context: 'one',
|
||||
postProcess: 'sentenceCase',
|
||||
})
|
||||
}`,
|
||||
openDelay: 0,
|
||||
@@ -308,7 +302,7 @@ const ShuffleAllButton = ({ disabled }: { disabled?: boolean }) => {
|
||||
icon={<Icon fill="default" icon="mediaRandom" size={buttonSize} />}
|
||||
onClick={() => openShuffleAllModal()}
|
||||
tooltip={{
|
||||
label: t('form.shuffleAll.title', { postProcess: 'sentenceCase' }),
|
||||
label: t('form.shuffleAll.title'),
|
||||
openDelay: 0,
|
||||
}}
|
||||
variant="tertiary"
|
||||
|
||||
@@ -58,7 +58,7 @@ export const FullScreenPlayerQueue = () => {
|
||||
if (webAudio) {
|
||||
items.push({
|
||||
active: activeTab === 'visualizer',
|
||||
label: t('page.fullscreenPlayer.visualizer', { postProcess: 'titleCase' }),
|
||||
label: t('page.fullscreenPlayer.visualizer'),
|
||||
onClick: () => setStore({ activeTab: 'visualizer' }),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -288,7 +288,7 @@ const Controls = () => {
|
||||
icon="arrowDownS"
|
||||
iconProps={{ size: 'lg' }}
|
||||
onClick={handleToggleFullScreenPlayer}
|
||||
tooltip={{ label: t('common.minimize', { postProcess: 'titleCase' }) }}
|
||||
tooltip={{ label: t('common.minimize') }}
|
||||
variant="subtle"
|
||||
/>
|
||||
<Popover position="bottom-start">
|
||||
@@ -296,16 +296,14 @@ const Controls = () => {
|
||||
<ActionIcon
|
||||
icon="settings2"
|
||||
iconProps={{ size: 'lg' }}
|
||||
tooltip={{ label: t('common.configure', { postProcess: 'titleCase' }) }}
|
||||
tooltip={{ label: t('common.configure') }}
|
||||
variant="subtle"
|
||||
/>
|
||||
</Popover.Target>
|
||||
<Popover.Dropdown>
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.dynamicBackground', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.fullscreenPlayer.config.dynamicBackground')}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Switch
|
||||
@@ -321,9 +319,7 @@ const Controls = () => {
|
||||
{dynamicBackground && (
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.dynamicIsImage', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.fullscreenPlayer.config.dynamicIsImage')}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Switch
|
||||
@@ -340,9 +336,7 @@ const Controls = () => {
|
||||
{dynamicBackground && dynamicIsImage && (
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.dynamicImageBlur', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.fullscreenPlayer.config.dynamicImageBlur')}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Slider
|
||||
@@ -359,11 +353,7 @@ const Controls = () => {
|
||||
)}
|
||||
{dynamicBackground && (
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.opacity', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</Option.Label>
|
||||
<Option.Label>{t('page.fullscreenPlayer.config.opacity')}</Option.Label>
|
||||
<Option.Control>
|
||||
<Slider
|
||||
defaultValue={opacity}
|
||||
@@ -378,9 +368,7 @@ const Controls = () => {
|
||||
)}
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.useImageAspectRatio', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.fullscreenPlayer.config.useImageAspectRatio')}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Switch
|
||||
@@ -396,9 +384,7 @@ const Controls = () => {
|
||||
<Divider my="sm" />
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.followCurrentLyric', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.fullscreenPlayer.config.followCurrentLyric')}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Switch
|
||||
@@ -411,9 +397,7 @@ const Controls = () => {
|
||||
</Option>
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.showLyricProvider', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.fullscreenPlayer.config.showLyricProvider')}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Switch
|
||||
@@ -426,9 +410,7 @@ const Controls = () => {
|
||||
</Option>
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.showLyricMatch', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.fullscreenPlayer.config.showLyricMatch')}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Switch
|
||||
@@ -440,19 +422,13 @@ const Controls = () => {
|
||||
</Option.Control>
|
||||
</Option>
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.lyricSize', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</Option.Label>
|
||||
<Option.Label>{t('page.fullscreenPlayer.config.lyricSize')}</Option.Label>
|
||||
<Option.Control>
|
||||
<Group w="100%" wrap="nowrap">
|
||||
<Slider
|
||||
defaultValue={lyricConfig.fontSize}
|
||||
label={(e) =>
|
||||
`${t('page.fullscreenPlayer.config.synchronized', {
|
||||
postProcess: 'titleCase',
|
||||
})}: ${e}px`
|
||||
`${t('page.fullscreenPlayer.config.synchronized')}: ${e}px`
|
||||
}
|
||||
max={72}
|
||||
min={8}
|
||||
@@ -462,9 +438,7 @@ const Controls = () => {
|
||||
<Slider
|
||||
defaultValue={lyricConfig.fontSize}
|
||||
label={(e) =>
|
||||
`${t('page.fullscreenPlayer.config.unsynchronized', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}: ${e}px`
|
||||
`${t('page.fullscreenPlayer.config.unsynchronized')}: ${e}px`
|
||||
}
|
||||
max={72}
|
||||
min={8}
|
||||
@@ -477,11 +451,7 @@ const Controls = () => {
|
||||
</Option.Control>
|
||||
</Option>
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.lyricGap', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</Option.Label>
|
||||
<Option.Label>{t('page.fullscreenPlayer.config.lyricGap')}</Option.Label>
|
||||
<Option.Control>
|
||||
<Group w="100%" wrap="nowrap">
|
||||
<Slider
|
||||
@@ -507,29 +477,21 @@ const Controls = () => {
|
||||
</Option>
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.lyricAlignment', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.fullscreenPlayer.config.lyricAlignment')}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<SegmentedControl
|
||||
data={[
|
||||
{
|
||||
label: t('common.left', {
|
||||
postProcess: 'titleCase',
|
||||
}),
|
||||
label: t('common.left'),
|
||||
value: 'left',
|
||||
},
|
||||
{
|
||||
label: t('common.center', {
|
||||
postProcess: 'titleCase',
|
||||
}),
|
||||
label: t('common.center'),
|
||||
value: 'center',
|
||||
},
|
||||
{
|
||||
label: t('common.right', {
|
||||
postProcess: 'titleCase',
|
||||
}),
|
||||
label: t('common.right'),
|
||||
value: 'right',
|
||||
},
|
||||
]}
|
||||
@@ -539,11 +501,7 @@ const Controls = () => {
|
||||
</Option.Control>
|
||||
</Option>
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.lyricOffset', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</Option.Label>
|
||||
<Option.Label>{t('page.fullscreenPlayer.config.lyricOffset')}</Option.Label>
|
||||
<Option.Control>
|
||||
<NumberInput
|
||||
defaultValue={lyricConfig.delayMs}
|
||||
|
||||
@@ -130,12 +130,7 @@ export const LeftControls = () => {
|
||||
role="button"
|
||||
transition={{ duration: 0.2, ease: 'easeIn' }}
|
||||
>
|
||||
<Tooltip
|
||||
label={t('player.toggleFullscreenPlayer', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
openDelay={0}
|
||||
>
|
||||
<Tooltip label={t('player.toggleFullscreenPlayer')} openDelay={0}>
|
||||
{isRadioMode && hasRadioStationImage ? (
|
||||
<ItemImage
|
||||
className={clsx(
|
||||
@@ -192,9 +187,7 @@ export const LeftControls = () => {
|
||||
top: 2,
|
||||
}}
|
||||
tooltip={{
|
||||
label: t('common.expand', {
|
||||
postProcess: 'titleCase',
|
||||
}),
|
||||
label: t('common.expand'),
|
||||
openDelay: 0,
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -33,7 +33,7 @@ export const MobileFullscreenPlayerControls = memo(
|
||||
icon={<Icon fill="default" icon="mediaPrevious" size="xl" />}
|
||||
onClick={mediaPrevious}
|
||||
tooltip={{
|
||||
label: t('player.previous', { postProcess: 'sentenceCase' }),
|
||||
label: t('player.previous'),
|
||||
openDelay: 0,
|
||||
}}
|
||||
variant="secondary"
|
||||
@@ -44,7 +44,6 @@ export const MobileFullscreenPlayerControls = memo(
|
||||
tooltip={{
|
||||
label: t('player.skip', {
|
||||
context: 'back',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
openDelay: 0,
|
||||
}}
|
||||
@@ -65,7 +64,6 @@ export const MobileFullscreenPlayerControls = memo(
|
||||
tooltip={{
|
||||
label: t('player.skip', {
|
||||
context: 'forward',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
openDelay: 0,
|
||||
}}
|
||||
@@ -75,7 +73,7 @@ export const MobileFullscreenPlayerControls = memo(
|
||||
icon={<Icon fill="default" icon="mediaNext" size="xl" />}
|
||||
onClick={mediaNext}
|
||||
tooltip={{
|
||||
label: t('player.next', { postProcess: 'sentenceCase' }),
|
||||
label: t('player.next'),
|
||||
openDelay: 0,
|
||||
}}
|
||||
variant="secondary"
|
||||
|
||||
@@ -84,7 +84,7 @@ export const MobileFullscreenPlayerHeader = memo(
|
||||
icon="arrowDownS"
|
||||
iconProps={{ size: 'lg' }}
|
||||
onClick={onClose}
|
||||
tooltip={{ label: t('common.minimize', { postProcess: 'titleCase' }) }}
|
||||
tooltip={{ label: t('common.minimize') }}
|
||||
variant={isPageHovered ? 'default' : 'subtle'}
|
||||
/>
|
||||
<Popover position="bottom-end">
|
||||
@@ -92,16 +92,14 @@ export const MobileFullscreenPlayerHeader = memo(
|
||||
<ActionIcon
|
||||
icon="settings2"
|
||||
iconProps={{ size: 'lg' }}
|
||||
tooltip={{ label: t('common.configure', { postProcess: 'titleCase' }) }}
|
||||
tooltip={{ label: t('common.configure') }}
|
||||
variant={isPageHovered ? 'default' : 'subtle'}
|
||||
/>
|
||||
</Popover.Target>
|
||||
<Popover.Dropdown>
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.dynamicBackground', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.fullscreenPlayer.config.dynamicBackground')}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Switch
|
||||
@@ -117,9 +115,7 @@ export const MobileFullscreenPlayerHeader = memo(
|
||||
{dynamicBackground && (
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.dynamicIsImage', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.fullscreenPlayer.config.dynamicIsImage')}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Switch
|
||||
@@ -136,9 +132,7 @@ export const MobileFullscreenPlayerHeader = memo(
|
||||
{dynamicBackground && dynamicIsImage && (
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.dynamicImageBlur', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.fullscreenPlayer.config.dynamicImageBlur')}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Slider
|
||||
@@ -158,9 +152,7 @@ export const MobileFullscreenPlayerHeader = memo(
|
||||
{dynamicBackground && (
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.opacity', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.fullscreenPlayer.config.opacity')}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Slider
|
||||
@@ -176,9 +168,7 @@ export const MobileFullscreenPlayerHeader = memo(
|
||||
)}
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.useImageAspectRatio', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.fullscreenPlayer.config.useImageAspectRatio')}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Switch
|
||||
@@ -194,9 +184,7 @@ export const MobileFullscreenPlayerHeader = memo(
|
||||
<Divider my="sm" />
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.followCurrentLyric', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.fullscreenPlayer.config.followCurrentLyric')}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Switch
|
||||
@@ -209,9 +197,7 @@ export const MobileFullscreenPlayerHeader = memo(
|
||||
</Option>
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.showLyricProvider', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.fullscreenPlayer.config.showLyricProvider')}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Switch
|
||||
@@ -227,9 +213,7 @@ export const MobileFullscreenPlayerHeader = memo(
|
||||
</Option>
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.showLyricMatch', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.fullscreenPlayer.config.showLyricMatch')}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Switch
|
||||
@@ -242,18 +226,14 @@ export const MobileFullscreenPlayerHeader = memo(
|
||||
</Option>
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.lyricSize', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.fullscreenPlayer.config.lyricSize')}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Group w="100%" wrap="nowrap">
|
||||
<Slider
|
||||
defaultValue={lyricConfig.fontSize}
|
||||
label={(e) =>
|
||||
`${t('page.fullscreenPlayer.config.synchronized', {
|
||||
postProcess: 'titleCase',
|
||||
})}: ${e}px`
|
||||
`${t('page.fullscreenPlayer.config.synchronized')}: ${e}px`
|
||||
}
|
||||
max={72}
|
||||
min={8}
|
||||
@@ -265,9 +245,7 @@ export const MobileFullscreenPlayerHeader = memo(
|
||||
<Slider
|
||||
defaultValue={lyricConfig.fontSizeUnsync}
|
||||
label={(e) =>
|
||||
`${t('page.fullscreenPlayer.config.unsynchronized', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}: ${e}px`
|
||||
`${t('page.fullscreenPlayer.config.unsynchronized')}: ${e}px`
|
||||
}
|
||||
max={72}
|
||||
min={8}
|
||||
@@ -281,9 +259,7 @@ export const MobileFullscreenPlayerHeader = memo(
|
||||
</Option>
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.lyricGap', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.fullscreenPlayer.config.lyricGap')}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Group w="100%" wrap="nowrap">
|
||||
@@ -310,29 +286,21 @@ export const MobileFullscreenPlayerHeader = memo(
|
||||
</Option>
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.lyricAlignment', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.fullscreenPlayer.config.lyricAlignment')}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<SegmentedControl
|
||||
data={[
|
||||
{
|
||||
label: t('common.left', {
|
||||
postProcess: 'titleCase',
|
||||
}),
|
||||
label: t('common.left'),
|
||||
value: 'left',
|
||||
},
|
||||
{
|
||||
label: t('common.center', {
|
||||
postProcess: 'titleCase',
|
||||
}),
|
||||
label: t('common.center'),
|
||||
value: 'center',
|
||||
},
|
||||
{
|
||||
label: t('common.right', {
|
||||
postProcess: 'titleCase',
|
||||
}),
|
||||
label: t('common.right'),
|
||||
value: 'right',
|
||||
},
|
||||
]}
|
||||
@@ -343,9 +311,7 @@ export const MobileFullscreenPlayerHeader = memo(
|
||||
</Option>
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.lyricOffset', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('page.fullscreenPlayer.config.lyricOffset')}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<NumberInput
|
||||
|
||||
@@ -545,7 +545,7 @@ export const MobileFullscreenPlayer = () => {
|
||||
variant={isPageHovered ? 'default' : 'subtle'}
|
||||
/>
|
||||
<Text fw={600} size="lg">
|
||||
{t('page.fullscreenPlayer.lyrics', { postProcess: 'sentenceCase' })}
|
||||
{t('page.fullscreenPlayer.lyrics')}
|
||||
</Text>
|
||||
<ActionIcon
|
||||
icon="x"
|
||||
|
||||
@@ -82,9 +82,7 @@ export const MobilePlayerbar = () => {
|
||||
transition={{ duration: 0.2, ease: 'easeIn' }}
|
||||
>
|
||||
<Tooltip
|
||||
label={t('player.toggleFullscreenPlayer', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
label={t('player.toggleFullscreenPlayer')}
|
||||
openDelay={0}
|
||||
>
|
||||
<ItemImage
|
||||
@@ -208,7 +206,7 @@ export const MobilePlayerbar = () => {
|
||||
mediaPrevious();
|
||||
}}
|
||||
tooltip={{
|
||||
label: t('player.previous', { postProcess: 'sentenceCase' }),
|
||||
label: t('player.previous'),
|
||||
openDelay: 0,
|
||||
}}
|
||||
variant="tertiary"
|
||||
@@ -228,7 +226,7 @@ export const MobilePlayerbar = () => {
|
||||
mediaNext();
|
||||
}}
|
||||
tooltip={{
|
||||
label: t('player.next', { postProcess: 'sentenceCase' }),
|
||||
label: t('player.next'),
|
||||
openDelay: 0,
|
||||
}}
|
||||
variant="tertiary"
|
||||
|
||||
@@ -80,9 +80,7 @@ export const MainPlayButton = forwardRef<HTMLButtonElement, PlayButtonProps>(
|
||||
}}
|
||||
ref={ref}
|
||||
tooltip={{
|
||||
label: isPaused
|
||||
? (t('player.play', { postProcess: 'sentenceCase' }) as string)
|
||||
: (t('player.pause', { postProcess: 'sentenceCase' }) as string),
|
||||
label: isPaused ? (t('player.play') as string) : (t('player.pause') as string),
|
||||
openDelay: 0,
|
||||
}}
|
||||
{...props}
|
||||
|
||||
@@ -54,12 +54,12 @@ export const PlayerConfig = () => {
|
||||
{
|
||||
component: <AudioPlayerTypeConfig />,
|
||||
id: 'audioPlayerType',
|
||||
label: t('setting.audioPlayer', { postProcess: 'titleCase' }),
|
||||
label: t('setting.audioPlayer'),
|
||||
},
|
||||
{
|
||||
component: <AudioDeviceConfig />,
|
||||
id: 'audioDevice',
|
||||
label: t('setting.audioDevice', { postProcess: 'titleCase' }),
|
||||
label: t('setting.audioDevice'),
|
||||
},
|
||||
{
|
||||
component: null,
|
||||
@@ -70,23 +70,17 @@ export const PlayerConfig = () => {
|
||||
{
|
||||
component: <TransitionTypeConfig />,
|
||||
id: 'transitionType',
|
||||
label: t('setting.playbackStyle', {
|
||||
postProcess: 'titleCase',
|
||||
}),
|
||||
label: t('setting.playbackStyle'),
|
||||
},
|
||||
{
|
||||
component: <CrossfadeStyleConfig />,
|
||||
id: 'crossfadeStyle',
|
||||
label: t('setting.crossfadeStyle', {
|
||||
postProcess: 'titleCase',
|
||||
}),
|
||||
label: t('setting.crossfadeStyle'),
|
||||
},
|
||||
{
|
||||
component: <CrossfadeDurationConfig />,
|
||||
id: 'crossfadeDuration',
|
||||
label: t('setting.crossfadeDuration', {
|
||||
postProcess: 'titleCase',
|
||||
}),
|
||||
label: t('setting.crossfadeDuration'),
|
||||
},
|
||||
{
|
||||
component: null,
|
||||
@@ -97,7 +91,7 @@ export const PlayerConfig = () => {
|
||||
{
|
||||
component: <PlaybackSpeedSlider />,
|
||||
id: 'playbackSpeed',
|
||||
label: t('player.playbackSpeed', { postProcess: 'titleCase' }),
|
||||
label: t('player.playbackSpeed'),
|
||||
},
|
||||
{
|
||||
component: (
|
||||
@@ -107,7 +101,7 @@ export const PlayerConfig = () => {
|
||||
/>
|
||||
),
|
||||
id: 'preservePitch',
|
||||
label: t('setting.preservePitch', { postProcess: 'titleCase' }),
|
||||
label: t('setting.preservePitch'),
|
||||
},
|
||||
{
|
||||
component: null,
|
||||
@@ -129,7 +123,7 @@ export const PlayerConfig = () => {
|
||||
/>
|
||||
),
|
||||
id: 'showLyricsInSidebar',
|
||||
label: t('setting.showLyricsInSidebar', { postProcess: 'titleCase' }),
|
||||
label: t('setting.showLyricsInSidebar'),
|
||||
},
|
||||
{
|
||||
component: (
|
||||
@@ -145,7 +139,7 @@ export const PlayerConfig = () => {
|
||||
/>
|
||||
),
|
||||
id: 'showVisualizerInSidebar',
|
||||
label: t('setting.showVisualizerInSidebar', { postProcess: 'titleCase' }),
|
||||
label: t('setting.showVisualizerInSidebar'),
|
||||
},
|
||||
{
|
||||
component: (
|
||||
@@ -161,7 +155,7 @@ export const PlayerConfig = () => {
|
||||
/>
|
||||
),
|
||||
id: 'combinedLyricsAndVisualizer',
|
||||
label: t('setting.combinedLyricsAndVisualizer', { postProcess: 'titleCase' }),
|
||||
label: t('setting.combinedLyricsAndVisualizer'),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -187,7 +181,7 @@ export const PlayerConfig = () => {
|
||||
size="sm"
|
||||
stopsPropagation
|
||||
tooltip={{
|
||||
label: t('common.setting', { count: 2, postProcess: 'titleCase' }),
|
||||
label: t('common.setting', { count: 2 }),
|
||||
openDelay: 0,
|
||||
}}
|
||||
variant="subtle"
|
||||
@@ -279,14 +273,12 @@ const TransitionTypeConfig = () => {
|
||||
{
|
||||
label: t('setting.playbackStyle', {
|
||||
context: 'optionNormal',
|
||||
postProcess: 'titleCase',
|
||||
}),
|
||||
value: PlayerStyle.GAPLESS,
|
||||
},
|
||||
{
|
||||
label: t('setting.playbackStyle', {
|
||||
context: 'optionCrossFade',
|
||||
postProcess: 'titleCase',
|
||||
}),
|
||||
value: PlayerStyle.CROSSFADE,
|
||||
},
|
||||
|
||||
@@ -159,7 +159,7 @@ const QueueButton = () => {
|
||||
onClick={handleClick}
|
||||
size="sm"
|
||||
tooltip={{
|
||||
label: t('player.viewQueue', { postProcess: 'titleCase' }),
|
||||
label: t('player.viewQueue'),
|
||||
openDelay: 0,
|
||||
}}
|
||||
variant="subtle"
|
||||
@@ -205,7 +205,7 @@ const LyricsButton = () => {
|
||||
role="button"
|
||||
size="sm"
|
||||
tooltip={{
|
||||
label: t('player.lyrics', { postProcess: 'titleCase' }),
|
||||
label: t('player.lyrics'),
|
||||
openDelay: 0,
|
||||
}}
|
||||
variant="subtle"
|
||||
@@ -288,9 +288,7 @@ const FavoriteButton = () => {
|
||||
}}
|
||||
size="sm"
|
||||
tooltip={{
|
||||
label: currentSong?.userFavorite
|
||||
? t('player.unfavorite', { postProcess: 'titleCase' })
|
||||
: t('player.favorite', { postProcess: 'titleCase' }),
|
||||
label: currentSong?.userFavorite ? t('player.unfavorite') : t('player.favorite'),
|
||||
openDelay: 0,
|
||||
}}
|
||||
variant="subtle"
|
||||
@@ -445,7 +443,7 @@ const VolumeButton = () => {
|
||||
onWheel={handleVolumeWheel}
|
||||
size="sm"
|
||||
tooltip={{
|
||||
label: muted ? t('player.muted', { postProcess: 'titleCase' }) : volume,
|
||||
label: muted ? t('player.muted') : volume,
|
||||
openDelay: 0,
|
||||
}}
|
||||
variant="subtle"
|
||||
|
||||
@@ -104,7 +104,7 @@ export const ShuffleAllContextModal = () => {
|
||||
return (
|
||||
<Stack gap="md">
|
||||
<NumberInput
|
||||
label={t('form.shuffleAll.input_limit', { postProcess: 'sentenceCase' })}
|
||||
label={t('form.shuffleAll.input_limit')}
|
||||
max={500}
|
||||
min={1}
|
||||
onChange={(e) => setStore({ limit: e ? Number(e) : 500 })}
|
||||
@@ -113,7 +113,7 @@ export const ShuffleAllContextModal = () => {
|
||||
/>
|
||||
<Group grow>
|
||||
<NumberInput
|
||||
label={t('form.shuffleAll.input_minYear', { postProcess: 'sentenceCase' })}
|
||||
label={t('form.shuffleAll.input_minYear')}
|
||||
max={2050}
|
||||
min={1850}
|
||||
onChange={(e) => setStore({ minYear: e ? Number(e) : 0 })}
|
||||
@@ -127,7 +127,7 @@ export const ShuffleAllContextModal = () => {
|
||||
value={minYear}
|
||||
/>
|
||||
<NumberInput
|
||||
label={t('form.shuffleAll.input_maxYear', { postProcess: 'sentenceCase' })}
|
||||
label={t('form.shuffleAll.input_maxYear')}
|
||||
max={2050}
|
||||
min={1850}
|
||||
onChange={(e) => setStore({ maxYear: e ? Number(e) : 0 })}
|
||||
@@ -148,7 +148,7 @@ export const ShuffleAllContextModal = () => {
|
||||
<Select
|
||||
clearable
|
||||
data={PLAYED_DATA}
|
||||
label={t('form.shuffleAll.input_played', { postProcess: 'sentenceCase' })}
|
||||
label={t('form.shuffleAll.input_played')}
|
||||
onChange={(e) => {
|
||||
setStore({ played: e as Played });
|
||||
}}
|
||||
@@ -191,7 +191,7 @@ export const openShuffleAllModal = async () => {
|
||||
innerProps: {},
|
||||
modal: 'shuffleAll',
|
||||
size: 'sm',
|
||||
title: i18n.t('player.playRandom', { postProcess: 'sentenceCase' }) as string,
|
||||
title: i18n.t('player.playRandom') as string,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -221,7 +221,7 @@ const GenreSelect = () => {
|
||||
<Select
|
||||
clearable
|
||||
data={genreData}
|
||||
label={t('form.shuffleAll.input_genre', { postProcess: 'sentenceCase' })}
|
||||
label={t('form.shuffleAll.input_genre')}
|
||||
onChange={(e) => setStore({ genre: e || '' })}
|
||||
searchable
|
||||
value={genre}
|
||||
|
||||
@@ -176,17 +176,15 @@ export const SleepTimerButton = () => {
|
||||
|
||||
const getPresetLabel = (option: (typeof PRESET_OPTIONS)[number]) => {
|
||||
if (option.mode === 'endOfSong') {
|
||||
return t('player.sleepTimer_endOfSong', { postProcess: 'sentenceCase' });
|
||||
return t('player.sleepTimer_endOfSong');
|
||||
}
|
||||
if (option.minutes >= 60) {
|
||||
return t('player.sleepTimer_hours', {
|
||||
count: option.minutes / 60,
|
||||
postProcess: 'sentenceCase',
|
||||
});
|
||||
}
|
||||
return t('player.sleepTimer_minutes', {
|
||||
count: option.minutes,
|
||||
postProcess: 'sentenceCase',
|
||||
});
|
||||
};
|
||||
|
||||
@@ -205,7 +203,7 @@ export const SleepTimerButton = () => {
|
||||
}}
|
||||
size="sm"
|
||||
tooltip={{
|
||||
label: t('player.sleepTimer', { postProcess: 'titleCase' }),
|
||||
label: t('player.sleepTimer'),
|
||||
openDelay: 0,
|
||||
}}
|
||||
variant="subtle"
|
||||
@@ -214,7 +212,7 @@ export const SleepTimerButton = () => {
|
||||
<Popover.Dropdown>
|
||||
<Stack gap="xs" p="xs">
|
||||
<Text fw="600" pb="md" size="sm" ta="center">
|
||||
{t('player.sleepTimer', { postProcess: 'titleCase' })}
|
||||
{t('player.sleepTimer')}
|
||||
</Text>
|
||||
|
||||
{active && (
|
||||
@@ -231,9 +229,7 @@ export const SleepTimerButton = () => {
|
||||
>
|
||||
{mode === 'endOfSong' ? (
|
||||
<Text c="primary" size="sm">
|
||||
{t('player.sleepTimer_endOfSong', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
{t('player.sleepTimer_endOfSong')}
|
||||
</Text>
|
||||
) : (
|
||||
<Text c="primary" fw="600" size="lg">
|
||||
@@ -248,7 +244,7 @@ export const SleepTimerButton = () => {
|
||||
size="compact-xs"
|
||||
variant="subtle"
|
||||
>
|
||||
{t('player.sleepTimer_cancel', { postProcess: 'titleCase' })}
|
||||
{t('player.sleepTimer_cancel')}
|
||||
</Button>
|
||||
</Flex>
|
||||
)}
|
||||
@@ -309,7 +305,7 @@ export const SleepTimerButton = () => {
|
||||
ta="center"
|
||||
variant="outline"
|
||||
>
|
||||
{t('player.sleepTimer_custom', { postProcess: 'sentenceCase' })}
|
||||
{t('player.sleepTimer_custom')}
|
||||
</Button>
|
||||
) : (
|
||||
<Stack gap="xs">
|
||||
@@ -350,7 +346,7 @@ export const SleepTimerButton = () => {
|
||||
size="xs"
|
||||
variant="filled"
|
||||
>
|
||||
{t('player.sleepTimer_setCustom', { postProcess: 'titleCase' })}
|
||||
{t('player.sleepTimer_setCustom')}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={(e) => {
|
||||
@@ -360,7 +356,7 @@ export const SleepTimerButton = () => {
|
||||
size="xs"
|
||||
variant="default"
|
||||
>
|
||||
{t('common.cancel', { postProcess: 'titleCase' })}
|
||||
{t('common.cancel')}
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
@@ -158,8 +158,8 @@ export const PlayerProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
children: (
|
||||
<ConfirmModal
|
||||
labels={{
|
||||
cancel: t('common.cancel', { postProcess: 'titleCase' }),
|
||||
confirm: t('common.confirm', { postProcess: 'titleCase' }),
|
||||
cancel: t('common.cancel'),
|
||||
confirm: t('common.confirm'),
|
||||
}}
|
||||
onCancel={() => {
|
||||
resolve(false);
|
||||
@@ -171,15 +171,9 @@ export const PlayerProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
}}
|
||||
>
|
||||
<Stack>
|
||||
<Text>
|
||||
{t('form.largeFetchConfirmation.description', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</Text>
|
||||
<Text>{t('form.largeFetchConfirmation.description')}</Text>
|
||||
<Checkbox
|
||||
label={t('common.doNotShowAgain', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
label={t('common.doNotShowAgain')}
|
||||
onChange={(event) => {
|
||||
setDoNotShowAgain(event.currentTarget.checked);
|
||||
}}
|
||||
@@ -187,9 +181,7 @@ export const PlayerProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
</Stack>
|
||||
</ConfirmModal>
|
||||
),
|
||||
title: t('form.largeFetchConfirmation.title', {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
title: t('form.largeFetchConfirmation.title'),
|
||||
});
|
||||
});
|
||||
}, [doNotShowAgain, setDoNotShowAgain, t]);
|
||||
@@ -236,9 +228,7 @@ export const PlayerProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
[fetchId]: setTimeout(() => {
|
||||
toastId = toast.info({
|
||||
autoClose: false,
|
||||
message: t('player.playbackFetchCancel', {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
message: t('player.playbackFetchCancel'),
|
||||
onClose: () => {
|
||||
queryClient.cancelQueries({
|
||||
exact: false,
|
||||
@@ -250,9 +240,7 @@ export const PlayerProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
queryKey: queryKeys.player.fetch(),
|
||||
});
|
||||
},
|
||||
title: t('player.playbackFetchInProgress', {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
title: t('player.playbackFetchInProgress'),
|
||||
});
|
||||
}, 2000),
|
||||
};
|
||||
@@ -312,7 +300,7 @@ export const PlayerProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
|
||||
toast.error({
|
||||
message: err.message,
|
||||
title: t('error.genericError', { postProcess: 'sentenceCase' }) as string,
|
||||
title: t('error.genericError') as string,
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -401,9 +389,7 @@ export const PlayerProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
[fetchId]: setTimeout(() => {
|
||||
toastId = toast.info({
|
||||
autoClose: false,
|
||||
message: t('player.playbackFetchCancel', {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
message: t('player.playbackFetchCancel'),
|
||||
onClose: () => {
|
||||
logFn.debug(logMsg[LogCategory.PLAYER].cancelledFetch, {
|
||||
category: LogCategory.PLAYER,
|
||||
@@ -420,9 +406,7 @@ export const PlayerProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
queryKey: queryKeys.player.fetch(),
|
||||
});
|
||||
},
|
||||
title: t('player.playbackFetchInProgress', {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
title: t('player.playbackFetchInProgress'),
|
||||
});
|
||||
}, 2000),
|
||||
};
|
||||
@@ -497,7 +481,7 @@ export const PlayerProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
|
||||
toast.error({
|
||||
message: err.message,
|
||||
title: t('error.genericError', { postProcess: 'sentenceCase' }) as string,
|
||||
title: t('error.genericError') as string,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@@ -43,7 +43,7 @@ export const useSaveQueue = () => {
|
||||
const mutation = useMutation({
|
||||
mutationFn: async () => {
|
||||
if (!serverId) {
|
||||
throw new Error(t('error.serverRequired', { postProcess: 'sentenceCase' }));
|
||||
throw new Error(t('error.serverRequired'));
|
||||
}
|
||||
|
||||
const state = usePlayerStore.getState();
|
||||
@@ -51,15 +51,11 @@ export const useSaveQueue = () => {
|
||||
|
||||
if (queue.items.some((item) => item._serverId !== serverId)) {
|
||||
toast.error({
|
||||
message: t('error.multipleServerSaveQueueError', {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
title: t('error.genericError', { postProcess: 'sentenceCase' }),
|
||||
message: t('error.multipleServerSaveQueueError'),
|
||||
title: t('error.genericError'),
|
||||
});
|
||||
|
||||
throw new Error(
|
||||
`${t('error.multipleServerSaveQueueError', { postProcess: 'sentenceCase' })}`,
|
||||
);
|
||||
throw new Error(`${t('error.multipleServerSaveQueueError')}`);
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -73,12 +69,12 @@ export const useSaveQueue = () => {
|
||||
});
|
||||
|
||||
toast.success({
|
||||
message: t('form.saveQueue.success', { postProcess: 'sentenceCase' }),
|
||||
message: t('form.saveQueue.success'),
|
||||
});
|
||||
} catch (error) {
|
||||
toast.error({
|
||||
message: (error as Error).message,
|
||||
title: t('error.saveQueueFailed', { postProcess: 'sentenceCase' }),
|
||||
title: t('error.saveQueueFailed'),
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
@@ -111,7 +107,7 @@ export const useRestoreQueue = () => {
|
||||
} catch (error) {
|
||||
toast.error({
|
||||
message: (error as Error).message,
|
||||
title: t('error.genericError', { postProcess: 'sentenceCase' }),
|
||||
title: t('error.genericError'),
|
||||
});
|
||||
}
|
||||
}, [player, queryClient, serverId]);
|
||||
|
||||
@@ -19,7 +19,7 @@ export const openVisualizerSettingsModal = () => {
|
||||
width: '100%',
|
||||
},
|
||||
},
|
||||
title: i18n.t('common.setting', { count: 2, postProcess: 'titleCase' }),
|
||||
title: i18n.t('common.setting', { count: 2 }),
|
||||
transitionProps: {
|
||||
transition: 'pop',
|
||||
},
|
||||
|
||||
@@ -221,7 +221,7 @@ export const AddToPlaylistContextModal = ({
|
||||
} catch (error: any) {
|
||||
toast.error({
|
||||
message: `[${playlist}] ${error?.message}`,
|
||||
title: t('error.genericError', { postProcess: 'sentenceCase' }),
|
||||
title: t('error.genericError'),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -273,7 +273,7 @@ export const AddToPlaylistContextModal = ({
|
||||
(playlist) => playlist.value === playlistId,
|
||||
)?.label
|
||||
}] ${err.message}`,
|
||||
title: t('error.genericError', { postProcess: 'sentenceCase' }),
|
||||
title: t('error.genericError'),
|
||||
});
|
||||
},
|
||||
},
|
||||
@@ -292,15 +292,14 @@ export const AddToPlaylistContextModal = ({
|
||||
message: t('form.addToPlaylist.success', {
|
||||
message: addMessage,
|
||||
numOfPlaylists: playlistIds.length,
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
});
|
||||
closeModal(id);
|
||||
} catch (error: any) {
|
||||
setIsLoading(false);
|
||||
toast.error({
|
||||
message: error?.message || t('error.genericError', { postProcess: 'sentenceCase' }),
|
||||
title: t('error.genericError', { postProcess: 'sentenceCase' }),
|
||||
message: error?.message || t('error.genericError'),
|
||||
title: t('error.genericError'),
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -422,9 +421,7 @@ export const AddToPlaylistContextModal = ({
|
||||
<TextInput
|
||||
data-autofocus
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
placeholder={t('form.addToPlaylist.searchOrCreate', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
placeholder={t('form.addToPlaylist.searchOrCreate')}
|
||||
value={search}
|
||||
/>
|
||||
<ScrollArea style={{ maxHeight: '18rem' }}>
|
||||
@@ -482,7 +479,6 @@ export const AddToPlaylistContextModal = ({
|
||||
>
|
||||
{t('form.addToPlaylist.create', {
|
||||
playlist: search,
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</Button>
|
||||
)}
|
||||
@@ -512,7 +508,6 @@ export const AddToPlaylistContextModal = ({
|
||||
<Switch
|
||||
label={t('form.addToPlaylist.input', {
|
||||
context: 'skipDuplicates',
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
{...form.getInputProps('skipDuplicates', { type: 'checkbox' })}
|
||||
/>
|
||||
@@ -523,7 +518,7 @@ export const AddToPlaylistContextModal = ({
|
||||
uppercase
|
||||
variant="subtle"
|
||||
>
|
||||
{t('common.cancel', { postProcess: 'titleCase' })}
|
||||
{t('common.cancel')}
|
||||
</ModalButton>
|
||||
<ModalButton
|
||||
disabled={
|
||||
@@ -537,7 +532,7 @@ export const AddToPlaylistContextModal = ({
|
||||
uppercase
|
||||
variant="filled"
|
||||
>
|
||||
{t('common.add', { postProcess: 'titleCase' })}
|
||||
{t('common.add')}
|
||||
</ModalButton>
|
||||
</Group>
|
||||
</Stack>
|
||||
@@ -587,13 +582,7 @@ const PlaylistTableItem = memo(
|
||||
</Group>
|
||||
|
||||
<Text className={styles.statusText} isMuted size="sm">
|
||||
{item.public
|
||||
? t('common.public', {
|
||||
postProcess: 'titleCase',
|
||||
})
|
||||
: t('common.private', {
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
{item.public ? t('common.public') : t('common.private')}
|
||||
</Text>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
@@ -399,9 +399,9 @@ export const ClientSideSongFilters = () => {
|
||||
|
||||
const segmentedControlData = useMemo(
|
||||
() => [
|
||||
{ label: t('common.none', { postProcess: 'titleCase' }), value: 'none' },
|
||||
{ label: t('common.yes', { postProcess: 'titleCase' }), value: 'true' },
|
||||
{ label: t('common.no', { postProcess: 'titleCase' }), value: 'false' },
|
||||
{ label: t('common.none'), value: 'none' },
|
||||
{ label: t('common.yes'), value: 'true' },
|
||||
{ label: t('common.no'), value: 'false' },
|
||||
],
|
||||
[t],
|
||||
);
|
||||
@@ -528,22 +528,22 @@ export const ClientSideSongFilters = () => {
|
||||
const queryMinYear = query[FILTER_KEYS.SONG.MIN_YEAR] as number | undefined;
|
||||
const queryMaxYear = query[FILTER_KEYS.SONG.MAX_YEAR] as number | undefined;
|
||||
|
||||
const matchAndLabel = t('filter.matchAnd', { postProcess: 'titleCase' });
|
||||
const matchOrLabel = t('filter.matchOr', { postProcess: 'titleCase' });
|
||||
const filterSingleLabel = t('common.filter_single', { postProcess: 'titleCase' });
|
||||
const filterMultipleLabel = t('common.filter_multiple', { postProcess: 'titleCase' });
|
||||
const matchAndLabel = t('filter.matchAnd');
|
||||
const matchOrLabel = t('filter.matchOr');
|
||||
const filterSingleLabel = t('common.filter_single');
|
||||
const filterMultipleLabel = t('common.filter_multiple');
|
||||
|
||||
return (
|
||||
<Stack px="md" py="md">
|
||||
<BooleanSegmentFilter
|
||||
label={t('filter.isFavorited', { postProcess: 'sentenceCase' })}
|
||||
label={t('filter.isFavorited')}
|
||||
onChange={setFavorite}
|
||||
segmentData={segmentedControlData}
|
||||
value={queryFavorite}
|
||||
/>
|
||||
<Stack gap="xs" mt="md">
|
||||
<BooleanSegmentFilter
|
||||
label={t('filter.isRated', { postProcess: 'sentenceCase' })}
|
||||
label={t('filter.isRated')}
|
||||
onChange={setHasRating}
|
||||
segmentData={segmentedControlData}
|
||||
value={queryHasRating}
|
||||
@@ -555,7 +555,7 @@ export const ClientSideSongFilters = () => {
|
||||
label={
|
||||
<MultiSelectFilterLabel
|
||||
andOrValue={artistIdsMode}
|
||||
entityLabel={t('entity.artist', { count: 2, postProcess: 'sentenceCase' })}
|
||||
entityLabel={t('entity.artist', { count: 2 })}
|
||||
filterMultipleLabel={filterMultipleLabel}
|
||||
filterSingleLabel={filterSingleLabel}
|
||||
matchAndLabel={matchAndLabel}
|
||||
@@ -580,7 +580,6 @@ export const ClientSideSongFilters = () => {
|
||||
andOrValue={albumArtistIdsMode}
|
||||
entityLabel={t('entity.albumArtist', {
|
||||
count: 2,
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
filterMultipleLabel={filterMultipleLabel}
|
||||
filterSingleLabel={filterSingleLabel}
|
||||
@@ -604,7 +603,7 @@ export const ClientSideSongFilters = () => {
|
||||
label={
|
||||
<MultiSelectFilterLabel
|
||||
andOrValue={genreIdsMode}
|
||||
entityLabel={t('entity.genre', { count: 2, postProcess: 'sentenceCase' })}
|
||||
entityLabel={t('entity.genre', { count: 2 })}
|
||||
filterMultipleLabel={filterMultipleLabel}
|
||||
filterSingleLabel={filterSingleLabel}
|
||||
matchAndLabel={matchAndLabel}
|
||||
@@ -623,12 +622,12 @@ export const ClientSideSongFilters = () => {
|
||||
/>
|
||||
<Divider my="md" />
|
||||
<YearRangeFilter
|
||||
fromYearLabel={t('filter.fromYear', { postProcess: 'titleCase' })}
|
||||
fromYearLabel={t('filter.fromYear')}
|
||||
maxYear={queryMaxYear}
|
||||
minYear={queryMinYear}
|
||||
onMaxYear={debouncedHandleMaxYear}
|
||||
onMinYear={debouncedHandleMinYear}
|
||||
toYearLabel={t('filter.toYear', { postProcess: 'titleCase' })}
|
||||
toYearLabel={t('filter.toYear')}
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
@@ -90,12 +90,12 @@ export const CreatePlaylistForm = ({ onCancel }: CreatePlaylistFormProps) => {
|
||||
onError: (err) => {
|
||||
toast.error({
|
||||
message: err.message,
|
||||
title: t('error.genericError', { postProcess: 'sentenceCase' }),
|
||||
title: t('error.genericError'),
|
||||
});
|
||||
},
|
||||
onSuccess: () => {
|
||||
toast.success({
|
||||
message: t('form.createPlaylist.success', { postProcess: 'sentenceCase' }),
|
||||
message: t('form.createPlaylist.success'),
|
||||
});
|
||||
onCancel();
|
||||
},
|
||||
@@ -115,7 +115,6 @@ export const CreatePlaylistForm = ({ onCancel }: CreatePlaylistFormProps) => {
|
||||
data-autofocus
|
||||
label={t('form.createPlaylist.input', {
|
||||
context: 'name',
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
required
|
||||
{...form.getInputProps('name')}
|
||||
@@ -125,7 +124,6 @@ export const CreatePlaylistForm = ({ onCancel }: CreatePlaylistFormProps) => {
|
||||
autosize
|
||||
label={t('form.createPlaylist.input', {
|
||||
context: 'description',
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
minRows={5}
|
||||
{...form.getInputProps('comment')}
|
||||
@@ -136,7 +134,6 @@ export const CreatePlaylistForm = ({ onCancel }: CreatePlaylistFormProps) => {
|
||||
<Switch
|
||||
label={t('form.createPlaylist.input', {
|
||||
context: 'public',
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
{...form.getInputProps('public', {
|
||||
type: 'checkbox',
|
||||
@@ -189,9 +186,7 @@ export const CreatePlaylistForm = ({ onCancel }: CreatePlaylistFormProps) => {
|
||||
type="submit"
|
||||
variant="filled"
|
||||
>
|
||||
{isSmartPlaylist && step === 1
|
||||
? t('common.confirm', { postProcess: 'sentenceCase' })
|
||||
: t('common.create')}
|
||||
{isSmartPlaylist && step === 1 ? t('common.confirm') : t('common.create')}
|
||||
</ModalButton>
|
||||
</Group>
|
||||
</Stack>
|
||||
@@ -208,6 +203,6 @@ export const openCreatePlaylistModal = (
|
||||
openModal({
|
||||
children: <CreatePlaylistForm onCancel={() => closeAllModals()} />,
|
||||
size: server?.type === ServerType?.NAVIDROME ? 'xl' : 'sm',
|
||||
title: t('form.createPlaylist.title', { postProcess: 'titleCase' }),
|
||||
title: t('form.createPlaylist.title'),
|
||||
});
|
||||
};
|
||||
|
||||
+8
-14
@@ -100,10 +100,10 @@ const PlaylistSongListFiltersModal = () => {
|
||||
variant="subtle"
|
||||
/>
|
||||
)}
|
||||
{t('common.filters', { postProcess: 'sentenceCase' })}
|
||||
{t('common.filters')}
|
||||
</Group>
|
||||
<Button onClick={clear} size="compact-sm" variant="subtle">
|
||||
{t('common.reset', { postProcess: 'sentenceCase' })}
|
||||
{t('common.reset')}
|
||||
</Button>
|
||||
</Group>
|
||||
}
|
||||
@@ -145,8 +145,8 @@ export const PlaylistDetailSongListHeaderFilters = ({
|
||||
: ItemListKey.PLAYLIST_SONG);
|
||||
const isAlbumMode = listKey === ItemListKey.PLAYLIST_ALBUM;
|
||||
const toggleChoice = isAlbumMode
|
||||
? t('entity.album', { count: 2, postProcess: 'titleCase' })
|
||||
: t('entity.track', { count: 2, postProcess: 'titleCase' });
|
||||
? t('entity.album', { count: 2 })
|
||||
: t('entity.track', { count: 2 });
|
||||
|
||||
const handleToggleDisplayMode = useCallback(() => {
|
||||
setPlaylistBehavior(
|
||||
@@ -209,16 +209,10 @@ export const PlaylistDetailSongListHeaderFilters = ({
|
||||
uppercase
|
||||
variant={mode === 'edit' ? 'state-error' : 'subtle'}
|
||||
>
|
||||
{mode === 'edit'
|
||||
? t('common.cancel', { postProcess: 'titleCase' })
|
||||
: t('common.edit', { postProcess: 'titleCase' })}
|
||||
{mode === 'edit' ? t('common.cancel') : t('common.edit')}
|
||||
</Button>
|
||||
)}
|
||||
<Tooltip
|
||||
label={t(`common.${collapsed ? 'expand' : 'collapse'}`, {
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
>
|
||||
<Tooltip label={t(`common.${collapsed ? 'expand' : 'collapse'}`, {})}>
|
||||
<ActionIcon
|
||||
icon={collapsed ? 'arrowDownS' : 'arrowUpS'}
|
||||
iconProps={{ size: 'xl' }}
|
||||
@@ -260,7 +254,7 @@ export const openSaveAndReplaceModal = (
|
||||
innerProps: { onSuccess, playlistId, songIds },
|
||||
modal: 'saveAndReplace',
|
||||
size: 'sm',
|
||||
title: i18n.t('common.saveAndReplace', { postProcess: 'titleCase' }) as string,
|
||||
title: i18n.t('common.saveAndReplace') as string,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -290,7 +284,7 @@ const SaveAndReplaceButton = ({ mode, songIds }: { mode?: 'edit' | 'view'; songI
|
||||
size="sm"
|
||||
variant="subtle"
|
||||
>
|
||||
{t('common.saveAndReplace', { postProcess: 'titleCase' })}
|
||||
{t('common.saveAndReplace')}
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -42,7 +42,7 @@ export const PlaylistListHeaderFilters = () => {
|
||||
</Group>
|
||||
<Group gap="sm" wrap="nowrap">
|
||||
<Button onClick={handleCreatePlaylistModal} variant="subtle">
|
||||
{t('action.createPlaylist', { postProcess: 'sentenceCase' })}
|
||||
{t('action.createPlaylist')}
|
||||
</Button>
|
||||
<ListDisplayTypeToggleButton listKey={ItemListKey.PLAYLIST} />
|
||||
<ListConfigMenu
|
||||
|
||||
@@ -19,7 +19,7 @@ interface PlaylistListHeaderProps {
|
||||
export const PlaylistListHeader = ({ title }: PlaylistListHeaderProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const pageTitle = title || t('page.playlistList.title', { postProcess: 'titleCase' });
|
||||
const pageTitle = title || t('page.playlistList.title');
|
||||
|
||||
return (
|
||||
<Stack gap={0}>
|
||||
|
||||
@@ -452,9 +452,7 @@ export const PlaylistQueryBuilder = forwardRef(
|
||||
// Custom Fields group
|
||||
if (customFields.length > 0) {
|
||||
groups.push({
|
||||
group: t('queryBuilder.customTags', {
|
||||
postProcess: 'titleCase',
|
||||
}),
|
||||
group: t('queryBuilder.customTags'),
|
||||
items: customFields,
|
||||
});
|
||||
}
|
||||
@@ -462,9 +460,7 @@ export const PlaylistQueryBuilder = forwardRef(
|
||||
// Standard Fields group
|
||||
if (NDSongQueryFields.length > 0) {
|
||||
groups.push({
|
||||
group: t('queryBuilder.standardTags', {
|
||||
postProcess: 'titleCase',
|
||||
}),
|
||||
group: t('queryBuilder.standardTags'),
|
||||
items: NDSongQueryFields,
|
||||
});
|
||||
}
|
||||
@@ -484,7 +480,7 @@ export const PlaylistQueryBuilder = forwardRef(
|
||||
const sortOptions = useMemo(
|
||||
() => [
|
||||
{
|
||||
label: t('filter.random', { postProcess: 'titleCase' }),
|
||||
label: t('filter.random'),
|
||||
type: 'string',
|
||||
value: 'random',
|
||||
},
|
||||
@@ -497,11 +493,11 @@ export const PlaylistQueryBuilder = forwardRef(
|
||||
const orderSelectData = useMemo(
|
||||
() => [
|
||||
{
|
||||
label: t('common.ascending', { postProcess: 'sentenceCase' }),
|
||||
label: t('common.ascending'),
|
||||
value: 'asc',
|
||||
},
|
||||
{
|
||||
label: t('common.descending', { postProcess: 'sentenceCase' }),
|
||||
label: t('common.descending'),
|
||||
value: 'desc',
|
||||
},
|
||||
],
|
||||
@@ -574,11 +570,7 @@ export const PlaylistQueryBuilder = forwardRef(
|
||||
<Group align="flex-end" gap="sm" key={index} wrap="nowrap">
|
||||
<Select
|
||||
data={sortOptions}
|
||||
label={
|
||||
index === 0
|
||||
? t('common.sort', { postProcess: 'titleCase' })
|
||||
: ''
|
||||
}
|
||||
label={index === 0 ? t('common.sort') : ''}
|
||||
onChange={(value) =>
|
||||
handleSortFieldChange(index, value || '')
|
||||
}
|
||||
@@ -588,13 +580,7 @@ export const PlaylistQueryBuilder = forwardRef(
|
||||
/>
|
||||
<Select
|
||||
data={orderSelectData}
|
||||
label={
|
||||
index === 0
|
||||
? t('common.sortOrder', {
|
||||
postProcess: 'titleCase',
|
||||
})
|
||||
: ''
|
||||
}
|
||||
label={index === 0 ? t('common.sortOrder') : ''}
|
||||
onChange={(value) =>
|
||||
handleSortOrderChange(
|
||||
index,
|
||||
@@ -625,7 +611,7 @@ export const PlaylistQueryBuilder = forwardRef(
|
||||
<NumberInput
|
||||
label={
|
||||
<Group align="center" gap="xs" wrap="nowrap">
|
||||
{t('common.limit', { postProcess: 'titleCase' })}
|
||||
{t('common.limit')}
|
||||
<SegmentedControl
|
||||
data={[
|
||||
{ label: '#', value: 'limit' },
|
||||
|
||||
@@ -141,7 +141,7 @@ export const PlaylistQueryEditor = ({
|
||||
const payload = getFiltersForSave();
|
||||
if (!payload) {
|
||||
if (editorMode === 'json') {
|
||||
toast.error({ message: t('error.invalidJson', { postProcess: 'sentenceCase' }) });
|
||||
toast.error({ message: t('error.invalidJson') });
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -156,7 +156,7 @@ export const PlaylistQueryEditor = ({
|
||||
openModal({
|
||||
children: <JsonPreview value={previewValue} />,
|
||||
size: 'xl',
|
||||
title: t('common.preview', { postProcess: 'titleCase' }),
|
||||
title: t('common.preview'),
|
||||
});
|
||||
}, [editorMode, getFiltersForSave, t]);
|
||||
|
||||
@@ -165,7 +165,7 @@ export const PlaylistQueryEditor = ({
|
||||
const payload = getFiltersForSave();
|
||||
if (!payload) {
|
||||
if (editorMode === 'json') {
|
||||
toast.error({ message: t('error.invalidJson', { postProcess: 'sentenceCase' }) });
|
||||
toast.error({ message: t('error.invalidJson') });
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -177,10 +177,10 @@ export const PlaylistQueryEditor = ({
|
||||
closeAllModals();
|
||||
}}
|
||||
>
|
||||
<Text>{t('common.areYouSure', { postProcess: 'sentenceCase' })}</Text>
|
||||
<Text>{t('common.areYouSure')}</Text>
|
||||
</ConfirmModal>
|
||||
),
|
||||
title: t('common.saveAndReplace', { postProcess: 'titleCase' }),
|
||||
title: t('common.saveAndReplace'),
|
||||
});
|
||||
}, [editorMode, getFiltersForSave, handleSave, isQueryBuilderExpanded, t]);
|
||||
|
||||
@@ -285,9 +285,7 @@ export const PlaylistQueryEditor = ({
|
||||
});
|
||||
} catch {
|
||||
toast.error({
|
||||
message: t('error.invalidJson', {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
message: t('error.invalidJson'),
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -326,9 +324,7 @@ export const PlaylistQueryEditor = ({
|
||||
size="sm"
|
||||
variant="subtle"
|
||||
>
|
||||
{t('form.queryEditor.title', {
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
{t('form.queryEditor.title')}
|
||||
</Button>
|
||||
{isQueryBuilderExpanded && (
|
||||
<SegmentedControl
|
||||
@@ -358,7 +354,7 @@ export const PlaylistQueryEditor = ({
|
||||
</Group>
|
||||
<Group gap="xs">
|
||||
<Button onClick={openPreviewModal} size="sm" variant="subtle">
|
||||
{t('common.preview', { postProcess: 'titleCase' })}
|
||||
{t('common.preview')}
|
||||
</Button>
|
||||
<Button
|
||||
disabled={!isQueryBuilderExpanded}
|
||||
@@ -371,16 +367,14 @@ export const PlaylistQueryEditor = ({
|
||||
handleSaveAs(payload.filter, payload.extraFilters);
|
||||
} else if (editorMode === 'json') {
|
||||
toast.error({
|
||||
message: t('error.invalidJson', {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
message: t('error.invalidJson'),
|
||||
});
|
||||
}
|
||||
}}
|
||||
size="sm"
|
||||
variant="subtle"
|
||||
>
|
||||
{t('common.saveAs', { postProcess: 'titleCase' })}
|
||||
{t('common.saveAs')}
|
||||
</Button>
|
||||
<Button
|
||||
disabled={!isQueryBuilderExpanded}
|
||||
@@ -389,9 +383,7 @@ export const PlaylistQueryEditor = ({
|
||||
size="sm"
|
||||
variant="subtle"
|
||||
>
|
||||
{t('common.saveAndReplace', {
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
{t('common.saveAndReplace')}
|
||||
</Button>
|
||||
</Group>
|
||||
</Group>
|
||||
|
||||
@@ -36,18 +36,14 @@ export const SaveAndReplaceContextModal = ({
|
||||
console.error(err);
|
||||
toast.error({
|
||||
message: err.message,
|
||||
title: t('error.genericError', {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
title: t('error.genericError'),
|
||||
});
|
||||
},
|
||||
onSuccess: () => {
|
||||
onSuccess();
|
||||
closeAllModals();
|
||||
toast.success({
|
||||
message: t('form.editPlaylist.success', {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
message: t('form.editPlaylist.success'),
|
||||
});
|
||||
},
|
||||
},
|
||||
@@ -56,7 +52,7 @@ export const SaveAndReplaceContextModal = ({
|
||||
|
||||
return (
|
||||
<ConfirmModal loading={updatePlaylistMutation.isPending} onConfirm={handleConfirm}>
|
||||
<Text>{t('common.areYouSure', { postProcess: 'sentenceCase' })}</Text>
|
||||
<Text>{t('common.areYouSure')}</Text>
|
||||
</ConfirmModal>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -50,12 +50,12 @@ export const SaveAsPlaylistForm = ({
|
||||
onError: (err) => {
|
||||
toast.error({
|
||||
message: err.message,
|
||||
title: t('error.genericError', { postProcess: 'sentenceCase' }),
|
||||
title: t('error.genericError'),
|
||||
});
|
||||
},
|
||||
onSuccess: (data) => {
|
||||
toast.success({
|
||||
message: t('form.createPlaylist.success', { postProcess: 'sentenceCase' }),
|
||||
message: t('form.createPlaylist.success'),
|
||||
});
|
||||
onSuccess(data);
|
||||
onCancel();
|
||||
@@ -74,7 +74,6 @@ export const SaveAsPlaylistForm = ({
|
||||
data-autofocus
|
||||
label={t('form.createPlaylist.input', {
|
||||
context: 'name',
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
required
|
||||
{...form.getInputProps('name')}
|
||||
@@ -83,7 +82,6 @@ export const SaveAsPlaylistForm = ({
|
||||
<TextInput
|
||||
label={t('form.createPlaylist.input', {
|
||||
context: 'description',
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
{...form.getInputProps('comment')}
|
||||
/>
|
||||
@@ -92,7 +90,6 @@ export const SaveAsPlaylistForm = ({
|
||||
<Switch
|
||||
label={t('form.createPlaylist.input', {
|
||||
context: 'public',
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
{...form.getInputProps('public', { type: 'checkbox' })}
|
||||
/>
|
||||
|
||||
@@ -108,13 +108,13 @@ export const UpdatePlaylistContextModal = ({
|
||||
}
|
||||
|
||||
toast.success({
|
||||
message: t('form.editPlaylist.success', { postProcess: 'sentenceCase' }),
|
||||
message: t('form.editPlaylist.success'),
|
||||
});
|
||||
closeModal(id);
|
||||
} catch (err: any) {
|
||||
toast.error({
|
||||
message: err?.message,
|
||||
title: t('error.genericError', { postProcess: 'sentenceCase' }),
|
||||
title: t('error.genericError'),
|
||||
});
|
||||
} finally {
|
||||
setIsSaving(false);
|
||||
@@ -134,7 +134,6 @@ export const UpdatePlaylistContextModal = ({
|
||||
key="name"
|
||||
label={t('form.createPlaylist.input', {
|
||||
context: 'name',
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
required
|
||||
{...form.getInputProps('name')}
|
||||
@@ -148,7 +147,6 @@ export const UpdatePlaylistContextModal = ({
|
||||
key="comment"
|
||||
label={t('form.createPlaylist.input', {
|
||||
context: 'description',
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
minRows={5}
|
||||
{...form.getInputProps('comment')}
|
||||
@@ -163,11 +161,7 @@ export const UpdatePlaylistContextModal = ({
|
||||
if (isPublicDisplayed) {
|
||||
if (server?.type === ServerType.JELLYFIN) {
|
||||
fieldNodes.push(
|
||||
<div key="jellyfin-public-note">
|
||||
{t('form.editPlaylist.publicJellyfinNote', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
</div>,
|
||||
<div key="jellyfin-public-note">{t('form.editPlaylist.publicJellyfinNote')}</div>,
|
||||
);
|
||||
}
|
||||
fieldNodes.push(
|
||||
@@ -175,7 +169,6 @@ export const UpdatePlaylistContextModal = ({
|
||||
key="public"
|
||||
label={t('form.createPlaylist.input', {
|
||||
context: 'public',
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
{...form.getInputProps('public', { type: 'checkbox' })}
|
||||
/>,
|
||||
@@ -377,7 +370,6 @@ const OwnerSelect = ({ form }: { form: ReturnType<typeof useForm<UpdatePlaylistB
|
||||
{...form.getInputProps('ownerId')}
|
||||
label={t('form.createPlaylist.input', {
|
||||
context: 'owner',
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -32,6 +32,6 @@ export const openUpdatePlaylistModal = async (args: { playlist: Playlist }) => {
|
||||
},
|
||||
modal: 'updatePlaylist',
|
||||
size: hasImageUpload ? 'lg' : 'md',
|
||||
title: i18n.t('form.editPlaylist.title', { postProcess: 'titleCase' }) as string,
|
||||
title: i18n.t('form.editPlaylist.title') as string,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -46,11 +46,11 @@ const PlaylistSongListFiltersSidebar = () => {
|
||||
<Stack h="100%" style={{ minHeight: 0 }}>
|
||||
<Group justify="space-between" pb={0} pl="md" pr="md" pt="md">
|
||||
<Text fw={500} size="xl">
|
||||
{t('common.filters', { postProcess: 'sentenceCase' })}
|
||||
{t('common.filters')}
|
||||
</Text>
|
||||
<Group gap="xs">
|
||||
<Button onClick={clear} size="compact-sm" variant="subtle">
|
||||
{t('common.reset', { postProcess: 'sentenceCase' })}
|
||||
{t('common.reset')}
|
||||
</Button>
|
||||
{setIsSidebarOpen && (
|
||||
<ActionIcon
|
||||
@@ -170,7 +170,7 @@ const PlaylistDetailSongListRoute = () => {
|
||||
serverId={detailQuery?.data?._serverId || ''}
|
||||
/>
|
||||
),
|
||||
title: t('common.saveAs', { postProcess: 'sentenceCase' }),
|
||||
title: t('common.saveAs'),
|
||||
});
|
||||
};
|
||||
|
||||
@@ -189,9 +189,7 @@ const PlaylistDetailSongListRoute = () => {
|
||||
onError: (err) => {
|
||||
toast.error({
|
||||
message: err.message,
|
||||
title: t('error.genericError', {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
title: t('error.genericError'),
|
||||
});
|
||||
},
|
||||
onSuccess: () => {
|
||||
@@ -205,7 +203,7 @@ const PlaylistDetailSongListRoute = () => {
|
||||
<Text>Are you sure you want to delete this playlist?</Text>
|
||||
</ConfirmModal>
|
||||
),
|
||||
title: t('form.deletePlaylist.title', { postProcess: 'sentenceCase' }),
|
||||
title: t('form.deletePlaylist.title'),
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -42,9 +42,7 @@ export const CreateRadioStationForm = ({ onCancel }: CreateRadioStationFormProps
|
||||
onError: (error) => {
|
||||
toast.error({
|
||||
message: (error as Error).message,
|
||||
title: t('error.genericError', {
|
||||
postProcess: 'sentenceCase',
|
||||
}) as string,
|
||||
title: t('error.genericError') as string,
|
||||
});
|
||||
},
|
||||
onSuccess: () => {
|
||||
@@ -60,7 +58,6 @@ export const CreateRadioStationForm = ({ onCancel }: CreateRadioStationFormProps
|
||||
<TextInput
|
||||
label={t('form.createRadioStation.input', {
|
||||
context: 'name',
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
required
|
||||
{...form.getInputProps('name')}
|
||||
@@ -68,7 +65,6 @@ export const CreateRadioStationForm = ({ onCancel }: CreateRadioStationFormProps
|
||||
<TextInput
|
||||
label={t('form.createRadioStation.input', {
|
||||
context: 'streamUrl',
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
required
|
||||
{...form.getInputProps('streamUrl')}
|
||||
@@ -76,16 +72,15 @@ export const CreateRadioStationForm = ({ onCancel }: CreateRadioStationFormProps
|
||||
<TextInput
|
||||
label={t('form.createRadioStation.input', {
|
||||
context: 'homepageUrl',
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
{...form.getInputProps('homepageUrl')}
|
||||
/>
|
||||
<Group justify="flex-end">
|
||||
<ModalButton onClick={onCancel} variant="subtle">
|
||||
{t('common.cancel', { postProcess: 'sentenceCase' })}
|
||||
{t('common.cancel')}
|
||||
</ModalButton>
|
||||
<ModalButton loading={mutation.isPending} type="submit" variant="filled">
|
||||
{t('common.create', { postProcess: 'sentenceCase' })}
|
||||
{t('common.create')}
|
||||
</ModalButton>
|
||||
</Group>
|
||||
</Stack>
|
||||
@@ -101,13 +96,13 @@ export const openCreateRadioStationModal = (
|
||||
|
||||
if (!server) {
|
||||
toast.error({
|
||||
message: t('common.error.noServer', { postProcess: 'sentenceCase' }) as string,
|
||||
message: t('common.error.noServer') as string,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
openModal({
|
||||
children: <CreateRadioStationForm onCancel={closeAllModals} />,
|
||||
title: t('action.createRadioStation', { postProcess: 'titleCase' }) as string,
|
||||
title: t('action.createRadioStation') as string,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -104,9 +104,7 @@ export const EditRadioStationForm = ({ onCancel, station }: EditRadioStationForm
|
||||
}
|
||||
|
||||
toast.success({
|
||||
message: t('form.editRadioStation.success', {
|
||||
postProcess: 'sentenceCase',
|
||||
}) as string,
|
||||
message: t('form.editRadioStation.success') as string,
|
||||
});
|
||||
closeAllModals();
|
||||
} catch (err: unknown) {
|
||||
@@ -116,7 +114,7 @@ export const EditRadioStationForm = ({ onCancel, station }: EditRadioStationForm
|
||||
|
||||
toast.error({
|
||||
message: (err as Error)?.message,
|
||||
title: t('error.genericError', { postProcess: 'sentenceCase' }) as string,
|
||||
title: t('error.genericError') as string,
|
||||
});
|
||||
} finally {
|
||||
setIsSaving(false);
|
||||
@@ -132,7 +130,6 @@ export const EditRadioStationForm = ({ onCancel, station }: EditRadioStationForm
|
||||
key="name"
|
||||
label={t('form.createRadioStation.input', {
|
||||
context: 'name',
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
required
|
||||
{...form.getInputProps('name')}
|
||||
@@ -141,7 +138,6 @@ export const EditRadioStationForm = ({ onCancel, station }: EditRadioStationForm
|
||||
key="streamUrl"
|
||||
label={t('form.createRadioStation.input', {
|
||||
context: 'streamUrl',
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
required
|
||||
{...form.getInputProps('streamUrl')}
|
||||
@@ -150,7 +146,6 @@ export const EditRadioStationForm = ({ onCancel, station }: EditRadioStationForm
|
||||
key="homepageUrl"
|
||||
label={t('form.createRadioStation.input', {
|
||||
context: 'homepageUrl',
|
||||
postProcess: 'titleCase',
|
||||
})}
|
||||
{...form.getInputProps('homepageUrl')}
|
||||
/>,
|
||||
@@ -329,7 +324,7 @@ export const openEditRadioStationModal = (
|
||||
|
||||
if (!server) {
|
||||
toast.error({
|
||||
message: t('common.error.noServer', { postProcess: 'sentenceCase' }) as string,
|
||||
message: t('common.error.noServer') as string,
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -339,6 +334,6 @@ export const openEditRadioStationModal = (
|
||||
openModal({
|
||||
children: <EditRadioStationForm onCancel={closeAllModals} station={station} />,
|
||||
size: hasImageUpload ? 'lg' : 'md',
|
||||
title: t('common.edit', { postProcess: 'titleCase' }) as string,
|
||||
title: t('common.edit') as string,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -38,7 +38,7 @@ export const RadioListHeaderFilters = () => {
|
||||
{permissions.radio.create && (
|
||||
<Group gap="sm" wrap="nowrap">
|
||||
<Button onClick={handleCreateRadioStationModal} variant="subtle">
|
||||
{t('action.createRadioStation', { postProcess: 'sentenceCase' })}
|
||||
{t('action.createRadioStation')}
|
||||
</Button>
|
||||
</Group>
|
||||
)}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user