Compare commits

..

No commits in common. "master" and "v0.58.0" have entirely different histories.

9 changed files with 16 additions and 791 deletions

View File

@ -32,14 +32,6 @@ server: check_go_env buildjs ##@Development Start the backend in development mod
@ND_ENABLEINSIGHTSCOLLECTOR="false" go tool reflex -d none -c reflex.conf
.PHONY: server
stop: ##@Development Stop development servers (UI and backend)
@echo "Stopping development servers..."
@-pkill -f "vite"
@-pkill -f "go tool reflex.*reflex.conf"
@-pkill -f "go run.*netgo"
@echo "Development servers stopped."
.PHONY: stop
watch: ##@Development Start Go tests in watch mode (re-run when code changes)
go tool ginkgo watch -tags=netgo -notify ./...
.PHONY: watch

View File

@ -1,628 +0,0 @@
{
"languageName": "Bosanski",
"resources": {
"song": {
"name": "Pjesma |||| Pjesme",
"fields": {
"albumArtist": "Izvođač albuma",
"duration": "Trajanje",
"trackNumber": "Pjesma #",
"playCount": "Reprodukcija",
"title": "Naslov",
"artist": "Izvođač",
"album": "Album",
"path": "Putanja datoteke",
"genre": "Žanr",
"compilation": "Kompilacija",
"year": "Godina",
"size": "Veličina datoteke",
"updatedAt": "Dodano",
"bitRate": "Brzina prijenosa",
"discSubtitle": "Podnaslov CD-a",
"starred": "Favorit",
"comment": "Komentar",
"rating": "Ocjena",
"quality": "Kvaliteta",
"bpm": "BPM",
"playDate": "Posljednja reprodukcija",
"channels": "Kanali",
"createdAt": "Dodano",
"grouping": "Grupisanje",
"mood": "Raspoloženje",
"participants": "Dodatni učesnici",
"tags": "Dodatne oznake",
"mappedTags": "Mapirane oznake",
"rawTags": "Sirovi podaci oznaka",
"bitDepth": "Dubina bita",
"sampleRate": "Uzorkovanje",
"missing": "Nedostaje",
"libraryName": "Biblioteka"
},
"actions": {
"addToQueue": "Reprodukcija kasnije",
"playNow": "Reprodukcija sada",
"addToPlaylist": "Dodaj u playlistu",
"shuffleAll": "Nasumična reprodukcija",
"download": "Preuzmi",
"playNext": "Reprodukcija sljedeće",
"info": "Više informacija",
"showInPlaylist": "Prikaži u playlisti"
}
},
"album": {
"name": "Album |||| Albumi",
"fields": {
"albumArtist": "Izvođač albuma",
"artist": "Izvođač",
"duration": "Trajanje",
"songCount": "Broj pjesama",
"playCount": "Reprodukcija",
"name": "Naziv",
"genre": "Žanr",
"compilation": "Kompilacija",
"year": "Godina",
"updatedAt": "Ažurirano",
"comment": "Komentar",
"rating": "Ocjena",
"createdAt": "Dodano",
"size": "Veličina",
"originalDate": "Originalni datum",
"releaseDate": "Datum izdanja",
"releases": "Izdanje |||| Izdanja",
"released": "Objavljeno",
"recordLabel": "Izdavač",
"catalogNum": "Kataloški broj",
"releaseType": "Tip",
"grouping": "Grupisanje",
"media": "Medij",
"mood": "Raspoloženje",
"date": "Datum snimanja",
"missing": "Nedostaje",
"libraryName": "Biblioteka"
},
"actions": {
"playAll": "Reprodukcija",
"playNext": "Reprodukcija sljedeće",
"addToQueue": "Dodaj u red",
"shuffle": "Nasumična reprodukcija",
"addToPlaylist": "Dodaj u playlistu",
"download": "Preuzmi",
"info": "Više informacija",
"share": "Podijeli"
},
"lists": {
"all": "Sve",
"random": "Nasumično",
"recentlyAdded": "Nedavno dodano",
"recentlyPlayed": "Nedavno reproducirano",
"mostPlayed": "Najviše reproducirano",
"starred": "Favoriti",
"topRated": "Najbolje ocijenjeno"
}
},
"artist": {
"name": "Izvođač |||| Izvođači",
"fields": {
"name": "Naziv",
"albumCount": "Broj albuma",
"songCount": "Broj pjesama",
"playCount": "Reprodukcija",
"rating": "Ocjena",
"genre": "Žanr",
"size": "Veličina",
"role": "Uloga",
"missing": "Nedostaje"
},
"roles": {
"albumartist": "Izvođač albuma |||| Izvođači albuma",
"artist": "Izvođač |||| Izvođači",
"composer": "Kompozitor |||| Kompozitori",
"conductor": "Dirigent |||| Dirigenti",
"lyricist": "Tekstopisac |||| Tekstopisci",
"arranger": "Aranžer |||| Aranžeri",
"producer": "Producent |||| Producenti",
"director": "Direktor |||| Direktori",
"engineer": "Inženjer |||| Inženjeri",
"mixer": "Mikser |||| Mikseri",
"remixer": "Remikser |||| Remikseri",
"djmixer": "DJ Mikser |||| DJ Mikseri",
"performer": "Izvođač |||| Izvođači",
"maincredit": "Izvođač albuma ili izvođač |||| Izvođači albuma ili izvođači"
},
"actions": {
"shuffle": "Nasumična reprodukcija",
"radio": "Radio",
"topSongs": "Najpopularnije pjesme"
}
},
"user": {
"name": "Korisnik |||| Korisnici",
"fields": {
"userName": "Korisničko ime",
"isAdmin": "Je admin",
"lastLoginAt": "Posljednja prijava",
"updatedAt": "Ažurirano",
"name": "Ime",
"password": "Lozinka",
"createdAt": "Kreirano",
"changePassword": "Promijeni lozinku?",
"currentPassword": "Trenutna lozinka",
"newPassword": "Nova lozinka",
"token": "Token",
"lastAccessAt": "Posljednji pristup",
"libraries": "Biblioteke"
},
"helperTexts": {
"name": "Promjena će biti aktivna nakon sljedeće prijave",
"libraries": "Odaberi specifične biblioteke za ovog korisnika ili ostavi prazno za standardne biblioteke"
},
"notifications": {
"created": "Korisnik kreiran",
"updated": "Korisnik ažuriran",
"deleted": "Korisnik obrisan"
},
"message": {
"listenBrainzToken": "Unesite svoj ListenBrainz korisnički token",
"clickHereForToken": "Kliknite ovdje za dobijanje tokena",
"selectAllLibraries": "Odaberi sve biblioteke",
"adminAutoLibraries": "Administratori automatski imaju pristup svim bibliotekama"
},
"validation": {
"librariesRequired": "Ne-administratori moraju imati barem jednu odabranu biblioteku"
}
},
"player": {
"name": "Player |||| Playeri",
"fields": {
"name": "Naziv",
"transcodingId": "ID transkodiranja",
"maxBitRate": "Maks. brzina prijenosa",
"client": "Klijent",
"userName": "Korisničko ime",
"lastSeen": "Posljednji put viđen",
"reportRealPath": "Prikaži stvarnu putanju",
"scrobbleEnabled": "Slanje podataka o reprodukciji (scrobbling)"
}
},
"transcoding": {
"name": "Transkodiranje |||| Transkodiranja",
"fields": {
"name": "Naziv",
"targetFormat": "Ciljani format",
"defaultBitRate": "Zadana brzina prijenosa",
"command": "Komanda"
}
},
"playlist": {
"name": "Playlista |||| Playliste",
"fields": {
"name": "Naziv",
"duration": "Trajanje",
"ownerName": "Vlasnik",
"public": "Javna",
"updatedAt": "Ažurirano",
"createdAt": "Kreirano",
"songCount": "Broj pjesama",
"comment": "Komentar",
"sync": "Auto-uvoz",
"path": "Uvezi iz"
},
"actions": {
"selectPlaylist": "Odaberi playlistu:",
"addNewPlaylist": "Kreiraj \"%{name}\"",
"export": "Izvezi",
"makePublic": "Učini javnom",
"makePrivate": "Učini privatnom",
"saveQueue": "Sačuvaj red čekanja u playlistu",
"searchOrCreate": "Pretraži playlistu ili kreiraj novu...",
"pressEnterToCreate": "Pritisni Enter za kreiranje nove playliste",
"removeFromSelection": "Ukloni iz odabira"
},
"message": {
"duplicate_song": "Dodaj duplikate",
"song_exist": "Neke pjesme su već u playlisti. Želiš li ih ipak dodati ili preskočiti?",
"noPlaylistsFound": "Nije pronađena nijedna playlista",
"noPlaylists": "Nema playlisti"
}
},
"radio": {
"name": "Radio |||| Radiji",
"fields": {
"name": "Naziv",
"streamUrl": "Stream URL",
"homePageUrl": "URL početne stranice",
"updatedAt": "Ažurirano",
"createdAt": "Dodano"
},
"actions": {
"playNow": "Reprodukcija sada"
}
},
"share": {
"name": "Dijeljenje |||| Dijeljenja",
"fields": {
"username": "Podijeljeno od strane",
"url": "URL",
"description": "Opis",
"contents": "Sadržaj",
"expiresAt": "Vrijedi do",
"lastVisitedAt": "Posljednja posjeta",
"visitCount": "Posjete",
"format": "Format",
"maxBitRate": "Maks. brzina prijenosa",
"updatedAt": "Ažurirano",
"createdAt": "Kreirano",
"downloadable": "Dozvoli preuzimanje?"
}
},
"missing": {
"name": "Nedostajuća datoteka |||| Nedostajuće datoteke",
"fields": {
"path": "Putanja",
"size": "Veličina",
"updatedAt": "Nedostaje od",
"libraryName": "Biblioteka"
},
"actions": {
"remove": "Ukloni",
"remove_all": "ukloni sve"
},
"notifications": {
"removed": "Nedostajuća(e) datoteka(e) uklonjena(e)"
},
"empty": "nema nedostajućih datoteka"
},
"library": {
"name": "Biblioteka |||| Biblioteke",
"fields": {
"name": "Naziv",
"path": "Putanja",
"remotePath": "Udaljena putanja",
"lastScanAt": "Posljednje skeniranje",
"songCount": "Pjesme",
"albumCount": "Albumi",
"artistCount": "Izvođači",
"totalSongs": "Pjesme",
"totalAlbums": "Albumi",
"totalArtists": "Izvođači",
"totalFolders": "Folderi",
"totalFiles": "Datoteke",
"totalMissingFiles": "Nedostajuće datoteke",
"totalSize": "Veličina",
"totalDuration": "Trajanje",
"defaultNewUsers": "Standardno za nove korisnike",
"createdAt": "Kreirano",
"updatedAt": "Ažurirano"
},
"sections": {
"basic": "Osnovne informacije",
"statistics": "Statistika"
},
"actions": {
"scan": "Skeniraj biblioteku",
"manageUsers": "Upravljaj pristupima",
"viewDetails": "Pogledaj detalje"
},
"notifications": {
"created": "Biblioteka uspješno kreirana",
"updated": "Biblioteka uspješno ažurirana",
"deleted": "Biblioteka uspješno obrisana",
"scanStarted": "Skeniranje biblioteke započeto",
"scanCompleted": "Skeniranje biblioteke završeno"
},
"validation": {
"nameRequired": "Naziv biblioteke je obavezan",
"pathRequired": "Putanja biblioteke je obavezna",
"pathNotDirectory": "Putanja biblioteke mora biti folder",
"pathNotFound": "Putanja biblioteke nije pronađena",
"pathNotAccessible": "Putanja biblioteke nije dostupna",
"pathInvalid": "Putanja biblioteke nije validna"
},
"messages": {
"deleteConfirm": "Da li zaista želiš obrisati ovu biblioteku? Pristup i podaci će biti uklonjeni.",
"scanInProgress": "Skeniranje biblioteke u toku...",
"noLibrariesAssigned": "Nema dodijeljenih biblioteka"
}
}
},
"ra": {
"auth": {
"welcome1": "Hvala što ste instalirali Navidrome!",
"welcome2": "Prvo kreirajte admin korisnika",
"confirmPassword": "Potvrdi lozinku",
"buttonCreateAdmin": "Kreiraj admina",
"auth_check_error": "Prijavite se da biste nastavili",
"user_menu": "Profil",
"username": "Korisničko ime",
"password": "Lozinka",
"sign_in": "Prijava",
"sign_in_error": "Greška pri prijavi",
"logout": "Odjava",
"insightsCollectionNote": "Navidrome prikuplja anonimne statistike \nda podrži razvoj projekta. \nKliknite [ovdje] za više informacija ili da isključite \"Insights\""
},
"validation": {
"invalidChars": "Koristite samo slova i brojeve",
"passwordDoesNotMatch": "Lozinke se ne podudaraju",
"required": "Obavezno",
"minLength": "Mora imati najmanje %{min} znakova",
"maxLength": "Mora imati najviše %{max} znakova",
"minValue": "Mora biti najmanje %{min}",
"maxValue": "Mora biti %{max} ili manje",
"number": "Mora biti broj",
"email": "Mora biti validna e-mail adresa",
"oneOf": "Mora biti jedan od: %{options}",
"regex": "Mora odgovarati regularnom izrazu: %{pattern}",
"unique": "Mora biti jedinstveno",
"url": "Mora biti validan URL"
},
"action": {
"add_filter": "Dodaj filter",
"add": "Dodaj",
"back": "Nazad",
"bulk_actions": "1 odabrana stavka |||| %{smart_count} odabrane stavke",
"cancel": "Otkaži",
"clear_input_value": "Obriši unos",
"clone": "Kloniraj",
"confirm": "Potvrdi",
"create": "Kreiraj",
"delete": "Obriši",
"edit": "Uredi",
"export": "Izvezi",
"list": "Lista",
"refresh": "Osvježi",
"remove_filter": "Ukloni filter",
"remove": "Ukloni",
"save": "Sačuvaj",
"search": "Pretraži",
"show": "Prikaži",
"sort": "Sortiraj",
"undo": "Poništi",
"expand": "Proširi",
"close": "Zatvori",
"open_menu": "Otvori meni",
"close_menu": "Zatvori meni",
"unselect": "Poništi odabir",
"skip": "Preskoči",
"bulk_actions_mobile": "1 |||| %{smart_count}",
"share": "Podijeli",
"download": "Preuzmi"
},
"boolean": {
"true": "Da",
"false": "Ne"
},
"page": {
"create": "Kreiraj %{name}",
"dashboard": "Kontrolna tabla",
"edit": "%{name} #%{id}",
"error": "Nešto je pošlo po zlu",
"list": "%{name}",
"loading": "Učitavanje",
"not_found": "Nije pronađeno",
"show": "%{name} #%{id}",
"empty": "Još nema %{name}.",
"invite": "Želiš li dodati jednu?"
},
"input": {
"file": {
"upload_several": "Povuci datoteke ovdje za prijenos ili klikni za odabir.",
"upload_single": "Povuci datoteku ovdje za prijenos ili klikni za odabir."
},
"image": {
"upload_several": "Povuci slike ovdje za prijenos ili klikni za odabir.",
"upload_single": "Povuci sliku ovdje za prijenos ili klikni za odabir."
},
"references": {
"all_missing": "Povezane reference nisu pronađene.",
"many_missing": "Neke povezane reference više nisu dostupne.",
"single_missing": "Povezana referenca više nije dostupna."
},
"password": {
"toggle_visible": "Sakrij lozinku",
"toggle_hidden": "Prikaži lozinku"
}
},
"message": {
"about": "O aplikaciji",
"are_you_sure": "Jesi li siguran?",
"bulk_delete_content": "Da li zaista želiš obrisati \"%{name}\"? |||| Da li zaista želiš obrisati %{smart_count} stavki?",
"bulk_delete_title": "Obriši %{name} |||| Obriši %{smart_count} %{name} stavki",
"delete_content": "Da li zaista želiš obrisati ovaj sadržaj?",
"delete_title": "Obriši %{name} #%{id}",
"details": "Detalji",
"error": "Došlo je do greške i zahtjev nije mogao biti završen.",
"invalid_form": "Formular nije validan. Provjeri unose.",
"loading": "Stranica se učitava",
"no": "Ne",
"not_found": "Stranica nije pronađena.",
"yes": "Da",
"unsaved_changes": "Neke promjene nisu sačuvane. Želiš li ih ignorisati?"
},
"navigation": {
"no_results": "Nema rezultata",
"no_more_results": "Stranica %{page} nema sadržaja.",
"page_out_of_boundaries": "Stranica %{page} je izvan opsega",
"page_out_from_end": "Posljednja stranica",
"page_out_from_begin": "Prva stranica",
"page_range_info": "%{offsetBegin}-%{offsetEnd} od %{total}",
"page_rows_per_page": "Redova po stranici:",
"next": "Sljedeća",
"prev": "Prethodna",
"skip_nav": "Preskoči na sadržaj"
},
"notification": {
"updated": "Stavka ažurirana |||| %{smart_count} stavki ažurirano",
"created": "Stavka kreirana",
"deleted": "Stavka obrisana |||| %{smart_count} stavki obrisano",
"bad_item": "Neispravna stavka",
"item_doesnt_exist": "Stavka ne postoji",
"http_error": "Greška u komunikaciji sa serverom",
"data_provider_error": "Greška u dataProvider-u. Provjeri konzolu za detalje.",
"i18n_error": "Prijevod za odabrani jezik nije dostupan",
"canceled": "Akcija otkazana",
"logged_out": "Sesija je istekla. Ponovo se prijavi.",
"new_version": "Nova verzija dostupna! Osveži stranicu."
},
"toggleFieldsMenu": {
"columnsToDisplay": "Odaberi kolone",
"layout": "Izgled",
"grid": "Mreža",
"table": "Tabela"
}
},
"message": {
"note": "NAPOMENA",
"transcodingDisabled": "Izmjena postavki transkodiranja preko web sučelja je onemogućena iz sigurnosnih razloga. Ako želiš promijeniti opcije transkodiranja (urediti ili dodati), ponovo pokreni server sa konfiguracijskom opcijom %{config}.",
"transcodingEnabled": "Navidrome trenutno radi sa %{config}, što omogućava izvršavanje sistemskih komandi kroz postavke transkodiranja preko web sučelja. Preporučujemo da ovo onemogućiš iz sigurnosnih razloga i koristiš samo prilikom konfiguracije transkodiranja.",
"songsAddedToPlaylist": "1 pjesma dodana u playlistu |||| %{smart_count} pjesme dodane u playlistu",
"noPlaylistsAvailable": "Nema dostupnih playlisti",
"delete_user_title": "Obriši korisnika '%{name}'",
"delete_user_content": "Da li zaista želiš obrisati ovog korisnika i sve njegove podatke (uključujući playliste i postavke)?",
"notifications_blocked": "Blokirali ste obavijesti za ovu stranicu u postavkama preglednika",
"notifications_not_available": "Ovaj preglednik ne podržava desktop obavijesti",
"lastfmLinkSuccess": "Last.fm veza uspostavljena i scrobbling omogućen",
"lastfmLinkFailure": "Last.fm veza nije uspjela",
"lastfmUnlinkSuccess": "Last.fm veza uklonjena i scrobbling onemogućen",
"lastfmUnlinkFailure": "Last.fm veza nije uklonjena",
"openIn": {
"lastfm": "Prikaži na Last.fm",
"musicbrainz": "Prikaži na MusicBrainz"
},
"lastfmLink": "Pročitaj više",
"listenBrainzLinkSuccess": "ListenBrainz veza uspostavljena i scrobbling omogućen kao korisnik: %{user}",
"listenBrainzLinkFailure": "ListenBrainz veza nije uspjela: %{error}",
"listenBrainzUnlinkSuccess": "ListenBrainz veza uklonjena i scrobbling onemogućen",
"listenBrainzUnlinkFailure": "ListenBrainz veza nije uklonjena",
"downloadOriginalFormat": "Preuzmi u originalnom formatu",
"shareOriginalFormat": "Podijeli u originalnom formatu",
"shareDialogTitle": "Podijeli %{resource} '%{name}'",
"shareBatchDialogTitle": "Podijeli 1 %{resource} |||| Podijeli %{smart_count} %{resource}",
"shareSuccess": "URL kopiran u međuspremnik: %{url}",
"shareFailure": "Greška pri kopiranju URL-a %{url} u međuspremnik",
"downloadDialogTitle": "Preuzmi %{resource} '%{name}' (%{size})",
"shareCopyToClipboard": "Kopiraj u međuspremnik: Ctrl+C, Enter",
"remove_missing_title": "Ukloni nedostajuće datoteke",
"remove_missing_content": "Da li zaista želiš ukloniti odabrane nedostajuće datoteke iz baze podataka? Sve reference na datoteke (broj reprodukcija, ocjene) bit će trajno obrisane.",
"remove_all_missing_title": "Ukloni sve nedostajuće datoteke",
"remove_all_missing_content": "Da li zaista želiš ukloniti sve nedostajuće datoteke iz baze podataka? Sve reference na datoteke (broj reprodukcija, ocjene) bit će trajno obrisane.",
"noSimilarSongsFound": "Nema sličnih pjesama",
"noTopSongsFound": "Nema popularnih pjesama"
},
"menu": {
"library": "Biblioteka",
"settings": "Postavke",
"version": "Verzija",
"theme": "Tema",
"personal": {
"name": "Lično",
"options": {
"theme": "Tema",
"language": "Jezik",
"defaultView": "Zadani pregled",
"desktop_notifications": "Desktop obavijesti",
"lastfmScrobbling": "Last.fm scrobbling",
"listenBrainzScrobbling": "ListenBrainz scrobbling",
"replaygain": "ReplayGain mod",
"preAmp": "ReplayGain pojačanje (dB)",
"gain": {
"none": "Isključeno",
"album": "Koristi album gain",
"track": "Koristi pjesmu gain"
},
"lastfmNotConfigured": "Last.fm API ključ nije konfiguriran"
}
},
"albumList": "Albumi",
"about": "O aplikaciji",
"playlists": "Playliste",
"sharedPlaylists": "Dijeljene playliste",
"librarySelector": {
"allLibraries": "Sve biblioteke (%{count})",
"multipleLibraries": "%{selected} od %{total} biblioteka",
"selectLibraries": "Odaberi biblioteke",
"none": "Nijedna"
}
},
"player": {
"playListsText": "Reprodukcija reda čekanja",
"openText": "Otvori",
"closeText": "Zatvori",
"notContentText": "Nema muzike",
"clickToPlayText": "Klikni za reprodukciju",
"clickToPauseText": "Klikni za pauzu",
"nextTrackText": "Sljedeća pjesma",
"previousTrackText": "Prethodna pjesma",
"reloadText": "Ponovo učitaj",
"volumeText": "Glasnoća",
"toggleLyricText": "Prikaži/sakrij tekst",
"toggleMiniModeText": "Minimiziraj",
"destroyText": "Uništi",
"downloadText": "Preuzmi",
"removeAudioListsText": "Ukloni audio liste",
"clickToDeleteText": "Klikni za brisanje %{name}",
"emptyLyricText": "Nema teksta",
"playModeText": {
"order": "Redom",
"orderLoop": "Ponavljaj",
"singleLoop": "Ponavljaj jednu",
"shufflePlay": "Nasumična reprodukcija"
}
},
"about": {
"links": {
"homepage": "Početna stranica",
"source": "Izvorni kod",
"featureRequests": "Zahtjevi za funkcijama",
"lastInsightsCollection": "Posljednje prikupljanje \"Insights\"",
"insights": {
"disabled": "Isključeno",
"waiting": "Čekanje"
}
},
"tabs": {
"about": "O aplikaciji",
"config": "Konfiguracija"
},
"config": {
"configName": "Postavka",
"environmentVariable": "Varijabla okruženja",
"currentValue": "Vrijednost",
"configurationFile": "Konfiguracijska datoteka",
"exportToml": "Izvezi konfiguraciju (TOML)",
"exportSuccess": "Konfiguracija kopirana u međuspremnik u TOML formatu",
"exportFailed": "Greška pri kopiranju konfiguracije",
"devFlagsHeader": "Dev postavke (mogu se promijeniti)",
"devFlagsComment": "Eksperimentalne postavke koje mogu biti uklonjene ili promijenjene u budućnosti"
}
},
"activity": {
"title": "Aktivnost",
"totalScanned": "Ukupno skeniranih foldera",
"quickScan": "Brzo skeniranje",
"fullScan": "Potpuno skeniranje",
"serverUptime": "Vrijeme rada servera",
"serverDown": "ISKLJUČEN",
"scanType": "Tip",
"status": "Greška pri skeniranju",
"elapsedTime": "Proteklo vrijeme"
},
"help": {
"title": "Navidrome prečice",
"hotkeys": {
"show_help": "Prikaži ovu pomoć",
"toggle_menu": "Uključi/isključi bočnu traku",
"toggle_play": "Reprodukcija / Pauza",
"prev_song": "Prethodna pjesma",
"next_song": "Sljedeća pjesma",
"vol_up": "Glasnije",
"vol_down": "Tiše",
"toggle_love": "Dodaj u favorite",
"current_song": "Prikaži trenutnu pjesmu"
}
},
"nowPlaying": {
"title": "Trenutna reprodukcija",
"empty": "Nema reprodukcije",
"minutesAgo": "Prije %{smart_count} minute |||| Prije %{smart_count} minuta"
}
}

