31 Commits

Author SHA1 Message Date
austinried
ad6d534286 context menu base and move query to state 2026-01-02 10:27:41 +09:00
austinried
2837d4576e logging framework 2025-12-14 10:09:32 +09:00
austinried
7f6ba4776a source settings (add/edit) 2025-12-10 20:21:43 +09:00
austinried
f7874bcead remove home tab for now 2025-12-07 13:21:32 +09:00
austinried
ba169092fd artist screen tweaks 2025-12-07 13:21:21 +09:00
austinried
4183e2d3b9 round album art corners in tiles 2025-12-07 11:26:48 +09:00
austinried
c3bb14edbf fix temp db seed 2025-12-07 11:26:33 +09:00
austinried
805e6fff7a artist screen 2025-12-07 11:26:21 +09:00
austinried
d245fc7fef fix song list source change not refreshing 2025-12-06 18:46:26 +09:00
austinried
3fcb938f2b playlists screen 2025-12-06 16:38:38 +09:00
austinried
97ea3c3230 devtools 2025-12-06 15:45:03 +09:00
austinried
71132a1f0e fix extra rebuild due to hierarchy change 2025-12-06 15:44:51 +09:00
austinried
f3969dc6af playlists list 2025-12-06 15:12:53 +09:00
austinried
a4e4c6fa57 songs list tab 2025-12-06 09:42:53 +09:00
austinried
16a79c81cb songs list and serializable list query 2025-12-05 21:16:48 +09:00
austinried
6609671ae2 cover art color scheme extraction (in background)
refactor text styles to use theme
port over part of album screen
2025-12-03 13:22:14 +09:00
austinried
b9a094c1c4 remove active sourceId subquery 2025-11-23 12:40:05 +09:00
austinried
fd800b0e12 flutter 3.38 upgrade 2025-11-23 11:41:20 +09:00
austinried
b6153ce3b6 refresh lists on source change and sync 2025-11-23 10:59:01 +09:00
austinried
798a907cca active source switching and reactivity 2025-11-22 17:00:14 +09:00
austinried
de9bc98044 active source/id from db watch 2025-11-20 22:04:07 +09:00
austinried
b5d52a034d library tabs translations 2025-11-18 21:59:13 +09:00
austinried
51b9f3f1a8 migrate l10n, state preloading 2025-11-18 19:01:25 +09:00
austinried
8c3979ca8b library screen refactor 2025-11-09 21:41:41 +09:00
austinried
aaab1d1278 refactor artist to use coverArt
fix cover art image caching
2025-11-09 17:11:35 +09:00
austinried
42ff02f88e don't need these prints now 2025-11-09 17:04:53 +09:00
austinried
d18ca13f48 artist list with images 2025-11-09 15:48:20 +09:00
austinried
ee2a276f2f display albums from db 2025-11-09 09:26:45 +09:00
austinried
0c80dbdba5 sync the rest of the source models
refactor music download/storage to avoid re-download during reset
add palylist to test server setup
2025-11-07 15:24:51 +09:00
austinried
0e6acbed0f bring in database
switch to just using source models (no extra db fields)
start re-implementing sync service
2025-11-07 11:45:13 +09:00
austinried
f1c734d432 reorg ui into app 2025-11-03 10:35:44 +09:00
119 changed files with 26851 additions and 1228 deletions

3
.gitignore vendored
View File

@@ -46,3 +46,6 @@ app.*.map.json
# VSCode
.vscode/settings.json
# subtracks
/music

578
.untranslated-messages.json Normal file
View File

@@ -0,0 +1,578 @@
{
"ar": [
"actionsCancel",
"actionsDelete",
"actionsDownload",
"actionsDownloadCancel",
"actionsDownloadDelete",
"actionsOk",
"controlsShuffle",
"navigationTabsAlbums",
"navigationTabsArtists",
"navigationTabsPlaylists",
"navigationTabsSongs",
"resourcesAlbumCount",
"resourcesArtistCount",
"resourcesFilterAlbum",
"resourcesFilterArtist",
"resourcesFilterOwner",
"resourcesFilterYear",
"resourcesPlaylistCount",
"resourcesSongCount",
"resourcesSongListDeleteAllContent",
"resourcesSongListDeleteAllTitle",
"resourcesSortByAlbum",
"resourcesSortByAlbumCount",
"resourcesSortByTitle",
"resourcesSortByUpdated",
"settingsAboutActionsSupport",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn",
"settingsNetworkOptionsStreamFormat",
"settingsNetworkOptionsStreamFormatServerDefault",
"settingsServersFieldsName"
],
"ca": [
"actionsCancel",
"actionsDelete",
"actionsDownload",
"actionsDownloadCancel",
"actionsDownloadDelete",
"actionsOk",
"controlsShuffle",
"navigationTabsAlbums",
"navigationTabsArtists",
"navigationTabsPlaylists",
"navigationTabsSongs",
"resourcesAlbumCount",
"resourcesArtistCount",
"resourcesFilterAlbum",
"resourcesFilterArtist",
"resourcesFilterOwner",
"resourcesFilterYear",
"resourcesPlaylistCount",
"resourcesSongCount",
"resourcesSongListDeleteAllContent",
"resourcesSongListDeleteAllTitle",
"resourcesSortByAlbum",
"resourcesSortByAlbumCount",
"resourcesSortByTitle",
"resourcesSortByUpdated",
"settingsAboutActionsSupport",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn",
"settingsNetworkOptionsStreamFormat",
"settingsNetworkOptionsStreamFormatServerDefault",
"settingsServersFieldsName"
],
"cs": [
"navigationTabsAlbums",
"navigationTabsArtists",
"navigationTabsPlaylists",
"navigationTabsSongs",
"resourcesAlbumCount",
"resourcesArtistCount",
"resourcesPlaylistCount",
"resourcesSongCount",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsMusicName",
"settingsMusicOptionsScrobbleDescriptionOff",
"settingsMusicOptionsScrobbleDescriptionOn",
"settingsMusicOptionsScrobbleTitle",
"settingsNetworkOptionsMaxBufferTitle",
"settingsNetworkOptionsMinBufferTitle",
"settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn"
],
"da": [
"actionsCancel",
"actionsDelete",
"actionsDownload",
"actionsDownloadCancel",
"actionsDownloadDelete",
"actionsOk",
"actionsStar",
"actionsUnstar",
"controlsShuffle",
"navigationTabsAlbums",
"navigationTabsArtists",
"navigationTabsPlaylists",
"navigationTabsSongs",
"resourcesAlbumCount",
"resourcesArtistCount",
"resourcesFilterAlbum",
"resourcesFilterArtist",
"resourcesFilterOwner",
"resourcesFilterStarred",
"resourcesFilterYear",
"resourcesPlaylistCount",
"resourcesSongCount",
"resourcesSongListDeleteAllContent",
"resourcesSongListDeleteAllTitle",
"resourcesSortByAdded",
"resourcesSortByAlbum",
"resourcesSortByAlbumCount",
"resourcesSortByFrequentlyPlayed",
"resourcesSortByRecentlyPlayed",
"resourcesSortByTitle",
"resourcesSortByUpdated",
"settingsAboutActionsSupport",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsMusicOptionsScrobbleDescriptionOff",
"settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn",
"settingsNetworkOptionsStreamFormat",
"settingsNetworkOptionsStreamFormatServerDefault",
"settingsServersFieldsName",
"settingsServersOptionsForcePlaintextPasswordDescriptionOff",
"settingsServersOptionsForcePlaintextPasswordDescriptionOn",
"settingsServersOptionsForcePlaintextPasswordTitle"
],
"de": [
"navigationTabsAlbums",
"navigationTabsArtists",
"navigationTabsPlaylists",
"navigationTabsSongs",
"settingsAboutShareLogs",
"settingsAboutChooseLog"
],
"es": [
"navigationTabsAlbums",
"navigationTabsArtists",
"navigationTabsPlaylists",
"navigationTabsSongs",
"resourcesAlbumCount",
"resourcesArtistCount",
"resourcesFilterAlbum",
"resourcesFilterArtist",
"resourcesFilterOwner",
"resourcesFilterYear",
"resourcesPlaylistCount",
"resourcesSongCount",
"resourcesSongListDeleteAllContent",
"resourcesSongListDeleteAllTitle",
"resourcesSortByAlbum",
"resourcesSortByAlbumCount",
"resourcesSortByTitle",
"resourcesSortByUpdated",
"settingsAboutActionsSupport",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn",
"settingsNetworkOptionsStreamFormat",
"settingsNetworkOptionsStreamFormatServerDefault",
"settingsServersFieldsName"
],
"fr": [
"actionsCancel",
"actionsDelete",
"actionsDownload",
"actionsDownloadCancel",
"actionsDownloadDelete",
"actionsOk",
"controlsShuffle",
"navigationTabsAlbums",
"navigationTabsArtists",
"navigationTabsPlaylists",
"navigationTabsSongs",
"resourcesAlbumCount",
"resourcesArtistCount",
"resourcesFilterAlbum",
"resourcesFilterArtist",
"resourcesFilterOwner",
"resourcesFilterYear",
"resourcesPlaylistCount",
"resourcesSongCount",
"resourcesSongListDeleteAllContent",
"resourcesSongListDeleteAllTitle",
"resourcesSortByAlbum",
"resourcesSortByAlbumCount",
"resourcesSortByTitle",
"resourcesSortByUpdated",
"settingsAboutActionsSupport",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn",
"settingsNetworkOptionsStreamFormat",
"settingsNetworkOptionsStreamFormatServerDefault",
"settingsServersFieldsName"
],
"gl": [
"navigationTabsAlbums",
"navigationTabsArtists",
"navigationTabsPlaylists",
"navigationTabsSongs"
],
"it": [
"actionsCancel",
"actionsDelete",
"actionsDownload",
"actionsDownloadCancel",
"actionsDownloadDelete",
"actionsOk",
"controlsShuffle",
"navigationTabsAlbums",
"navigationTabsArtists",
"navigationTabsPlaylists",
"navigationTabsSongs",
"resourcesAlbumCount",
"resourcesArtistCount",
"resourcesFilterAlbum",
"resourcesFilterArtist",
"resourcesFilterOwner",
"resourcesFilterYear",
"resourcesPlaylistCount",
"resourcesSongCount",
"resourcesSongListDeleteAllContent",
"resourcesSongListDeleteAllTitle",
"resourcesSortByAlbum",
"resourcesSortByAlbumCount",
"resourcesSortByTitle",
"resourcesSortByUpdated",
"settingsAboutActionsSupport",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn",
"settingsNetworkOptionsStreamFormat",
"settingsNetworkOptionsStreamFormatServerDefault",
"settingsServersFieldsName"
],
"ja": [
"actionsCancel",
"actionsDelete",
"actionsDownload",
"actionsDownloadCancel",
"actionsDownloadDelete",
"actionsOk",
"actionsStar",
"actionsUnstar",
"controlsShuffle",
"messagesNothingHere",
"navigationTabsAlbums",
"navigationTabsArtists",
"navigationTabsPlaylists",
"navigationTabsSongs",
"resourcesAlbumActionsPlay",
"resourcesAlbumActionsView",
"resourcesAlbumCount",
"resourcesAlbumListsSort",
"resourcesArtistActionsView",
"resourcesArtistCount",
"resourcesArtistListsSort",
"resourcesFilterAlbum",
"resourcesFilterArtist",
"resourcesFilterGenre",
"resourcesFilterOwner",
"resourcesFilterYear",
"resourcesPlaylistActionsPlay",
"resourcesPlaylistCount",
"resourcesQueueName",
"resourcesSongCount",
"resourcesSongListDeleteAllContent",
"resourcesSongListDeleteAllTitle",
"resourcesSortByAdded",
"resourcesSortByAlbum",
"resourcesSortByAlbumCount",
"resourcesSortByArtist",
"resourcesSortByName",
"resourcesSortByTitle",
"resourcesSortByUpdated",
"resourcesSortByYear",
"searchHeaderTitle",
"searchMoreResults",
"searchNowPlayingContext",
"settingsAboutActionsLicenses",
"settingsAboutActionsSupport",
"settingsAboutName",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsAboutVersion",
"settingsMusicOptionsScrobbleDescriptionOff",
"settingsMusicOptionsScrobbleDescriptionOn",
"settingsMusicOptionsScrobbleTitle",
"settingsNetworkOptionsMaxBitrateMobileTitle",
"settingsNetworkOptionsMaxBitrateWifiTitle",
"settingsNetworkOptionsMaxBufferTitle",
"settingsNetworkOptionsMinBufferTitle",
"settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn",
"settingsNetworkOptionsStreamFormat",
"settingsNetworkOptionsStreamFormatServerDefault",
"settingsNetworkValuesKbps",
"settingsNetworkValuesSeconds",
"settingsNetworkValuesUnlimitedKbps",
"settingsResetActionsClearImageCache",
"settingsServersActionsAdd",
"settingsServersActionsDelete",
"settingsServersActionsEdit",
"settingsServersActionsSave",
"settingsServersActionsTestConnection",
"settingsServersFieldsAddress",
"settingsServersFieldsName",
"settingsServersFieldsPassword",
"settingsServersFieldsUsername",
"settingsServersMessagesConnectionFailed",
"settingsServersMessagesConnectionOk",
"settingsServersOptionsForcePlaintextPasswordDescriptionOff",
"settingsServersOptionsForcePlaintextPasswordDescriptionOn",
"settingsServersOptionsForcePlaintextPasswordTitle"
],
"nb": [
"actionsCancel",
"actionsDelete",
"actionsDownload",
"actionsDownloadCancel",
"actionsDownloadDelete",
"actionsOk",
"controlsShuffle",
"navigationTabsAlbums",
"navigationTabsArtists",
"navigationTabsPlaylists",
"navigationTabsSongs",
"resourcesAlbumCount",
"resourcesArtistCount",
"resourcesFilterAlbum",
"resourcesFilterArtist",
"resourcesFilterOwner",
"resourcesFilterYear",
"resourcesPlaylistCount",
"resourcesSongCount",
"resourcesSongListDeleteAllContent",
"resourcesSongListDeleteAllTitle",
"resourcesSortByAlbum",
"resourcesSortByAlbumCount",
"resourcesSortByTitle",
"resourcesSortByUpdated",
"settingsAboutActionsSupport",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn",
"settingsNetworkOptionsStreamFormat",
"settingsNetworkOptionsStreamFormatServerDefault",
"settingsServersFieldsName"
],
"pa": [
"actionsCancel",
"actionsDelete",
"actionsDownload",
"actionsDownloadCancel",
"actionsDownloadDelete",
"actionsOk",
"controlsShuffle",
"navigationTabsAlbums",
"navigationTabsArtists",
"navigationTabsPlaylists",
"navigationTabsSongs",
"resourcesAlbumCount",
"resourcesArtistCount",
"resourcesFilterAlbum",
"resourcesFilterArtist",
"resourcesFilterOwner",
"resourcesFilterYear",
"resourcesPlaylistCount",
"resourcesSongCount",
"resourcesSongListDeleteAllContent",
"resourcesSongListDeleteAllTitle",
"resourcesSortByAlbum",
"resourcesSortByAlbumCount",
"resourcesSortByTitle",
"resourcesSortByUpdated",
"settingsAboutActionsSupport",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn",
"settingsNetworkOptionsStreamFormat",
"settingsNetworkOptionsStreamFormatServerDefault",
"settingsServersFieldsName"
],
"pl": [
"actionsCancel",
"actionsDelete",
"actionsDownload",
"actionsDownloadCancel",
"actionsDownloadDelete",
"actionsOk",
"controlsShuffle",
"navigationTabsAlbums",
"navigationTabsArtists",
"navigationTabsPlaylists",
"navigationTabsSongs",
"resourcesAlbumCount",
"resourcesArtistCount",
"resourcesFilterAlbum",
"resourcesFilterArtist",
"resourcesFilterOwner",
"resourcesFilterYear",
"resourcesPlaylistCount",
"resourcesSongCount",
"resourcesSongListDeleteAllContent",
"resourcesSongListDeleteAllTitle",
"resourcesSortByAlbum",
"resourcesSortByAlbumCount",
"resourcesSortByTitle",
"resourcesSortByUpdated",
"settingsAboutActionsSupport",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn",
"settingsNetworkOptionsStreamFormat",
"settingsNetworkOptionsStreamFormatServerDefault",
"settingsServersFieldsName"
],
"pt": [
"navigationTabsAlbums",
"navigationTabsArtists",
"navigationTabsPlaylists",
"navigationTabsSongs",
"resourcesAlbumCount",
"resourcesArtistCount",
"resourcesFilterOwner",
"resourcesPlaylistCount",
"resourcesSongCount",
"resourcesSongListDeleteAllContent",
"resourcesSongListDeleteAllTitle",
"resourcesSortByAlbumCount",
"resourcesSortByUpdated",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsNetworkOptionsStreamFormatServerDefault",
"settingsServersFieldsName"
],
"ru": [
"navigationTabsAlbums",
"navigationTabsArtists",
"navigationTabsPlaylists",
"navigationTabsSongs"
],
"tr": [
"actionsCancel",
"actionsDelete",
"actionsDownload",
"actionsDownloadCancel",
"actionsDownloadDelete",
"actionsOk",
"controlsShuffle",
"navigationTabsAlbums",
"navigationTabsArtists",
"navigationTabsPlaylists",
"navigationTabsSongs",
"resourcesAlbumCount",
"resourcesArtistCount",
"resourcesFilterAlbum",
"resourcesFilterArtist",
"resourcesFilterOwner",
"resourcesFilterYear",
"resourcesPlaylistCount",
"resourcesSongCount",
"resourcesSongListDeleteAllContent",
"resourcesSongListDeleteAllTitle",
"resourcesSortByAlbum",
"resourcesSortByAlbumCount",
"resourcesSortByTitle",
"resourcesSortByUpdated",
"settingsAboutActionsSupport",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn",
"settingsNetworkOptionsStreamFormat",
"settingsNetworkOptionsStreamFormatServerDefault",
"settingsServersFieldsName"
],
"vi": [
"actionsCancel",
"actionsDelete",
"actionsDownload",
"actionsDownloadCancel",
"actionsDownloadDelete",
"actionsOk",
"controlsShuffle",
"navigationTabsAlbums",
"navigationTabsArtists",
"navigationTabsPlaylists",
"navigationTabsSongs",
"resourcesAlbumCount",
"resourcesArtistCount",
"resourcesFilterAlbum",
"resourcesFilterArtist",
"resourcesFilterOwner",
"resourcesFilterYear",
"resourcesPlaylistCount",
"resourcesSongCount",
"resourcesSongListDeleteAllContent",
"resourcesSongListDeleteAllTitle",
"resourcesSortByAlbum",
"resourcesSortByAlbumCount",
"resourcesSortByTitle",
"resourcesSortByUpdated",
"settingsAboutActionsSupport",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn",
"settingsNetworkOptionsStreamFormat",
"settingsNetworkOptionsStreamFormatServerDefault",
"settingsServersFieldsName"
],
"zh": [
"controlsShuffle",
"navigationTabsAlbums",
"navigationTabsArtists",
"navigationTabsPlaylists",
"navigationTabsSongs",
"resourcesAlbumCount",
"resourcesArtistCount",
"resourcesPlaylistCount",
"resourcesSongCount",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn",
"settingsNetworkOptionsStreamFormat",
"settingsNetworkOptionsStreamFormatServerDefault",
"settingsServersFieldsName"
]
}

26
.vscode/launch.json vendored
View File

@@ -1,26 +0,0 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "debug",
"request": "launch",
"type": "dart",
"flutterMode": "debug"
},
{
"name": "profile mode",
"request": "launch",
"type": "dart",
"flutterMode": "profile"
},
{
"name": "release mode",
"request": "launch",
"type": "dart",
"flutterMode": "release"
}
]
}

View File

@@ -3,7 +3,7 @@ services:
build: ./docker/library-manager
volumes:
- deno-dir:/deno-dir
- music:/music
- ./music:/music
navidrome:
image: deluan/navidrome:latest
@@ -14,7 +14,7 @@ services:
ND_LOGLEVEL: debug
volumes:
- navidrome-data:/data
- music:/music:ro
- ./music:/music:ro
gonic:
image: sentriz/gonic:latest
@@ -26,7 +26,7 @@ services:
- 4747:80
volumes:
- gonic-data:/data
- music:/music:ro
- ./music:/music:ro
- gonic-podcasts:/podcasts
- gonic-playlists:/playlists
- gonic-cache:/cache

3
devtools_options.yaml Normal file
View File

@@ -0,0 +1,3 @@
description: This file stores settings for Dart & Flutter DevTools.
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
extensions:

View File

@@ -3,9 +3,6 @@ import * as path from "jsr:@std/path@1.1.2";
import { MUSIC_DIR } from "./util/env.ts";
import { SubsonicClient } from "./util/subsonic.ts";
await new Deno.Command("rm", { args: ["-rf", path.join(MUSIC_DIR, "*")] })
.output();
const client = new SubsonicClient(
"http://demo.subsonic.org",
"guest1",
@@ -13,7 +10,7 @@ const client = new SubsonicClient(
);
for (const id of ["197", "199", "321"]) {
const { res } = await client.get("download", { id });
const { res } = await client.get("download", [["id", id]]);
let filename = res.headers.get("Content-Disposition")
?.split(";")[1];

View File

@@ -2,23 +2,79 @@
import { SubsonicClient } from "./util/subsonic.ts";
import { sleep } from "./util/util.ts";
async function getArtistId(
client: SubsonicClient,
artist: string,
): Promise<string> {
const { xml } = await client.get("getArtists");
return xml.querySelector(
`artist[name='${artist.replaceAll("'", "\\'")}']`,
)?.id!;
}
async function getAlbumId(
client: SubsonicClient,
album: string,
): Promise<string> {
const { xml } = await client.get("getAlbumList2", [
["type", "newest"],
]);
return xml.querySelector(
`album[name='${album.replaceAll("'", "\\'")}']`,
)?.id!;
}
async function getSongId(
client: SubsonicClient,
album: string,
track: number,
): Promise<string> {
const albumId = await getAlbumId(client, album);
const { xml } = await client.get("getAlbum", [["id", albumId!]]);
return xml.querySelector(`song[track='${track}']`)?.id!;
}
async function scrobbleTrack(
client: SubsonicClient,
album: string,
track: number,
) {
const { xml: albumsXml } = await client.get("getAlbumList2", {
type: "newest",
});
const albumId = albumsXml.querySelector(`album[name='${album}']`)?.id;
const songId = await getSongId(client, album, track);
const { xml: songsXml } = await client.get("getAlbum", { id: albumId! });
const songId = songsXml.querySelector(`song[track='${track}']`)?.id;
await client.get("scrobble", [
["id", songId!],
["submission", "true"],
]);
}
await client.get("scrobble", {
id: songId!,
submission: "true",
});
async function starAlbum(client: SubsonicClient, album: string) {
const albumId = await getAlbumId(client, album);
await client.get("star", [["albumId", albumId]]);
}
async function starArtist(client: SubsonicClient, artist: string) {
const artistId = await getArtistId(client, artist);
await client.get("star", [["artistId", artistId]]);
}
async function createPlaylist(
client: SubsonicClient,
name: string,
songs: { album: string; track: number }[],
) {
const songIds = await Promise.all(songs.map(({ album, track }) => {
return getSongId(client, album, track);
}));
await client.get("createPlaylist", [
["name", name],
...songIds.map((songId) => ["songId", songId] as [string, string]),
]);
}
async function setupTestData(client: SubsonicClient) {
@@ -27,6 +83,19 @@ async function setupTestData(client: SubsonicClient) {
await scrobbleTrack(client, "Retroconnaissance EP", 2);
await sleep(1_000);
await scrobbleTrack(client, "Kosmonaut", 1);
await createPlaylist(client, "Playlist 1", [
{ album: "Retroconnaissance EP", track: 2 },
{ album: "Retroconnaissance EP", track: 1 },
{ album: "Kosmonaut", track: 2 },
{ album: "Kosmonaut", track: 4 },
{ album: "I Don't Know What I'm Doing", track: 9 },
{ album: "I Don't Know What I'm Doing", track: 10 },
{ album: "I Don't Know What I'm Doing", track: 11 },
]);
await starAlbum(client, "Kosmonaut");
await starArtist(client, "Ugress");
}
async function setupNavidrome() {

View File

@@ -10,15 +10,15 @@ export class SubsonicClient {
async get(
method: "download",
params?: Record<string, string>,
params?: [string, string][],
): Promise<{ res: Response; xml: undefined }>;
async get(
method: string,
params?: Record<string, string>,
params?: [string, string][],
): Promise<{ res: Response; xml: Document }>;
async get(
method: string,
params?: Record<string, string>,
params?: [string, string][],
): Promise<{ res: Response; xml: Document | undefined }> {
const url = new URL(`rest/${method}.view`, this.baseUrl);
@@ -28,9 +28,9 @@ export class SubsonicClient {
url.searchParams.set("c", "subtracks-test-fixture");
if (params) {
Object.entries(params).forEach(([key, value]) =>
url.searchParams.append(key, value)
);
for (const [key, value] of params) {
url.searchParams.append(key, value);
}
}
const res = await fetch(url);

6
l10n.yaml Normal file
View File

@@ -0,0 +1,6 @@
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-dir: lib/l10n/generated
output-localization-file: app_localizations.dart
untranslated-messages-file: .untranslated-messages.json
nullable-getter: false

View File

@@ -0,0 +1,22 @@
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../state/services.dart';
import '../state/source.dart';
void useOnSourceChange(WidgetRef ref, void Function(int sourceId) callback) {
final sourceId = ref.watch(sourceIdProvider);
useEffect(() {
callback(sourceId);
return;
}, [sourceId]);
}
void useOnSourceSync(WidgetRef ref, void Function() callback) {
final syncService = ref.watch(syncServiceProvider);
useOnListenableChange(syncService, () {
callback();
});
}

62
lib/app/router.dart Normal file
View File

@@ -0,0 +1,62 @@
import 'package:go_router/go_router.dart';
import 'screens/album_screen.dart';
import 'screens/artist_screen.dart';
import 'screens/library_screen.dart';
import 'screens/now_playing_screen.dart';
import 'screens/playlist_screen.dart';
import 'screens/preload_screen.dart';
import 'screens/root_shell_screen.dart';
import 'screens/settings_screen.dart';
import 'screens/settings_source_screen.dart';
final router = GoRouter(
initialLocation: '/preload',
routes: [
GoRoute(
path: '/preload',
builder: (context, state) => PreloadScreen(),
),
ShellRoute(
builder: (context, state, child) => RootShellScreen(child: child),
routes: [
GoRoute(
path: '/',
builder: (context, state) => LibraryScreen(),
routes: [
GoRoute(
path: 'albums/:id',
builder: (context, state) =>
AlbumScreen(id: state.pathParameters['id']!),
),
GoRoute(
path: 'artists/:id',
builder: (context, state) =>
ArtistScreen(id: state.pathParameters['id']!),
),
GoRoute(
path: 'playlists/:id',
builder: (context, state) =>
PlaylistScreen(id: state.pathParameters['id']!),
),
],
),
],
),
GoRoute(
path: '/now-playing',
builder: (context, state) => NowPlayingScreen(),
),
GoRoute(
path: '/settings',
builder: (context, state) => SettingsScreen(),
),
GoRoute(
path: '/sources/:id',
builder: (context, state) {
final id = state.pathParameters['id'];
return SettingsSourceScreen(id: id == 'add' ? null : int.parse(id!));
},
),
],
);

View File

@@ -0,0 +1,77 @@
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../../database/query.dart';
import '../../l10n/generated/app_localizations.dart';
import '../state/database.dart';
import '../state/source.dart';
import '../ui/cover_art_theme.dart';
import '../ui/gradient.dart';
import '../ui/lists/header.dart';
import '../ui/lists/items.dart';
import '../ui/lists/songs_list.dart';
class AlbumScreen extends HookConsumerWidget {
const AlbumScreen({
super.key,
required this.id,
});
final String id;
@override
Widget build(BuildContext context, WidgetRef ref) {
final l = AppLocalizations.of(context);
final db = ref.watch(databaseProvider);
final sourceId = ref.watch(sourceIdProvider);
final getAlbum = useMemoized(
() => db.libraryDao.getAlbum(sourceId, id).getSingle(),
);
final album = useFuture(getAlbum).data;
if (album == null) {
return Container();
}
final query = SongsQuery(
sourceId: sourceId,
filter: IList([SongsFilter.albumId(album.id)]),
sort: IList([
SortingTerm.songsAsc(SongsColumn.disc),
SortingTerm.songsAsc(SongsColumn.track),
SortingTerm.songsAsc(SongsColumn.title),
]),
);
return CoverArtTheme(
coverArt: album.coverArt,
child: Scaffold(
body: GradientScrollView(
slivers: [
SliverToBoxAdapter(
child: SongsListHeader(
title: album.name,
subtitle: album.albumArtist,
coverArt: album.coverArt,
playText: l.resourcesAlbumActionsPlay,
onPlay: () {},
onMore: () {},
),
),
SongsList(
query: query,
itemBuilder: (context, item, index) => SongListTile(
song: item.song,
onTap: () {},
),
),
],
),
),
);
}
}

View File

@@ -0,0 +1,124 @@
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../../database/query.dart';
import '../../sources/models.dart';
import '../state/database.dart';
import '../state/source.dart';
import '../ui/cover_art_theme.dart';
import '../ui/gradient.dart';
import '../ui/images.dart';
import '../ui/lists/albums_list.dart';
class ArtistScreen extends HookConsumerWidget {
const ArtistScreen({
super.key,
required this.id,
});
final String id;
@override
Widget build(BuildContext context, WidgetRef ref) {
final db = ref.watch(databaseProvider);
final sourceId = ref.watch(sourceIdProvider);
final getArtist = useMemoized(
() => db.libraryDao.getArtist(sourceId, id).getSingle(),
);
final artist = useFuture(getArtist).data;
if (artist == null) {
return Container();
}
final query = AlbumsQuery(
sourceId: sourceId,
filter: IList([AlbumsFilter.artistId(artist.id)]),
sort: IList([
SortingTerm.albumsDesc(AlbumsColumn.year),
SortingTerm.albumsAsc(AlbumsColumn.name),
]),
);
return CoverArtTheme(
coverArt: artist.coverArt,
child: Scaffold(
body: GradientScrollView(
slivers: [
ArtistHeader(artist: artist),
AlbumsList(query: query),
],
),
),
);
}
}
class ArtistHeader extends StatelessWidget {
const ArtistHeader({
super.key,
required this.artist,
});
final Artist artist;
@override
Widget build(BuildContext context) {
final textTheme = TextTheme.of(context);
final colorScheme = ColorScheme.of(context);
return SliverToBoxAdapter(
child: Stack(
fit: StackFit.passthrough,
alignment: AlignmentGeometry.bottomCenter,
children: [
CoverArtImage(
fit: BoxFit.cover,
coverArt: artist.coverArt,
thumbnail: false,
height: 350,
),
Column(
children: [
Container(
width: double.infinity,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: AlignmentGeometry.centerRight,
end: AlignmentGeometry.centerLeft,
colors: [
colorScheme.surface.withAlpha(220),
colorScheme.surface.withAlpha(150),
colorScheme.surface.withAlpha(20),
],
),
),
child: Padding(
padding: EdgeInsetsGeometry.symmetric(
vertical: 12,
horizontal: 16,
),
child: Text(
artist.name,
textAlign: TextAlign.right,
style: textTheme.headlineLarge?.copyWith(
shadows: [
Shadow(
blurRadius: 20,
color: colorScheme.surface,
),
],
),
),
),
),
],
),
],
),
);
}
}

View File

@@ -0,0 +1,294 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:material_symbols_icons/symbols.dart';
import '../../l10n/generated/app_localizations.dart';
import '../state/lists.dart';
import '../state/services.dart';
import '../ui/lists/albums_grid.dart';
import '../ui/lists/artists_list.dart';
import '../ui/lists/items.dart';
import '../ui/lists/playlists_list.dart';
import '../ui/lists/songs_list.dart';
import '../ui/menus.dart';
import '../util/custom_scroll_fix.dart';
const kIconSize = 26.0;
const kTabHeight = 36.0;
enum LibraryTab {
// home(Icon(Symbols.home_rounded)),
albums(Icon(Symbols.album_rounded)),
artists(Icon(Symbols.person_rounded)),
songs(Icon(Symbols.music_note_rounded)),
playlists(Icon(Symbols.playlist_play_rounded));
const LibraryTab(this.icon);
final Widget icon;
@override
toString() => name;
}
class LibraryScreen extends HookConsumerWidget {
const LibraryScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final tabController = useTabController(
initialLength: LibraryTab.values.length,
initialIndex: 0,
);
return Scaffold(
body: NestedScrollView(
floatHeaderSlivers: true,
headerSliverBuilder: (context, innerBoxIsScrolled) => <Widget>[
SliverOverlapAbsorber(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
sliver: LibraryTabsHeader(tabController: tabController),
),
],
body: Builder(
builder: (context) => CustomScrollProvider(
tabController: tabController,
parent: PrimaryScrollController.of(context),
child: LibraryTabBarView(tabController: tabController),
),
),
),
);
}
}
class LibraryTabBarView extends HookConsumerWidget {
const LibraryTabBarView({
super.key,
required this.tabController,
});
final TabController tabController;
@override
Widget build(BuildContext context, WidgetRef ref) {
final songsQuery = ref.watch(songsQueryProvider);
return TabBarView(
controller: tabController,
children: LibraryTab.values
.map(
(tab) => TabScrollView(
index: LibraryTab.values.indexOf(tab),
sliver: switch (tab) {
LibraryTab.albums => AlbumsGrid(),
LibraryTab.artists => ArtistsList(),
LibraryTab.playlists => PlaylistsList(),
LibraryTab.songs => SongsList(
query: songsQuery,
itemBuilder: (context, item, index) => SongListTile(
song: item.song,
coverArt: item.albumCoverArt,
showLeading: true,
onTap: () {},
),
),
// _ => SliverToBoxAdapter(child: Container()),
},
menuBuilder: switch (tab) {
LibraryTab.albums => (_) => AlbumsGridFilters(),
// LibraryTab.artists => (_) => AlbumsGridFilters(),
// LibraryTab.playlists => (_) => AlbumsGridFilters(),
// LibraryTab.songs => (_) => AlbumsGridFilters(),
_ => null,
},
),
)
.toList(),
);
}
}
class LibraryTabsHeader extends HookConsumerWidget {
const LibraryTabsHeader({
super.key,
required this.tabController,
});
final TabController tabController;
@override
Widget build(BuildContext context, WidgetRef ref) {
final theme = Theme.of(context);
return SliverAppBar(
pinned: true,
floating: true,
flexibleSpace: FlexibleSpaceBar(
collapseMode: CollapseMode.pin,
background: SafeArea(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 18, vertical: 16),
child: TabTitleText(tabController: tabController),
),
),
),
bottom: PreferredSize(
preferredSize: Size.fromHeight(kTabHeight + 18),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: IconTheme(
data: IconThemeData(
fill: 1,
color: theme.textTheme.headlineLarge?.color,
weight: 600,
opticalSize: kIconSize,
size: kIconSize,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TabBar(
controller: tabController,
dividerColor: Colors.transparent,
isScrollable: true,
tabAlignment: TabAlignment.start,
indicatorSize: TabBarIndicatorSize.label,
labelPadding: EdgeInsets.symmetric(horizontal: 2),
labelColor: theme.primaryColorDark,
unselectedLabelColor: theme.textTheme.headlineLarge?.color,
padding: EdgeInsets.symmetric(vertical: 8),
splashBorderRadius: BorderRadius.circular(8),
indicator: BoxDecoration(
color: theme.primaryTextTheme.headlineLarge?.color,
borderRadius: BorderRadius.circular(8),
),
tabs: LibraryTab.values
.map(
(tab) => Tab(
height: kTabHeight,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 6),
child: tab.icon,
),
),
)
.toList(),
),
Spacer(),
SyncButton(),
SettingsButton(),
],
),
),
),
),
);
}
}
class TabTitleText extends HookConsumerWidget {
const TabTitleText({
super.key,
required this.tabController,
});
final TabController tabController;
@override
Widget build(BuildContext context, WidgetRef ref) {
final l = AppLocalizations.of(context);
final text = TextTheme.of(context);
String tabLocalization(LibraryTab tab) => switch (tab) {
LibraryTab.albums => l.navigationTabsAlbums,
// LibraryTab.home => l.navigationTabsHome,
LibraryTab.artists => l.navigationTabsArtists,
LibraryTab.songs => l.navigationTabsSongs,
LibraryTab.playlists => l.navigationTabsPlaylists,
};
final tabName = tabLocalization(LibraryTab.values[tabController.index]);
final tabText = useState(tabName);
useListenable(tabController);
useEffect(() {
tabText.value = tabName;
return;
}, [tabName]);
return Text(tabText.value, style: text.headlineLarge);
}
}
class TabScrollView extends HookConsumerWidget {
const TabScrollView({
super.key,
required this.index,
required this.sliver,
this.menuBuilder,
});
final int index;
final Widget sliver;
final WidgetBuilder? menuBuilder;
@override
Widget build(BuildContext context, WidgetRef ref) {
useAutomaticKeepAlive();
final scrollProvider = CustomScrollProviderData.of(context);
final listBuilder = menuBuilder;
final floatingActionButton = listBuilder != null
? FabFilter(
listBuilder: listBuilder,
)
: null;
return Scaffold(
floatingActionButton: floatingActionButton,
body: CustomScrollView(
controller: scrollProvider.scrollControllers[index],
slivers: <Widget>[
SliverOverlapInjector(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
),
sliver,
],
),
);
}
}
class SyncButton extends HookConsumerWidget {
const SyncButton({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final syncService = ref.watch(syncServiceProvider);
return IconButton(
icon: Icon(Symbols.sync_rounded),
onPressed: () {
syncService.sync();
},
);
}
}
class SettingsButton extends HookConsumerWidget {
const SettingsButton({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
return IconButton(
icon: Icon(Symbols.settings_rounded),
onPressed: () {
context.push('/settings');
},
);
}
}

View File

@@ -0,0 +1,77 @@
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../../database/query.dart';
import '../../l10n/generated/app_localizations.dart';
import '../state/database.dart';
import '../state/source.dart';
import '../ui/cover_art_theme.dart';
import '../ui/gradient.dart';
import '../ui/lists/header.dart';
import '../ui/lists/items.dart';
import '../ui/lists/songs_list.dart';
class PlaylistScreen extends HookConsumerWidget {
const PlaylistScreen({
super.key,
required this.id,
});
final String id;
@override
Widget build(BuildContext context, WidgetRef ref) {
final l = AppLocalizations.of(context);
final db = ref.watch(databaseProvider);
final sourceId = ref.watch(sourceIdProvider);
final getPlaylist = useMemoized(
() => db.libraryDao.getPlaylist(sourceId, id).getSingle(),
);
final playlist = useFuture(getPlaylist).data;
if (playlist == null) {
return Container();
}
final query = SongsQuery(
sourceId: sourceId,
filter: IList([SongsFilter.playlistId(playlist.id)]),
sort: IList([
SortingTerm.songsAsc(SongsColumn.playlistPosition),
]),
);
return CoverArtTheme(
coverArt: playlist.coverArt,
child: Scaffold(
body: GradientScrollView(
slivers: [
SliverToBoxAdapter(
child: SongsListHeader(
title: playlist.name,
// subtitle: playlist.albumArtist,
coverArt: playlist.coverArt,
playText: l.resourcesPlaylistActionsPlay,
onPlay: () {},
onMore: () {},
),
),
SongsList(
query: query,
itemBuilder: (context, item, index) => SongListTile(
song: item.song,
coverArt: item.albumCoverArt,
showLeading: true,
onTap: () {},
),
),
],
),
),
);
}
}

View File

@@ -0,0 +1,30 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../state/database.dart';
import '../state/settings.dart';
import '../state/source.dart';
class PreloadScreen extends HookConsumerWidget {
const PreloadScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final initializers = [
ref.watch(databaseInitializer),
ref.watch(activeSourceInitializer),
ref.watch(packageInfoInitializer),
];
if (initializers.every((v) => v.hasValue)) {
Future.delayed(Duration(microseconds: 1)).then((_) {
if (context.mounted) {
context.replace('/');
}
});
}
return Container();
}
}

View File

@@ -0,0 +1,415 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../../l10n/generated/app_localizations.dart';
import '../state/database.dart';
import '../state/source.dart';
const kHorizontalPadding = 18.0;
class SettingsScreen extends HookConsumerWidget {
const SettingsScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final l = AppLocalizations.of(context);
final textTheme = TextTheme.of(context);
return Scaffold(
appBar: AppBar(
title: Text(l.navigationTabsSettings, style: textTheme.headlineLarge),
),
body: ListView(
children: [
_SectionHeader(l.settingsServersName),
const _Sources(),
// _SectionHeader(l.settingsNetworkName),
// const _Network(),
// _SectionHeader(l.settingsAboutName),
// _About(),
],
),
);
}
}
class _Section extends StatelessWidget {
const _Section({
required this.children,
});
final List<Widget> children;
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
...children,
],
);
}
}
class _SectionHeader extends StatelessWidget {
const _SectionHeader(
this.title,
);
final String title;
@override
Widget build(BuildContext context) {
final text = TextTheme.of(context);
return Padding(
padding: EdgeInsetsGeometry.directional(
start: kHorizontalPadding,
end: kHorizontalPadding,
top: 32,
bottom: 8,
),
child: Text(title, style: text.headlineMedium),
);
}
}
// class _Network extends StatelessWidget {
// const _Network();
// @override
// Widget build(BuildContext context) {
// return const _Section(
// children: [
// _OfflineMode(),
// _MaxBitrateWifi(),
// _MaxBitrateMobile(),
// _StreamFormat(),
// ],
// );
// }
// }
// class _About extends HookConsumerWidget {
// _About();
// final _homepage = Uri.parse('https://github.com/austinried/subtracks');
// final _donate = Uri.parse('https://ko-fi.com/austinried');
// @override
// Widget build(BuildContext context, WidgetRef ref) {
// final l = AppLocalizations.of(context);
// final pkg = ref.watch(packageInfoProvider).requireValue;
// return _Section(
// children: [
// ListTile(
// title: const Text('subtracks'),
// subtitle: Text(l.settingsAboutVersion(pkg.version)),
// ),
// ListTile(
// title: Text(l.settingsAboutActionsLicenses),
// // trailing: const Icon(Icons.open_in_new_rounded),
// onTap: () {},
// ),
// ListTile(
// title: Text(l.settingsAboutActionsProjectHomepage),
// subtitle: Text(_homepage.toString()),
// trailing: const Icon(Icons.open_in_new_rounded),
// onTap: () => launchUrl(
// _homepage,
// mode: LaunchMode.externalApplication,
// ),
// ),
// ListTile(
// title: Text(l.settingsAboutActionsSupport),
// subtitle: Text(_donate.toString()),
// trailing: const Icon(Icons.open_in_new_rounded),
// onTap: () => launchUrl(
// _donate,
// mode: LaunchMode.externalApplication,
// ),
// ),
// const SizedBox(height: 12),
// const _ShareLogsButton(),
// ],
// );
// }
// }
// class _ShareLogsButton extends StatelessWidget {
// const _ShareLogsButton();
// @override
// Widget build(BuildContext context) {
// final l = AppLocalizations.of(context);
// return Row(
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// OutlinedButton.icon(
// icon: const Icon(Icons.share),
// label: Text(l.settingsAboutShareLogs),
// onPressed: () async {
// final files = await logFiles();
// if (files.isEmpty) return;
// // ignore: use_build_context_synchronously
// final value = await showDialog<String>(
// context: context,
// builder: (context) => MultipleChoiceDialog<String>(
// title: l.settingsAboutChooseLog,
// current: files.first.path,
// options: files
// .map(
// (e) => MultiChoiceOption.string(
// title: path.basename(e.path),
// option: e.path,
// ),
// )
// .toIList(),
// ),
// );
// if (value == null) return;
// Share.shareXFiles(
// [XFile(value, mimeType: 'text/plain')],
// subject:
// 'Logs from subtracks: ${String.fromCharCodes(
// List.generate(8, (_) => Random().nextInt(26) + 65),
// )}',
// );
// },
// ),
// ],
// );
// }
// }
// class _MaxBitrateWifi extends HookConsumerWidget {
// const _MaxBitrateWifi();
// @override
// Widget build(BuildContext context, WidgetRef ref) {
// final bitrate = ref.watch(
// settingsServiceProvider.select(
// (value) => value.app.maxBitrateWifi,
// ),
// );
// final l = AppLocalizations.of(context);
// return _MaxBitrateOption(
// title: l.settingsNetworkOptionsMaxBitrateWifiTitle,
// bitrate: bitrate,
// onChange: (value) {
// ref.read(settingsServiceProvider.notifier).setMaxBitrateWifi(value);
// },
// );
// }
// }
// class _MaxBitrateMobile extends HookConsumerWidget {
// const _MaxBitrateMobile();
// @override
// Widget build(BuildContext context, WidgetRef ref) {
// final bitrate = ref.watch(
// settingsServiceProvider.select(
// (value) => value.app.maxBitrateMobile,
// ),
// );
// final l = AppLocalizations.of(context);
// return _MaxBitrateOption(
// title: l.settingsNetworkOptionsMaxBitrateMobileTitle,
// bitrate: bitrate,
// onChange: (value) {
// ref.read(settingsServiceProvider.notifier).setMaxBitrateMobile(value);
// },
// );
// }
// }
// class _MaxBitrateOption extends HookConsumerWidget {
// final String title;
// final int bitrate;
// final void Function(int value) onChange;
// const _MaxBitrateOption({
// required this.title,
// required this.bitrate,
// required this.onChange,
// });
// static const options = [0, 24, 32, 64, 96, 128, 192, 256, 320];
// String _bitrateText(AppLocalizations l, int bitrate) {
// return bitrate == 0
// ? l.settingsNetworkValuesUnlimitedKbps
// : l.settingsNetworkValuesKbps(bitrate.toString());
// }
// @override
// Widget build(BuildContext context, WidgetRef ref) {
// final l = AppLocalizations.of(context);
// return ListTile(
// title: Text(title),
// subtitle: Text(_bitrateText(l, bitrate)),
// onTap: () async {
// final value = await showDialog<int>(
// context: context,
// builder: (context) => MultipleChoiceDialog<int>(
// title: title,
// current: bitrate,
// options: options
// .map(
// (opt) => MultiChoiceOption.int(
// title: _bitrateText(l, opt),
// option: opt,
// ),
// )
// .toIList(),
// ),
// );
// if (value != null) {
// onChange(value);
// }
// },
// );
// }
// }
// class _StreamFormat extends HookConsumerWidget {
// const _StreamFormat();
// static const options = ['', 'mp3', 'opus', 'ogg'];
// @override
// Widget build(BuildContext context, WidgetRef ref) {
// final streamFormat = ref.watch(
// settingsServiceProvider.select((value) => value.app.streamFormat),
// );
// final l = AppLocalizations.of(context);
// return ListTile(
// title: Text(l.settingsNetworkOptionsStreamFormat),
// subtitle: Text(
// streamFormat ?? l.settingsNetworkOptionsStreamFormatServerDefault,
// ),
// onTap: () async {
// final value = await showDialog<String>(
// context: context,
// builder: (context) => MultipleChoiceDialog<String>(
// title: l.settingsNetworkOptionsStreamFormat,
// current: streamFormat ?? '',
// options: options
// .map(
// (opt) => MultiChoiceOption.string(
// title: opt == ''
// ? l.settingsNetworkOptionsStreamFormatServerDefault
// : opt,
// option: opt,
// ),
// )
// .toIList(),
// ),
// );
// if (value != null) {
// ref
// .read(settingsServiceProvider.notifier)
// .setStreamFormat(value == '' ? null : value);
// }
// },
// );
// }
// }
// class _OfflineMode extends HookConsumerWidget {
// const _OfflineMode();
// @override
// Widget build(BuildContext context, WidgetRef ref) {
// final offline = ref.watch(offlineModeProvider);
// final l = AppLocalizations.of(context);
// return SwitchListTile(
// value: offline,
// title: Text(l.settingsNetworkOptionsOfflineMode),
// subtitle: offline
// ? Text(l.settingsNetworkOptionsOfflineModeOn)
// : Text(l.settingsNetworkOptionsOfflineModeOff),
// onChanged: (value) {
// ref.read(offlineModeProvider.notifier).setMode(value);
// },
// );
// }
// }
class _Sources extends HookConsumerWidget {
const _Sources();
@override
Widget build(BuildContext context, WidgetRef ref) {
final db = ref.watch(databaseProvider);
final activeSourceId = ref.watch(sourceIdProvider);
final sources = useStream(db.sourcesDao.listSources()).data;
final l = AppLocalizations.of(context);
if (sources == null) {
return Container();
}
return _Section(
children: [
RadioGroup<int>(
groupValue: activeSourceId,
onChanged: (value) {
if (value != null) {
db.sourcesDao.setActiveSource(value);
}
},
child: Column(
children: [
for (final (:source, :subsonicSetting) in sources)
RadioListTile<int>(
value: source.id,
title: Text(source.name),
subtitle: Text(
subsonicSetting.address.toString(),
maxLines: 1,
softWrap: false,
overflow: TextOverflow.fade,
),
secondary: IconButton(
icon: const Icon(Icons.edit_rounded),
onPressed: () {
context.push('/sources/${source.id}');
},
),
),
],
),
),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
OutlinedButton.icon(
icon: const Icon(Icons.add_rounded),
label: Text(l.settingsServersActionsAdd),
onPressed: () {
context.push('/sources/add');
},
),
],
),
],
);
}
}

View File

@@ -0,0 +1,309 @@
import 'package:drift/drift.dart' show Value;
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../../database/dao/sources_dao.dart';
import '../../database/database.dart';
import '../../l10n/generated/app_localizations.dart';
import '../../util/logger.dart';
import '../state/database.dart';
import '../ui/menus.dart';
class SettingsSourceScreen extends HookConsumerWidget {
const SettingsSourceScreen({
super.key,
this.id,
});
final int? id;
@override
Widget build(BuildContext context, WidgetRef ref) {
final db = ref.watch(databaseProvider);
final getSource = useMemoized(
() async => id != null
? (result: await db.sourcesDao.getSource(id!).getSingle())
: await Future.value((result: null)),
[id],
);
final sourceResult = useFuture(getSource).data;
if (sourceResult == null) {
return Scaffold();
}
return _SettingsSourceScreen(source: sourceResult.result);
}
}
class _SettingsSourceScreen extends HookConsumerWidget {
const _SettingsSourceScreen({
required this.source,
});
final SourceSetting? source;
@override
Widget build(BuildContext context, WidgetRef ref) {
final l = AppLocalizations.of(context);
final textTheme = TextTheme.of(context);
final colorScheme = ColorScheme.of(context);
final form = useState(GlobalKey<FormState>()).value;
final isSaving = useState(false);
final isDeleting = useState(false);
final nameController = useTextEditingController(text: source?.source.name);
final addressController = useTextEditingController(
text: source?.subsonicSetting.address.toString(),
);
final usernameController = useTextEditingController(
text: source?.subsonicSetting.username,
);
final passwordController = useTextEditingController(
text: source?.subsonicSetting.password,
);
final forcePlaintextPassword = useState(
!(source?.subsonicSetting.useTokenAuth ?? true),
);
final name = LabeledTextField(
label: l.settingsServersFieldsName,
controller: nameController,
required: true,
);
final address = LabeledTextField(
label: l.settingsServersFieldsAddress,
controller: addressController,
keyboardType: TextInputType.url,
autofillHints: const [AutofillHints.url],
required: true,
validator: (value, label) {
final uri = Uri.tryParse(value ?? '');
if (uri?.isAbsolute != true || uri?.host.isNotEmpty != true) {
return '$label must be a valid URL';
}
return null;
},
);
final username = LabeledTextField(
label: l.settingsServersFieldsUsername,
controller: usernameController,
autofillHints: const [AutofillHints.username],
required: true,
);
final password = LabeledTextField(
label: l.settingsServersFieldsPassword,
controller: passwordController,
autofillHints: const [AutofillHints.password],
obscureText: true,
required: true,
);
final forcePlaintextSwitch = SwitchListTile(
value: forcePlaintextPassword.value,
title: Text(l.settingsServersOptionsForcePlaintextPasswordTitle),
subtitle: forcePlaintextPassword.value
? Text(l.settingsServersOptionsForcePlaintextPasswordDescriptionOn)
: Text(l.settingsServersOptionsForcePlaintextPasswordDescriptionOff),
onChanged: (value) => forcePlaintextPassword.value = value,
);
return PopScope(
canPop: !isSaving.value && !isDeleting.value,
child: Scaffold(
appBar: AppBar(
title: Text(
source == null
? l.settingsServersActionsAdd
: l.settingsServersActionsEdit,
style: textTheme.headlineLarge,
),
),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
if (source != null && source?.source.isActive != true)
FloatingActionButton(
backgroundColor: colorScheme.tertiaryContainer,
foregroundColor: colorScheme.onTertiaryContainer,
onPressed: !isSaving.value && !isDeleting.value
? () async {
try {
isDeleting.value = true;
await ref
.read(databaseProvider)
.sourcesDao
.deleteSource(source!.source.id);
} finally {
isDeleting.value = false;
}
if (context.mounted) {
context.pop();
}
}
: null,
child: isDeleting.value
? SizedBox(
height: 24,
width: 24,
child: CircularProgressIndicator(
color: colorScheme.onTertiaryContainer,
),
)
: const Icon(Icons.delete_forever_rounded),
),
const SizedBox(width: 12),
FloatingActionButton.extended(
heroTag: null,
icon: isSaving.value
? const SizedBox(
height: 24,
width: 24,
child: CircularProgressIndicator(),
)
: const Icon(Icons.save_rounded),
label: Text(l.settingsServersActionsSave),
onPressed: !isSaving.value && !isDeleting.value
? () async {
if (!form.currentState!.validate()) {
return;
}
var error = false;
try {
isSaving.value = true;
if (source != null) {
await ref
.read(databaseProvider)
.sourcesDao
.updateSource(
source!.source.copyWith(
name: nameController.text,
),
source!.subsonicSetting.copyWith(
address: Uri.parse(addressController.text),
username: usernameController.text,
password: passwordController.text,
useTokenAuth: !forcePlaintextPassword.value,
),
);
} else {
await ref
.read(databaseProvider)
.sourcesDao
.createSource(
SourcesCompanion.insert(
name: nameController.text,
),
SubsonicSettingsCompanion.insert(
address: Uri.parse(addressController.text),
username: usernameController.text,
password: passwordController.text,
useTokenAuth: Value(
!forcePlaintextPassword.value,
),
),
);
}
} catch (e, _) {
// showErrorSnackbar(context, e.toString());
// log.severe('Saving source', e, st);
logger.w('fuck');
error = true;
} finally {
isSaving.value = false;
}
if (!error && context.mounted) {
context.pop();
}
}
: null,
),
],
),
body: Form(
key: form,
child: AutofillGroup(
child: ListView(
children: [
name,
address,
username,
password,
const SizedBox(height: 24),
forcePlaintextSwitch,
const FabPadding(),
],
),
),
),
),
);
}
}
class LabeledTextField extends HookConsumerWidget {
const LabeledTextField({
super.key,
required this.label,
required this.controller,
this.obscureText = false,
this.keyboardType,
this.validator,
this.autofillHints,
this.required = false,
});
final String label;
final TextEditingController controller;
final bool obscureText;
final bool required;
final TextInputType? keyboardType;
final Iterable<String>? autofillHints;
final String? Function(String? value, String label)? validator;
@override
Widget build(BuildContext context, WidgetRef ref) {
final textTheme = TextTheme.of(context);
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const SizedBox(height: 32),
Text(label, style: textTheme.titleMedium),
TextFormField(
controller: controller,
obscureText: obscureText,
keyboardType: keyboardType,
autofillHints: autofillHints,
validator: (value) {
if (required) {
if (value == null || value.isEmpty) {
return '$label is required';
}
}
if (validator != null) {
return validator!(value, label);
}
return null;
},
),
],
),
);
}
}

View File

@@ -0,0 +1,49 @@
import 'package:drift/drift.dart' show InsertMode, Value;
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../../database/database.dart';
final databaseInitializer = FutureProvider<SubtracksDatabase>((ref) async {
final db = SubtracksDatabase();
await db.batch((batch) {
batch.insertAll(
db.sources,
[
SourcesCompanion.insert(
id: Value(1),
name: 'test subsonic',
isActive: Value(true),
),
SourcesCompanion.insert(
id: Value(2),
name: 'test navidrome',
isActive: Value(null),
),
],
mode: InsertMode.insertOrIgnore,
);
batch.insertAllOnConflictUpdate(db.subsonicSettings, [
SubsonicSettingsCompanion.insert(
sourceId: Value(1),
address: Uri.parse('http://demo.subsonic.org'),
username: 'guest1',
password: 'guest',
useTokenAuth: Value(true),
),
SubsonicSettingsCompanion.insert(
sourceId: Value(2),
address: Uri.parse('http://10.0.2.2:4533'),
username: 'admin',
password: 'password',
useTokenAuth: Value(true),
),
]);
});
return db;
});
final databaseProvider = Provider<SubtracksDatabase>((ref) {
return ref.watch(databaseInitializer).requireValue;
});

31
lib/app/state/lists.dart Normal file
View File

@@ -0,0 +1,31 @@
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../../database/query.dart';
import 'source.dart';
final albumsQueryProvider = Provider<AlbumsQuery>((ref) {
final sourceId = ref.watch(sourceIdProvider);
return AlbumsQuery(
sourceId: sourceId,
sort: IList([
SortingTerm.albumsDesc(AlbumsColumn.created),
]),
);
});
final songsQueryProvider = Provider<SongsQuery>((ref) {
final sourceId = ref.watch(sourceIdProvider);
return SongsQuery(
sourceId: sourceId,
sort: IList([
SortingTerm.songsAsc(SongsColumn.albumArtist),
SortingTerm.songsAsc(SongsColumn.album),
SortingTerm.songsAsc(SongsColumn.disc),
SortingTerm.songsAsc(SongsColumn.track),
SortingTerm.songsAsc(SongsColumn.title),
]),
);
});

View File

@@ -0,0 +1,13 @@
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../../services/sync_service.dart';
import 'database.dart';
import 'source.dart';
final syncServiceProvider = Provider<SyncService>((ref) {
final db = ref.watch(databaseProvider);
final source = ref.watch(sourceProvider);
final sourceId = ref.watch(sourceIdProvider);
return SyncService(source: source, db: db, sourceId: sourceId);
});

View File

@@ -0,0 +1,10 @@
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:package_info_plus/package_info_plus.dart';
final packageInfoInitializer = FutureProvider<PackageInfo>((ref) {
return PackageInfo.fromPlatform();
});
final packageInfoProvider = Provider<PackageInfo>((ref) {
return ref.watch(packageInfoInitializer).requireValue;
});

41
lib/app/state/source.dart Normal file
View File

@@ -0,0 +1,41 @@
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../../sources/subsonic/client.dart';
import '../../sources/subsonic/source.dart';
import '../../util/http.dart';
import 'database.dart';
final activeSourceInitializer = StreamProvider<(int, SubsonicSource)>((
ref,
) async* {
final db = ref.watch(databaseProvider);
final activeSource = db.sourcesDao.activeSourceId().watchSingle();
await for (final sourceId in activeSource) {
final subsonicSettings = await db.managers.subsonicSettings
.filter((f) => f.sourceId.equals(sourceId))
.getSingle();
yield (
sourceId!,
SubsonicSource(
SubsonicClient(
http: SubtracksHttpClient(),
address: subsonicSettings.address,
username: subsonicSettings.username,
password: subsonicSettings.password,
useTokenAuth: subsonicSettings.useTokenAuth,
),
),
);
}
});
final sourceProvider = Provider<SubsonicSource>((ref) {
return ref.watch(activeSourceInitializer).value!.$2;
});
final sourceIdProvider = Provider<int>((ref) {
return ref.watch(activeSourceInitializer).value!.$1;
});

View File

@@ -0,0 +1,61 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../../util/logger.dart';
import '../state/source.dart';
import '../util/color_scheme.dart';
import 'theme.dart';
class CoverArtTheme extends HookConsumerWidget {
const CoverArtTheme({
super.key,
required this.coverArt,
required this.child,
});
final String? coverArt;
final Widget child;
@override
Widget build(BuildContext context, WidgetRef ref) {
final source = ref.watch(sourceProvider);
final sourceId = ref.watch(sourceIdProvider);
final getColorScheme = useMemoized(
() async {
try {
return await colorSchemefromImageProvider(
brightness: Brightness.dark,
provider: CachedNetworkImageProvider(
coverArt != null
? source.coverArtUri(coverArt!, thumbnail: true).toString()
: 'https://placehold.net/400x400.png',
cacheKey: coverArt != null
? '$sourceId$coverArt${true}'
: 'https://placehold.net/400x400.png',
),
);
} catch (error, stackTrace) {
logger.w(
'Could not create color scheme from image provider',
error: error,
stackTrace: stackTrace,
);
return null;
}
},
[source, sourceId, coverArt],
);
final colorScheme = useFuture(getColorScheme).data;
return Theme(
data: colorScheme == null
? Theme.of(context)
: subtracksTheme(colorScheme),
child: child,
);
}
}

63
lib/app/ui/gradient.dart Normal file
View File

@@ -0,0 +1,63 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:sliver_tools/sliver_tools.dart';
class ThemedGradient extends LinearGradient {
const ThemedGradient({
required super.colors,
super.begin,
super.end,
});
factory ThemedGradient.of(
BuildContext context, {
AlignmentGeometry begin = Alignment.topCenter,
AlignmentGeometry end = Alignment.bottomCenter,
}) {
final colorScheme = Theme.of(context).colorScheme;
return ThemedGradient(
begin: begin,
end: end,
colors: [
colorScheme.primaryContainer,
colorScheme.surface,
],
);
}
}
class GradientScrollView extends HookConsumerWidget {
const GradientScrollView({
super.key,
required this.slivers,
});
final List<Widget> slivers;
@override
Widget build(BuildContext context, WidgetRef ref) {
return CustomScrollView(
slivers: [
SliverStack(
children: [
SliverPositioned.directional(
textDirection: TextDirection.ltr,
start: 0,
end: 0,
top: 0,
child: Ink(
width: double.infinity,
height: MediaQuery.heightOf(context),
decoration: BoxDecoration(
gradient: ThemedGradient.of(context),
),
),
),
MultiSliver(children: slivers),
],
),
],
);
}
}

45
lib/app/ui/images.dart Normal file
View File

@@ -0,0 +1,45 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:material_symbols_icons/symbols.dart';
import '../state/source.dart';
class CoverArtImage extends HookConsumerWidget {
const CoverArtImage({
super.key,
this.coverArt,
this.thumbnail = true,
this.fit = BoxFit.cover,
this.height,
this.width,
});
final String? coverArt;
final bool thumbnail;
final BoxFit fit;
final double? height;
final double? width;
@override
Widget build(BuildContext context, WidgetRef ref) {
final source = ref.watch(sourceProvider);
final sourceId = ref.watch(sourceIdProvider);
final imageUrl = coverArt != null
? source.coverArtUri(coverArt!, thumbnail: thumbnail).toString()
: 'https://placehold.net/400x400.png';
return CachedNetworkImage(
height: height,
width: width,
imageUrl: imageUrl,
cacheKey: '$sourceId$coverArt$thumbnail',
placeholder: (context, url) => Icon(Symbols.cached_rounded),
errorWidget: (context, url, error) => Icon(Icons.error),
fit: fit,
fadeOutDuration: Duration(milliseconds: 100),
fadeInDuration: Duration(milliseconds: 200),
);
}
}

View File

@@ -0,0 +1,78 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import '../../../sources/models.dart';
import '../../hooks/use_on_source.dart';
import '../../hooks/use_paging_controller.dart';
import '../../state/database.dart';
import '../../state/lists.dart';
import '../../state/source.dart';
import '../menus.dart';
import 'items.dart';
const kPageSize = 60;
class AlbumsGrid extends HookConsumerWidget {
const AlbumsGrid({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final db = ref.watch(databaseProvider);
final query = ref.watch(albumsQueryProvider);
final controller = usePagingController<int, Album>(
getNextPageKey: (state) =>
state.lastPageIsEmpty ? null : state.nextIntPageKey,
fetchPage: (pageKey) => db.libraryDao.listAlbums(
query.copyWith(
sourceId: ref.read(sourceIdProvider),
limit: kPageSize,
offset: (pageKey - 1) * kPageSize,
),
),
);
useOnSourceSync(ref, controller.refresh);
useValueChanged(query, (_, _) => controller.refresh());
return PagingListener(
controller: controller,
builder: (context, state, fetchNextPage) {
return SliverPadding(
padding: const EdgeInsets.all(8.0),
sliver: PagedSliverGrid(
state: state,
fetchNextPage: fetchNextPage,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
),
showNoMoreItemsIndicatorAsGridChild: false,
builderDelegate: PagedChildBuilderDelegate<Album>(
noMoreItemsIndicatorBuilder: (context) => FabPadding(),
itemBuilder: (context, item, index) => AlbumGridTile(
album: item,
onTap: () async {
context.push('/albums/${item.id}');
},
),
),
),
);
},
);
}
}
class AlbumsGridFilters extends HookConsumerWidget {
const AlbumsGridFilters({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
return ListView(
children: [],
);
}
}

View File

@@ -0,0 +1,92 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import '../../../database/query.dart';
import '../../../sources/models.dart';
import '../../hooks/use_on_source.dart';
import '../../hooks/use_paging_controller.dart';
import '../../state/database.dart';
import '../../state/source.dart';
import '../menus.dart';
import 'items.dart';
const kPageSize = 30;
class AlbumsList extends HookConsumerWidget {
const AlbumsList({
super.key,
required this.query,
});
final AlbumsQuery query;
@override
Widget build(BuildContext context, WidgetRef ref) {
final db = ref.watch(databaseProvider);
final controller = usePagingController<int, Album>(
getNextPageKey: (state) =>
state.lastPageIsEmpty ? null : state.nextIntPageKey,
fetchPage: (pageKey) => db.libraryDao.listAlbums(
query.copyWith(
sourceId: ref.read(sourceIdProvider),
limit: kPageSize,
offset: (pageKey - 1) * kPageSize,
),
),
);
useOnSourceChange(ref, (_) => controller.refresh());
useOnSourceSync(ref, controller.refresh);
return PagingListener(
controller: controller,
builder: (context, state, fetchNextPage) {
return PagedSliverList(
state: state,
fetchNextPage: fetchNextPage,
builderDelegate: PagedChildBuilderDelegate<Album>(
noMoreItemsIndicatorBuilder: (context) => FabPadding(),
itemBuilder: (context, item, index) {
final tile = AlbumListTile(
album: item,
onTap: () {
context.push('/albums/${item.id}');
},
);
final currentItemYear = item.year;
final previousItemYear = index == 0
? currentItemYear
: controller.items?.elementAtOrNull(index - 1)?.year;
if (index == 0 || currentItemYear != previousItemYear) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(
top: 24,
bottom: 8,
left: 16,
right: 16,
),
child: Text(
item.year?.toString() ?? 'Unknown year',
style: TextTheme.of(context).headlineMedium,
),
),
tile,
],
);
}
return tile;
},
),
);
},
);
}
}

View File

@@ -0,0 +1,66 @@
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import '../../../database/dao/library_dao.dart';
import '../../../database/query.dart';
import '../../hooks/use_on_source.dart';
import '../../hooks/use_paging_controller.dart';
import '../../state/database.dart';
import '../../state/source.dart';
import '../menus.dart';
import 'items.dart';
const kPageSize = 30;
class ArtistsList extends HookConsumerWidget {
const ArtistsList({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final db = ref.watch(databaseProvider);
final controller = usePagingController<int, AristListItem>(
getNextPageKey: (state) =>
state.lastPageIsEmpty ? null : state.nextIntPageKey,
fetchPage: (pageKey) => db.libraryDao.listArtists(
ArtistsQuery(
sourceId: ref.read(sourceIdProvider),
sort: IList([
SortingTerm.artistsAsc(ArtistsColumn.name),
]),
limit: kPageSize,
offset: (pageKey - 1) * kPageSize,
),
),
);
useOnSourceChange(ref, (_) => controller.refresh());
useOnSourceSync(ref, controller.refresh);
return PagingListener(
controller: controller,
builder: (context, state, fetchNextPage) {
return PagedSliverList(
state: state,
fetchNextPage: fetchNextPage,
builderDelegate: PagedChildBuilderDelegate<AristListItem>(
noMoreItemsIndicatorBuilder: (context) => FabPadding(),
itemBuilder: (context, item, index) {
final (:artist, :albumCount) = item;
return ArtistListTile(
artist: artist,
albumCount: albumCount,
onTap: () async {
context.push('/artists/${artist.id}');
},
);
},
),
);
},
);
}
}

View File

@@ -0,0 +1,105 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../images.dart';
class SongsListHeader extends HookConsumerWidget {
const SongsListHeader({
super.key,
required this.title,
this.subtitle,
this.coverArt,
this.playText,
this.onPlay,
this.onMore,
// required this.downloadActions,
});
final String title;
final String? subtitle;
final String? coverArt;
final String? playText;
final void Function()? onPlay;
final FutureOr<void> Function()? onMore;
// final List<DownloadAction> downloadActions;
@override
Widget build(BuildContext context, WidgetRef ref) {
final theme = Theme.of(context);
return SafeArea(
minimum: EdgeInsets.symmetric(horizontal: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(height: 24),
Container(
height: 300,
width: 300,
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
blurRadius: 20,
blurStyle: BlurStyle.normal,
color: Colors.black.withAlpha(100),
offset: Offset.zero,
spreadRadius: 2,
),
],
),
child: CoverArtImage(
thumbnail: false,
coverArt: coverArt,
fit: BoxFit.contain,
),
),
const SizedBox(height: 20),
Column(
children: [
Text(
title,
style: theme.textTheme.headlineMedium,
textAlign: TextAlign.center,
),
if (subtitle != null)
Text(
subtitle!,
style: theme.textTheme.headlineSmall,
textAlign: TextAlign.center,
),
],
),
const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
IconButton(
onPressed: () {},
icon: const Icon(Icons.download_done_rounded),
),
if (onPlay != null)
FilledButton.icon(
onPressed: onPlay,
icon: const Icon(Icons.play_arrow_rounded),
label: Text(
playText ?? '',
// style: theme.textTheme.bodyLarge?.copyWith(
// color: theme.colorScheme.onPrimary,
// ),
),
),
if (onMore != null)
IconButton(
onPressed: onMore,
icon: const Icon(Icons.more_horiz),
),
],
),
const SizedBox(height: 24),
],
),
);
}
}

215
lib/app/ui/lists/items.dart Normal file
View File

@@ -0,0 +1,215 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../../../sources/models.dart';
import '../../util/clip.dart';
import '../images.dart';
class AlbumGridTile extends HookConsumerWidget {
const AlbumGridTile({
super.key,
required this.album,
this.onTap,
});
final Album album;
final void Function()? onTap;
@override
Widget build(BuildContext context, WidgetRef ref) {
return CardTheme(
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(
borderRadius: BorderRadiusGeometry.circular(3),
),
margin: EdgeInsets.all(2),
child: ImageCard(
onTap: onTap,
child: CoverArtImage(
coverArt: album.coverArt,
thumbnail: true,
),
),
);
}
}
class ArtistListTile extends StatelessWidget {
const ArtistListTile({
super.key,
required this.artist,
required this.albumCount,
this.onTap,
});
final Artist artist;
final int albumCount;
final void Function()? onTap;
@override
Widget build(BuildContext context) {
return ListTile(
leading: CircleClip(
child: CoverArtImage(
coverArt: artist.coverArt,
thumbnail: true,
),
),
title: Text(artist.name),
subtitle: Text('$albumCount albums'),
onTap: onTap,
);
}
}
class AlbumListTile extends StatelessWidget {
const AlbumListTile({
super.key,
required this.album,
this.onTap,
});
final Album album;
final void Function()? onTap;
@override
Widget build(BuildContext context) {
final textTheme = TextTheme.of(context);
return InkWell(
onTap: onTap,
child: Padding(
padding: const EdgeInsets.all(12),
child: Row(
children: [
Padding(
padding: const EdgeInsets.only(left: 8, right: 18),
child: RoundedBoxClip(
child: CoverArtImage(
coverArt: album.coverArt,
thumbnail: true,
width: 80,
height: 80,
),
),
),
Flexible(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
album.name,
style: textTheme.bodyLarge?.copyWith(
fontWeight: FontWeight.bold,
),
overflow: TextOverflow.ellipsis,
maxLines: 2,
),
Text(
album.albumArtist ?? 'Unknown album artist',
style: textTheme.bodyMedium,
),
],
),
),
],
),
),
);
}
}
class PlaylistListTile extends StatelessWidget {
const PlaylistListTile({
super.key,
required this.playlist,
this.albumCount,
this.onTap,
});
final Playlist playlist;
final int? albumCount;
final void Function()? onTap;
@override
Widget build(BuildContext context) {
return ListTile(
leading: RoundedBoxClip(
child: CoverArtImage(
coverArt: playlist.coverArt,
thumbnail: true,
),
),
title: Text(playlist.name),
subtitle: Text(playlist.comment ?? ''),
onTap: onTap,
);
}
}
class SongListTile extends StatelessWidget {
const SongListTile({
super.key,
required this.song,
this.coverArt,
this.showLeading = false,
this.onTap,
});
final Song song;
final String? coverArt;
final bool showLeading;
final void Function()? onTap;
@override
Widget build(BuildContext context) {
return ListTile(
leading: showLeading
? RoundedBoxClip(
child: CoverArtImage(
coverArt: coverArt,
thumbnail: true,
),
)
: null,
title: Text(song.title),
subtitle: Text(song.artist ?? ''),
onTap: onTap,
);
}
}
class ImageCard extends StatelessWidget {
const ImageCard({
super.key,
required this.child,
this.onTap,
this.onLongPress,
});
final Widget child;
final void Function()? onTap;
final void Function()? onLongPress;
@override
Widget build(BuildContext context) {
return Card(
child: Stack(
fit: StackFit.passthrough,
alignment: Alignment.center,
children: [
child,
Positioned.fill(
child: Material(
type: MaterialType.transparency,
child: InkWell(
onTap: onTap,
onLongPress: onLongPress,
),
),
),
],
),
);
}
}

View File

@@ -0,0 +1,63 @@
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import '../../../database/query.dart';
import '../../../sources/models.dart';
import '../../hooks/use_on_source.dart';
import '../../hooks/use_paging_controller.dart';
import '../../state/database.dart';
import '../../state/source.dart';
import '../menus.dart';
import 'items.dart';
const kPageSize = 30;
class PlaylistsList extends HookConsumerWidget {
const PlaylistsList({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final db = ref.watch(databaseProvider);
final controller = usePagingController<int, Playlist>(
getNextPageKey: (state) =>
state.lastPageIsEmpty ? null : state.nextIntPageKey,
fetchPage: (pageKey) => db.libraryDao.listPlaylists(
PlaylistsQuery(
sourceId: ref.read(sourceIdProvider),
sort: IList([
SortingTerm.playlistsDesc(PlaylistsColumn.created),
]),
limit: kPageSize,
offset: (pageKey - 1) * kPageSize,
),
),
);
useOnSourceChange(ref, (_) => controller.refresh());
useOnSourceSync(ref, controller.refresh);
return PagingListener(
controller: controller,
builder: (context, state, fetchNextPage) {
return PagedSliverList(
state: state,
fetchNextPage: fetchNextPage,
builderDelegate: PagedChildBuilderDelegate<Playlist>(
noMoreItemsIndicatorBuilder: (context) => FabPadding(),
itemBuilder: (context, item, index) {
return PlaylistListTile(
playlist: item,
onTap: () {
context.push('/playlists/${item.id}');
},
);
},
),
);
},
);
}
}

View File

@@ -0,0 +1,59 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import '../../../database/dao/library_dao.dart';
import '../../../database/query.dart';
import '../../hooks/use_on_source.dart';
import '../../hooks/use_paging_controller.dart';
import '../../state/database.dart';
import '../../state/source.dart';
import '../menus.dart';
const kPageSize = 30;
class SongsList extends HookConsumerWidget {
const SongsList({
super.key,
required this.query,
required this.itemBuilder,
});
final SongsQuery query;
final Widget Function(BuildContext context, SongListItem item, int index)
itemBuilder;
@override
Widget build(BuildContext context, WidgetRef ref) {
final db = ref.watch(databaseProvider);
final controller = usePagingController<int, SongListItem>(
getNextPageKey: (state) =>
state.lastPageIsEmpty ? null : state.nextIntPageKey,
fetchPage: (pageKey) => db.libraryDao.listSongs(
query.copyWith(
sourceId: ref.read(sourceIdProvider),
limit: kPageSize,
offset: (pageKey - 1) * kPageSize,
),
),
);
useOnSourceSync(ref, controller.refresh);
useValueChanged(query, (_, _) => controller.refresh());
return PagingListener(
controller: controller,
builder: (context, state, fetchNextPage) {
return PagedSliverList(
state: state,
fetchNextPage: fetchNextPage,
builderDelegate: PagedChildBuilderDelegate<SongListItem>(
noMoreItemsIndicatorBuilder: (context) => FabPadding(),
itemBuilder: itemBuilder,
),
);
},
);
}
}

76
lib/app/ui/menus.dart Normal file
View File

@@ -0,0 +1,76 @@
import 'package:flutter/material.dart';
import 'package:material_symbols_icons/symbols.dart';
Future<void> showContextMenu({
required BuildContext context,
required WidgetBuilder listBuilder,
}) => showModalBottomSheet(
context: context,
useRootNavigator: true,
isScrollControlled: true,
builder: (context) => DraggableScrollableSheet(
expand: false,
snap: true,
initialChildSize: 0.3,
minChildSize: 0.3,
maxChildSize: 0.4,
builder: (context, scrollController) => PrimaryScrollController(
controller: scrollController,
child: listBuilder(context),
),
),
);
class ContextMenuList extends StatelessWidget {
const ContextMenuList({
super.key,
required this.children,
});
final List<Widget> children;
@override
Widget build(BuildContext context) {
return ListView(
children: children,
);
}
}
class FabFilter extends StatelessWidget {
const FabFilter({
super.key,
required this.listBuilder,
});
final WidgetBuilder listBuilder;
@override
Widget build(BuildContext context) {
return FloatingActionButton(
onPressed: () {
showContextMenu(
context: context,
listBuilder: listBuilder,
);
},
child: Icon(
Symbols.filter_list_rounded,
weight: 500,
opticalSize: 28,
size: 28,
),
);
}
}
class FabPadding extends StatelessWidget {
const FabPadding({
super.key,
});
@override
Widget build(BuildContext context) {
return const SizedBox(height: 86);
}
}

29
lib/app/ui/theme.dart Normal file
View File

@@ -0,0 +1,29 @@
import 'package:flutter/material.dart';
ThemeData subtracksTheme([ColorScheme? colorScheme]) {
final theme = ThemeData.from(
colorScheme:
colorScheme ??
ColorScheme.fromSeed(
seedColor: Colors.purple.shade800,
brightness: Brightness.dark,
),
useMaterial3: true,
);
final text = theme.textTheme.copyWith(
headlineLarge: theme.textTheme.headlineLarge?.copyWith(
fontWeight: FontWeight.w800,
),
headlineMedium: theme.textTheme.headlineMedium?.copyWith(
fontWeight: FontWeight.w700,
),
headlineSmall: theme.textTheme.headlineSmall?.copyWith(
fontWeight: FontWeight.w600,
),
);
return theme.copyWith(
textTheme: text,
);
}

View File

@@ -19,3 +19,21 @@ class CircleClip extends StatelessWidget {
);
}
}
class RoundedBoxClip extends StatelessWidget {
const RoundedBoxClip({
super.key,
required this.child,
});
final Widget child;
@override
Widget build(BuildContext context) {
return ClipRRect(
clipBehavior: Clip.antiAlias,
borderRadius: BorderRadiusGeometry.circular(3),
child: child,
);
}
}

View File

@@ -0,0 +1,431 @@
/// This file is a fork of the built-in [ColorScheme.fromImageProvider] function
/// with the following changes:
///
/// 1. [_extractColorsFromImageProvider] now runs the Quantizer to extract colors
/// in an isolate to prevent jank on the UI thread (especially noticable during
/// transitions).
///
/// 2. [_imageProviderToScaled] has its hard-coded image resize max dimensions
/// to 32x32 pixels.
library;
import 'dart:async';
import 'dart:isolate';
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:material_color_utilities/material_color_utilities.dart';
/// Generate a [ColorScheme] derived from the given `imageProvider`.
///
/// Material Color Utilities extracts the dominant color from the
/// supplied [ImageProvider]. Using this color, a [ColorScheme] is generated
/// with harmonious colors that meet contrast requirements for accessibility.
///
/// If any of the optional color parameters are non-null, they will be
/// used in place of the generated colors for that field in the resulting
/// [ColorScheme]. This allows apps to override specific colors for their
/// needs.
///
/// Given the nature of the algorithm, the most dominant color of the
/// `imageProvider` may not wind up as one of the [ColorScheme] colors.
///
/// The provided image will be scaled down to a maximum size of 112x112 pixels
/// during color extraction.
///
/// {@tool dartpad}
/// This sample shows how to use [ColorScheme.fromImageProvider] to create
/// content-based dynamic color schemes.
///
/// ** See code in examples/api/lib/material/color_scheme/dynamic_content_color.0.dart **
/// {@end-tool}
///
/// See also:
///
/// * [M3 Guidelines: Dynamic color from content](https://m3.material.io/styles/color/dynamic-color/user-generated-color#8af550b9-a19e-4e9f-bb0a-7f611fed5d0f)
/// * <https://pub.dev/packages/dynamic_color>, a package to create
/// [ColorScheme]s based on a platform's implementation of dynamic color.
/// * <https://m3.material.io/styles/color/the-color-system/color-roles>, the
/// Material 3 Color system specification.
/// * <https://pub.dev/packages/material_color_utilities>, the package
/// used to algorithmically determine the dominant color and to generate
/// the [ColorScheme].
Future<ColorScheme> colorSchemefromImageProvider({
required ImageProvider provider,
Brightness brightness = Brightness.light,
DynamicSchemeVariant dynamicSchemeVariant = DynamicSchemeVariant.tonalSpot,
double contrastLevel = 0.0,
Color? primary,
Color? onPrimary,
Color? primaryContainer,
Color? onPrimaryContainer,
Color? primaryFixed,
Color? primaryFixedDim,
Color? onPrimaryFixed,
Color? onPrimaryFixedVariant,
Color? secondary,
Color? onSecondary,
Color? secondaryContainer,
Color? onSecondaryContainer,
Color? secondaryFixed,
Color? secondaryFixedDim,
Color? onSecondaryFixed,
Color? onSecondaryFixedVariant,
Color? tertiary,
Color? onTertiary,
Color? tertiaryContainer,
Color? onTertiaryContainer,
Color? tertiaryFixed,
Color? tertiaryFixedDim,
Color? onTertiaryFixed,
Color? onTertiaryFixedVariant,
Color? error,
Color? onError,
Color? errorContainer,
Color? onErrorContainer,
Color? outline,
Color? outlineVariant,
Color? surface,
Color? onSurface,
Color? surfaceDim,
Color? surfaceBright,
Color? surfaceContainerLowest,
Color? surfaceContainerLow,
Color? surfaceContainer,
Color? surfaceContainerHigh,
Color? surfaceContainerHighest,
Color? onSurfaceVariant,
Color? inverseSurface,
Color? onInverseSurface,
Color? inversePrimary,
Color? shadow,
Color? scrim,
Color? surfaceTint,
@Deprecated(
'Use surface instead. '
'This feature was deprecated after v3.18.0-0.1.pre.',
)
Color? background,
@Deprecated(
'Use onSurface instead. '
'This feature was deprecated after v3.18.0-0.1.pre.',
)
Color? onBackground,
@Deprecated(
'Use surfaceContainerHighest instead. '
'This feature was deprecated after v3.18.0-0.1.pre.',
)
Color? surfaceVariant,
}) async {
// Extract dominant colors from image.
final QuantizerResult quantizerResult = await _extractColorsFromImageProvider(
provider,
);
final Map<int, int> colorToCount = quantizerResult.colorToCount.map(
(int key, int value) => MapEntry<int, int>(_getArgbFromAbgr(key), value),
);
// Score colors for color scheme suitability.
final List<int> scoredResults = Score.score(colorToCount, desired: 1);
final ui.Color baseColor = Color(scoredResults.first);
final DynamicScheme scheme = _buildDynamicScheme(
brightness,
baseColor,
dynamicSchemeVariant,
contrastLevel,
);
return ColorScheme(
primary: primary ?? Color(MaterialDynamicColors.primary.getArgb(scheme)),
onPrimary:
onPrimary ?? Color(MaterialDynamicColors.onPrimary.getArgb(scheme)),
primaryContainer:
primaryContainer ??
Color(MaterialDynamicColors.primaryContainer.getArgb(scheme)),
onPrimaryContainer:
onPrimaryContainer ??
Color(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)),
primaryFixed:
primaryFixed ??
Color(MaterialDynamicColors.primaryFixed.getArgb(scheme)),
primaryFixedDim:
primaryFixedDim ??
Color(MaterialDynamicColors.primaryFixedDim.getArgb(scheme)),
onPrimaryFixed:
onPrimaryFixed ??
Color(MaterialDynamicColors.onPrimaryFixed.getArgb(scheme)),
onPrimaryFixedVariant:
onPrimaryFixedVariant ??
Color(MaterialDynamicColors.onPrimaryFixedVariant.getArgb(scheme)),
secondary:
secondary ?? Color(MaterialDynamicColors.secondary.getArgb(scheme)),
onSecondary:
onSecondary ?? Color(MaterialDynamicColors.onSecondary.getArgb(scheme)),
secondaryContainer:
secondaryContainer ??
Color(MaterialDynamicColors.secondaryContainer.getArgb(scheme)),
onSecondaryContainer:
onSecondaryContainer ??
Color(MaterialDynamicColors.onSecondaryContainer.getArgb(scheme)),
secondaryFixed:
secondaryFixed ??
Color(MaterialDynamicColors.secondaryFixed.getArgb(scheme)),
secondaryFixedDim:
secondaryFixedDim ??
Color(MaterialDynamicColors.secondaryFixedDim.getArgb(scheme)),
onSecondaryFixed:
onSecondaryFixed ??
Color(MaterialDynamicColors.onSecondaryFixed.getArgb(scheme)),
onSecondaryFixedVariant:
onSecondaryFixedVariant ??
Color(MaterialDynamicColors.onSecondaryFixedVariant.getArgb(scheme)),
tertiary: tertiary ?? Color(MaterialDynamicColors.tertiary.getArgb(scheme)),
onTertiary:
onTertiary ?? Color(MaterialDynamicColors.onTertiary.getArgb(scheme)),
tertiaryContainer:
tertiaryContainer ??
Color(MaterialDynamicColors.tertiaryContainer.getArgb(scheme)),
onTertiaryContainer:
onTertiaryContainer ??
Color(MaterialDynamicColors.onTertiaryContainer.getArgb(scheme)),
tertiaryFixed:
tertiaryFixed ??
Color(MaterialDynamicColors.tertiaryFixed.getArgb(scheme)),
tertiaryFixedDim:
tertiaryFixedDim ??
Color(MaterialDynamicColors.tertiaryFixedDim.getArgb(scheme)),
onTertiaryFixed:
onTertiaryFixed ??
Color(MaterialDynamicColors.onTertiaryFixed.getArgb(scheme)),
onTertiaryFixedVariant:
onTertiaryFixedVariant ??
Color(MaterialDynamicColors.onTertiaryFixedVariant.getArgb(scheme)),
error: error ?? Color(MaterialDynamicColors.error.getArgb(scheme)),
onError: onError ?? Color(MaterialDynamicColors.onError.getArgb(scheme)),
errorContainer:
errorContainer ??
Color(MaterialDynamicColors.errorContainer.getArgb(scheme)),
onErrorContainer:
onErrorContainer ??
Color(MaterialDynamicColors.onErrorContainer.getArgb(scheme)),
outline: outline ?? Color(MaterialDynamicColors.outline.getArgb(scheme)),
outlineVariant:
outlineVariant ??
Color(MaterialDynamicColors.outlineVariant.getArgb(scheme)),
surface: surface ?? Color(MaterialDynamicColors.surface.getArgb(scheme)),
surfaceDim:
surfaceDim ?? Color(MaterialDynamicColors.surfaceDim.getArgb(scheme)),
surfaceBright:
surfaceBright ??
Color(MaterialDynamicColors.surfaceBright.getArgb(scheme)),
surfaceContainerLowest:
surfaceContainerLowest ??
Color(MaterialDynamicColors.surfaceContainerLowest.getArgb(scheme)),
surfaceContainerLow:
surfaceContainerLow ??
Color(MaterialDynamicColors.surfaceContainerLow.getArgb(scheme)),
surfaceContainer:
surfaceContainer ??
Color(MaterialDynamicColors.surfaceContainer.getArgb(scheme)),
surfaceContainerHigh:
surfaceContainerHigh ??
Color(MaterialDynamicColors.surfaceContainerHigh.getArgb(scheme)),
surfaceContainerHighest:
surfaceContainerHighest ??
Color(MaterialDynamicColors.surfaceContainerHighest.getArgb(scheme)),
onSurface:
onSurface ?? Color(MaterialDynamicColors.onSurface.getArgb(scheme)),
onSurfaceVariant:
onSurfaceVariant ??
Color(MaterialDynamicColors.onSurfaceVariant.getArgb(scheme)),
inverseSurface:
inverseSurface ??
Color(MaterialDynamicColors.inverseSurface.getArgb(scheme)),
onInverseSurface:
onInverseSurface ??
Color(MaterialDynamicColors.inverseOnSurface.getArgb(scheme)),
inversePrimary:
inversePrimary ??
Color(MaterialDynamicColors.inversePrimary.getArgb(scheme)),
shadow: shadow ?? Color(MaterialDynamicColors.shadow.getArgb(scheme)),
scrim: scrim ?? Color(MaterialDynamicColors.scrim.getArgb(scheme)),
surfaceTint:
surfaceTint ?? Color(MaterialDynamicColors.primary.getArgb(scheme)),
brightness: brightness,
// DEPRECATED (newest deprecations at the bottom)
// ignore: deprecated_member_use
background:
background ?? Color(MaterialDynamicColors.background.getArgb(scheme)),
// ignore: deprecated_member_use
onBackground:
onBackground ??
Color(MaterialDynamicColors.onBackground.getArgb(scheme)),
// ignore: deprecated_member_use
surfaceVariant:
surfaceVariant ??
Color(MaterialDynamicColors.surfaceVariant.getArgb(scheme)),
);
}
// ColorScheme.fromImageProvider() utilities.
/// Extracts bytes from an [ImageProvider] and returns a [QuantizerResult]
/// containing the most dominant colors.
Future<QuantizerResult> _extractColorsFromImageProvider(
ImageProvider imageProvider,
) async {
final ui.Image scaledImage = await _imageProviderToScaled(imageProvider);
final ByteData? imageBytes = await scaledImage.toByteData();
return Isolate.run(
() => QuantizerCelebi().quantize(
imageBytes!.buffer.asUint32List(),
128,
returnInputPixelToClusterPixel: true,
),
);
}
/// Scale image size down to reduce computation time of color extraction.
Future<ui.Image> _imageProviderToScaled(ImageProvider imageProvider) async {
const double maxDimension = 32.0;
final ImageStream stream = imageProvider.resolve(
const ImageConfiguration(size: Size(maxDimension, maxDimension)),
);
final Completer<ui.Image> imageCompleter = Completer<ui.Image>();
late ImageStreamListener listener;
late ui.Image scaledImage;
Timer? loadFailureTimeout;
listener = ImageStreamListener(
(ImageInfo info, bool sync) async {
loadFailureTimeout?.cancel();
stream.removeListener(listener);
final ui.Image image = info.image;
final int width = image.width;
final int height = image.height;
double paintWidth = width.toDouble();
double paintHeight = height.toDouble();
assert(width > 0 && height > 0);
final bool rescale = width > maxDimension || height > maxDimension;
if (rescale) {
paintWidth = (width > height)
? maxDimension
: (maxDimension / height) * width;
paintHeight = (height > width)
? maxDimension
: (maxDimension / width) * height;
}
final ui.PictureRecorder pictureRecorder = ui.PictureRecorder();
final Canvas canvas = Canvas(pictureRecorder);
paintImage(
canvas: canvas,
rect: Rect.fromLTRB(0, 0, paintWidth, paintHeight),
image: image,
filterQuality: FilterQuality.none,
);
final ui.Picture picture = pictureRecorder.endRecording();
scaledImage = await picture.toImage(
paintWidth.toInt(),
paintHeight.toInt(),
);
imageCompleter.complete(info.image);
},
onError: (Object exception, StackTrace? stackTrace) {
loadFailureTimeout?.cancel();
stream.removeListener(listener);
imageCompleter.completeError(
Exception('Failed to render image: $exception'),
stackTrace,
);
},
);
loadFailureTimeout = Timer(const Duration(seconds: 5), () {
stream.removeListener(listener);
imageCompleter.completeError(
TimeoutException('Timeout occurred trying to load image'),
);
});
stream.addListener(listener);
await imageCompleter.future;
return scaledImage;
}
/// Converts AABBGGRR color int to AARRGGBB format.
int _getArgbFromAbgr(int abgr) {
const int exceptRMask = 0xFF00FFFF;
const int onlyRMask = ~exceptRMask;
const int exceptBMask = 0xFFFFFF00;
const int onlyBMask = ~exceptBMask;
final int r = (abgr & onlyRMask) >> 16;
final int b = abgr & onlyBMask;
return (abgr & exceptRMask & exceptBMask) | (b << 16) | r;
}
DynamicScheme _buildDynamicScheme(
Brightness brightness,
Color seedColor,
DynamicSchemeVariant schemeVariant,
double contrastLevel,
) {
assert(
contrastLevel >= -1.0 && contrastLevel <= 1.0,
'contrastLevel must be between -1.0 and 1.0 inclusive.',
);
final bool isDark = brightness == Brightness.dark;
// ignore: deprecated_member_use
final Hct sourceColor = Hct.fromInt(seedColor.value);
return switch (schemeVariant) {
DynamicSchemeVariant.tonalSpot => SchemeTonalSpot(
sourceColorHct: sourceColor,
isDark: isDark,
contrastLevel: contrastLevel,
),
DynamicSchemeVariant.fidelity => SchemeFidelity(
sourceColorHct: sourceColor,
isDark: isDark,
contrastLevel: contrastLevel,
),
DynamicSchemeVariant.content => SchemeContent(
sourceColorHct: sourceColor,
isDark: isDark,
contrastLevel: contrastLevel,
),
DynamicSchemeVariant.monochrome => SchemeMonochrome(
sourceColorHct: sourceColor,
isDark: isDark,
contrastLevel: contrastLevel,
),
DynamicSchemeVariant.neutral => SchemeNeutral(
sourceColorHct: sourceColor,
isDark: isDark,
contrastLevel: contrastLevel,
),
DynamicSchemeVariant.vibrant => SchemeVibrant(
sourceColorHct: sourceColor,
isDark: isDark,
contrastLevel: contrastLevel,
),
DynamicSchemeVariant.expressive => SchemeExpressive(
sourceColorHct: sourceColor,
isDark: isDark,
contrastLevel: contrastLevel,
),
DynamicSchemeVariant.rainbow => SchemeRainbow(
sourceColorHct: sourceColor,
isDark: isDark,
contrastLevel: contrastLevel,
),
DynamicSchemeVariant.fruitSalad => SchemeFruitSalad(
sourceColorHct: sourceColor,
isDark: isDark,
contrastLevel: contrastLevel,
),
};
}

View File

@@ -119,14 +119,14 @@ class CustomScrollController extends ScrollController {
ScrollContext context,
ScrollPosition? oldPosition,
) {
debugPrint('$debugLabel-createScrollPosition: $isActive');
// debugPrint('$debugLabel-createScrollPosition: $isActive');
return parent.createScrollPosition(physics, context, oldPosition);
}
@override
void attach(ScrollPosition position) {
debugPrint('$debugLabel-attach: $isActive');
// debugPrint('$debugLabel-attach: $isActive');
super.attach(position);
if (isActive && !parent.positions.contains(position)) {
@@ -136,7 +136,7 @@ class CustomScrollController extends ScrollController {
@override
void detach(ScrollPosition position) {
debugPrint('$debugLabel-detach: $isActive');
// debugPrint('$debugLabel-detach: $isActive');
if (parent.positions.contains(position)) {
parent.detach(position);
@@ -146,7 +146,7 @@ class CustomScrollController extends ScrollController {
}
void forceDetach() {
debugPrint('$debugLabel-forceDetach: $isActive');
// debugPrint('$debugLabel-forceDetach: $isActive');
for (final position in positions) {
if (parent.positions.contains(position)) {
@@ -156,7 +156,7 @@ class CustomScrollController extends ScrollController {
}
void forceAttach() {
debugPrint('$debugLabel-forceAttach: $isActive');
// debugPrint('$debugLabel-forceAttach: $isActive');
for (final position in positions) {
if (!parent.positions.contains(position)) {
@@ -167,7 +167,7 @@ class CustomScrollController extends ScrollController {
@override
void dispose() {
debugPrint('$debugLabel-dispose: $isActive');
// debugPrint('$debugLabel-dispose: $isActive');
forceDetach();
super.dispose();

View File

@@ -0,0 +1,51 @@
import 'dart:convert';
import 'package:drift/drift.dart';
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
class DurationSecondsConverter extends TypeConverter<Duration, int> {
const DurationSecondsConverter();
@override
Duration fromSql(int fromDb) => Duration(seconds: fromDb);
@override
int toSql(Duration value) => value.inSeconds;
}
class UriConverter extends TypeConverter<Uri, String> {
const UriConverter();
@override
Uri fromSql(String fromDb) => Uri.parse(fromDb);
@override
String toSql(Uri value) => value.toString();
}
// class ListQueryConverter extends TypeConverter<ListQuery, String> {
// const ListQueryConverter();
// @override
// ListQuery fromSql(String fromDb) => ListQuery.fromJson(jsonDecode(fromDb));
// @override
// String toSql(ListQuery value) => jsonEncode(value.toJson());
// }
class IListIntConverter extends TypeConverter<IList<int>, String> {
const IListIntConverter();
@override
IList<int> fromSql(String fromDb) {
return IList<int>.fromJson(
jsonDecode(fromDb),
(item) => int.parse(item as String),
);
}
@override
String toSql(IList<int> value) {
return jsonEncode(value.toJson((e) => jsonEncode(e)));
}
}

View File

@@ -0,0 +1,249 @@
import 'package:drift/drift.dart';
import '../../sources/models.dart' as models;
import '../database.dart';
import '../query.dart';
part 'library_dao.g.dart';
typedef AristListItem = ({
models.Artist artist,
int albumCount,
});
typedef SongListItem = ({
models.Song song,
String? albumCoverArt,
});
extension on SortDirection {
OrderingMode toMode() => switch (this) {
SortDirection.asc => OrderingMode.asc,
SortDirection.desc => OrderingMode.desc,
};
}
@DriftAccessor(include: {'../tables.drift'})
class LibraryDao extends DatabaseAccessor<SubtracksDatabase>
with _$LibraryDaoMixin {
LibraryDao(super.db);
Future<List<models.Album>> listAlbums(AlbumsQuery q) {
final query = albums.select()
..where((albums) {
var filter = albums.sourceId.equals(q.sourceId);
for (final queryFilter in q.filter) {
filter &= switch (queryFilter) {
AlbumsFilterArtistId(:final artistId) => albums.artistId.equals(
artistId,
),
AlbumsFilterYearEquals(:final year) => albums.year.equals(year),
_ => CustomExpression(''),
};
}
return filter;
})
..orderBy(
q.sort
.map(
(sort) =>
(albums) => OrderingTerm(
expression: switch (sort.by) {
AlbumsColumn.name => albums.name,
AlbumsColumn.created => albums.created,
AlbumsColumn.year => albums.year,
AlbumsColumn.starred => albums.starred,
},
mode: sort.dir.toMode(),
),
)
.toList(),
);
_limitQuery(query: query, limit: q.limit, offset: q.offset);
return query.get();
}
Future<List<AristListItem>> listArtists(ArtistsQuery q) {
final albumCount = albums.id.count();
var filter =
artists.sourceId.equals(q.sourceId) &
albums.sourceId.equals(q.sourceId);
for (final queryFilter in q.filter) {
filter &= switch (queryFilter) {
ArtistsFilterStarred(:final starred) =>
starred ? artists.starred.isNotNull() : artists.starred.isNull(),
ArtistsFilterNameSearch() => CustomExpression(''),
_ => CustomExpression(''),
};
}
final query =
artists.select().join([
leftOuterJoin(
albums,
albums.artistId.equalsExp(artists.id),
),
])
..addColumns([albumCount])
..where(filter)
..groupBy([artists.sourceId, artists.id])
..orderBy(
q.sort
.map(
(sort) => OrderingTerm(
expression: switch (sort.by) {
ArtistsColumn.name => artists.name,
ArtistsColumn.starred => artists.starred,
ArtistsColumn.albumCount => albumCount,
},
mode: sort.dir.toMode(),
),
)
.toList(),
);
_limitQuery(query: query, limit: q.limit, offset: q.offset);
return query
.map(
(row) => (
artist: row.readTable(artists),
albumCount: row.read(albumCount) ?? 0,
),
)
.get();
}
Future<List<SongListItem>> listSongs(SongsQuery q) {
var joinPlaylistSongs = false;
var filter = songs.sourceId.equals(q.sourceId);
for (final queryFilter in q.filter) {
switch (queryFilter) {
case SongsFilterAlbumId(:final albumId):
filter &= songs.albumId.equals(albumId);
case SongsFilterPlaylistId(:final playlistId):
joinPlaylistSongs = true;
filter &= playlistSongs.playlistId.equals(playlistId);
}
}
final query =
songs.select().join([
leftOuterJoin(
albums,
albums.id.equalsExp(songs.albumId) &
albums.sourceId.equals(q.sourceId),
),
if (joinPlaylistSongs)
leftOuterJoin(
playlistSongs,
playlistSongs.sourceId.equals(q.sourceId) &
playlistSongs.songId.equalsExp(songs.id),
),
])
..addColumns([
albums.coverArt,
])
..where(filter)
..orderBy(
q.sort
.map(
(sort) => OrderingTerm(
expression: switch (sort.by) {
SongsColumn.title => songs.title,
SongsColumn.starred => songs.starred,
SongsColumn.disc => songs.disc,
SongsColumn.track => songs.track,
SongsColumn.album => songs.album,
SongsColumn.artist => songs.artist,
SongsColumn.albumArtist => albums.albumArtist,
SongsColumn.playlistPosition => playlistSongs.position,
},
mode: sort.dir.toMode(),
),
)
.toList(),
);
_limitQuery(query: query, limit: q.limit, offset: q.offset);
return query
.map(
(row) => (
song: row.readTable(songs),
albumCoverArt: row.read(albums.coverArt),
),
)
.get();
}
Future<List<models.Playlist>> listPlaylists(PlaylistsQuery q) {
final query = playlists.select()
..where((playlists) {
var filter = playlists.sourceId.equals(q.sourceId);
for (final queryFilter in q.filter) {
filter &= switch (queryFilter) {
PlaylistsFilterPublic(:final public) => playlists.public.equals(
public,
),
PlaylistsFilterNameSearch() => CustomExpression(''),
_ => CustomExpression(''),
};
}
return filter;
})
..orderBy(
q.sort
.map(
(sort) =>
(albums) => OrderingTerm(
expression: switch (sort.by) {
PlaylistsColumn.name => playlists.name,
PlaylistsColumn.created => playlists.created,
},
mode: sort.dir.toMode(),
),
)
.toList(),
);
_limitQuery(query: query, limit: q.limit, offset: q.offset);
return query.get();
}
Selectable<models.Album> getAlbum(int sourceId, String id) {
return db.managers.albums.filter(
(f) => f.sourceId.equals(sourceId) & f.id.equals(id),
);
}
Selectable<models.Artist> getArtist(int sourceId, String id) {
return db.managers.artists.filter(
(f) => f.sourceId.equals(sourceId) & f.id.equals(id),
);
}
Selectable<models.Playlist> getPlaylist(int sourceId, String id) {
return db.managers.playlists.filter(
(f) => f.sourceId.equals(sourceId) & f.id.equals(id),
);
}
void _limitQuery({
required LimitContainerMixin query,
required int? limit,
required int? offset,
}) {
if (limit != null) {
query.limit(limit, offset: offset);
}
}
}

View File

@@ -0,0 +1,14 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'library_dao.dart';
// ignore_for_file: type=lint
mixin _$LibraryDaoMixin on DatabaseAccessor<SubtracksDatabase> {
Sources get sources => attachedDatabase.sources;
SubsonicSettings get subsonicSettings => attachedDatabase.subsonicSettings;
Artists get artists => attachedDatabase.artists;
Albums get albums => attachedDatabase.albums;
Playlists get playlists => attachedDatabase.playlists;
PlaylistSongs get playlistSongs => attachedDatabase.playlistSongs;
Songs get songs => attachedDatabase.songs;
}

View File

@@ -0,0 +1,87 @@
import 'package:drift/drift.dart';
import '../database.dart';
part 'sources_dao.g.dart';
typedef SourceSetting = ({Source source, SubsonicSetting subsonicSetting});
@DriftAccessor(include: {'../tables.drift'})
class SourcesDao extends DatabaseAccessor<SubtracksDatabase>
with _$SourcesDaoMixin {
SourcesDao(super.db);
Selectable<int?> activeSourceId() {
return (selectOnly(sources)
..addColumns([sources.id])
..where(sources.isActive.equals(true)))
.map((row) => row.read(sources.id));
}
Stream<List<SourceSetting>> listSources() {
final query = select(sources).join([
innerJoin(
subsonicSettings,
sources.id.equalsExp(subsonicSettings.sourceId),
),
]);
return query
.map(
(row) => (
source: row.readTable(sources),
subsonicSetting: row.readTable(subsonicSettings),
),
)
.watch();
}
Selectable<SourceSetting> getSource(int id) {
final query = select(sources).join([
innerJoin(
subsonicSettings,
sources.id.equalsExp(subsonicSettings.sourceId),
),
])..where(sources.id.equals(id));
return query.map(
(row) => (
source: row.readTable(sources),
subsonicSetting: row.readTable(subsonicSettings),
),
);
}
Future<void> deleteSource(int id) async {
await sources.deleteWhere((f) => f.id.equals(id));
}
Future<void> updateSource(Source source, SubsonicSetting subsonic) async {
await db.transaction(() async {
await sources.update().replace(source);
await subsonicSettings.update().replace(subsonic);
});
}
Future<void> createSource(
SourcesCompanion source,
SubsonicSettingsCompanion subsonic,
) async {
await db.transaction(() async {
final sourceId = await sources.insertOnConflictUpdate(source);
await subsonicSettings.insertOnConflictUpdate(
subsonic.copyWith(sourceId: Value(sourceId)),
);
});
}
Future<void> setActiveSource(int id) async {
await transaction(() async {
await db.managers.sources.update((o) => o(isActive: Value(null)));
await db.managers.sources
.filter((f) => f.id.equals(id))
.update((o) => o(isActive: Value(true)));
});
}
}

View File

@@ -0,0 +1,14 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'sources_dao.dart';
// ignore_for_file: type=lint
mixin _$SourcesDaoMixin on DatabaseAccessor<SubtracksDatabase> {
Sources get sources => attachedDatabase.sources;
SubsonicSettings get subsonicSettings => attachedDatabase.subsonicSettings;
Artists get artists => attachedDatabase.artists;
Albums get albums => attachedDatabase.albums;
Playlists get playlists => attachedDatabase.playlists;
PlaylistSongs get playlistSongs => attachedDatabase.playlistSongs;
Songs get songs => attachedDatabase.songs;
}

117
lib/database/database.dart Normal file
View File

@@ -0,0 +1,117 @@
import 'package:drift/drift.dart';
import 'package:drift_flutter/drift_flutter.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';
import '../sources/models.dart' as models;
import 'converters.dart';
import 'dao/library_dao.dart';
import 'dao/sources_dao.dart';
import 'log_interceptor.dart';
part 'database.g.dart';
// don't exceed SQLITE_MAX_VARIABLE_NUMBER (32766 for version >= 3.32.0)
// https://www.sqlite.org/limits.html
const kSqliteMaxVariableNumber = 32766;
@DriftDatabase(
include: {'tables.drift'},
daos: [
SourcesDao,
LibraryDao,
],
)
class SubtracksDatabase extends _$SubtracksDatabase {
SubtracksDatabase([QueryExecutor? executor])
: super(executor ?? _openConnection());
static QueryExecutor _openConnection() {
return driftDatabase(
name: 'subtracks_database',
native: DriftNativeOptions(
databasePath: () async {
final directory = await getApplicationSupportDirectory();
return path.join(directory.absolute.path, 'subtracks.sqlite');
},
),
).interceptWith(LogInterceptor());
}
@override
int get schemaVersion => 1;
@override
MigrationStrategy get migration {
return MigrationStrategy(
beforeOpen: (details) async {
await customStatement('PRAGMA foreign_keys = ON');
},
);
}
}
extension ArtistToDb on models.Artist {
ArtistsCompanion toDb(int sourceId) => ArtistsCompanion.insert(
sourceId: sourceId,
id: id,
name: name,
starred: Value(starred),
coverArt: Value(coverArt),
);
}
extension AlbumToDb on models.Album {
AlbumsCompanion toDb(int sourceId) => AlbumsCompanion.insert(
sourceId: sourceId,
id: id,
artistId: Value(artistId),
name: name,
albumArtist: Value(albumArtist),
created: created,
coverArt: Value(coverArt),
genre: Value(genre),
year: Value(year),
starred: Value(starred),
frequentRank: Value(frequentRank),
recentRank: Value(recentRank),
);
}
extension SongToDb on models.Song {
SongsCompanion toDb(int sourceId) => SongsCompanion.insert(
sourceId: sourceId,
id: id,
albumId: Value(albumId),
artistId: Value(artistId),
title: title,
album: Value(album),
artist: Value(artist),
duration: Value(duration),
track: Value(track),
disc: Value(disc),
starred: Value(starred),
genre: Value(genre),
);
}
extension PlaylistToDb on models.Playlist {
PlaylistsCompanion toDb(int sourceId) => PlaylistsCompanion.insert(
sourceId: sourceId,
id: id,
name: name,
comment: Value(comment),
coverArt: Value(coverArt),
created: created,
changed: changed,
);
}
extension PlaylistSongToDb on models.PlaylistSong {
PlaylistSongsCompanion toDb(int sourceId) => PlaylistSongsCompanion.insert(
sourceId: sourceId,
playlistId: playlistId,
songId: songId,
position: position,
);
}

4243
lib/database/database.g.dart Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,120 @@
import 'dart:async';
import 'package:drift/drift.dart';
import 'package:logger/logger.dart';
import '../util/logger.dart';
/// https://drift.simonbinder.eu/examples/tracing/
class LogInterceptor extends QueryInterceptor {
Future<T> _run<T>(
String description,
FutureOr<T> Function() operation,
) async {
final trace = logger.level >= Level.trace;
final stopwatch = trace ? (Stopwatch()..start()) : null;
logger.t('Running $description');
try {
final result = await operation();
if (trace) {
logger.t(' => succeeded after ${stopwatch!.elapsedMilliseconds}ms');
}
return result;
} on Object catch (e, st) {
if (trace) {
logger.t(' => failed after ${stopwatch!.elapsedMilliseconds}ms');
}
logger.e('Query failed', error: e, stackTrace: st);
rethrow;
}
}
@override
TransactionExecutor beginTransaction(QueryExecutor parent) {
logger.t('begin');
return super.beginTransaction(parent);
}
@override
Future<void> commitTransaction(TransactionExecutor inner) {
return _run('commit', () => inner.send());
}
@override
Future<void> rollbackTransaction(TransactionExecutor inner) {
return _run('rollback', () => inner.rollback());
}
@override
Future<void> runBatched(
QueryExecutor executor,
BatchedStatements statements,
) {
return _run(
'batch with $statements',
() => executor.runBatched(statements),
);
}
@override
Future<int> runInsert(
QueryExecutor executor,
String statement,
List<Object?> args,
) {
return _run(
'$statement with $args',
() => executor.runInsert(statement, args),
);
}
@override
Future<int> runUpdate(
QueryExecutor executor,
String statement,
List<Object?> args,
) {
return _run(
'$statement with $args',
() => executor.runUpdate(statement, args),
);
}
@override
Future<int> runDelete(
QueryExecutor executor,
String statement,
List<Object?> args,
) {
return _run(
'$statement with $args',
() => executor.runDelete(statement, args),
);
}
@override
Future<void> runCustom(
QueryExecutor executor,
String statement,
List<Object?> args,
) {
return _run(
'$statement with $args',
() => executor.runCustom(statement, args),
);
}
@override
Future<List<Map<String, Object?>>> runSelect(
QueryExecutor executor,
String statement,
List<Object?> args,
) {
return _run(
'$statement with $args',
() => executor.runSelect(statement, args),
);
}
}

191
lib/database/query.dart Normal file
View File

@@ -0,0 +1,191 @@
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'query.freezed.dart';
part 'query.g.dart';
enum SortDirection {
asc,
desc,
}
enum AlbumsColumn {
name,
created,
year,
starred,
}
enum ArtistsColumn {
name,
starred,
albumCount,
}
enum SongsColumn {
title,
starred,
disc,
track,
album,
artist,
albumArtist,
playlistPosition,
}
enum PlaylistsColumn {
name,
created,
}
@freezed
abstract class SortingTerm with _$SortingTerm {
const factory SortingTerm.albums({
required SortDirection dir,
required AlbumsColumn by,
}) = AlbumsSortingTerm;
static AlbumsSortingTerm albumsAsc(AlbumsColumn by) {
return AlbumsSortingTerm(dir: SortDirection.asc, by: by);
}
static AlbumsSortingTerm albumsDesc(AlbumsColumn by) {
return AlbumsSortingTerm(dir: SortDirection.desc, by: by);
}
const factory SortingTerm.artists({
required SortDirection dir,
required ArtistsColumn by,
}) = ArtistsSortingTerm;
static ArtistsSortingTerm artistsAsc(ArtistsColumn by) {
return ArtistsSortingTerm(dir: SortDirection.asc, by: by);
}
static ArtistsSortingTerm artistsDesc(ArtistsColumn by) {
return ArtistsSortingTerm(dir: SortDirection.desc, by: by);
}
const factory SortingTerm.songs({
required SortDirection dir,
required SongsColumn by,
}) = SongsSortingTerm;
static SongsSortingTerm songsAsc(SongsColumn by) {
return SongsSortingTerm(dir: SortDirection.asc, by: by);
}
static SongsSortingTerm songsDesc(SongsColumn by) {
return SongsSortingTerm(dir: SortDirection.desc, by: by);
}
const factory SortingTerm.playlists({
required SortDirection dir,
required PlaylistsColumn by,
}) = PlaylistsSortingTerm;
static PlaylistsSortingTerm playlistsAsc(PlaylistsColumn by) {
return PlaylistsSortingTerm(dir: SortDirection.asc, by: by);
}
static PlaylistsSortingTerm playlistsDesc(PlaylistsColumn by) {
return PlaylistsSortingTerm(dir: SortDirection.desc, by: by);
}
factory SortingTerm.fromJson(Map<String, Object?> json) =>
_$SortingTermFromJson(json);
}
@freezed
abstract class AlbumsQuery with _$AlbumsQuery {
const factory AlbumsQuery({
required int sourceId,
@Default(IListConst([])) IList<AlbumsFilter> filter,
required IList<AlbumsSortingTerm> sort,
int? limit,
int? offset,
}) = _AlbumsQuery;
factory AlbumsQuery.fromJson(Map<String, Object?> json) =>
_$AlbumsQueryFromJson(json);
}
@freezed
abstract class AlbumsFilter with _$AlbumsFilter {
const factory AlbumsFilter.artistId(String artistId) = AlbumsFilterArtistId;
const factory AlbumsFilter.yearEquals(int year) = AlbumsFilterYearEquals;
factory AlbumsFilter.fromJson(Map<String, Object?> json) =>
_$AlbumsFilterFromJson(json);
}
@freezed
abstract class ArtistsQuery with _$ArtistsQuery {
const factory ArtistsQuery({
required int sourceId,
@Default(IListConst([])) IList<ArtistsFilter> filter,
required IList<ArtistsSortingTerm> sort,
int? limit,
int? offset,
}) = _ArtistsQuery;
factory ArtistsQuery.fromJson(Map<String, Object?> json) =>
_$ArtistsQueryFromJson(json);
}
@freezed
abstract class ArtistsFilter with _$ArtistsFilter {
const factory ArtistsFilter.nameSearch(String name) = ArtistsFilterNameSearch;
const factory ArtistsFilter.starred(bool starred) = ArtistsFilterStarred;
factory ArtistsFilter.fromJson(Map<String, Object?> json) =>
_$ArtistsFilterFromJson(json);
}
@freezed
abstract class SongsQuery with _$SongsQuery {
const factory SongsQuery({
required int sourceId,
@Default(IListConst([])) IList<SongsFilter> filter,
required IList<SongsSortingTerm> sort,
int? limit,
int? offset,
}) = _SongsQuery;
factory SongsQuery.fromJson(Map<String, Object?> json) =>
_$SongsQueryFromJson(json);
}
@freezed
abstract class SongsFilter with _$SongsFilter {
const factory SongsFilter.albumId(String albumId) = SongsFilterAlbumId;
const factory SongsFilter.playlistId(String playlistId) =
SongsFilterPlaylistId;
factory SongsFilter.fromJson(Map<String, Object?> json) =>
_$SongsFilterFromJson(json);
}
@freezed
abstract class PlaylistsQuery with _$PlaylistsQuery {
const factory PlaylistsQuery({
required int sourceId,
@Default(IListConst([])) IList<PlaylistsFilter> filter,
required IList<PlaylistsSortingTerm> sort,
int? limit,
int? offset,
}) = _PlaylistsQuery;
factory PlaylistsQuery.fromJson(Map<String, Object?> json) =>
_$PlaylistsQueryFromJson(json);
}
@freezed
abstract class PlaylistsFilter with _$PlaylistsFilter {
const factory PlaylistsFilter.nameSearch(String name) =
PlaylistsFilterNameSearch;
const factory PlaylistsFilter.public(bool public) = PlaylistsFilterPublic;
factory PlaylistsFilter.fromJson(Map<String, Object?> json) =>
_$PlaylistsFilterFromJson(json);
}

File diff suppressed because it is too large Load Diff

303
lib/database/query.g.dart Normal file
View File

@@ -0,0 +1,303 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'query.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
AlbumsSortingTerm _$AlbumsSortingTermFromJson(Map<String, dynamic> json) =>
AlbumsSortingTerm(
dir: $enumDecode(_$SortDirectionEnumMap, json['dir']),
by: $enumDecode(_$AlbumsColumnEnumMap, json['by']),
$type: json['runtimeType'] as String?,
);
Map<String, dynamic> _$AlbumsSortingTermToJson(AlbumsSortingTerm instance) =>
<String, dynamic>{
'dir': _$SortDirectionEnumMap[instance.dir]!,
'by': _$AlbumsColumnEnumMap[instance.by]!,
'runtimeType': instance.$type,
};
const _$SortDirectionEnumMap = {
SortDirection.asc: 'asc',
SortDirection.desc: 'desc',
};
const _$AlbumsColumnEnumMap = {
AlbumsColumn.name: 'name',
AlbumsColumn.created: 'created',
AlbumsColumn.year: 'year',
AlbumsColumn.starred: 'starred',
};
ArtistsSortingTerm _$ArtistsSortingTermFromJson(Map<String, dynamic> json) =>
ArtistsSortingTerm(
dir: $enumDecode(_$SortDirectionEnumMap, json['dir']),
by: $enumDecode(_$ArtistsColumnEnumMap, json['by']),
$type: json['runtimeType'] as String?,
);
Map<String, dynamic> _$ArtistsSortingTermToJson(ArtistsSortingTerm instance) =>
<String, dynamic>{
'dir': _$SortDirectionEnumMap[instance.dir]!,
'by': _$ArtistsColumnEnumMap[instance.by]!,
'runtimeType': instance.$type,
};
const _$ArtistsColumnEnumMap = {
ArtistsColumn.name: 'name',
ArtistsColumn.starred: 'starred',
ArtistsColumn.albumCount: 'albumCount',
};
SongsSortingTerm _$SongsSortingTermFromJson(Map<String, dynamic> json) =>
SongsSortingTerm(
dir: $enumDecode(_$SortDirectionEnumMap, json['dir']),
by: $enumDecode(_$SongsColumnEnumMap, json['by']),
$type: json['runtimeType'] as String?,
);
Map<String, dynamic> _$SongsSortingTermToJson(SongsSortingTerm instance) =>
<String, dynamic>{
'dir': _$SortDirectionEnumMap[instance.dir]!,
'by': _$SongsColumnEnumMap[instance.by]!,
'runtimeType': instance.$type,
};
const _$SongsColumnEnumMap = {
SongsColumn.title: 'title',
SongsColumn.starred: 'starred',
SongsColumn.disc: 'disc',
SongsColumn.track: 'track',
SongsColumn.album: 'album',
SongsColumn.artist: 'artist',
SongsColumn.albumArtist: 'albumArtist',
SongsColumn.playlistPosition: 'playlistPosition',
};
PlaylistsSortingTerm _$PlaylistsSortingTermFromJson(
Map<String, dynamic> json,
) => PlaylistsSortingTerm(
dir: $enumDecode(_$SortDirectionEnumMap, json['dir']),
by: $enumDecode(_$PlaylistsColumnEnumMap, json['by']),
$type: json['runtimeType'] as String?,
);
Map<String, dynamic> _$PlaylistsSortingTermToJson(
PlaylistsSortingTerm instance,
) => <String, dynamic>{
'dir': _$SortDirectionEnumMap[instance.dir]!,
'by': _$PlaylistsColumnEnumMap[instance.by]!,
'runtimeType': instance.$type,
};
const _$PlaylistsColumnEnumMap = {
PlaylistsColumn.name: 'name',
PlaylistsColumn.created: 'created',
};
_AlbumsQuery _$AlbumsQueryFromJson(Map<String, dynamic> json) => _AlbumsQuery(
sourceId: (json['sourceId'] as num).toInt(),
filter: json['filter'] == null
? const IListConst([])
: IList<AlbumsFilter>.fromJson(
json['filter'],
(value) => AlbumsFilter.fromJson(value as Map<String, dynamic>),
),
sort: IList<AlbumsSortingTerm>.fromJson(
json['sort'],
(value) => AlbumsSortingTerm.fromJson(value as Map<String, dynamic>),
),
limit: (json['limit'] as num?)?.toInt(),
offset: (json['offset'] as num?)?.toInt(),
);
Map<String, dynamic> _$AlbumsQueryToJson(_AlbumsQuery instance) =>
<String, dynamic>{
'sourceId': instance.sourceId,
'filter': instance.filter.toJson((value) => value),
'sort': instance.sort.toJson((value) => value),
'limit': instance.limit,
'offset': instance.offset,
};
AlbumsFilterArtistId _$AlbumsFilterArtistIdFromJson(
Map<String, dynamic> json,
) => AlbumsFilterArtistId(
json['artistId'] as String,
$type: json['runtimeType'] as String?,
);
Map<String, dynamic> _$AlbumsFilterArtistIdToJson(
AlbumsFilterArtistId instance,
) => <String, dynamic>{
'artistId': instance.artistId,
'runtimeType': instance.$type,
};
AlbumsFilterYearEquals _$AlbumsFilterYearEqualsFromJson(
Map<String, dynamic> json,
) => AlbumsFilterYearEquals(
(json['year'] as num).toInt(),
$type: json['runtimeType'] as String?,
);
Map<String, dynamic> _$AlbumsFilterYearEqualsToJson(
AlbumsFilterYearEquals instance,
) => <String, dynamic>{'year': instance.year, 'runtimeType': instance.$type};
_ArtistsQuery _$ArtistsQueryFromJson(Map<String, dynamic> json) =>
_ArtistsQuery(
sourceId: (json['sourceId'] as num).toInt(),
filter: json['filter'] == null
? const IListConst([])
: IList<ArtistsFilter>.fromJson(
json['filter'],
(value) => ArtistsFilter.fromJson(value as Map<String, dynamic>),
),
sort: IList<ArtistsSortingTerm>.fromJson(
json['sort'],
(value) => ArtistsSortingTerm.fromJson(value as Map<String, dynamic>),
),
limit: (json['limit'] as num?)?.toInt(),
offset: (json['offset'] as num?)?.toInt(),
);
Map<String, dynamic> _$ArtistsQueryToJson(_ArtistsQuery instance) =>
<String, dynamic>{
'sourceId': instance.sourceId,
'filter': instance.filter.toJson((value) => value),
'sort': instance.sort.toJson((value) => value),
'limit': instance.limit,
'offset': instance.offset,
};
ArtistsFilterNameSearch _$ArtistsFilterNameSearchFromJson(
Map<String, dynamic> json,
) => ArtistsFilterNameSearch(
json['name'] as String,
$type: json['runtimeType'] as String?,
);
Map<String, dynamic> _$ArtistsFilterNameSearchToJson(
ArtistsFilterNameSearch instance,
) => <String, dynamic>{'name': instance.name, 'runtimeType': instance.$type};
ArtistsFilterStarred _$ArtistsFilterStarredFromJson(
Map<String, dynamic> json,
) => ArtistsFilterStarred(
json['starred'] as bool,
$type: json['runtimeType'] as String?,
);
Map<String, dynamic> _$ArtistsFilterStarredToJson(
ArtistsFilterStarred instance,
) => <String, dynamic>{
'starred': instance.starred,
'runtimeType': instance.$type,
};
_SongsQuery _$SongsQueryFromJson(Map<String, dynamic> json) => _SongsQuery(
sourceId: (json['sourceId'] as num).toInt(),
filter: json['filter'] == null
? const IListConst([])
: IList<SongsFilter>.fromJson(
json['filter'],
(value) => SongsFilter.fromJson(value as Map<String, dynamic>),
),
sort: IList<SongsSortingTerm>.fromJson(
json['sort'],
(value) => SongsSortingTerm.fromJson(value as Map<String, dynamic>),
),
limit: (json['limit'] as num?)?.toInt(),
offset: (json['offset'] as num?)?.toInt(),
);
Map<String, dynamic> _$SongsQueryToJson(_SongsQuery instance) =>
<String, dynamic>{
'sourceId': instance.sourceId,
'filter': instance.filter.toJson((value) => value),
'sort': instance.sort.toJson((value) => value),
'limit': instance.limit,
'offset': instance.offset,
};
SongsFilterAlbumId _$SongsFilterAlbumIdFromJson(Map<String, dynamic> json) =>
SongsFilterAlbumId(
json['albumId'] as String,
$type: json['runtimeType'] as String?,
);
Map<String, dynamic> _$SongsFilterAlbumIdToJson(SongsFilterAlbumId instance) =>
<String, dynamic>{
'albumId': instance.albumId,
'runtimeType': instance.$type,
};
SongsFilterPlaylistId _$SongsFilterPlaylistIdFromJson(
Map<String, dynamic> json,
) => SongsFilterPlaylistId(
json['playlistId'] as String,
$type: json['runtimeType'] as String?,
);
Map<String, dynamic> _$SongsFilterPlaylistIdToJson(
SongsFilterPlaylistId instance,
) => <String, dynamic>{
'playlistId': instance.playlistId,
'runtimeType': instance.$type,
};
_PlaylistsQuery _$PlaylistsQueryFromJson(Map<String, dynamic> json) =>
_PlaylistsQuery(
sourceId: (json['sourceId'] as num).toInt(),
filter: json['filter'] == null
? const IListConst([])
: IList<PlaylistsFilter>.fromJson(
json['filter'],
(value) =>
PlaylistsFilter.fromJson(value as Map<String, dynamic>),
),
sort: IList<PlaylistsSortingTerm>.fromJson(
json['sort'],
(value) => PlaylistsSortingTerm.fromJson(value as Map<String, dynamic>),
),
limit: (json['limit'] as num?)?.toInt(),
offset: (json['offset'] as num?)?.toInt(),
);
Map<String, dynamic> _$PlaylistsQueryToJson(_PlaylistsQuery instance) =>
<String, dynamic>{
'sourceId': instance.sourceId,
'filter': instance.filter.toJson((value) => value),
'sort': instance.sort.toJson((value) => value),
'limit': instance.limit,
'offset': instance.offset,
};
PlaylistsFilterNameSearch _$PlaylistsFilterNameSearchFromJson(
Map<String, dynamic> json,
) => PlaylistsFilterNameSearch(
json['name'] as String,
$type: json['runtimeType'] as String?,
);
Map<String, dynamic> _$PlaylistsFilterNameSearchToJson(
PlaylistsFilterNameSearch instance,
) => <String, dynamic>{'name': instance.name, 'runtimeType': instance.$type};
PlaylistsFilterPublic _$PlaylistsFilterPublicFromJson(
Map<String, dynamic> json,
) => PlaylistsFilterPublic(
json['public'] as bool,
$type: json['runtimeType'] as String?,
);
Map<String, dynamic> _$PlaylistsFilterPublicToJson(
PlaylistsFilterPublic instance,
) => <String, dynamic>{
'public': instance.public,
'runtimeType': instance.$type,
};

555
lib/database/tables.drift Normal file
View File

@@ -0,0 +1,555 @@
import 'converters.dart';
import '../sources/models.dart';
--
-- SCHEMA
--
-- CREATE TABLE queue(
-- "index" INT NOT NULL PRIMARY KEY UNIQUE,
-- source_id INT NOT NULL,
-- id TEXT NOT NULL,
-- context ENUM(QueueContextType) NOT NULL,
-- context_id TEXT,
-- current_track BOOLEAN UNIQUE
-- );
-- CREATE INDEX queue_index ON queue ("index");
-- CREATE INDEX queue_current_track ON queue ("current_track");
-- CREATE TABLE last_audio_state(
-- id INT NOT NULL PRIMARY KEY,
-- queue_mode ENUM(QueueMode) NOT NULL,
-- shuffle_indicies TEXT MAPPED BY `const IListIntConverter()`,
-- repeat ENUM(RepeatMode) NOT NULL
-- );
-- CREATE TABLE last_bottom_nav_state(
-- id INT NOT NULL PRIMARY KEY,
-- tab TEXT NOT NULL
-- );
-- CREATE TABLE last_library_state(
-- id INT NOT NULL PRIMARY KEY,
-- tab TEXT NOT NULL,
-- albums_list TEXT NOT NULL MAPPED BY `const ListQueryConverter()`,
-- artists_list TEXT NOT NULL MAPPED BY `const ListQueryConverter()`,
-- playlists_list TEXT NOT NULL MAPPED BY `const ListQueryConverter()`,
-- songs_list TEXT NOT NULL MAPPED BY `const ListQueryConverter()`
-- );
-- CREATE TABLE app_settings(
-- id INT NOT NULL PRIMARY KEY,
-- max_bitrate_wifi INT NOT NULL,
-- max_bitrate_mobile INT NOT NULL,
-- stream_format TEXT
-- ) WITH AppSettings;
CREATE TABLE sources(
id INT NOT NULL PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL COLLATE NOCASE,
is_active BOOLEAN UNIQUE,
created_at DATETIME NOT NULL DEFAULT (strftime('%s', CURRENT_TIMESTAMP))
);
CREATE TABLE subsonic_settings(
source_id INT NOT NULL PRIMARY KEY,
address TEXT NOT NULL MAPPED BY `const UriConverter()`,
username TEXT NOT NULL,
password TEXT NOT NULL,
use_token_auth BOOLEAN NOT NULL DEFAULT 1,
FOREIGN KEY (source_id) REFERENCES sources (id) ON DELETE CASCADE
);
CREATE TABLE artists(
source_id INT NOT NULL,
id TEXT NOT NULL,
name TEXT NOT NULL COLLATE NOCASE,
starred DATETIME,
cover_art TEXT,
PRIMARY KEY (source_id, id),
FOREIGN KEY (source_id) REFERENCES sources (id) ON DELETE CASCADE
) WITH Artist;
CREATE INDEX artists_source_id ON artists (source_id);
-- CREATE VIRTUAL TABLE artists_fts USING fts5(source_id, name, content=artists, content_rowid=rowid);
-- CREATE TRIGGER artists_ai AFTER INSERT ON artists BEGIN
-- INSERT INTO artists_fts(rowid, source_id, name)
-- VALUES (new.rowid, new.source_id, new.name);
-- END;
-- CREATE TRIGGER artists_ad AFTER DELETE ON artists BEGIN
-- INSERT INTO artists_fts(artists_fts, rowid, source_id, name)
-- VALUES('delete', old.rowid, old.source_id, old.name);
-- END;
-- CREATE TRIGGER artists_au AFTER UPDATE ON artists BEGIN
-- INSERT INTO artists_fts(artists_fts, rowid, source_id, name)
-- VALUES('delete', old.rowid, old.source_id, old.name);
-- INSERT INTO artists_fts(rowid, source_id, name)
-- VALUES (new.rowid, new.source_id, new.name);
-- END;
CREATE TABLE albums(
source_id INT NOT NULL,
id TEXT NOT NULL,
artist_id TEXT,
name TEXT NOT NULL COLLATE NOCASE,
album_artist TEXT COLLATE NOCASE,
created DATETIME NOT NULL,
cover_art TEXT,
genre TEXT,
year INT,
starred DATETIME,
frequent_rank INT,
recent_rank INT,
PRIMARY KEY (source_id, id),
FOREIGN KEY (source_id) REFERENCES sources (id) ON DELETE CASCADE
) WITH Album;
CREATE INDEX albums_source_id ON albums (source_id);
CREATE INDEX albums_source_id_artist_id_idx ON albums (source_id, artist_id);
-- CREATE VIRTUAL TABLE albums_fts USING fts5(source_id, name, content=albums, content_rowid=rowid);
-- CREATE TRIGGER albums_ai AFTER INSERT ON albums BEGIN
-- INSERT INTO albums_fts(rowid, source_id, name)
-- VALUES (new.rowid, new.source_id, new.name);
-- END;
-- CREATE TRIGGER albums_ad AFTER DELETE ON albums BEGIN
-- INSERT INTO albums_fts(albums_fts, rowid, source_id, name)
-- VALUES('delete', old.rowid, old.source_id, old.name);
-- END;
-- CREATE TRIGGER albums_au AFTER UPDATE ON albums BEGIN
-- INSERT INTO albums_fts(albums_fts, rowid, source_id, name)
-- VALUES('delete', old.rowid, old.source_id, old.name);
-- INSERT INTO albums_fts(rowid, source_id, name)
-- VALUES (new.rowid, new.source_id, new.name);
-- END;
CREATE TABLE playlists(
source_id INT NOT NULL,
id TEXT NOT NULL,
name TEXT NOT NULL COLLATE NOCASE,
comment TEXT COLLATE NOCASE,
cover_art TEXT,
created DATETIME NOT NULL,
changed DATETIME NOT NULL,
public BOOLEAN,
PRIMARY KEY (source_id, id),
FOREIGN KEY (source_id) REFERENCES sources (id) ON DELETE CASCADE
) WITH Playlist;
CREATE INDEX playlists_source_id ON playlists (source_id);
CREATE TABLE playlist_songs(
source_id INT NOT NULL,
playlist_id TEXT NOT NULL,
song_id TEXT NOT NULL,
position INT NOT NULL,
PRIMARY KEY (source_id, playlist_id, position),
FOREIGN KEY (source_id) REFERENCES sources (id) ON DELETE CASCADE
) WITH PlaylistSong;
CREATE INDEX playlist_songs_source_id_playlist_id_idx ON playlist_songs (source_id, playlist_id);
CREATE INDEX playlist_songs_source_id_song_id_idx ON playlist_songs (source_id, song_id);
-- CREATE VIRTUAL TABLE playlists_fts USING fts5(source_id, name, content=playlists, content_rowid=rowid);
-- CREATE TRIGGER playlists_ai AFTER INSERT ON playlists BEGIN
-- INSERT INTO playlists_fts(rowid, source_id, name)
-- VALUES (new.rowid, new.source_id, new.name);
-- END;
-- CREATE TRIGGER playlists_ad AFTER DELETE ON playlists BEGIN
-- INSERT INTO playlists_fts(playlists_fts, rowid, source_id, name)
-- VALUES('delete', old.rowid, old.source_id, old.name);
-- END;
-- CREATE TRIGGER playlists_au AFTER UPDATE ON playlists BEGIN
-- INSERT INTO playlists_fts(playlists_fts, rowid, source_id, name)
-- VALUES('delete', old.rowid, old.source_id, old.name);
-- INSERT INTO playlists_fts(rowid, source_id, name)
-- VALUES (new.rowid, new.source_id, new.name);
-- END;
CREATE TABLE songs(
source_id INT NOT NULL,
id TEXT NOT NULL,
album_id TEXT,
artist_id TEXT,
title TEXT NOT NULL COLLATE NOCASE,
album TEXT COLLATE NOCASE,
artist TEXT COLLATE NOCASE,
duration INT MAPPED BY `const DurationSecondsConverter()`,
track INT,
disc INT,
starred DATETIME,
genre TEXT,
PRIMARY KEY (source_id, id),
FOREIGN KEY (source_id) REFERENCES sources (id) ON DELETE CASCADE
) WITH Song;
CREATE INDEX songs_source_id_album_id_idx ON songs (source_id, album_id);
CREATE INDEX songs_source_id_artist_id_idx ON songs (source_id, artist_id);
-- CREATE VIRTUAL TABLE songs_fts USING fts5(source_id, title, content=songs, content_rowid=rowid);
-- CREATE TRIGGER songs_ai AFTER INSERT ON songs BEGIN
-- INSERT INTO songs_fts(rowid, source_id, title)
-- VALUES (new.rowid, new.source_id, new.title);
-- END;
-- CREATE TRIGGER songs_ad AFTER DELETE ON songs BEGIN
-- INSERT INTO songs_fts(songs_fts, rowid, source_id, title)
-- VALUES('delete', old.rowid, old.source_id, old.title);
-- END;
-- CREATE TRIGGER songs_au AFTER UPDATE ON songs BEGIN
-- INSERT INTO songs_fts(songs_fts, rowid, source_id, title)
-- VALUES('delete', old.rowid, old.source_id, old.title);
-- INSERT INTO songs_fts(rowid, source_id, title)
-- VALUES (new.rowid, new.source_id, new.title);
-- END;
--
-- QUERIES
--
-- sourcesCount:
-- SELECT COUNT(*)
-- FROM sources;
-- allSubsonicSources WITH SubsonicSettings:
-- SELECT
-- sources.id,
-- sources.name,
-- sources.address,
-- sources.is_active,
-- sources.created_at,
-- subsonic_sources.features,
-- subsonic_sources.username,
-- subsonic_sources.password,
-- subsonic_sources.use_token_auth
-- FROM sources
-- JOIN subsonic_sources ON subsonic_sources.source_id = sources.id;
-- albumIdsWithDownloadStatus:
-- SELECT albums.id
-- FROM albums
-- JOIN songs on songs.source_id = albums.source_id AND songs.album_id = albums.id
-- WHERE
-- albums.source_id = :source_id
-- AND (songs.download_file_path IS NOT NULL OR songs.download_task_id IS NOT NULL)
-- GROUP BY albums.id;
-- artistIdsWithDownloadStatus:
-- SELECT artists.id
-- FROM artists
-- LEFT JOIN albums ON artists.source_id = albums.source_id AND artists.id = albums.artist_id
-- LEFT JOIN songs ON albums.source_id = songs.source_id AND albums.id = songs.album_id
-- WHERE
-- artists.source_id = :source_id
-- AND (songs.download_file_path IS NOT NULL OR songs.download_task_id IS NOT NULL)
-- GROUP BY artists.id;
-- playlistIdsWithDownloadStatus:
-- SELECT playlists.id
-- FROM playlists
-- LEFT JOIN playlist_songs ON playlist_songs.source_id = playlists.source_id AND playlist_songs.playlist_id = playlists.id
-- LEFT JOIN songs ON playlist_songs.source_id = songs.source_id AND playlist_songs.song_id = songs.id
-- WHERE
-- playlists.source_id = :source_id
-- AND (songs.download_file_path IS NOT NULL OR songs.download_task_id IS NOT NULL)
-- GROUP BY playlists.id;
-- searchArtists:
-- SELECT rowid
-- FROM artists_fts
-- WHERE artists_fts MATCH :query
-- ORDER BY rank
-- LIMIT :limit OFFSET :offset;
-- searchAlbums:
-- SELECT rowid
-- FROM albums_fts
-- WHERE albums_fts MATCH :query
-- ORDER BY rank
-- LIMIT :limit OFFSET :offset;
-- searchPlaylists:
-- SELECT rowid
-- FROM playlists_fts
-- WHERE playlists_fts MATCH :query
-- ORDER BY rank
-- LIMIT :limit OFFSET :offset;
-- searchSongs:
-- SELECT rowid
-- FROM songs_fts
-- WHERE songs_fts MATCH :query
-- ORDER BY rank
-- LIMIT :limit OFFSET :offset;
-- artistById:
-- SELECT * FROM artists
-- WHERE source_id = :source_id AND id = :id;
-- albumById:
-- SELECT * FROM albums
-- WHERE source_id = :source_id AND id = :id;
-- albumsByArtistId:
-- SELECT * FROM albums
-- WHERE source_id = :source_id AND artist_id = :artist_id;
-- albumsInIds:
-- SELECT * FROM albums
-- WHERE source_id = :source_id AND id IN :ids;
-- playlistById:
-- SELECT * FROM playlists
-- WHERE source_id = :source_id AND id = :id;
-- songById:
-- SELECT * FROM songs
-- WHERE source_id = :source_id AND id = :id;
-- albumGenres:
-- SELECT
-- genre
-- FROM albums
-- WHERE genre IS NOT NULL AND source_id = :source_id
-- GROUP BY genre
-- ORDER BY COUNT(genre) DESC
-- LIMIT :limit OFFSET :offset;
-- albumsByGenre:
-- SELECT
-- albums.*
-- FROM albums
-- JOIN songs ON albums.source_id = songs.source_id AND albums.id = songs.album_id
-- WHERE songs.source_id = :source_id AND songs.genre = :genre
-- GROUP BY albums.id
-- ORDER BY albums.created DESC, albums.name
-- LIMIT :limit OFFSET :offset;
-- filterSongsByGenre:
-- SELECT
-- songs.*
-- FROM songs
-- JOIN albums ON albums.source_id = songs.source_id AND albums.id = songs.album_id
-- WHERE $predicate
-- ORDER BY $order
-- LIMIT $limit;
-- songsByGenreCount:
-- SELECT
-- COUNT(*)
-- FROM songs
-- WHERE songs.source_id = :source_id AND songs.genre = :genre;
-- songsWithDownloadTasks:
-- SELECT * FROM songs
-- WHERE download_task_id IS NOT NULL;
-- songByDownloadTask:
-- SELECT * FROM songs
-- WHERE download_task_id = :task_id;
-- clearSongDownloadTaskBySong:
-- UPDATE songs SET
-- download_task_id = NULL
-- WHERE source_id = :source_id AND id = :id;
-- completeSongDownload:
-- UPDATE songs SET
-- download_task_id = NULL,
-- download_file_path = :file_path
-- WHERE download_task_id = :task_id;
-- clearSongDownloadTask:
-- UPDATE songs SET
-- download_task_id = NULL,
-- download_file_path = NULL
-- WHERE download_task_id = :task_id;
-- updateSongDownloadTask:
-- UPDATE songs SET
-- download_task_id = :task_id
-- WHERE source_id = :source_id AND id = :id;
-- deleteSongDownloadFile:
-- UPDATE songs SET
-- download_task_id = NULL,
-- download_file_path = NULL
-- WHERE source_id = :source_id AND id = :id;
-- albumDownloadStatus WITH ListDownloadStatus:
-- SELECT
-- COUNT(*) as total,
-- COUNT(CASE WHEN songs.download_file_path IS NOT NULL THEN songs.id ELSE NULL END) AS downloaded,
-- COUNT(CASE WHEN songs.download_task_id IS NOT NULL THEN songs.id ELSE NULL END) AS downloading
-- FROM albums
-- JOIN songs ON albums.source_id = songs.source_id AND albums.id = songs.album_id
-- WHERE albums.source_id = :source_id AND albums.id = :id;
-- playlistDownloadStatus WITH ListDownloadStatus:
-- SELECT
-- COUNT(DISTINCT songs.id) as total,
-- COUNT(DISTINCT CASE WHEN songs.download_file_path IS NOT NULL THEN songs.id ELSE NULL END) AS downloaded,
-- COUNT(DISTINCT CASE WHEN songs.download_task_id IS NOT NULL THEN songs.id ELSE NULL END) AS downloading
-- FROM playlists
-- JOIN playlist_songs ON
-- playlist_songs.source_id = playlists.source_id
-- AND playlist_songs.playlist_id = playlists.id
-- JOIN songs ON
-- songs.source_id = playlist_songs.source_id
-- AND songs.id = playlist_songs.song_id
-- WHERE
-- playlists.source_id = :source_id AND playlists.id = :id;
-- filterAlbums:
-- SELECT
-- albums.*
-- FROM albums
-- WHERE $predicate
-- ORDER BY $order
-- LIMIT $limit;
-- filterAlbumsDownloaded:
-- SELECT
-- albums.*
-- FROM albums
-- LEFT JOIN songs ON albums.source_id = songs.source_id AND albums.id = songs.album_id
-- WHERE $predicate
-- GROUP BY albums.source_id, albums.id
-- HAVING SUM(CASE WHEN songs.download_file_path IS NOT NULL THEN 1 ELSE 0 END) > 0
-- ORDER BY $order
-- LIMIT $limit;
-- filterArtists:
-- SELECT
-- artists.*
-- FROM artists
-- WHERE $predicate
-- ORDER BY $order
-- LIMIT $limit;
-- filterArtistsDownloaded WITH Artist:
-- SELECT
-- artists.*,
-- COUNT(DISTINCT CASE WHEN songs.download_file_path IS NOT NULL THEN songs.album_id ELSE NULL END) AS album_count
-- FROM artists
-- LEFT JOIN albums ON artists.source_id = albums.source_id AND artists.id = albums.artist_id
-- LEFT JOIN songs ON albums.source_id = songs.source_id AND albums.id = songs.album_id
-- WHERE $predicate
-- GROUP BY artists.source_id, artists.id
-- HAVING SUM(CASE WHEN songs.download_file_path IS NOT NULL THEN 1 ELSE 0 END) > 0
-- ORDER BY $order
-- LIMIT $limit;
-- filterPlaylists:
-- SELECT
-- playlists.*
-- FROM playlists
-- WHERE $predicate
-- ORDER BY $order
-- LIMIT $limit;
-- filterPlaylistsDownloaded WITH Playlist:
-- SELECT
-- playlists.*,
-- COUNT(CASE WHEN songs.download_file_path IS NOT NULL THEN songs.id ELSE NULL END) AS song_count
-- FROM playlists
-- LEFT JOIN playlist_songs ON playlist_songs.source_id = playlists.source_id AND playlist_songs.playlist_id = playlists.id
-- LEFT JOIN songs ON playlist_songs.source_id = songs.source_id AND playlist_songs.song_id = songs.id
-- WHERE $predicate
-- GROUP BY playlists.source_id, playlists.id
-- HAVING SUM(CASE WHEN songs.download_file_path IS NOT NULL THEN 1 ELSE 0 END) > 0
-- ORDER BY $order
-- LIMIT $limit;
-- filterSongs:
-- SELECT
-- songs.*
-- FROM songs
-- WHERE $predicate
-- ORDER BY $order
-- LIMIT $limit;
-- filterSongsDownloaded:
-- SELECT
-- songs.*
-- FROM songs
-- WHERE $predicate AND songs.download_file_path IS NOT NULL
-- ORDER BY $order
-- LIMIT $limit;
-- playlistIsDownloaded:
-- SELECT
-- COUNT(*) = 0
-- FROM playlists
-- JOIN playlist_songs ON
-- playlist_songs.source_id = playlists.source_id
-- AND playlist_songs.playlist_id = playlists.id
-- JOIN songs ON
-- songs.source_id = playlist_songs.source_id
-- AND songs.id = playlist_songs.song_id
-- WHERE
-- playlists.source_id = :source_id AND playlists.id = :id
-- AND songs.download_file_path IS NULL;
-- playlistHasDownloadsInProgress:
-- SELECT
-- COUNT(*) > 0
-- FROM playlists
-- JOIN playlist_songs ON
-- playlist_songs.source_id = playlists.source_id
-- AND playlist_songs.playlist_id = playlists.id
-- JOIN songs ON
-- songs.source_id = playlist_songs.source_id
-- AND songs.id = playlist_songs.song_id
-- WHERE playlists.source_id = :source_id AND playlists.id = :id
-- AND songs.download_task_id IS NOT NULL;
-- songsInIds:
-- SELECT *
-- FROM songs
-- WHERE source_id = :source_id AND id IN :ids;
-- songsInRowIds:
-- SELECT *
-- FROM songs
-- WHERE ROWID IN :row_ids;
-- albumsInRowIds:
-- SELECT *
-- FROM albums
-- WHERE ROWID IN :row_ids;
-- artistsInRowIds:
-- SELECT *
-- FROM artists
-- WHERE ROWID IN :row_ids;
-- playlistsInRowIds:
-- SELECT *
-- FROM playlists
-- WHERE ROWID IN :row_ids;
-- currentTrackIndex:
-- SELECT
-- queue."index"
-- FROM queue
-- WHERE queue.current_track = 1;
-- queueLength:
-- SELECT COUNT(*) FROM queue;
-- queueInIndicies:
-- SELECT *
-- FROM queue
-- WHERE queue."index" IN :indicies;
-- getAppSettings:
-- SELECT * FROM app_settings
-- WHERE id = 1;

196
lib/l10n/app_ar.arb Normal file
View File

@@ -0,0 +1,196 @@
{
"actionsStar": "مميز",
"@actionsStar": {},
"actionsUnstar": "ازل التمييز",
"@actionsUnstar": {},
"messagesNothingHere": "لا شيء هنا…",
"@messagesNothingHere": {},
"navigationTabsHome": "الرئيسية",
"@navigationTabsHome": {},
"navigationTabsLibrary": "المكتبة",
"@navigationTabsLibrary": {},
"navigationTabsSearch": "بحث",
"@navigationTabsSearch": {},
"navigationTabsSettings": "الإعدادات",
"@navigationTabsSettings": {},
"resourcesAlbumActionsPlay": "شَغل الألبوم",
"@resourcesAlbumActionsPlay": {},
"resourcesAlbumActionsView": "أعرض الألبوم",
"@resourcesAlbumActionsView": {},
"resourcesAlbumListsSort": "فرز الألبومات",
"@resourcesAlbumListsSort": {},
"resourcesAlbumName": "{count,plural, =1{} few{ألبوم} many{} other{}}",
"@resourcesAlbumName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesArtistActionsView": "أظهر الفنان",
"@resourcesArtistActionsView": {},
"resourcesArtistListsSort": "فرز الفنانين",
"@resourcesArtistListsSort": {},
"resourcesArtistName": "{count,plural, =1{} few{فنان} many{فنانان} other{فنانان}}",
"@resourcesArtistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesFilterGenre": "حسب النوع",
"@resourcesFilterGenre": {},
"resourcesFilterStarred": "موسوم",
"@resourcesFilterStarred": {},
"resourcesPlaylistActionsPlay": "شغل قائمة التشغيل",
"@resourcesPlaylistActionsPlay": {},
"resourcesPlaylistName": "{count,plural, =1{} few{قائمة تشغيل} many{قائمتان تشغيل} other{قائمتان تشغيل}}",
"@resourcesPlaylistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesQueueName": "{count,plural, =1{} few{صف} many{صفين} other{صفين}}",
"@resourcesQueueName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSongListsArtistTopSongs": "أشهر الأغاني",
"@resourcesSongListsArtistTopSongs": {},
"resourcesSongName": "{count,plural, =1{} few{أُغْنِيَة} many{} other{}}",
"@resourcesSongName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSortByAdded": "أضيف حديثا",
"@resourcesSortByAdded": {},
"resourcesSortByArtist": "حسب الفنان/ة",
"@resourcesSortByArtist": {},
"resourcesSortByFrequentlyPlayed": "مشغل كثيرا",
"@resourcesSortByFrequentlyPlayed": {},
"resourcesSortByName": "حسب الاسم",
"@resourcesSortByName": {},
"resourcesSortByRandom": "عشوائي",
"@resourcesSortByRandom": {},
"resourcesSortByRecentlyPlayed": "شغل حديثا",
"@resourcesSortByRecentlyPlayed": {},
"resourcesSortByYear": "حسب السنة",
"@resourcesSortByYear": {},
"searchHeaderTitle": "بحث: {query}",
"@searchHeaderTitle": {
"placeholders": {
"query": {
"type": "String"
}
}
},
"searchInputPlaceholder": "بحث",
"@searchInputPlaceholder": {},
"searchMoreResults": "المزيد…",
"@searchMoreResults": {},
"searchNowPlayingContext": "نتائج البحث",
"@searchNowPlayingContext": {},
"settingsAboutActionsLicenses": "الرخص",
"@settingsAboutActionsLicenses": {},
"settingsAboutActionsProjectHomepage": "موقع المشروع",
"@settingsAboutActionsProjectHomepage": {},
"settingsAboutName": "حول",
"@settingsAboutName": {},
"settingsAboutVersion": "الإصدار {version}",
"@settingsAboutVersion": {
"placeholders": {
"version": {
"type": "String"
}
}
},
"settingsMusicName": "موسيقى",
"@settingsMusicName": {},
"settingsMusicOptionsScrobbleDescriptionOff": "لا تستورد سجل التشغيل",
"@settingsMusicOptionsScrobbleDescriptionOff": {},
"settingsMusicOptionsScrobbleDescriptionOn": "استيراد سجل التشغيل",
"@settingsMusicOptionsScrobbleDescriptionOn": {},
"settingsMusicOptionsScrobbleTitle": "استيراد سجل التشغيل",
"@settingsMusicOptionsScrobbleTitle": {},
"settingsNetworkName": "الشبكة",
"@settingsNetworkName": {},
"settingsNetworkOptionsMaxBitrateMobileTitle": "أقصى معدل نقل بيانات (mobile)",
"@settingsNetworkOptionsMaxBitrateMobileTitle": {},
"settingsNetworkOptionsMaxBitrateWifiTitle": "أقصى معدل نقل بيانات (Wi-Fi)",
"@settingsNetworkOptionsMaxBitrateWifiTitle": {},
"settingsNetworkOptionsMaxBufferTitle": "الحد الأقصى من وقت التخزين المؤقت",
"@settingsNetworkOptionsMaxBufferTitle": {},
"settingsNetworkOptionsMinBufferTitle": "الحد الأدنى من وقت التخزين المؤقت",
"@settingsNetworkOptionsMinBufferTitle": {},
"settingsNetworkValuesKbps": "{value} كيلو بايت في الثانية",
"@settingsNetworkValuesKbps": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesSeconds": "{value} ثواني",
"@settingsNetworkValuesSeconds": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesUnlimitedKbps": "غير محدود",
"@settingsNetworkValuesUnlimitedKbps": {},
"settingsResetActionsClearImageCache": "مسح ذاكرة التخزين المؤقت للصور",
"@settingsResetActionsClearImageCache": {},
"settingsResetName": "إعادة ضبط",
"@settingsResetName": {},
"settingsServersActionsAdd": "أضف سيرفر",
"@settingsServersActionsAdd": {},
"settingsServersActionsDelete": "حذف",
"@settingsServersActionsDelete": {},
"settingsServersActionsEdit": "عدل السيرفر",
"@settingsServersActionsEdit": {},
"settingsServersActionsSave": "حفظ",
"@settingsServersActionsSave": {},
"settingsServersActionsTestConnection": "أخبر الأتصال",
"@settingsServersActionsTestConnection": {},
"settingsServersFieldsAddress": "العناوين",
"@settingsServersFieldsAddress": {},
"settingsServersFieldsPassword": "كلمة المرور",
"@settingsServersFieldsPassword": {},
"settingsServersFieldsUsername": "إسم المستخدم",
"@settingsServersFieldsUsername": {},
"settingsServersMessagesConnectionFailed": "الأتصال ب {address} فشل، ابحث في الإعدادات او السيرفر",
"@settingsServersMessagesConnectionFailed": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersMessagesConnectionOk": "الأتصال ب {address} جيد!",
"@settingsServersMessagesConnectionOk": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersName": "السيرفرات",
"@settingsServersName": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOff": "أرسل كلمة المرور على شكل توكِن",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOn": "أرسل كلمة المرور بنص عادي (قديم ، تأكد من أن اتصالك آمن!)",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {},
"settingsServersOptionsForcePlaintextPasswordTitle": "أظهر كلمة المرور",
"@settingsServersOptionsForcePlaintextPasswordTitle": {}
}

196
lib/l10n/app_ca.arb Normal file
View File

@@ -0,0 +1,196 @@
{
"actionsStar": "Afegir als favorits",
"@actionsStar": {},
"actionsUnstar": "Retirar estrella",
"@actionsUnstar": {},
"messagesNothingHere": "Aquí no hi ha res…",
"@messagesNothingHere": {},
"navigationTabsHome": "Inici",
"@navigationTabsHome": {},
"navigationTabsLibrary": "Biblioteca",
"@navigationTabsLibrary": {},
"navigationTabsSearch": "Cercar",
"@navigationTabsSearch": {},
"navigationTabsSettings": "Paràmetres",
"@navigationTabsSettings": {},
"resourcesAlbumActionsPlay": "Reproduir l'àlbum",
"@resourcesAlbumActionsPlay": {},
"resourcesAlbumActionsView": "Veure l'àlbum",
"@resourcesAlbumActionsView": {},
"resourcesAlbumListsSort": "Ordenar els àlbums",
"@resourcesAlbumListsSort": {},
"resourcesAlbumName": "{count,plural, =1{Àlbum} other{Àlbums}}",
"@resourcesAlbumName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesArtistActionsView": "Veure l'artista",
"@resourcesArtistActionsView": {},
"resourcesArtistListsSort": "Ordenar els artistes",
"@resourcesArtistListsSort": {},
"resourcesArtistName": "{count,plural, =1{Artista} other{Artistes}}",
"@resourcesArtistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesFilterGenre": "Per gènere",
"@resourcesFilterGenre": {},
"resourcesFilterStarred": "Favorits",
"@resourcesFilterStarred": {},
"resourcesPlaylistActionsPlay": "Reproduir la llista de reproducció",
"@resourcesPlaylistActionsPlay": {},
"resourcesPlaylistName": "{count,plural, =1{Llista de reproducció} other{Llistes de reproducció}}",
"@resourcesPlaylistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesQueueName": "{count,plural, =1{Cua} other{Cues}}",
"@resourcesQueueName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSongListsArtistTopSongs": "Millors cançons",
"@resourcesSongListsArtistTopSongs": {},
"resourcesSongName": "{count,plural, =1{Cançó} other{Cançons}}",
"@resourcesSongName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSortByAdded": "Afegit recentment",
"@resourcesSortByAdded": {},
"resourcesSortByArtist": "Per artista",
"@resourcesSortByArtist": {},
"resourcesSortByFrequentlyPlayed": "Escoltat freqüentment",
"@resourcesSortByFrequentlyPlayed": {},
"resourcesSortByName": "Pel nom",
"@resourcesSortByName": {},
"resourcesSortByRandom": "Aleatori",
"@resourcesSortByRandom": {},
"resourcesSortByRecentlyPlayed": "Reproduït recentment",
"@resourcesSortByRecentlyPlayed": {},
"resourcesSortByYear": "Per any",
"@resourcesSortByYear": {},
"searchHeaderTitle": "Cercar: {query}",
"@searchHeaderTitle": {
"placeholders": {
"query": {
"type": "String"
}
}
},
"searchInputPlaceholder": "Cercar",
"@searchInputPlaceholder": {},
"searchMoreResults": "Més…",
"@searchMoreResults": {},
"searchNowPlayingContext": "Resultats de la cerca",
"@searchNowPlayingContext": {},
"settingsAboutActionsLicenses": "Llicències",
"@settingsAboutActionsLicenses": {},
"settingsAboutActionsProjectHomepage": "Pàgina d'inici del projecte",
"@settingsAboutActionsProjectHomepage": {},
"settingsAboutName": "Quant a",
"@settingsAboutName": {},
"settingsAboutVersion": "versió {version}",
"@settingsAboutVersion": {
"placeholders": {
"version": {
"type": "String"
}
}
},
"settingsMusicName": "Música",
"@settingsMusicName": {},
"settingsMusicOptionsScrobbleDescriptionOff": "No capturar l'historial de reproducció",
"@settingsMusicOptionsScrobbleDescriptionOff": {},
"settingsMusicOptionsScrobbleDescriptionOn": "Capturar l'historial de reproduccions",
"@settingsMusicOptionsScrobbleDescriptionOn": {},
"settingsMusicOptionsScrobbleTitle": "Capturar la lectura",
"@settingsMusicOptionsScrobbleTitle": {},
"settingsNetworkName": "Xarxa",
"@settingsNetworkName": {},
"settingsNetworkOptionsMaxBitrateMobileTitle": "Taxa de bits màxima (mòbil)",
"@settingsNetworkOptionsMaxBitrateMobileTitle": {},
"settingsNetworkOptionsMaxBitrateWifiTitle": "Taxa de bits màxima (Wi-Fi)",
"@settingsNetworkOptionsMaxBitrateWifiTitle": {},
"settingsNetworkOptionsMaxBufferTitle": "Temps màxim en memòria intermèdia",
"@settingsNetworkOptionsMaxBufferTitle": {},
"settingsNetworkOptionsMinBufferTitle": "Temps mínim en memòria intermèdia",
"@settingsNetworkOptionsMinBufferTitle": {},
"settingsNetworkValuesKbps": "{value} kbps",
"@settingsNetworkValuesKbps": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesSeconds": "{value} segons",
"@settingsNetworkValuesSeconds": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesUnlimitedKbps": "Il·limitat",
"@settingsNetworkValuesUnlimitedKbps": {},
"settingsResetActionsClearImageCache": "Esborrar la memòria cau d'imatges",
"@settingsResetActionsClearImageCache": {},
"settingsResetName": "Reinicialitzar",
"@settingsResetName": {},
"settingsServersActionsAdd": "Afegir un servidor",
"@settingsServersActionsAdd": {},
"settingsServersActionsDelete": "Esborrar",
"@settingsServersActionsDelete": {},
"settingsServersActionsEdit": "Editar el servidor",
"@settingsServersActionsEdit": {},
"settingsServersActionsSave": "Desar",
"@settingsServersActionsSave": {},
"settingsServersActionsTestConnection": "Comprovar la connexió",
"@settingsServersActionsTestConnection": {},
"settingsServersFieldsAddress": "Adreça",
"@settingsServersFieldsAddress": {},
"settingsServersFieldsPassword": "Contrasenya",
"@settingsServersFieldsPassword": {},
"settingsServersFieldsUsername": "Nom dusuari",
"@settingsServersFieldsUsername": {},
"settingsServersMessagesConnectionFailed": "La connexió a {address} ha fallat, comprova la configuració o el servidor",
"@settingsServersMessagesConnectionFailed": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersMessagesConnectionOk": "Connexió a {address} OK!",
"@settingsServersMessagesConnectionOk": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersName": "Servidors",
"@settingsServersName": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Enviar contrasenya com a token + salt",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Enviar la contrasenya en text sense format (obsolet, assegura't que la teva connexió sigui segura!)",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {},
"settingsServersOptionsForcePlaintextPasswordTitle": "Forçar la contrasenya de text sense format",
"@settingsServersOptionsForcePlaintextPasswordTitle": {}
}

226
lib/l10n/app_cs.arb Normal file
View File

@@ -0,0 +1,226 @@
{
"actionsStar": "Ohodnotit",
"@actionsStar": {},
"actionsUnstar": "Zrušit hodnocení",
"@actionsUnstar": {},
"messagesNothingHere": "Zde nic není…",
"@messagesNothingHere": {},
"navigationTabsHome": "Domů",
"@navigationTabsHome": {},
"navigationTabsLibrary": "Knihovna",
"@navigationTabsLibrary": {},
"navigationTabsSearch": "Hledat",
"@navigationTabsSearch": {},
"navigationTabsSettings": "Nastavení",
"@navigationTabsSettings": {},
"resourcesAlbumActionsPlay": "Přehrát album",
"@resourcesAlbumActionsPlay": {},
"resourcesAlbumActionsView": "Zobrazit album",
"@resourcesAlbumActionsView": {},
"resourcesAlbumListsSort": "Seřadit alba",
"@resourcesAlbumListsSort": {},
"resourcesAlbumName": "{count,plural, =1{Album} few{Alba} many{Alba} other{Alba}}",
"@resourcesAlbumName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesArtistActionsView": "Zobrazit umělce",
"@resourcesArtistActionsView": {},
"resourcesArtistListsSort": "Seřadit umělce",
"@resourcesArtistListsSort": {},
"resourcesArtistName": "{count,plural, =1{Umělec} few{Umělci} many{Umělci} other{Umělci}}",
"@resourcesArtistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesFilterGenre": "Podle žánru",
"@resourcesFilterGenre": {},
"resourcesFilterStarred": "Ohodnocené",
"@resourcesFilterStarred": {},
"resourcesPlaylistActionsPlay": "Přehrát seznam skladeb",
"@resourcesPlaylistActionsPlay": {},
"resourcesPlaylistName": "{count,plural, =1{Seznam skladeb} few{Seznamy skladeb} many{Seznamy skladeb} other{Seznamy skladeb}}",
"@resourcesPlaylistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesQueueName": "{count,plural, =1{Fronta} few{Fronty} many{Fronty} other{Fronty}}",
"@resourcesQueueName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSongListsArtistTopSongs": "Top skladby",
"@resourcesSongListsArtistTopSongs": {},
"resourcesSongName": "{count,plural, =1{Skladba} few{Skladby} many{Skladby} other{Skladby}}",
"@resourcesSongName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSortByAdded": "Nedávno přidané",
"@resourcesSortByAdded": {},
"resourcesSortByArtist": "Umělce",
"@resourcesSortByArtist": {},
"resourcesSortByFrequentlyPlayed": "Často přehrávané",
"@resourcesSortByFrequentlyPlayed": {},
"resourcesSortByName": "Názvu",
"@resourcesSortByName": {},
"resourcesSortByRandom": "Náhodně",
"@resourcesSortByRandom": {},
"resourcesSortByRecentlyPlayed": "Často přehrávané",
"@resourcesSortByRecentlyPlayed": {},
"resourcesSortByYear": "Roku",
"@resourcesSortByYear": {},
"searchHeaderTitle": "Hledat: {query}",
"@searchHeaderTitle": {
"placeholders": {
"query": {
"type": "String"
}
}
},
"searchInputPlaceholder": "Hledat",
"@searchInputPlaceholder": {},
"searchMoreResults": "Více…",
"@searchMoreResults": {},
"searchNowPlayingContext": "Výsledky hledání",
"@searchNowPlayingContext": {},
"settingsNetworkName": "Síť",
"@settingsNetworkName": {},
"settingsNetworkOptionsMaxBitrateMobileTitle": "Maximální datový tok (mobil)",
"@settingsNetworkOptionsMaxBitrateMobileTitle": {},
"settingsNetworkOptionsMaxBitrateWifiTitle": "Maximální datový tok (Wi-Fi)",
"@settingsNetworkOptionsMaxBitrateWifiTitle": {},
"settingsNetworkValuesKbps": "{value}kbps",
"@settingsNetworkValuesKbps": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesSeconds": "{value} sekund",
"@settingsNetworkValuesSeconds": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesUnlimitedKbps": "Neomezeno",
"@settingsNetworkValuesUnlimitedKbps": {},
"settingsServersActionsAdd": "Přidat server",
"@settingsServersActionsAdd": {},
"settingsServersActionsDelete": "Odstranit",
"@settingsServersActionsDelete": {},
"settingsServersActionsEdit": "Upravit server",
"@settingsServersActionsEdit": {},
"settingsServersActionsSave": "Uložit",
"@settingsServersActionsSave": {},
"settingsServersActionsTestConnection": "Otestovat spojení",
"@settingsServersActionsTestConnection": {},
"settingsServersFieldsAddress": "Adresa",
"@settingsServersFieldsAddress": {},
"settingsServersFieldsPassword": "Heslo",
"@settingsServersFieldsPassword": {},
"settingsServersFieldsUsername": "Uživ. jméno",
"@settingsServersFieldsUsername": {},
"settingsServersMessagesConnectionFailed": "Připojení k {address} selhalo, zkontrolujte nastavení nebo server",
"@settingsServersMessagesConnectionFailed": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersMessagesConnectionOk": "Připojení k {address} je OK!",
"@settingsServersMessagesConnectionOk": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersName": "Servery",
"@settingsServersName": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Posílat heslo jako token + salt",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Posílat heslo v prostém textu (zastaralé, ujistěte se, že je vaše připojení zabezpečené!)",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {},
"settingsServersOptionsForcePlaintextPasswordTitle": "Vynutit heslo ve formátu prostého textu",
"@settingsServersOptionsForcePlaintextPasswordTitle": {},
"actionsDownloadDelete": "Smazat stažené",
"@actionsDownloadDelete": {},
"actionsOk": "OK",
"@actionsOk": {},
"actionsCancel": "Zrušit",
"@actionsCancel": {},
"actionsDownload": "Stáhnout",
"@actionsDownload": {},
"controlsShuffle": "Náhodně",
"@controlsShuffle": {},
"resourcesFilterAlbum": "Album",
"@resourcesFilterAlbum": {},
"resourcesFilterArtist": "Umělec",
"@resourcesFilterArtist": {},
"resourcesFilterYear": "Rok",
"@resourcesFilterYear": {},
"resourcesFilterOwner": "Majitele",
"@resourcesFilterOwner": {},
"resourcesSongListDeleteAllTitle": "Smazat stažené?",
"@resourcesSongListDeleteAllTitle": {},
"resourcesSongListDeleteAllContent": "Toto odstraní všechny stažené soubory s hudbou.",
"@resourcesSongListDeleteAllContent": {},
"resourcesSortByUpdated": "Naposledy upravené",
"@resourcesSortByUpdated": {},
"resourcesSortByAlbum": "Alba",
"@resourcesSortByAlbum": {},
"resourcesSortByAlbumCount": "Počtu alb",
"@resourcesSortByAlbumCount": {},
"resourcesSortByTitle": "Názvu",
"@resourcesSortByTitle": {},
"settingsAboutActionsLicenses": "Licence",
"@settingsAboutActionsLicenses": {},
"settingsAboutActionsProjectHomepage": "Stránka projektu",
"@settingsAboutActionsProjectHomepage": {},
"settingsAboutActionsSupport": "Podpořit vývojáře 💜",
"@settingsAboutActionsSupport": {},
"settingsAboutVersion": "verze {version}",
"@settingsAboutVersion": {
"placeholders": {
"version": {
"type": "String"
}
}
},
"settingsNetworkOptionsStreamFormat": "Preferovaný formát pro streamování",
"@settingsNetworkOptionsStreamFormat": {},
"settingsNetworkOptionsStreamFormatServerDefault": "Použít nastavení serveru",
"@settingsNetworkOptionsStreamFormatServerDefault": {},
"settingsResetActionsClearImageCache": "Smazat mezipaměť obrázků",
"@settingsResetActionsClearImageCache": {},
"settingsResetName": "Resetovat",
"@settingsResetName": {},
"settingsServersFieldsName": "Jméno",
"@settingsServersFieldsName": {},
"settingsAboutName": "O aplikaci",
"@settingsAboutName": {},
"actionsDownloadCancel": "Zrušit stahování",
"@actionsDownloadCancel": {},
"actionsDelete": "Smazat",
"@actionsDelete": {}
}

176
lib/l10n/app_da.arb Normal file
View File

@@ -0,0 +1,176 @@
{
"messagesNothingHere": "Intet her…",
"@messagesNothingHere": {},
"navigationTabsHome": "Hjem",
"@navigationTabsHome": {},
"navigationTabsLibrary": "Bibliotek",
"@navigationTabsLibrary": {},
"navigationTabsSearch": "Søg",
"@navigationTabsSearch": {},
"navigationTabsSettings": "Indstillinger",
"@navigationTabsSettings": {},
"resourcesAlbumActionsPlay": "Afspil album",
"@resourcesAlbumActionsPlay": {},
"resourcesAlbumActionsView": "Se album",
"@resourcesAlbumActionsView": {},
"resourcesAlbumListsSort": "Sortér albums",
"@resourcesAlbumListsSort": {},
"resourcesAlbumName": "{count,plural, =1{Album} other{Albums}}",
"@resourcesAlbumName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesArtistActionsView": "Se kunstnere",
"@resourcesArtistActionsView": {},
"resourcesArtistListsSort": "Sortér kunstnere",
"@resourcesArtistListsSort": {},
"resourcesArtistName": "{count,plural, =1{Kunstner} other{Kunstnere}}",
"@resourcesArtistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesFilterGenre": "Efter genre",
"@resourcesFilterGenre": {},
"resourcesPlaylistActionsPlay": "Afspil spilleliste",
"@resourcesPlaylistActionsPlay": {},
"resourcesPlaylistName": "{count,plural, =1{Spilleliste} other{Spillelister}}",
"@resourcesPlaylistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesQueueName": "{count,plural, =1{Kø} other{Køer}}",
"@resourcesQueueName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSongListsArtistTopSongs": "Top sange",
"@resourcesSongListsArtistTopSongs": {},
"resourcesSongName": "{count,plural, =1{Sang} other{Sange}}",
"@resourcesSongName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSortByArtist": "Efter kunstner",
"@resourcesSortByArtist": {},
"resourcesSortByName": "Efter navn",
"@resourcesSortByName": {},
"resourcesSortByRandom": "Tilfældig",
"@resourcesSortByRandom": {},
"resourcesSortByYear": "Efter år",
"@resourcesSortByYear": {},
"searchHeaderTitle": "Søg: {query}",
"@searchHeaderTitle": {
"placeholders": {
"query": {
"type": "String"
}
}
},
"searchInputPlaceholder": "Søg",
"@searchInputPlaceholder": {},
"searchMoreResults": "Mere…",
"@searchMoreResults": {},
"searchNowPlayingContext": "Søgeresultater",
"@searchNowPlayingContext": {},
"settingsAboutActionsLicenses": "Licenser",
"@settingsAboutActionsLicenses": {},
"settingsAboutActionsProjectHomepage": "Projekt hjemmeside",
"@settingsAboutActionsProjectHomepage": {},
"settingsAboutName": "Omkring",
"@settingsAboutName": {},
"settingsAboutVersion": "version {version}",
"@settingsAboutVersion": {
"placeholders": {
"version": {
"type": "String"
}
}
},
"settingsMusicName": "Musik",
"@settingsMusicName": {},
"settingsMusicOptionsScrobbleDescriptionOn": "Scrobble afspilningshistorik",
"@settingsMusicOptionsScrobbleDescriptionOn": {},
"settingsMusicOptionsScrobbleTitle": "Scrobble afspilninger",
"@settingsMusicOptionsScrobbleTitle": {},
"settingsNetworkName": "Netværk",
"@settingsNetworkName": {},
"settingsNetworkOptionsMaxBitrateMobileTitle": "Maksimum bitrate (mobil)",
"@settingsNetworkOptionsMaxBitrateMobileTitle": {},
"settingsNetworkOptionsMaxBitrateWifiTitle": "Maksimum bitrate (Wi-Fi)",
"@settingsNetworkOptionsMaxBitrateWifiTitle": {},
"settingsNetworkOptionsMaxBufferTitle": "Maksimum buffertid",
"@settingsNetworkOptionsMaxBufferTitle": {},
"settingsNetworkOptionsMinBufferTitle": "Minimum buffertid",
"@settingsNetworkOptionsMinBufferTitle": {},
"settingsNetworkValuesKbps": "{value}kbps",
"@settingsNetworkValuesKbps": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesSeconds": "{value} sekunder",
"@settingsNetworkValuesSeconds": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesUnlimitedKbps": "Ubegrænset",
"@settingsNetworkValuesUnlimitedKbps": {},
"settingsResetActionsClearImageCache": "Ryd billede cache",
"@settingsResetActionsClearImageCache": {},
"settingsResetName": "Nulstil",
"@settingsResetName": {},
"settingsServersActionsAdd": "Tilføj server",
"@settingsServersActionsAdd": {},
"settingsServersActionsDelete": "Slet",
"@settingsServersActionsDelete": {},
"settingsServersActionsEdit": "Redigér server",
"@settingsServersActionsEdit": {},
"settingsServersActionsSave": "Gem",
"@settingsServersActionsSave": {},
"settingsServersActionsTestConnection": "Test forbindelse",
"@settingsServersActionsTestConnection": {},
"settingsServersFieldsAddress": "Adresse",
"@settingsServersFieldsAddress": {},
"settingsServersFieldsPassword": "Adgangskode",
"@settingsServersFieldsPassword": {},
"settingsServersFieldsUsername": "Brugernavn",
"@settingsServersFieldsUsername": {},
"settingsServersMessagesConnectionFailed": "Forbindelse til {address} mislykkedes, tjek indstillinger eller server",
"@settingsServersMessagesConnectionFailed": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersMessagesConnectionOk": "Forbindelse til {address} OK!",
"@settingsServersMessagesConnectionOk": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersName": "Servere",
"@settingsServersName": {}
}

276
lib/l10n/app_de.arb Normal file
View File

@@ -0,0 +1,276 @@
{
"actionsStar": "Markieren",
"@actionsStar": {},
"actionsUnstar": "Markierung entfernen",
"@actionsUnstar": {},
"messagesNothingHere": "Hier ist nichts…",
"@messagesNothingHere": {},
"navigationTabsHome": "Startseite",
"@navigationTabsHome": {},
"navigationTabsLibrary": "Bibliothek",
"@navigationTabsLibrary": {},
"navigationTabsSearch": "Suche",
"@navigationTabsSearch": {},
"navigationTabsSettings": "Einstellungen",
"@navigationTabsSettings": {},
"resourcesAlbumActionsPlay": "Album abspielen",
"@resourcesAlbumActionsPlay": {},
"resourcesAlbumActionsView": "Album anzeigen",
"@resourcesAlbumActionsView": {},
"resourcesAlbumListsSort": "Alben sortieren",
"@resourcesAlbumListsSort": {},
"resourcesAlbumName": "{count,plural, =1{Album} other{Alben}}",
"@resourcesAlbumName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesArtistActionsView": "Interpret anzeigen",
"@resourcesArtistActionsView": {},
"resourcesArtistListsSort": "Interpreten sortieren",
"@resourcesArtistListsSort": {},
"resourcesArtistName": "{count,plural, =1{Interpret} other{Interpreten}}",
"@resourcesArtistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesFilterGenre": "Nach Genre",
"@resourcesFilterGenre": {},
"resourcesFilterStarred": "Favoriten",
"@resourcesFilterStarred": {},
"resourcesPlaylistActionsPlay": "Wiedergabeliste abspielen",
"@resourcesPlaylistActionsPlay": {},
"resourcesPlaylistName": "{count,plural, =1{Wiedergabeliste} other{Wiedergabelisten}}",
"@resourcesPlaylistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesQueueName": "{count,plural, =1{Warteschlange} other{Warteschlangen}}",
"@resourcesQueueName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSongListsArtistTopSongs": "Top Lieder",
"@resourcesSongListsArtistTopSongs": {},
"resourcesSongName": "{count,plural, =1{Lied} other{Lieder}}",
"@resourcesSongName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSortByAdded": "Kürzlich hinzugefügt",
"@resourcesSortByAdded": {},
"resourcesSortByArtist": "Nach Interpreten",
"@resourcesSortByArtist": {},
"resourcesSortByFrequentlyPlayed": "Häufig abgespielt",
"@resourcesSortByFrequentlyPlayed": {},
"resourcesSortByName": "Nach Name",
"@resourcesSortByName": {},
"resourcesSortByRandom": "Zufällig",
"@resourcesSortByRandom": {},
"resourcesSortByRecentlyPlayed": "Kürzlich abgespielt",
"@resourcesSortByRecentlyPlayed": {},
"resourcesSortByYear": "Nach Jahr",
"@resourcesSortByYear": {},
"searchHeaderTitle": "Suche: {query}",
"@searchHeaderTitle": {
"placeholders": {
"query": {
"type": "String"
}
}
},
"searchInputPlaceholder": "Suche",
"@searchInputPlaceholder": {},
"searchMoreResults": "Mehr…",
"@searchMoreResults": {},
"searchNowPlayingContext": "Suchergebnis",
"@searchNowPlayingContext": {},
"settingsAboutActionsLicenses": "Lizenzen",
"@settingsAboutActionsLicenses": {},
"settingsAboutActionsProjectHomepage": "Projektseite",
"@settingsAboutActionsProjectHomepage": {},
"settingsAboutName": "Über",
"@settingsAboutName": {},
"settingsAboutVersion": "Version {version}",
"@settingsAboutVersion": {
"placeholders": {
"version": {
"type": "String"
}
}
},
"settingsMusicName": "Musik",
"@settingsMusicName": {},
"settingsMusicOptionsScrobbleDescriptionOff": "Kein Scrobble für Wiedergabeverlauf",
"@settingsMusicOptionsScrobbleDescriptionOff": {},
"settingsMusicOptionsScrobbleDescriptionOn": "Scrobble Wiedergabeverlauf",
"@settingsMusicOptionsScrobbleDescriptionOn": {},
"settingsMusicOptionsScrobbleTitle": "Scrobble Wiedergabe",
"@settingsMusicOptionsScrobbleTitle": {},
"settingsNetworkName": "Netzwerk",
"@settingsNetworkName": {},
"settingsNetworkOptionsMaxBitrateMobileTitle": "Maximale Bitrate (Mobil)",
"@settingsNetworkOptionsMaxBitrateMobileTitle": {},
"settingsNetworkOptionsMaxBitrateWifiTitle": "Maximale Bitrate (WLAN)",
"@settingsNetworkOptionsMaxBitrateWifiTitle": {},
"settingsNetworkOptionsMaxBufferTitle": "Maximale Pufferzeit",
"@settingsNetworkOptionsMaxBufferTitle": {},
"settingsNetworkOptionsMinBufferTitle": "Minimale Pufferzeit",
"@settingsNetworkOptionsMinBufferTitle": {},
"settingsNetworkValuesKbps": "{value}kbps",
"@settingsNetworkValuesKbps": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesSeconds": "{value} Sekunden",
"@settingsNetworkValuesSeconds": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesUnlimitedKbps": "Unbegrenzt",
"@settingsNetworkValuesUnlimitedKbps": {},
"settingsResetActionsClearImageCache": "Bildzwischenspeicher löschen",
"@settingsResetActionsClearImageCache": {},
"settingsResetName": "Zurücksetzen",
"@settingsResetName": {},
"settingsServersActionsAdd": "Server hinzufügen",
"@settingsServersActionsAdd": {},
"settingsServersActionsDelete": "Löschen",
"@settingsServersActionsDelete": {},
"settingsServersActionsEdit": "Server bearbeiten",
"@settingsServersActionsEdit": {},
"settingsServersActionsSave": "Speichern",
"@settingsServersActionsSave": {},
"settingsServersActionsTestConnection": "Verbindung testen",
"@settingsServersActionsTestConnection": {},
"settingsServersFieldsAddress": "Adresse",
"@settingsServersFieldsAddress": {},
"settingsServersFieldsPassword": "Passwort",
"@settingsServersFieldsPassword": {},
"settingsServersFieldsUsername": "Nutzername",
"@settingsServersFieldsUsername": {},
"settingsServersMessagesConnectionFailed": "Verbindung zu {address} fehlgeschlagen, überprüfe Einstellungen oder Server",
"@settingsServersMessagesConnectionFailed": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersMessagesConnectionOk": "Verbindung zu {address} ist OK!",
"@settingsServersMessagesConnectionOk": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersName": "Server",
"@settingsServersName": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Sende Passwort als Token + Salt",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Passwort als Klartext senden (Veraltet, stellen Sie sicher, dass Ihre Verbindung sicher ist!)",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {},
"settingsServersOptionsForcePlaintextPasswordTitle": "Erzwinge Klartextpasswort",
"@settingsServersOptionsForcePlaintextPasswordTitle": {},
"actionsDelete": "Löschen",
"@actionsDelete": {},
"actionsDownload": "Herunterladen",
"@actionsDownload": {},
"actionsDownloadCancel": "Download abbrechen",
"@actionsDownloadCancel": {},
"controlsShuffle": "Zufall",
"@controlsShuffle": {},
"actionsCancel": "Abbrechen",
"@actionsCancel": {},
"actionsDownloadDelete": "Heruntergeladene Inhalte löschen",
"@actionsDownloadDelete": {},
"actionsOk": "OK",
"@actionsOk": {},
"resourcesAlbumCount": "{count,plural, =1{{count} Album} other{{count} Alben}}",
"@resourcesAlbumCount": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesFilterAlbum": "Album",
"@resourcesFilterAlbum": {},
"resourcesArtistCount": "{count,plural, =1{{count} Künstler} other{{count} Künstler}}",
"@resourcesArtistCount": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesFilterArtist": "Künstler",
"@resourcesFilterArtist": {},
"resourcesFilterOwner": "Besitzer",
"@resourcesFilterOwner": {},
"resourcesFilterYear": "Jahr",
"@resourcesFilterYear": {},
"resourcesPlaylistCount": "{count,plural, =1{{count} Playlist} other{{count} Playlists}}",
"@resourcesPlaylistCount": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSongCount": "{count,plural, =1{{count} Song} other{{count} Songs}}",
"@resourcesSongCount": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSongListDeleteAllContent": "Hierdurch werden alle heruntergeladenen Inhalte entfernt.",
"@resourcesSongListDeleteAllContent": {},
"resourcesSortByAlbum": "Album",
"@resourcesSortByAlbum": {},
"resourcesSortByAlbumCount": "Albenanzahl",
"@resourcesSortByAlbumCount": {},
"resourcesSortByTitle": "Titel",
"@resourcesSortByTitle": {},
"resourcesSortByUpdated": "Kürzlich hinzugefügt",
"@resourcesSortByUpdated": {},
"settingsAboutActionsSupport": "Den Entwickler unterstützen",
"@settingsAboutActionsSupport": {},
"settingsNetworkOptionsOfflineMode": "Offline Modus",
"@settingsNetworkOptionsOfflineMode": {},
"settingsNetworkOptionsOfflineModeOff": "Nutze das Internet um Musik zu synchronisieren.",
"@settingsNetworkOptionsOfflineModeOff": {},
"settingsNetworkOptionsOfflineModeOn": "Nutze nicht das Internet um Musik zu synchronisieren.",
"@settingsNetworkOptionsOfflineModeOn": {},
"settingsNetworkOptionsStreamFormat": "Bevorzugtes Streaming-Format",
"@settingsNetworkOptionsStreamFormat": {},
"settingsServersFieldsName": "Name",
"@settingsServersFieldsName": {},
"resourcesSongListDeleteAllTitle": "Downloads löschen?",
"@resourcesSongListDeleteAllTitle": {},
"settingsNetworkOptionsStreamFormatServerDefault": "Server-Standard verwenden",
"@settingsNetworkOptionsStreamFormatServerDefault": {}
}

289
lib/l10n/app_en.arb Normal file
View File

@@ -0,0 +1,289 @@
{
"@@locale": "en",
"actionsCancel": "Cancel",
"@actionsCancel": {},
"actionsDelete": "Delete",
"@actionsDelete": {},
"actionsDownload": "Download",
"@actionsDownload": {},
"actionsDownloadCancel": "Cancel download",
"@actionsDownloadCancel": {},
"actionsDownloadDelete": "Delete downloaded",
"@actionsDownloadDelete": {},
"actionsOk": "OK",
"@actionsOk": {},
"actionsStar": "Star",
"@actionsStar": {},
"actionsUnstar": "Unstar",
"@actionsUnstar": {},
"controlsShuffle": "Shuffle",
"@controlsShuffle": {},
"messagesNothingHere": "Nothing here…",
"@messagesNothingHere": {},
"navigationTabsHome": "Home",
"@navigationTabsHome": {},
"navigationTabsAlbums": "Albums",
"@navigationTabsAlbums": {},
"navigationTabsArtists": "Artists",
"@navigationTabsArtists": {},
"navigationTabsPlaylists": "Playlists",
"@navigationTabsPlaylists": {},
"navigationTabsSongs": "Songs",
"@navigationTabsSongs": {},
"navigationTabsLibrary": "Library",
"@navigationTabsLibrary": {},
"navigationTabsSearch": "Search",
"@navigationTabsSearch": {},
"navigationTabsSettings": "Settings",
"@navigationTabsSettings": {},
"resourcesAlbumActionsPlay": "Play album",
"@resourcesAlbumActionsPlay": {},
"resourcesAlbumActionsView": "View album",
"@resourcesAlbumActionsView": {},
"resourcesAlbumCount": "{count,plural, =1{{count} album} other{{count} albums}}",
"@resourcesAlbumCount": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesAlbumListsSort": "Sort albums",
"@resourcesAlbumListsSort": {},
"resourcesAlbumName": "{count,plural, =1{Album} other{Albums}}",
"@resourcesAlbumName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesArtistActionsView": "View artist",
"@resourcesArtistActionsView": {},
"resourcesArtistCount": "{count,plural, =1{{count} artist} other{{count} artists}}",
"@resourcesArtistCount": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesArtistListsSort": "Sort artists",
"@resourcesArtistListsSort": {},
"resourcesArtistName": "{count,plural, =1{Artist} other{Artists}}",
"@resourcesArtistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesFilterAlbum": "Album",
"@resourcesFilterAlbum": {},
"resourcesFilterArtist": "Artist",
"@resourcesFilterArtist": {},
"resourcesFilterGenre": "Genre",
"@resourcesFilterGenre": {},
"resourcesFilterOwner": "Owner",
"@resourcesFilterOwner": {},
"resourcesFilterStarred": "Starred",
"@resourcesFilterStarred": {},
"resourcesFilterYear": "Year",
"@resourcesFilterYear": {},
"resourcesPlaylistActionsPlay": "Play playlist",
"@resourcesPlaylistActionsPlay": {},
"resourcesPlaylistCount": "{count,plural, =1{{count} playlist} other{{count} playlists}}",
"@resourcesPlaylistCount": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesPlaylistName": "{count,plural, =1{Playlist} other{Playlists}}",
"@resourcesPlaylistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesQueueName": "{count,plural, =1{Queue} other{Queues}}",
"@resourcesQueueName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSongCount": "{count,plural, =1{{count} song} other{{count} songs}}",
"@resourcesSongCount": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSongListDeleteAllContent": "This will remove all downloaded song files.",
"@resourcesSongListDeleteAllContent": {},
"resourcesSongListDeleteAllTitle": "Delete downloads?",
"@resourcesSongListDeleteAllTitle": {},
"resourcesSongListsArtistTopSongs": "Top Songs",
"@resourcesSongListsArtistTopSongs": {},
"resourcesSongName": "{count,plural, =1{Song} other{Songs}}",
"@resourcesSongName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSortByAdded": "Recently added",
"@resourcesSortByAdded": {},
"resourcesSortByAlbum": "Album",
"@resourcesSortByAlbum": {},
"resourcesSortByAlbumCount": "Album count",
"@resourcesSortByAlbumCount": {},
"resourcesSortByArtist": "Artist",
"@resourcesSortByArtist": {},
"resourcesSortByFrequentlyPlayed": "Frequently played",
"@resourcesSortByFrequentlyPlayed": {},
"resourcesSortByName": "Name",
"@resourcesSortByName": {},
"resourcesSortByRandom": "Random",
"@resourcesSortByRandom": {},
"resourcesSortByRecentlyPlayed": "Recently played",
"@resourcesSortByRecentlyPlayed": {},
"resourcesSortByTitle": "Title",
"@resourcesSortByTitle": {},
"resourcesSortByUpdated": "Recently updated",
"@resourcesSortByUpdated": {},
"resourcesSortByYear": "Year",
"@resourcesSortByYear": {},
"searchHeaderTitle": "Search: {query}",
"@searchHeaderTitle": {
"placeholders": {
"query": {
"type": "String"
}
}
},
"searchInputPlaceholder": "Search",
"@searchInputPlaceholder": {},
"searchMoreResults": "More…",
"@searchMoreResults": {},
"searchNowPlayingContext": "Search results",
"@searchNowPlayingContext": {},
"settingsAboutActionsLicenses": "Licenses",
"@settingsAboutActionsLicenses": {},
"settingsAboutActionsProjectHomepage": "Project homepage",
"@settingsAboutActionsProjectHomepage": {},
"settingsAboutActionsSupport": "Support the developer 💜",
"@settingsAboutActionsSupport": {},
"settingsAboutName": "About",
"@settingsAboutName": {},
"settingsAboutShareLogs": "Share logs",
"@settingsAboutShareLogs": {},
"settingsAboutChooseLog": "Choose a log file",
"@settingsAboutChooseLog": {},
"settingsAboutVersion": "version {version}",
"@settingsAboutVersion": {
"placeholders": {
"version": {
"type": "String"
}
}
},
"settingsMusicName": "Music",
"@settingsMusicName": {},
"settingsMusicOptionsScrobbleDescriptionOff": "Don't scrobble play history",
"@settingsMusicOptionsScrobbleDescriptionOff": {},
"settingsMusicOptionsScrobbleDescriptionOn": "Scrobble play history",
"@settingsMusicOptionsScrobbleDescriptionOn": {},
"settingsMusicOptionsScrobbleTitle": "Scrobble plays",
"@settingsMusicOptionsScrobbleTitle": {},
"settingsNetworkName": "Network",
"@settingsNetworkName": {},
"settingsNetworkOptionsMaxBitrateMobileTitle": "Maximum bitrate (mobile data)",
"@settingsNetworkOptionsMaxBitrateMobileTitle": {},
"settingsNetworkOptionsMaxBitrateWifiTitle": "Maximum bitrate (Wi-Fi)",
"@settingsNetworkOptionsMaxBitrateWifiTitle": {},
"settingsNetworkOptionsMaxBufferTitle": "Maximum buffer time",
"@settingsNetworkOptionsMaxBufferTitle": {},
"settingsNetworkOptionsMinBufferTitle": "Minimum buffer time",
"@settingsNetworkOptionsMinBufferTitle": {},
"settingsNetworkOptionsOfflineMode": "Offline mode",
"@settingsNetworkOptionsOfflineMode": {},
"settingsNetworkOptionsOfflineModeOff": "Use the internet to sync music.",
"@settingsNetworkOptionsOfflineModeOff": {},
"settingsNetworkOptionsOfflineModeOn": "Don't use the internet to sync or play music.",
"@settingsNetworkOptionsOfflineModeOn": {},
"settingsNetworkOptionsStreamFormat": "Preferred stream format",
"@settingsNetworkOptionsStreamFormat": {},
"settingsNetworkOptionsStreamFormatServerDefault": "Use server default",
"@settingsNetworkOptionsStreamFormatServerDefault": {},
"settingsNetworkValuesKbps": "{value}kbps",
"@settingsNetworkValuesKbps": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesSeconds": "{value} seconds",
"@settingsNetworkValuesSeconds": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesUnlimitedKbps": "Unlimited",
"@settingsNetworkValuesUnlimitedKbps": {},
"settingsResetActionsClearImageCache": "Clear Image Cache",
"@settingsResetActionsClearImageCache": {},
"settingsResetName": "Reset",
"@settingsResetName": {},
"settingsServersActionsAdd": "Add source",
"@settingsServersActionsAdd": {},
"settingsServersActionsDelete": "Delete",
"@settingsServersActionsDelete": {},
"settingsServersActionsEdit": "Edit source",
"@settingsServersActionsEdit": {},
"settingsServersActionsSave": "Save",
"@settingsServersActionsSave": {},
"settingsServersActionsTestConnection": "Test connection",
"@settingsServersActionsTestConnection": {},
"settingsServersFieldsAddress": "Address",
"@settingsServersFieldsAddress": {},
"settingsServersFieldsName": "Name",
"@settingsServersFieldsName": {},
"settingsServersFieldsPassword": "Password",
"@settingsServersFieldsPassword": {},
"settingsServersFieldsUsername": "Username",
"@settingsServersFieldsUsername": {},
"settingsServersMessagesConnectionFailed": "Connection to {address} failed, check settings or server",
"@settingsServersMessagesConnectionFailed": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersMessagesConnectionOk": "Connection to {address} OK!",
"@settingsServersMessagesConnectionOk": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersName": "Sources",
"@settingsServersName": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Send password as token + salt",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Send password in plaintext (legacy, make sure your connection is secure!)",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {},
"settingsServersOptionsForcePlaintextPasswordTitle": "Force plaintext password",
"@settingsServersOptionsForcePlaintextPasswordTitle": {}
}

210
lib/l10n/app_es.arb Normal file
View File

@@ -0,0 +1,210 @@
{
"actionsStar": "Favorito",
"@actionsStar": {},
"actionsUnstar": "Retirar favorito",
"@actionsUnstar": {},
"messagesNothingHere": "Nada aquí…",
"@messagesNothingHere": {},
"navigationTabsHome": "Casa",
"@navigationTabsHome": {},
"navigationTabsLibrary": "Biblioteca",
"@navigationTabsLibrary": {},
"navigationTabsSearch": "Buscar",
"@navigationTabsSearch": {},
"navigationTabsSettings": "Entorno",
"@navigationTabsSettings": {},
"resourcesAlbumActionsPlay": "Reproducir Álbum",
"@resourcesAlbumActionsPlay": {},
"resourcesAlbumActionsView": "Ver Álbum",
"@resourcesAlbumActionsView": {},
"resourcesAlbumListsSort": "Ordenar Álbumes",
"@resourcesAlbumListsSort": {},
"resourcesAlbumName": "{count,plural, =1{Álbum} other{Álbumes}}",
"@resourcesAlbumName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesArtistActionsView": "Ver Artista",
"@resourcesArtistActionsView": {},
"resourcesArtistListsSort": "Oredenar Artistas",
"@resourcesArtistListsSort": {},
"resourcesArtistName": "{count,plural, =1{Artista} other{Artistas}}",
"@resourcesArtistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesFilterGenre": "Por Género",
"@resourcesFilterGenre": {},
"resourcesFilterStarred": "Estrellas",
"@resourcesFilterStarred": {},
"resourcesPlaylistActionsPlay": "Reproducir Lista de reproducción",
"@resourcesPlaylistActionsPlay": {},
"resourcesPlaylistName": "{count,plural, =1{Lista de reproducción} other{Listas de reproducción}}",
"@resourcesPlaylistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesQueueName": "{count,plural, =1{Cola} other{Colas}}",
"@resourcesQueueName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSongListsArtistTopSongs": "Mejores Canciones",
"@resourcesSongListsArtistTopSongs": {},
"resourcesSongName": "{count,plural, =1{Cancion} other{Canciones}}",
"@resourcesSongName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSortByAdded": "Recientemente Añadido",
"@resourcesSortByAdded": {},
"resourcesSortByArtist": "Por Artista",
"@resourcesSortByArtist": {},
"resourcesSortByFrequentlyPlayed": "Jugado Frecuentemente",
"@resourcesSortByFrequentlyPlayed": {},
"resourcesSortByName": "Por Nombre",
"@resourcesSortByName": {},
"resourcesSortByRandom": "Aleatorio",
"@resourcesSortByRandom": {},
"resourcesSortByRecentlyPlayed": "Recientemente Jugado",
"@resourcesSortByRecentlyPlayed": {},
"resourcesSortByYear": "Por Año",
"@resourcesSortByYear": {},
"searchHeaderTitle": "Buscar: {query}",
"@searchHeaderTitle": {
"placeholders": {
"query": {
"type": "String"
}
}
},
"searchInputPlaceholder": "Buscar",
"@searchInputPlaceholder": {},
"searchMoreResults": "Más…",
"@searchMoreResults": {},
"searchNowPlayingContext": "Resultados de la búsqueda",
"@searchNowPlayingContext": {},
"settingsAboutActionsLicenses": "Licencias",
"@settingsAboutActionsLicenses": {},
"settingsAboutActionsProjectHomepage": "Página de inicio del proyecto",
"@settingsAboutActionsProjectHomepage": {},
"settingsAboutName": "Información",
"@settingsAboutName": {},
"settingsAboutVersion": "versión {version}",
"@settingsAboutVersion": {
"placeholders": {
"version": {
"type": "String"
}
}
},
"settingsMusicName": "Música",
"@settingsMusicName": {},
"settingsMusicOptionsScrobbleDescriptionOff": "No hagas historial de reproducción de scrobble",
"@settingsMusicOptionsScrobbleDescriptionOff": {},
"settingsMusicOptionsScrobbleDescriptionOn": "Historial de reproducción de scrobble",
"@settingsMusicOptionsScrobbleDescriptionOn": {},
"settingsMusicOptionsScrobbleTitle": "Obras de teatro de Scrobble",
"@settingsMusicOptionsScrobbleTitle": {},
"settingsNetworkName": "Sitio",
"@settingsNetworkName": {},
"settingsNetworkOptionsMaxBitrateMobileTitle": "Tasa de bits máxima (mobile)",
"@settingsNetworkOptionsMaxBitrateMobileTitle": {},
"settingsNetworkOptionsMaxBitrateWifiTitle": "Tasa de bits máxima (Wi-Fi)",
"@settingsNetworkOptionsMaxBitrateWifiTitle": {},
"settingsNetworkOptionsMaxBufferTitle": "Máxima de buffer tiempo",
"@settingsNetworkOptionsMaxBufferTitle": {},
"settingsNetworkOptionsMinBufferTitle": "Mínimo de buffer tiempo",
"@settingsNetworkOptionsMinBufferTitle": {},
"settingsNetworkValuesKbps": "{value} kilobytes por segundo",
"@settingsNetworkValuesKbps": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesSeconds": "{value} segundos",
"@settingsNetworkValuesSeconds": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesUnlimitedKbps": "Ilimitados",
"@settingsNetworkValuesUnlimitedKbps": {},
"settingsResetActionsClearImageCache": "Caché de imágenes claras",
"@settingsResetActionsClearImageCache": {},
"settingsResetName": "Reinicializar",
"@settingsResetName": {},
"settingsServersActionsAdd": "Agregar Servidor",
"@settingsServersActionsAdd": {},
"settingsServersActionsDelete": "Supr",
"@settingsServersActionsDelete": {},
"settingsServersActionsEdit": "Editar Servidor",
"@settingsServersActionsEdit": {},
"settingsServersActionsSave": "Enviar",
"@settingsServersActionsSave": {},
"settingsServersActionsTestConnection": "Conexión de prueba",
"@settingsServersActionsTestConnection": {},
"settingsServersFieldsAddress": "Alocución",
"@settingsServersFieldsAddress": {},
"settingsServersFieldsPassword": "La contraseña",
"@settingsServersFieldsPassword": {},
"settingsServersFieldsUsername": "Nombre de usuario",
"@settingsServersFieldsUsername": {},
"settingsServersMessagesConnectionFailed": "La conexión a {address} falló, verifique la configuracón o el servidor",
"@settingsServersMessagesConnectionFailed": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersMessagesConnectionOk": "¡Conexión con {address} Ok!",
"@settingsServersMessagesConnectionOk": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersName": "Servidores",
"@settingsServersName": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Enviar contraseña como token + sal",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Enviar contraseña en texto plano (¡legado, asegúrese de que su conexión sea segura!)",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {},
"settingsServersOptionsForcePlaintextPasswordTitle": "Forzar contraseña de texto sin formato",
"@settingsServersOptionsForcePlaintextPasswordTitle": {},
"actionsDelete": "Borrar",
"@actionsDelete": {},
"actionsOk": "Ok",
"@actionsOk": {},
"actionsDownload": "Descargar",
"@actionsDownload": {},
"actionsDownloadCancel": "Anular descargar",
"@actionsDownloadCancel": {},
"controlsShuffle": "Reproducir aleatoriamente",
"@controlsShuffle": {},
"actionsCancel": "Cancelar",
"@actionsCancel": {},
"actionsDownloadDelete": "Eliminar descargado",
"@actionsDownloadDelete": {}
}

196
lib/l10n/app_fr.arb Normal file
View File

@@ -0,0 +1,196 @@
{
"actionsStar": "Mettre en favoris",
"@actionsStar": {},
"actionsUnstar": "Enlever des favoris",
"@actionsUnstar": {},
"messagesNothingHere": "Rien ici…",
"@messagesNothingHere": {},
"navigationTabsHome": "Accueil",
"@navigationTabsHome": {},
"navigationTabsLibrary": "Bibliothèque",
"@navigationTabsLibrary": {},
"navigationTabsSearch": "Recherche",
"@navigationTabsSearch": {},
"navigationTabsSettings": "Paramètres",
"@navigationTabsSettings": {},
"resourcesAlbumActionsPlay": "Jouer l'album",
"@resourcesAlbumActionsPlay": {},
"resourcesAlbumActionsView": "Voir l'album",
"@resourcesAlbumActionsView": {},
"resourcesAlbumListsSort": "Trier les albums",
"@resourcesAlbumListsSort": {},
"resourcesAlbumName": "{count,plural, =1{Album} other{Albums}}",
"@resourcesAlbumName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesArtistActionsView": "Voir l'artiste",
"@resourcesArtistActionsView": {},
"resourcesArtistListsSort": "Trier les artistes",
"@resourcesArtistListsSort": {},
"resourcesArtistName": "{count,plural, =1{Artiste} other{Artistes}}",
"@resourcesArtistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesFilterGenre": "Par Genre",
"@resourcesFilterGenre": {},
"resourcesFilterStarred": "Favoris",
"@resourcesFilterStarred": {},
"resourcesPlaylistActionsPlay": "Lire la playlist",
"@resourcesPlaylistActionsPlay": {},
"resourcesPlaylistName": "{count,plural, =1{Playlist} other{Playlists}}",
"@resourcesPlaylistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesQueueName": "{count,plural, =1{File d'attente} other{Files d'attente}}",
"@resourcesQueueName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSongListsArtistTopSongs": "Meilleures Chansons",
"@resourcesSongListsArtistTopSongs": {},
"resourcesSongName": "{count,plural, =1{Chanson} other{Chansons}}",
"@resourcesSongName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSortByAdded": "Récemment Ajouté",
"@resourcesSortByAdded": {},
"resourcesSortByArtist": "Par Artiste",
"@resourcesSortByArtist": {},
"resourcesSortByFrequentlyPlayed": "Fréquemment Joué",
"@resourcesSortByFrequentlyPlayed": {},
"resourcesSortByName": "Par Nom",
"@resourcesSortByName": {},
"resourcesSortByRandom": "Aléatoire",
"@resourcesSortByRandom": {},
"resourcesSortByRecentlyPlayed": "Récemment Joué",
"@resourcesSortByRecentlyPlayed": {},
"resourcesSortByYear": "Par Année",
"@resourcesSortByYear": {},
"searchHeaderTitle": "Recherche : {query}",
"@searchHeaderTitle": {
"placeholders": {
"query": {
"type": "String"
}
}
},
"searchInputPlaceholder": "Recherche",
"@searchInputPlaceholder": {},
"searchMoreResults": "Plus…",
"@searchMoreResults": {},
"searchNowPlayingContext": "Résultats de recherche",
"@searchNowPlayingContext": {},
"settingsAboutActionsLicenses": "Licences",
"@settingsAboutActionsLicenses": {},
"settingsAboutActionsProjectHomepage": "Page d'accueil du projet",
"@settingsAboutActionsProjectHomepage": {},
"settingsAboutName": "À propos",
"@settingsAboutName": {},
"settingsAboutVersion": "version {version}",
"@settingsAboutVersion": {
"placeholders": {
"version": {
"type": "String"
}
}
},
"settingsMusicName": "Musique",
"@settingsMusicName": {},
"settingsMusicOptionsScrobbleDescriptionOff": "Ne pas scrobbler l'historique de lecture",
"@settingsMusicOptionsScrobbleDescriptionOff": {},
"settingsMusicOptionsScrobbleDescriptionOn": "Scrobbler l'historique de lecture",
"@settingsMusicOptionsScrobbleDescriptionOn": {},
"settingsMusicOptionsScrobbleTitle": "Scrobbler la lecture",
"@settingsMusicOptionsScrobbleTitle": {},
"settingsNetworkName": "Réseau",
"@settingsNetworkName": {},
"settingsNetworkOptionsMaxBitrateMobileTitle": "Débit binaire maximum (mobile)",
"@settingsNetworkOptionsMaxBitrateMobileTitle": {},
"settingsNetworkOptionsMaxBitrateWifiTitle": "Débit binaire maximum (Wi-Fi)",
"@settingsNetworkOptionsMaxBitrateWifiTitle": {},
"settingsNetworkOptionsMaxBufferTitle": "Temps maximum en mémoire tampon",
"@settingsNetworkOptionsMaxBufferTitle": {},
"settingsNetworkOptionsMinBufferTitle": "Temps minimum en mémoire tampon",
"@settingsNetworkOptionsMinBufferTitle": {},
"settingsNetworkValuesKbps": "{value}kbit/s",
"@settingsNetworkValuesKbps": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesSeconds": "{value} secondes",
"@settingsNetworkValuesSeconds": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesUnlimitedKbps": "Illimité",
"@settingsNetworkValuesUnlimitedKbps": {},
"settingsResetActionsClearImageCache": "Vider le cache d'images",
"@settingsResetActionsClearImageCache": {},
"settingsResetName": "Réinitialiser",
"@settingsResetName": {},
"settingsServersActionsAdd": "Ajouter un serveur",
"@settingsServersActionsAdd": {},
"settingsServersActionsDelete": "Supprimer",
"@settingsServersActionsDelete": {},
"settingsServersActionsEdit": "Modifier le serveur",
"@settingsServersActionsEdit": {},
"settingsServersActionsSave": "Sauvegarder",
"@settingsServersActionsSave": {},
"settingsServersActionsTestConnection": "Tester la connexion",
"@settingsServersActionsTestConnection": {},
"settingsServersFieldsAddress": "Adresse",
"@settingsServersFieldsAddress": {},
"settingsServersFieldsPassword": "Mot de passe",
"@settingsServersFieldsPassword": {},
"settingsServersFieldsUsername": "Nom d'utilisateur",
"@settingsServersFieldsUsername": {},
"settingsServersMessagesConnectionFailed": "Échec de la connexion à {address}, vérifiez les paramètres ou le serveur",
"@settingsServersMessagesConnectionFailed": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersMessagesConnectionOk": "Connexion à {address} OK !",
"@settingsServersMessagesConnectionOk": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersName": "Serveurs",
"@settingsServersName": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Envoyer le mot de passe sous forme de jeton + salage",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Envoyer le mot de passe en test clair (héritage, assurez-vous que la connexion est sécurisée !)",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {},
"settingsServersOptionsForcePlaintextPasswordTitle": "Forcer le mot de passe en texte clair",
"@settingsServersOptionsForcePlaintextPasswordTitle": {}
}

280
lib/l10n/app_gl.arb Normal file
View File

@@ -0,0 +1,280 @@
{
"actionsStar": "Estrela",
"@actionsStar": {},
"actionsUnstar": "Retirar",
"@actionsUnstar": {},
"messagesNothingHere": "Nada por aquí…",
"@messagesNothingHere": {},
"navigationTabsHome": "Inicio",
"@navigationTabsHome": {},
"navigationTabsLibrary": "Biblioteca",
"@navigationTabsLibrary": {},
"navigationTabsSearch": "Buscar",
"@navigationTabsSearch": {},
"navigationTabsSettings": "Axustes",
"@navigationTabsSettings": {},
"resourcesAlbumActionsPlay": "Reproducir",
"@resourcesAlbumActionsPlay": {},
"resourcesAlbumActionsView": "Ver Álbum",
"@resourcesAlbumActionsView": {},
"resourcesAlbumListsSort": "Ordenar Álbums",
"@resourcesAlbumListsSort": {},
"resourcesAlbumName": "{count,plural, =1{Álbum} other{Álbums}}",
"@resourcesAlbumName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesArtistActionsView": "Ver Artista",
"@resourcesArtistActionsView": {},
"resourcesArtistListsSort": "Ordenar Artistas",
"@resourcesArtistListsSort": {},
"resourcesArtistName": "{count,plural, =1{Artista} other{Artistas}}",
"@resourcesArtistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesFilterGenre": "Por xénero",
"@resourcesFilterGenre": {},
"resourcesFilterStarred": "Favoritas",
"@resourcesFilterStarred": {},
"resourcesPlaylistActionsPlay": "Reproducir lista",
"@resourcesPlaylistActionsPlay": {},
"resourcesPlaylistName": "{count,plural, =1{Listaxe} other{Listaxes}}",
"@resourcesPlaylistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesQueueName": "{count,plural, =1{Fila} other{Filas}}",
"@resourcesQueueName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSongListsArtistTopSongs": "Máis reproducidas",
"@resourcesSongListsArtistTopSongs": {},
"resourcesSongName": "{count,plural, =1{Canción} other{Cancións}}",
"@resourcesSongName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSortByAdded": "Últimas engadidas",
"@resourcesSortByAdded": {},
"resourcesSortByArtist": "Por artista",
"@resourcesSortByArtist": {},
"resourcesSortByFrequentlyPlayed": "Reproducidas a miúdo",
"@resourcesSortByFrequentlyPlayed": {},
"resourcesSortByName": "Por nome",
"@resourcesSortByName": {},
"resourcesSortByRandom": "Ao chou",
"@resourcesSortByRandom": {},
"resourcesSortByRecentlyPlayed": "Reproducidas a miúdo",
"@resourcesSortByRecentlyPlayed": {},
"resourcesSortByYear": "Por ano",
"@resourcesSortByYear": {},
"searchHeaderTitle": "Buscar: {query}",
"@searchHeaderTitle": {
"placeholders": {
"query": {
"type": "String"
}
}
},
"searchInputPlaceholder": "Buscar",
"@searchInputPlaceholder": {},
"searchMoreResults": "Máis…",
"@searchMoreResults": {},
"searchNowPlayingContext": "Resultados",
"@searchNowPlayingContext": {},
"settingsAboutActionsLicenses": "Licenzas",
"@settingsAboutActionsLicenses": {},
"settingsAboutActionsProjectHomepage": "Web do Proxecto",
"@settingsAboutActionsProjectHomepage": {},
"settingsAboutName": "Acerca de",
"@settingsAboutName": {},
"settingsAboutVersion": "versión {version}",
"@settingsAboutVersion": {
"placeholders": {
"version": {
"type": "String"
}
}
},
"settingsMusicName": "Música",
"@settingsMusicName": {},
"settingsMusicOptionsScrobbleDescriptionOff": "Non rexistrar o historial de reprodución",
"@settingsMusicOptionsScrobbleDescriptionOff": {},
"settingsMusicOptionsScrobbleDescriptionOn": "Rexistrar o historial de reprodución",
"@settingsMusicOptionsScrobbleDescriptionOn": {},
"settingsMusicOptionsScrobbleTitle": "Rexistrar reprodución",
"@settingsMusicOptionsScrobbleTitle": {},
"settingsNetworkName": "Rede",
"@settingsNetworkName": {},
"settingsNetworkOptionsMaxBitrateMobileTitle": "Bitrate máx. (móbil)",
"@settingsNetworkOptionsMaxBitrateMobileTitle": {},
"settingsNetworkOptionsMaxBitrateWifiTitle": "Bitrate máx. (Wi-Fi)",
"@settingsNetworkOptionsMaxBitrateWifiTitle": {},
"settingsNetworkOptionsMaxBufferTitle": "Tempo máximo na memoria",
"@settingsNetworkOptionsMaxBufferTitle": {},
"settingsNetworkOptionsMinBufferTitle": "Tempo mínimo na memoria",
"@settingsNetworkOptionsMinBufferTitle": {},
"settingsNetworkValuesKbps": "{value}kbps",
"@settingsNetworkValuesKbps": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesSeconds": "{value} segundos",
"@settingsNetworkValuesSeconds": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesUnlimitedKbps": "Sen límite",
"@settingsNetworkValuesUnlimitedKbps": {},
"settingsResetActionsClearImageCache": "Limpar a caché de imaxes",
"@settingsResetActionsClearImageCache": {},
"settingsResetName": "Restablecer",
"@settingsResetName": {},
"settingsServersActionsAdd": "Engadir Servidor",
"@settingsServersActionsAdd": {},
"settingsServersActionsDelete": "Eliminar",
"@settingsServersActionsDelete": {},
"settingsServersActionsEdit": "Editar Servidor",
"@settingsServersActionsEdit": {},
"settingsServersActionsSave": "Gardar",
"@settingsServersActionsSave": {},
"settingsServersActionsTestConnection": "Comprobar Conexión",
"@settingsServersActionsTestConnection": {},
"settingsServersFieldsAddress": "Enderezo",
"@settingsServersFieldsAddress": {},
"settingsServersFieldsPassword": "Contrasinal",
"@settingsServersFieldsPassword": {},
"settingsServersFieldsUsername": "Identificador",
"@settingsServersFieldsUsername": {},
"settingsServersMessagesConnectionFailed": "Fallou a conexión a {address}, comproba os axustes",
"@settingsServersMessagesConnectionFailed": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersMessagesConnectionOk": "Conexión con {address} OK!",
"@settingsServersMessagesConnectionOk": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersName": "Servidores",
"@settingsServersName": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Enviar contrasinal como token + salt",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Enviar contrasinal en texto plano (herdado, pon coidado en que a conexión sexa segura!)",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {},
"settingsServersOptionsForcePlaintextPasswordTitle": "Forzar contrasinal en texto plano",
"@settingsServersOptionsForcePlaintextPasswordTitle": {},
"actionsCancel": "Cancelar",
"@actionsCancel": {},
"actionsDelete": "Eliminar",
"@actionsDelete": {},
"actionsDownload": "Descargar",
"@actionsDownload": {},
"actionsDownloadCancel": "Cancelar a descarga",
"@actionsDownloadCancel": {},
"actionsDownloadDelete": "Eliminar o descargado",
"@actionsDownloadDelete": {},
"actionsOk": "OK",
"@actionsOk": {},
"controlsShuffle": "Barallar",
"@controlsShuffle": {},
"resourcesAlbumCount": "{count,plural, =1{{count} álbum} other{{count} álbums}}",
"@resourcesAlbumCount": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesArtistCount": "{count,plural, =1{{count} artista} other{{count} artistas}}",
"@resourcesArtistCount": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesFilterAlbum": "Álbum",
"@resourcesFilterAlbum": {},
"resourcesFilterArtist": "Artista",
"@resourcesFilterArtist": {},
"resourcesFilterOwner": "Dono",
"@resourcesFilterOwner": {},
"resourcesFilterYear": "Ano",
"@resourcesFilterYear": {},
"resourcesPlaylistCount": "{count,plural, =1{{count} lista} other{{count} listas}}",
"@resourcesPlaylistCount": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSongCount": "{count,plural, =1{{count} canción} other{{count} cancións}}",
"@resourcesSongCount": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSongListDeleteAllContent": "Vas eliminar todas as cancións descargadas.",
"@resourcesSongListDeleteAllContent": {},
"resourcesSongListDeleteAllTitle": "Eliminar descargas?",
"@resourcesSongListDeleteAllTitle": {},
"resourcesSortByAlbum": "Álbum",
"@resourcesSortByAlbum": {},
"resourcesSortByAlbumCount": "Número de álbums",
"@resourcesSortByAlbumCount": {},
"settingsAboutActionsSupport": "Axuda ao desenvolvemento 💜",
"@settingsAboutActionsSupport": {},
"settingsNetworkOptionsOfflineMode": "Modo sen conexión",
"@settingsNetworkOptionsOfflineMode": {},
"settingsNetworkOptionsOfflineModeOff": "Usa internet para sincr. música.",
"@settingsNetworkOptionsOfflineModeOff": {},
"settingsNetworkOptionsOfflineModeOn": "Non usar internet para sincr. ou reproducir música.",
"@settingsNetworkOptionsOfflineModeOn": {},
"settingsNetworkOptionsStreamFormat": "Modo de reprodución preferido",
"@settingsNetworkOptionsStreamFormat": {},
"settingsNetworkOptionsStreamFormatServerDefault": "Usar por defecto do servidor",
"@settingsNetworkOptionsStreamFormatServerDefault": {},
"settingsServersFieldsName": "Nome",
"@settingsServersFieldsName": {},
"resourcesSortByTitle": "Título",
"@resourcesSortByTitle": {},
"resourcesSortByUpdated": "Actualizado recentemente",
"@resourcesSortByUpdated": {},
"settingsAboutShareLogs": "Compartir rexistros",
"@settingsAboutShareLogs": {},
"settingsAboutChooseLog": "Escolle un ficheiro de rexistro",
"@settingsAboutChooseLog": {}
}

196
lib/l10n/app_it.arb Normal file
View File

@@ -0,0 +1,196 @@
{
"actionsStar": "Aggiungi ai preferiti",
"@actionsStar": {},
"actionsUnstar": "Rimuovi dai preferiti",
"@actionsUnstar": {},
"messagesNothingHere": "Non c'è niente qui…",
"@messagesNothingHere": {},
"navigationTabsHome": "Home",
"@navigationTabsHome": {},
"navigationTabsLibrary": "Libreria",
"@navigationTabsLibrary": {},
"navigationTabsSearch": "Cerca",
"@navigationTabsSearch": {},
"navigationTabsSettings": "Impostazioni",
"@navigationTabsSettings": {},
"resourcesAlbumActionsPlay": "Riproduci album",
"@resourcesAlbumActionsPlay": {},
"resourcesAlbumActionsView": "Vedi album",
"@resourcesAlbumActionsView": {},
"resourcesAlbumListsSort": "Ordina album",
"@resourcesAlbumListsSort": {},
"resourcesAlbumName": "{count,plural, =1{Album} other{Album}}",
"@resourcesAlbumName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesArtistActionsView": "Vedi artista",
"@resourcesArtistActionsView": {},
"resourcesArtistListsSort": "Ordina artisti",
"@resourcesArtistListsSort": {},
"resourcesArtistName": "{count,plural, =1{Artista} other{Artisti}}",
"@resourcesArtistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesFilterGenre": "Per genere",
"@resourcesFilterGenre": {},
"resourcesFilterStarred": "Preferiti",
"@resourcesFilterStarred": {},
"resourcesPlaylistActionsPlay": "Riproduci playlist",
"@resourcesPlaylistActionsPlay": {},
"resourcesPlaylistName": "{count,plural, =1{Playlist} other{Playlist}}",
"@resourcesPlaylistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesQueueName": "{count,plural, =1{Coda} other{Code}}",
"@resourcesQueueName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSongListsArtistTopSongs": "Brani più popolari",
"@resourcesSongListsArtistTopSongs": {},
"resourcesSongName": "{count,plural, =1{Brano} other{Brani}}",
"@resourcesSongName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSortByAdded": "Aggiunti di recente",
"@resourcesSortByAdded": {},
"resourcesSortByArtist": "Per artista",
"@resourcesSortByArtist": {},
"resourcesSortByFrequentlyPlayed": "Ascoltati frequentemente",
"@resourcesSortByFrequentlyPlayed": {},
"resourcesSortByName": "Per nome",
"@resourcesSortByName": {},
"resourcesSortByRandom": "Casuale",
"@resourcesSortByRandom": {},
"resourcesSortByRecentlyPlayed": "Ascoltati di recente",
"@resourcesSortByRecentlyPlayed": {},
"resourcesSortByYear": "Per anno",
"@resourcesSortByYear": {},
"searchHeaderTitle": "Ricerca: {query}",
"@searchHeaderTitle": {
"placeholders": {
"query": {
"type": "String"
}
}
},
"searchInputPlaceholder": "Ricerca",
"@searchInputPlaceholder": {},
"searchMoreResults": "Mostra di più…",
"@searchMoreResults": {},
"searchNowPlayingContext": "Risultati della ricerca",
"@searchNowPlayingContext": {},
"settingsAboutActionsLicenses": "Licenze",
"@settingsAboutActionsLicenses": {},
"settingsAboutActionsProjectHomepage": "Pagina principale del progetto",
"@settingsAboutActionsProjectHomepage": {},
"settingsAboutName": "Informazioni",
"@settingsAboutName": {},
"settingsAboutVersion": "versione {version}",
"@settingsAboutVersion": {
"placeholders": {
"version": {
"type": "String"
}
}
},
"settingsMusicName": "Musica",
"@settingsMusicName": {},
"settingsMusicOptionsScrobbleDescriptionOff": "Non eseguire lo scrobbling della cronologia d'ascolto",
"@settingsMusicOptionsScrobbleDescriptionOff": {},
"settingsMusicOptionsScrobbleDescriptionOn": "Scrobbling della cronologia di ascolto",
"@settingsMusicOptionsScrobbleDescriptionOn": {},
"settingsMusicOptionsScrobbleTitle": "Scrobbling delle riproduzioni",
"@settingsMusicOptionsScrobbleTitle": {},
"settingsNetworkName": "Rete",
"@settingsNetworkName": {},
"settingsNetworkOptionsMaxBitrateMobileTitle": "Bitrate massimo (rete dati)",
"@settingsNetworkOptionsMaxBitrateMobileTitle": {},
"settingsNetworkOptionsMaxBitrateWifiTitle": "Bitrate massimo (Wi-Fi)",
"@settingsNetworkOptionsMaxBitrateWifiTitle": {},
"settingsNetworkOptionsMaxBufferTitle": "Tempo di buffer massimo",
"@settingsNetworkOptionsMaxBufferTitle": {},
"settingsNetworkOptionsMinBufferTitle": "Tempo di buffer minimo",
"@settingsNetworkOptionsMinBufferTitle": {},
"settingsNetworkValuesKbps": "{value}kbps",
"@settingsNetworkValuesKbps": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesSeconds": "{value} secondi",
"@settingsNetworkValuesSeconds": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesUnlimitedKbps": "Illimitato",
"@settingsNetworkValuesUnlimitedKbps": {},
"settingsResetActionsClearImageCache": "Pulisci la cache delle immagini",
"@settingsResetActionsClearImageCache": {},
"settingsResetName": "Reimposta",
"@settingsResetName": {},
"settingsServersActionsAdd": "Aggiungi server",
"@settingsServersActionsAdd": {},
"settingsServersActionsDelete": "Rimuovi",
"@settingsServersActionsDelete": {},
"settingsServersActionsEdit": "Modifica server",
"@settingsServersActionsEdit": {},
"settingsServersActionsSave": "Salva",
"@settingsServersActionsSave": {},
"settingsServersActionsTestConnection": "Prova connessione",
"@settingsServersActionsTestConnection": {},
"settingsServersFieldsAddress": "Indirizzo",
"@settingsServersFieldsAddress": {},
"settingsServersFieldsPassword": "Password",
"@settingsServersFieldsPassword": {},
"settingsServersFieldsUsername": "Nome utente",
"@settingsServersFieldsUsername": {},
"settingsServersMessagesConnectionFailed": "Connessione a {address} fallita, controlla le impostazioni o il server",
"@settingsServersMessagesConnectionFailed": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersMessagesConnectionOk": "Connesso a {address} con successo!",
"@settingsServersMessagesConnectionOk": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersName": "Server",
"@settingsServersName": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Invia la password come token + salt",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Invia password in chiaro (deprecato, assicurati che la tua connessione sia sicura!)",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {},
"settingsServersOptionsForcePlaintextPasswordTitle": "Forza password in chiaro",
"@settingsServersOptionsForcePlaintextPasswordTitle": {}
}

64
lib/l10n/app_ja.arb Normal file
View File

@@ -0,0 +1,64 @@
{
"navigationTabsHome": "ホーム",
"@navigationTabsHome": {},
"navigationTabsLibrary": "ライブラリ",
"@navigationTabsLibrary": {},
"navigationTabsSearch": "検索",
"@navigationTabsSearch": {},
"navigationTabsSettings": "設定",
"@navigationTabsSettings": {},
"resourcesAlbumName": "{count,plural, other{アルバム}}",
"@resourcesAlbumName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesArtistName": "{count,plural, other{アーティスト}}",
"@resourcesArtistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesFilterStarred": "星付きアルバム",
"@resourcesFilterStarred": {},
"resourcesPlaylistName": "{count,plural, other{プレイリスト}}",
"@resourcesPlaylistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSongListsArtistTopSongs": "人気曲",
"@resourcesSongListsArtistTopSongs": {},
"resourcesSongName": "{count,plural, other{歌}}",
"@resourcesSongName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSortByFrequentlyPlayed": "よく聴くアルバム",
"@resourcesSortByFrequentlyPlayed": {},
"resourcesSortByRandom": "ランダムアルバム",
"@resourcesSortByRandom": {},
"resourcesSortByRecentlyPlayed": "最近再生した",
"@resourcesSortByRecentlyPlayed": {},
"searchInputPlaceholder": "検索",
"@searchInputPlaceholder": {},
"settingsAboutActionsProjectHomepage": "ホームページ",
"@settingsAboutActionsProjectHomepage": {},
"settingsMusicName": "音楽",
"@settingsMusicName": {},
"settingsNetworkName": "ネット",
"@settingsNetworkName": {},
"settingsResetName": "リセット",
"@settingsResetName": {},
"settingsServersName": "サーバ",
"@settingsServersName": {}
}

196
lib/l10n/app_nb.arb Normal file
View File

@@ -0,0 +1,196 @@
{
"actionsStar": "Stjernemerk",
"@actionsStar": {},
"actionsUnstar": "Fjern stjernemerking",
"@actionsUnstar": {},
"messagesNothingHere": "Ingenting her …",
"@messagesNothingHere": {},
"navigationTabsHome": "Hjem",
"@navigationTabsHome": {},
"navigationTabsLibrary": "Bibliotek",
"@navigationTabsLibrary": {},
"navigationTabsSearch": "Søk",
"@navigationTabsSearch": {},
"navigationTabsSettings": "Innstillinger",
"@navigationTabsSettings": {},
"resourcesAlbumActionsPlay": "Spill album",
"@resourcesAlbumActionsPlay": {},
"resourcesAlbumActionsView": "Vis album",
"@resourcesAlbumActionsView": {},
"resourcesAlbumListsSort": "Sorter album",
"@resourcesAlbumListsSort": {},
"resourcesAlbumName": "{count,plural, =1{Album} other{Album}}",
"@resourcesAlbumName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesArtistActionsView": "Vis artist",
"@resourcesArtistActionsView": {},
"resourcesArtistListsSort": "Sorter artister",
"@resourcesArtistListsSort": {},
"resourcesArtistName": "{count,plural, =1{Artist} other{Artister}}",
"@resourcesArtistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesFilterGenre": "Etter sjanger",
"@resourcesFilterGenre": {},
"resourcesFilterStarred": "Stjernemerket",
"@resourcesFilterStarred": {},
"resourcesPlaylistActionsPlay": "Spill av spilleliste",
"@resourcesPlaylistActionsPlay": {},
"resourcesPlaylistName": "{count,plural, =1{Spilleliste} other{Spillelister}}",
"@resourcesPlaylistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesQueueName": "{count,plural, =1{Kø} other{Køer}}",
"@resourcesQueueName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSongListsArtistTopSongs": "Toppspor",
"@resourcesSongListsArtistTopSongs": {},
"resourcesSongName": "{count,plural, =1{Spor} other{Spor}}",
"@resourcesSongName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSortByAdded": "Nylig tillagt",
"@resourcesSortByAdded": {},
"resourcesSortByArtist": "Etter artist",
"@resourcesSortByArtist": {},
"resourcesSortByFrequentlyPlayed": "Ofte spilt",
"@resourcesSortByFrequentlyPlayed": {},
"resourcesSortByName": "Etter navn",
"@resourcesSortByName": {},
"resourcesSortByRandom": "Tilfeldig",
"@resourcesSortByRandom": {},
"resourcesSortByRecentlyPlayed": "Nylig spilt",
"@resourcesSortByRecentlyPlayed": {},
"resourcesSortByYear": "Etter år",
"@resourcesSortByYear": {},
"searchHeaderTitle": "Søk: {query}",
"@searchHeaderTitle": {
"placeholders": {
"query": {
"type": "String"
}
}
},
"searchInputPlaceholder": "Søk",
"@searchInputPlaceholder": {},
"searchMoreResults": "Mer …",
"@searchMoreResults": {},
"searchNowPlayingContext": "Søkeresultater",
"@searchNowPlayingContext": {},
"settingsAboutActionsLicenses": "Lisenser",
"@settingsAboutActionsLicenses": {},
"settingsAboutActionsProjectHomepage": "Prosjekthjemmeside",
"@settingsAboutActionsProjectHomepage": {},
"settingsAboutName": "Om",
"@settingsAboutName": {},
"settingsAboutVersion": "versjon {version}",
"@settingsAboutVersion": {
"placeholders": {
"version": {
"type": "String"
}
}
},
"settingsMusicName": "Musikk",
"@settingsMusicName": {},
"settingsMusicOptionsScrobbleDescriptionOff": "Ikke utfør sporinfodeling av avspillingshistorikk",
"@settingsMusicOptionsScrobbleDescriptionOff": {},
"settingsMusicOptionsScrobbleDescriptionOn": "Sporinfodelings-avspillinghistorikk",
"@settingsMusicOptionsScrobbleDescriptionOn": {},
"settingsMusicOptionsScrobbleTitle": "Sporinfodelingsavspillinger",
"@settingsMusicOptionsScrobbleTitle": {},
"settingsNetworkName": "Nettverk",
"@settingsNetworkName": {},
"settingsNetworkOptionsMaxBitrateMobileTitle": "Maksimal bitrate (mobil)",
"@settingsNetworkOptionsMaxBitrateMobileTitle": {},
"settingsNetworkOptionsMaxBitrateWifiTitle": "Maksimal bitrate (Wi-Fi)",
"@settingsNetworkOptionsMaxBitrateWifiTitle": {},
"settingsNetworkOptionsMaxBufferTitle": "Maksimal mellomlagringstid",
"@settingsNetworkOptionsMaxBufferTitle": {},
"settingsNetworkOptionsMinBufferTitle": "Minimal mellomlagringstid",
"@settingsNetworkOptionsMinBufferTitle": {},
"settingsNetworkValuesKbps": "{value} kbps",
"@settingsNetworkValuesKbps": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesSeconds": "{value} sekunder",
"@settingsNetworkValuesSeconds": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesUnlimitedKbps": "Ubegrenset",
"@settingsNetworkValuesUnlimitedKbps": {},
"settingsResetActionsClearImageCache": "Tøm bildehurtiglager",
"@settingsResetActionsClearImageCache": {},
"settingsResetName": "Tilbakestill",
"@settingsResetName": {},
"settingsServersActionsAdd": "Legg til tjener",
"@settingsServersActionsAdd": {},
"settingsServersActionsDelete": "Slett",
"@settingsServersActionsDelete": {},
"settingsServersActionsEdit": "Rediger tjener",
"@settingsServersActionsEdit": {},
"settingsServersActionsSave": "Lagre",
"@settingsServersActionsSave": {},
"settingsServersActionsTestConnection": "Test tilkobling",
"@settingsServersActionsTestConnection": {},
"settingsServersFieldsAddress": "Adresse",
"@settingsServersFieldsAddress": {},
"settingsServersFieldsPassword": "Passord",
"@settingsServersFieldsPassword": {},
"settingsServersFieldsUsername": "Brukernavn",
"@settingsServersFieldsUsername": {},
"settingsServersMessagesConnectionFailed": "Tilkobling til {address} mislyktes. Sjekk innstillingene eller tjeneren.",
"@settingsServersMessagesConnectionFailed": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersMessagesConnectionOk": "Tilkobling til {address} OK.",
"@settingsServersMessagesConnectionOk": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersName": "Tjenere",
"@settingsServersName": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Send passord som symbol + salt",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Send passord i klartekst (Foreldet. Forsikre deg om at tilkoblingen er sikker.)",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {},
"settingsServersOptionsForcePlaintextPasswordTitle": "Påtving klartekstspassord",
"@settingsServersOptionsForcePlaintextPasswordTitle": {}
}

196
lib/l10n/app_pa.arb Normal file
View File

@@ -0,0 +1,196 @@
{
"actionsStar": "ਤਾਰਾ",
"@actionsStar": {},
"actionsUnstar": "ਤਾਰਾ ਹਟਾਓ",
"@actionsUnstar": {},
"messagesNothingHere": "ਇੱਥੇ ਕੁਝ ਨਹੀਂ ਹੈ…",
"@messagesNothingHere": {},
"navigationTabsHome": "ਘਰ",
"@navigationTabsHome": {},
"navigationTabsLibrary": "ਲਾਇਬ੍ਰੇਰੀ",
"@navigationTabsLibrary": {},
"navigationTabsSearch": "ਖੋਜ",
"@navigationTabsSearch": {},
"navigationTabsSettings": "ਸੈਟਿੰਗਾਂ",
"@navigationTabsSettings": {},
"resourcesAlbumActionsPlay": "ਐਲਬਮ ਚਲਾਓ",
"@resourcesAlbumActionsPlay": {},
"resourcesAlbumActionsView": "ਐਲਬਮ ਦੇਖੋ",
"@resourcesAlbumActionsView": {},
"resourcesAlbumListsSort": "ਐਲਬਮਾਂ ਨੂੰ ਕਰਮਬੱਧ ਕਰੋ",
"@resourcesAlbumListsSort": {},
"resourcesAlbumName": "{count,plural, =1{ਐਲਬਮ} other{ਐਲਬਮਾਂ}}",
"@resourcesAlbumName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesArtistActionsView": "ਕਲਾਕਾਰ ਦੇਖੋ",
"@resourcesArtistActionsView": {},
"resourcesArtistListsSort": "ਕਲਾਕਾਰਾਂ ਦੀ ਛਾਂਟੀ",
"@resourcesArtistListsSort": {},
"resourcesArtistName": "{count,plural, =1{ਕਲਾਕਾਰ} other{ਕਲਾਕਾਰਾਂ}}",
"@resourcesArtistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesFilterGenre": "ਸ਼ੈਲੀ ਦੁਆਰਾ",
"@resourcesFilterGenre": {},
"resourcesFilterStarred": "ਸਟਾਰ ਕੀਤੇ ਗਏ",
"@resourcesFilterStarred": {},
"resourcesPlaylistActionsPlay": "ਪਲੇਲਿਸਟ ਚਲਾਓ",
"@resourcesPlaylistActionsPlay": {},
"resourcesPlaylistName": "{count,plural, =1{ਪਲੇਲਿਸਟ} other{ਪਲੇਲਿਸਟਸ}}",
"@resourcesPlaylistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesQueueName": "{count,plural, =1{ਕਤਾਰ} other{ਕਤਾਰਾਂ}}",
"@resourcesQueueName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSongListsArtistTopSongs": "ਉੱਤਮ ਗਾਣੇ",
"@resourcesSongListsArtistTopSongs": {},
"resourcesSongName": "{count,plural, =1{ਗਾਣਾ} other{ਗਾਣੇ}}",
"@resourcesSongName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSortByAdded": "ਤਾਜ਼ਾ ਸ਼ਾਮਿਲ",
"@resourcesSortByAdded": {},
"resourcesSortByArtist": "ਕਲਾਕਾਰ ਦੁਆਰਾ",
"@resourcesSortByArtist": {},
"resourcesSortByFrequentlyPlayed": "ਅਕਸਰ ਚਲਾਏ ਗਏ",
"@resourcesSortByFrequentlyPlayed": {},
"resourcesSortByName": "ਨਾਮ ਦੁਆਰਾ",
"@resourcesSortByName": {},
"resourcesSortByRandom": "ਅਟਕਲ-ਪੱਚੂ",
"@resourcesSortByRandom": {},
"resourcesSortByRecentlyPlayed": "ਹਾਲ ਹੀ ਵਿੱਚ ਚਲਾਏ ਗਏ",
"@resourcesSortByRecentlyPlayed": {},
"resourcesSortByYear": "ਸਾਲ ਦੁਆਰਾ",
"@resourcesSortByYear": {},
"searchHeaderTitle": "ਖੋਜ: {query}",
"@searchHeaderTitle": {
"placeholders": {
"query": {
"type": "String"
}
}
},
"searchInputPlaceholder": "ਖੋਜੋ",
"@searchInputPlaceholder": {},
"searchMoreResults": "ਹੋਰ…",
"@searchMoreResults": {},
"searchNowPlayingContext": "ਖੋਜ ਨਤੀਜੇ",
"@searchNowPlayingContext": {},
"settingsAboutActionsLicenses": "ਲਾਇਸੰਸ",
"@settingsAboutActionsLicenses": {},
"settingsAboutActionsProjectHomepage": "ਪ੍ਰੋਜੈਕਟ ਹੋਮਪੇਜ",
"@settingsAboutActionsProjectHomepage": {},
"settingsAboutName": "ਬਾਰੇ",
"@settingsAboutName": {},
"settingsAboutVersion": "ਸੰਸਕਰਣ {version}",
"@settingsAboutVersion": {
"placeholders": {
"version": {
"type": "String"
}
}
},
"settingsMusicName": "ਸੰਗੀਤ",
"@settingsMusicName": {},
"settingsMusicOptionsScrobbleDescriptionOff": "ਸੁਣੇ ਹੋਏ ਗਾਣੇ ਸਕ੍ਰੋਬਲ ਨਾ ਕਰੋ",
"@settingsMusicOptionsScrobbleDescriptionOff": {},
"settingsMusicOptionsScrobbleDescriptionOn": "ਸੁਣੇ ਹੋਏ ਗਾਣੇ ਸਕ੍ਰੋਬਲ ਕਰੋ",
"@settingsMusicOptionsScrobbleDescriptionOn": {},
"settingsMusicOptionsScrobbleTitle": "ਗਾਣੇ ਸਕ੍ਰੋਬਲ ਕਰੋ",
"@settingsMusicOptionsScrobbleTitle": {},
"settingsNetworkName": "ਨੈੱਟਵਰਕ",
"@settingsNetworkName": {},
"settingsNetworkOptionsMaxBitrateMobileTitle": "ਵੱਧ ਤੋਂ ਵੱਧ ਬਿੱਟਰੇਟ (ਮੋਬਾਈਲ)",
"@settingsNetworkOptionsMaxBitrateMobileTitle": {},
"settingsNetworkOptionsMaxBitrateWifiTitle": "ਵੱਧ ਤੋਂ ਵੱਧ ਬਿੱਟਰੇਟ (ਵਾਈ-ਫਾਈ)",
"@settingsNetworkOptionsMaxBitrateWifiTitle": {},
"settingsNetworkOptionsMaxBufferTitle": "ਵੱਧ ਤੋਂ ਵੱਧ ਬਫਰ ਸਮਾਂ",
"@settingsNetworkOptionsMaxBufferTitle": {},
"settingsNetworkOptionsMinBufferTitle": "ਘੱਟੋ-ਘੱਟ ਬਫਰ ਸਮਾਂ",
"@settingsNetworkOptionsMinBufferTitle": {},
"settingsNetworkValuesKbps": "{value}kbps",
"@settingsNetworkValuesKbps": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesSeconds": "{value} ਸਕਿੰਟ",
"@settingsNetworkValuesSeconds": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesUnlimitedKbps": "ਅਸੀਮਿਤ",
"@settingsNetworkValuesUnlimitedKbps": {},
"settingsResetActionsClearImageCache": "ਚਿੱਤਰ ਕੈਸ਼ ਸਾਫ਼ ਕਰੋ",
"@settingsResetActionsClearImageCache": {},
"settingsResetName": "ਰੀਸੈਟ ਕਰੋ",
"@settingsResetName": {},
"settingsServersActionsAdd": "ਸਰਵਰ ਸ਼ਾਮਲ ਕਰੋ",
"@settingsServersActionsAdd": {},
"settingsServersActionsDelete": "ਮਿਟਾਓ",
"@settingsServersActionsDelete": {},
"settingsServersActionsEdit": "ਸਰਵਰ ਦਾ ਸੰਪਾਦਨ",
"@settingsServersActionsEdit": {},
"settingsServersActionsSave": "ਸੇਵ ਕਰੋ",
"@settingsServersActionsSave": {},
"settingsServersActionsTestConnection": "ਟੈਸਟ ਕਨੈਕਸ਼ਨ",
"@settingsServersActionsTestConnection": {},
"settingsServersFieldsAddress": "ਪਤਾ",
"@settingsServersFieldsAddress": {},
"settingsServersFieldsPassword": "ਪਾਸਵਰਡ",
"@settingsServersFieldsPassword": {},
"settingsServersFieldsUsername": "ਯੂਜ਼ਰਨੇਮ",
"@settingsServersFieldsUsername": {},
"settingsServersMessagesConnectionFailed": "{address} ਨਾਲ ਕਨੈਕਸ਼ਨ ਅਸਫਲ, ਸੈਟਿੰਗਾਂ ਜਾਂ ਸਰਵਰ ਦੀ ਜਾਂਚ ਕਰੋ",
"@settingsServersMessagesConnectionFailed": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersMessagesConnectionOk": "{address} ਨਾਲ ਕਨੈਕਸ਼ਨ ਠੀਕ ਹੈ!",
"@settingsServersMessagesConnectionOk": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersName": "ਸਰਵਰ",
"@settingsServersName": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOff": "ਪਾਸਵਰਡ ਨੂੰ ਟੋਕਨ + ਸਾਲ੍ਟ ਵਜੋਂ ਭੇਜੋ",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOn": "ਪਾਸਵਰਡ ਨੂੰ ਸਾਦੇ ਟੈਕਸਟ ਵਿੱਚ ਭੇਜੋ (ਪੁਰਾਣਾ, ਯਕੀਨੀ ਬਣਾਓ ਕਿ ਤੁਹਾਡਾ ਕਨੈਕਸ਼ਨ ਸੁਰੱਖਿਅਤ ਹੈ!)",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {},
"settingsServersOptionsForcePlaintextPasswordTitle": "ਸਾਦੇ ਪਾਸਵਰਡ ਨੂੰ ਜਬਰੀ ਕਰੋ",
"@settingsServersOptionsForcePlaintextPasswordTitle": {}
}

196
lib/l10n/app_pl.arb Normal file
View File

@@ -0,0 +1,196 @@
{
"actionsStar": "Ulubione",
"@actionsStar": {},
"actionsUnstar": "Usuń ulubione",
"@actionsUnstar": {},
"messagesNothingHere": "Pusto tu…",
"@messagesNothingHere": {},
"navigationTabsHome": "Strona główna",
"@navigationTabsHome": {},
"navigationTabsLibrary": "Kolekcja",
"@navigationTabsLibrary": {},
"navigationTabsSearch": "Wyszukaj",
"@navigationTabsSearch": {},
"navigationTabsSettings": "Ustawienia",
"@navigationTabsSettings": {},
"resourcesAlbumActionsPlay": "Otwarzaj album",
"@resourcesAlbumActionsPlay": {},
"resourcesAlbumActionsView": "Zobacz album",
"@resourcesAlbumActionsView": {},
"resourcesAlbumListsSort": "Sortowanie albumów",
"@resourcesAlbumListsSort": {},
"resourcesAlbumName": "{count,plural, =1{Album} few{Albumy} many{Albumów} other{Albumów}}",
"@resourcesAlbumName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesArtistActionsView": "Zobacz wykonawcę",
"@resourcesArtistActionsView": {},
"resourcesArtistListsSort": "Sortowanie wykonawców",
"@resourcesArtistListsSort": {},
"resourcesArtistName": "{count,plural, =1{Wykonawca} few{Wykonawcy} many{Wykonawców} other{Wykonawców}}",
"@resourcesArtistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesFilterGenre": "Wg gatunku",
"@resourcesFilterGenre": {},
"resourcesFilterStarred": "Ulubione",
"@resourcesFilterStarred": {},
"resourcesPlaylistActionsPlay": "Odtwarzaj playlistę",
"@resourcesPlaylistActionsPlay": {},
"resourcesPlaylistName": "{count,plural, =1{Playlista} few{Playlisty} many{Playlist} other{Playlist}}",
"@resourcesPlaylistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesQueueName": "{count,plural, =1{Kolejka} few{Kolejki} many{Kolejek} other{Kolejek}}",
"@resourcesQueueName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSongListsArtistTopSongs": "Najpopularniejsze utwory",
"@resourcesSongListsArtistTopSongs": {},
"resourcesSongName": "{count,plural, =1{Utwór} few{Utwory} many{Utworów} other{Utworów}}",
"@resourcesSongName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSortByAdded": "Ostatnio dodane",
"@resourcesSortByAdded": {},
"resourcesSortByArtist": "Wg wykonawcy",
"@resourcesSortByArtist": {},
"resourcesSortByFrequentlyPlayed": "Często odtwarzane",
"@resourcesSortByFrequentlyPlayed": {},
"resourcesSortByName": "Wg nazwy",
"@resourcesSortByName": {},
"resourcesSortByRandom": "Losowo",
"@resourcesSortByRandom": {},
"resourcesSortByRecentlyPlayed": "Ostatnio odtwarzane",
"@resourcesSortByRecentlyPlayed": {},
"resourcesSortByYear": "Wg roku",
"@resourcesSortByYear": {},
"searchHeaderTitle": "Szukaj: {query}",
"@searchHeaderTitle": {
"placeholders": {
"query": {
"type": "String"
}
}
},
"searchInputPlaceholder": "Szukaj",
"@searchInputPlaceholder": {},
"searchMoreResults": "Więcej…",
"@searchMoreResults": {},
"searchNowPlayingContext": "Wyniki wyszukiwania",
"@searchNowPlayingContext": {},
"settingsAboutActionsLicenses": "Licencje",
"@settingsAboutActionsLicenses": {},
"settingsAboutActionsProjectHomepage": "Strona główna projektu",
"@settingsAboutActionsProjectHomepage": {},
"settingsAboutName": "Informacje o projekcie",
"@settingsAboutName": {},
"settingsAboutVersion": "wersja {version}",
"@settingsAboutVersion": {
"placeholders": {
"version": {
"type": "String"
}
}
},
"settingsMusicName": "Muzyka",
"@settingsMusicName": {},
"settingsMusicOptionsScrobbleDescriptionOff": "Nie śledź swojej historii odtwarzania",
"@settingsMusicOptionsScrobbleDescriptionOff": {},
"settingsMusicOptionsScrobbleDescriptionOn": "Śledź swoją histrorię odtwarzania",
"@settingsMusicOptionsScrobbleDescriptionOn": {},
"settingsMusicOptionsScrobbleTitle": "Śledzenie odtworzeń",
"@settingsMusicOptionsScrobbleTitle": {},
"settingsNetworkName": "Sieć",
"@settingsNetworkName": {},
"settingsNetworkOptionsMaxBitrateMobileTitle": "Maksymalny bitrate (sieć komórkowa)",
"@settingsNetworkOptionsMaxBitrateMobileTitle": {},
"settingsNetworkOptionsMaxBitrateWifiTitle": "Maksymalny bitrate (Wi-Fi)",
"@settingsNetworkOptionsMaxBitrateWifiTitle": {},
"settingsNetworkOptionsMaxBufferTitle": "Maksymalny czas buforowania",
"@settingsNetworkOptionsMaxBufferTitle": {},
"settingsNetworkOptionsMinBufferTitle": "Minimalny czas buforowania",
"@settingsNetworkOptionsMinBufferTitle": {},
"settingsNetworkValuesKbps": "{value}kbps",
"@settingsNetworkValuesKbps": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesSeconds": "{value} sekund",
"@settingsNetworkValuesSeconds": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesUnlimitedKbps": "Bez ograniczeń",
"@settingsNetworkValuesUnlimitedKbps": {},
"settingsResetActionsClearImageCache": "Wyczyść pamięć podręczną obrazów",
"@settingsResetActionsClearImageCache": {},
"settingsResetName": "Przywracanie",
"@settingsResetName": {},
"settingsServersActionsAdd": "Dodaj serwer",
"@settingsServersActionsAdd": {},
"settingsServersActionsDelete": "Usuń",
"@settingsServersActionsDelete": {},
"settingsServersActionsEdit": "Edytuj serwer",
"@settingsServersActionsEdit": {},
"settingsServersActionsSave": "Zapisz",
"@settingsServersActionsSave": {},
"settingsServersActionsTestConnection": "Przetestuj połączenie",
"@settingsServersActionsTestConnection": {},
"settingsServersFieldsAddress": "Adres serwera",
"@settingsServersFieldsAddress": {},
"settingsServersFieldsPassword": "Hasło",
"@settingsServersFieldsPassword": {},
"settingsServersFieldsUsername": "Nazwa użytkownika",
"@settingsServersFieldsUsername": {},
"settingsServersMessagesConnectionFailed": "Błąd połączenia z {address}, sprawdź ustawienia lub serwer",
"@settingsServersMessagesConnectionFailed": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersMessagesConnectionOk": "Połączeno poprawnie z {address}!",
"@settingsServersMessagesConnectionOk": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersName": "Serwery",
"@settingsServersName": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Wyślij hasło jako token i ciąg zaburzający",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Wyślij hasło jako tekst (przestarzałe, upewnij się, że Twoje połączenie jest zabezpieczone)",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {},
"settingsServersOptionsForcePlaintextPasswordTitle": "Wymuś hasło jako tekst (plaintext)",
"@settingsServersOptionsForcePlaintextPasswordTitle": {}
}

230
lib/l10n/app_pt.arb Normal file
View File

@@ -0,0 +1,230 @@
{
"actionsStar": "Favorito",
"@actionsStar": {},
"actionsUnstar": "Remover favorito",
"@actionsUnstar": {},
"messagesNothingHere": "Não existe nada…",
"@messagesNothingHere": {},
"navigationTabsHome": "Início",
"@navigationTabsHome": {},
"navigationTabsLibrary": "Biblioteca",
"@navigationTabsLibrary": {},
"navigationTabsSearch": "Procurar",
"@navigationTabsSearch": {},
"navigationTabsSettings": "Definições",
"@navigationTabsSettings": {},
"resourcesAlbumActionsPlay": "Tocar Álbum",
"@resourcesAlbumActionsPlay": {},
"resourcesAlbumActionsView": "Ver Álbum",
"@resourcesAlbumActionsView": {},
"resourcesAlbumListsSort": "Ordenar Álbuns",
"@resourcesAlbumListsSort": {},
"resourcesAlbumName": "{count,plural, =1{Álbum} other{Álbuns}}",
"@resourcesAlbumName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesArtistActionsView": "Ver Artista",
"@resourcesArtistActionsView": {},
"resourcesArtistListsSort": "Ordenar Artistas",
"@resourcesArtistListsSort": {},
"resourcesArtistName": "{count,plural, =1{Artista} other{Artistas}}",
"@resourcesArtistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesFilterGenre": "Por Género",
"@resourcesFilterGenre": {},
"resourcesFilterStarred": "Favoritos",
"@resourcesFilterStarred": {},
"resourcesPlaylistActionsPlay": "Tocar Playlist",
"@resourcesPlaylistActionsPlay": {},
"resourcesPlaylistName": "{count,plural, =1{Lista} other{Listas}}",
"@resourcesPlaylistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesQueueName": "{count,plural, =1{Fila} other{Filas}}",
"@resourcesQueueName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSongListsArtistTopSongs": "Top Músicas",
"@resourcesSongListsArtistTopSongs": {},
"resourcesSongName": "{count,plural, =1{Música} other{Músicas}}",
"@resourcesSongName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSortByAdded": "Adicionado recentemente",
"@resourcesSortByAdded": {},
"resourcesSortByArtist": "Por Artista",
"@resourcesSortByArtist": {},
"resourcesSortByFrequentlyPlayed": "Mais Tocado",
"@resourcesSortByFrequentlyPlayed": {},
"resourcesSortByName": "Por Nome",
"@resourcesSortByName": {},
"resourcesSortByRandom": "Aleatório",
"@resourcesSortByRandom": {},
"resourcesSortByRecentlyPlayed": "Ouviu recentemente",
"@resourcesSortByRecentlyPlayed": {},
"resourcesSortByYear": "Por Ano",
"@resourcesSortByYear": {},
"searchHeaderTitle": "Procurar: {query}",
"@searchHeaderTitle": {
"placeholders": {
"query": {
"type": "String"
}
}
},
"searchInputPlaceholder": "Procurar",
"@searchInputPlaceholder": {},
"searchMoreResults": "Mais…",
"@searchMoreResults": {},
"searchNowPlayingContext": "Resultados da Pesquisa",
"@searchNowPlayingContext": {},
"settingsAboutActionsLicenses": "Licenças",
"@settingsAboutActionsLicenses": {},
"settingsAboutActionsProjectHomepage": "Página do Projeto",
"@settingsAboutActionsProjectHomepage": {},
"settingsAboutName": "Acerca",
"@settingsAboutName": {},
"settingsAboutVersion": "versão {version}",
"@settingsAboutVersion": {
"placeholders": {
"version": {
"type": "String"
}
}
},
"settingsMusicName": "Música",
"@settingsMusicName": {},
"settingsMusicOptionsScrobbleDescriptionOff": "Não enviar histórico de reproduções por scrobble",
"@settingsMusicOptionsScrobbleDescriptionOff": {},
"settingsMusicOptionsScrobbleDescriptionOn": "Enviar histórico de reproduções por scrobble",
"@settingsMusicOptionsScrobbleDescriptionOn": {},
"settingsMusicOptionsScrobbleTitle": "Enviar reproduções por scrobble",
"@settingsMusicOptionsScrobbleTitle": {},
"settingsNetworkName": "Rede",
"@settingsNetworkName": {},
"settingsNetworkOptionsMaxBitrateMobileTitle": "Bitrate Máximo (móvel)",
"@settingsNetworkOptionsMaxBitrateMobileTitle": {},
"settingsNetworkOptionsMaxBitrateWifiTitle": "Bitrate Máximo (Wi-Fi)",
"@settingsNetworkOptionsMaxBitrateWifiTitle": {},
"settingsNetworkOptionsMaxBufferTitle": "Tempo de buffer máximo",
"@settingsNetworkOptionsMaxBufferTitle": {},
"settingsNetworkOptionsMinBufferTitle": "Tempo de buffer mínimo",
"@settingsNetworkOptionsMinBufferTitle": {},
"settingsNetworkValuesKbps": "{value}kbps",
"@settingsNetworkValuesKbps": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesSeconds": "{value} segundos",
"@settingsNetworkValuesSeconds": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesUnlimitedKbps": "Ilimitado",
"@settingsNetworkValuesUnlimitedKbps": {},
"settingsResetActionsClearImageCache": "Limpar cache de Imagens",
"@settingsResetActionsClearImageCache": {},
"settingsResetName": "Redefinir",
"@settingsResetName": {},
"settingsServersActionsAdd": "Adicionar Servidor",
"@settingsServersActionsAdd": {},
"settingsServersActionsDelete": "Apagar",
"@settingsServersActionsDelete": {},
"settingsServersActionsEdit": "Editar Servidor",
"@settingsServersActionsEdit": {},
"settingsServersActionsSave": "Guardar",
"@settingsServersActionsSave": {},
"settingsServersActionsTestConnection": "Testar Ligação",
"@settingsServersActionsTestConnection": {},
"settingsServersFieldsAddress": "Endereço",
"@settingsServersFieldsAddress": {},
"settingsServersFieldsPassword": "Senha",
"@settingsServersFieldsPassword": {},
"settingsServersFieldsUsername": "Nome de utilizador",
"@settingsServersFieldsUsername": {},
"settingsServersMessagesConnectionFailed": "Ligação a {address} falhou, verifique definições ou servidor",
"@settingsServersMessagesConnectionFailed": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersMessagesConnectionOk": "Ligação a {address} OK!",
"@settingsServersMessagesConnectionOk": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersName": "Servidores",
"@settingsServersName": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Enviar senha como token + sal",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Enviar senha em texto simples (antigo, certifique-se que a sua ligação é segura!)",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {},
"settingsServersOptionsForcePlaintextPasswordTitle": "Forçar password em texto simples",
"@settingsServersOptionsForcePlaintextPasswordTitle": {},
"actionsCancel": "Cancelar",
"@actionsCancel": {},
"actionsDelete": "Apagar",
"@actionsDelete": {},
"actionsDownload": "Descarregar",
"@actionsDownload": {},
"actionsDownloadCancel": "Cancelar descarga",
"@actionsDownloadCancel": {},
"actionsDownloadDelete": "Apagar descarga",
"@actionsDownloadDelete": {},
"resourcesFilterAlbum": "Álbum",
"@resourcesFilterAlbum": {},
"resourcesFilterArtist": "Artista",
"@resourcesFilterArtist": {},
"resourcesFilterYear": "Ano",
"@resourcesFilterYear": {},
"resourcesSortByAlbum": "Álbum",
"@resourcesSortByAlbum": {},
"settingsAboutActionsSupport": "Apoie o programador 💜",
"@settingsAboutActionsSupport": {},
"settingsNetworkOptionsOfflineMode": "Modo offline",
"@settingsNetworkOptionsOfflineMode": {},
"settingsNetworkOptionsOfflineModeOff": "Usar a internet para sincronizar música.",
"@settingsNetworkOptionsOfflineModeOff": {},
"settingsNetworkOptionsOfflineModeOn": "Não usar a internet para sincronizar ou tocar música.",
"@settingsNetworkOptionsOfflineModeOn": {},
"settingsNetworkOptionsStreamFormat": "Formato preferido de streaming",
"@settingsNetworkOptionsStreamFormat": {},
"resourcesSortByTitle": "Título",
"@resourcesSortByTitle": {},
"actionsOk": "OK",
"@actionsOk": {},
"controlsShuffle": "Aleatório",
"@controlsShuffle": {}
}

280
lib/l10n/app_ru.arb Normal file
View File

@@ -0,0 +1,280 @@
{
"actionsStar": "Избранное",
"@actionsStar": {},
"actionsUnstar": "Убрать из избранного",
"@actionsUnstar": {},
"messagesNothingHere": "Здесь ничего нет…",
"@messagesNothingHere": {},
"navigationTabsHome": "Главная",
"@navigationTabsHome": {},
"navigationTabsLibrary": "Библиотека",
"@navigationTabsLibrary": {},
"navigationTabsSearch": "Поиск",
"@navigationTabsSearch": {},
"navigationTabsSettings": "Настройки",
"@navigationTabsSettings": {},
"resourcesAlbumActionsPlay": "Воспроизвести альбом",
"@resourcesAlbumActionsPlay": {},
"resourcesAlbumActionsView": "Посмотреть альбом",
"@resourcesAlbumActionsView": {},
"resourcesAlbumListsSort": "Сортировка альбомов",
"@resourcesAlbumListsSort": {},
"resourcesAlbumName": "{count,plural, =1{Альбом} few{Альбомы} many{Альбомов} other{Альбомов}}",
"@resourcesAlbumName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesArtistActionsView": "Посмотреть исполнителя",
"@resourcesArtistActionsView": {},
"resourcesArtistListsSort": "Сортировать исполнителей",
"@resourcesArtistListsSort": {},
"resourcesArtistName": "{count,plural, =1{Исполнитель} few{Исполнители} many{Исполнителей} other{Исполнителей}}",
"@resourcesArtistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesFilterGenre": "По жанру",
"@resourcesFilterGenre": {},
"resourcesFilterStarred": "Избранные",
"@resourcesFilterStarred": {},
"resourcesPlaylistActionsPlay": "Воспроизвести плейлист",
"@resourcesPlaylistActionsPlay": {},
"resourcesPlaylistName": "{count,plural, =1{Плейлист} few{Плейлисты} many{Плейлистов} other{Плейлистов}}",
"@resourcesPlaylistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesQueueName": "{count,plural, =1{Очередь} few{Очереди} many{Очередей} other{Очередей}}",
"@resourcesQueueName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSongListsArtistTopSongs": "Лучшие треки",
"@resourcesSongListsArtistTopSongs": {},
"resourcesSongName": "{count,plural, =1{Трек} few{Трека} many{Треков} other{Треков}}",
"@resourcesSongName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSortByAdded": "Недавно добавленные",
"@resourcesSortByAdded": {},
"resourcesSortByArtist": "По исполнителям",
"@resourcesSortByArtist": {},
"resourcesSortByFrequentlyPlayed": "Часто проигрываемые",
"@resourcesSortByFrequentlyPlayed": {},
"resourcesSortByName": "По имени",
"@resourcesSortByName": {},
"resourcesSortByRandom": "Случайно",
"@resourcesSortByRandom": {},
"resourcesSortByRecentlyPlayed": "Недавно проигранные",
"@resourcesSortByRecentlyPlayed": {},
"resourcesSortByYear": "По году",
"@resourcesSortByYear": {},
"searchHeaderTitle": "Поиск: {query}",
"@searchHeaderTitle": {
"placeholders": {
"query": {
"type": "String"
}
}
},
"searchInputPlaceholder": "Поиск",
"@searchInputPlaceholder": {},
"searchMoreResults": "Больше…",
"@searchMoreResults": {},
"searchNowPlayingContext": "Результаты поиска",
"@searchNowPlayingContext": {},
"settingsAboutActionsLicenses": "Лицензии",
"@settingsAboutActionsLicenses": {},
"settingsAboutActionsProjectHomepage": "Сайт проекта",
"@settingsAboutActionsProjectHomepage": {},
"settingsAboutName": "О Subtracks",
"@settingsAboutName": {},
"settingsAboutVersion": "версия {version}",
"@settingsAboutVersion": {
"placeholders": {
"version": {
"type": "String"
}
}
},
"settingsMusicName": "Музыка",
"@settingsMusicName": {},
"settingsMusicOptionsScrobbleDescriptionOff": "Не отправлять историю воспроизведений",
"@settingsMusicOptionsScrobbleDescriptionOff": {},
"settingsMusicOptionsScrobbleDescriptionOn": "Скробблинг истории воспроизведения",
"@settingsMusicOptionsScrobbleDescriptionOn": {},
"settingsMusicOptionsScrobbleTitle": "Скробблинг",
"@settingsMusicOptionsScrobbleTitle": {},
"settingsNetworkName": "Сеть",
"@settingsNetworkName": {},
"settingsNetworkOptionsMaxBitrateMobileTitle": "Максимальный битрейт (мобильный интернет)",
"@settingsNetworkOptionsMaxBitrateMobileTitle": {},
"settingsNetworkOptionsMaxBitrateWifiTitle": "Максимальный битрейт (Wi-Fi)",
"@settingsNetworkOptionsMaxBitrateWifiTitle": {},
"settingsNetworkOptionsMaxBufferTitle": "Максимальное время буферизации",
"@settingsNetworkOptionsMaxBufferTitle": {},
"settingsNetworkOptionsMinBufferTitle": "Минимальное время буферизации",
"@settingsNetworkOptionsMinBufferTitle": {},
"settingsNetworkValuesKbps": "{value} кбит/с",
"@settingsNetworkValuesKbps": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesSeconds": "{value} секунд",
"@settingsNetworkValuesSeconds": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesUnlimitedKbps": "Без ограничений",
"@settingsNetworkValuesUnlimitedKbps": {},
"settingsResetActionsClearImageCache": "Очистить кэш изображения",
"@settingsResetActionsClearImageCache": {},
"settingsResetName": "Сброс",
"@settingsResetName": {},
"settingsServersActionsAdd": "Добавить сервер",
"@settingsServersActionsAdd": {},
"settingsServersActionsDelete": "Удалить",
"@settingsServersActionsDelete": {},
"settingsServersActionsEdit": "Редактировать сервер",
"@settingsServersActionsEdit": {},
"settingsServersActionsSave": "Сохранить",
"@settingsServersActionsSave": {},
"settingsServersActionsTestConnection": "Проверить подключение",
"@settingsServersActionsTestConnection": {},
"settingsServersFieldsAddress": "Адрес",
"@settingsServersFieldsAddress": {},
"settingsServersFieldsPassword": "Пароль",
"@settingsServersFieldsPassword": {},
"settingsServersFieldsUsername": "Имя пользователя",
"@settingsServersFieldsUsername": {},
"settingsServersMessagesConnectionFailed": "Не удалось подключиться к {address}, проверьте настройки или сервер",
"@settingsServersMessagesConnectionFailed": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersMessagesConnectionOk": "Подключение к {address} установлено!",
"@settingsServersMessagesConnectionOk": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersName": "Серверы",
"@settingsServersName": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Отправить пароль в виде токена",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Отправить пароль в виде текста (устарело, убедитесь, что ваше соединение безопасно!)",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {},
"settingsServersOptionsForcePlaintextPasswordTitle": "Принудительно использовать текстовой пароль",
"@settingsServersOptionsForcePlaintextPasswordTitle": {},
"settingsAboutShareLogs": "Поделиться журналами",
"@settingsAboutShareLogs": {},
"settingsAboutChooseLog": "Выбрать файл журнала",
"@settingsAboutChooseLog": {},
"settingsNetworkOptionsStreamFormatServerDefault": "Использовать сервер по умолчанию",
"@settingsNetworkOptionsStreamFormatServerDefault": {},
"actionsDownload": "Скачать",
"@actionsDownload": {},
"actionsDownloadCancel": "Отменить загрузку",
"@actionsDownloadCancel": {},
"actionsCancel": "Отменить",
"@actionsCancel": {},
"resourcesSongCount": "{count,plural, =1{{count} трек} other{{count} треки}}",
"@resourcesSongCount": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSortByAlbum": "По альбомам",
"@resourcesSortByAlbum": {},
"resourcesSortByTitle": "По заголовку",
"@resourcesSortByTitle": {},
"resourcesSortByUpdated": "По недавно обновленному",
"@resourcesSortByUpdated": {},
"resourcesSortByAlbumCount": "По количеству альбомов",
"@resourcesSortByAlbumCount": {},
"settingsNetworkOptionsOfflineMode": "Автономный режим",
"@settingsNetworkOptionsOfflineMode": {},
"settingsNetworkOptionsOfflineModeOff": "Использовать интернет для синхронизации музыки.",
"@settingsNetworkOptionsOfflineModeOff": {},
"settingsServersFieldsName": "Имя",
"@settingsServersFieldsName": {},
"actionsDelete": "Удалить",
"@actionsDelete": {},
"actionsDownloadDelete": "Удалить загруженное",
"@actionsDownloadDelete": {},
"actionsOk": "ОК",
"@actionsOk": {},
"controlsShuffle": "Перемешать",
"@controlsShuffle": {},
"resourcesFilterArtist": "По исполнителю",
"@resourcesFilterArtist": {},
"resourcesFilterAlbum": "По альбомам",
"@resourcesFilterAlbum": {},
"resourcesFilterYear": "По годам",
"@resourcesFilterYear": {},
"resourcesFilterOwner": "По владельцу",
"@resourcesFilterOwner": {},
"resourcesSongListDeleteAllContent": "Это удалит все загруженные файлы песен.",
"@resourcesSongListDeleteAllContent": {},
"settingsNetworkOptionsStreamFormat": "Предпочтительный формат потока",
"@settingsNetworkOptionsStreamFormat": {},
"resourcesSongListDeleteAllTitle": "Удалить загрузки?",
"@resourcesSongListDeleteAllTitle": {},
"settingsNetworkOptionsOfflineModeOn": "Не использовать интернет для синхронизации или воспроизведения музыки.",
"@settingsNetworkOptionsOfflineModeOn": {},
"settingsAboutActionsSupport": "Поддержать разработчика",
"@settingsAboutActionsSupport": {},
"resourcesArtistCount": "{count,plural, =1{{count} исполнитель} other{{count} исполнители}}",
"@resourcesArtistCount": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesPlaylistCount": "{count,plural, =1{{count} плейлист} other{{count} плейлисты}}",
"@resourcesPlaylistCount": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesAlbumCount": "{count,plural, =1{{count} альбом} other{{count} альбомы}}",
"@resourcesAlbumCount": {
"placeholders": {
"count": {
"type": "int"
}
}
}
}

196
lib/l10n/app_tr.arb Normal file
View File

@@ -0,0 +1,196 @@
{
"actionsStar": "Yıldızla",
"@actionsStar": {},
"actionsUnstar": "Yıldızı Kaldır",
"@actionsUnstar": {},
"messagesNothingHere": "Burada bir şey yok …",
"@messagesNothingHere": {},
"navigationTabsHome": "Giriş",
"@navigationTabsHome": {},
"navigationTabsLibrary": "Kütüphane",
"@navigationTabsLibrary": {},
"navigationTabsSearch": "Arama",
"@navigationTabsSearch": {},
"navigationTabsSettings": "Ayarlar",
"@navigationTabsSettings": {},
"resourcesAlbumActionsPlay": "Albümü Çal",
"@resourcesAlbumActionsPlay": {},
"resourcesAlbumActionsView": "Albüme Git",
"@resourcesAlbumActionsView": {},
"resourcesAlbumListsSort": "Albümleri Sırala",
"@resourcesAlbumListsSort": {},
"resourcesAlbumName": "{count,plural, =1{Albüm} other{Albümler}}",
"@resourcesAlbumName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesArtistActionsView": "Sanatçıya Git",
"@resourcesArtistActionsView": {},
"resourcesArtistListsSort": "Sanatçıları Sırala",
"@resourcesArtistListsSort": {},
"resourcesArtistName": "{count,plural, =1{Sanatçı} other{Sanatçılar}}",
"@resourcesArtistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesFilterGenre": "Türe göre",
"@resourcesFilterGenre": {},
"resourcesFilterStarred": "Yıldızlı",
"@resourcesFilterStarred": {},
"resourcesPlaylistActionsPlay": "Listeyi Çal",
"@resourcesPlaylistActionsPlay": {},
"resourcesPlaylistName": "{count,plural, =1{Çalma Listesi} other{Çalma Listeleri}}",
"@resourcesPlaylistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesQueueName": "{count,plural, =1{Sıra} other{Sıralar}}",
"@resourcesQueueName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSongListsArtistTopSongs": "En İyi Şarkılar",
"@resourcesSongListsArtistTopSongs": {},
"resourcesSongName": "{count,plural, =1{Şarkı} other{Şarkılar}}",
"@resourcesSongName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSortByAdded": "Son Eklenenler",
"@resourcesSortByAdded": {},
"resourcesSortByArtist": "Sanatçıya Göre",
"@resourcesSortByArtist": {},
"resourcesSortByFrequentlyPlayed": "Sık Dinlenenler",
"@resourcesSortByFrequentlyPlayed": {},
"resourcesSortByName": "İsme göre",
"@resourcesSortByName": {},
"resourcesSortByRandom": "Rastgele",
"@resourcesSortByRandom": {},
"resourcesSortByRecentlyPlayed": "Yeni Dinleneler",
"@resourcesSortByRecentlyPlayed": {},
"resourcesSortByYear": "Yıla göre",
"@resourcesSortByYear": {},
"searchHeaderTitle": "Aranan: {query}",
"@searchHeaderTitle": {
"placeholders": {
"query": {
"type": "String"
}
}
},
"searchInputPlaceholder": "Ara",
"@searchInputPlaceholder": {},
"searchMoreResults": "Tüm Sonuçlar …",
"@searchMoreResults": {},
"searchNowPlayingContext": "Arama Sonuçları",
"@searchNowPlayingContext": {},
"settingsAboutActionsLicenses": "Lisanslar",
"@settingsAboutActionsLicenses": {},
"settingsAboutActionsProjectHomepage": "Proje Ana Sayfası",
"@settingsAboutActionsProjectHomepage": {},
"settingsAboutName": "Hakkında",
"@settingsAboutName": {},
"settingsAboutVersion": "sürüm {version}",
"@settingsAboutVersion": {
"placeholders": {
"version": {
"type": "String"
}
}
},
"settingsMusicName": "Müzik",
"@settingsMusicName": {},
"settingsMusicOptionsScrobbleDescriptionOff": "Müzik geçmişini profilime ekleme",
"@settingsMusicOptionsScrobbleDescriptionOff": {},
"settingsMusicOptionsScrobbleDescriptionOn": "Müzik geçmişini profilime ekle",
"@settingsMusicOptionsScrobbleDescriptionOn": {},
"settingsMusicOptionsScrobbleTitle": "Çalan müziği profilime ekle",
"@settingsMusicOptionsScrobbleTitle": {},
"settingsNetworkName": "Ağ",
"@settingsNetworkName": {},
"settingsNetworkOptionsMaxBitrateMobileTitle": "Azami bithızı (SIM interneti)",
"@settingsNetworkOptionsMaxBitrateMobileTitle": {},
"settingsNetworkOptionsMaxBitrateWifiTitle": "Azami bithızı (Wi-Fi)",
"@settingsNetworkOptionsMaxBitrateWifiTitle": {},
"settingsNetworkOptionsMaxBufferTitle": "Azami arabellek süresi",
"@settingsNetworkOptionsMaxBufferTitle": {},
"settingsNetworkOptionsMinBufferTitle": "Asgari arabellek süresi",
"@settingsNetworkOptionsMinBufferTitle": {},
"settingsNetworkValuesKbps": "{value}kb/sn",
"@settingsNetworkValuesKbps": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesSeconds": "{value} saniye",
"@settingsNetworkValuesSeconds": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesUnlimitedKbps": "Sınırsız",
"@settingsNetworkValuesUnlimitedKbps": {},
"settingsResetActionsClearImageCache": "Görüntü Önbelleğini Temizle",
"@settingsResetActionsClearImageCache": {},
"settingsResetName": "Sıfırlama",
"@settingsResetName": {},
"settingsServersActionsAdd": "Sunucu Ekle",
"@settingsServersActionsAdd": {},
"settingsServersActionsDelete": "Kaldır",
"@settingsServersActionsDelete": {},
"settingsServersActionsEdit": "Sunucu Ayarı",
"@settingsServersActionsEdit": {},
"settingsServersActionsSave": "Kaydet",
"@settingsServersActionsSave": {},
"settingsServersActionsTestConnection": "Bağlantıyı Sına",
"@settingsServersActionsTestConnection": {},
"settingsServersFieldsAddress": "Adres",
"@settingsServersFieldsAddress": {},
"settingsServersFieldsPassword": "Şifre",
"@settingsServersFieldsPassword": {},
"settingsServersFieldsUsername": "Kullanıcı Adı",
"@settingsServersFieldsUsername": {},
"settingsServersMessagesConnectionFailed": "{address} ile bağlantı başarısız. Sunucu ayarlarınızın doğrulığundan emin olun.",
"@settingsServersMessagesConnectionFailed": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersMessagesConnectionOk": "{address} ile bağlantı başarılı!",
"@settingsServersMessagesConnectionOk": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersName": "Sunucular",
"@settingsServersName": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Şifreyi dizgecik ve tuz karışımı olarak gönder",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Şifreyi düzmetin olarak gönderir (eski yöntem, bağlantının güvenli (HTTPS) olduğu sunucularda kullanın!)",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {},
"settingsServersOptionsForcePlaintextPasswordTitle": "Düzyazı şifre kullanmayı zorla",
"@settingsServersOptionsForcePlaintextPasswordTitle": {}
}

196
lib/l10n/app_vi.arb Normal file
View File

@@ -0,0 +1,196 @@
{
"actionsStar": "Đánh dấu sao",
"@actionsStar": {},
"actionsUnstar": "Bỏ dấu sao",
"@actionsUnstar": {},
"messagesNothingHere": "Không có gì ở đây…",
"@messagesNothingHere": {},
"navigationTabsHome": "Trang chủ",
"@navigationTabsHome": {},
"navigationTabsLibrary": "Thư Viện",
"@navigationTabsLibrary": {},
"navigationTabsSearch": "Tìm kiếm",
"@navigationTabsSearch": {},
"navigationTabsSettings": "Thiết Lập",
"@navigationTabsSettings": {},
"resourcesAlbumActionsPlay": "Phát Album",
"@resourcesAlbumActionsPlay": {},
"resourcesAlbumActionsView": "Xem Album",
"@resourcesAlbumActionsView": {},
"resourcesAlbumListsSort": "Sắp xếp Album",
"@resourcesAlbumListsSort": {},
"resourcesAlbumName": "{count,plural, other{Album}}",
"@resourcesAlbumName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesArtistActionsView": "Xem Nghệ sĩ",
"@resourcesArtistActionsView": {},
"resourcesArtistListsSort": "Sắp xếp nghệ sĩ",
"@resourcesArtistListsSort": {},
"resourcesArtistName": "{count,plural, other{Nghệ sĩ}}",
"@resourcesArtistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesFilterGenre": "Theo thể loại",
"@resourcesFilterGenre": {},
"resourcesFilterStarred": "Có gắn dấu sao",
"@resourcesFilterStarred": {},
"resourcesPlaylistActionsPlay": "Phát Danh sách phát",
"@resourcesPlaylistActionsPlay": {},
"resourcesPlaylistName": "{count,plural, other{Danh sách phát}}",
"@resourcesPlaylistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesQueueName": "{count,plural, other{Hàng chờ}}",
"@resourcesQueueName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSongListsArtistTopSongs": "Bài hát hàng đầu",
"@resourcesSongListsArtistTopSongs": {},
"resourcesSongName": "{count,plural, other{Bài hát}}",
"@resourcesSongName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSortByAdded": "Thêm vào gần đây",
"@resourcesSortByAdded": {},
"resourcesSortByArtist": "Theo nghệ sĩ",
"@resourcesSortByArtist": {},
"resourcesSortByFrequentlyPlayed": "Thường xuyên chơi",
"@resourcesSortByFrequentlyPlayed": {},
"resourcesSortByName": "Theo tên",
"@resourcesSortByName": {},
"resourcesSortByRandom": "Ngẫu Nhiên",
"@resourcesSortByRandom": {},
"resourcesSortByRecentlyPlayed": "Đã phát gần đây",
"@resourcesSortByRecentlyPlayed": {},
"resourcesSortByYear": "Theo năm",
"@resourcesSortByYear": {},
"searchHeaderTitle": "Tìm kiếm: {query}",
"@searchHeaderTitle": {
"placeholders": {
"query": {
"type": "String"
}
}
},
"searchInputPlaceholder": "Tìm kiếm",
"@searchInputPlaceholder": {},
"searchMoreResults": "Nhiều hơn…",
"@searchMoreResults": {},
"searchNowPlayingContext": "Kết quả tìm kiếm",
"@searchNowPlayingContext": {},
"settingsAboutActionsLicenses": "Giấy phép",
"@settingsAboutActionsLicenses": {},
"settingsAboutActionsProjectHomepage": "Trang chủ Dự án",
"@settingsAboutActionsProjectHomepage": {},
"settingsAboutName": "Giới thiệu",
"@settingsAboutName": {},
"settingsAboutVersion": "phiên bản {version}",
"@settingsAboutVersion": {
"placeholders": {
"version": {
"type": "String"
}
}
},
"settingsMusicName": "Âm nhạc",
"@settingsMusicName": {},
"settingsMusicOptionsScrobbleDescriptionOff": "Đừng scrobble lịch sử chơi",
"@settingsMusicOptionsScrobbleDescriptionOff": {},
"settingsMusicOptionsScrobbleDescriptionOn": "Lịch sử chơi Scrobble",
"@settingsMusicOptionsScrobbleDescriptionOn": {},
"settingsMusicOptionsScrobbleTitle": "Scrobble lượt chơi",
"@settingsMusicOptionsScrobbleTitle": {},
"settingsNetworkName": "Mạng",
"@settingsNetworkName": {},
"settingsNetworkOptionsMaxBitrateMobileTitle": "Tối đa bitrate (mobile)",
"@settingsNetworkOptionsMaxBitrateMobileTitle": {},
"settingsNetworkOptionsMaxBitrateWifiTitle": "Tối đa bitrate (Wi-Fi)",
"@settingsNetworkOptionsMaxBitrateWifiTitle": {},
"settingsNetworkOptionsMaxBufferTitle": "Thời gian đệm tối đa",
"@settingsNetworkOptionsMaxBufferTitle": {},
"settingsNetworkOptionsMinBufferTitle": "Thời gian đệm tối thiểu",
"@settingsNetworkOptionsMinBufferTitle": {},
"settingsNetworkValuesKbps": "{value}kbps",
"@settingsNetworkValuesKbps": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesSeconds": "{value} giây",
"@settingsNetworkValuesSeconds": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesUnlimitedKbps": "Không giới hạn",
"@settingsNetworkValuesUnlimitedKbps": {},
"settingsResetActionsClearImageCache": "Xóa bộ nhớ đệm hình ảnh",
"@settingsResetActionsClearImageCache": {},
"settingsResetName": "Cài đặt lại",
"@settingsResetName": {},
"settingsServersActionsAdd": "Thêm máy chủ",
"@settingsServersActionsAdd": {},
"settingsServersActionsDelete": "Xóa",
"@settingsServersActionsDelete": {},
"settingsServersActionsEdit": "Chỉnh sửa máy chủ",
"@settingsServersActionsEdit": {},
"settingsServersActionsSave": "Lưu",
"@settingsServersActionsSave": {},
"settingsServersActionsTestConnection": "Kiểm tra kết nối",
"@settingsServersActionsTestConnection": {},
"settingsServersFieldsAddress": "Địa chỉ",
"@settingsServersFieldsAddress": {},
"settingsServersFieldsPassword": "Mật Khẩu",
"@settingsServersFieldsPassword": {},
"settingsServersFieldsUsername": "Tên đăng nhập",
"@settingsServersFieldsUsername": {},
"settingsServersMessagesConnectionFailed": "Kết nối với {address} không thành công, hãy kiểm tra cài đặt hoặc máy chủ",
"@settingsServersMessagesConnectionFailed": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersMessagesConnectionOk": "Kết nối với {address} OK!",
"@settingsServersMessagesConnectionOk": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersName": "Máy chủ",
"@settingsServersName": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Gửi mật khẩu dưới dạng token + salt",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Gửi mật khẩu ở dạng văn bản rõ ràng (kế thừa, đảm bảo kết nối của bạn an toàn!)",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {},
"settingsServersOptionsForcePlaintextPasswordTitle": "Buộc mật khẩu văn bản thuần túy",
"@settingsServersOptionsForcePlaintextPasswordTitle": {}
}

230
lib/l10n/app_zh.arb Normal file
View File

@@ -0,0 +1,230 @@
{
"actionsStar": "收藏",
"@actionsStar": {},
"actionsUnstar": "移除收藏",
"@actionsUnstar": {},
"messagesNothingHere": "什么都没有…",
"@messagesNothingHere": {},
"navigationTabsHome": "首页",
"@navigationTabsHome": {},
"navigationTabsLibrary": "所有",
"@navigationTabsLibrary": {},
"navigationTabsSearch": "搜索",
"@navigationTabsSearch": {},
"navigationTabsSettings": "设置",
"@navigationTabsSettings": {},
"resourcesAlbumActionsPlay": "播放专辑",
"@resourcesAlbumActionsPlay": {},
"resourcesAlbumActionsView": "查看专辑",
"@resourcesAlbumActionsView": {},
"resourcesAlbumListsSort": "专辑排序",
"@resourcesAlbumListsSort": {},
"resourcesAlbumName": "{count,plural, other{专辑}}",
"@resourcesAlbumName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesArtistActionsView": "查看歌手",
"@resourcesArtistActionsView": {},
"resourcesArtistListsSort": "歌手排序",
"@resourcesArtistListsSort": {},
"resourcesArtistName": "{count,plural, other{歌手}}",
"@resourcesArtistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesFilterGenre": "根据类型",
"@resourcesFilterGenre": {},
"resourcesFilterStarred": "已收藏",
"@resourcesFilterStarred": {},
"resourcesPlaylistActionsPlay": "全部播放",
"@resourcesPlaylistActionsPlay": {},
"resourcesPlaylistName": "{count,plural, other{播放列表}}",
"@resourcesPlaylistName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesQueueName": "{count,plural, other{队列}}",
"@resourcesQueueName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSongListsArtistTopSongs": "热门歌曲",
"@resourcesSongListsArtistTopSongs": {},
"resourcesSongName": "{count,plural, other{歌曲}}",
"@resourcesSongName": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSortByAdded": "最近添加",
"@resourcesSortByAdded": {},
"resourcesSortByArtist": "根据歌手",
"@resourcesSortByArtist": {},
"resourcesSortByFrequentlyPlayed": "播放最多",
"@resourcesSortByFrequentlyPlayed": {},
"resourcesSortByName": "根据名称",
"@resourcesSortByName": {},
"resourcesSortByRandom": "随机",
"@resourcesSortByRandom": {},
"resourcesSortByRecentlyPlayed": "最近播放",
"@resourcesSortByRecentlyPlayed": {},
"resourcesSortByYear": "根据年份",
"@resourcesSortByYear": {},
"searchHeaderTitle": "搜索: {query}",
"@searchHeaderTitle": {
"placeholders": {
"query": {
"type": "String"
}
}
},
"searchInputPlaceholder": "搜索",
"@searchInputPlaceholder": {},
"searchMoreResults": "更多…",
"@searchMoreResults": {},
"searchNowPlayingContext": "搜索结果",
"@searchNowPlayingContext": {},
"settingsAboutActionsLicenses": "许可",
"@settingsAboutActionsLicenses": {},
"settingsAboutActionsProjectHomepage": "项目地址",
"@settingsAboutActionsProjectHomepage": {},
"settingsAboutName": "关于",
"@settingsAboutName": {},
"settingsAboutVersion": "版本 {version}",
"@settingsAboutVersion": {
"placeholders": {
"version": {
"type": "String"
}
}
},
"settingsMusicName": "音乐",
"@settingsMusicName": {},
"settingsMusicOptionsScrobbleDescriptionOff": "不记录scrobble历史",
"@settingsMusicOptionsScrobbleDescriptionOff": {},
"settingsMusicOptionsScrobbleDescriptionOn": "Scrobble播放历史",
"@settingsMusicOptionsScrobbleDescriptionOn": {},
"settingsMusicOptionsScrobbleTitle": "Scrobble模式",
"@settingsMusicOptionsScrobbleTitle": {},
"settingsNetworkName": "网络",
"@settingsNetworkName": {},
"settingsNetworkOptionsMaxBitrateMobileTitle": "最大比特率 (3G/4G/5G)",
"@settingsNetworkOptionsMaxBitrateMobileTitle": {},
"settingsNetworkOptionsMaxBitrateWifiTitle": "最大比特率 (Wi-Fi)",
"@settingsNetworkOptionsMaxBitrateWifiTitle": {},
"settingsNetworkOptionsMaxBufferTitle": "最大缓冲时间",
"@settingsNetworkOptionsMaxBufferTitle": {},
"settingsNetworkOptionsMinBufferTitle": "最小缓冲时间",
"@settingsNetworkOptionsMinBufferTitle": {},
"settingsNetworkValuesKbps": "{value}kbps",
"@settingsNetworkValuesKbps": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesSeconds": "{value} 秒",
"@settingsNetworkValuesSeconds": {
"placeholders": {
"value": {
"type": "String"
}
}
},
"settingsNetworkValuesUnlimitedKbps": "不限制",
"@settingsNetworkValuesUnlimitedKbps": {},
"settingsResetActionsClearImageCache": "清除图片缓存",
"@settingsResetActionsClearImageCache": {},
"settingsResetName": "重置",
"@settingsResetName": {},
"settingsServersActionsAdd": "添加服务器",
"@settingsServersActionsAdd": {},
"settingsServersActionsDelete": "删除",
"@settingsServersActionsDelete": {},
"settingsServersActionsEdit": "编辑服务器",
"@settingsServersActionsEdit": {},
"settingsServersActionsSave": "保存",
"@settingsServersActionsSave": {},
"settingsServersActionsTestConnection": "测试连接",
"@settingsServersActionsTestConnection": {},
"settingsServersFieldsAddress": "地址",
"@settingsServersFieldsAddress": {},
"settingsServersFieldsPassword": "密码",
"@settingsServersFieldsPassword": {},
"settingsServersFieldsUsername": "用户名",
"@settingsServersFieldsUsername": {},
"settingsServersMessagesConnectionFailed": "连接到 {address} 失败,检查设置或服务器",
"@settingsServersMessagesConnectionFailed": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersMessagesConnectionOk": "连接到 {address} 正常!",
"@settingsServersMessagesConnectionOk": {
"placeholders": {
"address": {
"type": "String"
}
}
},
"settingsServersName": "服务器",
"@settingsServersName": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOff": "密码以 token + salt 加密发送",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOn": "密码以明文发送(不推荐,注意链接安全!)",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {},
"settingsServersOptionsForcePlaintextPasswordTitle": "强制使用明文密码",
"@settingsServersOptionsForcePlaintextPasswordTitle": {},
"actionsDownload": "下载",
"@actionsDownload": {},
"actionsDownloadCancel": "取消下载",
"@actionsDownloadCancel": {},
"actionsDownloadDelete": "删除已下载",
"@actionsDownloadDelete": {},
"actionsOk": "确定",
"@actionsOk": {},
"resourcesFilterArtist": "歌手",
"@resourcesFilterArtist": {},
"resourcesFilterOwner": "所有者",
"@resourcesFilterOwner": {},
"resourcesSongListDeleteAllTitle": "删除下载?",
"@resourcesSongListDeleteAllTitle": {},
"resourcesSortByAlbum": "专辑",
"@resourcesSortByAlbum": {},
"resourcesSortByAlbumCount": "专辑数量",
"@resourcesSortByAlbumCount": {},
"resourcesSortByUpdated": "最近添加",
"@resourcesSortByUpdated": {},
"settingsAboutActionsSupport": "支持开发者",
"@settingsAboutActionsSupport": {},
"resourcesFilterAlbum": "专辑",
"@resourcesFilterAlbum": {},
"resourcesSortByTitle": "标题",
"@resourcesSortByTitle": {},
"actionsCancel": "取消",
"@actionsCancel": {},
"actionsDelete": "删除",
"@actionsDelete": {},
"resourcesFilterYear": "年份",
"@resourcesFilterYear": {},
"resourcesSongListDeleteAllContent": "该操作会删除所有已下载的歌曲文件。",
"@resourcesSongListDeleteAllContent": {}
}

View File

@@ -0,0 +1,809 @@
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart' as intl;
import 'app_localizations_ar.dart';
import 'app_localizations_ca.dart';
import 'app_localizations_cs.dart';
import 'app_localizations_da.dart';
import 'app_localizations_de.dart';
import 'app_localizations_en.dart';
import 'app_localizations_es.dart';
import 'app_localizations_fr.dart';
import 'app_localizations_gl.dart';
import 'app_localizations_it.dart';
import 'app_localizations_ja.dart';
import 'app_localizations_nb.dart';
import 'app_localizations_pa.dart';
import 'app_localizations_pl.dart';
import 'app_localizations_pt.dart';
import 'app_localizations_ru.dart';
import 'app_localizations_tr.dart';
import 'app_localizations_vi.dart';
import 'app_localizations_zh.dart';
// ignore_for_file: type=lint
/// Callers can lookup localized strings with an instance of AppLocalizations
/// returned by `AppLocalizations.of(context)`.
///
/// Applications need to include `AppLocalizations.delegate()` in their app's
/// `localizationDelegates` list, and the locales they support in the app's
/// `supportedLocales` list. For example:
///
/// ```dart
/// import 'generated/app_localizations.dart';
///
/// return MaterialApp(
/// localizationsDelegates: AppLocalizations.localizationsDelegates,
/// supportedLocales: AppLocalizations.supportedLocales,
/// home: MyApplicationHome(),
/// );
/// ```
///
/// ## Update pubspec.yaml
///
/// Please make sure to update your pubspec.yaml to include the following
/// packages:
///
/// ```yaml
/// dependencies:
/// # Internationalization support.
/// flutter_localizations:
/// sdk: flutter
/// intl: any # Use the pinned version from flutter_localizations
///
/// # Rest of dependencies
/// ```
///
/// ## iOS Applications
///
/// iOS applications define key application metadata, including supported
/// locales, in an Info.plist file that is built into the application bundle.
/// To configure the locales supported by your app, youll need to edit this
/// file.
///
/// First, open your projects ios/Runner.xcworkspace Xcode workspace file.
/// Then, in the Project Navigator, open the Info.plist file under the Runner
/// projects Runner folder.
///
/// Next, select the Information Property List item, select Add Item from the
/// Editor menu, then select Localizations from the pop-up menu.
///
/// Select and expand the newly-created Localizations item then, for each
/// locale your application supports, add a new item and select the locale
/// you wish to add from the pop-up menu in the Value field. This list should
/// be consistent with the languages listed in the AppLocalizations.supportedLocales
/// property.
abstract class AppLocalizations {
AppLocalizations(String locale)
: localeName = intl.Intl.canonicalizedLocale(locale.toString());
final String localeName;
static AppLocalizations of(BuildContext context) {
return Localizations.of<AppLocalizations>(context, AppLocalizations)!;
}
static const LocalizationsDelegate<AppLocalizations> delegate =
_AppLocalizationsDelegate();
/// A list of this localizations delegate along with the default localizations
/// delegates.
///
/// Returns a list of localizations delegates containing this delegate along with
/// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate,
/// and GlobalWidgetsLocalizations.delegate.
///
/// Additional delegates can be added by appending to this list in
/// MaterialApp. This list does not have to be used at all if a custom list
/// of delegates is preferred or required.
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates =
<LocalizationsDelegate<dynamic>>[
delegate,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
];
/// A list of this localizations delegate's supported locales.
static const List<Locale> supportedLocales = <Locale>[
Locale('ar'),
Locale('ca'),
Locale('cs'),
Locale('da'),
Locale('de'),
Locale('en'),
Locale('es'),
Locale('fr'),
Locale('gl'),
Locale('it'),
Locale('ja'),
Locale('nb'),
Locale('pa'),
Locale('pl'),
Locale('pt'),
Locale('ru'),
Locale('tr'),
Locale('vi'),
Locale('zh'),
];
/// No description provided for @actionsCancel.
///
/// In en, this message translates to:
/// **'Cancel'**
String get actionsCancel;
/// No description provided for @actionsDelete.
///
/// In en, this message translates to:
/// **'Delete'**
String get actionsDelete;
/// No description provided for @actionsDownload.
///
/// In en, this message translates to:
/// **'Download'**
String get actionsDownload;
/// No description provided for @actionsDownloadCancel.
///
/// In en, this message translates to:
/// **'Cancel download'**
String get actionsDownloadCancel;
/// No description provided for @actionsDownloadDelete.
///
/// In en, this message translates to:
/// **'Delete downloaded'**
String get actionsDownloadDelete;
/// No description provided for @actionsOk.
///
/// In en, this message translates to:
/// **'OK'**
String get actionsOk;
/// No description provided for @actionsStar.
///
/// In en, this message translates to:
/// **'Star'**
String get actionsStar;
/// No description provided for @actionsUnstar.
///
/// In en, this message translates to:
/// **'Unstar'**
String get actionsUnstar;
/// No description provided for @controlsShuffle.
///
/// In en, this message translates to:
/// **'Shuffle'**
String get controlsShuffle;
/// No description provided for @messagesNothingHere.
///
/// In en, this message translates to:
/// **'Nothing here…'**
String get messagesNothingHere;
/// No description provided for @navigationTabsHome.
///
/// In en, this message translates to:
/// **'Home'**
String get navigationTabsHome;
/// No description provided for @navigationTabsAlbums.
///
/// In en, this message translates to:
/// **'Albums'**
String get navigationTabsAlbums;
/// No description provided for @navigationTabsArtists.
///
/// In en, this message translates to:
/// **'Artists'**
String get navigationTabsArtists;
/// No description provided for @navigationTabsPlaylists.
///
/// In en, this message translates to:
/// **'Playlists'**
String get navigationTabsPlaylists;
/// No description provided for @navigationTabsSongs.
///
/// In en, this message translates to:
/// **'Songs'**
String get navigationTabsSongs;
/// No description provided for @navigationTabsLibrary.
///
/// In en, this message translates to:
/// **'Library'**
String get navigationTabsLibrary;
/// No description provided for @navigationTabsSearch.
///
/// In en, this message translates to:
/// **'Search'**
String get navigationTabsSearch;
/// No description provided for @navigationTabsSettings.
///
/// In en, this message translates to:
/// **'Settings'**
String get navigationTabsSettings;
/// No description provided for @resourcesAlbumActionsPlay.
///
/// In en, this message translates to:
/// **'Play album'**
String get resourcesAlbumActionsPlay;
/// No description provided for @resourcesAlbumActionsView.
///
/// In en, this message translates to:
/// **'View album'**
String get resourcesAlbumActionsView;
/// No description provided for @resourcesAlbumCount.
///
/// In en, this message translates to:
/// **'{count,plural, =1{{count} album} other{{count} albums}}'**
String resourcesAlbumCount(int count);
/// No description provided for @resourcesAlbumListsSort.
///
/// In en, this message translates to:
/// **'Sort albums'**
String get resourcesAlbumListsSort;
/// No description provided for @resourcesAlbumName.
///
/// In en, this message translates to:
/// **'{count,plural, =1{Album} other{Albums}}'**
String resourcesAlbumName(int count);
/// No description provided for @resourcesArtistActionsView.
///
/// In en, this message translates to:
/// **'View artist'**
String get resourcesArtistActionsView;
/// No description provided for @resourcesArtistCount.
///
/// In en, this message translates to:
/// **'{count,plural, =1{{count} artist} other{{count} artists}}'**
String resourcesArtistCount(int count);
/// No description provided for @resourcesArtistListsSort.
///
/// In en, this message translates to:
/// **'Sort artists'**
String get resourcesArtistListsSort;
/// No description provided for @resourcesArtistName.
///
/// In en, this message translates to:
/// **'{count,plural, =1{Artist} other{Artists}}'**
String resourcesArtistName(int count);
/// No description provided for @resourcesFilterAlbum.
///
/// In en, this message translates to:
/// **'Album'**
String get resourcesFilterAlbum;
/// No description provided for @resourcesFilterArtist.
///
/// In en, this message translates to:
/// **'Artist'**
String get resourcesFilterArtist;
/// No description provided for @resourcesFilterGenre.
///
/// In en, this message translates to:
/// **'Genre'**
String get resourcesFilterGenre;
/// No description provided for @resourcesFilterOwner.
///
/// In en, this message translates to:
/// **'Owner'**
String get resourcesFilterOwner;
/// No description provided for @resourcesFilterStarred.
///
/// In en, this message translates to:
/// **'Starred'**
String get resourcesFilterStarred;
/// No description provided for @resourcesFilterYear.
///
/// In en, this message translates to:
/// **'Year'**
String get resourcesFilterYear;
/// No description provided for @resourcesPlaylistActionsPlay.
///
/// In en, this message translates to:
/// **'Play playlist'**
String get resourcesPlaylistActionsPlay;
/// No description provided for @resourcesPlaylistCount.
///
/// In en, this message translates to:
/// **'{count,plural, =1{{count} playlist} other{{count} playlists}}'**
String resourcesPlaylistCount(int count);
/// No description provided for @resourcesPlaylistName.
///
/// In en, this message translates to:
/// **'{count,plural, =1{Playlist} other{Playlists}}'**
String resourcesPlaylistName(int count);
/// No description provided for @resourcesQueueName.
///
/// In en, this message translates to:
/// **'{count,plural, =1{Queue} other{Queues}}'**
String resourcesQueueName(int count);
/// No description provided for @resourcesSongCount.
///
/// In en, this message translates to:
/// **'{count,plural, =1{{count} song} other{{count} songs}}'**
String resourcesSongCount(int count);
/// No description provided for @resourcesSongListDeleteAllContent.
///
/// In en, this message translates to:
/// **'This will remove all downloaded song files.'**
String get resourcesSongListDeleteAllContent;
/// No description provided for @resourcesSongListDeleteAllTitle.
///
/// In en, this message translates to:
/// **'Delete downloads?'**
String get resourcesSongListDeleteAllTitle;
/// No description provided for @resourcesSongListsArtistTopSongs.
///
/// In en, this message translates to:
/// **'Top Songs'**
String get resourcesSongListsArtistTopSongs;
/// No description provided for @resourcesSongName.
///
/// In en, this message translates to:
/// **'{count,plural, =1{Song} other{Songs}}'**
String resourcesSongName(int count);
/// No description provided for @resourcesSortByAdded.
///
/// In en, this message translates to:
/// **'Recently added'**
String get resourcesSortByAdded;
/// No description provided for @resourcesSortByAlbum.
///
/// In en, this message translates to:
/// **'Album'**
String get resourcesSortByAlbum;
/// No description provided for @resourcesSortByAlbumCount.
///
/// In en, this message translates to:
/// **'Album count'**
String get resourcesSortByAlbumCount;
/// No description provided for @resourcesSortByArtist.
///
/// In en, this message translates to:
/// **'Artist'**
String get resourcesSortByArtist;
/// No description provided for @resourcesSortByFrequentlyPlayed.
///
/// In en, this message translates to:
/// **'Frequently played'**
String get resourcesSortByFrequentlyPlayed;
/// No description provided for @resourcesSortByName.
///
/// In en, this message translates to:
/// **'Name'**
String get resourcesSortByName;
/// No description provided for @resourcesSortByRandom.
///
/// In en, this message translates to:
/// **'Random'**
String get resourcesSortByRandom;
/// No description provided for @resourcesSortByRecentlyPlayed.
///
/// In en, this message translates to:
/// **'Recently played'**
String get resourcesSortByRecentlyPlayed;
/// No description provided for @resourcesSortByTitle.
///
/// In en, this message translates to:
/// **'Title'**
String get resourcesSortByTitle;
/// No description provided for @resourcesSortByUpdated.
///
/// In en, this message translates to:
/// **'Recently updated'**
String get resourcesSortByUpdated;
/// No description provided for @resourcesSortByYear.
///
/// In en, this message translates to:
/// **'Year'**
String get resourcesSortByYear;
/// No description provided for @searchHeaderTitle.
///
/// In en, this message translates to:
/// **'Search: {query}'**
String searchHeaderTitle(String query);
/// No description provided for @searchInputPlaceholder.
///
/// In en, this message translates to:
/// **'Search'**
String get searchInputPlaceholder;
/// No description provided for @searchMoreResults.
///
/// In en, this message translates to:
/// **'More…'**
String get searchMoreResults;
/// No description provided for @searchNowPlayingContext.
///
/// In en, this message translates to:
/// **'Search results'**
String get searchNowPlayingContext;
/// No description provided for @settingsAboutActionsLicenses.
///
/// In en, this message translates to:
/// **'Licenses'**
String get settingsAboutActionsLicenses;
/// No description provided for @settingsAboutActionsProjectHomepage.
///
/// In en, this message translates to:
/// **'Project homepage'**
String get settingsAboutActionsProjectHomepage;
/// No description provided for @settingsAboutActionsSupport.
///
/// In en, this message translates to:
/// **'Support the developer 💜'**
String get settingsAboutActionsSupport;
/// No description provided for @settingsAboutName.
///
/// In en, this message translates to:
/// **'About'**
String get settingsAboutName;
/// No description provided for @settingsAboutShareLogs.
///
/// In en, this message translates to:
/// **'Share logs'**
String get settingsAboutShareLogs;
/// No description provided for @settingsAboutChooseLog.
///
/// In en, this message translates to:
/// **'Choose a log file'**
String get settingsAboutChooseLog;
/// No description provided for @settingsAboutVersion.
///
/// In en, this message translates to:
/// **'version {version}'**
String settingsAboutVersion(String version);
/// No description provided for @settingsMusicName.
///
/// In en, this message translates to:
/// **'Music'**
String get settingsMusicName;
/// No description provided for @settingsMusicOptionsScrobbleDescriptionOff.
///
/// In en, this message translates to:
/// **'Don\'t scrobble play history'**
String get settingsMusicOptionsScrobbleDescriptionOff;
/// No description provided for @settingsMusicOptionsScrobbleDescriptionOn.
///
/// In en, this message translates to:
/// **'Scrobble play history'**
String get settingsMusicOptionsScrobbleDescriptionOn;
/// No description provided for @settingsMusicOptionsScrobbleTitle.
///
/// In en, this message translates to:
/// **'Scrobble plays'**
String get settingsMusicOptionsScrobbleTitle;
/// No description provided for @settingsNetworkName.
///
/// In en, this message translates to:
/// **'Network'**
String get settingsNetworkName;
/// No description provided for @settingsNetworkOptionsMaxBitrateMobileTitle.
///
/// In en, this message translates to:
/// **'Maximum bitrate (mobile data)'**
String get settingsNetworkOptionsMaxBitrateMobileTitle;
/// No description provided for @settingsNetworkOptionsMaxBitrateWifiTitle.
///
/// In en, this message translates to:
/// **'Maximum bitrate (Wi-Fi)'**
String get settingsNetworkOptionsMaxBitrateWifiTitle;
/// No description provided for @settingsNetworkOptionsMaxBufferTitle.
///
/// In en, this message translates to:
/// **'Maximum buffer time'**
String get settingsNetworkOptionsMaxBufferTitle;
/// No description provided for @settingsNetworkOptionsMinBufferTitle.
///
/// In en, this message translates to:
/// **'Minimum buffer time'**
String get settingsNetworkOptionsMinBufferTitle;
/// No description provided for @settingsNetworkOptionsOfflineMode.
///
/// In en, this message translates to:
/// **'Offline mode'**
String get settingsNetworkOptionsOfflineMode;
/// No description provided for @settingsNetworkOptionsOfflineModeOff.
///
/// In en, this message translates to:
/// **'Use the internet to sync music.'**
String get settingsNetworkOptionsOfflineModeOff;
/// No description provided for @settingsNetworkOptionsOfflineModeOn.
///
/// In en, this message translates to:
/// **'Don\'t use the internet to sync or play music.'**
String get settingsNetworkOptionsOfflineModeOn;
/// No description provided for @settingsNetworkOptionsStreamFormat.
///
/// In en, this message translates to:
/// **'Preferred stream format'**
String get settingsNetworkOptionsStreamFormat;
/// No description provided for @settingsNetworkOptionsStreamFormatServerDefault.
///
/// In en, this message translates to:
/// **'Use server default'**
String get settingsNetworkOptionsStreamFormatServerDefault;
/// No description provided for @settingsNetworkValuesKbps.
///
/// In en, this message translates to:
/// **'{value}kbps'**
String settingsNetworkValuesKbps(String value);
/// No description provided for @settingsNetworkValuesSeconds.
///
/// In en, this message translates to:
/// **'{value} seconds'**
String settingsNetworkValuesSeconds(String value);
/// No description provided for @settingsNetworkValuesUnlimitedKbps.
///
/// In en, this message translates to:
/// **'Unlimited'**
String get settingsNetworkValuesUnlimitedKbps;
/// No description provided for @settingsResetActionsClearImageCache.
///
/// In en, this message translates to:
/// **'Clear Image Cache'**
String get settingsResetActionsClearImageCache;
/// No description provided for @settingsResetName.
///
/// In en, this message translates to:
/// **'Reset'**
String get settingsResetName;
/// No description provided for @settingsServersActionsAdd.
///
/// In en, this message translates to:
/// **'Add source'**
String get settingsServersActionsAdd;
/// No description provided for @settingsServersActionsDelete.
///
/// In en, this message translates to:
/// **'Delete'**
String get settingsServersActionsDelete;
/// No description provided for @settingsServersActionsEdit.
///
/// In en, this message translates to:
/// **'Edit source'**
String get settingsServersActionsEdit;
/// No description provided for @settingsServersActionsSave.
///
/// In en, this message translates to:
/// **'Save'**
String get settingsServersActionsSave;
/// No description provided for @settingsServersActionsTestConnection.
///
/// In en, this message translates to:
/// **'Test connection'**
String get settingsServersActionsTestConnection;
/// No description provided for @settingsServersFieldsAddress.
///
/// In en, this message translates to:
/// **'Address'**
String get settingsServersFieldsAddress;
/// No description provided for @settingsServersFieldsName.
///
/// In en, this message translates to:
/// **'Name'**
String get settingsServersFieldsName;
/// No description provided for @settingsServersFieldsPassword.
///
/// In en, this message translates to:
/// **'Password'**
String get settingsServersFieldsPassword;
/// No description provided for @settingsServersFieldsUsername.
///
/// In en, this message translates to:
/// **'Username'**
String get settingsServersFieldsUsername;
/// No description provided for @settingsServersMessagesConnectionFailed.
///
/// In en, this message translates to:
/// **'Connection to {address} failed, check settings or server'**
String settingsServersMessagesConnectionFailed(String address);
/// No description provided for @settingsServersMessagesConnectionOk.
///
/// In en, this message translates to:
/// **'Connection to {address} OK!'**
String settingsServersMessagesConnectionOk(String address);
/// No description provided for @settingsServersName.
///
/// In en, this message translates to:
/// **'Sources'**
String get settingsServersName;
/// No description provided for @settingsServersOptionsForcePlaintextPasswordDescriptionOff.
///
/// In en, this message translates to:
/// **'Send password as token + salt'**
String get settingsServersOptionsForcePlaintextPasswordDescriptionOff;
/// No description provided for @settingsServersOptionsForcePlaintextPasswordDescriptionOn.
///
/// In en, this message translates to:
/// **'Send password in plaintext (legacy, make sure your connection is secure!)'**
String get settingsServersOptionsForcePlaintextPasswordDescriptionOn;
/// No description provided for @settingsServersOptionsForcePlaintextPasswordTitle.
///
/// In en, this message translates to:
/// **'Force plaintext password'**
String get settingsServersOptionsForcePlaintextPasswordTitle;
}
class _AppLocalizationsDelegate
extends LocalizationsDelegate<AppLocalizations> {
const _AppLocalizationsDelegate();
@override
Future<AppLocalizations> load(Locale locale) {
return SynchronousFuture<AppLocalizations>(lookupAppLocalizations(locale));
}
@override
bool isSupported(Locale locale) => <String>[
'ar',
'ca',
'cs',
'da',
'de',
'en',
'es',
'fr',
'gl',
'it',
'ja',
'nb',
'pa',
'pl',
'pt',
'ru',
'tr',
'vi',
'zh',
].contains(locale.languageCode);
@override
bool shouldReload(_AppLocalizationsDelegate old) => false;
}
AppLocalizations lookupAppLocalizations(Locale locale) {
// Lookup logic when only language code is specified.
switch (locale.languageCode) {
case 'ar':
return AppLocalizationsAr();
case 'ca':
return AppLocalizationsCa();
case 'cs':
return AppLocalizationsCs();
case 'da':
return AppLocalizationsDa();
case 'de':
return AppLocalizationsDe();
case 'en':
return AppLocalizationsEn();
case 'es':
return AppLocalizationsEs();
case 'fr':
return AppLocalizationsFr();
case 'gl':
return AppLocalizationsGl();
case 'it':
return AppLocalizationsIt();
case 'ja':
return AppLocalizationsJa();
case 'nb':
return AppLocalizationsNb();
case 'pa':
return AppLocalizationsPa();
case 'pl':
return AppLocalizationsPl();
case 'pt':
return AppLocalizationsPt();
case 'ru':
return AppLocalizationsRu();
case 'tr':
return AppLocalizationsTr();
case 'vi':
return AppLocalizationsVi();
case 'zh':
return AppLocalizationsZh();
}
throw FlutterError(
'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
'an issue with the localizations generation tool. Please file an issue '
'on GitHub with a reproducible sample app and the gen-l10n configuration '
'that was used.',
);
}

View File

@@ -0,0 +1,411 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for Arabic (`ar`).
class AppLocalizationsAr extends AppLocalizations {
AppLocalizationsAr([String locale = 'ar']) : super(locale);
@override
String get actionsCancel => 'Cancel';
@override
String get actionsDelete => 'Delete';
@override
String get actionsDownload => 'Download';
@override
String get actionsDownloadCancel => 'Cancel download';
@override
String get actionsDownloadDelete => 'Delete downloaded';
@override
String get actionsOk => 'OK';
@override
String get actionsStar => 'مميز';
@override
String get actionsUnstar => 'ازل التمييز';
@override
String get controlsShuffle => 'Shuffle';
@override
String get messagesNothingHere => 'لا شيء هنا…';
@override
String get navigationTabsHome => 'الرئيسية';
@override
String get navigationTabsAlbums => 'Albums';
@override
String get navigationTabsArtists => 'Artists';
@override
String get navigationTabsPlaylists => 'Playlists';
@override
String get navigationTabsSongs => 'Songs';
@override
String get navigationTabsLibrary => 'المكتبة';
@override
String get navigationTabsSearch => 'بحث';
@override
String get navigationTabsSettings => 'الإعدادات';
@override
String get resourcesAlbumActionsPlay => 'شَغل الألبوم';
@override
String get resourcesAlbumActionsView => 'أعرض الألبوم';
@override
String resourcesAlbumCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count albums',
one: '$count album',
);
return '$_temp0';
}
@override
String get resourcesAlbumListsSort => 'فرز الألبومات';
@override
String resourcesAlbumName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '',
many: '',
few: 'ألبوم',
one: '',
);
return '$_temp0';
}
@override
String get resourcesArtistActionsView => 'أظهر الفنان';
@override
String resourcesArtistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count artists',
one: '$count artist',
);
return '$_temp0';
}
@override
String get resourcesArtistListsSort => 'فرز الفنانين';
@override
String resourcesArtistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'فنانان',
many: 'فنانان',
few: 'فنان',
one: '',
);
return '$_temp0';
}
@override
String get resourcesFilterAlbum => 'Album';
@override
String get resourcesFilterArtist => 'Artist';
@override
String get resourcesFilterGenre => 'حسب النوع';
@override
String get resourcesFilterOwner => 'Owner';
@override
String get resourcesFilterStarred => 'موسوم';
@override
String get resourcesFilterYear => 'Year';
@override
String get resourcesPlaylistActionsPlay => 'شغل قائمة التشغيل';
@override
String resourcesPlaylistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count playlists',
one: '$count playlist',
);
return '$_temp0';
}
@override
String resourcesPlaylistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'قائمتان تشغيل',
many: 'قائمتان تشغيل',
few: 'قائمة تشغيل',
one: '',
);
return '$_temp0';
}
@override
String resourcesQueueName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'صفين',
many: 'صفين',
few: 'صف',
one: '',
);
return '$_temp0';
}
@override
String resourcesSongCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count songs',
one: '$count song',
);
return '$_temp0';
}
@override
String get resourcesSongListDeleteAllContent =>
'This will remove all downloaded song files.';
@override
String get resourcesSongListDeleteAllTitle => 'Delete downloads?';
@override
String get resourcesSongListsArtistTopSongs => 'أشهر الأغاني';
@override
String resourcesSongName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '',
many: '',
few: 'أُغْنِيَة',
one: '',
);
return '$_temp0';
}
@override
String get resourcesSortByAdded => 'أضيف حديثا';
@override
String get resourcesSortByAlbum => 'Album';
@override
String get resourcesSortByAlbumCount => 'Album count';
@override
String get resourcesSortByArtist => 'حسب الفنان/ة';
@override
String get resourcesSortByFrequentlyPlayed => 'مشغل كثيرا';
@override
String get resourcesSortByName => 'حسب الاسم';
@override
String get resourcesSortByRandom => 'عشوائي';
@override
String get resourcesSortByRecentlyPlayed => 'شغل حديثا';
@override
String get resourcesSortByTitle => 'Title';
@override
String get resourcesSortByUpdated => 'Recently updated';
@override
String get resourcesSortByYear => 'حسب السنة';
@override
String searchHeaderTitle(String query) {
return 'بحث: $query';
}
@override
String get searchInputPlaceholder => 'بحث';
@override
String get searchMoreResults => 'المزيد…';
@override
String get searchNowPlayingContext => 'نتائج البحث';
@override
String get settingsAboutActionsLicenses => 'الرخص';
@override
String get settingsAboutActionsProjectHomepage => 'موقع المشروع';
@override
String get settingsAboutActionsSupport => 'Support the developer 💜';
@override
String get settingsAboutName => 'حول';
@override
String get settingsAboutShareLogs => 'Share logs';
@override
String get settingsAboutChooseLog => 'Choose a log file';
@override
String settingsAboutVersion(String version) {
return 'الإصدار $version';
}
@override
String get settingsMusicName => 'موسيقى';
@override
String get settingsMusicOptionsScrobbleDescriptionOff =>
'لا تستورد سجل التشغيل';
@override
String get settingsMusicOptionsScrobbleDescriptionOn => 'استيراد سجل التشغيل';
@override
String get settingsMusicOptionsScrobbleTitle => 'استيراد سجل التشغيل';
@override
String get settingsNetworkName => 'الشبكة';
@override
String get settingsNetworkOptionsMaxBitrateMobileTitle =>
'أقصى معدل نقل بيانات (mobile)';
@override
String get settingsNetworkOptionsMaxBitrateWifiTitle =>
'أقصى معدل نقل بيانات (Wi-Fi)';
@override
String get settingsNetworkOptionsMaxBufferTitle =>
'الحد الأقصى من وقت التخزين المؤقت';
@override
String get settingsNetworkOptionsMinBufferTitle =>
'الحد الأدنى من وقت التخزين المؤقت';
@override
String get settingsNetworkOptionsOfflineMode => 'Offline mode';
@override
String get settingsNetworkOptionsOfflineModeOff =>
'Use the internet to sync music.';
@override
String get settingsNetworkOptionsOfflineModeOn =>
'Don\'t use the internet to sync or play music.';
@override
String get settingsNetworkOptionsStreamFormat => 'Preferred stream format';
@override
String get settingsNetworkOptionsStreamFormatServerDefault =>
'Use server default';
@override
String settingsNetworkValuesKbps(String value) {
return '$value كيلو بايت في الثانية';
}
@override
String settingsNetworkValuesSeconds(String value) {
return '$value ثواني';
}
@override
String get settingsNetworkValuesUnlimitedKbps => 'غير محدود';
@override
String get settingsResetActionsClearImageCache =>
'مسح ذاكرة التخزين المؤقت للصور';
@override
String get settingsResetName => 'إعادة ضبط';
@override
String get settingsServersActionsAdd => 'أضف سيرفر';
@override
String get settingsServersActionsDelete => 'حذف';
@override
String get settingsServersActionsEdit => 'عدل السيرفر';
@override
String get settingsServersActionsSave => 'حفظ';
@override
String get settingsServersActionsTestConnection => 'أخبر الأتصال';
@override
String get settingsServersFieldsAddress => 'العناوين';
@override
String get settingsServersFieldsName => 'Name';
@override
String get settingsServersFieldsPassword => 'كلمة المرور';
@override
String get settingsServersFieldsUsername => 'إسم المستخدم';
@override
String settingsServersMessagesConnectionFailed(String address) {
return 'الأتصال ب $address فشل، ابحث في الإعدادات او السيرفر';
}
@override
String settingsServersMessagesConnectionOk(String address) {
return 'الأتصال ب $address جيد!';
}
@override
String get settingsServersName => 'السيرفرات';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOff =>
'أرسل كلمة المرور على شكل توكِن';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOn =>
'أرسل كلمة المرور بنص عادي (قديم ، تأكد من أن اتصالك آمن!)';
@override
String get settingsServersOptionsForcePlaintextPasswordTitle =>
'أظهر كلمة المرور';
}

View File

@@ -0,0 +1,404 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for Catalan Valencian (`ca`).
class AppLocalizationsCa extends AppLocalizations {
AppLocalizationsCa([String locale = 'ca']) : super(locale);
@override
String get actionsCancel => 'Cancel';
@override
String get actionsDelete => 'Delete';
@override
String get actionsDownload => 'Download';
@override
String get actionsDownloadCancel => 'Cancel download';
@override
String get actionsDownloadDelete => 'Delete downloaded';
@override
String get actionsOk => 'OK';
@override
String get actionsStar => 'Afegir als favorits';
@override
String get actionsUnstar => 'Retirar estrella';
@override
String get controlsShuffle => 'Shuffle';
@override
String get messagesNothingHere => 'Aquí no hi ha res…';
@override
String get navigationTabsHome => 'Inici';
@override
String get navigationTabsAlbums => 'Albums';
@override
String get navigationTabsArtists => 'Artists';
@override
String get navigationTabsPlaylists => 'Playlists';
@override
String get navigationTabsSongs => 'Songs';
@override
String get navigationTabsLibrary => 'Biblioteca';
@override
String get navigationTabsSearch => 'Cercar';
@override
String get navigationTabsSettings => 'Paràmetres';
@override
String get resourcesAlbumActionsPlay => 'Reproduir l\'àlbum';
@override
String get resourcesAlbumActionsView => 'Veure l\'àlbum';
@override
String resourcesAlbumCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count albums',
one: '$count album',
);
return '$_temp0';
}
@override
String get resourcesAlbumListsSort => 'Ordenar els àlbums';
@override
String resourcesAlbumName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Àlbums',
one: 'Àlbum',
);
return '$_temp0';
}
@override
String get resourcesArtistActionsView => 'Veure l\'artista';
@override
String resourcesArtistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count artists',
one: '$count artist',
);
return '$_temp0';
}
@override
String get resourcesArtistListsSort => 'Ordenar els artistes';
@override
String resourcesArtistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Artistes',
one: 'Artista',
);
return '$_temp0';
}
@override
String get resourcesFilterAlbum => 'Album';
@override
String get resourcesFilterArtist => 'Artist';
@override
String get resourcesFilterGenre => 'Per gènere';
@override
String get resourcesFilterOwner => 'Owner';
@override
String get resourcesFilterStarred => 'Favorits';
@override
String get resourcesFilterYear => 'Year';
@override
String get resourcesPlaylistActionsPlay =>
'Reproduir la llista de reproducció';
@override
String resourcesPlaylistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count playlists',
one: '$count playlist',
);
return '$_temp0';
}
@override
String resourcesPlaylistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Llistes de reproducció',
one: 'Llista de reproducció',
);
return '$_temp0';
}
@override
String resourcesQueueName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Cues',
one: 'Cua',
);
return '$_temp0';
}
@override
String resourcesSongCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count songs',
one: '$count song',
);
return '$_temp0';
}
@override
String get resourcesSongListDeleteAllContent =>
'This will remove all downloaded song files.';
@override
String get resourcesSongListDeleteAllTitle => 'Delete downloads?';
@override
String get resourcesSongListsArtistTopSongs => 'Millors cançons';
@override
String resourcesSongName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Cançons',
one: 'Cançó',
);
return '$_temp0';
}
@override
String get resourcesSortByAdded => 'Afegit recentment';
@override
String get resourcesSortByAlbum => 'Album';
@override
String get resourcesSortByAlbumCount => 'Album count';
@override
String get resourcesSortByArtist => 'Per artista';
@override
String get resourcesSortByFrequentlyPlayed => 'Escoltat freqüentment';
@override
String get resourcesSortByName => 'Pel nom';
@override
String get resourcesSortByRandom => 'Aleatori';
@override
String get resourcesSortByRecentlyPlayed => 'Reproduït recentment';
@override
String get resourcesSortByTitle => 'Title';
@override
String get resourcesSortByUpdated => 'Recently updated';
@override
String get resourcesSortByYear => 'Per any';
@override
String searchHeaderTitle(String query) {
return 'Cercar: $query';
}
@override
String get searchInputPlaceholder => 'Cercar';
@override
String get searchMoreResults => 'Més…';
@override
String get searchNowPlayingContext => 'Resultats de la cerca';
@override
String get settingsAboutActionsLicenses => 'Llicències';
@override
String get settingsAboutActionsProjectHomepage =>
'Pàgina d\'inici del projecte';
@override
String get settingsAboutActionsSupport => 'Support the developer 💜';
@override
String get settingsAboutName => 'Quant a';
@override
String get settingsAboutShareLogs => 'Share logs';
@override
String get settingsAboutChooseLog => 'Choose a log file';
@override
String settingsAboutVersion(String version) {
return 'versió $version';
}
@override
String get settingsMusicName => 'Música';
@override
String get settingsMusicOptionsScrobbleDescriptionOff =>
'No capturar l\'historial de reproducció';
@override
String get settingsMusicOptionsScrobbleDescriptionOn =>
'Capturar l\'historial de reproduccions';
@override
String get settingsMusicOptionsScrobbleTitle => 'Capturar la lectura';
@override
String get settingsNetworkName => 'Xarxa';
@override
String get settingsNetworkOptionsMaxBitrateMobileTitle =>
'Taxa de bits màxima (mòbil)';
@override
String get settingsNetworkOptionsMaxBitrateWifiTitle =>
'Taxa de bits màxima (Wi-Fi)';
@override
String get settingsNetworkOptionsMaxBufferTitle =>
'Temps màxim en memòria intermèdia';
@override
String get settingsNetworkOptionsMinBufferTitle =>
'Temps mínim en memòria intermèdia';
@override
String get settingsNetworkOptionsOfflineMode => 'Offline mode';
@override
String get settingsNetworkOptionsOfflineModeOff =>
'Use the internet to sync music.';
@override
String get settingsNetworkOptionsOfflineModeOn =>
'Don\'t use the internet to sync or play music.';
@override
String get settingsNetworkOptionsStreamFormat => 'Preferred stream format';
@override
String get settingsNetworkOptionsStreamFormatServerDefault =>
'Use server default';
@override
String settingsNetworkValuesKbps(String value) {
return '$value kbps';
}
@override
String settingsNetworkValuesSeconds(String value) {
return '$value segons';
}
@override
String get settingsNetworkValuesUnlimitedKbps => 'Il·limitat';
@override
String get settingsResetActionsClearImageCache =>
'Esborrar la memòria cau d\'imatges';
@override
String get settingsResetName => 'Reinicialitzar';
@override
String get settingsServersActionsAdd => 'Afegir un servidor';
@override
String get settingsServersActionsDelete => 'Esborrar';
@override
String get settingsServersActionsEdit => 'Editar el servidor';
@override
String get settingsServersActionsSave => 'Desar';
@override
String get settingsServersActionsTestConnection => 'Comprovar la connexió';
@override
String get settingsServersFieldsAddress => 'Adreça';
@override
String get settingsServersFieldsName => 'Name';
@override
String get settingsServersFieldsPassword => 'Contrasenya';
@override
String get settingsServersFieldsUsername => 'Nom dusuari';
@override
String settingsServersMessagesConnectionFailed(String address) {
return 'La connexió a $address ha fallat, comprova la configuració o el servidor';
}
@override
String settingsServersMessagesConnectionOk(String address) {
return 'Connexió a $address OK!';
}
@override
String get settingsServersName => 'Servidors';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOff =>
'Enviar contrasenya com a token + salt';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOn =>
'Enviar la contrasenya en text sense format (obsolet, assegura\'t que la teva connexió sigui segura!)';
@override
String get settingsServersOptionsForcePlaintextPasswordTitle =>
'Forçar la contrasenya de text sense format';
}

View File

@@ -0,0 +1,410 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for Czech (`cs`).
class AppLocalizationsCs extends AppLocalizations {
AppLocalizationsCs([String locale = 'cs']) : super(locale);
@override
String get actionsCancel => 'Zrušit';
@override
String get actionsDelete => 'Smazat';
@override
String get actionsDownload => 'Stáhnout';
@override
String get actionsDownloadCancel => 'Zrušit stahování';
@override
String get actionsDownloadDelete => 'Smazat stažené';
@override
String get actionsOk => 'OK';
@override
String get actionsStar => 'Ohodnotit';
@override
String get actionsUnstar => 'Zrušit hodnocení';
@override
String get controlsShuffle => 'Náhodně';
@override
String get messagesNothingHere => 'Zde nic není…';
@override
String get navigationTabsHome => 'Domů';
@override
String get navigationTabsAlbums => 'Albums';
@override
String get navigationTabsArtists => 'Artists';
@override
String get navigationTabsPlaylists => 'Playlists';
@override
String get navigationTabsSongs => 'Songs';
@override
String get navigationTabsLibrary => 'Knihovna';
@override
String get navigationTabsSearch => 'Hledat';
@override
String get navigationTabsSettings => 'Nastavení';
@override
String get resourcesAlbumActionsPlay => 'Přehrát album';
@override
String get resourcesAlbumActionsView => 'Zobrazit album';
@override
String resourcesAlbumCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count albums',
one: '$count album',
);
return '$_temp0';
}
@override
String get resourcesAlbumListsSort => 'Seřadit alba';
@override
String resourcesAlbumName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Alba',
many: 'Alba',
few: 'Alba',
one: 'Album',
);
return '$_temp0';
}
@override
String get resourcesArtistActionsView => 'Zobrazit umělce';
@override
String resourcesArtistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count artists',
one: '$count artist',
);
return '$_temp0';
}
@override
String get resourcesArtistListsSort => 'Seřadit umělce';
@override
String resourcesArtistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Umělci',
many: 'Umělci',
few: 'Umělci',
one: 'Umělec',
);
return '$_temp0';
}
@override
String get resourcesFilterAlbum => 'Album';
@override
String get resourcesFilterArtist => 'Umělec';
@override
String get resourcesFilterGenre => 'Podle žánru';
@override
String get resourcesFilterOwner => 'Majitele';
@override
String get resourcesFilterStarred => 'Ohodnocené';
@override
String get resourcesFilterYear => 'Rok';
@override
String get resourcesPlaylistActionsPlay => 'Přehrát seznam skladeb';
@override
String resourcesPlaylistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count playlists',
one: '$count playlist',
);
return '$_temp0';
}
@override
String resourcesPlaylistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Seznamy skladeb',
many: 'Seznamy skladeb',
few: 'Seznamy skladeb',
one: 'Seznam skladeb',
);
return '$_temp0';
}
@override
String resourcesQueueName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Fronty',
many: 'Fronty',
few: 'Fronty',
one: 'Fronta',
);
return '$_temp0';
}
@override
String resourcesSongCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count songs',
one: '$count song',
);
return '$_temp0';
}
@override
String get resourcesSongListDeleteAllContent =>
'Toto odstraní všechny stažené soubory s hudbou.';
@override
String get resourcesSongListDeleteAllTitle => 'Smazat stažené?';
@override
String get resourcesSongListsArtistTopSongs => 'Top skladby';
@override
String resourcesSongName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Skladby',
many: 'Skladby',
few: 'Skladby',
one: 'Skladba',
);
return '$_temp0';
}
@override
String get resourcesSortByAdded => 'Nedávno přidané';
@override
String get resourcesSortByAlbum => 'Alba';
@override
String get resourcesSortByAlbumCount => 'Počtu alb';
@override
String get resourcesSortByArtist => 'Umělce';
@override
String get resourcesSortByFrequentlyPlayed => 'Často přehrávané';
@override
String get resourcesSortByName => 'Názvu';
@override
String get resourcesSortByRandom => 'Náhodně';
@override
String get resourcesSortByRecentlyPlayed => 'Často přehrávané';
@override
String get resourcesSortByTitle => 'Názvu';
@override
String get resourcesSortByUpdated => 'Naposledy upravené';
@override
String get resourcesSortByYear => 'Roku';
@override
String searchHeaderTitle(String query) {
return 'Hledat: $query';
}
@override
String get searchInputPlaceholder => 'Hledat';
@override
String get searchMoreResults => 'Více…';
@override
String get searchNowPlayingContext => 'Výsledky hledání';
@override
String get settingsAboutActionsLicenses => 'Licence';
@override
String get settingsAboutActionsProjectHomepage => 'Stránka projektu';
@override
String get settingsAboutActionsSupport => 'Podpořit vývojáře 💜';
@override
String get settingsAboutName => 'O aplikaci';
@override
String get settingsAboutShareLogs => 'Share logs';
@override
String get settingsAboutChooseLog => 'Choose a log file';
@override
String settingsAboutVersion(String version) {
return 'verze $version';
}
@override
String get settingsMusicName => 'Music';
@override
String get settingsMusicOptionsScrobbleDescriptionOff =>
'Don\'t scrobble play history';
@override
String get settingsMusicOptionsScrobbleDescriptionOn =>
'Scrobble play history';
@override
String get settingsMusicOptionsScrobbleTitle => 'Scrobble plays';
@override
String get settingsNetworkName => 'Síť';
@override
String get settingsNetworkOptionsMaxBitrateMobileTitle =>
'Maximální datový tok (mobil)';
@override
String get settingsNetworkOptionsMaxBitrateWifiTitle =>
'Maximální datový tok (Wi-Fi)';
@override
String get settingsNetworkOptionsMaxBufferTitle => 'Maximum buffer time';
@override
String get settingsNetworkOptionsMinBufferTitle => 'Minimum buffer time';
@override
String get settingsNetworkOptionsOfflineMode => 'Offline mode';
@override
String get settingsNetworkOptionsOfflineModeOff =>
'Use the internet to sync music.';
@override
String get settingsNetworkOptionsOfflineModeOn =>
'Don\'t use the internet to sync or play music.';
@override
String get settingsNetworkOptionsStreamFormat =>
'Preferovaný formát pro streamování';
@override
String get settingsNetworkOptionsStreamFormatServerDefault =>
'Použít nastavení serveru';
@override
String settingsNetworkValuesKbps(String value) {
return '${value}kbps';
}
@override
String settingsNetworkValuesSeconds(String value) {
return '$value sekund';
}
@override
String get settingsNetworkValuesUnlimitedKbps => 'Neomezeno';
@override
String get settingsResetActionsClearImageCache => 'Smazat mezipaměť obrázků';
@override
String get settingsResetName => 'Resetovat';
@override
String get settingsServersActionsAdd => 'Přidat server';
@override
String get settingsServersActionsDelete => 'Odstranit';
@override
String get settingsServersActionsEdit => 'Upravit server';
@override
String get settingsServersActionsSave => 'Uložit';
@override
String get settingsServersActionsTestConnection => 'Otestovat spojení';
@override
String get settingsServersFieldsAddress => 'Adresa';
@override
String get settingsServersFieldsName => 'Jméno';
@override
String get settingsServersFieldsPassword => 'Heslo';
@override
String get settingsServersFieldsUsername => 'Uživ. jméno';
@override
String settingsServersMessagesConnectionFailed(String address) {
return 'Připojení k $address selhalo, zkontrolujte nastavení nebo server';
}
@override
String settingsServersMessagesConnectionOk(String address) {
return 'Připojení k $address je OK!';
}
@override
String get settingsServersName => 'Servery';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOff =>
'Posílat heslo jako token + salt';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOn =>
'Posílat heslo v prostém textu (zastaralé, ujistěte se, že je vaše připojení zabezpečené!)';
@override
String get settingsServersOptionsForcePlaintextPasswordTitle =>
'Vynutit heslo ve formátu prostého textu';
}

View File

@@ -0,0 +1,399 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for Danish (`da`).
class AppLocalizationsDa extends AppLocalizations {
AppLocalizationsDa([String locale = 'da']) : super(locale);
@override
String get actionsCancel => 'Cancel';
@override
String get actionsDelete => 'Delete';
@override
String get actionsDownload => 'Download';
@override
String get actionsDownloadCancel => 'Cancel download';
@override
String get actionsDownloadDelete => 'Delete downloaded';
@override
String get actionsOk => 'OK';
@override
String get actionsStar => 'Star';
@override
String get actionsUnstar => 'Unstar';
@override
String get controlsShuffle => 'Shuffle';
@override
String get messagesNothingHere => 'Intet her…';
@override
String get navigationTabsHome => 'Hjem';
@override
String get navigationTabsAlbums => 'Albums';
@override
String get navigationTabsArtists => 'Artists';
@override
String get navigationTabsPlaylists => 'Playlists';
@override
String get navigationTabsSongs => 'Songs';
@override
String get navigationTabsLibrary => 'Bibliotek';
@override
String get navigationTabsSearch => 'Søg';
@override
String get navigationTabsSettings => 'Indstillinger';
@override
String get resourcesAlbumActionsPlay => 'Afspil album';
@override
String get resourcesAlbumActionsView => 'Se album';
@override
String resourcesAlbumCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count albums',
one: '$count album',
);
return '$_temp0';
}
@override
String get resourcesAlbumListsSort => 'Sortér albums';
@override
String resourcesAlbumName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Albums',
one: 'Album',
);
return '$_temp0';
}
@override
String get resourcesArtistActionsView => 'Se kunstnere';
@override
String resourcesArtistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count artists',
one: '$count artist',
);
return '$_temp0';
}
@override
String get resourcesArtistListsSort => 'Sortér kunstnere';
@override
String resourcesArtistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Kunstnere',
one: 'Kunstner',
);
return '$_temp0';
}
@override
String get resourcesFilterAlbum => 'Album';
@override
String get resourcesFilterArtist => 'Artist';
@override
String get resourcesFilterGenre => 'Efter genre';
@override
String get resourcesFilterOwner => 'Owner';
@override
String get resourcesFilterStarred => 'Starred';
@override
String get resourcesFilterYear => 'Year';
@override
String get resourcesPlaylistActionsPlay => 'Afspil spilleliste';
@override
String resourcesPlaylistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count playlists',
one: '$count playlist',
);
return '$_temp0';
}
@override
String resourcesPlaylistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Spillelister',
one: 'Spilleliste',
);
return '$_temp0';
}
@override
String resourcesQueueName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Køer',
one: '',
);
return '$_temp0';
}
@override
String resourcesSongCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count songs',
one: '$count song',
);
return '$_temp0';
}
@override
String get resourcesSongListDeleteAllContent =>
'This will remove all downloaded song files.';
@override
String get resourcesSongListDeleteAllTitle => 'Delete downloads?';
@override
String get resourcesSongListsArtistTopSongs => 'Top sange';
@override
String resourcesSongName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Sange',
one: 'Sang',
);
return '$_temp0';
}
@override
String get resourcesSortByAdded => 'Recently added';
@override
String get resourcesSortByAlbum => 'Album';
@override
String get resourcesSortByAlbumCount => 'Album count';
@override
String get resourcesSortByArtist => 'Efter kunstner';
@override
String get resourcesSortByFrequentlyPlayed => 'Frequently played';
@override
String get resourcesSortByName => 'Efter navn';
@override
String get resourcesSortByRandom => 'Tilfældig';
@override
String get resourcesSortByRecentlyPlayed => 'Recently played';
@override
String get resourcesSortByTitle => 'Title';
@override
String get resourcesSortByUpdated => 'Recently updated';
@override
String get resourcesSortByYear => 'Efter år';
@override
String searchHeaderTitle(String query) {
return 'Søg: $query';
}
@override
String get searchInputPlaceholder => 'Søg';
@override
String get searchMoreResults => 'Mere…';
@override
String get searchNowPlayingContext => 'Søgeresultater';
@override
String get settingsAboutActionsLicenses => 'Licenser';
@override
String get settingsAboutActionsProjectHomepage => 'Projekt hjemmeside';
@override
String get settingsAboutActionsSupport => 'Support the developer 💜';
@override
String get settingsAboutName => 'Omkring';
@override
String get settingsAboutShareLogs => 'Share logs';
@override
String get settingsAboutChooseLog => 'Choose a log file';
@override
String settingsAboutVersion(String version) {
return 'version $version';
}
@override
String get settingsMusicName => 'Musik';
@override
String get settingsMusicOptionsScrobbleDescriptionOff =>
'Don\'t scrobble play history';
@override
String get settingsMusicOptionsScrobbleDescriptionOn =>
'Scrobble afspilningshistorik';
@override
String get settingsMusicOptionsScrobbleTitle => 'Scrobble afspilninger';
@override
String get settingsNetworkName => 'Netværk';
@override
String get settingsNetworkOptionsMaxBitrateMobileTitle =>
'Maksimum bitrate (mobil)';
@override
String get settingsNetworkOptionsMaxBitrateWifiTitle =>
'Maksimum bitrate (Wi-Fi)';
@override
String get settingsNetworkOptionsMaxBufferTitle => 'Maksimum buffertid';
@override
String get settingsNetworkOptionsMinBufferTitle => 'Minimum buffertid';
@override
String get settingsNetworkOptionsOfflineMode => 'Offline mode';
@override
String get settingsNetworkOptionsOfflineModeOff =>
'Use the internet to sync music.';
@override
String get settingsNetworkOptionsOfflineModeOn =>
'Don\'t use the internet to sync or play music.';
@override
String get settingsNetworkOptionsStreamFormat => 'Preferred stream format';
@override
String get settingsNetworkOptionsStreamFormatServerDefault =>
'Use server default';
@override
String settingsNetworkValuesKbps(String value) {
return '${value}kbps';
}
@override
String settingsNetworkValuesSeconds(String value) {
return '$value sekunder';
}
@override
String get settingsNetworkValuesUnlimitedKbps => 'Ubegrænset';
@override
String get settingsResetActionsClearImageCache => 'Ryd billede cache';
@override
String get settingsResetName => 'Nulstil';
@override
String get settingsServersActionsAdd => 'Tilføj server';
@override
String get settingsServersActionsDelete => 'Slet';
@override
String get settingsServersActionsEdit => 'Redigér server';
@override
String get settingsServersActionsSave => 'Gem';
@override
String get settingsServersActionsTestConnection => 'Test forbindelse';
@override
String get settingsServersFieldsAddress => 'Adresse';
@override
String get settingsServersFieldsName => 'Name';
@override
String get settingsServersFieldsPassword => 'Adgangskode';
@override
String get settingsServersFieldsUsername => 'Brugernavn';
@override
String settingsServersMessagesConnectionFailed(String address) {
return 'Forbindelse til $address mislykkedes, tjek indstillinger eller server';
}
@override
String settingsServersMessagesConnectionOk(String address) {
return 'Forbindelse til $address OK!';
}
@override
String get settingsServersName => 'Servere';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOff =>
'Send password as token + salt';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOn =>
'Send password in plaintext (legacy, make sure your connection is secure!)';
@override
String get settingsServersOptionsForcePlaintextPasswordTitle =>
'Force plaintext password';
}

View File

@@ -0,0 +1,401 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for German (`de`).
class AppLocalizationsDe extends AppLocalizations {
AppLocalizationsDe([String locale = 'de']) : super(locale);
@override
String get actionsCancel => 'Abbrechen';
@override
String get actionsDelete => 'Löschen';
@override
String get actionsDownload => 'Herunterladen';
@override
String get actionsDownloadCancel => 'Download abbrechen';
@override
String get actionsDownloadDelete => 'Heruntergeladene Inhalte löschen';
@override
String get actionsOk => 'OK';
@override
String get actionsStar => 'Markieren';
@override
String get actionsUnstar => 'Markierung entfernen';
@override
String get controlsShuffle => 'Zufall';
@override
String get messagesNothingHere => 'Hier ist nichts…';
@override
String get navigationTabsHome => 'Startseite';
@override
String get navigationTabsAlbums => 'Albums';
@override
String get navigationTabsArtists => 'Artists';
@override
String get navigationTabsPlaylists => 'Playlists';
@override
String get navigationTabsSongs => 'Songs';
@override
String get navigationTabsLibrary => 'Bibliothek';
@override
String get navigationTabsSearch => 'Suche';
@override
String get navigationTabsSettings => 'Einstellungen';
@override
String get resourcesAlbumActionsPlay => 'Album abspielen';
@override
String get resourcesAlbumActionsView => 'Album anzeigen';
@override
String resourcesAlbumCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count Alben',
one: '$count Album',
);
return '$_temp0';
}
@override
String get resourcesAlbumListsSort => 'Alben sortieren';
@override
String resourcesAlbumName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Alben',
one: 'Album',
);
return '$_temp0';
}
@override
String get resourcesArtistActionsView => 'Interpret anzeigen';
@override
String resourcesArtistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count Künstler',
one: '$count Künstler',
);
return '$_temp0';
}
@override
String get resourcesArtistListsSort => 'Interpreten sortieren';
@override
String resourcesArtistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Interpreten',
one: 'Interpret',
);
return '$_temp0';
}
@override
String get resourcesFilterAlbum => 'Album';
@override
String get resourcesFilterArtist => 'Künstler';
@override
String get resourcesFilterGenre => 'Nach Genre';
@override
String get resourcesFilterOwner => 'Besitzer';
@override
String get resourcesFilterStarred => 'Favoriten';
@override
String get resourcesFilterYear => 'Jahr';
@override
String get resourcesPlaylistActionsPlay => 'Wiedergabeliste abspielen';
@override
String resourcesPlaylistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count Playlists',
one: '$count Playlist',
);
return '$_temp0';
}
@override
String resourcesPlaylistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Wiedergabelisten',
one: 'Wiedergabeliste',
);
return '$_temp0';
}
@override
String resourcesQueueName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Warteschlangen',
one: 'Warteschlange',
);
return '$_temp0';
}
@override
String resourcesSongCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count Songs',
one: '$count Song',
);
return '$_temp0';
}
@override
String get resourcesSongListDeleteAllContent =>
'Hierdurch werden alle heruntergeladenen Inhalte entfernt.';
@override
String get resourcesSongListDeleteAllTitle => 'Downloads löschen?';
@override
String get resourcesSongListsArtistTopSongs => 'Top Lieder';
@override
String resourcesSongName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Lieder',
one: 'Lied',
);
return '$_temp0';
}
@override
String get resourcesSortByAdded => 'Kürzlich hinzugefügt';
@override
String get resourcesSortByAlbum => 'Album';
@override
String get resourcesSortByAlbumCount => 'Albenanzahl';
@override
String get resourcesSortByArtist => 'Nach Interpreten';
@override
String get resourcesSortByFrequentlyPlayed => 'Häufig abgespielt';
@override
String get resourcesSortByName => 'Nach Name';
@override
String get resourcesSortByRandom => 'Zufällig';
@override
String get resourcesSortByRecentlyPlayed => 'Kürzlich abgespielt';
@override
String get resourcesSortByTitle => 'Titel';
@override
String get resourcesSortByUpdated => 'Kürzlich hinzugefügt';
@override
String get resourcesSortByYear => 'Nach Jahr';
@override
String searchHeaderTitle(String query) {
return 'Suche: $query';
}
@override
String get searchInputPlaceholder => 'Suche';
@override
String get searchMoreResults => 'Mehr…';
@override
String get searchNowPlayingContext => 'Suchergebnis';
@override
String get settingsAboutActionsLicenses => 'Lizenzen';
@override
String get settingsAboutActionsProjectHomepage => 'Projektseite';
@override
String get settingsAboutActionsSupport => 'Den Entwickler unterstützen';
@override
String get settingsAboutName => 'Über';
@override
String get settingsAboutShareLogs => 'Share logs';
@override
String get settingsAboutChooseLog => 'Choose a log file';
@override
String settingsAboutVersion(String version) {
return 'Version $version';
}
@override
String get settingsMusicName => 'Musik';
@override
String get settingsMusicOptionsScrobbleDescriptionOff =>
'Kein Scrobble für Wiedergabeverlauf';
@override
String get settingsMusicOptionsScrobbleDescriptionOn =>
'Scrobble Wiedergabeverlauf';
@override
String get settingsMusicOptionsScrobbleTitle => 'Scrobble Wiedergabe';
@override
String get settingsNetworkName => 'Netzwerk';
@override
String get settingsNetworkOptionsMaxBitrateMobileTitle =>
'Maximale Bitrate (Mobil)';
@override
String get settingsNetworkOptionsMaxBitrateWifiTitle =>
'Maximale Bitrate (WLAN)';
@override
String get settingsNetworkOptionsMaxBufferTitle => 'Maximale Pufferzeit';
@override
String get settingsNetworkOptionsMinBufferTitle => 'Minimale Pufferzeit';
@override
String get settingsNetworkOptionsOfflineMode => 'Offline Modus';
@override
String get settingsNetworkOptionsOfflineModeOff =>
'Nutze das Internet um Musik zu synchronisieren.';
@override
String get settingsNetworkOptionsOfflineModeOn =>
'Nutze nicht das Internet um Musik zu synchronisieren.';
@override
String get settingsNetworkOptionsStreamFormat =>
'Bevorzugtes Streaming-Format';
@override
String get settingsNetworkOptionsStreamFormatServerDefault =>
'Server-Standard verwenden';
@override
String settingsNetworkValuesKbps(String value) {
return '${value}kbps';
}
@override
String settingsNetworkValuesSeconds(String value) {
return '$value Sekunden';
}
@override
String get settingsNetworkValuesUnlimitedKbps => 'Unbegrenzt';
@override
String get settingsResetActionsClearImageCache =>
'Bildzwischenspeicher löschen';
@override
String get settingsResetName => 'Zurücksetzen';
@override
String get settingsServersActionsAdd => 'Server hinzufügen';
@override
String get settingsServersActionsDelete => 'Löschen';
@override
String get settingsServersActionsEdit => 'Server bearbeiten';
@override
String get settingsServersActionsSave => 'Speichern';
@override
String get settingsServersActionsTestConnection => 'Verbindung testen';
@override
String get settingsServersFieldsAddress => 'Adresse';
@override
String get settingsServersFieldsName => 'Name';
@override
String get settingsServersFieldsPassword => 'Passwort';
@override
String get settingsServersFieldsUsername => 'Nutzername';
@override
String settingsServersMessagesConnectionFailed(String address) {
return 'Verbindung zu $address fehlgeschlagen, überprüfe Einstellungen oder Server';
}
@override
String settingsServersMessagesConnectionOk(String address) {
return 'Verbindung zu $address ist OK!';
}
@override
String get settingsServersName => 'Server';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOff =>
'Sende Passwort als Token + Salt';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOn =>
'Passwort als Klartext senden (Veraltet, stellen Sie sicher, dass Ihre Verbindung sicher ist!)';
@override
String get settingsServersOptionsForcePlaintextPasswordTitle =>
'Erzwinge Klartextpasswort';
}

View File

@@ -0,0 +1,399 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for English (`en`).
class AppLocalizationsEn extends AppLocalizations {
AppLocalizationsEn([String locale = 'en']) : super(locale);
@override
String get actionsCancel => 'Cancel';
@override
String get actionsDelete => 'Delete';
@override
String get actionsDownload => 'Download';
@override
String get actionsDownloadCancel => 'Cancel download';
@override
String get actionsDownloadDelete => 'Delete downloaded';
@override
String get actionsOk => 'OK';
@override
String get actionsStar => 'Star';
@override
String get actionsUnstar => 'Unstar';
@override
String get controlsShuffle => 'Shuffle';
@override
String get messagesNothingHere => 'Nothing here…';
@override
String get navigationTabsHome => 'Home';
@override
String get navigationTabsAlbums => 'Albums';
@override
String get navigationTabsArtists => 'Artists';
@override
String get navigationTabsPlaylists => 'Playlists';
@override
String get navigationTabsSongs => 'Songs';
@override
String get navigationTabsLibrary => 'Library';
@override
String get navigationTabsSearch => 'Search';
@override
String get navigationTabsSettings => 'Settings';
@override
String get resourcesAlbumActionsPlay => 'Play album';
@override
String get resourcesAlbumActionsView => 'View album';
@override
String resourcesAlbumCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count albums',
one: '$count album',
);
return '$_temp0';
}
@override
String get resourcesAlbumListsSort => 'Sort albums';
@override
String resourcesAlbumName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Albums',
one: 'Album',
);
return '$_temp0';
}
@override
String get resourcesArtistActionsView => 'View artist';
@override
String resourcesArtistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count artists',
one: '$count artist',
);
return '$_temp0';
}
@override
String get resourcesArtistListsSort => 'Sort artists';
@override
String resourcesArtistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Artists',
one: 'Artist',
);
return '$_temp0';
}
@override
String get resourcesFilterAlbum => 'Album';
@override
String get resourcesFilterArtist => 'Artist';
@override
String get resourcesFilterGenre => 'Genre';
@override
String get resourcesFilterOwner => 'Owner';
@override
String get resourcesFilterStarred => 'Starred';
@override
String get resourcesFilterYear => 'Year';
@override
String get resourcesPlaylistActionsPlay => 'Play playlist';
@override
String resourcesPlaylistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count playlists',
one: '$count playlist',
);
return '$_temp0';
}
@override
String resourcesPlaylistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Playlists',
one: 'Playlist',
);
return '$_temp0';
}
@override
String resourcesQueueName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Queues',
one: 'Queue',
);
return '$_temp0';
}
@override
String resourcesSongCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count songs',
one: '$count song',
);
return '$_temp0';
}
@override
String get resourcesSongListDeleteAllContent =>
'This will remove all downloaded song files.';
@override
String get resourcesSongListDeleteAllTitle => 'Delete downloads?';
@override
String get resourcesSongListsArtistTopSongs => 'Top Songs';
@override
String resourcesSongName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Songs',
one: 'Song',
);
return '$_temp0';
}
@override
String get resourcesSortByAdded => 'Recently added';
@override
String get resourcesSortByAlbum => 'Album';
@override
String get resourcesSortByAlbumCount => 'Album count';
@override
String get resourcesSortByArtist => 'Artist';
@override
String get resourcesSortByFrequentlyPlayed => 'Frequently played';
@override
String get resourcesSortByName => 'Name';
@override
String get resourcesSortByRandom => 'Random';
@override
String get resourcesSortByRecentlyPlayed => 'Recently played';
@override
String get resourcesSortByTitle => 'Title';
@override
String get resourcesSortByUpdated => 'Recently updated';
@override
String get resourcesSortByYear => 'Year';
@override
String searchHeaderTitle(String query) {
return 'Search: $query';
}
@override
String get searchInputPlaceholder => 'Search';
@override
String get searchMoreResults => 'More…';
@override
String get searchNowPlayingContext => 'Search results';
@override
String get settingsAboutActionsLicenses => 'Licenses';
@override
String get settingsAboutActionsProjectHomepage => 'Project homepage';
@override
String get settingsAboutActionsSupport => 'Support the developer 💜';
@override
String get settingsAboutName => 'About';
@override
String get settingsAboutShareLogs => 'Share logs';
@override
String get settingsAboutChooseLog => 'Choose a log file';
@override
String settingsAboutVersion(String version) {
return 'version $version';
}
@override
String get settingsMusicName => 'Music';
@override
String get settingsMusicOptionsScrobbleDescriptionOff =>
'Don\'t scrobble play history';
@override
String get settingsMusicOptionsScrobbleDescriptionOn =>
'Scrobble play history';
@override
String get settingsMusicOptionsScrobbleTitle => 'Scrobble plays';
@override
String get settingsNetworkName => 'Network';
@override
String get settingsNetworkOptionsMaxBitrateMobileTitle =>
'Maximum bitrate (mobile data)';
@override
String get settingsNetworkOptionsMaxBitrateWifiTitle =>
'Maximum bitrate (Wi-Fi)';
@override
String get settingsNetworkOptionsMaxBufferTitle => 'Maximum buffer time';
@override
String get settingsNetworkOptionsMinBufferTitle => 'Minimum buffer time';
@override
String get settingsNetworkOptionsOfflineMode => 'Offline mode';
@override
String get settingsNetworkOptionsOfflineModeOff =>
'Use the internet to sync music.';
@override
String get settingsNetworkOptionsOfflineModeOn =>
'Don\'t use the internet to sync or play music.';
@override
String get settingsNetworkOptionsStreamFormat => 'Preferred stream format';
@override
String get settingsNetworkOptionsStreamFormatServerDefault =>
'Use server default';
@override
String settingsNetworkValuesKbps(String value) {
return '${value}kbps';
}
@override
String settingsNetworkValuesSeconds(String value) {
return '$value seconds';
}
@override
String get settingsNetworkValuesUnlimitedKbps => 'Unlimited';
@override
String get settingsResetActionsClearImageCache => 'Clear Image Cache';
@override
String get settingsResetName => 'Reset';
@override
String get settingsServersActionsAdd => 'Add source';
@override
String get settingsServersActionsDelete => 'Delete';
@override
String get settingsServersActionsEdit => 'Edit source';
@override
String get settingsServersActionsSave => 'Save';
@override
String get settingsServersActionsTestConnection => 'Test connection';
@override
String get settingsServersFieldsAddress => 'Address';
@override
String get settingsServersFieldsName => 'Name';
@override
String get settingsServersFieldsPassword => 'Password';
@override
String get settingsServersFieldsUsername => 'Username';
@override
String settingsServersMessagesConnectionFailed(String address) {
return 'Connection to $address failed, check settings or server';
}
@override
String settingsServersMessagesConnectionOk(String address) {
return 'Connection to $address OK!';
}
@override
String get settingsServersName => 'Sources';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOff =>
'Send password as token + salt';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOn =>
'Send password in plaintext (legacy, make sure your connection is secure!)';
@override
String get settingsServersOptionsForcePlaintextPasswordTitle =>
'Force plaintext password';
}

View File

@@ -0,0 +1,400 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for Spanish Castilian (`es`).
class AppLocalizationsEs extends AppLocalizations {
AppLocalizationsEs([String locale = 'es']) : super(locale);
@override
String get actionsCancel => 'Cancelar';
@override
String get actionsDelete => 'Borrar';
@override
String get actionsDownload => 'Descargar';
@override
String get actionsDownloadCancel => 'Anular descargar';
@override
String get actionsDownloadDelete => 'Eliminar descargado';
@override
String get actionsOk => 'Ok';
@override
String get actionsStar => 'Favorito';
@override
String get actionsUnstar => 'Retirar favorito';
@override
String get controlsShuffle => 'Reproducir aleatoriamente';
@override
String get messagesNothingHere => 'Nada aquí…';
@override
String get navigationTabsHome => 'Casa';
@override
String get navigationTabsAlbums => 'Albums';
@override
String get navigationTabsArtists => 'Artists';
@override
String get navigationTabsPlaylists => 'Playlists';
@override
String get navigationTabsSongs => 'Songs';
@override
String get navigationTabsLibrary => 'Biblioteca';
@override
String get navigationTabsSearch => 'Buscar';
@override
String get navigationTabsSettings => 'Entorno';
@override
String get resourcesAlbumActionsPlay => 'Reproducir Álbum';
@override
String get resourcesAlbumActionsView => 'Ver Álbum';
@override
String resourcesAlbumCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count albums',
one: '$count album',
);
return '$_temp0';
}
@override
String get resourcesAlbumListsSort => 'Ordenar Álbumes';
@override
String resourcesAlbumName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Álbumes',
one: 'Álbum',
);
return '$_temp0';
}
@override
String get resourcesArtistActionsView => 'Ver Artista';
@override
String resourcesArtistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count artists',
one: '$count artist',
);
return '$_temp0';
}
@override
String get resourcesArtistListsSort => 'Oredenar Artistas';
@override
String resourcesArtistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Artistas',
one: 'Artista',
);
return '$_temp0';
}
@override
String get resourcesFilterAlbum => 'Album';
@override
String get resourcesFilterArtist => 'Artist';
@override
String get resourcesFilterGenre => 'Por Género';
@override
String get resourcesFilterOwner => 'Owner';
@override
String get resourcesFilterStarred => 'Estrellas';
@override
String get resourcesFilterYear => 'Year';
@override
String get resourcesPlaylistActionsPlay => 'Reproducir Lista de reproducción';
@override
String resourcesPlaylistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count playlists',
one: '$count playlist',
);
return '$_temp0';
}
@override
String resourcesPlaylistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Listas de reproducción',
one: 'Lista de reproducción',
);
return '$_temp0';
}
@override
String resourcesQueueName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Colas',
one: 'Cola',
);
return '$_temp0';
}
@override
String resourcesSongCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count songs',
one: '$count song',
);
return '$_temp0';
}
@override
String get resourcesSongListDeleteAllContent =>
'This will remove all downloaded song files.';
@override
String get resourcesSongListDeleteAllTitle => 'Delete downloads?';
@override
String get resourcesSongListsArtistTopSongs => 'Mejores Canciones';
@override
String resourcesSongName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Canciones',
one: 'Cancion',
);
return '$_temp0';
}
@override
String get resourcesSortByAdded => 'Recientemente Añadido';
@override
String get resourcesSortByAlbum => 'Album';
@override
String get resourcesSortByAlbumCount => 'Album count';
@override
String get resourcesSortByArtist => 'Por Artista';
@override
String get resourcesSortByFrequentlyPlayed => 'Jugado Frecuentemente';
@override
String get resourcesSortByName => 'Por Nombre';
@override
String get resourcesSortByRandom => 'Aleatorio';
@override
String get resourcesSortByRecentlyPlayed => 'Recientemente Jugado';
@override
String get resourcesSortByTitle => 'Title';
@override
String get resourcesSortByUpdated => 'Recently updated';
@override
String get resourcesSortByYear => 'Por Año';
@override
String searchHeaderTitle(String query) {
return 'Buscar: $query';
}
@override
String get searchInputPlaceholder => 'Buscar';
@override
String get searchMoreResults => 'Más…';
@override
String get searchNowPlayingContext => 'Resultados de la búsqueda';
@override
String get settingsAboutActionsLicenses => 'Licencias';
@override
String get settingsAboutActionsProjectHomepage =>
'Página de inicio del proyecto';
@override
String get settingsAboutActionsSupport => 'Support the developer 💜';
@override
String get settingsAboutName => 'Información';
@override
String get settingsAboutShareLogs => 'Share logs';
@override
String get settingsAboutChooseLog => 'Choose a log file';
@override
String settingsAboutVersion(String version) {
return 'versión $version';
}
@override
String get settingsMusicName => 'Música';
@override
String get settingsMusicOptionsScrobbleDescriptionOff =>
'No hagas historial de reproducción de scrobble';
@override
String get settingsMusicOptionsScrobbleDescriptionOn =>
'Historial de reproducción de scrobble';
@override
String get settingsMusicOptionsScrobbleTitle => 'Obras de teatro de Scrobble';
@override
String get settingsNetworkName => 'Sitio';
@override
String get settingsNetworkOptionsMaxBitrateMobileTitle =>
'Tasa de bits máxima (mobile)';
@override
String get settingsNetworkOptionsMaxBitrateWifiTitle =>
'Tasa de bits máxima (Wi-Fi)';
@override
String get settingsNetworkOptionsMaxBufferTitle => 'Máxima de buffer tiempo';
@override
String get settingsNetworkOptionsMinBufferTitle => 'Mínimo de buffer tiempo';
@override
String get settingsNetworkOptionsOfflineMode => 'Offline mode';
@override
String get settingsNetworkOptionsOfflineModeOff =>
'Use the internet to sync music.';
@override
String get settingsNetworkOptionsOfflineModeOn =>
'Don\'t use the internet to sync or play music.';
@override
String get settingsNetworkOptionsStreamFormat => 'Preferred stream format';
@override
String get settingsNetworkOptionsStreamFormatServerDefault =>
'Use server default';
@override
String settingsNetworkValuesKbps(String value) {
return '$value kilobytes por segundo';
}
@override
String settingsNetworkValuesSeconds(String value) {
return '$value segundos';
}
@override
String get settingsNetworkValuesUnlimitedKbps => 'Ilimitados';
@override
String get settingsResetActionsClearImageCache => 'Caché de imágenes claras';
@override
String get settingsResetName => 'Reinicializar';
@override
String get settingsServersActionsAdd => 'Agregar Servidor';
@override
String get settingsServersActionsDelete => 'Supr';
@override
String get settingsServersActionsEdit => 'Editar Servidor';
@override
String get settingsServersActionsSave => 'Enviar';
@override
String get settingsServersActionsTestConnection => 'Conexión de prueba';
@override
String get settingsServersFieldsAddress => 'Alocución';
@override
String get settingsServersFieldsName => 'Name';
@override
String get settingsServersFieldsPassword => 'La contraseña';
@override
String get settingsServersFieldsUsername => 'Nombre de usuario';
@override
String settingsServersMessagesConnectionFailed(String address) {
return 'La conexión a $address falló, verifique la configuracón o el servidor';
}
@override
String settingsServersMessagesConnectionOk(String address) {
return '¡Conexión con $address Ok!';
}
@override
String get settingsServersName => 'Servidores';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOff =>
'Enviar contraseña como token + sal';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOn =>
'Enviar contraseña en texto plano (¡legado, asegúrese de que su conexión sea segura!)';
@override
String get settingsServersOptionsForcePlaintextPasswordTitle =>
'Forzar contraseña de texto sin formato';
}

View File

@@ -0,0 +1,401 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for French (`fr`).
class AppLocalizationsFr extends AppLocalizations {
AppLocalizationsFr([String locale = 'fr']) : super(locale);
@override
String get actionsCancel => 'Cancel';
@override
String get actionsDelete => 'Delete';
@override
String get actionsDownload => 'Download';
@override
String get actionsDownloadCancel => 'Cancel download';
@override
String get actionsDownloadDelete => 'Delete downloaded';
@override
String get actionsOk => 'OK';
@override
String get actionsStar => 'Mettre en favoris';
@override
String get actionsUnstar => 'Enlever des favoris';
@override
String get controlsShuffle => 'Shuffle';
@override
String get messagesNothingHere => 'Rien ici…';
@override
String get navigationTabsHome => 'Accueil';
@override
String get navigationTabsAlbums => 'Albums';
@override
String get navigationTabsArtists => 'Artists';
@override
String get navigationTabsPlaylists => 'Playlists';
@override
String get navigationTabsSongs => 'Songs';
@override
String get navigationTabsLibrary => 'Bibliothèque';
@override
String get navigationTabsSearch => 'Recherche';
@override
String get navigationTabsSettings => 'Paramètres';
@override
String get resourcesAlbumActionsPlay => 'Jouer l\'album';
@override
String get resourcesAlbumActionsView => 'Voir l\'album';
@override
String resourcesAlbumCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count albums',
one: '$count album',
);
return '$_temp0';
}
@override
String get resourcesAlbumListsSort => 'Trier les albums';
@override
String resourcesAlbumName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Albums',
one: 'Album',
);
return '$_temp0';
}
@override
String get resourcesArtistActionsView => 'Voir l\'artiste';
@override
String resourcesArtistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count artists',
one: '$count artist',
);
return '$_temp0';
}
@override
String get resourcesArtistListsSort => 'Trier les artistes';
@override
String resourcesArtistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Artistes',
one: 'Artiste',
);
return '$_temp0';
}
@override
String get resourcesFilterAlbum => 'Album';
@override
String get resourcesFilterArtist => 'Artist';
@override
String get resourcesFilterGenre => 'Par Genre';
@override
String get resourcesFilterOwner => 'Owner';
@override
String get resourcesFilterStarred => 'Favoris';
@override
String get resourcesFilterYear => 'Year';
@override
String get resourcesPlaylistActionsPlay => 'Lire la playlist';
@override
String resourcesPlaylistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count playlists',
one: '$count playlist',
);
return '$_temp0';
}
@override
String resourcesPlaylistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Playlists',
one: 'Playlist',
);
return '$_temp0';
}
@override
String resourcesQueueName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Files d\'attente',
one: 'File d\'attente',
);
return '$_temp0';
}
@override
String resourcesSongCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count songs',
one: '$count song',
);
return '$_temp0';
}
@override
String get resourcesSongListDeleteAllContent =>
'This will remove all downloaded song files.';
@override
String get resourcesSongListDeleteAllTitle => 'Delete downloads?';
@override
String get resourcesSongListsArtistTopSongs => 'Meilleures Chansons';
@override
String resourcesSongName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Chansons',
one: 'Chanson',
);
return '$_temp0';
}
@override
String get resourcesSortByAdded => 'Récemment Ajouté';
@override
String get resourcesSortByAlbum => 'Album';
@override
String get resourcesSortByAlbumCount => 'Album count';
@override
String get resourcesSortByArtist => 'Par Artiste';
@override
String get resourcesSortByFrequentlyPlayed => 'Fréquemment Joué';
@override
String get resourcesSortByName => 'Par Nom';
@override
String get resourcesSortByRandom => 'Aléatoire';
@override
String get resourcesSortByRecentlyPlayed => 'Récemment Joué';
@override
String get resourcesSortByTitle => 'Title';
@override
String get resourcesSortByUpdated => 'Recently updated';
@override
String get resourcesSortByYear => 'Par Année';
@override
String searchHeaderTitle(String query) {
return 'Recherche : $query';
}
@override
String get searchInputPlaceholder => 'Recherche';
@override
String get searchMoreResults => 'Plus…';
@override
String get searchNowPlayingContext => 'Résultats de recherche';
@override
String get settingsAboutActionsLicenses => 'Licences';
@override
String get settingsAboutActionsProjectHomepage => 'Page d\'accueil du projet';
@override
String get settingsAboutActionsSupport => 'Support the developer 💜';
@override
String get settingsAboutName => 'À propos';
@override
String get settingsAboutShareLogs => 'Share logs';
@override
String get settingsAboutChooseLog => 'Choose a log file';
@override
String settingsAboutVersion(String version) {
return 'version $version';
}
@override
String get settingsMusicName => 'Musique';
@override
String get settingsMusicOptionsScrobbleDescriptionOff =>
'Ne pas scrobbler l\'historique de lecture';
@override
String get settingsMusicOptionsScrobbleDescriptionOn =>
'Scrobbler l\'historique de lecture';
@override
String get settingsMusicOptionsScrobbleTitle => 'Scrobbler la lecture';
@override
String get settingsNetworkName => 'Réseau';
@override
String get settingsNetworkOptionsMaxBitrateMobileTitle =>
'Débit binaire maximum (mobile)';
@override
String get settingsNetworkOptionsMaxBitrateWifiTitle =>
'Débit binaire maximum (Wi-Fi)';
@override
String get settingsNetworkOptionsMaxBufferTitle =>
'Temps maximum en mémoire tampon';
@override
String get settingsNetworkOptionsMinBufferTitle =>
'Temps minimum en mémoire tampon';
@override
String get settingsNetworkOptionsOfflineMode => 'Offline mode';
@override
String get settingsNetworkOptionsOfflineModeOff =>
'Use the internet to sync music.';
@override
String get settingsNetworkOptionsOfflineModeOn =>
'Don\'t use the internet to sync or play music.';
@override
String get settingsNetworkOptionsStreamFormat => 'Preferred stream format';
@override
String get settingsNetworkOptionsStreamFormatServerDefault =>
'Use server default';
@override
String settingsNetworkValuesKbps(String value) {
return '${value}kbit/s';
}
@override
String settingsNetworkValuesSeconds(String value) {
return '$value secondes';
}
@override
String get settingsNetworkValuesUnlimitedKbps => 'Illimité';
@override
String get settingsResetActionsClearImageCache => 'Vider le cache d\'images';
@override
String get settingsResetName => 'Réinitialiser';
@override
String get settingsServersActionsAdd => 'Ajouter un serveur';
@override
String get settingsServersActionsDelete => 'Supprimer';
@override
String get settingsServersActionsEdit => 'Modifier le serveur';
@override
String get settingsServersActionsSave => 'Sauvegarder';
@override
String get settingsServersActionsTestConnection => 'Tester la connexion';
@override
String get settingsServersFieldsAddress => 'Adresse';
@override
String get settingsServersFieldsName => 'Name';
@override
String get settingsServersFieldsPassword => 'Mot de passe';
@override
String get settingsServersFieldsUsername => 'Nom d\'utilisateur';
@override
String settingsServersMessagesConnectionFailed(String address) {
return 'Échec de la connexion à $address, vérifiez les paramètres ou le serveur';
}
@override
String settingsServersMessagesConnectionOk(String address) {
return 'Connexion à $address OK !';
}
@override
String get settingsServersName => 'Serveurs';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOff =>
'Envoyer le mot de passe sous forme de jeton + salage';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOn =>
'Envoyer le mot de passe en test clair (héritage, assurez-vous que la connexion est sécurisée !)';
@override
String get settingsServersOptionsForcePlaintextPasswordTitle =>
'Forcer le mot de passe en texte clair';
}

View File

@@ -0,0 +1,400 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for Galician (`gl`).
class AppLocalizationsGl extends AppLocalizations {
AppLocalizationsGl([String locale = 'gl']) : super(locale);
@override
String get actionsCancel => 'Cancelar';
@override
String get actionsDelete => 'Eliminar';
@override
String get actionsDownload => 'Descargar';
@override
String get actionsDownloadCancel => 'Cancelar a descarga';
@override
String get actionsDownloadDelete => 'Eliminar o descargado';
@override
String get actionsOk => 'OK';
@override
String get actionsStar => 'Estrela';
@override
String get actionsUnstar => 'Retirar';
@override
String get controlsShuffle => 'Barallar';
@override
String get messagesNothingHere => 'Nada por aquí…';
@override
String get navigationTabsHome => 'Inicio';
@override
String get navigationTabsAlbums => 'Albums';
@override
String get navigationTabsArtists => 'Artists';
@override
String get navigationTabsPlaylists => 'Playlists';
@override
String get navigationTabsSongs => 'Songs';
@override
String get navigationTabsLibrary => 'Biblioteca';
@override
String get navigationTabsSearch => 'Buscar';
@override
String get navigationTabsSettings => 'Axustes';
@override
String get resourcesAlbumActionsPlay => 'Reproducir';
@override
String get resourcesAlbumActionsView => 'Ver Álbum';
@override
String resourcesAlbumCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count álbums',
one: '$count álbum',
);
return '$_temp0';
}
@override
String get resourcesAlbumListsSort => 'Ordenar Álbums';
@override
String resourcesAlbumName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Álbums',
one: 'Álbum',
);
return '$_temp0';
}
@override
String get resourcesArtistActionsView => 'Ver Artista';
@override
String resourcesArtistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count artistas',
one: '$count artista',
);
return '$_temp0';
}
@override
String get resourcesArtistListsSort => 'Ordenar Artistas';
@override
String resourcesArtistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Artistas',
one: 'Artista',
);
return '$_temp0';
}
@override
String get resourcesFilterAlbum => 'Álbum';
@override
String get resourcesFilterArtist => 'Artista';
@override
String get resourcesFilterGenre => 'Por xénero';
@override
String get resourcesFilterOwner => 'Dono';
@override
String get resourcesFilterStarred => 'Favoritas';
@override
String get resourcesFilterYear => 'Ano';
@override
String get resourcesPlaylistActionsPlay => 'Reproducir lista';
@override
String resourcesPlaylistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count listas',
one: '$count lista',
);
return '$_temp0';
}
@override
String resourcesPlaylistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Listaxes',
one: 'Listaxe',
);
return '$_temp0';
}
@override
String resourcesQueueName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Filas',
one: 'Fila',
);
return '$_temp0';
}
@override
String resourcesSongCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count cancións',
one: '$count canción',
);
return '$_temp0';
}
@override
String get resourcesSongListDeleteAllContent =>
'Vas eliminar todas as cancións descargadas.';
@override
String get resourcesSongListDeleteAllTitle => 'Eliminar descargas?';
@override
String get resourcesSongListsArtistTopSongs => 'Máis reproducidas';
@override
String resourcesSongName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Cancións',
one: 'Canción',
);
return '$_temp0';
}
@override
String get resourcesSortByAdded => 'Últimas engadidas';
@override
String get resourcesSortByAlbum => 'Álbum';
@override
String get resourcesSortByAlbumCount => 'Número de álbums';
@override
String get resourcesSortByArtist => 'Por artista';
@override
String get resourcesSortByFrequentlyPlayed => 'Reproducidas a miúdo';
@override
String get resourcesSortByName => 'Por nome';
@override
String get resourcesSortByRandom => 'Ao chou';
@override
String get resourcesSortByRecentlyPlayed => 'Reproducidas a miúdo';
@override
String get resourcesSortByTitle => 'Título';
@override
String get resourcesSortByUpdated => 'Actualizado recentemente';
@override
String get resourcesSortByYear => 'Por ano';
@override
String searchHeaderTitle(String query) {
return 'Buscar: $query';
}
@override
String get searchInputPlaceholder => 'Buscar';
@override
String get searchMoreResults => 'Máis…';
@override
String get searchNowPlayingContext => 'Resultados';
@override
String get settingsAboutActionsLicenses => 'Licenzas';
@override
String get settingsAboutActionsProjectHomepage => 'Web do Proxecto';
@override
String get settingsAboutActionsSupport => 'Axuda ao desenvolvemento 💜';
@override
String get settingsAboutName => 'Acerca de';
@override
String get settingsAboutShareLogs => 'Compartir rexistros';
@override
String get settingsAboutChooseLog => 'Escolle un ficheiro de rexistro';
@override
String settingsAboutVersion(String version) {
return 'versión $version';
}
@override
String get settingsMusicName => 'Música';
@override
String get settingsMusicOptionsScrobbleDescriptionOff =>
'Non rexistrar o historial de reprodución';
@override
String get settingsMusicOptionsScrobbleDescriptionOn =>
'Rexistrar o historial de reprodución';
@override
String get settingsMusicOptionsScrobbleTitle => 'Rexistrar reprodución';
@override
String get settingsNetworkName => 'Rede';
@override
String get settingsNetworkOptionsMaxBitrateMobileTitle =>
'Bitrate máx. (móbil)';
@override
String get settingsNetworkOptionsMaxBitrateWifiTitle =>
'Bitrate máx. (Wi-Fi)';
@override
String get settingsNetworkOptionsMaxBufferTitle => 'Tempo máximo na memoria';
@override
String get settingsNetworkOptionsMinBufferTitle => 'Tempo mínimo na memoria';
@override
String get settingsNetworkOptionsOfflineMode => 'Modo sen conexión';
@override
String get settingsNetworkOptionsOfflineModeOff =>
'Usa internet para sincr. música.';
@override
String get settingsNetworkOptionsOfflineModeOn =>
'Non usar internet para sincr. ou reproducir música.';
@override
String get settingsNetworkOptionsStreamFormat =>
'Modo de reprodución preferido';
@override
String get settingsNetworkOptionsStreamFormatServerDefault =>
'Usar por defecto do servidor';
@override
String settingsNetworkValuesKbps(String value) {
return '${value}kbps';
}
@override
String settingsNetworkValuesSeconds(String value) {
return '$value segundos';
}
@override
String get settingsNetworkValuesUnlimitedKbps => 'Sen límite';
@override
String get settingsResetActionsClearImageCache => 'Limpar a caché de imaxes';
@override
String get settingsResetName => 'Restablecer';
@override
String get settingsServersActionsAdd => 'Engadir Servidor';
@override
String get settingsServersActionsDelete => 'Eliminar';
@override
String get settingsServersActionsEdit => 'Editar Servidor';
@override
String get settingsServersActionsSave => 'Gardar';
@override
String get settingsServersActionsTestConnection => 'Comprobar Conexión';
@override
String get settingsServersFieldsAddress => 'Enderezo';
@override
String get settingsServersFieldsName => 'Nome';
@override
String get settingsServersFieldsPassword => 'Contrasinal';
@override
String get settingsServersFieldsUsername => 'Identificador';
@override
String settingsServersMessagesConnectionFailed(String address) {
return 'Fallou a conexión a $address, comproba os axustes';
}
@override
String settingsServersMessagesConnectionOk(String address) {
return 'Conexión con $address OK!';
}
@override
String get settingsServersName => 'Servidores';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOff =>
'Enviar contrasinal como token + salt';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOn =>
'Enviar contrasinal en texto plano (herdado, pon coidado en que a conexión sexa segura!)';
@override
String get settingsServersOptionsForcePlaintextPasswordTitle =>
'Forzar contrasinal en texto plano';
}

View File

@@ -0,0 +1,402 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for Italian (`it`).
class AppLocalizationsIt extends AppLocalizations {
AppLocalizationsIt([String locale = 'it']) : super(locale);
@override
String get actionsCancel => 'Cancel';
@override
String get actionsDelete => 'Delete';
@override
String get actionsDownload => 'Download';
@override
String get actionsDownloadCancel => 'Cancel download';
@override
String get actionsDownloadDelete => 'Delete downloaded';
@override
String get actionsOk => 'OK';
@override
String get actionsStar => 'Aggiungi ai preferiti';
@override
String get actionsUnstar => 'Rimuovi dai preferiti';
@override
String get controlsShuffle => 'Shuffle';
@override
String get messagesNothingHere => 'Non c\'è niente qui…';
@override
String get navigationTabsHome => 'Home';
@override
String get navigationTabsAlbums => 'Albums';
@override
String get navigationTabsArtists => 'Artists';
@override
String get navigationTabsPlaylists => 'Playlists';
@override
String get navigationTabsSongs => 'Songs';
@override
String get navigationTabsLibrary => 'Libreria';
@override
String get navigationTabsSearch => 'Cerca';
@override
String get navigationTabsSettings => 'Impostazioni';
@override
String get resourcesAlbumActionsPlay => 'Riproduci album';
@override
String get resourcesAlbumActionsView => 'Vedi album';
@override
String resourcesAlbumCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count albums',
one: '$count album',
);
return '$_temp0';
}
@override
String get resourcesAlbumListsSort => 'Ordina album';
@override
String resourcesAlbumName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Album',
one: 'Album',
);
return '$_temp0';
}
@override
String get resourcesArtistActionsView => 'Vedi artista';
@override
String resourcesArtistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count artists',
one: '$count artist',
);
return '$_temp0';
}
@override
String get resourcesArtistListsSort => 'Ordina artisti';
@override
String resourcesArtistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Artisti',
one: 'Artista',
);
return '$_temp0';
}
@override
String get resourcesFilterAlbum => 'Album';
@override
String get resourcesFilterArtist => 'Artist';
@override
String get resourcesFilterGenre => 'Per genere';
@override
String get resourcesFilterOwner => 'Owner';
@override
String get resourcesFilterStarred => 'Preferiti';
@override
String get resourcesFilterYear => 'Year';
@override
String get resourcesPlaylistActionsPlay => 'Riproduci playlist';
@override
String resourcesPlaylistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count playlists',
one: '$count playlist',
);
return '$_temp0';
}
@override
String resourcesPlaylistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Playlist',
one: 'Playlist',
);
return '$_temp0';
}
@override
String resourcesQueueName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Code',
one: 'Coda',
);
return '$_temp0';
}
@override
String resourcesSongCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count songs',
one: '$count song',
);
return '$_temp0';
}
@override
String get resourcesSongListDeleteAllContent =>
'This will remove all downloaded song files.';
@override
String get resourcesSongListDeleteAllTitle => 'Delete downloads?';
@override
String get resourcesSongListsArtistTopSongs => 'Brani più popolari';
@override
String resourcesSongName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Brani',
one: 'Brano',
);
return '$_temp0';
}
@override
String get resourcesSortByAdded => 'Aggiunti di recente';
@override
String get resourcesSortByAlbum => 'Album';
@override
String get resourcesSortByAlbumCount => 'Album count';
@override
String get resourcesSortByArtist => 'Per artista';
@override
String get resourcesSortByFrequentlyPlayed => 'Ascoltati frequentemente';
@override
String get resourcesSortByName => 'Per nome';
@override
String get resourcesSortByRandom => 'Casuale';
@override
String get resourcesSortByRecentlyPlayed => 'Ascoltati di recente';
@override
String get resourcesSortByTitle => 'Title';
@override
String get resourcesSortByUpdated => 'Recently updated';
@override
String get resourcesSortByYear => 'Per anno';
@override
String searchHeaderTitle(String query) {
return 'Ricerca: $query';
}
@override
String get searchInputPlaceholder => 'Ricerca';
@override
String get searchMoreResults => 'Mostra di più…';
@override
String get searchNowPlayingContext => 'Risultati della ricerca';
@override
String get settingsAboutActionsLicenses => 'Licenze';
@override
String get settingsAboutActionsProjectHomepage =>
'Pagina principale del progetto';
@override
String get settingsAboutActionsSupport => 'Support the developer 💜';
@override
String get settingsAboutName => 'Informazioni';
@override
String get settingsAboutShareLogs => 'Share logs';
@override
String get settingsAboutChooseLog => 'Choose a log file';
@override
String settingsAboutVersion(String version) {
return 'versione $version';
}
@override
String get settingsMusicName => 'Musica';
@override
String get settingsMusicOptionsScrobbleDescriptionOff =>
'Non eseguire lo scrobbling della cronologia d\'ascolto';
@override
String get settingsMusicOptionsScrobbleDescriptionOn =>
'Scrobbling della cronologia di ascolto';
@override
String get settingsMusicOptionsScrobbleTitle =>
'Scrobbling delle riproduzioni';
@override
String get settingsNetworkName => 'Rete';
@override
String get settingsNetworkOptionsMaxBitrateMobileTitle =>
'Bitrate massimo (rete dati)';
@override
String get settingsNetworkOptionsMaxBitrateWifiTitle =>
'Bitrate massimo (Wi-Fi)';
@override
String get settingsNetworkOptionsMaxBufferTitle => 'Tempo di buffer massimo';
@override
String get settingsNetworkOptionsMinBufferTitle => 'Tempo di buffer minimo';
@override
String get settingsNetworkOptionsOfflineMode => 'Offline mode';
@override
String get settingsNetworkOptionsOfflineModeOff =>
'Use the internet to sync music.';
@override
String get settingsNetworkOptionsOfflineModeOn =>
'Don\'t use the internet to sync or play music.';
@override
String get settingsNetworkOptionsStreamFormat => 'Preferred stream format';
@override
String get settingsNetworkOptionsStreamFormatServerDefault =>
'Use server default';
@override
String settingsNetworkValuesKbps(String value) {
return '${value}kbps';
}
@override
String settingsNetworkValuesSeconds(String value) {
return '$value secondi';
}
@override
String get settingsNetworkValuesUnlimitedKbps => 'Illimitato';
@override
String get settingsResetActionsClearImageCache =>
'Pulisci la cache delle immagini';
@override
String get settingsResetName => 'Reimposta';
@override
String get settingsServersActionsAdd => 'Aggiungi server';
@override
String get settingsServersActionsDelete => 'Rimuovi';
@override
String get settingsServersActionsEdit => 'Modifica server';
@override
String get settingsServersActionsSave => 'Salva';
@override
String get settingsServersActionsTestConnection => 'Prova connessione';
@override
String get settingsServersFieldsAddress => 'Indirizzo';
@override
String get settingsServersFieldsName => 'Name';
@override
String get settingsServersFieldsPassword => 'Password';
@override
String get settingsServersFieldsUsername => 'Nome utente';
@override
String settingsServersMessagesConnectionFailed(String address) {
return 'Connessione a $address fallita, controlla le impostazioni o il server';
}
@override
String settingsServersMessagesConnectionOk(String address) {
return 'Connesso a $address con successo!';
}
@override
String get settingsServersName => 'Server';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOff =>
'Invia la password come token + salt';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOn =>
'Invia password in chiaro (deprecato, assicurati che la tua connessione sia sicura!)';
@override
String get settingsServersOptionsForcePlaintextPasswordTitle =>
'Forza password in chiaro';
}

View File

@@ -0,0 +1,395 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for Japanese (`ja`).
class AppLocalizationsJa extends AppLocalizations {
AppLocalizationsJa([String locale = 'ja']) : super(locale);
@override
String get actionsCancel => 'Cancel';
@override
String get actionsDelete => 'Delete';
@override
String get actionsDownload => 'Download';
@override
String get actionsDownloadCancel => 'Cancel download';
@override
String get actionsDownloadDelete => 'Delete downloaded';
@override
String get actionsOk => 'OK';
@override
String get actionsStar => 'Star';
@override
String get actionsUnstar => 'Unstar';
@override
String get controlsShuffle => 'Shuffle';
@override
String get messagesNothingHere => 'Nothing here…';
@override
String get navigationTabsHome => 'ホーム';
@override
String get navigationTabsAlbums => 'Albums';
@override
String get navigationTabsArtists => 'Artists';
@override
String get navigationTabsPlaylists => 'Playlists';
@override
String get navigationTabsSongs => 'Songs';
@override
String get navigationTabsLibrary => 'ライブラリ';
@override
String get navigationTabsSearch => '検索';
@override
String get navigationTabsSettings => '設定';
@override
String get resourcesAlbumActionsPlay => 'Play album';
@override
String get resourcesAlbumActionsView => 'View album';
@override
String resourcesAlbumCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count albums',
one: '$count album',
);
return '$_temp0';
}
@override
String get resourcesAlbumListsSort => 'Sort albums';
@override
String resourcesAlbumName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'アルバム',
);
return '$_temp0';
}
@override
String get resourcesArtistActionsView => 'View artist';
@override
String resourcesArtistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count artists',
one: '$count artist',
);
return '$_temp0';
}
@override
String get resourcesArtistListsSort => 'Sort artists';
@override
String resourcesArtistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'アーティスト',
);
return '$_temp0';
}
@override
String get resourcesFilterAlbum => 'Album';
@override
String get resourcesFilterArtist => 'Artist';
@override
String get resourcesFilterGenre => 'Genre';
@override
String get resourcesFilterOwner => 'Owner';
@override
String get resourcesFilterStarred => '星付きアルバム';
@override
String get resourcesFilterYear => 'Year';
@override
String get resourcesPlaylistActionsPlay => 'Play playlist';
@override
String resourcesPlaylistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count playlists',
one: '$count playlist',
);
return '$_temp0';
}
@override
String resourcesPlaylistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'プレイリスト',
);
return '$_temp0';
}
@override
String resourcesQueueName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Queues',
one: 'Queue',
);
return '$_temp0';
}
@override
String resourcesSongCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count songs',
one: '$count song',
);
return '$_temp0';
}
@override
String get resourcesSongListDeleteAllContent =>
'This will remove all downloaded song files.';
@override
String get resourcesSongListDeleteAllTitle => 'Delete downloads?';
@override
String get resourcesSongListsArtistTopSongs => '人気曲';
@override
String resourcesSongName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '',
);
return '$_temp0';
}
@override
String get resourcesSortByAdded => 'Recently added';
@override
String get resourcesSortByAlbum => 'Album';
@override
String get resourcesSortByAlbumCount => 'Album count';
@override
String get resourcesSortByArtist => 'Artist';
@override
String get resourcesSortByFrequentlyPlayed => 'よく聴くアルバム';
@override
String get resourcesSortByName => 'Name';
@override
String get resourcesSortByRandom => 'ランダムアルバム';
@override
String get resourcesSortByRecentlyPlayed => '最近再生した';
@override
String get resourcesSortByTitle => 'Title';
@override
String get resourcesSortByUpdated => 'Recently updated';
@override
String get resourcesSortByYear => 'Year';
@override
String searchHeaderTitle(String query) {
return 'Search: $query';
}
@override
String get searchInputPlaceholder => '検索';
@override
String get searchMoreResults => 'More…';
@override
String get searchNowPlayingContext => 'Search results';
@override
String get settingsAboutActionsLicenses => 'Licenses';
@override
String get settingsAboutActionsProjectHomepage => 'ホームページ';
@override
String get settingsAboutActionsSupport => 'Support the developer 💜';
@override
String get settingsAboutName => 'About';
@override
String get settingsAboutShareLogs => 'Share logs';
@override
String get settingsAboutChooseLog => 'Choose a log file';
@override
String settingsAboutVersion(String version) {
return 'version $version';
}
@override
String get settingsMusicName => '音楽';
@override
String get settingsMusicOptionsScrobbleDescriptionOff =>
'Don\'t scrobble play history';
@override
String get settingsMusicOptionsScrobbleDescriptionOn =>
'Scrobble play history';
@override
String get settingsMusicOptionsScrobbleTitle => 'Scrobble plays';
@override
String get settingsNetworkName => 'ネット';
@override
String get settingsNetworkOptionsMaxBitrateMobileTitle =>
'Maximum bitrate (mobile data)';
@override
String get settingsNetworkOptionsMaxBitrateWifiTitle =>
'Maximum bitrate (Wi-Fi)';
@override
String get settingsNetworkOptionsMaxBufferTitle => 'Maximum buffer time';
@override
String get settingsNetworkOptionsMinBufferTitle => 'Minimum buffer time';
@override
String get settingsNetworkOptionsOfflineMode => 'Offline mode';
@override
String get settingsNetworkOptionsOfflineModeOff =>
'Use the internet to sync music.';
@override
String get settingsNetworkOptionsOfflineModeOn =>
'Don\'t use the internet to sync or play music.';
@override
String get settingsNetworkOptionsStreamFormat => 'Preferred stream format';
@override
String get settingsNetworkOptionsStreamFormatServerDefault =>
'Use server default';
@override
String settingsNetworkValuesKbps(String value) {
return '${value}kbps';
}
@override
String settingsNetworkValuesSeconds(String value) {
return '$value seconds';
}
@override
String get settingsNetworkValuesUnlimitedKbps => 'Unlimited';
@override
String get settingsResetActionsClearImageCache => 'Clear Image Cache';
@override
String get settingsResetName => 'リセット';
@override
String get settingsServersActionsAdd => 'Add source';
@override
String get settingsServersActionsDelete => 'Delete';
@override
String get settingsServersActionsEdit => 'Edit source';
@override
String get settingsServersActionsSave => 'Save';
@override
String get settingsServersActionsTestConnection => 'Test connection';
@override
String get settingsServersFieldsAddress => 'Address';
@override
String get settingsServersFieldsName => 'Name';
@override
String get settingsServersFieldsPassword => 'Password';
@override
String get settingsServersFieldsUsername => 'Username';
@override
String settingsServersMessagesConnectionFailed(String address) {
return 'Connection to $address failed, check settings or server';
}
@override
String settingsServersMessagesConnectionOk(String address) {
return 'Connection to $address OK!';
}
@override
String get settingsServersName => 'サーバ';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOff =>
'Send password as token + salt';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOn =>
'Send password in plaintext (legacy, make sure your connection is secure!)';
@override
String get settingsServersOptionsForcePlaintextPasswordTitle =>
'Force plaintext password';
}

View File

@@ -0,0 +1,401 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for Norwegian Bokmål (`nb`).
class AppLocalizationsNb extends AppLocalizations {
AppLocalizationsNb([String locale = 'nb']) : super(locale);
@override
String get actionsCancel => 'Cancel';
@override
String get actionsDelete => 'Delete';
@override
String get actionsDownload => 'Download';
@override
String get actionsDownloadCancel => 'Cancel download';
@override
String get actionsDownloadDelete => 'Delete downloaded';
@override
String get actionsOk => 'OK';
@override
String get actionsStar => 'Stjernemerk';
@override
String get actionsUnstar => 'Fjern stjernemerking';
@override
String get controlsShuffle => 'Shuffle';
@override
String get messagesNothingHere => 'Ingenting her …';
@override
String get navigationTabsHome => 'Hjem';
@override
String get navigationTabsAlbums => 'Albums';
@override
String get navigationTabsArtists => 'Artists';
@override
String get navigationTabsPlaylists => 'Playlists';
@override
String get navigationTabsSongs => 'Songs';
@override
String get navigationTabsLibrary => 'Bibliotek';
@override
String get navigationTabsSearch => 'Søk';
@override
String get navigationTabsSettings => 'Innstillinger';
@override
String get resourcesAlbumActionsPlay => 'Spill album';
@override
String get resourcesAlbumActionsView => 'Vis album';
@override
String resourcesAlbumCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count albums',
one: '$count album',
);
return '$_temp0';
}
@override
String get resourcesAlbumListsSort => 'Sorter album';
@override
String resourcesAlbumName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Album',
one: 'Album',
);
return '$_temp0';
}
@override
String get resourcesArtistActionsView => 'Vis artist';
@override
String resourcesArtistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count artists',
one: '$count artist',
);
return '$_temp0';
}
@override
String get resourcesArtistListsSort => 'Sorter artister';
@override
String resourcesArtistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Artister',
one: 'Artist',
);
return '$_temp0';
}
@override
String get resourcesFilterAlbum => 'Album';
@override
String get resourcesFilterArtist => 'Artist';
@override
String get resourcesFilterGenre => 'Etter sjanger';
@override
String get resourcesFilterOwner => 'Owner';
@override
String get resourcesFilterStarred => 'Stjernemerket';
@override
String get resourcesFilterYear => 'Year';
@override
String get resourcesPlaylistActionsPlay => 'Spill av spilleliste';
@override
String resourcesPlaylistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count playlists',
one: '$count playlist',
);
return '$_temp0';
}
@override
String resourcesPlaylistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Spillelister',
one: 'Spilleliste',
);
return '$_temp0';
}
@override
String resourcesQueueName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Køer',
one: '',
);
return '$_temp0';
}
@override
String resourcesSongCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count songs',
one: '$count song',
);
return '$_temp0';
}
@override
String get resourcesSongListDeleteAllContent =>
'This will remove all downloaded song files.';
@override
String get resourcesSongListDeleteAllTitle => 'Delete downloads?';
@override
String get resourcesSongListsArtistTopSongs => 'Toppspor';
@override
String resourcesSongName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Spor',
one: 'Spor',
);
return '$_temp0';
}
@override
String get resourcesSortByAdded => 'Nylig tillagt';
@override
String get resourcesSortByAlbum => 'Album';
@override
String get resourcesSortByAlbumCount => 'Album count';
@override
String get resourcesSortByArtist => 'Etter artist';
@override
String get resourcesSortByFrequentlyPlayed => 'Ofte spilt';
@override
String get resourcesSortByName => 'Etter navn';
@override
String get resourcesSortByRandom => 'Tilfeldig';
@override
String get resourcesSortByRecentlyPlayed => 'Nylig spilt';
@override
String get resourcesSortByTitle => 'Title';
@override
String get resourcesSortByUpdated => 'Recently updated';
@override
String get resourcesSortByYear => 'Etter år';
@override
String searchHeaderTitle(String query) {
return 'Søk: $query';
}
@override
String get searchInputPlaceholder => 'Søk';
@override
String get searchMoreResults => 'Mer …';
@override
String get searchNowPlayingContext => 'Søkeresultater';
@override
String get settingsAboutActionsLicenses => 'Lisenser';
@override
String get settingsAboutActionsProjectHomepage => 'Prosjekthjemmeside';
@override
String get settingsAboutActionsSupport => 'Support the developer 💜';
@override
String get settingsAboutName => 'Om';
@override
String get settingsAboutShareLogs => 'Share logs';
@override
String get settingsAboutChooseLog => 'Choose a log file';
@override
String settingsAboutVersion(String version) {
return 'versjon $version';
}
@override
String get settingsMusicName => 'Musikk';
@override
String get settingsMusicOptionsScrobbleDescriptionOff =>
'Ikke utfør sporinfodeling av avspillingshistorikk';
@override
String get settingsMusicOptionsScrobbleDescriptionOn =>
'Sporinfodelings-avspillinghistorikk';
@override
String get settingsMusicOptionsScrobbleTitle => 'Sporinfodelingsavspillinger';
@override
String get settingsNetworkName => 'Nettverk';
@override
String get settingsNetworkOptionsMaxBitrateMobileTitle =>
'Maksimal bitrate (mobil)';
@override
String get settingsNetworkOptionsMaxBitrateWifiTitle =>
'Maksimal bitrate (Wi-Fi)';
@override
String get settingsNetworkOptionsMaxBufferTitle =>
'Maksimal mellomlagringstid';
@override
String get settingsNetworkOptionsMinBufferTitle =>
'Minimal mellomlagringstid';
@override
String get settingsNetworkOptionsOfflineMode => 'Offline mode';
@override
String get settingsNetworkOptionsOfflineModeOff =>
'Use the internet to sync music.';
@override
String get settingsNetworkOptionsOfflineModeOn =>
'Don\'t use the internet to sync or play music.';
@override
String get settingsNetworkOptionsStreamFormat => 'Preferred stream format';
@override
String get settingsNetworkOptionsStreamFormatServerDefault =>
'Use server default';
@override
String settingsNetworkValuesKbps(String value) {
return '$value kbps';
}
@override
String settingsNetworkValuesSeconds(String value) {
return '$value sekunder';
}
@override
String get settingsNetworkValuesUnlimitedKbps => 'Ubegrenset';
@override
String get settingsResetActionsClearImageCache => 'Tøm bildehurtiglager';
@override
String get settingsResetName => 'Tilbakestill';
@override
String get settingsServersActionsAdd => 'Legg til tjener';
@override
String get settingsServersActionsDelete => 'Slett';
@override
String get settingsServersActionsEdit => 'Rediger tjener';
@override
String get settingsServersActionsSave => 'Lagre';
@override
String get settingsServersActionsTestConnection => 'Test tilkobling';
@override
String get settingsServersFieldsAddress => 'Adresse';
@override
String get settingsServersFieldsName => 'Name';
@override
String get settingsServersFieldsPassword => 'Passord';
@override
String get settingsServersFieldsUsername => 'Brukernavn';
@override
String settingsServersMessagesConnectionFailed(String address) {
return 'Tilkobling til $address mislyktes. Sjekk innstillingene eller tjeneren.';
}
@override
String settingsServersMessagesConnectionOk(String address) {
return 'Tilkobling til $address OK.';
}
@override
String get settingsServersName => 'Tjenere';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOff =>
'Send passord som symbol + salt';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOn =>
'Send passord i klartekst (Foreldet. Forsikre deg om at tilkoblingen er sikker.)';
@override
String get settingsServersOptionsForcePlaintextPasswordTitle =>
'Påtving klartekstspassord';
}

View File

@@ -0,0 +1,399 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for Panjabi Punjabi (`pa`).
class AppLocalizationsPa extends AppLocalizations {
AppLocalizationsPa([String locale = 'pa']) : super(locale);
@override
String get actionsCancel => 'Cancel';
@override
String get actionsDelete => 'Delete';
@override
String get actionsDownload => 'Download';
@override
String get actionsDownloadCancel => 'Cancel download';
@override
String get actionsDownloadDelete => 'Delete downloaded';
@override
String get actionsOk => 'OK';
@override
String get actionsStar => 'ਤਾਰਾ';
@override
String get actionsUnstar => 'ਤਾਰਾ ਹਟਾਓ';
@override
String get controlsShuffle => 'Shuffle';
@override
String get messagesNothingHere => 'ਇੱਥੇ ਕੁਝ ਨਹੀਂ ਹੈ…';
@override
String get navigationTabsHome => 'ਘਰ';
@override
String get navigationTabsAlbums => 'Albums';
@override
String get navigationTabsArtists => 'Artists';
@override
String get navigationTabsPlaylists => 'Playlists';
@override
String get navigationTabsSongs => 'Songs';
@override
String get navigationTabsLibrary => 'ਲਾਇਬ੍ਰੇਰੀ';
@override
String get navigationTabsSearch => 'ਖੋਜ';
@override
String get navigationTabsSettings => 'ਸੈਟਿੰਗਾਂ';
@override
String get resourcesAlbumActionsPlay => 'ਐਲਬਮ ਚਲਾਓ';
@override
String get resourcesAlbumActionsView => 'ਐਲਬਮ ਦੇਖੋ';
@override
String resourcesAlbumCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count albums',
one: '$count album',
);
return '$_temp0';
}
@override
String get resourcesAlbumListsSort => 'ਐਲਬਮਾਂ ਨੂੰ ਕਰਮਬੱਧ ਕਰੋ';
@override
String resourcesAlbumName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'ਐਲਬਮਾਂ',
one: 'ਐਲਬਮ',
);
return '$_temp0';
}
@override
String get resourcesArtistActionsView => 'ਕਲਾਕਾਰ ਦੇਖੋ';
@override
String resourcesArtistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count artists',
one: '$count artist',
);
return '$_temp0';
}
@override
String get resourcesArtistListsSort => 'ਕਲਾਕਾਰਾਂ ਦੀ ਛਾਂਟੀ';
@override
String resourcesArtistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'ਕਲਾਕਾਰਾਂ',
one: 'ਕਲਾਕਾਰ',
);
return '$_temp0';
}
@override
String get resourcesFilterAlbum => 'Album';
@override
String get resourcesFilterArtist => 'Artist';
@override
String get resourcesFilterGenre => 'ਸ਼ੈਲੀ ਦੁਆਰਾ';
@override
String get resourcesFilterOwner => 'Owner';
@override
String get resourcesFilterStarred => 'ਸਟਾਰ ਕੀਤੇ ਗਏ';
@override
String get resourcesFilterYear => 'Year';
@override
String get resourcesPlaylistActionsPlay => 'ਪਲੇਲਿਸਟ ਚਲਾਓ';
@override
String resourcesPlaylistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count playlists',
one: '$count playlist',
);
return '$_temp0';
}
@override
String resourcesPlaylistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'ਪਲੇਲਿਸਟਸ',
one: 'ਪਲੇਲਿਸਟ',
);
return '$_temp0';
}
@override
String resourcesQueueName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'ਕਤਾਰਾਂ',
one: 'ਕਤਾਰ',
);
return '$_temp0';
}
@override
String resourcesSongCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count songs',
one: '$count song',
);
return '$_temp0';
}
@override
String get resourcesSongListDeleteAllContent =>
'This will remove all downloaded song files.';
@override
String get resourcesSongListDeleteAllTitle => 'Delete downloads?';
@override
String get resourcesSongListsArtistTopSongs => 'ਉੱਤਮ ਗਾਣੇ';
@override
String resourcesSongName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'ਗਾਣੇ',
one: 'ਗਾਣਾ',
);
return '$_temp0';
}
@override
String get resourcesSortByAdded => 'ਤਾਜ਼ਾ ਸ਼ਾਮਿਲ';
@override
String get resourcesSortByAlbum => 'Album';
@override
String get resourcesSortByAlbumCount => 'Album count';
@override
String get resourcesSortByArtist => 'ਕਲਾਕਾਰ ਦੁਆਰਾ';
@override
String get resourcesSortByFrequentlyPlayed => 'ਅਕਸਰ ਚਲਾਏ ਗਏ';
@override
String get resourcesSortByName => 'ਨਾਮ ਦੁਆਰਾ';
@override
String get resourcesSortByRandom => 'ਅਟਕਲ-ਪੱਚੂ';
@override
String get resourcesSortByRecentlyPlayed => 'ਹਾਲ ਹੀ ਵਿੱਚ ਚਲਾਏ ਗਏ';
@override
String get resourcesSortByTitle => 'Title';
@override
String get resourcesSortByUpdated => 'Recently updated';
@override
String get resourcesSortByYear => 'ਸਾਲ ਦੁਆਰਾ';
@override
String searchHeaderTitle(String query) {
return 'ਖੋਜ: $query';
}
@override
String get searchInputPlaceholder => 'ਖੋਜੋ';
@override
String get searchMoreResults => 'ਹੋਰ…';
@override
String get searchNowPlayingContext => 'ਖੋਜ ਨਤੀਜੇ';
@override
String get settingsAboutActionsLicenses => 'ਲਾਇਸੰਸ';
@override
String get settingsAboutActionsProjectHomepage => 'ਪ੍ਰੋਜੈਕਟ ਹੋਮਪੇਜ';
@override
String get settingsAboutActionsSupport => 'Support the developer 💜';
@override
String get settingsAboutName => 'ਬਾਰੇ';
@override
String get settingsAboutShareLogs => 'Share logs';
@override
String get settingsAboutChooseLog => 'Choose a log file';
@override
String settingsAboutVersion(String version) {
return 'ਸੰਸਕਰਣ $version';
}
@override
String get settingsMusicName => 'ਸੰਗੀਤ';
@override
String get settingsMusicOptionsScrobbleDescriptionOff =>
'ਸੁਣੇ ਹੋਏ ਗਾਣੇ ਸਕ੍ਰੋਬਲ ਨਾ ਕਰੋ';
@override
String get settingsMusicOptionsScrobbleDescriptionOn =>
'ਸੁਣੇ ਹੋਏ ਗਾਣੇ ਸਕ੍ਰੋਬਲ ਕਰੋ';
@override
String get settingsMusicOptionsScrobbleTitle => 'ਗਾਣੇ ਸਕ੍ਰੋਬਲ ਕਰੋ';
@override
String get settingsNetworkName => 'ਨੈੱਟਵਰਕ';
@override
String get settingsNetworkOptionsMaxBitrateMobileTitle =>
'ਵੱਧ ਤੋਂ ਵੱਧ ਬਿੱਟਰੇਟ (ਮੋਬਾਈਲ)';
@override
String get settingsNetworkOptionsMaxBitrateWifiTitle =>
'ਵੱਧ ਤੋਂ ਵੱਧ ਬਿੱਟਰੇਟ (ਵਾਈ-ਫਾਈ)';
@override
String get settingsNetworkOptionsMaxBufferTitle => 'ਵੱਧ ਤੋਂ ਵੱਧ ਬਫਰ ਸਮਾਂ';
@override
String get settingsNetworkOptionsMinBufferTitle => 'ਘੱਟੋ-ਘੱਟ ਬਫਰ ਸਮਾਂ';
@override
String get settingsNetworkOptionsOfflineMode => 'Offline mode';
@override
String get settingsNetworkOptionsOfflineModeOff =>
'Use the internet to sync music.';
@override
String get settingsNetworkOptionsOfflineModeOn =>
'Don\'t use the internet to sync or play music.';
@override
String get settingsNetworkOptionsStreamFormat => 'Preferred stream format';
@override
String get settingsNetworkOptionsStreamFormatServerDefault =>
'Use server default';
@override
String settingsNetworkValuesKbps(String value) {
return '${value}kbps';
}
@override
String settingsNetworkValuesSeconds(String value) {
return '$value ਸਕਿੰਟ';
}
@override
String get settingsNetworkValuesUnlimitedKbps => 'ਅਸੀਮਿਤ';
@override
String get settingsResetActionsClearImageCache => 'ਚਿੱਤਰ ਕੈਸ਼ ਸਾਫ਼ ਕਰੋ';
@override
String get settingsResetName => 'ਰੀਸੈਟ ਕਰੋ';
@override
String get settingsServersActionsAdd => 'ਸਰਵਰ ਸ਼ਾਮਲ ਕਰੋ';
@override
String get settingsServersActionsDelete => 'ਮਿਟਾਓ';
@override
String get settingsServersActionsEdit => 'ਸਰਵਰ ਦਾ ਸੰਪਾਦਨ';
@override
String get settingsServersActionsSave => 'ਸੇਵ ਕਰੋ';
@override
String get settingsServersActionsTestConnection => 'ਟੈਸਟ ਕਨੈਕਸ਼ਨ';
@override
String get settingsServersFieldsAddress => 'ਪਤਾ';
@override
String get settingsServersFieldsName => 'Name';
@override
String get settingsServersFieldsPassword => 'ਪਾਸਵਰਡ';
@override
String get settingsServersFieldsUsername => 'ਯੂਜ਼ਰਨੇਮ';
@override
String settingsServersMessagesConnectionFailed(String address) {
return '$address ਨਾਲ ਕਨੈਕਸ਼ਨ ਅਸਫਲ, ਸੈਟਿੰਗਾਂ ਜਾਂ ਸਰਵਰ ਦੀ ਜਾਂਚ ਕਰੋ';
}
@override
String settingsServersMessagesConnectionOk(String address) {
return '$address ਨਾਲ ਕਨੈਕਸ਼ਨ ਠੀਕ ਹੈ!';
}
@override
String get settingsServersName => 'ਸਰਵਰ';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOff =>
'ਪਾਸਵਰਡ ਨੂੰ ਟੋਕਨ + ਸਾਲ੍ਟ ਵਜੋਂ ਭੇਜੋ';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOn =>
'ਪਾਸਵਰਡ ਨੂੰ ਸਾਦੇ ਟੈਕਸਟ ਵਿੱਚ ਭੇਜੋ (ਪੁਰਾਣਾ, ਯਕੀਨੀ ਬਣਾਓ ਕਿ ਤੁਹਾਡਾ ਕਨੈਕਸ਼ਨ ਸੁਰੱਖਿਅਤ ਹੈ!)';
@override
String get settingsServersOptionsForcePlaintextPasswordTitle =>
'ਸਾਦੇ ਪਾਸਵਰਡ ਨੂੰ ਜਬਰੀ ਕਰੋ';
}

View File

@@ -0,0 +1,412 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for Polish (`pl`).
class AppLocalizationsPl extends AppLocalizations {
AppLocalizationsPl([String locale = 'pl']) : super(locale);
@override
String get actionsCancel => 'Cancel';
@override
String get actionsDelete => 'Delete';
@override
String get actionsDownload => 'Download';
@override
String get actionsDownloadCancel => 'Cancel download';
@override
String get actionsDownloadDelete => 'Delete downloaded';
@override
String get actionsOk => 'OK';
@override
String get actionsStar => 'Ulubione';
@override
String get actionsUnstar => 'Usuń ulubione';
@override
String get controlsShuffle => 'Shuffle';
@override
String get messagesNothingHere => 'Pusto tu…';
@override
String get navigationTabsHome => 'Strona główna';
@override
String get navigationTabsAlbums => 'Albums';
@override
String get navigationTabsArtists => 'Artists';
@override
String get navigationTabsPlaylists => 'Playlists';
@override
String get navigationTabsSongs => 'Songs';
@override
String get navigationTabsLibrary => 'Kolekcja';
@override
String get navigationTabsSearch => 'Wyszukaj';
@override
String get navigationTabsSettings => 'Ustawienia';
@override
String get resourcesAlbumActionsPlay => 'Otwarzaj album';
@override
String get resourcesAlbumActionsView => 'Zobacz album';
@override
String resourcesAlbumCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count albums',
one: '$count album',
);
return '$_temp0';
}
@override
String get resourcesAlbumListsSort => 'Sortowanie albumów';
@override
String resourcesAlbumName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Albumów',
many: 'Albumów',
few: 'Albumy',
one: 'Album',
);
return '$_temp0';
}
@override
String get resourcesArtistActionsView => 'Zobacz wykonawcę';
@override
String resourcesArtistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count artists',
one: '$count artist',
);
return '$_temp0';
}
@override
String get resourcesArtistListsSort => 'Sortowanie wykonawców';
@override
String resourcesArtistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Wykonawców',
many: 'Wykonawców',
few: 'Wykonawcy',
one: 'Wykonawca',
);
return '$_temp0';
}
@override
String get resourcesFilterAlbum => 'Album';
@override
String get resourcesFilterArtist => 'Artist';
@override
String get resourcesFilterGenre => 'Wg gatunku';
@override
String get resourcesFilterOwner => 'Owner';
@override
String get resourcesFilterStarred => 'Ulubione';
@override
String get resourcesFilterYear => 'Year';
@override
String get resourcesPlaylistActionsPlay => 'Odtwarzaj playlistę';
@override
String resourcesPlaylistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count playlists',
one: '$count playlist',
);
return '$_temp0';
}
@override
String resourcesPlaylistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Playlist',
many: 'Playlist',
few: 'Playlisty',
one: 'Playlista',
);
return '$_temp0';
}
@override
String resourcesQueueName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Kolejek',
many: 'Kolejek',
few: 'Kolejki',
one: 'Kolejka',
);
return '$_temp0';
}
@override
String resourcesSongCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count songs',
one: '$count song',
);
return '$_temp0';
}
@override
String get resourcesSongListDeleteAllContent =>
'This will remove all downloaded song files.';
@override
String get resourcesSongListDeleteAllTitle => 'Delete downloads?';
@override
String get resourcesSongListsArtistTopSongs => 'Najpopularniejsze utwory';
@override
String resourcesSongName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Utworów',
many: 'Utworów',
few: 'Utwory',
one: 'Utwór',
);
return '$_temp0';
}
@override
String get resourcesSortByAdded => 'Ostatnio dodane';
@override
String get resourcesSortByAlbum => 'Album';
@override
String get resourcesSortByAlbumCount => 'Album count';
@override
String get resourcesSortByArtist => 'Wg wykonawcy';
@override
String get resourcesSortByFrequentlyPlayed => 'Często odtwarzane';
@override
String get resourcesSortByName => 'Wg nazwy';
@override
String get resourcesSortByRandom => 'Losowo';
@override
String get resourcesSortByRecentlyPlayed => 'Ostatnio odtwarzane';
@override
String get resourcesSortByTitle => 'Title';
@override
String get resourcesSortByUpdated => 'Recently updated';
@override
String get resourcesSortByYear => 'Wg roku';
@override
String searchHeaderTitle(String query) {
return 'Szukaj: $query';
}
@override
String get searchInputPlaceholder => 'Szukaj';
@override
String get searchMoreResults => 'Więcej…';
@override
String get searchNowPlayingContext => 'Wyniki wyszukiwania';
@override
String get settingsAboutActionsLicenses => 'Licencje';
@override
String get settingsAboutActionsProjectHomepage => 'Strona główna projektu';
@override
String get settingsAboutActionsSupport => 'Support the developer 💜';
@override
String get settingsAboutName => 'Informacje o projekcie';
@override
String get settingsAboutShareLogs => 'Share logs';
@override
String get settingsAboutChooseLog => 'Choose a log file';
@override
String settingsAboutVersion(String version) {
return 'wersja $version';
}
@override
String get settingsMusicName => 'Muzyka';
@override
String get settingsMusicOptionsScrobbleDescriptionOff =>
'Nie śledź swojej historii odtwarzania';
@override
String get settingsMusicOptionsScrobbleDescriptionOn =>
'Śledź swoją histrorię odtwarzania';
@override
String get settingsMusicOptionsScrobbleTitle => 'Śledzenie odtworzeń';
@override
String get settingsNetworkName => 'Sieć';
@override
String get settingsNetworkOptionsMaxBitrateMobileTitle =>
'Maksymalny bitrate (sieć komórkowa)';
@override
String get settingsNetworkOptionsMaxBitrateWifiTitle =>
'Maksymalny bitrate (Wi-Fi)';
@override
String get settingsNetworkOptionsMaxBufferTitle =>
'Maksymalny czas buforowania';
@override
String get settingsNetworkOptionsMinBufferTitle =>
'Minimalny czas buforowania';
@override
String get settingsNetworkOptionsOfflineMode => 'Offline mode';
@override
String get settingsNetworkOptionsOfflineModeOff =>
'Use the internet to sync music.';
@override
String get settingsNetworkOptionsOfflineModeOn =>
'Don\'t use the internet to sync or play music.';
@override
String get settingsNetworkOptionsStreamFormat => 'Preferred stream format';
@override
String get settingsNetworkOptionsStreamFormatServerDefault =>
'Use server default';
@override
String settingsNetworkValuesKbps(String value) {
return '${value}kbps';
}
@override
String settingsNetworkValuesSeconds(String value) {
return '$value sekund';
}
@override
String get settingsNetworkValuesUnlimitedKbps => 'Bez ograniczeń';
@override
String get settingsResetActionsClearImageCache =>
'Wyczyść pamięć podręczną obrazów';
@override
String get settingsResetName => 'Przywracanie';
@override
String get settingsServersActionsAdd => 'Dodaj serwer';
@override
String get settingsServersActionsDelete => 'Usuń';
@override
String get settingsServersActionsEdit => 'Edytuj serwer';
@override
String get settingsServersActionsSave => 'Zapisz';
@override
String get settingsServersActionsTestConnection => 'Przetestuj połączenie';
@override
String get settingsServersFieldsAddress => 'Adres serwera';
@override
String get settingsServersFieldsName => 'Name';
@override
String get settingsServersFieldsPassword => 'Hasło';
@override
String get settingsServersFieldsUsername => 'Nazwa użytkownika';
@override
String settingsServersMessagesConnectionFailed(String address) {
return 'Błąd połączenia z $address, sprawdź ustawienia lub serwer';
}
@override
String settingsServersMessagesConnectionOk(String address) {
return 'Połączeno poprawnie z $address!';
}
@override
String get settingsServersName => 'Serwery';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOff =>
'Wyślij hasło jako token i ciąg zaburzający';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOn =>
'Wyślij hasło jako tekst (przestarzałe, upewnij się, że Twoje połączenie jest zabezpieczone)';
@override
String get settingsServersOptionsForcePlaintextPasswordTitle =>
'Wymuś hasło jako tekst (plaintext)';
}

View File

@@ -0,0 +1,401 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for Portuguese (`pt`).
class AppLocalizationsPt extends AppLocalizations {
AppLocalizationsPt([String locale = 'pt']) : super(locale);
@override
String get actionsCancel => 'Cancelar';
@override
String get actionsDelete => 'Apagar';
@override
String get actionsDownload => 'Descarregar';
@override
String get actionsDownloadCancel => 'Cancelar descarga';
@override
String get actionsDownloadDelete => 'Apagar descarga';
@override
String get actionsOk => 'OK';
@override
String get actionsStar => 'Favorito';
@override
String get actionsUnstar => 'Remover favorito';
@override
String get controlsShuffle => 'Aleatório';
@override
String get messagesNothingHere => 'Não existe nada…';
@override
String get navigationTabsHome => 'Início';
@override
String get navigationTabsAlbums => 'Albums';
@override
String get navigationTabsArtists => 'Artists';
@override
String get navigationTabsPlaylists => 'Playlists';
@override
String get navigationTabsSongs => 'Songs';
@override
String get navigationTabsLibrary => 'Biblioteca';
@override
String get navigationTabsSearch => 'Procurar';
@override
String get navigationTabsSettings => 'Definições';
@override
String get resourcesAlbumActionsPlay => 'Tocar Álbum';
@override
String get resourcesAlbumActionsView => 'Ver Álbum';
@override
String resourcesAlbumCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count albums',
one: '$count album',
);
return '$_temp0';
}
@override
String get resourcesAlbumListsSort => 'Ordenar Álbuns';
@override
String resourcesAlbumName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Álbuns',
one: 'Álbum',
);
return '$_temp0';
}
@override
String get resourcesArtistActionsView => 'Ver Artista';
@override
String resourcesArtistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count artists',
one: '$count artist',
);
return '$_temp0';
}
@override
String get resourcesArtistListsSort => 'Ordenar Artistas';
@override
String resourcesArtistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Artistas',
one: 'Artista',
);
return '$_temp0';
}
@override
String get resourcesFilterAlbum => 'Álbum';
@override
String get resourcesFilterArtist => 'Artista';
@override
String get resourcesFilterGenre => 'Por Género';
@override
String get resourcesFilterOwner => 'Owner';
@override
String get resourcesFilterStarred => 'Favoritos';
@override
String get resourcesFilterYear => 'Ano';
@override
String get resourcesPlaylistActionsPlay => 'Tocar Playlist';
@override
String resourcesPlaylistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count playlists',
one: '$count playlist',
);
return '$_temp0';
}
@override
String resourcesPlaylistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Listas',
one: 'Lista',
);
return '$_temp0';
}
@override
String resourcesQueueName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Filas',
one: 'Fila',
);
return '$_temp0';
}
@override
String resourcesSongCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count songs',
one: '$count song',
);
return '$_temp0';
}
@override
String get resourcesSongListDeleteAllContent =>
'This will remove all downloaded song files.';
@override
String get resourcesSongListDeleteAllTitle => 'Delete downloads?';
@override
String get resourcesSongListsArtistTopSongs => 'Top Músicas';
@override
String resourcesSongName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Músicas',
one: 'Música',
);
return '$_temp0';
}
@override
String get resourcesSortByAdded => 'Adicionado recentemente';
@override
String get resourcesSortByAlbum => 'Álbum';
@override
String get resourcesSortByAlbumCount => 'Album count';
@override
String get resourcesSortByArtist => 'Por Artista';
@override
String get resourcesSortByFrequentlyPlayed => 'Mais Tocado';
@override
String get resourcesSortByName => 'Por Nome';
@override
String get resourcesSortByRandom => 'Aleatório';
@override
String get resourcesSortByRecentlyPlayed => 'Ouviu recentemente';
@override
String get resourcesSortByTitle => 'Título';
@override
String get resourcesSortByUpdated => 'Recently updated';
@override
String get resourcesSortByYear => 'Por Ano';
@override
String searchHeaderTitle(String query) {
return 'Procurar: $query';
}
@override
String get searchInputPlaceholder => 'Procurar';
@override
String get searchMoreResults => 'Mais…';
@override
String get searchNowPlayingContext => 'Resultados da Pesquisa';
@override
String get settingsAboutActionsLicenses => 'Licenças';
@override
String get settingsAboutActionsProjectHomepage => 'Página do Projeto';
@override
String get settingsAboutActionsSupport => 'Apoie o programador 💜';
@override
String get settingsAboutName => 'Acerca';
@override
String get settingsAboutShareLogs => 'Share logs';
@override
String get settingsAboutChooseLog => 'Choose a log file';
@override
String settingsAboutVersion(String version) {
return 'versão $version';
}
@override
String get settingsMusicName => 'Música';
@override
String get settingsMusicOptionsScrobbleDescriptionOff =>
'Não enviar histórico de reproduções por scrobble';
@override
String get settingsMusicOptionsScrobbleDescriptionOn =>
'Enviar histórico de reproduções por scrobble';
@override
String get settingsMusicOptionsScrobbleTitle =>
'Enviar reproduções por scrobble';
@override
String get settingsNetworkName => 'Rede';
@override
String get settingsNetworkOptionsMaxBitrateMobileTitle =>
'Bitrate Máximo (móvel)';
@override
String get settingsNetworkOptionsMaxBitrateWifiTitle =>
'Bitrate Máximo (Wi-Fi)';
@override
String get settingsNetworkOptionsMaxBufferTitle => 'Tempo de buffer máximo';
@override
String get settingsNetworkOptionsMinBufferTitle => 'Tempo de buffer mínimo';
@override
String get settingsNetworkOptionsOfflineMode => 'Modo offline';
@override
String get settingsNetworkOptionsOfflineModeOff =>
'Usar a internet para sincronizar música.';
@override
String get settingsNetworkOptionsOfflineModeOn =>
'Não usar a internet para sincronizar ou tocar música.';
@override
String get settingsNetworkOptionsStreamFormat =>
'Formato preferido de streaming';
@override
String get settingsNetworkOptionsStreamFormatServerDefault =>
'Use server default';
@override
String settingsNetworkValuesKbps(String value) {
return '${value}kbps';
}
@override
String settingsNetworkValuesSeconds(String value) {
return '$value segundos';
}
@override
String get settingsNetworkValuesUnlimitedKbps => 'Ilimitado';
@override
String get settingsResetActionsClearImageCache => 'Limpar cache de Imagens';
@override
String get settingsResetName => 'Redefinir';
@override
String get settingsServersActionsAdd => 'Adicionar Servidor';
@override
String get settingsServersActionsDelete => 'Apagar';
@override
String get settingsServersActionsEdit => 'Editar Servidor';
@override
String get settingsServersActionsSave => 'Guardar';
@override
String get settingsServersActionsTestConnection => 'Testar Ligação';
@override
String get settingsServersFieldsAddress => 'Endereço';
@override
String get settingsServersFieldsName => 'Name';
@override
String get settingsServersFieldsPassword => 'Senha';
@override
String get settingsServersFieldsUsername => 'Nome de utilizador';
@override
String settingsServersMessagesConnectionFailed(String address) {
return 'Ligação a $address falhou, verifique definições ou servidor';
}
@override
String settingsServersMessagesConnectionOk(String address) {
return 'Ligação a $address OK!';
}
@override
String get settingsServersName => 'Servidores';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOff =>
'Enviar senha como token + sal';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOn =>
'Enviar senha em texto simples (antigo, certifique-se que a sua ligação é segura!)';
@override
String get settingsServersOptionsForcePlaintextPasswordTitle =>
'Forçar password em texto simples';
}

View File

@@ -0,0 +1,412 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for Russian (`ru`).
class AppLocalizationsRu extends AppLocalizations {
AppLocalizationsRu([String locale = 'ru']) : super(locale);
@override
String get actionsCancel => 'Отменить';
@override
String get actionsDelete => 'Удалить';
@override
String get actionsDownload => 'Скачать';
@override
String get actionsDownloadCancel => 'Отменить загрузку';
@override
String get actionsDownloadDelete => 'Удалить загруженное';
@override
String get actionsOk => 'ОК';
@override
String get actionsStar => 'Избранное';
@override
String get actionsUnstar => 'Убрать из избранного';
@override
String get controlsShuffle => 'Перемешать';
@override
String get messagesNothingHere => 'Здесь ничего нет…';
@override
String get navigationTabsHome => 'Главная';
@override
String get navigationTabsAlbums => 'Albums';
@override
String get navigationTabsArtists => 'Artists';
@override
String get navigationTabsPlaylists => 'Playlists';
@override
String get navigationTabsSongs => 'Songs';
@override
String get navigationTabsLibrary => 'Библиотека';
@override
String get navigationTabsSearch => 'Поиск';
@override
String get navigationTabsSettings => 'Настройки';
@override
String get resourcesAlbumActionsPlay => 'Воспроизвести альбом';
@override
String get resourcesAlbumActionsView => 'Посмотреть альбом';
@override
String resourcesAlbumCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count альбомы',
one: '$count альбом',
);
return '$_temp0';
}
@override
String get resourcesAlbumListsSort => 'Сортировка альбомов';
@override
String resourcesAlbumName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Альбомов',
many: 'Альбомов',
few: 'Альбомы',
one: 'Альбом',
);
return '$_temp0';
}
@override
String get resourcesArtistActionsView => 'Посмотреть исполнителя';
@override
String resourcesArtistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count исполнители',
one: '$count исполнитель',
);
return '$_temp0';
}
@override
String get resourcesArtistListsSort => 'Сортировать исполнителей';
@override
String resourcesArtistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Исполнителей',
many: 'Исполнителей',
few: 'Исполнители',
one: 'Исполнитель',
);
return '$_temp0';
}
@override
String get resourcesFilterAlbum => 'По альбомам';
@override
String get resourcesFilterArtist => 'По исполнителю';
@override
String get resourcesFilterGenre => 'По жанру';
@override
String get resourcesFilterOwner => 'По владельцу';
@override
String get resourcesFilterStarred => 'Избранные';
@override
String get resourcesFilterYear => 'По годам';
@override
String get resourcesPlaylistActionsPlay => 'Воспроизвести плейлист';
@override
String resourcesPlaylistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count плейлисты',
one: '$count плейлист',
);
return '$_temp0';
}
@override
String resourcesPlaylistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Плейлистов',
many: 'Плейлистов',
few: 'Плейлисты',
one: 'Плейлист',
);
return '$_temp0';
}
@override
String resourcesQueueName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Очередей',
many: 'Очередей',
few: 'Очереди',
one: 'Очередь',
);
return '$_temp0';
}
@override
String resourcesSongCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count треки',
one: '$count трек',
);
return '$_temp0';
}
@override
String get resourcesSongListDeleteAllContent =>
'Это удалит все загруженные файлы песен.';
@override
String get resourcesSongListDeleteAllTitle => 'Удалить загрузки?';
@override
String get resourcesSongListsArtistTopSongs => 'Лучшие треки';
@override
String resourcesSongName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Треков',
many: 'Треков',
few: 'Трека',
one: 'Трек',
);
return '$_temp0';
}
@override
String get resourcesSortByAdded => 'Недавно добавленные';
@override
String get resourcesSortByAlbum => 'По альбомам';
@override
String get resourcesSortByAlbumCount => 'По количеству альбомов';
@override
String get resourcesSortByArtist => 'По исполнителям';
@override
String get resourcesSortByFrequentlyPlayed => 'Часто проигрываемые';
@override
String get resourcesSortByName => 'По имени';
@override
String get resourcesSortByRandom => 'Случайно';
@override
String get resourcesSortByRecentlyPlayed => 'Недавно проигранные';
@override
String get resourcesSortByTitle => 'По заголовку';
@override
String get resourcesSortByUpdated => 'По недавно обновленному';
@override
String get resourcesSortByYear => 'По году';
@override
String searchHeaderTitle(String query) {
return 'Поиск: $query';
}
@override
String get searchInputPlaceholder => 'Поиск';
@override
String get searchMoreResults => 'Больше…';
@override
String get searchNowPlayingContext => 'Результаты поиска';
@override
String get settingsAboutActionsLicenses => 'Лицензии';
@override
String get settingsAboutActionsProjectHomepage => 'Сайт проекта';
@override
String get settingsAboutActionsSupport => 'Поддержать разработчика';
@override
String get settingsAboutName => 'О Subtracks';
@override
String get settingsAboutShareLogs => 'Поделиться журналами';
@override
String get settingsAboutChooseLog => 'Выбрать файл журнала';
@override
String settingsAboutVersion(String version) {
return 'версия $version';
}
@override
String get settingsMusicName => 'Музыка';
@override
String get settingsMusicOptionsScrobbleDescriptionOff =>
'Не отправлять историю воспроизведений';
@override
String get settingsMusicOptionsScrobbleDescriptionOn =>
'Скробблинг истории воспроизведения';
@override
String get settingsMusicOptionsScrobbleTitle => 'Скробблинг';
@override
String get settingsNetworkName => 'Сеть';
@override
String get settingsNetworkOptionsMaxBitrateMobileTitle =>
'Максимальный битрейт (мобильный интернет)';
@override
String get settingsNetworkOptionsMaxBitrateWifiTitle =>
'Максимальный битрейт (Wi-Fi)';
@override
String get settingsNetworkOptionsMaxBufferTitle =>
'Максимальное время буферизации';
@override
String get settingsNetworkOptionsMinBufferTitle =>
'Минимальное время буферизации';
@override
String get settingsNetworkOptionsOfflineMode => 'Автономный режим';
@override
String get settingsNetworkOptionsOfflineModeOff =>
'Использовать интернет для синхронизации музыки.';
@override
String get settingsNetworkOptionsOfflineModeOn =>
'Не использовать интернет для синхронизации или воспроизведения музыки.';
@override
String get settingsNetworkOptionsStreamFormat =>
'Предпочтительный формат потока';
@override
String get settingsNetworkOptionsStreamFormatServerDefault =>
'Использовать сервер по умолчанию';
@override
String settingsNetworkValuesKbps(String value) {
return '$value кбит/с';
}
@override
String settingsNetworkValuesSeconds(String value) {
return '$value секунд';
}
@override
String get settingsNetworkValuesUnlimitedKbps => 'Без ограничений';
@override
String get settingsResetActionsClearImageCache => 'Очистить кэш изображения';
@override
String get settingsResetName => 'Сброс';
@override
String get settingsServersActionsAdd => 'Добавить сервер';
@override
String get settingsServersActionsDelete => 'Удалить';
@override
String get settingsServersActionsEdit => 'Редактировать сервер';
@override
String get settingsServersActionsSave => 'Сохранить';
@override
String get settingsServersActionsTestConnection => 'Проверить подключение';
@override
String get settingsServersFieldsAddress => 'Адрес';
@override
String get settingsServersFieldsName => 'Имя';
@override
String get settingsServersFieldsPassword => 'Пароль';
@override
String get settingsServersFieldsUsername => 'Имя пользователя';
@override
String settingsServersMessagesConnectionFailed(String address) {
return 'Не удалось подключиться к $address, проверьте настройки или сервер';
}
@override
String settingsServersMessagesConnectionOk(String address) {
return 'Подключение к $address установлено!';
}
@override
String get settingsServersName => 'Серверы';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOff =>
'Отправить пароль в виде токена';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOn =>
'Отправить пароль в виде текста (устарело, убедитесь, что ваше соединение безопасно!)';
@override
String get settingsServersOptionsForcePlaintextPasswordTitle =>
'Принудительно использовать текстовой пароль';
}

View File

@@ -0,0 +1,400 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for Turkish (`tr`).
class AppLocalizationsTr extends AppLocalizations {
AppLocalizationsTr([String locale = 'tr']) : super(locale);
@override
String get actionsCancel => 'Cancel';
@override
String get actionsDelete => 'Delete';
@override
String get actionsDownload => 'Download';
@override
String get actionsDownloadCancel => 'Cancel download';
@override
String get actionsDownloadDelete => 'Delete downloaded';
@override
String get actionsOk => 'OK';
@override
String get actionsStar => 'Yıldızla';
@override
String get actionsUnstar => 'Yıldızı Kaldır';
@override
String get controlsShuffle => 'Shuffle';
@override
String get messagesNothingHere => 'Burada bir şey yok …';
@override
String get navigationTabsHome => 'Giriş';
@override
String get navigationTabsAlbums => 'Albums';
@override
String get navigationTabsArtists => 'Artists';
@override
String get navigationTabsPlaylists => 'Playlists';
@override
String get navigationTabsSongs => 'Songs';
@override
String get navigationTabsLibrary => 'Kütüphane';
@override
String get navigationTabsSearch => 'Arama';
@override
String get navigationTabsSettings => 'Ayarlar';
@override
String get resourcesAlbumActionsPlay => 'Albümü Çal';
@override
String get resourcesAlbumActionsView => 'Albüme Git';
@override
String resourcesAlbumCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count albums',
one: '$count album',
);
return '$_temp0';
}
@override
String get resourcesAlbumListsSort => 'Albümleri Sırala';
@override
String resourcesAlbumName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Albümler',
one: 'Albüm',
);
return '$_temp0';
}
@override
String get resourcesArtistActionsView => 'Sanatçıya Git';
@override
String resourcesArtistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count artists',
one: '$count artist',
);
return '$_temp0';
}
@override
String get resourcesArtistListsSort => 'Sanatçıları Sırala';
@override
String resourcesArtistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Sanatçılar',
one: 'Sanatçı',
);
return '$_temp0';
}
@override
String get resourcesFilterAlbum => 'Album';
@override
String get resourcesFilterArtist => 'Artist';
@override
String get resourcesFilterGenre => 'Türe göre';
@override
String get resourcesFilterOwner => 'Owner';
@override
String get resourcesFilterStarred => 'Yıldızlı';
@override
String get resourcesFilterYear => 'Year';
@override
String get resourcesPlaylistActionsPlay => 'Listeyi Çal';
@override
String resourcesPlaylistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count playlists',
one: '$count playlist',
);
return '$_temp0';
}
@override
String resourcesPlaylistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Çalma Listeleri',
one: 'Çalma Listesi',
);
return '$_temp0';
}
@override
String resourcesQueueName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Sıralar',
one: 'Sıra',
);
return '$_temp0';
}
@override
String resourcesSongCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count songs',
one: '$count song',
);
return '$_temp0';
}
@override
String get resourcesSongListDeleteAllContent =>
'This will remove all downloaded song files.';
@override
String get resourcesSongListDeleteAllTitle => 'Delete downloads?';
@override
String get resourcesSongListsArtistTopSongs => 'En İyi Şarkılar';
@override
String resourcesSongName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Şarkılar',
one: 'Şarkı',
);
return '$_temp0';
}
@override
String get resourcesSortByAdded => 'Son Eklenenler';
@override
String get resourcesSortByAlbum => 'Album';
@override
String get resourcesSortByAlbumCount => 'Album count';
@override
String get resourcesSortByArtist => 'Sanatçıya Göre';
@override
String get resourcesSortByFrequentlyPlayed => 'Sık Dinlenenler';
@override
String get resourcesSortByName => 'İsme göre';
@override
String get resourcesSortByRandom => 'Rastgele';
@override
String get resourcesSortByRecentlyPlayed => 'Yeni Dinleneler';
@override
String get resourcesSortByTitle => 'Title';
@override
String get resourcesSortByUpdated => 'Recently updated';
@override
String get resourcesSortByYear => 'Yıla göre';
@override
String searchHeaderTitle(String query) {
return 'Aranan: $query';
}
@override
String get searchInputPlaceholder => 'Ara';
@override
String get searchMoreResults => 'Tüm Sonuçlar …';
@override
String get searchNowPlayingContext => 'Arama Sonuçları';
@override
String get settingsAboutActionsLicenses => 'Lisanslar';
@override
String get settingsAboutActionsProjectHomepage => 'Proje Ana Sayfası';
@override
String get settingsAboutActionsSupport => 'Support the developer 💜';
@override
String get settingsAboutName => 'Hakkında';
@override
String get settingsAboutShareLogs => 'Share logs';
@override
String get settingsAboutChooseLog => 'Choose a log file';
@override
String settingsAboutVersion(String version) {
return 'sürüm $version';
}
@override
String get settingsMusicName => 'Müzik';
@override
String get settingsMusicOptionsScrobbleDescriptionOff =>
'Müzik geçmişini profilime ekleme';
@override
String get settingsMusicOptionsScrobbleDescriptionOn =>
'Müzik geçmişini profilime ekle';
@override
String get settingsMusicOptionsScrobbleTitle => 'Çalan müziği profilime ekle';
@override
String get settingsNetworkName => '';
@override
String get settingsNetworkOptionsMaxBitrateMobileTitle =>
'Azami bithızı (SIM interneti)';
@override
String get settingsNetworkOptionsMaxBitrateWifiTitle =>
'Azami bithızı (Wi-Fi)';
@override
String get settingsNetworkOptionsMaxBufferTitle => 'Azami arabellek süresi';
@override
String get settingsNetworkOptionsMinBufferTitle => 'Asgari arabellek süresi';
@override
String get settingsNetworkOptionsOfflineMode => 'Offline mode';
@override
String get settingsNetworkOptionsOfflineModeOff =>
'Use the internet to sync music.';
@override
String get settingsNetworkOptionsOfflineModeOn =>
'Don\'t use the internet to sync or play music.';
@override
String get settingsNetworkOptionsStreamFormat => 'Preferred stream format';
@override
String get settingsNetworkOptionsStreamFormatServerDefault =>
'Use server default';
@override
String settingsNetworkValuesKbps(String value) {
return '${value}kb/sn';
}
@override
String settingsNetworkValuesSeconds(String value) {
return '$value saniye';
}
@override
String get settingsNetworkValuesUnlimitedKbps => 'Sınırsız';
@override
String get settingsResetActionsClearImageCache =>
'Görüntü Önbelleğini Temizle';
@override
String get settingsResetName => 'Sıfırlama';
@override
String get settingsServersActionsAdd => 'Sunucu Ekle';
@override
String get settingsServersActionsDelete => 'Kaldır';
@override
String get settingsServersActionsEdit => 'Sunucu Ayarı';
@override
String get settingsServersActionsSave => 'Kaydet';
@override
String get settingsServersActionsTestConnection => 'Bağlantıyı Sına';
@override
String get settingsServersFieldsAddress => 'Adres';
@override
String get settingsServersFieldsName => 'Name';
@override
String get settingsServersFieldsPassword => 'Şifre';
@override
String get settingsServersFieldsUsername => 'Kullanıcı Adı';
@override
String settingsServersMessagesConnectionFailed(String address) {
return '$address ile bağlantı başarısız. Sunucu ayarlarınızın doğrulığundan emin olun.';
}
@override
String settingsServersMessagesConnectionOk(String address) {
return '$address ile bağlantı başarılı!';
}
@override
String get settingsServersName => 'Sunucular';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOff =>
'Şifreyi dizgecik ve tuz karışımı olarak gönder';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOn =>
'Şifreyi düzmetin olarak gönderir (eski yöntem, bağlantının güvenli (HTTPS) olduğu sunucularda kullanın!)';
@override
String get settingsServersOptionsForcePlaintextPasswordTitle =>
'Düzyazı şifre kullanmayı zorla';
}

View File

@@ -0,0 +1,394 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for Vietnamese (`vi`).
class AppLocalizationsVi extends AppLocalizations {
AppLocalizationsVi([String locale = 'vi']) : super(locale);
@override
String get actionsCancel => 'Cancel';
@override
String get actionsDelete => 'Delete';
@override
String get actionsDownload => 'Download';
@override
String get actionsDownloadCancel => 'Cancel download';
@override
String get actionsDownloadDelete => 'Delete downloaded';
@override
String get actionsOk => 'OK';
@override
String get actionsStar => 'Đánh dấu sao';
@override
String get actionsUnstar => 'Bỏ dấu sao';
@override
String get controlsShuffle => 'Shuffle';
@override
String get messagesNothingHere => 'Không có gì ở đây…';
@override
String get navigationTabsHome => 'Trang chủ';
@override
String get navigationTabsAlbums => 'Albums';
@override
String get navigationTabsArtists => 'Artists';
@override
String get navigationTabsPlaylists => 'Playlists';
@override
String get navigationTabsSongs => 'Songs';
@override
String get navigationTabsLibrary => 'Thư Viện';
@override
String get navigationTabsSearch => 'Tìm kiếm';
@override
String get navigationTabsSettings => 'Thiết Lập';
@override
String get resourcesAlbumActionsPlay => 'Phát Album';
@override
String get resourcesAlbumActionsView => 'Xem Album';
@override
String resourcesAlbumCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count albums',
one: '$count album',
);
return '$_temp0';
}
@override
String get resourcesAlbumListsSort => 'Sắp xếp Album';
@override
String resourcesAlbumName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Album',
);
return '$_temp0';
}
@override
String get resourcesArtistActionsView => 'Xem Nghệ sĩ';
@override
String resourcesArtistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count artists',
one: '$count artist',
);
return '$_temp0';
}
@override
String get resourcesArtistListsSort => 'Sắp xếp nghệ sĩ';
@override
String resourcesArtistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Nghệ sĩ',
);
return '$_temp0';
}
@override
String get resourcesFilterAlbum => 'Album';
@override
String get resourcesFilterArtist => 'Artist';
@override
String get resourcesFilterGenre => 'Theo thể loại';
@override
String get resourcesFilterOwner => 'Owner';
@override
String get resourcesFilterStarred => 'Có gắn dấu sao';
@override
String get resourcesFilterYear => 'Year';
@override
String get resourcesPlaylistActionsPlay => 'Phát Danh sách phát';
@override
String resourcesPlaylistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count playlists',
one: '$count playlist',
);
return '$_temp0';
}
@override
String resourcesPlaylistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Danh sách phát',
);
return '$_temp0';
}
@override
String resourcesQueueName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Hàng chờ',
);
return '$_temp0';
}
@override
String resourcesSongCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count songs',
one: '$count song',
);
return '$_temp0';
}
@override
String get resourcesSongListDeleteAllContent =>
'This will remove all downloaded song files.';
@override
String get resourcesSongListDeleteAllTitle => 'Delete downloads?';
@override
String get resourcesSongListsArtistTopSongs => 'Bài hát hàng đầu';
@override
String resourcesSongName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Bài hát',
);
return '$_temp0';
}
@override
String get resourcesSortByAdded => 'Thêm vào gần đây';
@override
String get resourcesSortByAlbum => 'Album';
@override
String get resourcesSortByAlbumCount => 'Album count';
@override
String get resourcesSortByArtist => 'Theo nghệ sĩ';
@override
String get resourcesSortByFrequentlyPlayed => 'Thường xuyên chơi';
@override
String get resourcesSortByName => 'Theo tên';
@override
String get resourcesSortByRandom => 'Ngẫu Nhiên';
@override
String get resourcesSortByRecentlyPlayed => 'Đã phát gần đây';
@override
String get resourcesSortByTitle => 'Title';
@override
String get resourcesSortByUpdated => 'Recently updated';
@override
String get resourcesSortByYear => 'Theo năm';
@override
String searchHeaderTitle(String query) {
return 'Tìm kiếm: $query';
}
@override
String get searchInputPlaceholder => 'Tìm kiếm';
@override
String get searchMoreResults => 'Nhiều hơn…';
@override
String get searchNowPlayingContext => 'Kết quả tìm kiếm';
@override
String get settingsAboutActionsLicenses => 'Giấy phép';
@override
String get settingsAboutActionsProjectHomepage => 'Trang chủ Dự án';
@override
String get settingsAboutActionsSupport => 'Support the developer 💜';
@override
String get settingsAboutName => 'Giới thiệu';
@override
String get settingsAboutShareLogs => 'Share logs';
@override
String get settingsAboutChooseLog => 'Choose a log file';
@override
String settingsAboutVersion(String version) {
return 'phiên bản $version';
}
@override
String get settingsMusicName => 'Âm nhạc';
@override
String get settingsMusicOptionsScrobbleDescriptionOff =>
'Đừng scrobble lịch sử chơi';
@override
String get settingsMusicOptionsScrobbleDescriptionOn =>
'Lịch sử chơi Scrobble';
@override
String get settingsMusicOptionsScrobbleTitle => 'Scrobble lượt chơi';
@override
String get settingsNetworkName => 'Mạng';
@override
String get settingsNetworkOptionsMaxBitrateMobileTitle =>
'Tối đa bitrate (mobile)';
@override
String get settingsNetworkOptionsMaxBitrateWifiTitle =>
'Tối đa bitrate (Wi-Fi)';
@override
String get settingsNetworkOptionsMaxBufferTitle => 'Thời gian đệm tối đa';
@override
String get settingsNetworkOptionsMinBufferTitle => 'Thời gian đệm tối thiểu';
@override
String get settingsNetworkOptionsOfflineMode => 'Offline mode';
@override
String get settingsNetworkOptionsOfflineModeOff =>
'Use the internet to sync music.';
@override
String get settingsNetworkOptionsOfflineModeOn =>
'Don\'t use the internet to sync or play music.';
@override
String get settingsNetworkOptionsStreamFormat => 'Preferred stream format';
@override
String get settingsNetworkOptionsStreamFormatServerDefault =>
'Use server default';
@override
String settingsNetworkValuesKbps(String value) {
return '${value}kbps';
}
@override
String settingsNetworkValuesSeconds(String value) {
return '$value giây';
}
@override
String get settingsNetworkValuesUnlimitedKbps => 'Không giới hạn';
@override
String get settingsResetActionsClearImageCache => 'Xóa bộ nhớ đệm hình ảnh';
@override
String get settingsResetName => 'Cài đặt lại';
@override
String get settingsServersActionsAdd => 'Thêm máy chủ';
@override
String get settingsServersActionsDelete => 'Xóa';
@override
String get settingsServersActionsEdit => 'Chỉnh sửa máy chủ';
@override
String get settingsServersActionsSave => 'Lưu';
@override
String get settingsServersActionsTestConnection => 'Kiểm tra kết nối';
@override
String get settingsServersFieldsAddress => 'Địa chỉ';
@override
String get settingsServersFieldsName => 'Name';
@override
String get settingsServersFieldsPassword => 'Mật Khẩu';
@override
String get settingsServersFieldsUsername => 'Tên đăng nhập';
@override
String settingsServersMessagesConnectionFailed(String address) {
return 'Kết nối với $address không thành công, hãy kiểm tra cài đặt hoặc máy chủ';
}
@override
String settingsServersMessagesConnectionOk(String address) {
return 'Kết nối với $address OK!';
}
@override
String get settingsServersName => 'Máy chủ';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOff =>
'Gửi mật khẩu dưới dạng token + salt';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOn =>
'Gửi mật khẩu ở dạng văn bản rõ ràng (kế thừa, đảm bảo kết nối của bạn an toàn!)';
@override
String get settingsServersOptionsForcePlaintextPasswordTitle =>
'Buộc mật khẩu văn bản thuần túy';
}

View File

@@ -0,0 +1,388 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for Chinese (`zh`).
class AppLocalizationsZh extends AppLocalizations {
AppLocalizationsZh([String locale = 'zh']) : super(locale);
@override
String get actionsCancel => '取消';
@override
String get actionsDelete => '删除';
@override
String get actionsDownload => '下载';
@override
String get actionsDownloadCancel => '取消下载';
@override
String get actionsDownloadDelete => '删除已下载';
@override
String get actionsOk => '确定';
@override
String get actionsStar => '收藏';
@override
String get actionsUnstar => '移除收藏';
@override
String get controlsShuffle => 'Shuffle';
@override
String get messagesNothingHere => '什么都没有…';
@override
String get navigationTabsHome => '首页';
@override
String get navigationTabsAlbums => 'Albums';
@override
String get navigationTabsArtists => 'Artists';
@override
String get navigationTabsPlaylists => 'Playlists';
@override
String get navigationTabsSongs => 'Songs';
@override
String get navigationTabsLibrary => '所有';
@override
String get navigationTabsSearch => '搜索';
@override
String get navigationTabsSettings => '设置';
@override
String get resourcesAlbumActionsPlay => '播放专辑';
@override
String get resourcesAlbumActionsView => '查看专辑';
@override
String resourcesAlbumCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count albums',
one: '$count album',
);
return '$_temp0';
}
@override
String get resourcesAlbumListsSort => '专辑排序';
@override
String resourcesAlbumName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '专辑',
);
return '$_temp0';
}
@override
String get resourcesArtistActionsView => '查看歌手';
@override
String resourcesArtistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count artists',
one: '$count artist',
);
return '$_temp0';
}
@override
String get resourcesArtistListsSort => '歌手排序';
@override
String resourcesArtistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '歌手',
);
return '$_temp0';
}
@override
String get resourcesFilterAlbum => '专辑';
@override
String get resourcesFilterArtist => '歌手';
@override
String get resourcesFilterGenre => '根据类型';
@override
String get resourcesFilterOwner => '所有者';
@override
String get resourcesFilterStarred => '已收藏';
@override
String get resourcesFilterYear => '年份';
@override
String get resourcesPlaylistActionsPlay => '全部播放';
@override
String resourcesPlaylistCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count playlists',
one: '$count playlist',
);
return '$_temp0';
}
@override
String resourcesPlaylistName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '播放列表',
);
return '$_temp0';
}
@override
String resourcesQueueName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '队列',
);
return '$_temp0';
}
@override
String resourcesSongCount(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count songs',
one: '$count song',
);
return '$_temp0';
}
@override
String get resourcesSongListDeleteAllContent => '该操作会删除所有已下载的歌曲文件。';
@override
String get resourcesSongListDeleteAllTitle => '删除下载?';
@override
String get resourcesSongListsArtistTopSongs => '热门歌曲';
@override
String resourcesSongName(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '歌曲',
);
return '$_temp0';
}
@override
String get resourcesSortByAdded => '最近添加';
@override
String get resourcesSortByAlbum => '专辑';
@override
String get resourcesSortByAlbumCount => '专辑数量';
@override
String get resourcesSortByArtist => '根据歌手';
@override
String get resourcesSortByFrequentlyPlayed => '播放最多';
@override
String get resourcesSortByName => '根据名称';
@override
String get resourcesSortByRandom => '随机';
@override
String get resourcesSortByRecentlyPlayed => '最近播放';
@override
String get resourcesSortByTitle => '标题';
@override
String get resourcesSortByUpdated => '最近添加';
@override
String get resourcesSortByYear => '根据年份';
@override
String searchHeaderTitle(String query) {
return '搜索: $query';
}
@override
String get searchInputPlaceholder => '搜索';
@override
String get searchMoreResults => '更多…';
@override
String get searchNowPlayingContext => '搜索结果';
@override
String get settingsAboutActionsLicenses => '许可';
@override
String get settingsAboutActionsProjectHomepage => '项目地址';
@override
String get settingsAboutActionsSupport => '支持开发者';
@override
String get settingsAboutName => '关于';
@override
String get settingsAboutShareLogs => 'Share logs';
@override
String get settingsAboutChooseLog => 'Choose a log file';
@override
String settingsAboutVersion(String version) {
return '版本 $version';
}
@override
String get settingsMusicName => '音乐';
@override
String get settingsMusicOptionsScrobbleDescriptionOff => '不记录scrobble历史';
@override
String get settingsMusicOptionsScrobbleDescriptionOn => 'Scrobble播放历史';
@override
String get settingsMusicOptionsScrobbleTitle => 'Scrobble模式';
@override
String get settingsNetworkName => '网络';
@override
String get settingsNetworkOptionsMaxBitrateMobileTitle => '最大比特率 (3G/4G/5G)';
@override
String get settingsNetworkOptionsMaxBitrateWifiTitle => '最大比特率 (Wi-Fi)';
@override
String get settingsNetworkOptionsMaxBufferTitle => '最大缓冲时间';
@override
String get settingsNetworkOptionsMinBufferTitle => '最小缓冲时间';
@override
String get settingsNetworkOptionsOfflineMode => 'Offline mode';
@override
String get settingsNetworkOptionsOfflineModeOff =>
'Use the internet to sync music.';
@override
String get settingsNetworkOptionsOfflineModeOn =>
'Don\'t use the internet to sync or play music.';
@override
String get settingsNetworkOptionsStreamFormat => 'Preferred stream format';
@override
String get settingsNetworkOptionsStreamFormatServerDefault =>
'Use server default';
@override
String settingsNetworkValuesKbps(String value) {
return '${value}kbps';
}
@override
String settingsNetworkValuesSeconds(String value) {
return '$value';
}
@override
String get settingsNetworkValuesUnlimitedKbps => '不限制';
@override
String get settingsResetActionsClearImageCache => '清除图片缓存';
@override
String get settingsResetName => '重置';
@override
String get settingsServersActionsAdd => '添加服务器';
@override
String get settingsServersActionsDelete => '删除';
@override
String get settingsServersActionsEdit => '编辑服务器';
@override
String get settingsServersActionsSave => '保存';
@override
String get settingsServersActionsTestConnection => '测试连接';
@override
String get settingsServersFieldsAddress => '地址';
@override
String get settingsServersFieldsName => 'Name';
@override
String get settingsServersFieldsPassword => '密码';
@override
String get settingsServersFieldsUsername => '用户名';
@override
String settingsServersMessagesConnectionFailed(String address) {
return '连接到 $address 失败,检查设置或服务器';
}
@override
String settingsServersMessagesConnectionOk(String address) {
return '连接到 $address 正常!';
}
@override
String get settingsServersName => '服务器';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOff =>
'密码以 token + salt 加密发送';
@override
String get settingsServersOptionsForcePlaintextPasswordDescriptionOn =>
'密码以明文发送(不推荐,注意链接安全!)';
@override
String get settingsServersOptionsForcePlaintextPasswordTitle => '强制使用明文密码';
}

View File

@@ -1,40 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:go_router/go_router.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import '../hooks/use_paging_controller.dart';
import 'list_items.dart';
class AlbumsGrid extends HookWidget {
const AlbumsGrid({super.key});
@override
Widget build(BuildContext context) {
final controller = usePagingController<int, String>(
getNextPageKey: (state) =>
state.lastPageIsEmpty ? null : state.nextIntPageKey,
fetchPage: (pageKey) => List.generate(30, (_) => pageKey.toString()),
);
return PagingListener(
controller: controller,
builder: (context, state, fetchNextPage) {
return PagedSliverGrid(
state: state,
fetchNextPage: fetchNextPage,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
),
builderDelegate: PagedChildBuilderDelegate<String>(
itemBuilder: (context, item, index) => AlbumGridTile(
onTap: () {
context.push('/album');
},
),
),
);
},
);
}
}

View File

@@ -1,85 +0,0 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import '../util/clip.dart';
class AlbumGridTile extends StatelessWidget {
const AlbumGridTile({
super.key,
this.onTap,
});
final void Function()? onTap;
@override
Widget build(BuildContext context) {
return CardTheme(
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(
borderRadius: BorderRadiusGeometry.circular(3),
),
margin: EdgeInsets.all(2),
child: ImageCard(
onTap: onTap,
child: CachedNetworkImage(
imageUrl: 'https://placehold.net/400x400.png',
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
),
),
);
}
}
class ArtistListTile extends StatelessWidget {
const ArtistListTile({super.key});
@override
Widget build(BuildContext context) {
return ListTile(
leading: CircleClip(
child: CachedNetworkImage(
imageUrl: 'https://placehold.net/400x400.png',
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
),
),
title: Text('Some Artist'),
);
}
}
class ImageCard extends StatelessWidget {
const ImageCard({
super.key,
required this.child,
this.onTap,
this.onLongPress,
});
final Widget child;
final void Function()? onTap;
final void Function()? onLongPress;
@override
Widget build(BuildContext context) {
return Card(
child: Stack(
fit: StackFit.passthrough,
alignment: Alignment.center,
children: [
child,
Positioned.fill(
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: onTap,
onLongPress: onLongPress,
),
),
),
],
),
);
}
}

View File

@@ -1,9 +1,14 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'router.dart';
import 'app/router.dart';
import 'app/ui/theme.dart';
import 'l10n/generated/app_localizations.dart';
void main() {
runApp(const MainApp());
void main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(ProviderScope(child: const MainApp()));
}
class MainApp extends StatelessWidget {
@@ -13,9 +18,11 @@ class MainApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp.router(
themeMode: ThemeMode.dark,
darkTheme: ThemeData.dark(useMaterial3: true),
darkTheme: subtracksTheme(),
debugShowCheckedModeBanner: false,
routerConfig: router,
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
);
}
}

View File

@@ -1,40 +0,0 @@
import 'package:go_router/go_router.dart';
import 'screens/album_screen.dart';
import 'screens/artist_screen.dart';
import 'screens/library_screen.dart';
import 'screens/now_playing_screen.dart';
import 'screens/root_shell_screen.dart';
import 'screens/settings_screen.dart';
final router = GoRouter(
routes: [
ShellRoute(
builder: (context, state, child) => RootShellScreen(child: child),
routes: [
GoRoute(
path: '/',
builder: (context, state) => LibraryScreen(),
routes: [
GoRoute(
path: 'album',
builder: (context, state) => AlbumScreen(),
),
GoRoute(
path: 'artist',
builder: (context, state) => ArtistScreen(),
),
],
),
],
),
GoRoute(
path: '/now-playing',
builder: (context, state) => NowPlayingScreen(),
),
GoRoute(
path: '/settings',
builder: (context, state) => SettingsScreen(),
),
],
);

View File

@@ -1,32 +0,0 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
class AlbumScreen extends StatelessWidget {
const AlbumScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Album!'),
TextButton(
onPressed: () {
context.push('/artist');
},
child: Text('Artist...'),
),
CachedNetworkImage(
imageUrl: 'https://placehold.net/400x400.png',
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
),
],
),
),
);
}
}

View File

@@ -1,12 +0,0 @@
import 'package:flutter/material.dart';
class ArtistScreen extends StatelessWidget {
const ArtistScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(child: Text('Artist!')),
);
}
}

View File

@@ -1,211 +0,0 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:material_symbols_icons/symbols.dart';
import '../lists/albums_grid.dart';
import '../util/custom_scroll_fix.dart';
class LibraryScreen extends StatefulWidget {
const LibraryScreen({super.key});
@override
State<LibraryScreen> createState() => _LibraryScreenState();
}
class _LibraryScreenState extends State<LibraryScreen>
with SingleTickerProviderStateMixin {
late final TabController tabController;
final iconSize = 26.0;
final tabHeight = 36.0;
late final List<(String, Widget)> tabs = [
('Home', Icon(Symbols.home_rounded, size: iconSize)),
('Albums', Icon(Symbols.album_rounded, size: iconSize)),
('Artists', Icon(Symbols.person_rounded, size: iconSize)),
('Songs', Icon(Symbols.music_note_rounded, size: iconSize)),
('Playlists', Icon(Symbols.playlist_play_rounded, size: iconSize)),
];
@override
void initState() {
super.initState();
tabController = TabController(
length: tabs.length,
initialIndex: 1,
vsync: this,
);
}
@override
void dispose() {
tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return IconTheme(
data: IconThemeData(
fill: 1,
color: TextTheme.of(context).headlineLarge?.color,
weight: 600,
opticalSize: iconSize,
),
child: Scaffold(
body: NestedScrollView(
floatHeaderSlivers: true,
headerSliverBuilder: (context, innerBoxIsScrolled) {
return <Widget>[
SliverOverlapAbsorber(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
context,
),
sliver: SliverAppBar(
flexibleSpace: FlexibleSpaceBar(
collapseMode: CollapseMode.pin,
background: SafeArea(
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: 18,
vertical: 16,
),
child: Text(
'Albums',
style: TextTheme.of(context).headlineLarge?.copyWith(
fontWeight: FontWeight.w800,
),
),
),
),
),
pinned: true,
floating: true,
bottom: PreferredSize(
preferredSize: Size.fromHeight(tabHeight + 18),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TabBar(
controller: tabController,
dividerColor: Colors.transparent,
isScrollable: true,
tabAlignment: TabAlignment.start,
indicatorSize: TabBarIndicatorSize.label,
labelPadding: EdgeInsets.symmetric(
horizontal: 2,
),
labelColor: Theme.of(context).primaryColorDark,
unselectedLabelColor: Theme.of(
context,
).textTheme.headlineLarge?.color,
padding: EdgeInsets.symmetric(
// horizontal: 12,
vertical: 8,
),
splashBorderRadius: BorderRadius.circular(8),
indicator: BoxDecoration(
color: Theme.of(
context,
).primaryTextTheme.headlineLarge?.color,
borderRadius: BorderRadius.circular(8),
),
tabs: tabs
.map(
(tab) => Tab(
height: tabHeight,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 6,
),
child: tab.$2,
),
),
)
.toList(),
),
IconButton(
onPressed: () {
context.push('/settings');
},
icon: Icon(
Symbols.settings_rounded,
),
),
],
),
),
),
),
),
];
},
body: Builder(
builder: (context) {
return CustomScrollProvider(
tabController: tabController,
parent: PrimaryScrollController.of(context),
child: TabBarView(
// These are the contents of the tab views, below the tabs.
controller: tabController,
children: tabs.map((tab) {
final index = tabs.indexOf(tab);
return SafeArea(
top: false,
bottom: false,
child: NewWidget(index: index, tab: tab),
);
}).toList(),
),
);
},
),
),
),
);
}
}
class NewWidget extends StatefulWidget {
const NewWidget({
super.key,
required this.index,
required this.tab,
});
final int index;
final (String, Widget) tab;
@override
State<NewWidget> createState() => _NewWidgetState();
}
class _NewWidgetState extends State<NewWidget>
with AutomaticKeepAliveClientMixin {
@override
bool get wantKeepAlive => true;
@override
Widget build(BuildContext context) {
super.build(context);
final scrollProvider = CustomScrollProviderData.of(context);
return CustomScrollView(
controller: scrollProvider.scrollControllers[widget.index],
slivers: <Widget>[
SliverOverlapInjector(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
context,
),
),
SliverPadding(
padding: const EdgeInsets.all(8.0),
sliver: AlbumsGrid(),
),
],
);
}
}

View File

@@ -1,12 +0,0 @@
import 'package:flutter/material.dart';
class SettingsScreen extends StatelessWidget {
const SettingsScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(child: Text('Settings!')),
);
}
}

Some files were not shown because too many files have changed in this diff Show More