0.5.2 - Download fixes, translation updates, system theme

This commit is contained in:
exttex 2020-10-11 22:06:29 +02:00
parent b9474ffdeb
commit 9585adf528
20 changed files with 1028 additions and 331 deletions

View File

@ -52,6 +52,8 @@ VIRGIN_KLM: Greek
koreezzz: Korean koreezzz: Korean
Fwwwwwwwwwweze: French Fwwwwwwwwwweze: French
kobyrevah: Hebrew kobyrevah: Hebrew
MicroMihai: Romanian
HoScHaKaL: Turkish
### just_audio, audio_service ### just_audio, audio_service
This app depends on modified just_audio and audio_service plugins with Deezer support. This app depends on modified just_audio and audio_service plugins with Deezer support.

View File

@ -38,10 +38,30 @@ import javax.net.ssl.HttpsURLConnection;
public class Deezer { public class Deezer {
DownloadLog logger; DownloadLog logger;
String token;
String arl;
String sid;
boolean authorized = false;
boolean authorizing = false;
//Initialize for logging //Initialize for logging
void init(DownloadLog logger) { void init(DownloadLog logger, String arl) {
this.logger = logger; this.logger = logger;
this.arl = arl;
}
//Authorize GWLight API
public void authorize() {
if (!authorized || sid == null || token == null) {
authorizing = true;
try {
callGWAPI("deezer.getUserData", "{}");
authorized = true;
} catch (Exception e) {
logger.warn("Error authorizing to Deezer API! " + e.toString());
}
}
authorizing = false;
} }
//Get guest SID cookie from deezer.com //Get guest SID cookie from deezer.com
@ -59,11 +79,18 @@ public class Deezer {
return sid; return sid;
} }
//Same as gw_light API, but doesn't need authentication public JSONObject callGWAPI(String method, String params) throws Exception {
public static JSONObject callMobileAPI(String method, String params) throws Exception{ if (sid == null)
String sid = Deezer.getSidCookie(); this.sid = Deezer.getSidCookie();
URL url = new URL("https://api.deezer.com/1.0/gateway.php?api_key=4VCYIJUCDLOUELGD1V8WBVYBNVDYOXEWSLLZDONGBBDFVXTZJRXPR29JRLQFO6ZE&sid=" + sid + "&input=3&output=3&method=" + method); //Get token
if (token == null) {
token = "null";
callGWAPI("deezer.getUserData", "{}");
}
//Call
URL url = new URL("https://www.deezer.com/ajax/gw-light.php?method=" + method + "&input=3&api_version=1.0&api_token=" + token);
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setConnectTimeout(20000); connection.setConnectTimeout(20000);
connection.setDoOutput(true); connection.setDoOutput(true);
@ -73,6 +100,8 @@ public class Deezer {
connection.setRequestProperty("Content-Type", "application/json"); connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Accept", "*/*"); connection.setRequestProperty("Accept", "*/*");
connection.setRequestProperty("Content-Length", Integer.toString(params.getBytes(StandardCharsets.UTF_8).length)); connection.setRequestProperty("Content-Length", Integer.toString(params.getBytes(StandardCharsets.UTF_8).length));
String cookies = "arl=" + arl + "; sid=" + sid;
connection.setRequestProperty("Cookie", cookies);
//Write body //Write body
DataOutputStream wr = new DataOutputStream(connection.getOutputStream()); DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
@ -87,9 +116,26 @@ public class Deezer {
//Parse JSON //Parse JSON
JSONObject out = new JSONObject(data); JSONObject out = new JSONObject(data);
//Save token
if ((token == null || token.equals("null")) && method.equals("deezer.getUserData")) {
token = out.getJSONObject("results").getString("checkForm");
//SID
try {
String newSid = null;
for (String cookie : connection.getHeaderFields().get("Set-Cookie")) {
if (cookie.startsWith("sid=")) {
newSid = cookie.split(";")[0].split("=")[1];
}
}
this.sid = newSid;
} catch (Exception ignored) {}
}
return out; return out;
} }
//api.deezer.com/$method/$param //api.deezer.com/$method/$param
public static JSONObject callPublicAPI(String method, String param) throws Exception { public static JSONObject callPublicAPI(String method, String param) throws Exception {
URL url = new URL("https://api.deezer.com/" + method + "/" + param); URL url = new URL("https://api.deezer.com/" + method + "/" + param);
@ -267,7 +313,7 @@ public class Deezer {
} }
//Tag track with data from API //Tag track with data from API
public static void tagTrack(String path, JSONObject publicTrack, JSONObject publicAlbum, String cover) throws Exception { public static void tagTrack(String path, JSONObject publicTrack, JSONObject publicAlbum, String cover, JSONObject lyricsData) throws Exception {
TagOptionSingleton.getInstance().setAndroid(true); TagOptionSingleton.getInstance().setAndroid(true);
//Load file //Load file
AudioFile f = AudioFileIO.read(new File(path)); AudioFile f = AudioFileIO.read(new File(path));
@ -281,21 +327,38 @@ public class Deezer {
tag.setField(FieldKey.TITLE, publicTrack.getString("title")); tag.setField(FieldKey.TITLE, publicTrack.getString("title"));
tag.setField(FieldKey.ALBUM, publicTrack.getJSONObject("album").getString("title")); tag.setField(FieldKey.ALBUM, publicTrack.getJSONObject("album").getString("title"));
//Artist //Artist
String artists = "";
for (int i=0; i<publicTrack.getJSONArray("contributors").length(); i++) { for (int i=0; i<publicTrack.getJSONArray("contributors").length(); i++) {
tag.addField(FieldKey.ARTIST, publicTrack.getJSONArray("contributors").getJSONObject(i).getString("name")); artists += ", " + publicTrack.getJSONArray("contributors").getJSONObject(i).getString("name");
} }
tag.addField(FieldKey.ARTIST, artists.substring(2));
tag.setField(FieldKey.TRACK, Integer.toString(publicTrack.getInt("track_position"))); tag.setField(FieldKey.TRACK, Integer.toString(publicTrack.getInt("track_position")));
tag.setField(FieldKey.DISC_NO, Integer.toString(publicTrack.getInt("disk_number"))); tag.setField(FieldKey.DISC_NO, Integer.toString(publicTrack.getInt("disk_number")));
tag.setField(FieldKey.ALBUM_ARTIST, publicAlbum.getJSONObject("artist").getString("name")); tag.setField(FieldKey.ALBUM_ARTIST, publicAlbum.getJSONObject("artist").getString("name"));
tag.setField(FieldKey.YEAR, publicTrack.getString("release_date").substring(0, 4)); tag.setField(FieldKey.YEAR, publicTrack.getString("release_date").substring(0, 4));
tag.setField(FieldKey.BPM, Integer.toString((int)publicTrack.getDouble("bpm"))); tag.setField(FieldKey.BPM, Integer.toString((int)publicTrack.getDouble("bpm")));
tag.setField(FieldKey.RECORD_LABEL, publicAlbum.getString("label")); tag.setField(FieldKey.RECORD_LABEL, publicAlbum.getString("label"));
//Genres tag.setField(FieldKey.ISRC, publicTrack.getString("isrc"));
for (int i=0; i<publicAlbum.getJSONObject("genres").getJSONArray("data").length(); i++) { tag.setField(FieldKey.BARCODE, publicAlbum.getString("upc"));
String genre = publicAlbum.getJSONObject("genres").getJSONArray("data").getJSONObject(0).getString("name");
tag.addField(FieldKey.GENRE, genre); //Unsynced lyrics
if (lyricsData != null) {
try {
String lyrics = lyricsData.getJSONObject("results").getString("LYRICS_TEXT");
tag.setField(FieldKey.LYRICS, lyrics);
} catch (Exception e) {
Log.w("WARN", "Error adding unsynced lyrics!");
}
} }
//Genres
String genres = "";
for (int i=0; i<publicAlbum.getJSONObject("genres").getJSONArray("data").length(); i++) {
genres += ", " + publicAlbum.getJSONObject("genres").getJSONArray("data").getJSONObject(0).getString("name");
}
if (genres.length() > 2)
tag.addField(FieldKey.GENRE, genres.substring(2));
File coverFile = new File(cover); File coverFile = new File(cover);
boolean addCover = (coverFile.exists() && coverFile.length() > 0); boolean addCover = (coverFile.exists() && coverFile.length() > 0);

View File

@ -25,11 +25,13 @@ import org.json.JSONObject;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.nio.channels.FileChannel;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.StandardCopyOption; import java.nio.file.StandardCopyOption;
import java.text.DecimalFormat; import java.text.DecimalFormat;
@ -83,7 +85,7 @@ public class DownloadService extends Service {
//Setup logger, deezer api //Setup logger, deezer api
logger.open(context); logger.open(context);
deezer.init(logger); deezer.init(logger, "");
//Get DB //Get DB
DownloadsDatabase dbHelper = new DownloadsDatabase(getApplicationContext()); DownloadsDatabase dbHelper = new DownloadsDatabase(getApplicationContext());
@ -215,7 +217,9 @@ public class DownloadService extends Service {
updating = true; updating = true;
while (updateRequests.size() > 0) { while (updateRequests.size() > 0) {
updateQueue(); updateQueue();
updateRequests.remove(0); //Because threading
if (updateRequests.size() > 0)
updateRequests.remove(0);
} }
} }
updating = false; updating = false;
@ -280,6 +284,49 @@ public class DownloadService extends Service {
//Set state //Set state
download.state = Download.DownloadState.DOWNLOADING; download.state = Download.DownloadState.DOWNLOADING;
//Authorize deezer api
if (!deezer.authorized && !deezer.authorizing)
deezer.authorize();
while (deezer.authorizing)
try {Thread.sleep(50);} catch (Exception ignored) {}
//Fetch metadata
try {
trackJson = Deezer.callPublicAPI("track", download.trackId);
albumJson = Deezer.callPublicAPI("album", Integer.toString(trackJson.getJSONObject("album").getInt("id")));
} catch (Exception e) {
logger.error("Unable to fetch track and album metadata! " + e.toString(), download);
e.printStackTrace();
download.state = Download.DownloadState.ERROR;
exit();
return;
}
//ISRC Fallback
try {
if (trackJson.has("available_countries") && trackJson.getJSONArray("available_countries").length() == 0) {
logger.warn("ISRC Fallback!", download);
JSONObject newTrackJson = Deezer.callPublicAPI("track", "isrc:" + trackJson.getString("isrc"));
//Same track check
if (newTrackJson.getJSONArray("available_countries").length() == 0 || newTrackJson.getInt("id") == trackJson.getInt("id")) throw new Exception("No more to fallback!");
//Get private data
JSONObject privateJson = deezer.callGWAPI("song.getListData", "{\"sng_ids\": [" + newTrackJson.getInt("id") + "]}");
JSONObject trackData = privateJson.getJSONObject("results").getJSONArray("data").getJSONObject(0);
download.trackId = trackData.getString("SNG_ID");
download.md5origin = trackData.getString("MD5_ORIGIN");
download.mediaVersion = trackData.getString("MEDIA_VERSION");
run();
return;
}
} catch (Exception e) {
logger.error("ISRC Fallback failed, track unavailable! " + e.toString());
download.state = Download.DownloadState.DEEZER_ERROR;
exit();
return;
}
//Quality fallback //Quality fallback
int newQuality; int newQuality;
try { try {
@ -300,18 +347,6 @@ public class DownloadService extends Service {
download.quality = newQuality; download.quality = newQuality;
if (!download.priv) { if (!download.priv) {
//Fetch metadata
try {
trackJson = Deezer.callPublicAPI("track", download.trackId);
albumJson = Deezer.callPublicAPI("album", Integer.toString(trackJson.getJSONObject("album").getInt("id")));
} catch (Exception e) {
logger.error("Unable to fetch track and album metadata! " + e.toString(), download);
e.printStackTrace();
download.state = Download.DownloadState.ERROR;
exit();
return;
}
//Check file //Check file
try { try {
outFile = new File(Deezer.generateFilename(download.path, trackJson, albumJson, newQuality)); outFile = new File(Deezer.generateFilename(download.path, trackJson, albumJson, newQuality));
@ -422,21 +457,29 @@ public class DownloadService extends Service {
//Create dirs and copy //Create dirs and copy
parentDir.mkdirs(); parentDir.mkdirs();
if (!tmpFile.renameTo(outFile)) { if (!tmpFile.renameTo(outFile)) {
boolean error = true;
try { try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Files.move(tmpFile.toPath(), outFile.toPath(), StandardCopyOption.REPLACE_EXISTING); Files.move(tmpFile.toPath(), outFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
tmpFile.delete(); tmpFile.delete();
error = false; } else {
//Android <O copy
FileInputStream inputStream = new FileInputStream(tmpFile);
FileOutputStream outputStream = new FileOutputStream(outFile);
FileChannel inputChannel = inputStream.getChannel();
FileChannel outputChannel = outputStream.getChannel();
inputChannel.transferTo(0, inputChannel.size(), outputChannel);
inputStream.close();
outputStream.close();
} }
} catch (Exception e) { } catch (Exception e) {
//Clean
try {
outFile.delete();
tmpFile.delete();
} catch (Exception ignored) {}
//Log & Exit
logger.error("Error moving file! " + outFile.getPath() + ", " + e.toString(), download); logger.error("Error moving file! " + outFile.getPath() + ", " + e.toString(), download);
download.state = Download.DownloadState.ERROR; e.printStackTrace();
exit();
return;
}
if (error) {
logger.error("Error moving file! " + outFile.getPath(), download);
download.state = Download.DownloadState.ERROR; download.state = Download.DownloadState.ERROR;
exit(); exit();
return; return;
@ -473,13 +516,28 @@ public class DownloadService extends Service {
} catch (Exception e) { } catch (Exception e) {
logger.error("Error downloading cover! " + e.toString(), download); logger.error("Error downloading cover! " + e.toString(), download);
e.printStackTrace(); e.printStackTrace();
coverFile.delete(); }
JSONObject lyricsData = null;
//Lyrics
if (settings.downloadLyrics) {
try {
lyricsData = deezer.callGWAPI("song.getLyrics", "{\"sng_id\": " + download.trackId + "}");
String lrcData = Deezer.generateLRC(lyricsData, trackJson);
//Create file
String lrcFilename = outFile.getPath().substring(0, outFile.getPath().lastIndexOf(".")+1) + "lrc";
FileOutputStream fileOutputStream = new FileOutputStream(lrcFilename);
fileOutputStream.write(lrcData.getBytes());
fileOutputStream.close();
} catch (Exception e) {
logger.warn("Error downloading lyrics! " + e.toString(), download);
}
} }
//Tag //Tag
try { try {
Deezer.tagTrack(outFile.getPath(), trackJson, albumJson, coverFile.getPath()); Deezer.tagTrack(outFile.getPath(), trackJson, albumJson, coverFile.getPath(), lyricsData);
} catch (Exception e) { } catch (Exception e) {
Log.e("ERR", "Tagging error!"); Log.e("ERR", "Tagging error!");
e.printStackTrace(); e.printStackTrace();
@ -491,21 +549,6 @@ public class DownloadService extends Service {
//Album cover //Album cover
downloadAlbumCover(albumJson); downloadAlbumCover(albumJson);
//Lyrics
if (settings.downloadLyrics) {
try {
JSONObject lyricsData = Deezer.callMobileAPI("song.getLyrics", "{\"sng_id\": " + download.trackId + "}");
String lrcData = Deezer.generateLRC(lyricsData, trackJson);
//Create file
String lrcFilename = outFile.getPath().substring(0, outFile.getPath().lastIndexOf(".")+1) + "lrc";
FileOutputStream fileOutputStream = new FileOutputStream(lrcFilename);
fileOutputStream.write(lrcData.getBytes());
fileOutputStream.close();
} catch (Exception e) {
logger.warn("Error downloading lyrics! " + e.toString(), download);
}
}
} }
download.state = Download.DownloadState.DONE; download.state = Download.DownloadState.DONE;
@ -521,7 +564,7 @@ public class DownloadService extends Service {
File coverFile = new File(parentDir, "cover.jpg"); File coverFile = new File(parentDir, "cover.jpg");
if (coverFile.exists()) return; if (coverFile.exists()) return;
//Don't download if doesn't have album //Don't download if doesn't have album
if (!download.path.contains("/%album%/")) return; if (!download.path.matches(".*/%album%.*/.*")) return;
try { try {
//Create to lock //Create to lock
@ -664,6 +707,7 @@ public class DownloadService extends Service {
//Load settings //Load settings
case SERVICE_SETTINGS_UPDATE: case SERVICE_SETTINGS_UPDATE:
settings = DownloadSettings.fromBundle(msg.getData()); settings = DownloadSettings.fromBundle(msg.getData());
deezer.arl = settings.arl;
break; break;
//Stop downloads //Stop downloads
@ -760,17 +804,19 @@ public class DownloadService extends Service {
boolean overwriteDownload; boolean overwriteDownload;
boolean downloadLyrics; boolean downloadLyrics;
boolean trackCover; boolean trackCover;
String arl;
private DownloadSettings(int downloadThreads, boolean overwriteDownload, boolean downloadLyrics, boolean trackCover) { private DownloadSettings(int downloadThreads, boolean overwriteDownload, boolean downloadLyrics, boolean trackCover, String arl) {
this.downloadThreads = downloadThreads; this.downloadThreads = downloadThreads;
this.overwriteDownload = overwriteDownload; this.overwriteDownload = overwriteDownload;
this.downloadLyrics = downloadLyrics; this.downloadLyrics = downloadLyrics;
this.trackCover = trackCover; this.trackCover = trackCover;
this.arl = arl;
} }
//Parse settings from bundle sent from UI //Parse settings from bundle sent from UI
static DownloadSettings fromBundle(Bundle b) { static DownloadSettings fromBundle(Bundle b) {
return new DownloadSettings(b.getInt("downloadThreads"), b.getBoolean("overwriteDownload"), b.getBoolean("downloadLyrics"), b.getBoolean("trackCover")); return new DownloadSettings(b.getInt("downloadThreads"), b.getBoolean("overwriteDownload"), b.getBoolean("downloadLyrics"), b.getBoolean("trackCover"), b.getString("arl"));
} }
} }

View File

@ -118,6 +118,7 @@ public class MainActivity extends FlutterActivity {
bundle.putBoolean("overwriteDownload", (boolean)call.argument("overwriteDownload")); bundle.putBoolean("overwriteDownload", (boolean)call.argument("overwriteDownload"));
bundle.putBoolean("downloadLyrics", (boolean)call.argument("downloadLyrics")); bundle.putBoolean("downloadLyrics", (boolean)call.argument("downloadLyrics"));
bundle.putBoolean("trackCover", (boolean)call.argument("trackCover")); bundle.putBoolean("trackCover", (boolean)call.argument("trackCover"));
bundle.putString("arl", (String)call.argument("arl"));
sendMessage(DownloadService.SERVICE_SETTINGS_UPDATE, bundle); sendMessage(DownloadService.SERVICE_SETTINGS_UPDATE, bundle);
result.success(null); result.success(null);

@ -1 +1 @@
Subproject commit b268066d26c1cc28183bfc3f0f4ab60d31ebf1f7 Subproject commit c169591d41beb6cca3908c1971039332db454f2b

View File

@ -428,7 +428,7 @@ class DownloadManager {
//Album folder / with disk number //Album folder / with disk number
if (settings.albumFolder) { if (settings.albumFolder) {
if (settings.albumDiscFolder) { if (settings.albumDiscFolder) {
path = p.join(path, '%album%' + ' - Disk ' + track.diskNumber.toString()); path = p.join(path, '%album%' + ' - Disk ' + (track.diskNumber??null).toString());
} else { } else {
path = p.join(path, '%album%'); path = p.join(path, '%album%');
} }

View File

@ -34,7 +34,7 @@ class PlayerHelper {
int get queueIndex => AudioService.queue.indexWhere((mi) => mi.id == AudioService.currentMediaItem?.id??'Random string so it returns -1'); int get queueIndex => AudioService.queue.indexWhere((mi) => mi.id == AudioService.currentMediaItem?.id??'Random string so it returns -1');
Future start() async { Future start() async {
//Subscribe to custom events //Subscribe to custom events
_customEventSubscription = AudioService.customEventStream.listen((event) async { _customEventSubscription = AudioService.customEventStream.listen((event) async {
if (!(event is Map)) return; if (!(event is Map)) return;
if (event['action'] == 'onLoad') { if (event['action'] == 'onLoad') {
@ -78,11 +78,10 @@ class PlayerHelper {
} }
}); });
_mediaItemSubscription = AudioService.currentMediaItemStream.listen((event) { _mediaItemSubscription = AudioService.currentMediaItemStream.listen((event) {
if (event == null) return;
//Save queue //Save queue
AudioService.customAction('saveQueue'); AudioService.customAction('saveQueue');
//Add to history //Add to history
if (event == null) return;
if (cache.history == null) cache.history = []; if (cache.history == null) cache.history = [];
if (cache.history.length > 0 && cache.history.last.id == event.id) return; if (cache.history.length > 0 && cache.history.last.id == event.id) return;
cache.history.add(Track.fromMediaItem(event)); cache.history.add(Track.fromMediaItem(event));
@ -90,21 +89,24 @@ class PlayerHelper {
}); });
//Start audio_service //Start audio_service
startService(); await startService();
} }
Future startService() async { Future startService() async {
if (AudioService.running) return; if (AudioService.running && AudioService.connected) return;
await AudioService.start( if (!AudioService.connected)
backgroundTaskEntrypoint: backgroundTaskEntrypoint, await AudioService.connect();
androidEnableQueue: true, if (!AudioService.running)
androidStopForegroundOnPause: false, await AudioService.start(
androidNotificationOngoing: false, backgroundTaskEntrypoint: backgroundTaskEntrypoint,
androidNotificationClickStartsActivity: false, androidEnableQueue: true,
androidNotificationChannelDescription: 'Freezer', androidStopForegroundOnPause: false,
androidNotificationChannelName: 'Freezer', androidNotificationOngoing: false,
androidNotificationIcon: 'drawable/ic_logo', androidNotificationClickStartsActivity: true,
); androidNotificationChannelDescription: 'Freezer',
androidNotificationChannelName: 'Freezer',
androidNotificationIcon: 'drawable/ic_logo',
);
} }
Future toggleShuffle() async { Future toggleShuffle() async {

View File

@ -168,7 +168,7 @@ const language_ar_ar = {
"Importing...": "جار الاستيراد...", "Importing...": "جار الاستيراد...",
"Radio": "راديو", "Radio": "راديو",
//0.5.0 Strings: //0.5.0 Strings:
"Storage permission denied!": "رفض إذن التخزين!", "Storage permission denied!": "رفض إذن التخزين!",
"Failed": "فشل", "Failed": "فشل",
"Queued": "في قائمة الانتظار", "Queued": "في قائمة الانتظار",
@ -199,5 +199,9 @@ const language_ar_ar = {
"Repository": "Repository", "Repository": "Repository",
"Source code, report issues there.": "كود المصدر ، ابلغ عن المشاكل هنا.", "Source code, report issues there.": "كود المصدر ، ابلغ عن المشاكل هنا.",
//0.5.2 Strings:
"Use system theme": "استخدم ثيم النظام",
"Light": "ابيض",
} }
}; };

View File

@ -9,7 +9,8 @@ const language_es_es = {
"Home": "Inicio", "Home": "Inicio",
"Search": "Buscar", "Search": "Buscar",
"Library": "Biblioteca", "Library": "Biblioteca",
"Offline mode, can't play flow or smart track lists.": "Modo sin conexión, no se puede reproducir el flow o las listas de pistas inteligentes.", "Offline mode, can't play flow or smart track lists.":
"Modo sin conexión, no se puede reproducir el flow o las listas de pistas inteligentes.",
"Added to library": "Agregado a la biblioteca", "Added to library": "Agregado a la biblioteca",
"Download": "Descargar", "Download": "Descargar",
"Disk": "Disco", "Disk": "Disco",
@ -27,30 +28,39 @@ const language_es_es = {
"Post processing...": "Post procesamiento...", "Post processing...": "Post procesamiento...",
"Done": "Hecho", "Done": "Hecho",
"Delete": "Eliminar", "Delete": "Eliminar",
"Are you sure you want to delete this download?": "¿Estás seguro de que quieres borrar esta descarga?", "Are you sure you want to delete this download?":
"¿Estás seguro de que quieres borrar esta descarga?",
"Cancel": "Cancelar", "Cancel": "Cancelar",
"Downloads": "Descargas", "Downloads": "Descargas",
"Clear queue": "Limpiar la cola", "Clear queue": "Limpiar la cola",
"This won't delete currently downloading item": "Esto no borrará el elemento que se está descargando actualmente", "This won't delete currently downloading item":
"Are you sure you want to delete all queued downloads?": "¿Estás seguro de que quieres borrar todas las descargas en cola?", "Esto no borrará el elemento que se está descargando actualmente",
"Are you sure you want to delete all queued downloads?":
"¿Estás seguro de que quieres borrar todas las descargas en cola?",
"Clear downloads history": "Borrar el historial de descargas", "Clear downloads history": "Borrar el historial de descargas",
"WARNING: This will only clear non-offline (external downloads)": "ADVERTENCIA: Esto sólo borrará las descargas que no están en modo sin conexión (descargas externas).", "WARNING: This will only clear non-offline (external downloads)":
"Please check your connection and try again later...": "Por favor, compruebe su conexión y vuelva a intentarlo más tarde...", "ADVERTENCIA: Esto sólo borrará las descargas que no están en modo sin conexión (descargas externas).",
"Please check your connection and try again later...":
"Por favor, compruebe su conexión y vuelva a intentarlo más tarde...",
"Show more": "Mostrar más", "Show more": "Mostrar más",
"Importer": "Importador", "Importer": "Importador",
"Currently supporting only Spotify, with 100 tracks limit": "Actualmente sólo se soporta Spotify, con un límite de 100 pistas", "Currently supporting only Spotify, with 100 tracks limit":
"Actualmente sólo se soporta Spotify, con un límite de 100 pistas",
"Due to API limitations": "Debido a limitaciones de API", "Due to API limitations": "Debido a limitaciones de API",
"Enter your playlist link below": "Ingrese el enlace de su lista de reproducción a continuación", "Enter your playlist link below":
"Ingrese el enlace de su lista de reproducción a continuación",
"Error loading URL!": "¡Error al cargar la URL!", "Error loading URL!": "¡Error al cargar la URL!",
"Convert": "Convertir", "Convert": "Convertir",
"Download only": "Sólo descargar", "Download only": "Sólo descargar",
"Downloading is currently stopped, click here to resume.": "La descarga está actualmente detenida, haga clic aquí para reanudarla.", "Downloading is currently stopped, click here to resume.":
"La descarga está actualmente detenida, haga clic aquí para reanudarla.",
"Tracks": "Pistas", "Tracks": "Pistas",
"Albums": "Álbumes", "Albums": "Álbumes",
"Artists": "Artistas", "Artists": "Artistas",
"Playlists": "Listas de reproducción", "Playlists": "Listas de reproducción",
"Import": "Importar", "Import": "Importar",
"Import playlists from Spotify": "Importar listas de reproducción de Spotify", "Import playlists from Spotify":
"Importar listas de reproducción de Spotify",
"Statistics": "Estadísticas", "Statistics": "Estadísticas",
"Offline tracks": "Pistas sin conexión", "Offline tracks": "Pistas sin conexión",
"Offline albums": "Álbumes sin conexión", "Offline albums": "Álbumes sin conexión",
@ -61,20 +71,25 @@ const language_es_es = {
"Favorites": "Favoritas", "Favorites": "Favoritas",
"All offline tracks": "Todas las pistas fuera de línea", "All offline tracks": "Todas las pistas fuera de línea",
"Create new playlist": "Crear nueva lista de reproducción", "Create new playlist": "Crear nueva lista de reproducción",
"Cannot create playlists in offline mode": "No se pueden crear listas de reproducción en el modo sin conexión", "Cannot create playlists in offline mode":
"No se pueden crear listas de reproducción en el modo sin conexión",
"Error": "Error", "Error": "Error",
"Error logging in! Please check your token and internet connection and try again.": "¡Error al iniciar la sesión! Por favor, compruebe su token y su conexión a Internet e inténtelo de nuevo.", "Error logging in! Please check your token and internet connection and try again.":
"¡Error al iniciar la sesión! Por favor, compruebe su token y su conexión a Internet e inténtelo de nuevo.",
"Dismiss": "Descartar", "Dismiss": "Descartar",
"Welcome to": "Bienvenido a", "Welcome to": "Bienvenido a",
"Please login using your Deezer account.": "Por favor, inicie sesión con su cuenta de Deezer.", "Please login using your Deezer account.":
"Por favor, inicie sesión con su cuenta de Deezer.",
"Login using browser": "Ingresar usando el navegador", "Login using browser": "Ingresar usando el navegador",
"Login using token": "Ingresar usando token", "Login using token": "Ingresar usando token",
"Enter ARL": "Ingrese ARL", "Enter ARL": "Ingrese ARL",
"Token (ARL)": "Token (ARL)", "Token (ARL)": "Token (ARL)",
"Save": "Guardar", "Save": "Guardar",
"If you don't have account, you can register on deezer.com for free.": "Si no tienes una cuenta, puedes registrarte en deezer.com de forma gratuita.", "If you don't have account, you can register on deezer.com for free.":
"Si no tienes una cuenta, puedes registrarte en deezer.com de forma gratuita.",
"Open in browser": "Abrir en el navegador", "Open in browser": "Abrir en el navegador",
"By using this app, you don't agree with the Deezer ToS": "Al usar esta aplicación, no está de acuerdo con las Condiciones de servicio de Deezer", "By using this app, you don't agree with the Deezer ToS":
"Al usar esta aplicación, no está de acuerdo con las Condiciones de servicio de Deezer",
"Play next": "Reproducir siguiente", "Play next": "Reproducir siguiente",
"Add to queue": "Añadir a la cola", "Add to queue": "Añadir a la cola",
"Add track to favorites": "Agregar pista a favoritos", "Add track to favorites": "Agregar pista a favoritos",
@ -95,7 +110,8 @@ const language_es_es = {
"Add to favorites": "Agregar a favoritos", "Add to favorites": "Agregar a favoritos",
"Remove from library": "Eliminar de la biblioteca", "Remove from library": "Eliminar de la biblioteca",
"Add playlist to library": "Agregar lista de reproducción a la biblioteca", "Add playlist to library": "Agregar lista de reproducción a la biblioteca",
"Added playlist to library": "Lista de reproducción agregada a la biblioteca", "Added playlist to library":
"Lista de reproducción agregada a la biblioteca",
"Make playlist offline": "Hacer lista de reproducción sin conexión", "Make playlist offline": "Hacer lista de reproducción sin conexión",
"Download playlist": "Descargar lista de reproducción", "Download playlist": "Descargar lista de reproducción",
"Create playlist": "Crear lista de reproducción", "Create playlist": "Crear lista de reproducción",
@ -126,21 +142,25 @@ const language_es_es = {
"Deezer (Dark)": "Deezer (oscuro)", "Deezer (Dark)": "Deezer (oscuro)",
"Primary color": "Color primario", "Primary color": "Color primario",
"Selected color": "Color seleccionado", "Selected color": "Color seleccionado",
"Use album art primary color": "Usar el color primario de la carátula del álbum", "Use album art primary color":
"Usar el color primario de la carátula del álbum",
"Warning: might be buggy": "Advertencia: podría tener errores", "Warning: might be buggy": "Advertencia: podría tener errores",
"Mobile streaming": "Transmisión móvil", "Mobile streaming": "Transmisión móvil",
"Wifi streaming": "Transmisión WiFi", "Wifi streaming": "Transmisión WiFi",
"External downloads": "Descargas externas", "External downloads": "Descargas externas",
"Content language": "Lenguaje del contenido", "Content language": "Lenguaje del contenido",
"Not app language, used in headers. Now": "No es un lenguaje de la aplicación, se usa en los encabezados. Ahora", "Not app language, used in headers. Now":
"No es un lenguaje de la aplicación, se usa en los encabezados. Ahora",
"Select language": "Seleccione el idioma", "Select language": "Seleccione el idioma",
"Content country": "País del contenido", "Content country": "País del contenido",
"Country used in headers. Now": "País utilizado en los encabezados. Ahora", "Country used in headers. Now": "País utilizado en los encabezados. Ahora",
"Log tracks": "Seguimiento de las pistas", "Log tracks": "Seguimiento de las pistas",
"Send track listen logs to Deezer, enable it for features like Flow to work properly": "Envía los registros de escucha de las pistas a Deezer, habilítalo para que funciones como Flow funcionen correctamente", "Send track listen logs to Deezer, enable it for features like Flow to work properly":
"Envía los registros de escucha de las pistas a Deezer, habilítalo para que funciones como Flow funcionen correctamente",
"Offline mode": "Modo sin conexión", "Offline mode": "Modo sin conexión",
"Will be overwritten on start.": "Se sobrescribirá al inicio.", "Will be overwritten on start.": "Se sobrescribirá al inicio.",
"Error logging in, check your internet connections.": "Error al iniciar sesión, verifique su conexión a internet.", "Error logging in, check your internet connections.":
"Error al iniciar sesión, verifique su conexión a internet.",
"Logging in...": "Ingresando...", "Logging in...": "Ingresando...",
"Download path": "Ruta de las descargas", "Download path": "Ruta de las descargas",
"Downloads naming": "Nombramiento de las descargas", "Downloads naming": "Nombramiento de las descargas",
@ -151,12 +171,15 @@ const language_es_es = {
"Create folders for artist": "Crear carpetas por artista", "Create folders for artist": "Crear carpetas por artista",
"Create folders for albums": "Crear carpetas por álbumes", "Create folders for albums": "Crear carpetas por álbumes",
"Separate albums by discs": "Separar los álbumes por discos", "Separate albums by discs": "Separar los álbumes por discos",
"Overwrite already downloaded files": "Sobrescribir los archivos ya descargados", "Overwrite already downloaded files":
"Sobrescribir los archivos ya descargados",
"Copy ARL": "Copiar ARL", "Copy ARL": "Copiar ARL",
"Copy userToken/ARL Cookie for use in other apps.": "Copia el Token de usuario/Cookie ARL para su uso en otras aplicaciones.", "Copy userToken/ARL Cookie for use in other apps.":
"Copia el Token de usuario/Cookie ARL para su uso en otras aplicaciones.",
"Copied": "Copiado", "Copied": "Copiado",
"Log out": "Cerrar sesión", "Log out": "Cerrar sesión",
"Due to plugin incompatibility, login using browser is unavailable without restart.": "Debido a la incompatibilidad de los plugins, no se puede iniciar la sesión con el navegador sin reiniciar.", "Due to plugin incompatibility, login using browser is unavailable without restart.":
"Debido a la incompatibilidad de los plugins, no se puede iniciar la sesión con el navegador sin reiniciar.",
"(ARL ONLY) Continue": "Continuar (SÓLO ARL)", "(ARL ONLY) Continue": "Continuar (SÓLO ARL)",
"Log out & Exit": "Cerrar sesión y salir", "Log out & Exit": "Cerrar sesión y salir",
"Pick-a-Path": "Escoja una ruta", "Pick-a-Path": "Escoja una ruta",
@ -164,13 +187,13 @@ const language_es_es = {
"Go up": "Subir", "Go up": "Subir",
"Permission denied": "Permiso denegado", "Permission denied": "Permiso denegado",
"Language": "Idioma", "Language": "Idioma",
"Language changed, please restart Freezer to apply!": "¡El idioma ha cambiado, por favor reinicie Freezer para aplicarlo!", "Language changed, please restart Freezer to apply!":
"¡El idioma ha cambiado, por favor reinicie Freezer para aplicarlo!",
"Importing...": "Importando...", "Importing...": "Importando...",
"Radio": "Radio", "Radio": "Radio",
"Flow": "Flow", "Flow": "Flow",
//0.5.0 Strings: //0.5.0 Strings:
"Storage permission denied!": "Permiso de almacenamiento denegado!", "Storage permission denied!": "Permiso de almacenamiento denegado!",
"Failed": "Fallido", "Failed": "Fallido",
"Queued": "Puesto en cola", "Queued": "Puesto en cola",
@ -185,20 +208,28 @@ const language_es_es = {
"Search or paste URL": "Buscar o pegar URL", "Search or paste URL": "Buscar o pegar URL",
"History": "Historial", "History": "Historial",
"Download threads": "Descargas simultáneas", "Download threads": "Descargas simultáneas",
"Lyrics unavailable, empty or failed to load!": "Letras no disponibles, vacías o no se pudieron cargar!", "Lyrics unavailable, empty or failed to load!":
"Letras no disponibles, vacías o no se pudieron cargar!",
"About": "Acerca de", "About": "Acerca de",
"Telegram Channel": "Canal de Telegram", "Telegram Channel": "Canal de Telegram",
"To get latest releases": "Para obtener los últimos lanzamientos", "To get latest releases": "Para obtener los últimos lanzamientos",
"Official chat": "Chat oficial", "Official chat": "Chat oficial",
"Telegram Group": "Grupo de Telegram", "Telegram Group": "Grupo de Telegram",
"Huge thanks to all the contributors! <3": "Muchas gracias a todos los contribuyentes contributors! <3", "Huge thanks to all the contributors! <3":
"Muchas gracias a todos los contribuyentes contributors! <3",
"Edit playlist": "Editar lista de reproducción", "Edit playlist": "Editar lista de reproducción",
"Update": "Actualizar", "Update": "Actualizar",
"Playlist updated!": "Lista de reproducción actualizada!", "Playlist updated!": "Lista de reproducción actualizada!",
"Downloads added!": "Descargas agregadas!" "Downloads added!": "Descargas agregadas!",
"Save cover file for every track": "Guarde el archivo de portada para cada pista", "Save cover file for every track":
"Guarde el archivo de portada para cada pista",
"Download Log": "Registro de Descarga", "Download Log": "Registro de Descarga",
"Repository": "Repositorio", "Repository": "Repositorio",
"Source code, report issues there.": "Código fuente, informe de problemas allí." "Source code, report issues there.":
"Código fuente, informe de problemas allí.",
//0.5.2 Strings:
"Use system theme": "Usar tema del sistema",
"Light": "blanco"
} }
}; };

View File

@ -10,7 +10,7 @@ const language_it_it = {
"Search": "Cerca", "Search": "Cerca",
"Library": "Libreria", "Library": "Libreria",
"Offline mode, can't play flow or smart track lists.": "Offline mode, can't play flow or smart track lists.":
"Modalità offline, non è possibile riprodurre flow o tracklist smart", "Modalità offline, non è possibile riprodurre flow o tracklist smart",
"Added to library": "Aggiunto alla libreria", "Added to library": "Aggiunto alla libreria",
"Download": "Scarica", "Download": "Scarica",
"Disk": "Disco", "Disk": "Disco",
@ -29,31 +29,31 @@ const language_it_it = {
"Done": "Fatto", "Done": "Fatto",
"Delete": "Cancellare", "Delete": "Cancellare",
"Are you sure you want to delete this download?": "Are you sure you want to delete this download?":
"Sei sicuro di voler cancellare questo download?", "Sei sicuro di voler cancellare questo download?",
"Cancel": "Annulla", "Cancel": "Annulla",
"Downloads": "Download", "Downloads": "Download",
"Clear queue": "Pulisci la coda", "Clear queue": "Pulisci la coda",
"This won't delete currently downloading item": "This won't delete currently downloading item":
"Questa azione non cancellerà i download", "Questa azione non cancellerà i download",
"Are you sure you want to delete all queued downloads?": "Are you sure you want to delete all queued downloads?":
"Sei sicuro di voler cancellare tutti i download in coda?", "Sei sicuro di voler cancellare tutti i download in coda?",
"Clear downloads history": "Pulisci la cronologia dei download", "Clear downloads history": "Pulisci la cronologia dei download",
"WARNING: This will only clear non-offline (external downloads)": "WARNING: This will only clear non-offline (external downloads)":
"ATTENZIONE: Questa azione, pulirà solo i files che non sono offline (download esterni)", "ATTENZIONE: Questa azione, pulirà solo i files che non sono offline (download esterni)",
"Please check your connection and try again later...": "Please check your connection and try again later...":
"Per favore controlla la tua connessione e riprova più tardi...", "Per favore controlla la tua connessione e riprova più tardi...",
"Show more": "Mostra di più", "Show more": "Mostra di più",
"Importer": "Importa", "Importer": "Importa",
"Currently supporting only Spotify, with 100 tracks limit": "Currently supporting only Spotify, with 100 tracks limit":
"Attualmente supporta solo Spotify, con un limite di 100 brani", "Attualmente supporta solo Spotify, con un limite di 100 brani",
"Due to API limitations": "A causa delle limitazioni delle API", "Due to API limitations": "A causa delle limitazioni delle API",
"Enter your playlist link below": "Enter your playlist link below":
"Inserisci il link della tua playlist qui sotto", "Inserisci il link della tua playlist qui sotto",
"Error loading URL!": "Errore nel caricare l'URL!", "Error loading URL!": "Errore nel caricare l'URL!",
"Convert": "Converti", "Convert": "Converti",
"Download only": "Solo Download", "Download only": "Solo Download",
"Downloading is currently stopped, click here to resume.": "Downloading is currently stopped, click here to resume.":
"Il download è attualmente interrotto, fare clic qui per riprenderlo.", "Il download è attualmente interrotto, fare clic qui per riprenderlo.",
"Tracks": "Brani", "Tracks": "Brani",
"Albums": "Album", "Albums": "Album",
"Artists": "Artisti", "Artists": "Artisti",
@ -71,24 +71,24 @@ const language_it_it = {
"All offline tracks": "Tutte i brani offline", "All offline tracks": "Tutte i brani offline",
"Create new playlist": "Crea una nuova playlist", "Create new playlist": "Crea una nuova playlist",
"Cannot create playlists in offline mode": "Cannot create playlists in offline mode":
"Impossibile creare playlist in modalità offline", "Impossibile creare playlist in modalità offline",
"Error": "Errore", "Error": "Errore",
"Error logging in! Please check your token and internet connection and try again.": "Error logging in! Please check your token and internet connection and try again.":
"Errore durante l'accesso! Controlla il token, la tua connessione ad internet e riprova.", "Errore durante l'accesso! Controlla il token, la tua connessione ad internet e riprova.",
"Dismiss": "Chiudi", "Dismiss": "Chiudi",
"Welcome to": "Benvenuto su", "Welcome to": "Benvenuto su",
"Please login using your Deezer account.": "Please login using your Deezer account.":
"Per favore, esegui il login utilizzando il tuo account Deezer.", "Per favore, esegui il login utilizzando il tuo account Deezer.",
"Login using browser": "Login utilizzando il browser", "Login using browser": "Login utilizzando il browser",
"Login using token": "Login utilizzando il token", "Login using token": "Login utilizzando il token",
"Enter ARL": "Inserisci l'ARL", "Enter ARL": "Inserisci l'ARL",
"Token (ARL)": "Token (ARL)", "Token (ARL)": "Token (ARL)",
"Save": "Salva", "Save": "Salva",
"If you don't have account, you can register on deezer.com for free.": "If you don't have account, you can register on deezer.com for free.":
"Se non possiedi un account, puoi registrarti sul sito deezer.com gratuitamente.", "Se non possiedi un account, puoi registrarti sul sito deezer.com gratuitamente.",
"Open in browser": "Apri nel browser", "Open in browser": "Apri nel browser",
"By using this app, you don't agree with the Deezer ToS": "By using this app, you don't agree with the Deezer ToS":
"Utilizzando questa applicazione, non accetti i ToS di Deezer", "Utilizzando questa applicazione, non accetti i ToS di Deezer",
"Play next": "Riproduci subito dopo", "Play next": "Riproduci subito dopo",
"Add to queue": "Aggiungi alla coda", "Add to queue": "Aggiungi alla coda",
"Add track to favorites": "Aggiungi il brano ai preferiti", "Add track to favorites": "Aggiungi il brano ai preferiti",
@ -141,24 +141,24 @@ const language_it_it = {
"Primary color": "Colore Principale", "Primary color": "Colore Principale",
"Selected color": "Colore Selezionato", "Selected color": "Colore Selezionato",
"Use album art primary color": "Use album art primary color":
"Usa il colore principale della copertina dell'album", "Usa il colore principale della copertina dell'album",
"Warning: might be buggy": "Attenzione: potrebbe causare problemi", "Warning: might be buggy": "Attenzione: potrebbe causare problemi",
"Mobile streaming": "Streaming con dati", "Mobile streaming": "Streaming con dati",
"Wifi streaming": "Streaming con WiFi", "Wifi streaming": "Streaming con WiFi",
"External downloads": "Download esterni", "External downloads": "Download esterni",
"Content language": "Lingua dei contenuti", "Content language": "Lingua dei contenuti",
"Not app language, used in headers. Now": "Not app language, used in headers. Now":
"Non la lingua dell'app, utilizzata negli header. Adesso", "Non la lingua dell'app, utilizzata negli header. Adesso",
"Select language": "Seleziona la lingua", "Select language": "Seleziona la lingua",
"Content country": "Contenuto dal Paese", "Content country": "Contenuto dal Paese",
"Country used in headers. Now": "Paese contenuto negli header. Ora", "Country used in headers. Now": "Paese contenuto negli header. Ora",
"Log tracks": "Log delle tracce", "Log tracks": "Log delle tracce",
"Send track listen logs to Deezer, enable it for features like Flow to work properly": "Send track listen logs to Deezer, enable it for features like Flow to work properly":
"Invia i log delle canzioni ascoltate a Deezer, abilitalo affinché features come Flow funzionino correttamente", "Invia i log delle canzioni ascoltate a Deezer, abilitalo affinché features come Flow funzionino correttamente",
"Offline mode": "Modalità Offline", "Offline mode": "Modalità Offline",
"Will be overwritten on start.": "Sarà sovrascritto all'avvio.", "Will be overwritten on start.": "Sarà sovrascritto all'avvio.",
"Error logging in, check your internet connections.": "Error logging in, check your internet connections.":
"Errore durante l'accesso, controlla la tua connessione Internet.", "Errore durante l'accesso, controlla la tua connessione Internet.",
"Logging in...": "Accesso in corso...", "Logging in...": "Accesso in corso...",
"Download path": "Percorso di download", "Download path": "Percorso di download",
"Downloads naming": "Denominazione dei download", "Downloads naming": "Denominazione dei download",
@ -172,11 +172,11 @@ const language_it_it = {
"Overwrite already downloaded files": "Sovrascrivi i file già scaricati", "Overwrite already downloaded files": "Sovrascrivi i file già scaricati",
"Copy ARL": "Copia ARL", "Copy ARL": "Copia ARL",
"Copy userToken/ARL Cookie for use in other apps.": "Copy userToken/ARL Cookie for use in other apps.":
"Copia userToken / ARL Cookie da utilizzare in altre app.", "Copia userToken / ARL Cookie da utilizzare in altre app.",
"Copied": "Copiato", "Copied": "Copiato",
"Log out": "Disconnettiti", "Log out": "Disconnettiti",
"Due to plugin incompatibility, login using browser is unavailable without restart.": "Due to plugin incompatibility, login using browser is unavailable without restart.":
"A causa dell'incompatibilità del plug-in, l'accesso tramite browser non è disponibile senza riavvio.", "A causa dell'incompatibilità del plug-in, l'accesso tramite browser non è disponibile senza riavvio.",
"(ARL ONLY) Continue": "(SOLO ARL) Continua", "(ARL ONLY) Continue": "(SOLO ARL) Continua",
"Log out & Exit": "Disconnettiti e Esci", "Log out & Exit": "Disconnettiti e Esci",
"Pick-a-Path": "Scegli un percorso", "Pick-a-Path": "Scegli un percorso",
@ -185,14 +185,12 @@ const language_it_it = {
"Permission denied": "Permesso negato", "Permission denied": "Permesso negato",
"Language": "Lingua", "Language": "Lingua",
"Language changed, please restart Freezer to apply!": "Language changed, please restart Freezer to apply!":
"Lingua cambiata, riavvia Freezer per applicare la modifica!", "Lingua cambiata, riavvia Freezer per applicare la modifica!",
"Importing...": "Importando...", "Importing...": "Importando...",
"Radio": "Radio", "Radio": "Radio",
"Flow": "Flow", "Flow": "Flow",
//0.5.0 Strings: //0.5.0 Strings:
"Storage permission denied!": "Autorizzazione di archiviazione negata!", "Storage permission denied!": "Autorizzazione di archiviazione negata!",
"Failed": "Fallito", "Failed": "Fallito",
"Queued": "In coda", "Queued": "In coda",
@ -207,22 +205,28 @@ const language_it_it = {
"Search or paste URL": "Cerca o incolla l'URL", "Search or paste URL": "Cerca o incolla l'URL",
"History": "Storia", "History": "Storia",
"Download threads": "Download simultanei", "Download threads": "Download simultanei",
"Lyrics unavailable, empty or failed to load!": "Testi non disponibili, vuoti o caricamento non riuscito!", "Lyrics unavailable, empty or failed to load!":
"Testi non disponibili, vuoti o caricamento non riuscito!",
"About": "Info", "About": "Info",
"Telegram Channel": "Canale Telegram", "Telegram Channel": "Canale Telegram",
"To get latest releases": "Per ottenere le ultime versioni", "To get latest releases": "Per ottenere le ultime versioni",
"Official chat": "Chat ufficiale", "Official chat": "Chat ufficiale",
"Telegram Group": "Gruppo Telegram", "Telegram Group": "Gruppo Telegram",
"Huge thanks to all the contributors! <3": "Un enorme grazie a tutti i collaboratori! <3", "Huge thanks to all the contributors! <3":
"Un enorme grazie a tutti i collaboratori! <3",
"Edit playlist": "Modifica playlist", "Edit playlist": "Modifica playlist",
"Update": "Aggiorna", "Update": "Aggiorna",
"Playlist updated!": "Playlist aggiornata!", "Playlist updated!": "Playlist aggiornata!",
"Downloads added!": "Download aggiunti!" "Downloads added!": "Download aggiunti!",
"Save cover file for every track": "Salva la copertina dell'album per ogni traccia", "Save cover file for every track":
"Salva la copertina dell'album per ogni traccia",
"Download Log": "Download Log", "Download Log": "Download Log",
"Repository": "Repository", "Repository": "Repository",
"Source code, report issues there.": "Codice sorgente, segnala i problemi lì." "Source code, report issues there.":
"Codice sorgente, segnala i problemi lì.",
//0.5.2 Strings:
"Use system theme": "Utilizza il tema di sistema",
"Light": "Chiaro"
} }
}; };

230
lib/languages/ro_ro.dart Normal file
View File

@ -0,0 +1,230 @@
/*
Translated by: MicroMihai
*/
const language_ro_ro = {
"ro_ro": {
"Home": "Home",
"Search": "Căutare",
"Library": "Librărie",
"Offline mode, can't play flow or smart track lists.":
"Mod offline, nu pot reda flow-uri sau liste smart track.",
"Added to library": "Adăugat la librărie",
"Download": "Descărcați",
"Disk": "Disc",
"Offline": "Offline",
"Top Tracks": "Piese Top",
"Show more tracks": "Afișează mai multe piese",
"Top": "Top",
"Top Albums": "Albume Top",
"Show all albums": "Afișează toate albumele",
"Discography": "Discografie",
"Default": "Implicit",
"Reverse": "Invers",
"Alphabetic": "Alfabetic",
"Artist": "Artist",
"Post processing...": "Post procesare...",
"Done": "Gata",
"Delete": "Ștergeți",
"Are you sure you want to delete this download?":
"Ești sigur că vrei să ștergi această descărcare?",
"Cancel": "Anulează",
"Downloads": "Descărcări",
"Clear queue": "Ștergeți coada",
"This won't delete currently downloading item":
"Aceasta nu va șterge elementul care se descarcă acum",
"Are you sure you want to delete all queued downloads?":
"Ești sigur că vrei să ștergi toate descărcările aflate în coadă?",
"Clear downloads history": "Șterge istoricul descărcărilor",
"WARNING: This will only clear non-offline (external downloads)":
"AVERTISMENT: Aceasta va șterge numai non-offline-urile (descărcări externe)",
"Please check your connection and try again later...":
"Vă rugăm să verificați conexiunea și să încercați din nou mai târziu...",
"Show more": "Arată mai multe",
"Importer": "Importator",
"Currently supporting only Spotify, with 100 tracks limit":
"În prezent acceptă doar Spotify, cu limita de 100 de piese",
"Due to API limitations": "Din cauza limitărilor API",
"Enter your playlist link below": "Introduceți linkul playlistului de mai jos",
"Error loading URL!": "Eroare la încărcarea URL-ului!",
"Convert": "Convertiți",
"Download only": "Doar descărcare",
"Downloading is currently stopped, click here to resume.":
"Descărcarea acum este oprită, faceți clic pentru a relua.",
"Tracks": "Piese",
"Albums": "Albume",
"Artists": "Artiști",
"Playlists": "Playlist-uri",
"Import": "Import",
"Import playlists from Spotify": "Importă playlist-uri din Spotify",
"Statistics": "Statistici",
"Offline tracks": "Piese offline",
"Offline albums": "Albume offline",
"Offline playlists": "Playlist-uri offline",
"Offline size": "Dimensiune offline",
"Free space": "Spațiu liber",
"Loved tracks": "Piese favorite",
"Favorites": "Favorite",
"All offline tracks": "Toate piesele offline",
"Create new playlist": "Crează un nou playlist",
"Cannot create playlists in offline mode":
"Nu se pot crea playlist-uri în modul offline",
"Error": "Eroare",
"Error logging in! Please check your token and internet connection and try again.":
"Eroare la conectare! Verificați token-ul și conexiunea la internet și încercați din nou.",
"Dismiss": "Renunță",
"Welcome to": "Bun venit la",
"Please login using your Deezer account.":
"Te rugăm să te conectezi utilizând contul tau Deezer.",
"Login using browser": "Autentificare utilizând browserul",
"Login using token": "Autentificare folosind token-ul",
"Enter ARL": "Introduceți ARL-ul",
"Token (ARL)": "Token (ARL)",
"Save": "Salvează",
"If you don't have account, you can register on deezer.com for free.":
"Dacă nu ai un cont, te poți înregistra gratuit pe deezer.com.",
"Open in browser": "Deschide în browser",
"By using this app, you don't agree with the Deezer ToS":
"Prin utilizarea acestei aplicații, nu sunteți de acord cu Deezer ToS",
"Play next": "Redă urmatorul",
"Add to queue": "Adaugă la coadă",
"Add track to favorites": "Adaugă piesa la favorite",
"Add to playlist": "Adaugă la un playlist",
"Select playlist": "Selectează playlist-ul",
"Track added to": "Piesa a fost adăugată la",
"Remove from playlist": "Șterge din playlist",
"Track removed from": "Piesa a fost eliminată din",
"Remove favorite": "Ștergeți favoritul",
"Track removed from library": "Piesa a fost eliminată din librărie",
"Go to": "Accesați",
"Make offline": "Pune offline",
"Add to library": "Adaugă la librărie",
"Remove album": "Șterge album-ul",
"Album removed": "Album-ul a fost șters",
"Remove from favorites": "Șterge din favorite",
"Artist removed from library": "Artist șters din librărie",
"Add to favorites": "Adaugă la favorite",
"Remove from library": "Șterge din librărie",
"Add playlist to library": "Adaugă playlist-ul la librărie",
"Added playlist to library": "Playlist-ul a fost adăugat la librărie",
"Make playlist offline": "Pune playlist-ul offline",
"Download playlist": "Descarcă playlist-ul",
"Create playlist": "Crează un playlist",
"Title": "Titlu",
"Description": "Descriere",
"Private": "Privat",
"Collaborative": "Colaborativ",
"Create": "Create",
"Playlist created!": "Playlist-ul a fost creat!",
"Playing from:": "Redare din:",
"Queue": "Coadă",
"Offline search": "Căutare offline",
"Search Results": "Rezultate găsite",
"No results!": "Nici un rezultat",
"Show all tracks": "Afișează toate piesele",
"Show all playlists": "Afișează toate playlist-urile",
"Settings": "Setări",
"General": "General",
"Appearance": "Aspect",
"Quality": "Calitate",
"Deezer": "Deezer",
"Theme": "Temă",
"Currently": "Acum",
"Select theme": "Alege tema",
"Light (default)": "Aprins (Default)",
"Dark": "Întunecat",
"Black (AMOLED)": "Negru (AMOLED)",
"Deezer (Dark)": "Deezer (Întunecat)",
"Primary color": "Culoare primară",
"Selected color": "Culoarea selectată",
"Use album art primary color": "Utilizați culoarea primară ale album-ului",
"Warning: might be buggy": "Avertisment: ar putea fi cam bug-uit",
"Mobile streaming": "Streaming mobil",
"Wifi streaming": "Streaming Wi-Fi",
"External downloads": "Descărcări externe",
"Content language": "Limbajul conținutului",
"Not app language, used in headers. Now":
"Nu este limba aplicației, folosit în header (titlu). Acum",
"Select language": "Alege o limbă",
"Content country": "Conținutul tării",
"Country used in headers. Now": "Țara este utilizată în header-i (titluri). Acum",
"Log tracks": "Log-ul pieselor",
"Send track listen logs to Deezer, enable it for features like Flow to work properly":
"Trimiteți log-urile de ascultare a pieselor către Deezer, activați-l pentru funcții precum Flow să funcționeze corect",
"Offline mode": "Mod offline",
"Will be overwritten on start.": "Va fi suprascris la început.",
"Error logging in, check your internet connections.":
"Eroare la conectare, verificați conexiunile la internet.",
"Logging in...": "Conectare...",
"Download path": "Calea descărcărilor",
"Downloads naming": "Denumirea descărcărilor",
"Downloaded tracks filename": "Numele pieselor descărcate",
"Valid variables are": "Variabilele valide sunt",
"Reset": "Reset",
"Clear": "Șterge",
"Create folders for artist": "Creați foldere pentru artiști",
"Create folders for albums": "Creați foldere pentru albume",
"Separate albums by discs": "Separează albumele după discuri",
"Overwrite already downloaded files": "Suprascrieți fișierele deja descărcate",
"Copy ARL": "Copiază ARL-ul",
"Copy userToken/ARL Cookie for use in other apps.":
"Copiază userToken-ul/ARL-ul Cookie utilizarea în alte aplicații.",
"Copied": "Copiat",
"Log out": "Deconectază",
"Due to plugin incompatibility, login using browser is unavailable without restart.":
"Din cauza incompatibilității plugin-ului, conectarea utilizând browserul nu este disponibilă fără un restart",
"(ARL ONLY) Continue": "(DOAR ARL) Continuă",
"Log out & Exit": "Deconectează și ieși",
"Pick-a-Path": "Alege o cale",
"Select storage": "Selectează stocarea",
"Go up": "Du-te sus",
"Permission denied": "Permisie refuzată",
"Language": "Limbă",
"Language changed, please restart Freezer to apply!":
"Limba a fost schimbată, restart-ați Freezer pentru a aplica schimbarea!",
"Importing...": "Importând...",
"Radio": "Radio",
"Flow": "Flow",
"Track is not available on Deezer!": "Piesa nu este disponibilă pe Deezer!",
"Failed to download track! Please restart.": "Descărcarea piesei nu a reușit! Restart-ați.",
//0.5.0 Strings:
"Storage permission denied!": "Permisia de stocare a fost refuzată!",
"Failed": "Eșuat",
"Queued": "În coadă",
//Updated in 0.5.1 - used in context of download:
"External": "Stocare",
//0.5.0
"Restart failed downloads": "Restart-ați descărcările eșuate",
"Clear failed": "Șterge eșuatele",
"Download Settings": "Descărcați setările",
"Create folder for playlist": "Creați foldere pentru playlist-uri",
"Download .LRC lyrics": "Descărcați versurile .LRC",
"Proxy": "Proxy",
"Not set": "Nu este setat",
"Search or paste URL": "Caută sau pune un URL",
"History": "Istorie",
//Updated 0.5.1
"Download threads": "Descărcări simultane",
//0.5.0
"Lyrics unavailable, empty or failed to load!": "Versurile nu sunt disponibile, goale sau au eșuat încărcarea!",
"About": "Despre",
"Telegram Channel": "Canalul Telegram",
"To get latest releases": "Pentru a obține cele mai recente versiuni",
"Official chat": "Chat-ul oficial",
"Telegram Group": "Grupul Telegram",
"Huge thanks to all the contributors! <3": "Mulțumesc frumos tuturor colaboratorilor! <3",
"Edit playlist": "Editați playlist-ul",
"Update": "Actualizează",
"Playlist updated!": "Playlist actualizat!",
"Downloads added!": "Descărcări adăugate!",
//0.5.1 Strings:
"Save cover file for every track": "Salvează cover-ul pentru fiecare piesă",
"Download Log": "Log-ul descărcării",
"Repository": "Depozit",
"Source code, report issues there.": "Codul sursă (Source code), raportați problemele acolo."
}
};

View File

@ -1,30 +1,30 @@
/* /*
Translated by: Annexhack Translated by: @Orfej
*/ */
const language_ru_ru = { const language_ru_ru = {
"ru_ru": { "ru_ru": {
"Home": "Главная", "Home": "Главная",
"Search": "Поиск", "Search": "Поиск",
"Library": "Библиотека", "Library": "Избранное",
"Offline mode, can't play flow or smart track lists.": "Офлайн режим, нельзя воспроизводить потоки или умные списки треков.", "Offline mode, can't play flow or smart track lists.":
"Added to library": "Добавить в библиотеку", "Режим офлайн. Невозможно воспроизвести персональные подборки",
"Added to library": "Добавлено в любимые треки",
"Download": "Скачать", "Download": "Скачать",
"Disk": "Диск", "Disk": "Диск",
"Offline": "Скачанные треки", "Offline": "Загрузить в кеш",
"Top Tracks": "Лучшие треки", "Top Tracks": "Популярные треки",
"Show more tracks": "Показать больше треков", "Show more tracks": "Показать все",
"Top": "Top", "Top": "Лучшее",
"Top Albums": "Лучшие альбомы", "Top Albums": "Лучшие альбомы",
"Show all albums": "Показать все альбомы", "Show all albums": "Показать все",
"Discography": "Дискография", "Discography": "Дискография",
"Default": "По умолчанию", "Default": "По умолчанию",
"Reverse": "Обратный", "Reverse": "В обратном порядке",
"Alphabetic": "По алфавиту", "Alphabetic": "По алфавиту",
"Artist": "Исполнитель", "Artist": "Исполнитель",
"Post processing...": "Постобработка...", "Post processing...": "Делаем магию...",
"Done": "Готово", "Done": "Готово",
"Delete": "Удалить", "Delete": "Удалить",
"Are you sure you want to delete this download?": "Are you sure you want to delete this download?":
@ -32,152 +32,198 @@ const language_ru_ru = {
"Cancel": "Отмена", "Cancel": "Отмена",
"Downloads": "Загрузки", "Downloads": "Загрузки",
"Clear queue": "Очистить очередь", "Clear queue": "Очистить очередь",
"This won't delete currently downloading item": "Это не удалит загружаемый в данный момент элемент", "This won't delete currently downloading item":
"Это не удалит загружаемый сейчас трек",
"Are you sure you want to delete all queued downloads?": "Are you sure you want to delete all queued downloads?":
"Вы действительно хотите удалить все загрузки в очереди?", "Вы действительно хотите удалить все запланированные загрузки?",
"Clear downloads history": "Очистить историю загрузок", "Clear downloads history": "Очистить историю загрузок",
"WARNING: This will only clear non-offline (external downloads)": "WARNING: This will only clear non-offline (external downloads)":
"ВНИМАНИЕ: Это очистит только не офлайн(external downloads)", "Внимание! Это удалит только загрузки (не кеш)",
"Please check your connection and try again later...": "Please check your connection and try again later...":
"Пожалуйста, проверьте ваше соединение и повторите попытку позже...", "Проверьте соединение с Интернетом...",
"Show more": "Показать больше", "Show more": "Показать больше",
"Importer": "Импортер", "Importer": "Импорт плейлистов",
"Currently supporting only Spotify, with 100 tracks limit": "В настоящее время поддерживается только Spotify, с ограничением 100 треков", "Currently supporting only Spotify, with 100 tracks limit":
"Due to API limitations": "Из-за ограничений API", "В настоящий момент поддерживается только Spotify",
"Enter your playlist link below": "Введите ссылку на свой плейлист ниже", "Due to API limitations": "Можно импортировать не более 100 треков за раз",
"Error loading URL!": "Ошибка загрузки URL!", "Enter your playlist link below": "Ссылка на плейлист",
"Convert": "Перерабатывать", "Error loading URL!": "Ошибка загрузки!",
"Download only": "Только скачанные", "Convert": "Импортировать",
"Downloading is currently stopped, click here to resume.": "В настоящее время загрузка остановлена, нажмите здесь, чтобы возобновить.", "Download only": "Скачать",
"Downloading is currently stopped, click here to resume.":
"Загрузка приостановлена, нажмите, чтобы продолжить.",
"Tracks": "Треки", "Tracks": "Треки",
"Albums": "Альбомы", "Albums": "Альбомы",
"Artists": "Артисты", "Artists": "Артисты",
"Playlists": "Плейлисты", "Playlists": "Playlists",
"Import": "Импорт", "Import": "Импорт плейлистов",
"Import playlists from Spotify": "Импортировать плейлисты из Spotify", "Import playlists from Spotify": "В настоящий момент поддерживается только Spotify",
"Statistics": "Статистика", "Statistics": "Размер кеша",
"Offline tracks": "Автономные треки", "Offline tracks": "Треки в кеше:",
"Offline albums": "Автономные альбомы", "Offline albums": "Альбомы в кеше:",
"Offline playlists": "Офлайн-плейлисты", "Offline playlists": "Плейлисты в кеше:",
"Offline size": "Автономный размер", "Offline size": "Размер кеша:",
"Free space": "Свободное место", "Free space": "Свободно:",
"Loved tracks": "Любимые треки", "Loved tracks": "Любимые треки",
"Favorites": "Избранное", "Favorites": "Избранное",
"All offline tracks": "Скачанные треки", "All offline tracks": "Все треки в кеше",
"Create new playlist": "Создать новый плейлист", "Create new playlist": "Новый плейлист",
"Cannot create playlists in offline mode": "Невозможно создавать плейлисты в автономном режиме", "Cannot create playlists in offline mode":
"Нельзя создавать плейлисты в режиме офлайн",
"Error": "Ошибка", "Error": "Ошибка",
"Error logging in! Please check your token and internet connection and try again.": "Error logging in! Please check your token and internet connection and try again.":
"Ошибка входа! Проверьте свой токен и подключение к Интернету и повторите попытку.", "Ошибка входа. Проверьте корректность ARL и соединение с Интернетом",
"Dismiss": "Отклонить", "Dismiss": "Я понял",
"Welcome to": "Добро пожаловать в", "Welcome to": "Добро пожаловать в",
"Please login using your Deezer account.": "Please login using your Deezer account.":
"Пожалуйста, войдите, используя свою учетную запись Deezer.", "Войдите, используя свой аккаунт Deezer.",
"Login using browser": "Войти через браузер", "Login using browser": "Войти через браузер",
"Login using token": "Войти с помощью токена", "Login using token": "Войти по токену (ARL)",
"Enter ARL": "Введите ARL", "Enter ARL": "Введите ARL",
"Token (ARL)": "Токен (ARL)", "Token (ARL)": "Токен (ARL)",
"Save": "Сохранить", "Save": "Сохранить",
"If you don't have account, you can register on deezer.com for free.": "If you don't have account, you can register on deezer.com for free.":
"Если у вас нет учетной записи, вы можете бесплатно зарегистрироваться на deezer.com.", "Вы можете создать аккаунт на deezer.com. Это бесплатно.",
"Open in browser": "Открыть в браузере", "Open in browser": "Зарегестрироваться",
"By using this app, you don't agree with the Deezer ToS": "By using this app, you don't agree with the Deezer ToS":
"Используя это приложение, вы не соглашаетесь с Условиями использования Deezer.", "Используя это приложение, вы не соглашаетесь с Условиями использования Deezer.",
"Play next": "Следующая песня", "Play next": "Играть следующим",
"Add to queue": "Добавить в очередь", "Add to queue": "Добавить в очередь",
"Add track to favorites": "Добавить в избранное", "Add track to favorites": "Добавить в любимые треки",
"Add to playlist": "Добавить в плейлист", "Add to playlist": "Добавить в плейлист",
"Select playlist": "Выбрать плейлист", "Select playlist": "Выберите плейлист",
"Track added to": "Трек добавлен в", "Track added to": "Трек добавлен в",
"Remove from playlist": "Удалить из плейлиста", "Remove from playlist": "Удалить из плейлиста",
"Track removed from": "Трек удален из", "Track removed from": "Трек удалён из",
"Remove favorite": "Удалить избранное", "Remove favorite": "Удалить из любимых треков",
"Track removed from library": "Трек удален из библиотеки", "Track removed from library": "Трек удален из Избранного",
"Go to": "Перейти к", "Go to": "Перейти к",
"Make offline": "Сделать офлайн", "Make offline": "Загрузить в кеш",
"Add to library": "Добавить в библиотеку", "Add to library": "Добавить в Избранное",
"Remove album": "Удалить альбом", "Remove album": "Удалить альбом",
"Album removed": "Альбом удален", "Album removed": "Альбом удален",
"Remove from favorites": "Удалить из Избранного", "Remove from favorites": "Удалить из Избранного",
"Artist removed from library": "Артист удален из библиотеки", "Artist removed from library": "Артист удалён",
"Add to favorites": "Добавить в избранное", "Add to favorites": "Добавить в Избранное",
"Remove from library": "Удалить из библиотеки", "Remove from library": "Удалить из Избранного",
"Add playlist to library": "Добавить плейлист в библиотеку", "Add playlist to library": "Добавить плейлист в Избранное",
"Added playlist to library": "Добавлен плейлист в библиотеку", "Added playlist to library": "Плейлист добавлен в Избранное",
"Make playlist offline": "Сделать плейлист офлайн", "Make playlist offline": "Загрузить плейлист в кеш",
"Download playlist": "Скачать плейлист", "Download playlist": "Скачать плейлист",
"Create playlist": "Создать плейлист", "Create playlist": "Создать плейлист",
"Title": "Название", "Title": "Название",
"Description": "Описание", "Description": "Описание",
"Private": "Частный", "Private": "Скрытый",
"Collaborative": "Совместная", "Collaborative": "Общего пользования",
"Create": "Создать", "Create": "Создать",
"Playlist created!": "Плейлист создан!", "Playlist created!": "Плейлист создан!",
"Playing from:": "Играя с:", "Playing from:": "Сейчас играет:",
"Queue": "Очередь", "Queue": "Очередь",
"Offline search": "Оффлайн поиск", "Offline search": "Поиск по кешу",
"Search Results": "Результаты поиска", "Search Results": "Результаты поиска",
"No results!": "Нет результатов!", "No results!": "Ничего не найдено!",
"Show all tracks": "Показать все треки", "Show all tracks": "Показать все треки",
"Show all playlists": "Показать все плейлисты", "Show all playlists": "Показать все плейлисты",
"Settings": "Настройки", "Settings": "Настрокий",
"General": "Общее", "General": "Управление аккаунтом",
"Appearance": "Интерфейс", "Appearance": "Внешний вид",
"Quality": "Качество звука", "Quality": "Качество звука",
"Deezer": "Deezer", "Deezer": "Взаимодействие с Deezer",
"Theme": "Тема", "Theme": "Тема",
"Currently": "Выбрана тема", "Currently": "Используется:",
"Select theme": "Выберите тему", "Select theme": "Выберите тему",
"Light (default)": "Светлая (По умолчанию)", "Light (default)": "Светлая (По умолчанию)",
"Dark": "Dark (Темная тема)", "Dark": "Темная",
"Black (AMOLED)": "Черная (AMOLED)", "Black (AMOLED)": "Черная (AMOLED)",
"Deezer (Dark)": "Deezer (Dark)", "Deezer (Dark)": "Deezer (Темная)",
"Primary color": "Основной цвет", "Primary color": "Цвет акцента",
"Selected color": "Выбранный цвет", "Selected color": "Акцент будет выглядеть так",
"Use album art primary color": "Использовать цвет обложки", "Use album art primary color": "Подбирать акцент в цвет обложки",
"Warning: might be buggy": "Предупреждение: может быть ошибка", "Warning: might be buggy": "Осторожно, может вызвать баги",
"Mobile streaming": "Мобильная сеть", "Mobile streaming": "Воспроизведение в мобильной сети",
"Wifi streaming": "Wifi сеть", "Wifi streaming": "Воспроизведение по Wi-Fi",
"External downloads": "Внешние загрузки", "External downloads": "Скачанные треки",
"Content language": "Язык содержания", "Content language": "Язык контента",
"Not app language, used in headers. Now": "Используемый в заголовках. Сейчас", "Not app language, used in headers. Now":
"Используется в тегах.",
"Select language": "Выберите язык", "Select language": "Выберите язык",
"Content country": "Страна содержания", "Content country": "Страна контента",
"Country used in headers. Now": "Страна, используемая в заголовках. Сейчас", "Country used in headers. Now": "Также используется в тегах.",
"Log tracks": "Журнал треков", "Log tracks": "Отправлять статистику",
"Send track listen logs to Deezer, enable it for features like Flow to work properly": "Send track listen logs to Deezer, enable it for features like Flow to work properly":
"Отправьте журналы прослушивания треков в Deezer, включите его, чтобы такие функции, как Flow, работали правильно", "Отправлять статистику прослушивания. Необходимо для правильной работы рекомендаций",
"Offline mode": "Офлайн режим", "Offline mode": "Режим офлайн",
"Will be overwritten on start.": "Будет перезаписан при запуске.", "Will be overwritten on start.": "Можно слушать только кешированные треки. Работает до перезапуска.",
"Error logging in, check your internet connections.": "Error logging in, check your internet connections.":
"Ошибка при входе, проверьте свои интернет-соединения.", "Ошибка входа, проверьте соединение с Интернетом",
"Logging in...": "Происходит вход в систему...", "Logging in...": "Вход...",
"Download path": "Путь сохранения файлов", "Download path": "Папка загрузок",
"Downloads naming": "Название при скачивании", "Downloads naming": "Шаблон для названия",
"Downloaded tracks filename": "Имя файла загруженных треков", "Downloaded tracks filename": "Шаблон для названий загруженных треков",
"Valid variables are": "Допустимые переменные:", "Valid variables are": "Допустимые переменные:",
"Reset": "Сброс", "Reset": "Сброс",
"Clear": "Очистить", "Clear": "Очистить",
"Create folders for artist": "Создавайте папки для исполнителя", "Create folders for artist": "Создавать папки для исполнителей",
"Create folders for albums": "Создавайте папки для альбомов", "Create folders for albums": "Создавать папки для альбомов",
"Separate albums by discs": "Отдельные альбомы по дискам", "Separate albums by discs": "Разделять альбомы по дискам",
"Overwrite already downloaded files": "Перезаписать уже загруженные файлы", "Overwrite already downloaded files": "Перезаписывать существующие",
"Copy ARL": "Копировать ARL", "Copy ARL": "Скопировать токен (ARL)",
"Copy userToken/ARL Cookie for use in other apps.": "Copy userToken/ARL Cookie for use in other apps.":
"Копировать userToken/ARL Cookie для использования в других приложениях.", "Может быть полезно для использования в других приложениях. Не сообщайте токен никому!",
"Copied": "Скопировано", "Copied": "Скопировано",
"Log out": "Выйти", "Log out": "Выйти",
"Due to plugin incompatibility, login using browser is unavailable without restart.": "Due to plugin incompatibility, login using browser is unavailable without restart.":
"Из-за несовместимости плагинов вход через браузер без перезапуска невозможен.", "После авторизации/выхода через браузер требуется перезапуск.",
"(ARL ONLY) Continue": "(ARL ONLY) Продолжать", "(ARL ONLY) Continue": "(Вход по токену) Выйти",
"Log out & Exit": "Выйти и закрыть", "Log out & Exit": "Выйти и перезапустить",
"Pick-a-Path": "Выбери путь", "Pick-a-Path": "Выберите папку",
"Select storage": "Выберите хранилище", "Select storage": "Выбрерите хранилище",
"Go up": "Подниматься", "Go up": "На уровень вверх",
"Permission denied": "Доступ запрещен", "Permission denied": "Доступ запрещен",
"Language": "Язык приложения", "Language": "Язык",
"Language changed, please restart Freezer to apply!": "Язык изменен, перезапустите Freezer, чтобы применить!", "Language changed, please restart Freezer to apply!":
"Язык изменен, перезапустите приложения для применения",
"Importing...": "Импорт...", "Importing...": "Импорт...",
"Radio": "Радио" "Radio": "Радио",
"Flow": "Flow",
"Track is not available on Deezer!": "Трек недоступен на Deezer!",
"Failed to download track! Please restart.": "Ошибка заргузки.Попробуйте снова.",
//0.5.0 Strings:
"Storage permission denied!": "Доступ к хранилищу запрещен!",
"Failed": "Ошибка",
"Queued": "Добавлено в очередь",
//Updated in 0.5.1 - used in context of download:
"External": "Хранилище",
//0.5.0
"Restart failed downloads": "Перезапустить загрузки с ошибками",
"Clear failed": "Не удалось очистить",
"Download Settings": "Настройки загрузок",
"Create folder for playlist": "Создавать папки для плейлистов",
"Download .LRC lyrics": "Скачивать тексты .LRC",
"Proxy": "Настройки прокси",
"Not set": "Прокси не настроен",
"Search or paste URL": "Введите запрос или ссылку",
"History": "История",
//Updated 0.5.1
"Download threads": "Количество одновременных загрузок",
//0.5.0
"Lyrics unavailable, empty or failed to load!": "Ошибка получения текста!",
"About": "О приложении",
"Telegram Channel": "Канал в Telegram",
"To get latest releases": "Здесь можно скачать официальные обновления",
"Official chat": "Группа в Telegram",
"Telegram Group": "Свободное общение о приложении",
"Huge thanks to all the contributors! <3": "Большое спасибо всем участинкам <3",
"Edit playlist": "Изменить плейлист",
"Update": "Обновить",
"Playlist updated!": "Плейлист обновлен!",
"Downloads added!": "Загрузки добавлены!",
//0.5.1 Strings:
"Save cover file for every track": "Обложки для каждого трека отдельным файлом",
"Download Log": "Лог загрузок (технические данные)",
"Repository": "Репозиторий",
"Source code, report issues there.": "Исходный код, вопросы, предложения."
} }
}; };

231
lib/languages/tr_tr.dart Normal file
View File

@ -0,0 +1,231 @@
/*
Translated by: HoScHaKaL
*/
const language_tr_tr = {
"tr_tr": {
"Kebab": "Based",
"Home": "Anasayfa",
"Search": "Ara",
"Library": "Kütüphane",
"Offline mode, can't play flow or smart track lists.":
"Çevrimdışı mod, akış veya akıllı parça listelerini çalınamaz.",
"Added to library": "Kütüphaneye eklendi",
"Download": "İndir",
"Disk": "Disk",
"Offline": "Çevrimdışı",
"Top Tracks": "En iyi Parçalar",
"Show more tracks": "Daha fazla parça göster",
"Top": "En iyiler",
"Top Albums": "En iyi Albümler",
"Show all albums": "Tüm albümleri göster",
"Discography": "Diskografi",
"Default": "Varsayılan",
"Reverse": "Tersten",
"Alphabetic": "Alfabetik",
"Artist": "Sanatçı",
"Post processing...": "İşleniyor...",
"Done": "Bitti",
"Delete": "Sil",
"Are you sure you want to delete this download?":
"Bu indirmeyi silmek istediğinizden emin misiniz?",
"Cancel": "İptal",
"Downloads": "İndirilenler",
"Clear queue": "Sırayı temizle",
"This won't delete currently downloading item":
"Bu, şu anda indirilen öğeyi silemez",
"Are you sure you want to delete all queued downloads?":
"Sıradaki tüm indirmeleri silmek istediğinizden emin misiniz?",
"Clear downloads history": "İndirme geçmişini temizle",
"WARNING: This will only clear non-offline (external downloads)":
"UYARI: Bu yalnızca çevrimdışı olmayanları temizler (harici indirmeler)",
"Please check your connection and try again later...":
"Lütfen bağlantınızı kontrol edin ve daha sonra tekrar deneyin ...",
"Show more": "Daha fazla göster",
"Importer": "Importer",
"Currently supporting only Spotify, with 100 tracks limit":
"Şu anda 100 parça sınırıyla yalnızca Spotify'ı destekliyor",
"Due to API limitations": "API sınırlamaları nedeniyle",
"Enter your playlist link below": "Oynatma listesi bağlantınızı aşağıya girin",
"Error loading URL!": "URL yüklenirken hata oluştu!",
"Convert": "Dönüştür",
"Download only": "Sadece indir",
"Downloading is currently stopped, click here to resume.":
"İndirme durduruldu , devam etmek için tıklayın.",
"Tracks": "Parçalar",
"Albums": "Albümler",
"Artists": "Sanatçılar",
"Playlists": "Oynatma listeleri",
"Import": "İçe Aktar",
"Import playlists from Spotify": "Spotify'dan çalma listelerini içe aktarın",
"Statistics": "İstatistikler",
"Offline tracks": "Çevrimdışı parçalar",
"Offline albums": "Çevrimdışı albümler",
"Offline playlists": "Çevrimdışı oynatma listeleri",
"Offline size": "Çevrimdışı boyut",
"Free space": "Boş alan",
"Loved tracks": "Sevilen parçalar",
"Favorites": "Favoriler",
"All offline tracks": "Tüm çevrimdışı parçalar",
"Create new playlist": "Yeni oynatma listesi oluştur",
"Cannot create playlists in offline mode":
"Çevrimdışı modda oynatma listeleri oluşturulamaz",
"Error": "Hata",
"Error logging in! Please check your token and internet connection and try again.":
"Oturum açma hatası! Lütfen tokeninizi ve internet bağlantınızı kontrol edin ve tekrar deneyin.",
"Dismiss": "Reddet",
"Welcome to": "Hoşgeldiniz",
"Please login using your Deezer account.":
"Lütfen Deezer hesabınızı kullanarak giriş yapın.",
"Login using browser": "Tarayıcı kullanarak giriş yapın",
"Login using token": "Token kullanarak giriş yap",
"Enter ARL": "ARL girin",
"Token (ARL)": "Token (ARL)",
"Save": "Kaydet",
"If you don't have account, you can register on deezer.com for free.":
"Hesabınız yoksa deezer.com'a ücretsiz kayıt olabilirsiniz.",
"Open in browser": "Tarayıcıda aç",
"By using this app, you don't agree with the Deezer ToS":
"Bu uygulamayı kullanarak Deezer Hizmet Şartları'nı kabul etmiyorsunuz",
"Play next": "Sonrakini çal",
"Add to queue": "Sıraya ekle",
"Add track to favorites": "Favorilere parça ekle",
"Add to playlist": "Oynatma listesine ekle",
"Select playlist": "Oynatma listesi seçin",
"Track added to": "Parça şuraya eklendi",
"Remove from playlist": "Oynatma listesinden kaldır",
"Track removed from": "Parça şuradan kaldırıldı",
"Remove favorite": "Favoriyi kaldır",
"Track removed from library": "Parça kütüphaneden kaldırıldı",
"Go to": "Git",
"Make offline": "Çevrimdışı yap",
"Add to library": "Kütüphaneye ekle",
"Remove album": "Albümü kaldır",
"Album removed": "Albüm kaldırıldı",
"Remove from favorites": "Favorilerden çıkar",
"Artist removed from library": "Sanatçı kütüphaneden kaldırıldı",
"Add to favorites": "Favorilere ekle",
"Remove from library": "Kütüphaneden kaldır",
"Add playlist to library": "Oynatma listesini kütüphaneye ekleyin",
"Added playlist to library": "Kütüphaneye oynatma listesi eklendi",
"Make playlist offline": "Oynatma listesini çevrimdışı yapın",
"Download playlist": "Oynatma listesini indirin",
"Create playlist": "Oynatma listesi oluştur",
"Title": "Başlık",
"Description": "ıklama",
"Private": "Özel",
"Collaborative": "İşbirlikçi",
"Create": "Oluştur",
"Playlist created!": "Oynatma listesi oluşturuldu!",
"Playing from:": "Şuradan oynatılıyor:",
"Queue": "Kuyruk",
"Offline search": "Offline search",
"Search Results": "Arama Sonuçları",
"No results!": "Sonuç yok!",
"Show all tracks": "Tüm parçaları göster",
"Show all playlists": "Tüm oynatma listelerini göster",
"Settings": "Ayarlar",
"General": "Genel",
"Appearance": "Arayüz",
"Quality": "Kalite",
"Deezer": "Deezer",
"Theme": "Tema",
"Currently": "Şu anda",
"Select theme": "Tema seçin",
"Light (default)": "Light (Varsayılan)",
"Dark": "Dark",
"Black (AMOLED)": "Black (AMOLED)",
"Deezer (Dark)": "Deezer (Dark)",
"Primary color": "Ana renk",
"Selected color": "Seçilen renk",
"Use album art primary color": "Albüm resmi ana rengini kullan",
"Warning: might be buggy": "Uyarı: hatalı olabilir",
"Mobile streaming": "Mobil akış",
"Wifi streaming": "Wifi akışı",
"External downloads": "Harici indirmeler",
"Content language": "İçerik dili",
"Not app language, used in headers. Now":
"Not app language, used in headers. Now",
"Select language": "Dil seçin",
"Content country": "İçerik ülkesi",
"Country used in headers. Now": "Başlıklarda kullanılan ülke. Şimdi",
"Log tracks": "Log tracks",
"Send track listen logs to Deezer, enable it for features like Flow to work properly":
"Parça dinleme günlüklerini Deezer'a gönderin, Flow gibi özelliklerin düzgün çalışması için etkinleştirin",
"Offline mode": "Çevrimdışı mod",
"Will be overwritten on start.": "Başlangıçta üzerine yazılacak.",
"Error logging in, check your internet connections.":
"Giriş hatası, internet bağlantılarınızı kontrol edin.",
"Logging in...": "Giriş yapılıyor...",
"Download path": "İndirme yolu",
"Downloads naming": "İndirilenler adlandırma",
"Downloaded tracks filename": "İndirilen parçaların dosya adı",
"Valid variables are": "Geçerli değişkenler",
"Reset": "Sıfırla",
"Clear": "Temizle",
"Create folders for artist": "Sanatçı için klasörler oluşturun",
"Create folders for albums": "Albümler için klasörler oluşturun",
"Separate albums by discs": "Albümleri disklere göre ayırın",
"Overwrite already downloaded files": "Zaten indirilmiş dosyaların üzerine yaz",
"Copy ARL": "ARL kopyala",
"Copy userToken/ARL Cookie for use in other apps.":
"Diğer uygulamalarda kullanmak için userToken / ARL Cookie'yi kopyalayın.",
"Copied": "Kopyalandı",
"Log out": "Çıkış yap",
"Due to plugin incompatibility, login using browser is unavailable without restart.":
"Eklenti uyumsuzluğu nedeniyle, yeniden başlatmadan tarayıcı kullanarak oturum açılamaz.",
"(ARL ONLY) Continue": "(SADECE ARL) Devam et",
"Log out & Exit": "Çıkış yap & Çık",
"Pick-a-Path": "Konum seç",
"Select storage": "Depolama seç",
"Go up": "Yukarı git",
"Permission denied": "İzin reddedildi",
"Language": "Dil",
"Language changed, please restart Freezer to apply!":
"Dil değişti,değişiklik için Freezeri yeniden başlatın!",
"Importing...": "İçe aktarılıyor...",
"Radio": "Radyo",
"Flow": "Flow",
"Track is not available on Deezer!": "Parça Deezer'da mevcut değil!",
"Failed to download track! Please restart.": "Parça indirilemedi! Lütfen yeniden başlat.",
//0.5.0 Strings:
"Storage permission denied!": "Depolama izni reddedildi!",
"Failed": "Başarısız",
"Queued": "Sıraya alındı",
//Updated in 0.5.1 - used in context of download:
"External": "Storage",
//0.5.0
"Restart failed downloads": "Başarısız indirmeleri yeniden başlatın",
"Clear failed": "Silinemedi",
"Download Settings": "İndirme Ayarları",
"Create folder for playlist": "Oynatma listesi için klasör oluştur",
"Download .LRC lyrics": ".LRC şarkı sözlerini indir",
"Proxy": "Proxy",
"Not set": "Ayarlanmadı",
"Search or paste URL": "Arayın veya URL yapıştırın",
"History": "Geçmiş",
//Updated 0.5.1
"Download threads": "Eşzamanlı indirmeler",
//0.5.0
"Lyrics unavailable, empty or failed to load!": "Sözler mevcut değil, boş veya yüklenemedi!",
"About": "Hakkında",
"Telegram Channel": "Telegram Kanalı",
"To get latest releases": "En son sürümleri almak için",
"Official chat": "Resmi sohbet",
"Telegram Group": "Telegram Grubu",
"Huge thanks to all the contributors! <3": "Katkıda bulunanlara çok teşekkürler! <3",
"Edit playlist": "Oynatma listesini düzenleyin",
"Update": "Güncelle",
"Playlist updated!": "Oynatma listesi güncellendi!",
"Downloads added!": "İndirmeler eklendi!",
//0.5.1 Strings:
"Save cover file for every track": "Her parça için kapak dosyasını kaydedin",
"Download Log": "İndirme Kayıtları",
"Repository": "Depo",
"Source code, report issues there.": "Kaynak kodu, sorunları bildirin"
}
};

View File

@ -1,6 +1,5 @@
import 'dart:async';
import 'package:audio_service/audio_service.dart'; import 'package:audio_service/audio_service.dart';
import 'package:flutter/scheduler.dart';
import 'package:freezer/api/download.dart'; import 'package:freezer/api/download.dart';
import 'package:freezer/main.dart'; import 'package:freezer/main.dart';
import 'package:freezer/ui/cached_image.dart'; import 'package:freezer/ui/cached_image.dart';
@ -12,6 +11,7 @@ import 'package:flutter/material.dart';
import 'dart:io'; import 'dart:io';
import 'dart:convert'; import 'dart:convert';
import 'dart:async';
part 'settings.g.dart'; part 'settings.g.dart';
@ -62,8 +62,10 @@ class Settings {
bool trackCover; bool trackCover;
//Appearance //Appearance
@JsonKey(defaultValue: Themes.Light) @JsonKey(defaultValue: Themes.Dark)
Themes theme; Themes theme;
@JsonKey(defaultValue: false)
bool useSystemTheme;
//Colors //Colors
@JsonKey(toJson: _colorToJson, fromJson: _colorFromJson) @JsonKey(toJson: _colorToJson, fromJson: _colorFromJson)
@ -76,7 +78,6 @@ class Settings {
bool useArtColor = false; bool useArtColor = false;
StreamSubscription _useArtColorSub; StreamSubscription _useArtColorSub;
//Deezer //Deezer
@JsonKey(defaultValue: 'en') @JsonKey(defaultValue: 'en')
String deezerLanguage; String deezerLanguage;
@ -89,63 +90,18 @@ class Settings {
Settings({this.downloadPath, this.arl}); Settings({this.downloadPath, this.arl});
static const deezerBg = Color(0xFF1F1A16);
static const font = 'MabryPro';
ThemeData get themeData { ThemeData get themeData {
switch (theme??Themes.Light) { //System theme
case Themes.Light: if (useSystemTheme) {
return ThemeData( if (SchedulerBinding.instance.window.platformBrightness == Brightness.light) {
fontFamily: font, return _themeData[Themes.Light];
primaryColor: primaryColor, } else {
accentColor: primaryColor, if (theme == Themes.Light) return _themeData[Themes.Dark];
sliderTheme: _sliderTheme, return _themeData[theme];
toggleableActiveColor: primaryColor, }
bottomAppBarColor: Color(0xfff7f7f7)
);
case Themes.Dark:
return ThemeData(
fontFamily: font,
brightness: Brightness.dark,
primaryColor: primaryColor,
accentColor: primaryColor,
sliderTheme: _sliderTheme,
toggleableActiveColor: primaryColor,
);
case Themes.Deezer:
return ThemeData(
fontFamily: font,
brightness: Brightness.dark,
primaryColor: primaryColor,
accentColor: primaryColor,
sliderTheme: _sliderTheme,
toggleableActiveColor: primaryColor,
backgroundColor: deezerBg,
scaffoldBackgroundColor: deezerBg,
bottomAppBarColor: deezerBg,
dialogBackgroundColor: deezerBg,
bottomSheetTheme: BottomSheetThemeData(
backgroundColor: deezerBg
),
cardColor: deezerBg
);
case Themes.Black:
return ThemeData(
fontFamily: font,
brightness: Brightness.dark,
primaryColor: primaryColor,
accentColor: primaryColor,
backgroundColor: Colors.black,
scaffoldBackgroundColor: Colors.black,
bottomAppBarColor: Colors.black,
dialogBackgroundColor: Colors.black,
sliderTheme: _sliderTheme,
toggleableActiveColor: primaryColor,
bottomSheetTheme: BottomSheetThemeData(
backgroundColor: Colors.black
)
);
} }
return ThemeData(); //Theme
return _themeData[theme]??ThemeData();
} }
//JSON to forward into download service //JSON to forward into download service
@ -154,7 +110,8 @@ class Settings {
"downloadThreads": downloadThreads, "downloadThreads": downloadThreads,
"overwriteDownload": overwriteDownload, "overwriteDownload": overwriteDownload,
"downloadLyrics": downloadLyrics, "downloadLyrics": downloadLyrics,
"trackCover": trackCover "trackCover": trackCover,
"arl": arl
}; };
} }
@ -221,6 +178,57 @@ class Settings {
return 8; //default return 8; //default
} }
static const deezerBg = Color(0xFF1F1A16);
static const font = 'MabryPro';
Map<Themes, ThemeData> get _themeData => {
Themes.Light: ThemeData(
fontFamily: font,
primaryColor: primaryColor,
accentColor: primaryColor,
sliderTheme: _sliderTheme,
toggleableActiveColor: primaryColor,
bottomAppBarColor: Color(0xfff7f7f7)
),
Themes.Dark: ThemeData(
fontFamily: font,
brightness: Brightness.dark,
primaryColor: primaryColor,
accentColor: primaryColor,
sliderTheme: _sliderTheme,
toggleableActiveColor: primaryColor,
),
Themes.Deezer: ThemeData(
fontFamily: font,
brightness: Brightness.dark,
primaryColor: primaryColor,
accentColor: primaryColor,
sliderTheme: _sliderTheme,
toggleableActiveColor: primaryColor,
backgroundColor: deezerBg,
scaffoldBackgroundColor: deezerBg,
bottomAppBarColor: deezerBg,
dialogBackgroundColor: deezerBg,
bottomSheetTheme: BottomSheetThemeData(
backgroundColor: deezerBg
),
cardColor: deezerBg
),
Themes.Black: ThemeData(
fontFamily: font,
brightness: Brightness.dark,
primaryColor: primaryColor,
accentColor: primaryColor,
backgroundColor: Colors.black,
scaffoldBackgroundColor: Colors.black,
bottomAppBarColor: Colors.black,
dialogBackgroundColor: Colors.black,
sliderTheme: _sliderTheme,
toggleableActiveColor: primaryColor,
bottomSheetTheme: BottomSheetThemeData(
backgroundColor: Colors.black
))
};
Future<String> getPath() async => p.join((await getApplicationDocumentsDirectory()).path, 'settings.json'); Future<String> getPath() async => p.join((await getApplicationDocumentsDirectory()).path, 'settings.json');
//JSON //JSON

View File

@ -35,7 +35,8 @@ Settings _$SettingsFromJson(Map<String, dynamic> json) {
..downloadLyrics = json['downloadLyrics'] as bool ?? true ..downloadLyrics = json['downloadLyrics'] as bool ?? true
..trackCover = json['trackCover'] as bool ?? false ..trackCover = json['trackCover'] as bool ?? false
..theme = ..theme =
_$enumDecodeNullable(_$ThemesEnumMap, json['theme']) ?? Themes.Light _$enumDecodeNullable(_$ThemesEnumMap, json['theme']) ?? Themes.Dark
..useSystemTheme = json['useSystemTheme'] as bool ?? false
..primaryColor = Settings._colorFromJson(json['primaryColor'] as int) ..primaryColor = Settings._colorFromJson(json['primaryColor'] as int)
..useArtColor = json['useArtColor'] as bool ?? false ..useArtColor = json['useArtColor'] as bool ?? false
..deezerLanguage = json['deezerLanguage'] as String ?? 'en' ..deezerLanguage = json['deezerLanguage'] as String ?? 'en'
@ -62,6 +63,7 @@ Map<String, dynamic> _$SettingsToJson(Settings instance) => <String, dynamic>{
'downloadLyrics': instance.downloadLyrics, 'downloadLyrics': instance.downloadLyrics,
'trackCover': instance.trackCover, 'trackCover': instance.trackCover,
'theme': _$ThemesEnumMap[instance.theme], 'theme': _$ThemesEnumMap[instance.theme],
'useSystemTheme': instance.useSystemTheme,
'primaryColor': Settings._colorToJson(instance.primaryColor), 'primaryColor': Settings._colorToJson(instance.primaryColor),
'useArtColor': instance.useArtColor, 'useArtColor': instance.useArtColor,
'deezerLanguage': instance.deezerLanguage, 'deezerLanguage': instance.deezerLanguage,

View File

@ -11,7 +11,9 @@ import 'package:freezer/languages/hr_hr.dart';
import 'package:freezer/languages/it_it.dart'; import 'package:freezer/languages/it_it.dart';
import 'package:freezer/languages/ko_ko.dart'; import 'package:freezer/languages/ko_ko.dart';
import 'package:freezer/languages/pt_br.dart'; import 'package:freezer/languages/pt_br.dart';
import 'package:freezer/languages/ro_ro.dart';
import 'package:freezer/languages/ru_ru.dart'; import 'package:freezer/languages/ru_ru.dart';
import 'package:freezer/languages/tr_tr.dart';
import 'package:i18n_extension/i18n_extension.dart'; import 'package:i18n_extension/i18n_extension.dart';
const supportedLocales = [ const supportedLocales = [
@ -27,6 +29,8 @@ const supportedLocales = [
const Locale('ko', 'KO'), const Locale('ko', 'KO'),
const Locale('fr', 'FR'), const Locale('fr', 'FR'),
const Locale('he', 'IL'), const Locale('he', 'IL'),
const Locale('tr', 'TR'),
const Locale('ro', 'RO'),
const Locale('fil', 'PH') const Locale('fil', 'PH')
]; ];
@ -34,7 +38,7 @@ extension Localization on String {
static var _t = Translations.byLocale("en_US") + static var _t = Translations.byLocale("en_US") +
language_en_us + language_ar_ar + language_pt_br + language_it_it + language_de_de + language_ru_ru + language_en_us + language_ar_ar + language_pt_br + language_it_it + language_de_de + language_ru_ru +
language_fil_ph + language_es_es + language_el_gr + language_hr_hr + language_ko_ko + language_fr_fr + language_fil_ph + language_es_es + language_el_gr + language_hr_hr + language_ko_ko + language_fr_fr +
language_he_il; language_he_il + language_tr_tr + language_ro_ro;
String get i18n => localize(this, _t); String get i18n => localize(this, _t);
} }

View File

@ -289,7 +289,7 @@ class DownloadTile extends StatelessWidget {
ListTile( ListTile(
title: Text(download.title), title: Text(download.title),
leading: CachedImage(url: download.image), leading: CachedImage(url: download.image),
subtitle: Text(subtitle()), subtitle: Text(subtitle(), maxLines: 1, overflow: TextOverflow.ellipsis),
trailing: trailing(), trailing: trailing(),
onTap: () => onClick(context), onTap: () => onClick(context),
), ),

View File

@ -239,7 +239,7 @@ class LoginBrowser extends StatelessWidget {
onLoadStart: (InAppWebViewController controller, String url) async { onLoadStart: (InAppWebViewController controller, String url) async {
//Offers URL //Offers URL
if (url.contains('/offers')) { if (!url.contains('/login') && !url.contains('/register')) {
controller.evaluateJavascript(source: 'window.location.href = "/open_app"'); controller.evaluateJavascript(source: 'window.location.href = "/open_app"');
} }

View File

@ -44,8 +44,9 @@ class _SettingsScreenState extends State<SettingsScreen> {
List<Map<String, String>> _l = supportedLocales.map<Map<String, String>>((l) { List<Map<String, String>> _l = supportedLocales.map<Map<String, String>>((l) {
Map _lang = defaultLanguagesList.firstWhere((lang) => lang['isoCode'] == l.languageCode); Map _lang = defaultLanguagesList.firstWhere((lang) => lang['isoCode'] == l.languageCode);
return { return {
'name': _lang['name'] + ' (${l.toString()})', 'name': _lang['name'],
'isoCode': _lang['isoCode'] 'isoCode': _lang['isoCode'],
'locale': l.toString()
}; };
}).toList(); }).toList();
return _l; return _l;
@ -101,33 +102,37 @@ class _SettingsScreenState extends State<SettingsScreen> {
onTap: () { onTap: () {
showDialog( showDialog(
context: context, context: context,
builder: (context) => LanguagePickerDialog( builder: (context) => SimpleDialog(
titlePadding: EdgeInsets.all(8.0),
title: Text('Select language'.i18n), title: Text('Select language'.i18n),
isSearchable: false, children: List.generate(_languages().length, (int i) {
languagesList: _languages(), Map l = _languages()[i];
onValuePicked: (Language l) async { return ListTile(
setState(() { title: Text(l['name']),
Locale locale = supportedLocales.firstWhere((_l) => _l.languageCode == l.isoCode); subtitle: Text(l['locale']),
settings.language = locale.toString(); onTap: () async {
}); setState(() => settings.language = l['locale']);
await settings.save(); await settings.save();
showDialog( showDialog(
context: context, context: context,
builder: (context) { builder: (context) {
return AlertDialog( return AlertDialog(
title: Text('Language'.i18n), title: Text('Language'.i18n),
content: Text('Language changed, please restart Freezer to apply!'.i18n), content: Text('Language changed, please restart Freezer to apply!'.i18n),
actions: [ actions: [
FlatButton( FlatButton(
child: Text('OK'), child: Text('OK'),
onPressed: () => Navigator.of(context).pop(), onPressed: () {
) Navigator.of(context).pop();
], Navigator.of(context).pop();
},
)
],
);
}
); );
} },
); );
}, })
) )
); );
}, },
@ -173,7 +178,7 @@ class _AppearanceSettingsState extends State<AppearanceSettings> {
title: Text('Select theme'.i18n), title: Text('Select theme'.i18n),
children: <Widget>[ children: <Widget>[
SimpleDialogOption( SimpleDialogOption(
child: Text('Light (default)'.i18n), child: Text('Light'.i18n),
onPressed: () { onPressed: () {
setState(() => settings.theme = Themes.Light); setState(() => settings.theme = Themes.Light);
settings.save(); settings.save();
@ -214,6 +219,22 @@ class _AppearanceSettingsState extends State<AppearanceSettings> {
); );
}, },
), ),
ListTile(
title: Text('Use system theme'.i18n),
leading: Container(
width: 30.0,
child: Checkbox(
value: settings.useSystemTheme,
onChanged: (bool v) async {
setState(() {
settings.useSystemTheme = v;
});
updateTheme();
await settings.save();
},
),
),
),
ListTile( ListTile(
title: Text('Primary color'.i18n), title: Text('Primary color'.i18n),
leading: Icon(Icons.format_paint), leading: Icon(Icons.format_paint),
@ -1033,14 +1054,16 @@ class _CreditsScreenState extends State<CreditsScreen> {
['Markus', 'German'], ['Markus', 'German'],
['Andrea', 'Italian'], ['Andrea', 'Italian'],
['Diego Hiro', 'Portuguese'], ['Diego Hiro', 'Portuguese'],
['Annexhack', 'Russian'], ['Orfej', 'Russian'],
['Chino Pacia', 'Filipino'], ['Chino Pacia', 'Filipino'],
['ArcherDelta & PetFix', 'Spanish'], ['ArcherDelta & PetFix', 'Spanish'],
['Shazzaam', 'Croatian'], ['Shazzaam', 'Croatian'],
['VIRGIN_KLM', 'Greek'], ['VIRGIN_KLM', 'Greek'],
['koreezzz', 'Korean'], ['koreezzz', 'Korean'],
['Fwwwwwwwwwweze', 'French'], ['Fwwwwwwwwwweze', 'French'],
['kobyrevah', 'Hebrew'] ['kobyrevah', 'Hebrew'],
['HoScHaKaL', 'Turkish'],
['MicroMihai', 'Romanian']
]; ];
@override @override

View File

@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at # Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 0.5.1+1 version: 0.5.2+1
environment: environment:
sdk: ">=2.8.0 <3.0.0" sdk: ">=2.8.0 <3.0.0"