View File

@ -273,7 +273,7 @@
"empty": "keine fehlenden Dateien"
},
"library": {
"name": "Bibliothek |||| Bibliotheken",
"name": "Bibliothek ||| Bibliotheken",
"fields": {
"name": "Name",
"path": "Pfad",

View File

@ -63,7 +63,7 @@
"size": "Tamaño",
"originalDate": "Orixinal",
"releaseDate": "Publicado",
"releases": "Publicación |||| Publicacións",
"releases": "Publicación ||| Publicacións",
"released": "Publicado",
"recordLabel": "Editorial",
"catalogNum": "Número de catálogo",

View File

@ -232,7 +232,7 @@
"add_filter": "Aggiungi un filtro",
"add": "Aggiungi",
"back": "Indietro",
"bulk_actions": "Un elemento selezionato |||| %{smart_count} elementi selezionati",
"bulk_actions": "Un elemento selezionato ||| %{smart_count} elementi selezionati",
"cancel": "Annulla",
"clear_input_value": "Cancella",
"clone": "Duplica",

View File

@ -13,14 +13,12 @@
"album": "专辑",
"path": "文件路径",
"genre": "流派",
"libraryName": "媒体库",
"compilation": "合辑",
"year": "发行年份",
"size": "文件大小",
"updatedAt": "更新于",
"bitRate": "比特率",
"bitDepth": "比特深度",
"sampleRate": "采样率",
"channels": "声道",
"discSubtitle": "字幕",
"starred": "收藏",
@ -35,14 +33,12 @@
"participants": "其他参与人员",
"tags": "附加标签",
"mappedTags": "映射标签",
"rawTags": "原始标签",
"missing": "缺失"
"rawTags": "原始标签"
},
"actions": {
"addToQueue": "加入播放列表",
"playNow": "立即播放",
"addToPlaylist": "加入歌单",
"showInPlaylist": "定位到播放列表",
"shuffleAll": "全部随机播放",
"download": "下载",
"playNext": "下一首播放",
@ -60,7 +56,6 @@
"size": "文件大小",
"name": "名称",
"genre": "流派",
"libraryName": "媒体库",
"compilation": "合辑",
"year": "发行年份",
"date": "录制日期",
@ -77,8 +72,7 @@
"releaseType": "发行类型",
"grouping": "分组",
"media": "媒体类型",
"mood": "情绪",
"missing": "缺失"
"mood": "情绪"
},
"actions": {
"playAll": "立即播放",
@ -110,8 +104,7 @@
"playCount": "播放次数",
"rating": "评分",
"genre": "流派",
"role": "参与角色",
"missing": "缺失"
"role": "参与角色"
},
"roles": {
"albumartist": "专辑歌手",
@ -126,13 +119,7 @@
"mixer": "混音师",
"remixer": "重混师",
"djmixer": "DJ混音师",
"performer": "演奏家",
"maincredit": "主要艺术家"
},
"actions": {
"topSongs": "热门歌曲",
"shuffle": "随机播放",
"radio": "电台"
"performer": "演奏家"
}
},
"user": {
@ -149,26 +136,19 @@
"changePassword": "修改密码?",
"currentPassword": "当前密码",
"newPassword": "新密码",
"token": "令牌",
"libraries": "媒体库"
"token": "令牌"
},
"helperTexts": {
"name": "名称的更改将在下次登录时生效",
"libraries": "为该用户选择指定媒体库,留空则使用默认媒体库"
"name": "名称的更改将在下次登录时生效"
},
"notifications": {
"created": "用户已创建",
"updated": "用户已更新",
"deleted": "用户已删除"
},
"validation": {
"librariesRequired": "普通用户必须至少选择一个媒体库"
},
"message": {
"listenBrainzToken": "输入您的 ListenBrainz 用户令牌",
"clickHereForToken": "点击这里来获得你的 ListenBrainz 令牌",
"selectAllLibraries": "选择全部媒体库",
"adminAutoLibraries": "管理员默认可访问所有媒体库"
"clickHereForToken": "点击这里来获得你的 ListenBrainz 令牌"
}
},
"player": {
@ -211,18 +191,12 @@
"selectPlaylist": "选择歌单",
"addNewPlaylist": "新建 %{name}",
"export": "导出",
"saveQueue": "保存为歌单",
"makePublic": "设为公开",
"makePrivate": "设为私有",
"searchOrCreate": "搜索歌单,或输入名称新建…",
"pressEnterToCreate": "按 Enter 键新建歌单",
"removeFromSelection": "移除选中项"
"makePrivate": "设为私有"
},
"message": {
"duplicate_song": "添加重复的歌曲",
"song_exist": "部分选定的歌曲已存在歌单中,继续添加或是跳过它们?",
"noPlaylistsFound": "未找到歌单",
"noPlaylists": "暂无可用歌单"
"song_exist": "部分选定的歌曲已存在歌单中,继续添加或是跳过它们?"
}
},
"radio": {
@ -263,68 +237,14 @@
"fields": {
"path": "路径",
"size": "文件大小",
"libraryName": "媒体库",
"updatedAt": "丢失于"
},
"actions": {
"remove": "移除",
"remove_all": "移除所有"
"remove": "移除"
},
"notifications": {
"removed": "丢失文件已移除"
}
},
"library": {
"name": "媒体库",
"fields": {
"name": "名称",
"path": "路径",
"remotePath": "远程路径",
"lastScanAt": "上次扫描",
"songCount": "歌曲",
"albumCount": "专辑",
"artistCount": "艺术家",
"totalSongs": "歌曲",
"totalAlbums": "专辑",
"totalArtists": "艺术家",
"totalFolders": "目录",
"totalFiles": "文件",
"totalMissingFiles": "缺失的文件",
"totalSize": "总大小",
"totalDuration": "时长",
"defaultNewUsers": "新用户默认",
"createdAt": "创建于",
"updatedAt": "更新于"
},
"sections": {
"basic": "基本信息",
"statistics": "统计数据"
},
"actions": {
"scan": "扫描媒体库",
"manageUsers": "管理用户权限",
"viewDetails": "查看详情"
},
"notifications": {
"created": "媒体库已创建",
"updated": "媒体库已更新",
"deleted": "媒体库已删除",
"scanStarted": "开始扫描媒体库",
"scanCompleted": "媒体库扫描已完成"
},
"validation": {
"nameRequired": "媒体库名称不能为空!",
"pathRequired": "媒体库路径不能为空!",
"pathNotDirectory": "媒体库路径必须为目录!",
"pathNotFound": "媒体库路径不存在!",
"pathNotAccessible": "媒体库路径无法访问!",
"pathInvalid": "媒体库路径无效!"
},
"messages": {
"deleteConfirm": "您确定要删除此媒体库吗?此操作将删除所有关联数据及用户访问权限!",
"scanInProgress": "正在扫描...",
"noLibrariesAssigned": "该用户未分配任何媒体库!"
}
}
},
"ra": {
@ -477,15 +397,11 @@
"transcodingDisabled": "出于安全原因,从 Web 界面更改转码配置的功能已被禁用。要更改(编辑或新增)转码选项,请在启用 %{config} 选项的情况下重新启动服务器。",
"transcodingEnabled": "Navidrome 当前与 %{config} 一起使用,可以通过配置转码选项来执行任意命令,建议仅在配置转码选项时启用此功能。",
"songsAddedToPlaylist": "已添加 %{smart_count} 首歌到歌单",
"noSimilarSongsFound": "未找到相似歌曲",
"noTopSongsFound": "未找到热门歌曲",
"noPlaylistsAvailable": "没有有效的歌单",
"delete_user_title": "删除用户 %{name}",
"delete_user_content": "您确定要删除该用户及其相关数据(包括歌单和用户配置)吗?",
"remove_missing_title": "移除丢失文件",
"remove_missing_content": "您确定要将选中的丢失文件从数据库中永久移除吗?此操作将删除所有相关信息,包括播放次数和评分。",
"remove_all_missing_title": "删除所有丢失文件",
"remove_all_missing_content": "您确定要从数据库中删除所有丢失文件吗?这将永久删除对它们的所有引用,包括它们的播放次数和评分。",
"notifications_blocked": "您已在浏览器的设置中屏蔽了此网站的通知",
"notifications_not_available": "此浏览器不支持桌面通知",
"lastfmLinkSuccess": "Last.fm 已关联并启用喜好记录",
@ -512,12 +428,6 @@
},
"menu": {
"library": "曲库",
"librarySelector": {
"allLibraries": "全部媒体库 (%{count})",
"multipleLibraries": "已选 %{selected} 共 %{total} 媒体库",
"selectLibraries": "选择媒体库",
"none": "无"
},
"settings": "设置",
"version": "版本",
"theme": "主题",
@ -580,21 +490,6 @@
"disabled": "禁用",
"waiting": "等待"
}
},
"tabs": {
"about": "关于",
"config": "配置"
},
"config": {
"configName": "配置名称",
"environmentVariable": "环境变量",
"currentValue": "当前值",
"configurationFile": "配置文件",
"exportToml": "导出配置TOML",
"exportSuccess": "配置以 TOML 格式导出到剪贴板",
"exportFailed": "复制配置失败",
"devFlagsHeader": "开发标志(可能会更改/删除)",
"devFlagsComment": "这些是实验性设置,可能会在未来版本中删除"
}
},
"activity": {
@ -603,15 +498,7 @@
"quickScan": "快速扫描",
"fullScan": "完全扫描",
"serverUptime": "服务器已运行",
"serverDown": "服务器已离线",
"scanType": "扫描类型",
"status": "扫描状态",
"elapsedTime": "用时"
},
"nowPlaying": {
"title": "正在播放",
"empty": "无播放内容",
"minutesAgo": "%{smart_count} 分钟前"
"serverDown": "服务器已离线"
},
"help": {
"title": "Navidrome 快捷键",
@ -627,4 +514,4 @@
"toggle_love": "添加/移除星标"
}
}
}
}

