diff --git a/conf/configuration.go b/conf/configuration.go index aa1056f75..ad7bb2d0b 100644 --- a/conf/configuration.go +++ b/conf/configuration.go @@ -643,7 +643,8 @@ func setViperDefaults() { viper.SetDefault("subsonic.artistparticipations", false) viper.SetDefault("subsonic.defaultreportrealpath", false) viper.SetDefault("subsonic.enableaveragerating", true) - viper.SetDefault("subsonic.legacyclients", "DSub,SubMusic") + viper.SetDefault("subsonic.legacyclients", "DSub") + viper.SetDefault("subsonic.minimalclients", "SubMusic") viper.SetDefault("agents", "lastfm,spotify,deezer") viper.SetDefault("lastfm.enabled", true) viper.SetDefault("lastfm.language", consts.DefaultInfoLanguage) diff --git a/resources/i18n/ca.json b/resources/i18n/ca.json index a7244b5bd..264a76639 100644 --- a/resources/i18n/ca.json +++ b/resources/i18n/ca.json @@ -95,11 +95,11 @@ "lists": { "all": "Tot", "random": "Aleatori", - "recentlyAdded": "Afegit fa poc", - "recentlyPlayed": "Reproduït fa poc", - "mostPlayed": "Més reproduït", + "recentlyAdded": "Afegits recentment", + "recentlyPlayed": "Reproduïts recentment", + "mostPlayed": "Més reproduïts", "starred": "Preferits", - "topRated": "Més ben valorades" + "topRated": "Més ben valorats" } }, "artist": { @@ -119,7 +119,7 @@ "albumartist": "Artista de l'Àlbum |||| Artistes de l'Àlbum", "artist": "Artista |||| Artistes", "composer": "Compositor |||| Compositors", - "conductor": "Conductor |||| Conductors", + "conductor": "Director |||| Directors", "lyricist": "Lletrista |||| Lletristes", "arranger": "Arranjador |||| Arranjadors", "producer": "Productor |||| Productors", @@ -127,7 +127,7 @@ "engineer": "Enginyer |||| Enginyers", "mixer": "Mesclador |||| Mescladors", "remixer": "Remesclador |||| Remescladors", - "djmixer": "DJ Mesclador |||| DJ Mescladors", + "djmixer": "Mesclador DJ |||| Mescladors DJ", "performer": "Intèrpret |||| Intèrprets", "maincredit": "Artista de l'àlbum or Artista |||| Artistes de l'àlbum or Artistes" }, @@ -654,7 +654,7 @@ "links": { "homepage": "Inici", "source": "Codi font", - "featureRequests": "Sol·licitud de funcionalitats", + "featureRequests": "Sol·licita funcionalitats", "lastInsightsCollection": "Última recolecció d'informació", "insights": { "disabled": "Desactivada", diff --git a/resources/i18n/de.json b/resources/i18n/de.json index 972debb37..568c65c51 100644 --- a/resources/i18n/de.json +++ b/resources/i18n/de.json @@ -48,7 +48,7 @@ "playNext": "Als nächstes abspielen", "info": "Mehr Informationen", "showInPlaylist": "In Wiedergabeliste anzeigen", - "instantMix": "" + "instantMix": "Sofort-Mix" } }, "album": { @@ -588,7 +588,7 @@ "remove_all_missing_content": "Möchtest du wirklich alle Fehlenden Dateien aus der Datenbank entfernen? Alle Referenzen zu den Dateien wie Anzahl Wiedergaben und Bewertungen werden permanent gelöscht.", "noSimilarSongsFound": "Keine ähnlichen Titel gefunden", "noTopSongsFound": "Keine beliebten Titel gefunden", - "startingInstantMix": "" + "startingInstantMix": "Lade Sofort-Mix..." }, "menu": { "library": "Bibliothek", diff --git a/resources/i18n/es.json b/resources/i18n/es.json index 4e9e13e57..38c1379c9 100644 --- a/resources/i18n/es.json +++ b/resources/i18n/es.json @@ -48,7 +48,7 @@ "playNext": "Siguiente", "info": "Obtener información", "showInPlaylist": "Mostrar en la lista de reproducción", - "instantMix": "" + "instantMix": "Mezcla instantánea" } }, "album": { @@ -588,7 +588,7 @@ "remove_all_missing_content": "¿Realmente desea eliminar todos los archivos faltantes de la base de datos? Esto eliminará permanentemente cualquier referencia a ellos, incluidas sus reproducciones y valoraciones.", "noSimilarSongsFound": "No se encontraron canciones similares", "noTopSongsFound": "No se encontraron canciones destacadas", - "startingInstantMix": "" + "startingInstantMix": "Cargando la mezcla instantánea..." }, "menu": { "library": "Biblioteca", diff --git a/resources/i18n/fr.json b/resources/i18n/fr.json index d3d0d5d57..66bd454cc 100644 --- a/resources/i18n/fr.json +++ b/resources/i18n/fr.json @@ -48,7 +48,7 @@ "playNext": "Jouer ensuite", "info": "Plus d'informations", "showInPlaylist": "Montrer dans la playlist", - "instantMix": "" + "instantMix": "Mix instantanné" } }, "album": { @@ -588,7 +588,7 @@ "remove_all_missing_content": "Êtes-vous sûr(e) de vouloir supprimer tous les fichiers manquants de la base de données ? Cette action est permanente et supprimera leurs nombres d'écoutes, leur notations et tout ce qui y fait référence.", "noSimilarSongsFound": "Aucun titre similaire n'a été trouvé", "noTopSongsFound": "Aucun meilleur titre n'a été trouvé", - "startingInstantMix": "" + "startingInstantMix": "Chargement du mix instantanné..." }, "menu": { "library": "Bibliothèque", diff --git a/resources/i18n/id.json b/resources/i18n/id.json index 38ee2fff9..cdba66663 100644 --- a/resources/i18n/id.json +++ b/resources/i18n/id.json @@ -36,7 +36,8 @@ "bitDepth": "Bit depth", "sampleRate": "Sample rate", "missing": "Hilang", - "libraryName": "Pustaka" + "libraryName": "Pustaka", + "composer": "Komposer" }, "actions": { "addToQueue": "Tambah ke antrean", @@ -46,7 +47,8 @@ "download": "Unduh", "playNext": "Putar Berikutnya", "info": "Lihat Info", - "showInPlaylist": "Tampilkan di Playlist" + "showInPlaylist": "Tampilkan di Playlist", + "instantMix": "Mix Instan" } }, "album": { @@ -301,14 +303,19 @@ "actions": { "scan": "Pindai Pustaka", "manageUsers": "Kelola Akses Pengguna", - "viewDetails": "Lihat Detail" + "viewDetails": "Lihat Detail", + "quickScan": "Pindai Cepat", + "fullScan": "Pindai Keseluruhan" }, "notifications": { "created": "Pustaka berhasil dibuat", "updated": "Pustaka berhasil dibuat", "deleted": "Berhasil menghapus pustaka", "scanStarted": "Memindai pustaka dimulai", - "scanCompleted": "Memindai pustaka selesai" + "scanCompleted": "Memindai pustaka selesai", + "quickScanStarted": "Pemindaian cepat dimulai", + "fullScanStarted": "Pemindaian keseluruhan dimulai", + "scanError": "Kesalahan saat memulai pemindaian. Periksa log" }, "validation": { "nameRequired": "Nama pustaka diperlukan", @@ -323,6 +330,80 @@ "scanInProgress": "Pemindaian sedang berlangsung...", "noLibrariesAssigned": "Tidak ada pustaka yang ditugaskan ke pengguna ini" } + }, + "plugin": { + "name": "Plugin |||| Plugin", + "fields": { + "id": "ID", + "name": "Nama", + "description": "Deskripsi", + "version": "Versi", + "author": "Pembuat", + "website": "Situs Web", + "permissions": "Perizinan", + "enabled": "Diaktifkan", + "status": "Status", + "path": "Jalur", + "lastError": "Kesalahan", + "hasError": "Kesalahan", + "updatedAt": "Diperbarui", + "createdAt": "Terinstal", + "configKey": "Key", + "configValue": "Value", + "allUsers": "Izinkan semua pengguna", + "selectedUsers": "Pengguna yang dipilih", + "allLibraries": "Izinkan semua pustaka", + "selectedLibraries": "Pustaka dipilih" + }, + "sections": { + "status": "Status", + "info": "Informasi plugin", + "configuration": "Konfigurasi", + "manifest": "Manifes", + "usersPermission": "Pengguna yang Diizinkan", + "libraryPermission": "Pustaka yang Diizinkan" + }, + "status": { + "enabled": "Diaktifkan", + "disabled": "Dinonaktifkan" + }, + "actions": { + "enable": "Aktifkan", + "disable": "Nonaktifkan", + "disabledDueToError": "Perbaiki kesalahan sebelum diaktifkan", + "disabledUsersRequired": "Pilih pengguna sebelum diaktifkan", + "disabledLibrariesRequired": "Pilih pustaka sebelum diaktifkan", + "addConfig": "Tambahkan Konfigurasi", + "rescan": "Pindai ulang" + }, + "notifications": { + "enabled": "Plugin diaktifkan", + "disabled": "Plugin dinonaktifkan", + "updated": "Plugin diperbarui", + "error": "Kesalahan saat memperbarui plugin" + }, + "validation": { + "invalidJson": "Konfigurasi harus berupa JSON yang valid" + }, + "messages": { + "configHelp": "Konfigurasikan plugin menggunakan key-value pairs. Biarkan kosong jika plugin tidak membutuhkan konfigurasi.", + "clickPermissions": "Klik perizinan untuk detail", + "noConfig": "Konfigurasi tidak diatur", + "allUsersHelp": "Ketika diaktifkan, plugin akan mengakses untuk semua pengguna, termasuk yang akan dibuat di masa depan.", + "noUsers": "Tidak ada pengguna yang dipilih", + "permissionReason": "Alasan", + "usersRequired": "Plugin ini membutuhkan akses ke informasi pengguna. Pilih pengguna yang bisa mengakses plugin, atau aktifkan 'Izinkan semua pengguna'.", + "allLibrariesHelp": "Ketika diaktifkan, plugin akan memiliki akses ke semua pustaka, termasuk yang dibuat di masa depan.", + "noLibraries": "Tidak ada pustaka yang dipilih", + "librariesRequired": "Plugin ini membutuhkan akses ke informasi pustaka. Pilih beberapa pustaka yang bisa diakses, atau aktifkan 'Izinkan semua pustaka'.", + "requiredHosts": "Hosts diperlukan", + "configValidationError": "Validasi konfigurasi gagal:", + "schemaRenderError": "Tidak dapat menampilkan form konfigurasi. Skema plugin mungkin tidak valid." + }, + "placeholders": { + "configKey": "key", + "configValue": "value" + } } }, "ra": { @@ -506,7 +587,8 @@ "remove_all_missing_title": "Hapus semua file yang hilang", "remove_all_missing_content": "Apa kamu yakin ingin menghapus semua file dari database? Ini akan menghapus permanen dan apapun referensi ke mereka, termasuk hitungan pemutaran dan rating mereka.", "noSimilarSongsFound": "Tidak ada lagu yang serupa ditemukan", - "noTopSongsFound": "Tidak ada lagu teratas ditemukan" + "noTopSongsFound": "Tidak ada lagu teratas ditemukan", + "startingInstantMix": "Memuat Mix Instan..." }, "menu": { "library": "Pustaka", @@ -604,7 +686,8 @@ "serverDown": "LURING", "scanType": "Tipe", "status": "Kesalahan Memindai", - "elapsedTime": "Waktu Berakhir" + "elapsedTime": "Waktu Berakhir", + "selectiveScan": "Selektif" }, "help": { "title": "Tombol Pintasan Navidrome", diff --git a/resources/i18n/pl.json b/resources/i18n/pl.json index f5aac031c..6229798e9 100644 --- a/resources/i18n/pl.json +++ b/resources/i18n/pl.json @@ -48,7 +48,7 @@ "playNext": "Odtwarzaj Następny", "info": "Zdobądź Informacje", "showInPlaylist": "Pokaż w Liście Odtwarzania", - "instantMix": "" + "instantMix": "Natychmiastowy Miks" } }, "album": { @@ -588,7 +588,7 @@ "remove_all_missing_content": "Czy chcesz usunąć wszystkie brakujące pliki z bazy danych? Spowoduje to trwałe usunięcie wszelkich odniesień do tych plików, takich jak liczba odtworzeń, czy oceny.", "noSimilarSongsFound": "Brak podobnych utworów", "noTopSongsFound": "Brak najlepszych utworów", - "startingInstantMix": "" + "startingInstantMix": "Ładowanie Natychmiastowego Miksu..." }, "menu": { "library": "Biblioteka", diff --git a/ui/src/album/AlbumDetails.jsx b/ui/src/album/AlbumDetails.jsx index 3263fd55e..bd6a41523 100644 --- a/ui/src/album/AlbumDetails.jsx +++ b/ui/src/album/AlbumDetails.jsx @@ -351,7 +351,9 @@ const AlbumDetails = (props) => { variant={'body1'} onClick={() => setExpanded(!expanded)} > - {notes} + + {notes} + )} @@ -371,7 +373,9 @@ const AlbumDetails = (props) => { variant={'body1'} onClick={() => setExpanded(!expanded)} > - {notes} + + {notes} + diff --git a/ui/src/artist/ArtistShow.jsx b/ui/src/artist/ArtistShow.jsx index 668e07212..ba8586d06 100644 --- a/ui/src/artist/ArtistShow.jsx +++ b/ui/src/artist/ArtistShow.jsx @@ -71,7 +71,9 @@ const ArtistDetails = (props) => { }, [record.id]) const Component = isDesktop ? DesktopArtistDetails : MobileArtistDetails - return + return ( + + ) } const ArtistShowLayout = (props) => { diff --git a/ui/src/artist/DesktopArtistDetails.jsx b/ui/src/artist/DesktopArtistDetails.jsx index f999b02ff..1e074ce4e 100644 --- a/ui/src/artist/DesktopArtistDetails.jsx +++ b/ui/src/artist/DesktopArtistDetails.jsx @@ -173,7 +173,9 @@ const DesktopArtistDetails = ({ artistInfo, record, biography }) => { variant={'body1'} onClick={() => setExpanded(!expanded)} > - {biography} + + {biography} + diff --git a/ui/src/artist/MobileArtistDetails.jsx b/ui/src/artist/MobileArtistDetails.jsx index de9b3867a..e8c044d66 100644 --- a/ui/src/artist/MobileArtistDetails.jsx +++ b/ui/src/artist/MobileArtistDetails.jsx @@ -169,7 +169,9 @@ const MobileArtistDetails = ({ artistInfo, biography, record }) => {
setExpanded(!expanded)}> - {biography} + + {biography} +
diff --git a/ui/src/common/MultiLineTextField.jsx b/ui/src/common/MultiLineTextField.jsx index d95def2f8..1218d4bd6 100644 --- a/ui/src/common/MultiLineTextField.jsx +++ b/ui/src/common/MultiLineTextField.jsx @@ -28,9 +28,7 @@ export const MultiLineTextField = memo( component="span" {...sanitizeFieldRestProps(rest)} > - {lines.length === 0 && emptyText - ? emptyText - : lines} + {lines.length === 0 && emptyText ? emptyText : lines} ) }, diff --git a/ui/src/common/SafeHTML.jsx b/ui/src/common/SafeHTML.jsx index 7d73e17fe..643b538b8 100644 --- a/ui/src/common/SafeHTML.jsx +++ b/ui/src/common/SafeHTML.jsx @@ -1,9 +1,7 @@ import DOMPurify from 'dompurify' import { Fragment, useMemo } from 'react' -export const SafeHTML = ({ - children, -}) => { +export const SafeHTML = ({ children }) => { const purified = useMemo(() => { const purify = DOMPurify()