mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-09 20:29:36 +02:00
Add missing translations
This commit is contained in:
+168
-160
@@ -2,10 +2,12 @@
|
|||||||
"action": {
|
"action": {
|
||||||
"addToFavorites": "add to $t(entity.favorite_other)",
|
"addToFavorites": "add to $t(entity.favorite_other)",
|
||||||
"addToPlaylist": "add to $t(entity.playlist_one)",
|
"addToPlaylist": "add to $t(entity.playlist_one)",
|
||||||
|
"clearQueue": "clear queue",
|
||||||
"createPlaylist": "create $t(entity.playlist_one)",
|
"createPlaylist": "create $t(entity.playlist_one)",
|
||||||
"deletePlaylist": "delete $t(entity.playlist_one)",
|
"deletePlaylist": "delete $t(entity.playlist_one)",
|
||||||
"deselectAll": "deselect all",
|
"deselectAll": "deselect all",
|
||||||
"editPlaylist": "edit $t(entity.playlist_one)",
|
"editPlaylist": "edit $t(entity.playlist_one)",
|
||||||
|
"goToPage": "go to page",
|
||||||
"moveToBottom": "move to bottom",
|
"moveToBottom": "move to bottom",
|
||||||
"moveToTop": "move to top",
|
"moveToTop": "move to top",
|
||||||
"refresh": "$t(glossary.refresh)",
|
"refresh": "$t(glossary.refresh)",
|
||||||
@@ -17,43 +19,46 @@
|
|||||||
"viewPlaylists": "view $t(entity.playlist_other)"
|
"viewPlaylists": "view $t(entity.playlist_other)"
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"currentSong": "current $t(entity.track_one)",
|
|
||||||
"previousSong": "previous $t(entity.track_one)",
|
|
||||||
"backward": "backward",
|
|
||||||
"forward": "forward",
|
|
||||||
"modified": "modified",
|
|
||||||
"minimize": "minimize",
|
|
||||||
"increase": "increase",
|
|
||||||
"decrease": "decrease",
|
|
||||||
"maximize": "maximize",
|
|
||||||
"areYouSure": "are you sure?",
|
|
||||||
"resetToDefault": "reset to default",
|
|
||||||
"manage": "manage",
|
|
||||||
"add": "add",
|
"add": "add",
|
||||||
|
"areYouSure": "are you sure?",
|
||||||
|
"backward": "backward",
|
||||||
"cancel": "cancel",
|
"cancel": "cancel",
|
||||||
|
"center": "center",
|
||||||
|
"comingSoon": "coming soon...",
|
||||||
"confirm": "confirm",
|
"confirm": "confirm",
|
||||||
"create": "create",
|
"create": "create",
|
||||||
|
"currentSong": "current $t(entity.track_one)",
|
||||||
|
"decrease": "decrease",
|
||||||
"delete": "delete",
|
"delete": "delete",
|
||||||
"disable": "disable",
|
"disable": "disable",
|
||||||
"dismiss": "dismiss",
|
"dismiss": "dismiss",
|
||||||
"edit": "edit",
|
"edit": "edit",
|
||||||
"enable": "enable",
|
"enable": "enable",
|
||||||
|
"filters": "filters",
|
||||||
|
"forceRestartRequired": "restart to apply changes... close the notification to restart",
|
||||||
|
"forward": "forward",
|
||||||
|
"increase": "increase",
|
||||||
|
"left": "left",
|
||||||
|
"manage": "manage",
|
||||||
|
"maximize": "maximize",
|
||||||
|
"minimize": "minimize",
|
||||||
|
"modified": "modified",
|
||||||
"no": "no",
|
"no": "no",
|
||||||
"none": "none",
|
"none": "none",
|
||||||
|
"noResultsFromQuery": "the query returned no results",
|
||||||
"ok": "ok",
|
"ok": "ok",
|
||||||
"playerMustBePaused": "player must be paused",
|
"playerMustBePaused": "player must be paused",
|
||||||
|
"previousSong": "previous $t(entity.track_one)",
|
||||||
"quit": "quit",
|
"quit": "quit",
|
||||||
|
"resetToDefault": "reset to default",
|
||||||
"restartRequired": "restart required",
|
"restartRequired": "restart required",
|
||||||
"forceRestartRequired": "restart to apply changes... close the notification to restart",
|
|
||||||
"save": "save",
|
|
||||||
"saveAs": "save as",
|
|
||||||
"saveAndReplace": "save and replace",
|
|
||||||
"yes": "yes",
|
|
||||||
"left": "left",
|
|
||||||
"center": "center",
|
|
||||||
"right": "right",
|
"right": "right",
|
||||||
|
"save": "save",
|
||||||
|
"saveAndReplace": "save and replace",
|
||||||
|
"saveAs": "save as",
|
||||||
"search": "search",
|
"search": "search",
|
||||||
"noResultsFromQuery": "the query returned no results"
|
"unknown": "unknown",
|
||||||
|
"yes": "yes"
|
||||||
},
|
},
|
||||||
"entity": {
|
"entity": {
|
||||||
"album_one": "album",
|
"album_one": "album",
|
||||||
@@ -82,8 +87,6 @@
|
|||||||
"playlist_other": "playlists",
|
"playlist_other": "playlists",
|
||||||
"playlistWithCount_one": "{{count}} playlist",
|
"playlistWithCount_one": "{{count}} playlist",
|
||||||
"playlistWithCount_other": "{{count}} playlists",
|
"playlistWithCount_other": "{{count}} playlists",
|
||||||
"setting_one": "setting",
|
|
||||||
"setting_other": "settings",
|
|
||||||
"smartPlaylist": "smart $t(entity.playlist_one)",
|
"smartPlaylist": "smart $t(entity.playlist_one)",
|
||||||
"track_one": "track",
|
"track_one": "track",
|
||||||
"track_other": "tracks",
|
"track_other": "tracks",
|
||||||
@@ -91,79 +94,27 @@
|
|||||||
"trackWithCount_other": "{{count}} tracks"
|
"trackWithCount_other": "{{count}} tracks"
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"playbackError": "an error occurred when trying to play the media",
|
|
||||||
"genericError": "an error occurred",
|
|
||||||
"apiRouteError": "unable to route request",
|
"apiRouteError": "unable to route request",
|
||||||
"serverNotSelectedError": "no server selected",
|
|
||||||
"endpointNotImplementedError": "endpoint {{endpoint} is not implemented for {{serverType}}",
|
|
||||||
"audioDeviceFetchError": "an error occurred when trying to get audio devices",
|
"audioDeviceFetchError": "an error occurred when trying to get audio devices",
|
||||||
|
"authenticationFailed": "authentication failed",
|
||||||
|
"credentialsRequired": "credentials required",
|
||||||
|
"endpointNotImplementedError": "endpoint {{endpoint} is not implemented for {{serverType}}",
|
||||||
|
"genericError": "an error occurred",
|
||||||
|
"invalidServer": "invalid server",
|
||||||
"localFontAccessDenied": "access denied to local fonts",
|
"localFontAccessDenied": "access denied to local fonts",
|
||||||
|
"loginRateError": "too many login attempts, please try again in a few seconds",
|
||||||
|
"mpvRequired": "MPV required",
|
||||||
|
"playbackError": "an error occurred when trying to play the media",
|
||||||
"remoteDisableError": "an error occurred when trying to $t(common.disable) the remote server",
|
"remoteDisableError": "an error occurred when trying to $t(common.disable) the remote server",
|
||||||
"remoteEnableError": "an error occurred when trying to $t(common.enable) the remote server",
|
"remoteEnableError": "an error occurred when trying to $t(common.enable) the remote server",
|
||||||
"remotePortError": "an error occurred when trying to set the remote server port",
|
"remotePortError": "an error occurred when trying to set the remote server port",
|
||||||
"remotePortWarning": "restart the server to apply the new port",
|
"remotePortWarning": "restart the server to apply the new port",
|
||||||
"systemFontError": "an error occurred when trying to get system fonts",
|
"serverNotSelectedError": "no server selected",
|
||||||
"invalidServer": "invalid server",
|
"serverRequired": "server required",
|
||||||
"authenticationFailed": "authentication failed",
|
|
||||||
"sessionExpiredError": "your session has expired",
|
"sessionExpiredError": "your session has expired",
|
||||||
"loginRateError": "too many login attempts, please try again in a few seconds",
|
"systemFontError": "an error occurred when trying to get system fonts"
|
||||||
"mpvRequired": "MPV required",
|
|
||||||
"credentialsRequired": "credentials required",
|
|
||||||
"serverRequired": "server required"
|
|
||||||
},
|
|
||||||
"form": {
|
|
||||||
"addServer": {
|
|
||||||
"title": "add server",
|
|
||||||
"input_name": "server name",
|
|
||||||
"input_url": "url",
|
|
||||||
"input_username": "username",
|
|
||||||
"input_password": "password",
|
|
||||||
"input_savePassword": "save password",
|
|
||||||
"input_legacyAuthentication": "enable legacy authentication",
|
|
||||||
"ignoreCors": "ignore cors ($t(common.restartRequired))",
|
|
||||||
"ignoreSsl": "ignore ssl ($t(common.restartRequired))",
|
|
||||||
"success": "server added successfully",
|
|
||||||
"error_savePassword": "an error occurred when trying to save the password"
|
|
||||||
},
|
|
||||||
"createPlaylist": {
|
|
||||||
"title": "create $t(entity.playlist_one)",
|
|
||||||
"input_name": "$t(glossary.name)",
|
|
||||||
"input_description": "$t(glossary.description)",
|
|
||||||
"input_public": "public",
|
|
||||||
"input_owner": "$t(glossary.owner)",
|
|
||||||
"success": "$t(entity.playlist_one) created successfully"
|
|
||||||
},
|
|
||||||
"editPlaylist": {
|
|
||||||
"title": "edit $t(entity.playlist_one)"
|
|
||||||
},
|
|
||||||
"deletePlaylist": {
|
|
||||||
"title": "delete $t(entity.playlist_one)",
|
|
||||||
"input_confirm": "type the name of the $t(entity.playlist_one) to confirm",
|
|
||||||
"success": "$t(entity.playlist_one) deleted successfully"
|
|
||||||
},
|
|
||||||
"addToPlaylist": {
|
|
||||||
"title": "add to $t(entity.playlist_one)",
|
|
||||||
"input_playlists": "$t(entity.playlist_other)",
|
|
||||||
"input_skipDuplicates": "skip duplicates",
|
|
||||||
"success": "added {{message}} $t(entity.song_other) to {{numOfPlaylists}} $t(entity.playlist_other)"
|
|
||||||
},
|
|
||||||
"updateServer": {
|
|
||||||
"title": "update server",
|
|
||||||
"success": "server updated successfully"
|
|
||||||
},
|
|
||||||
"lyricSearch": {
|
|
||||||
"title": "lyric search",
|
|
||||||
"input_name": "$t(glossary.name)",
|
|
||||||
"input_artist": "$t(entity.artist_one)"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"filter": {
|
"filter": {
|
||||||
"isRated": "is rated",
|
|
||||||
"isFavorited": "is favorited",
|
|
||||||
"isCompilation": "is compilation",
|
|
||||||
"isRecentlyPlayed": "is recently played",
|
|
||||||
"fromYear": "from year",
|
|
||||||
"toYear": "to year",
|
|
||||||
"albumArtist": "$t(entity.albumArtist_one)",
|
"albumArtist": "$t(entity.albumArtist_one)",
|
||||||
"artist": "$t(entity.artist_one)",
|
"artist": "$t(entity.artist_one)",
|
||||||
"biography": "biography",
|
"biography": "biography",
|
||||||
@@ -175,6 +126,11 @@
|
|||||||
"disc": "disc",
|
"disc": "disc",
|
||||||
"duration": "duration",
|
"duration": "duration",
|
||||||
"favorited": "favorited",
|
"favorited": "favorited",
|
||||||
|
"fromYear": "from year",
|
||||||
|
"isCompilation": "is compilation",
|
||||||
|
"isFavorited": "is favorited",
|
||||||
|
"isRated": "is rated",
|
||||||
|
"isRecentlyPlayed": "is recently played",
|
||||||
"lastPlayed": "last played",
|
"lastPlayed": "last played",
|
||||||
"mostPlayed": "most played",
|
"mostPlayed": "most played",
|
||||||
"name": "name",
|
"name": "name",
|
||||||
@@ -190,16 +146,61 @@
|
|||||||
"search": "search",
|
"search": "search",
|
||||||
"songCount": "song count",
|
"songCount": "song count",
|
||||||
"title": "title",
|
"title": "title",
|
||||||
|
"toYear": "to year",
|
||||||
"trackNumber": "track"
|
"trackNumber": "track"
|
||||||
},
|
},
|
||||||
|
"form": {
|
||||||
|
"addServer": {
|
||||||
|
"error_savePassword": "an error occurred when trying to save the password",
|
||||||
|
"ignoreCors": "ignore cors ($t(common.restartRequired))",
|
||||||
|
"ignoreSsl": "ignore ssl ($t(common.restartRequired))",
|
||||||
|
"input_legacyAuthentication": "enable legacy authentication",
|
||||||
|
"input_name": "server name",
|
||||||
|
"input_password": "password",
|
||||||
|
"input_savePassword": "save password",
|
||||||
|
"input_url": "url",
|
||||||
|
"input_username": "username",
|
||||||
|
"success": "server added successfully",
|
||||||
|
"title": "add server"
|
||||||
|
},
|
||||||
|
"addToPlaylist": {
|
||||||
|
"input_playlists": "$t(entity.playlist_other)",
|
||||||
|
"input_skipDuplicates": "skip duplicates",
|
||||||
|
"success": "added {{message}} $t(entity.song_other) to {{numOfPlaylists}} $t(entity.playlist_other)",
|
||||||
|
"title": "add to $t(entity.playlist_one)"
|
||||||
|
},
|
||||||
|
"createPlaylist": {
|
||||||
|
"input_description": "$t(glossary.description)",
|
||||||
|
"input_name": "$t(glossary.name)",
|
||||||
|
"input_owner": "$t(glossary.owner)",
|
||||||
|
"input_public": "public",
|
||||||
|
"success": "$t(entity.playlist_one) created successfully",
|
||||||
|
"title": "create $t(entity.playlist_one)"
|
||||||
|
},
|
||||||
|
"deletePlaylist": {
|
||||||
|
"input_confirm": "type the name of the $t(entity.playlist_one) to confirm",
|
||||||
|
"success": "$t(entity.playlist_one) deleted successfully",
|
||||||
|
"title": "delete $t(entity.playlist_one)"
|
||||||
|
},
|
||||||
|
"editPlaylist": {
|
||||||
|
"title": "edit $t(entity.playlist_one)"
|
||||||
|
},
|
||||||
|
"lyricSearch": {
|
||||||
|
"input_artist": "$t(entity.artist_one)",
|
||||||
|
"input_name": "$t(glossary.name)",
|
||||||
|
"title": "lyric search"
|
||||||
|
},
|
||||||
|
"queryEditor": {
|
||||||
|
"input_optionMatchAll": "match all",
|
||||||
|
"input_optionMatchAny": "match any"
|
||||||
|
},
|
||||||
|
"updateServer": {
|
||||||
|
"success": "server updated successfully",
|
||||||
|
"title": "update server"
|
||||||
|
}
|
||||||
|
},
|
||||||
"glossary": {
|
"glossary": {
|
||||||
"sortOrder": "order",
|
|
||||||
"limit": "limit",
|
|
||||||
"reset": "reset",
|
|
||||||
"clear": "clear",
|
|
||||||
"action": "action",
|
"action": "action",
|
||||||
"expand": "expand",
|
|
||||||
"collapse": "collapse",
|
|
||||||
"action_other": "actions",
|
"action_other": "actions",
|
||||||
"ascending": "ascending",
|
"ascending": "ascending",
|
||||||
"biography": "biography",
|
"biography": "biography",
|
||||||
@@ -207,16 +208,20 @@
|
|||||||
"bpm": "bpm",
|
"bpm": "bpm",
|
||||||
"channel": "channel",
|
"channel": "channel",
|
||||||
"channel_other": "channels",
|
"channel_other": "channels",
|
||||||
|
"clear": "clear",
|
||||||
|
"collapse": "collapse",
|
||||||
"configure": "configure",
|
"configure": "configure",
|
||||||
"descending": "descending",
|
"descending": "descending",
|
||||||
|
"description": "description",
|
||||||
"disc": "disc",
|
"disc": "disc",
|
||||||
"duration": "duration",
|
"duration": "duration",
|
||||||
|
"expand": "expand",
|
||||||
"favorite": "favorite",
|
"favorite": "favorite",
|
||||||
"filter_one": "filter",
|
"filter_one": "filter",
|
||||||
"filter_other": "filters",
|
"filter_other": "filters",
|
||||||
"description": "description",
|
|
||||||
"gap": "gap",
|
"gap": "gap",
|
||||||
"home": "home",
|
"home": "home",
|
||||||
|
"limit": "limit",
|
||||||
"menu": "menu",
|
"menu": "menu",
|
||||||
"name": "name",
|
"name": "name",
|
||||||
"note": "note",
|
"note": "note",
|
||||||
@@ -225,29 +230,25 @@
|
|||||||
"random": "random",
|
"random": "random",
|
||||||
"rating": "rating",
|
"rating": "rating",
|
||||||
"refresh": "refresh",
|
"refresh": "refresh",
|
||||||
|
"reset": "reset",
|
||||||
"search": "search",
|
"search": "search",
|
||||||
"setting": "setting",
|
"setting": "setting",
|
||||||
"setting_other": "settings",
|
"setting_other": "settings",
|
||||||
"size": "size",
|
"size": "size",
|
||||||
|
"sortOrder": "order",
|
||||||
"title": "title",
|
"title": "title",
|
||||||
"trackNumber": "track",
|
"trackNumber": "track",
|
||||||
"version": "version",
|
"version": "version",
|
||||||
"year": "year"
|
"year": "year"
|
||||||
},
|
},
|
||||||
"page": {
|
"page": {
|
||||||
|
"albumArtistList": {
|
||||||
|
"title": "$t(entity.albumArtist_other)"
|
||||||
|
},
|
||||||
"albumDetail": {
|
"albumDetail": {
|
||||||
"moreFromArtist": "more from this $t(entity.genre_one)",
|
"moreFromArtist": "more from this $t(entity.genre_one)",
|
||||||
"moreFromGeneric": "more from {{item}}"
|
"moreFromGeneric": "more from {{item}}"
|
||||||
},
|
},
|
||||||
"setting": {
|
|
||||||
"generalTab": "general",
|
|
||||||
"playbackTab": "playback",
|
|
||||||
"hotkeysTab": "hotkeys",
|
|
||||||
"windowTab": "window"
|
|
||||||
},
|
|
||||||
"albumArtistList": {
|
|
||||||
"title": "$t(entity.albumArtist_other)"
|
|
||||||
},
|
|
||||||
"albumList": {
|
"albumList": {
|
||||||
"title": "$t(entity.album_other)"
|
"title": "$t(entity.album_other)"
|
||||||
},
|
},
|
||||||
@@ -281,9 +282,35 @@
|
|||||||
"removeFromQueue": "$t(action.removeFromQueue)",
|
"removeFromQueue": "$t(action.removeFromQueue)",
|
||||||
"setRating": "$t(action.setRating)"
|
"setRating": "$t(action.setRating)"
|
||||||
},
|
},
|
||||||
|
"fullscreenPlayer": {
|
||||||
|
"config": {
|
||||||
|
"dynamicBackground": "dynamic background",
|
||||||
|
"followCurrentLyric": "follow current lyric",
|
||||||
|
"lyricAlignment": "lyric alignment",
|
||||||
|
"lyricGap": "lyric gap",
|
||||||
|
"lyricSize": "lyric size",
|
||||||
|
"opacity": "opacity",
|
||||||
|
"showLyricMatch": "show lyric match",
|
||||||
|
"showLyricProvider": "show lyric provider",
|
||||||
|
"synchronized": "synchronized",
|
||||||
|
"unsynchronized": "unsynchronized",
|
||||||
|
"useImageAspectRatio": "use image aspect ratio"
|
||||||
|
},
|
||||||
|
"lyrics": "lyrics",
|
||||||
|
"related": "related",
|
||||||
|
"upNext": "up next"
|
||||||
|
},
|
||||||
"genreList": {
|
"genreList": {
|
||||||
"title": "$t(entity.genre_other)"
|
"title": "$t(entity.genre_other)"
|
||||||
},
|
},
|
||||||
|
"globalSearch": {
|
||||||
|
"commands": {
|
||||||
|
"goToPage": "go to page",
|
||||||
|
"searchFor": "search for {{query}}",
|
||||||
|
"serverCommands": "server commands"
|
||||||
|
},
|
||||||
|
"title": "commands"
|
||||||
|
},
|
||||||
"home": {
|
"home": {
|
||||||
"explore": "explore from your library",
|
"explore": "explore from your library",
|
||||||
"mostPlayed": "most played",
|
"mostPlayed": "most played",
|
||||||
@@ -294,10 +321,16 @@
|
|||||||
"playlistList": {
|
"playlistList": {
|
||||||
"title": "$t(entity.playlist_other)"
|
"title": "$t(entity.playlist_other)"
|
||||||
},
|
},
|
||||||
|
"setting": {
|
||||||
|
"generalTab": "general",
|
||||||
|
"hotkeysTab": "hotkeys",
|
||||||
|
"playbackTab": "playback",
|
||||||
|
"windowTab": "window"
|
||||||
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
|
"albumArtists": "$t(entity.albumArtist_other)",
|
||||||
"albums": "$t(entity.album_other)",
|
"albums": "$t(entity.album_other)",
|
||||||
"artists": "$t(entity.artist_other)",
|
"artists": "$t(entity.artist_other)",
|
||||||
"albumArtists": "$t(entity.albumArtist_other)",
|
|
||||||
"folders": "$t(entity.folder_other)",
|
"folders": "$t(entity.folder_other)",
|
||||||
"genres": "$t(entity.genre_other)",
|
"genres": "$t(entity.genre_other)",
|
||||||
"home": "$t(glossary.home)",
|
"home": "$t(glossary.home)",
|
||||||
@@ -309,40 +342,21 @@
|
|||||||
},
|
},
|
||||||
"trackList": {
|
"trackList": {
|
||||||
"title": "$t(entity.track_other)"
|
"title": "$t(entity.track_other)"
|
||||||
},
|
|
||||||
"globalSearch": {
|
|
||||||
"title": "commands",
|
|
||||||
"commands": {
|
|
||||||
"searchFor": "search for {{query}}",
|
|
||||||
"goToPage": "go to page",
|
|
||||||
"serverCommands": "server commands"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fullscreenPlayer": {
|
|
||||||
"config": {
|
|
||||||
"dynamicBackground": "dynamic background",
|
|
||||||
"useImageAspectRatio": "use image aspect ratio",
|
|
||||||
"opacity": "opacity",
|
|
||||||
"followCurrentLyric": "follow current lyric",
|
|
||||||
"showLyricProvider": "show lyric provider",
|
|
||||||
"showLyricMatch": "show lyric match",
|
|
||||||
"lyricSize": "lyric size",
|
|
||||||
"synchronized": "synchronized",
|
|
||||||
"unsynchronized": "unsynchronized",
|
|
||||||
"lyricGap": "lyric gap",
|
|
||||||
"lyricAlignment": "lyric alignment"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"player": {
|
"player": {
|
||||||
"favorite": "favorite",
|
|
||||||
"unfavorite": "unfavorite",
|
|
||||||
"addLast": "add last",
|
"addLast": "add last",
|
||||||
"addNext": "add next",
|
"addNext": "add next",
|
||||||
|
"favorite": "favorite",
|
||||||
"mute": "mute",
|
"mute": "mute",
|
||||||
"muted": "muted",
|
"muted": "muted",
|
||||||
"next": "next",
|
"next": "next",
|
||||||
"play": "play",
|
"play": "play",
|
||||||
|
"playbackFetchCancel": "this is taking a while... close the notification to cancel",
|
||||||
|
"playbackFetchInProgress": "loading songs...",
|
||||||
|
"playbackFetchNoResults": "no songs found",
|
||||||
|
"playbackSpeed": "playback speed",
|
||||||
|
"playRandom": "play random",
|
||||||
"previous": "previous",
|
"previous": "previous",
|
||||||
"queue_clear": "clear queue",
|
"queue_clear": "clear queue",
|
||||||
"queue_moveToBottom": "move selected to top",
|
"queue_moveToBottom": "move selected to top",
|
||||||
@@ -352,36 +366,16 @@
|
|||||||
"repeat_all": "repeat all",
|
"repeat_all": "repeat all",
|
||||||
"repeat_off": "repeat disabled",
|
"repeat_off": "repeat disabled",
|
||||||
"repeat_one": "repeat one",
|
"repeat_one": "repeat one",
|
||||||
|
"shuffle": "shuffle",
|
||||||
|
"shuffle_off": "shuffle disabled",
|
||||||
"skip": "skip",
|
"skip": "skip",
|
||||||
"skip_back": "skip backwards",
|
"skip_back": "skip backwards",
|
||||||
"skip_forward": "skip forwards",
|
"skip_forward": "skip forwards",
|
||||||
"shuffle": "shuffle",
|
|
||||||
"playRandom": "play random",
|
|
||||||
"shuffle_off": "shuffle disabled",
|
|
||||||
"stop": "stop",
|
"stop": "stop",
|
||||||
"toggleFullscreenPlayer": "toggle fullscreen player",
|
"toggleFullscreenPlayer": "toggle fullscreen player",
|
||||||
"playbackSpeed": "playback speed",
|
"unfavorite": "unfavorite"
|
||||||
"playbackFetchNoResults": "no songs found",
|
|
||||||
"playbackFetchInProgress": "loading songs...",
|
|
||||||
"playbackFetchCancel": "this is taking a while... close the notification to cancel"
|
|
||||||
},
|
},
|
||||||
"setting": {
|
"setting": {
|
||||||
"exitToTray": "exit to tray",
|
|
||||||
"exitToTray_description": "exit the application to the system tray",
|
|
||||||
"minimizeToTray": "minimize to tray",
|
|
||||||
"minimizeToTray_description": "minimize the application to the system tray",
|
|
||||||
"windowBarStyle": "window bar style",
|
|
||||||
"windowBarStyle_description": "select the style of the window bar",
|
|
||||||
"disableAutomaticUpdates": "disable automatic updates",
|
|
||||||
"disableLibraryUpdateOnStartup": "disable checking for new versions on startup",
|
|
||||||
"discordRichPresence": "{{discord}} rich presence",
|
|
||||||
"discordRichPresence_description": "enable playback status in {{discord}} rich presence. Image keys are: {{icon}}, {{playing}}, and {{paused}} ",
|
|
||||||
"discordApplicationId": "{{discord}} application id",
|
|
||||||
"discordApplicationId_description": "the application id for {{discord}} rich presence (defaults to {{defaultId}}",
|
|
||||||
"discordUpdateInterval": "{{discord}} rich presence update interval",
|
|
||||||
"discordUpdateInterval_description": "the time in seconds between each update (minimum 15 seconds)",
|
|
||||||
"discordIdleStatus": "show rich presence idle status",
|
|
||||||
"discordIdleStatus_description": "when enabled, update status while player is idle",
|
|
||||||
"accentColor": "accent color",
|
"accentColor": "accent color",
|
||||||
"accentColor_description": "sets the accent color for the application",
|
"accentColor_description": "sets the accent color for the application",
|
||||||
"applicationHotkeys": "application hotkeys",
|
"applicationHotkeys": "application hotkeys",
|
||||||
@@ -398,8 +392,20 @@
|
|||||||
"crossfadeStyle_description": "select the crossfade style to use for the audio player",
|
"crossfadeStyle_description": "select the crossfade style to use for the audio player",
|
||||||
"customFontPath": "custom font path",
|
"customFontPath": "custom font path",
|
||||||
"customFontPath_description": "sets the path to the custom font to use for the application",
|
"customFontPath_description": "sets the path to the custom font to use for the application",
|
||||||
|
"disableAutomaticUpdates": "disable automatic updates",
|
||||||
|
"disableLibraryUpdateOnStartup": "disable checking for new versions on startup",
|
||||||
|
"discordApplicationId": "{{discord}} application id",
|
||||||
|
"discordApplicationId_description": "the application id for {{discord}} rich presence (defaults to {{defaultId}}",
|
||||||
|
"discordIdleStatus": "show rich presence idle status",
|
||||||
|
"discordIdleStatus_description": "when enabled, update status while player is idle",
|
||||||
|
"discordRichPresence": "{{discord}} rich presence",
|
||||||
|
"discordRichPresence_description": "enable playback status in {{discord}} rich presence. Image keys are: {{icon}}, {{playing}}, and {{paused}} ",
|
||||||
|
"discordUpdateInterval": "{{discord}} rich presence update interval",
|
||||||
|
"discordUpdateInterval_description": "the time in seconds between each update (minimum 15 seconds)",
|
||||||
"enableRemote": "enable remote control server",
|
"enableRemote": "enable remote control server",
|
||||||
"enableRemote_description": "enables the remote control server to allow other devices to control the application",
|
"enableRemote_description": "enables the remote control server to allow other devices to control the application",
|
||||||
|
"exitToTray": "exit to tray",
|
||||||
|
"exitToTray_description": "exit the application to the system tray",
|
||||||
"floatingQueueArea": "show floating queue hover area",
|
"floatingQueueArea": "show floating queue hover area",
|
||||||
"floatingQueueArea_description": "display a hover icon on the right side of the screen to view the play queue",
|
"floatingQueueArea_description": "display a hover icon on the right side of the screen to view the play queue",
|
||||||
"followLyric": "follow current lyric",
|
"followLyric": "follow current lyric",
|
||||||
@@ -416,14 +422,10 @@
|
|||||||
"gaplessAudio_optionWeak": "weak (recommended)",
|
"gaplessAudio_optionWeak": "weak (recommended)",
|
||||||
"globalMediaHotkeys": "global media hotkeys",
|
"globalMediaHotkeys": "global media hotkeys",
|
||||||
"globalMediaHotkeys_description": "enable or disable the usage of your system media hotkeys to control playback",
|
"globalMediaHotkeys_description": "enable or disable the usage of your system media hotkeys to control playback",
|
||||||
"hotkey_favoriteCurrentSong": "favorite $t(common.currentSong)",
|
|
||||||
"hotkey_unfavoriteCurrentSong": "unfavorite $t(common.currentSong)",
|
|
||||||
"hotkey_toggleCurrentSongFavorite": "toggle $t(common.currentSong) favorite",
|
|
||||||
"hotkey_favoritePreviousSong": "favorite $t(common.previousSong)",
|
|
||||||
"hotkey_unfavoritePreviousSong": "unfavorite $t(common.previousSong)",
|
|
||||||
"hotkey_togglePreviousSongFavorite": "toggle $t(common.previousSong) favorite",
|
|
||||||
"hotkey_browserBack": "browser back",
|
"hotkey_browserBack": "browser back",
|
||||||
"hotkey_browserForward": "browser forward",
|
"hotkey_browserForward": "browser forward",
|
||||||
|
"hotkey_favoriteCurrentSong": "favorite $t(common.currentSong)",
|
||||||
|
"hotkey_favoritePreviousSong": "favorite $t(common.previousSong)",
|
||||||
"hotkey_globalSearch": "global search",
|
"hotkey_globalSearch": "global search",
|
||||||
"hotkey_localSearch": "in-page search",
|
"hotkey_localSearch": "in-page search",
|
||||||
"hotkey_playbackNext": "next track",
|
"hotkey_playbackNext": "next track",
|
||||||
@@ -440,23 +442,29 @@
|
|||||||
"hotkey_rate5": "rating 5 stars",
|
"hotkey_rate5": "rating 5 stars",
|
||||||
"hotkey_skipBackward": "skip backward",
|
"hotkey_skipBackward": "skip backward",
|
||||||
"hotkey_skipForward": "skip forward",
|
"hotkey_skipForward": "skip forward",
|
||||||
|
"hotkey_toggleCurrentSongFavorite": "toggle $t(common.currentSong) favorite",
|
||||||
"hotkey_toggleFullScreenPlayer": "toggle full screen player",
|
"hotkey_toggleFullScreenPlayer": "toggle full screen player",
|
||||||
|
"hotkey_togglePreviousSongFavorite": "toggle $t(common.previousSong) favorite",
|
||||||
"hotkey_toggleQueue": "toggle queue",
|
"hotkey_toggleQueue": "toggle queue",
|
||||||
"hotkey_toggleRepeat": "toggle repeat",
|
"hotkey_toggleRepeat": "toggle repeat",
|
||||||
"hotkey_toggleShuffle": "toggle shuffle",
|
"hotkey_toggleShuffle": "toggle shuffle",
|
||||||
|
"hotkey_unfavoriteCurrentSong": "unfavorite $t(common.currentSong)",
|
||||||
|
"hotkey_unfavoritePreviousSong": "unfavorite $t(common.previousSong)",
|
||||||
"hotkey_volumeDown": "volume down",
|
"hotkey_volumeDown": "volume down",
|
||||||
"hotkey_volumeMute": "volume mute",
|
"hotkey_volumeMute": "volume mute",
|
||||||
"hotkey_volumeUp": "volume up",
|
"hotkey_volumeUp": "volume up",
|
||||||
"hotkey_zoomIn": "zoom in",
|
"hotkey_zoomIn": "zoom in",
|
||||||
"hotkey_zoomOut": "zoom out",
|
"hotkey_zoomOut": "zoom out",
|
||||||
"language": "language",
|
"language": "language",
|
||||||
"language_description": "sets the language for the application",
|
"language_description": "sets the language for the application ($t(common.restartRequired))",
|
||||||
"lyricFetch": "fetch lyrics from the internet",
|
"lyricFetch": "fetch lyrics from the internet",
|
||||||
"lyricFetch_description": "fetch lyrics from various internet sources",
|
"lyricFetch_description": "fetch lyrics from various internet sources",
|
||||||
"lyricFetchProvider": "providers to fetch lyrics from",
|
"lyricFetchProvider": "providers to fetch lyrics from",
|
||||||
"lyricFetchProvider_description": "select the providers to fetch lyrics from. the order of the providers is the order in which they will be queried",
|
"lyricFetchProvider_description": "select the providers to fetch lyrics from. the order of the providers is the order in which they will be queried",
|
||||||
"lyricOffset": "lyric offset (ms)",
|
"lyricOffset": "lyric offset (ms)",
|
||||||
"lyricOffset_description": "offset the lyric by the specified amount of milliseconds",
|
"lyricOffset_description": "offset the lyric by the specified amount of milliseconds",
|
||||||
|
"minimizeToTray": "minimize to tray",
|
||||||
|
"minimizeToTray_description": "minimize the application to the system tray",
|
||||||
"minimumScrobblePercentage": "minimum scrobble duration (percentage)",
|
"minimumScrobblePercentage": "minimum scrobble duration (percentage)",
|
||||||
"minimumScrobblePercentage_description": "the minimum percentage of the song that must be played before it is scrobbled",
|
"minimumScrobblePercentage_description": "the minimum percentage of the song that must be played before it is scrobbled",
|
||||||
"minimumScrobbleSeconds": "minimum scrobble (seconds)",
|
"minimumScrobbleSeconds": "minimum scrobble (seconds)",
|
||||||
@@ -525,10 +533,10 @@
|
|||||||
"useSystemTheme_description": "follow the system-defined light or dark preference",
|
"useSystemTheme_description": "follow the system-defined light or dark preference",
|
||||||
"volumeWheelStep": "volume wheel step",
|
"volumeWheelStep": "volume wheel step",
|
||||||
"volumeWheelStep_description": "the amount of volume to change when scrolling the mouse wheel on the volume slider",
|
"volumeWheelStep_description": "the amount of volume to change when scrolling the mouse wheel on the volume slider",
|
||||||
|
"windowBarStyle": "window bar style",
|
||||||
|
"windowBarStyle_description": "select the style of the window bar",
|
||||||
"zoom": "zoom percentage",
|
"zoom": "zoom percentage",
|
||||||
"zoom_description": "sets the zoom percentage for the application",
|
"zoom_description": "sets the zoom percentage for the application"
|
||||||
"zoomPercentage": "zoom percentage",
|
|
||||||
"zoomPercentage_description": "sets the zoom percentage for the application"
|
|
||||||
},
|
},
|
||||||
"table": {
|
"table": {
|
||||||
"column": {
|
"column": {
|
||||||
|
|||||||
@@ -6,14 +6,21 @@ import { Button } from '/@/renderer/components/button';
|
|||||||
import { DropdownMenu } from '/@/renderer/components/dropdown-menu';
|
import { DropdownMenu } from '/@/renderer/components/dropdown-menu';
|
||||||
import { QueryBuilderOption } from '/@/renderer/components/query-builder/query-builder-option';
|
import { QueryBuilderOption } from '/@/renderer/components/query-builder/query-builder-option';
|
||||||
import { QueryBuilderGroup, QueryBuilderRule } from '/@/renderer/types';
|
import { QueryBuilderGroup, QueryBuilderRule } from '/@/renderer/types';
|
||||||
|
import i18n from '/@/i18n/i18n';
|
||||||
|
|
||||||
const FILTER_GROUP_OPTIONS_DATA = [
|
const FILTER_GROUP_OPTIONS_DATA = [
|
||||||
{
|
{
|
||||||
label: 'Match all',
|
label: i18n.t('form.queryEditor.input', {
|
||||||
|
context: 'optionMatchAll',
|
||||||
|
postProcess: 'sentenceCase',
|
||||||
|
}),
|
||||||
value: 'all',
|
value: 'all',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Match any',
|
label: i18n.t('form.queryEditor.input', {
|
||||||
|
context: 'optionMatchAny',
|
||||||
|
postProcess: 'sentenceCase',
|
||||||
|
}),
|
||||||
value: 'any',
|
value: 'any',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
|
import { MutableRefObject } from 'react';
|
||||||
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
|
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
|
||||||
import { Group } from '@mantine/core';
|
import { Group } from '@mantine/core';
|
||||||
import { useForm } from '@mantine/form';
|
import { useForm } from '@mantine/form';
|
||||||
import { useDisclosure } from '@mantine/hooks';
|
import { useDisclosure } from '@mantine/hooks';
|
||||||
import { MutableRefObject } from 'react';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { RiHashtag } from 'react-icons/ri';
|
import { RiHashtag } from 'react-icons/ri';
|
||||||
import { Button } from '/@/renderer/components/button';
|
import { Button } from '/@/renderer/components/button';
|
||||||
import { MotionFlex } from '../motion';
|
import { MotionFlex } from '../motion';
|
||||||
@@ -29,6 +30,7 @@ export const TablePagination = ({
|
|||||||
setPagination,
|
setPagination,
|
||||||
setIdPagination,
|
setIdPagination,
|
||||||
}: TablePaginationProps) => {
|
}: TablePaginationProps) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const [isGoToPageOpen, handlers] = useDisclosure(false);
|
const [isGoToPageOpen, handlers] = useDisclosure(false);
|
||||||
const containerQuery = useContainerQuery();
|
const containerQuery = useContainerQuery();
|
||||||
|
|
||||||
@@ -115,7 +117,9 @@ export const TablePagination = ({
|
|||||||
radius="sm"
|
radius="sm"
|
||||||
size="sm"
|
size="sm"
|
||||||
sx={{ height: '26px', padding: '0', width: '26px' }}
|
sx={{ height: '26px', padding: '0', width: '26px' }}
|
||||||
tooltip={{ label: 'Go to page' }}
|
tooltip={{
|
||||||
|
label: t('action.goToPage', { postProcess: 'sentenceCase' }),
|
||||||
|
}}
|
||||||
variant="default"
|
variant="default"
|
||||||
onClick={() => handlers.toggle()}
|
onClick={() => handlers.toggle()}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export const JellyfinAlbumFilters = ({
|
|||||||
|
|
||||||
const toggleFilters = [
|
const toggleFilters = [
|
||||||
{
|
{
|
||||||
label: 'Is favorited',
|
label: t('filter.isFavorited', { postProcess: 'sentenceCase' }),
|
||||||
onChange: (e: ChangeEvent<HTMLInputElement>) => {
|
onChange: (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
const updatedFilters = setFilter({
|
const updatedFilters = setFilter({
|
||||||
customFilters,
|
customFilters,
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
|
import { ChangeEvent, MouseEvent, MutableRefObject, useCallback } from 'react';
|
||||||
import { IDatasource } from '@ag-grid-community/core';
|
import { IDatasource } from '@ag-grid-community/core';
|
||||||
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
|
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
|
||||||
import { Divider, Flex, Group, Stack } from '@mantine/core';
|
import { Divider, Flex, Group, Stack } from '@mantine/core';
|
||||||
import { useQueryClient } from '@tanstack/react-query';
|
import { useQueryClient } from '@tanstack/react-query';
|
||||||
import debounce from 'lodash/debounce';
|
import debounce from 'lodash/debounce';
|
||||||
import { ChangeEvent, MouseEvent, MutableRefObject, useCallback } from 'react';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { RiFolder2Line, RiMoreFill, RiRefreshLine, RiSettings3Fill } from 'react-icons/ri';
|
import { RiFolder2Line, RiMoreFill, RiRefreshLine, RiSettings3Fill } from 'react-icons/ri';
|
||||||
import { useListContext } from '../../../context/list-context';
|
import { useListContext } from '../../../context/list-context';
|
||||||
import { api } from '/@/renderer/api';
|
import { api } from '/@/renderer/api';
|
||||||
@@ -62,6 +63,7 @@ export const AlbumArtistListHeaderFilters = ({
|
|||||||
gridRef,
|
gridRef,
|
||||||
tableRef,
|
tableRef,
|
||||||
}: AlbumArtistListHeaderFiltersProps) => {
|
}: AlbumArtistListHeaderFiltersProps) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const server = useCurrentServer();
|
const server = useCurrentServer();
|
||||||
const { pageKey } = useListContext();
|
const { pageKey } = useListContext();
|
||||||
@@ -77,7 +79,7 @@ export const AlbumArtistListHeaderFilters = ({
|
|||||||
(server?.type &&
|
(server?.type &&
|
||||||
FILTERS[server.type as keyof typeof FILTERS].find((f) => f.value === filter.sortBy)
|
FILTERS[server.type as keyof typeof FILTERS].find((f) => f.value === filter.sortBy)
|
||||||
?.name) ||
|
?.name) ||
|
||||||
'Unknown';
|
t('common.unknown', { postProcess: 'titleCase' });
|
||||||
|
|
||||||
const handleItemSize = (e: number) => {
|
const handleItemSize = (e: number) => {
|
||||||
if (display === ListDisplayType.TABLE || display === ListDisplayType.TABLE_PAGINATED) {
|
if (display === ListDisplayType.TABLE || display === ListDisplayType.TABLE_PAGINATED) {
|
||||||
@@ -359,7 +361,7 @@ export const AlbumArtistListHeaderFilters = ({
|
|||||||
<Button
|
<Button
|
||||||
compact
|
compact
|
||||||
size="md"
|
size="md"
|
||||||
tooltip={{ label: 'Refresh' }}
|
tooltip={{ label: t('common.refresh', { postProcess: 'titleCase' }) }}
|
||||||
variant="subtle"
|
variant="subtle"
|
||||||
onClick={handleRefresh}
|
onClick={handleRefresh}
|
||||||
>
|
>
|
||||||
@@ -407,21 +409,27 @@ export const AlbumArtistListHeaderFilters = ({
|
|||||||
value={ListDisplayType.CARD}
|
value={ListDisplayType.CARD}
|
||||||
onClick={handleSetViewType}
|
onClick={handleSetViewType}
|
||||||
>
|
>
|
||||||
Card
|
{t('table.config.view.card', {
|
||||||
|
postProcess: 'sentenceCase',
|
||||||
|
})}
|
||||||
</DropdownMenu.Item>
|
</DropdownMenu.Item>
|
||||||
<DropdownMenu.Item
|
<DropdownMenu.Item
|
||||||
$isActive={display === ListDisplayType.POSTER}
|
$isActive={display === ListDisplayType.POSTER}
|
||||||
value={ListDisplayType.POSTER}
|
value={ListDisplayType.POSTER}
|
||||||
onClick={handleSetViewType}
|
onClick={handleSetViewType}
|
||||||
>
|
>
|
||||||
Poster
|
{t('table.config.view.poster', {
|
||||||
|
postProcess: 'sentenceCase',
|
||||||
|
})}
|
||||||
</DropdownMenu.Item>
|
</DropdownMenu.Item>
|
||||||
<DropdownMenu.Item
|
<DropdownMenu.Item
|
||||||
$isActive={display === ListDisplayType.TABLE}
|
$isActive={display === ListDisplayType.TABLE}
|
||||||
value={ListDisplayType.TABLE}
|
value={ListDisplayType.TABLE}
|
||||||
onClick={handleSetViewType}
|
onClick={handleSetViewType}
|
||||||
>
|
>
|
||||||
Table
|
{t('table.config.view.table', {
|
||||||
|
postProcess: 'sentenceCase',
|
||||||
|
})}
|
||||||
</DropdownMenu.Item>
|
</DropdownMenu.Item>
|
||||||
{/* <DropdownMenu.Item
|
{/* <DropdownMenu.Item
|
||||||
$isActive={display === ListDisplayType.TABLE_PAGINATED}
|
$isActive={display === ListDisplayType.TABLE_PAGINATED}
|
||||||
@@ -465,7 +473,11 @@ export const AlbumArtistListHeaderFilters = ({
|
|||||||
)}
|
)}
|
||||||
{!isGrid && (
|
{!isGrid && (
|
||||||
<>
|
<>
|
||||||
<DropdownMenu.Label>Table Columns</DropdownMenu.Label>
|
<DropdownMenu.Label>
|
||||||
|
{t('table.config.general.tableColumns', {
|
||||||
|
postProcess: 'sentenceCase',
|
||||||
|
})}
|
||||||
|
</DropdownMenu.Label>
|
||||||
<DropdownMenu.Item
|
<DropdownMenu.Item
|
||||||
closeMenuOnClick={false}
|
closeMenuOnClick={false}
|
||||||
component="div"
|
component="div"
|
||||||
@@ -482,7 +494,11 @@ export const AlbumArtistListHeaderFilters = ({
|
|||||||
onChange={handleTableColumns}
|
onChange={handleTableColumns}
|
||||||
/>
|
/>
|
||||||
<Group position="apart">
|
<Group position="apart">
|
||||||
<Text>Auto Fit Columns</Text>
|
<Text>
|
||||||
|
{t('table.config.general.autoFitColumns', {
|
||||||
|
postProcess: 'sentenceCase',
|
||||||
|
})}
|
||||||
|
</Text>
|
||||||
<Switch
|
<Switch
|
||||||
defaultChecked={table.autoFit}
|
defaultChecked={table.autoFit}
|
||||||
onChange={handleAutoFitColumns}
|
onChange={handleAutoFitColumns}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/li
|
|||||||
import { Group } from '@mantine/core';
|
import { Group } from '@mantine/core';
|
||||||
import { Button, Popover } from '/@/renderer/components';
|
import { Button, Popover } from '/@/renderer/components';
|
||||||
import isElectron from 'is-electron';
|
import isElectron from 'is-electron';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
import {
|
import {
|
||||||
RiArrowDownLine,
|
RiArrowDownLine,
|
||||||
RiArrowUpLine,
|
RiArrowUpLine,
|
||||||
@@ -27,6 +28,7 @@ interface PlayQueueListOptionsProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const PlayQueueListControls = ({ type, tableRef }: PlayQueueListOptionsProps) => {
|
export const PlayQueueListControls = ({ type, tableRef }: PlayQueueListOptionsProps) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const { clearQueue, moveToBottomOfQueue, moveToTopOfQueue, shuffleQueue, removeFromQueue } =
|
const { clearQueue, moveToBottomOfQueue, moveToTopOfQueue, shuffleQueue, removeFromQueue } =
|
||||||
useQueueControls();
|
useQueueControls();
|
||||||
|
|
||||||
@@ -115,7 +117,7 @@ export const PlayQueueListControls = ({ type, tableRef }: PlayQueueListOptionsPr
|
|||||||
<Button
|
<Button
|
||||||
compact
|
compact
|
||||||
size="md"
|
size="md"
|
||||||
tooltip={{ label: 'Shuffle queue' }}
|
tooltip={{ label: t('player.shuffle', { postProcess: 'sentenceCase' }) }}
|
||||||
variant="default"
|
variant="default"
|
||||||
onClick={handleShuffleQueue}
|
onClick={handleShuffleQueue}
|
||||||
>
|
>
|
||||||
@@ -124,7 +126,7 @@ export const PlayQueueListControls = ({ type, tableRef }: PlayQueueListOptionsPr
|
|||||||
<Button
|
<Button
|
||||||
compact
|
compact
|
||||||
size="md"
|
size="md"
|
||||||
tooltip={{ label: 'Move selected to bottom' }}
|
tooltip={{ label: t('action.moveToBottom', { postProcess: 'sentenceCase' }) }}
|
||||||
variant="default"
|
variant="default"
|
||||||
onClick={handleMoveToBottom}
|
onClick={handleMoveToBottom}
|
||||||
>
|
>
|
||||||
@@ -133,7 +135,7 @@ export const PlayQueueListControls = ({ type, tableRef }: PlayQueueListOptionsPr
|
|||||||
<Button
|
<Button
|
||||||
compact
|
compact
|
||||||
size="md"
|
size="md"
|
||||||
tooltip={{ label: 'Move selected to top' }}
|
tooltip={{ label: t('action.moveToTop', { postProcess: 'sentenceCase' }) }}
|
||||||
variant="default"
|
variant="default"
|
||||||
onClick={handleMoveToTop}
|
onClick={handleMoveToTop}
|
||||||
>
|
>
|
||||||
@@ -142,7 +144,9 @@ export const PlayQueueListControls = ({ type, tableRef }: PlayQueueListOptionsPr
|
|||||||
<Button
|
<Button
|
||||||
compact
|
compact
|
||||||
size="md"
|
size="md"
|
||||||
tooltip={{ label: 'Remove selected' }}
|
tooltip={{
|
||||||
|
label: t('action.removeFromQueue', { postProcess: 'sentenceCase' }),
|
||||||
|
}}
|
||||||
variant="default"
|
variant="default"
|
||||||
onClick={handleRemoveSelected}
|
onClick={handleRemoveSelected}
|
||||||
>
|
>
|
||||||
@@ -151,7 +155,7 @@ export const PlayQueueListControls = ({ type, tableRef }: PlayQueueListOptionsPr
|
|||||||
<Button
|
<Button
|
||||||
compact
|
compact
|
||||||
size="md"
|
size="md"
|
||||||
tooltip={{ label: 'Clear queue' }}
|
tooltip={{ label: t('action.clearQueue', { postProcess: 'sentenceCase' }) }}
|
||||||
variant="default"
|
variant="default"
|
||||||
onClick={handleClearQueue}
|
onClick={handleClearQueue}
|
||||||
>
|
>
|
||||||
@@ -167,7 +171,9 @@ export const PlayQueueListControls = ({ type, tableRef }: PlayQueueListOptionsPr
|
|||||||
<Button
|
<Button
|
||||||
compact
|
compact
|
||||||
size="md"
|
size="md"
|
||||||
tooltip={{ label: 'Configure' }}
|
tooltip={{
|
||||||
|
label: t('glossary.configure', { postProcess: 'sentenceCase' }),
|
||||||
|
}}
|
||||||
variant="subtle"
|
variant="subtle"
|
||||||
>
|
>
|
||||||
<RiListSettingsLine size="1.1rem" />
|
<RiListSettingsLine size="1.1rem" />
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Group, Center } from '@mantine/core';
|
import { Group, Center } from '@mantine/core';
|
||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
import { HiOutlineQueueList } from 'react-icons/hi2';
|
import { HiOutlineQueueList } from 'react-icons/hi2';
|
||||||
import { RiFileMusicLine, RiFileTextLine, RiInformationFill } from 'react-icons/ri';
|
import { RiFileMusicLine, RiFileTextLine, RiInformationFill } from 'react-icons/ri';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
@@ -50,11 +51,12 @@ const GridContainer = styled.div<TransparendGridContainerProps>`
|
|||||||
grid-template-rows: auto minmax(0, 1fr);
|
grid-template-rows: auto minmax(0, 1fr);
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
background: rgb(var(--main-bg-transparent), ${({ opacity }) => opacity}%);
|
background: rgb(var(--main-bg-transparent) ${({ opacity }) => opacity}%);
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const FullScreenPlayerQueue = () => {
|
export const FullScreenPlayerQueue = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const { activeTab, opacity } = useFullScreenPlayerStore();
|
const { activeTab, opacity } = useFullScreenPlayerStore();
|
||||||
const { setStore } = useFullScreenPlayerStoreActions();
|
const { setStore } = useFullScreenPlayerStoreActions();
|
||||||
|
|
||||||
@@ -62,19 +64,19 @@ export const FullScreenPlayerQueue = () => {
|
|||||||
{
|
{
|
||||||
active: activeTab === 'queue',
|
active: activeTab === 'queue',
|
||||||
icon: <RiFileMusicLine size="1.5rem" />,
|
icon: <RiFileMusicLine size="1.5rem" />,
|
||||||
label: 'Up Next',
|
label: t('page.fullScreenPlayer.upNext'),
|
||||||
onClick: () => setStore({ activeTab: 'queue' }),
|
onClick: () => setStore({ activeTab: 'queue' }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
active: activeTab === 'related',
|
active: activeTab === 'related',
|
||||||
icon: <HiOutlineQueueList size="1.5rem" />,
|
icon: <HiOutlineQueueList size="1.5rem" />,
|
||||||
label: 'Related',
|
label: t('page.fullScreenPlayer.related'),
|
||||||
onClick: () => setStore({ activeTab: 'related' }),
|
onClick: () => setStore({ activeTab: 'related' }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
active: activeTab === 'lyrics',
|
active: activeTab === 'lyrics',
|
||||||
icon: <RiFileTextLine size="1.5rem" />,
|
icon: <RiFileTextLine size="1.5rem" />,
|
||||||
label: 'Lyrics',
|
label: t('page.fullScreenPlayer.lyrics'),
|
||||||
onClick: () => setStore({ activeTab: 'lyrics' }),
|
onClick: () => setStore({ activeTab: 'lyrics' }),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@@ -125,7 +127,7 @@ export const FullScreenPlayerQueue = () => {
|
|||||||
order={3}
|
order={3}
|
||||||
weight={700}
|
weight={700}
|
||||||
>
|
>
|
||||||
COMING SOON
|
{t('common.comingSoon', { postProcess: 'upperCase' })}
|
||||||
</TextTitle>
|
</TextTitle>
|
||||||
</Group>
|
</Group>
|
||||||
</Center>
|
</Center>
|
||||||
|
|||||||
@@ -271,9 +271,14 @@ export const ApplicationSettings = () => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
description: 'Sets the application zoom factor in percent',
|
description: t('setting.zoom', {
|
||||||
|
context: 'description',
|
||||||
|
postProcess: 'sentenceCase',
|
||||||
|
}),
|
||||||
isHidden: !isElectron(),
|
isHidden: !isElectron(),
|
||||||
title: 'Zoom factor',
|
title: t('setting.zoom', {
|
||||||
|
postProcess: 'sentenceCase',
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ export const SidebarSettings = () => {
|
|||||||
variant="filled"
|
variant="filled"
|
||||||
onClick={handleSave}
|
onClick={handleSave}
|
||||||
>
|
>
|
||||||
Save sidebar configuration
|
{t('common.save', { postProcess: 'titleCase' })}
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
description={t('setting.sidebarCollapsedNavigation', {
|
description={t('setting.sidebarCollapsedNavigation', {
|
||||||
|
|||||||
@@ -282,7 +282,7 @@ export const MpvSettings = () => {
|
|||||||
note: t('common.restartRequired', { postProcess: 'sentenceCase' }),
|
note: t('common.restartRequired', { postProcess: 'sentenceCase' }),
|
||||||
title: t('setting.replayGainMode', {
|
title: t('setting.replayGainMode', {
|
||||||
ReplayGain: 'ReplayGain',
|
ReplayGain: 'ReplayGain',
|
||||||
postProcess: 'lowerCase',
|
postProcess: 'sentenceCase',
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -300,7 +300,7 @@ export const MpvSettings = () => {
|
|||||||
}),
|
}),
|
||||||
title: t('setting.replayGainPreamp', {
|
title: t('setting.replayGainPreamp', {
|
||||||
ReplayGain: 'ReplayGain',
|
ReplayGain: 'ReplayGain',
|
||||||
postProcess: 'lowerCase',
|
postProcess: 'sentenceCase',
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -318,7 +318,7 @@ export const MpvSettings = () => {
|
|||||||
}),
|
}),
|
||||||
title: t('setting.replayGainClipping', {
|
title: t('setting.replayGainClipping', {
|
||||||
ReplayGain: 'ReplayGain',
|
ReplayGain: 'ReplayGain',
|
||||||
postProcess: 'lowerCase',
|
postProcess: 'sentenceCase',
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -335,7 +335,7 @@ export const MpvSettings = () => {
|
|||||||
}),
|
}),
|
||||||
title: t('setting.replayGainFallback', {
|
title: t('setting.replayGainFallback', {
|
||||||
ReplayGain: 'ReplayGain',
|
ReplayGain: 'ReplayGain',
|
||||||
postProcess: 'lowerCase',
|
postProcess: 'sentenceCase',
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ export const DiscordSettings = () => {
|
|||||||
isHidden: !isElectron(),
|
isHidden: !isElectron(),
|
||||||
title: t('setting.discordRichPresence', {
|
title: t('setting.discordRichPresence', {
|
||||||
discord: 'Discord',
|
discord: 'Discord',
|
||||||
postProcess: 'lowerCase',
|
postProcess: 'sentenceCase',
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -64,7 +64,7 @@ export const DiscordSettings = () => {
|
|||||||
isHidden: !isElectron(),
|
isHidden: !isElectron(),
|
||||||
title: t('setting.discordApplicationId', {
|
title: t('setting.discordApplicationId', {
|
||||||
discord: 'Discord',
|
discord: 'Discord',
|
||||||
postProcess: 'lowerCase',
|
postProcess: 'sentenceCase',
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -93,7 +93,7 @@ export const DiscordSettings = () => {
|
|||||||
isHidden: !isElectron(),
|
isHidden: !isElectron(),
|
||||||
title: t('setting.discordUpdateInterval', {
|
title: t('setting.discordUpdateInterval', {
|
||||||
discord: 'Discord',
|
discord: 'Discord',
|
||||||
postProcess: 'lowerCase',
|
postProcess: 'sentenceCase',
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Group } from '@mantine/core';
|
|
||||||
import { forwardRef, ReactNode, Ref, useState } from 'react';
|
import { forwardRef, ReactNode, Ref, useState } from 'react';
|
||||||
|
import { Group } from '@mantine/core';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import styles from './library-header.module.scss';
|
import styles from './library-header.module.scss';
|
||||||
import { LibraryItem } from '/@/renderer/api/types';
|
import { LibraryItem } from '/@/renderer/api/types';
|
||||||
@@ -20,12 +21,30 @@ export const LibraryHeader = forwardRef(
|
|||||||
{ imageUrl, imagePlaceholderUrl, background, title, item, children }: LibraryHeaderProps,
|
{ imageUrl, imagePlaceholderUrl, background, title, item, children }: LibraryHeaderProps,
|
||||||
ref: Ref<HTMLDivElement>,
|
ref: Ref<HTMLDivElement>,
|
||||||
) => {
|
) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const [isImageError, setIsImageError] = useState<boolean | null>(false);
|
const [isImageError, setIsImageError] = useState<boolean | null>(false);
|
||||||
|
|
||||||
const onImageError = () => {
|
const onImageError = () => {
|
||||||
setIsImageError(true);
|
setIsImageError(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const itemTypeString = () => {
|
||||||
|
switch (item.type) {
|
||||||
|
case LibraryItem.ALBUM:
|
||||||
|
return t('entity.album', { count: 1 });
|
||||||
|
case LibraryItem.ARTIST:
|
||||||
|
return t('entity.artist', { count: 1 });
|
||||||
|
case LibraryItem.ALBUM_ARTIST:
|
||||||
|
return t('entity.albumArtist', { count: 1 });
|
||||||
|
case LibraryItem.PLAYLIST:
|
||||||
|
return t('entity.playlist', { count: 1 });
|
||||||
|
case LibraryItem.SONG:
|
||||||
|
return t('entity.track', { count: 1 });
|
||||||
|
default:
|
||||||
|
return t('common.unknown');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
ref={ref}
|
ref={ref}
|
||||||
@@ -59,7 +78,7 @@ export const LibraryHeader = forwardRef(
|
|||||||
tt="uppercase"
|
tt="uppercase"
|
||||||
weight={600}
|
weight={600}
|
||||||
>
|
>
|
||||||
{item.type}
|
{itemTypeString()}
|
||||||
</Text>
|
</Text>
|
||||||
</Group>
|
</Group>
|
||||||
<h1 className={styles.title}>{title}</h1>
|
<h1 className={styles.title}>{title}</h1>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Grid, Group } from '@mantine/core';
|
import { Grid, Group } from '@mantine/core';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
import { RiSearchLine, RiMenuFill, RiArrowLeftSLine, RiArrowRightSLine } from 'react-icons/ri';
|
import { RiSearchLine, RiMenuFill, RiArrowLeftSLine, RiArrowRightSLine } from 'react-icons/ri';
|
||||||
import { useNavigate } from 'react-router';
|
import { useNavigate } from 'react-router';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
@@ -19,6 +20,7 @@ const ActionsContainer = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export const ActionBar = () => {
|
export const ActionBar = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const cq = useContainerQuery({ md: 300 });
|
const cq = useContainerQuery({ md: 300 });
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { open } = useCommandPalette();
|
const { open } = useCommandPalette();
|
||||||
@@ -36,6 +38,7 @@ export const ActionBar = () => {
|
|||||||
<TextInput
|
<TextInput
|
||||||
readOnly
|
readOnly
|
||||||
icon={<RiSearchLine />}
|
icon={<RiSearchLine />}
|
||||||
|
placeholder={t('common.search', { postProcess: 'titleCase' })}
|
||||||
size="md"
|
size="md"
|
||||||
onClick={open}
|
onClick={open}
|
||||||
onKeyDown={(e) => {
|
onKeyDown={(e) => {
|
||||||
|
|||||||
@@ -423,7 +423,7 @@ export const SongListHeaderFilters = ({ gridRef, tableRef }: SongListHeaderFilte
|
|||||||
fill: isFilterApplied ? 'var(--primary-color) !important' : undefined,
|
fill: isFilterApplied ? 'var(--primary-color) !important' : undefined,
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
tooltip={{ label: 'Filters' }}
|
tooltip={{ label: t('common.filters', { postProcess: 'titleCase' }) }}
|
||||||
variant="subtle"
|
variant="subtle"
|
||||||
onClick={handleOpenFiltersModal}
|
onClick={handleOpenFiltersModal}
|
||||||
>
|
>
|
||||||
@@ -433,7 +433,7 @@ export const SongListHeaderFilters = ({ gridRef, tableRef }: SongListHeaderFilte
|
|||||||
<Button
|
<Button
|
||||||
compact
|
compact
|
||||||
size="md"
|
size="md"
|
||||||
tooltip={{ label: 'Refresh' }}
|
tooltip={{ label: t('glossary.refresh', { postProcess: 'titleCase' }) }}
|
||||||
variant="subtle"
|
variant="subtle"
|
||||||
onClick={handleRefresh}
|
onClick={handleRefresh}
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user