View File

@ -7,7 +7,6 @@ import (
"github.com/navidrome/navidrome/model"
"github.com/navidrome/navidrome/model/request"
"github.com/navidrome/navidrome/server/subsonic/responses"
"github.com/navidrome/navidrome/utils/slice"
)
// buildUserResponse creates a User response object from a User model
@ -20,7 +19,6 @@ func buildUserResponse(user model.User) responses.User {
ScrobblingEnabled: true,
DownloadRole: conf.Server.EnableDownloads,
ShareRole: conf.Server.EnableSharing,
Folder: slice.Map(user.Libraries, func(lib model.Library) int32 { return int32(lib.ID) }),
}
if conf.Server.Jukebox.Enabled {
@ -30,6 +28,7 @@ func buildUserResponse(user model.User) responses.User {
return userResponse
}
// TODO This is a placeholder. The real one has to read this info from a config file or the database
func (api *Router) GetUser(r *http.Request) (*responses.Subsonic, error) {
loggedUser, ok := request.UserFrom(r.Context())
if !ok {

View File

@ -36,12 +36,6 @@ var _ = Describe("Users", func() {
conf.Server.EnableSharing = true
conf.Server.Jukebox.Enabled = false
// Set up user with libraries
testUser.Libraries = model.Libraries{
{ID: 10, Name: "Music"},
{ID: 20, Name: "Podcasts"},
}
// Create request with user in context
req := httptest.NewRequest("GET", "/rest/getUser", nil)
ctx := request.WithUser(context.Background(), testUser)
@ -63,7 +57,6 @@ var _ = Describe("Users", func() {
Expect(userResponse.User.ScrobblingEnabled).To(BeTrue())
Expect(userResponse.User.DownloadRole).To(BeTrue())
Expect(userResponse.User.ShareRole).To(BeTrue())
Expect(userResponse.User.Folder).To(ContainElements(int32(10), int32(20)))
// Verify GetUsers response structure
Expect(usersResponse.Status).To(Equal(responses.StatusOK))
@ -82,7 +75,6 @@ var _ = Describe("Users", func() {
Expect(singleUser.DownloadRole).To(Equal(userFromList.DownloadRole))
Expect(singleUser.ShareRole).To(Equal(userFromList.ShareRole))
Expect(singleUser.JukeboxRole).To(Equal(userFromList.JukeboxRole))
Expect(singleUser.Folder).To(Equal(userFromList.Folder))
})
})
@ -101,19 +93,4 @@ var _ = Describe("Users", func() {
Entry("jukebox enabled, admin-only, regular user", true, true, false, false),
Entry("jukebox enabled, admin-only, admin user", true, true, true, true),
)
Describe("Folder list population", func() {
It("should populate Folder field with user's accessible library IDs", func() {
testUser.Libraries = model.Libraries{
{ID: 1, Name: "Music"},
{ID: 2, Name: "Podcasts"},
{ID: 5, Name: "Audiobooks"},
}
response := buildUserResponse(testUser)
Expect(response.Folder).To(HaveLen(3))
Expect(response.Folder).To(ContainElements(int32(1), int32(2), int32(5)))
})
})
})

View File

@ -169,7 +169,6 @@ const PlaylistSongs = ({ playlistId, readOnly, actions, ...props }) => {
quality: isDesktop && <QualityInfo source="quality" sortable={false} />,
channels: isDesktop && <NumberField source="channels" />,
bpm: isDesktop && <NumberField source="bpm" />,
genre: <TextField source="genre" />,
rating: config.enableStarRating && (
<RatingField
source="rating"
@ -191,7 +190,6 @@ const PlaylistSongs = ({ playlistId, readOnly, actions, ...props }) => {
'playCount',
'playDate',
'albumArtist',
'genre',
'rating',
],
})