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
Fwwwwwwwwwweze: French
kobyrevah: Hebrew
MicroMihai: Romanian
HoScHaKaL: Turkish
### just_audio, audio_service
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 {
DownloadLog logger;
String token;
String arl;
String sid;
boolean authorized = false;
boolean authorizing = false;
//Initialize for logging
void init(DownloadLog logger) {
void init(DownloadLog logger, String arl) {
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
@ -59,11 +79,18 @@ public class Deezer {
return sid;
}
//Same as gw_light API, but doesn't need authentication
public static JSONObject callMobileAPI(String method, String params) throws Exception{
String sid = Deezer.getSidCookie();
public JSONObject callGWAPI(String method, String params) throws Exception {
if (sid == null)
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();
connection.setConnectTimeout(20000);
connection.setDoOutput(true);
@ -73,6 +100,8 @@ public class Deezer {
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Accept", "*/*");
connection.setRequestProperty("Content-Length", Integer.toString(params.getBytes(StandardCharsets.UTF_8).length));
String cookies = "arl=" + arl + "; sid=" + sid;
connection.setRequestProperty("Cookie", cookies);
//Write body
DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
@ -87,9 +116,26 @@ public class Deezer {
//Parse JSON
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;
}
//api.deezer.com/$method/$param
public static JSONObject callPublicAPI(String method, String param) throws Exception {
URL url = new URL("https://api.deezer.com/" + method + "/" + param);
@ -267,7 +313,7 @@ public class Deezer {
}
//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);
//Load file
AudioFile f = AudioFileIO.read(new File(path));
@ -281,21 +327,38 @@ public class Deezer {
tag.setField(FieldKey.TITLE, publicTrack.getString("title"));
tag.setField(FieldKey.ALBUM, publicTrack.getJSONObject("album").getString("title"));
//Artist
String artists = "";
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.DISC_NO, Integer.toString(publicTrack.getInt("disk_number")));
tag.setField(FieldKey.ALBUM_ARTIST, publicAlbum.getJSONObject("artist").getString("name"));
tag.setField(FieldKey.YEAR, publicTrack.getString("release_date").substring(0, 4));
tag.setField(FieldKey.BPM, Integer.toString((int)publicTrack.getDouble("bpm")));
tag.setField(FieldKey.RECORD_LABEL, publicAlbum.getString("label"));
//Genres
for (int i=0; i<publicAlbum.getJSONObject("genres").getJSONArray("data").length(); i++) {
String genre = publicAlbum.getJSONObject("genres").getJSONArray("data").getJSONObject(0).getString("name");
tag.addField(FieldKey.GENRE, genre);
tag.setField(FieldKey.ISRC, publicTrack.getString("isrc"));
tag.setField(FieldKey.BARCODE, publicAlbum.getString("upc"));
//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);
boolean addCover = (coverFile.exists() && coverFile.length() > 0);

View File

@ -25,11 +25,13 @@ import org.json.JSONObject;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.text.DecimalFormat;
@ -83,7 +85,7 @@ public class DownloadService extends Service {
//Setup logger, deezer api
logger.open(context);
deezer.init(logger);
deezer.init(logger, "");
//Get DB
DownloadsDatabase dbHelper = new DownloadsDatabase(getApplicationContext());
@ -215,7 +217,9 @@ public class DownloadService extends Service {
updating = true;
while (updateRequests.size() > 0) {
updateQueue();
updateRequests.remove(0);
//Because threading
if (updateRequests.size() > 0)
updateRequests.remove(0);
}
}
updating = false;
@ -280,6 +284,49 @@ public class DownloadService extends Service {
//Set state
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
int newQuality;
try {
@ -300,18 +347,6 @@ public class DownloadService extends Service {
download.quality = newQuality;
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
try {
outFile = new File(Deezer.generateFilename(download.path, trackJson, albumJson, newQuality));
@ -422,21 +457,29 @@ public class DownloadService extends Service {
//Create dirs and copy
parentDir.mkdirs();
if (!tmpFile.renameTo(outFile)) {
boolean error = true;
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Files.move(tmpFile.toPath(), outFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
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) {
//Clean
try {
outFile.delete();
tmpFile.delete();
} catch (Exception ignored) {}
//Log & Exit
logger.error("Error moving file! " + outFile.getPath() + ", " + e.toString(), download);
download.state = Download.DownloadState.ERROR;
exit();
return;
}
if (error) {
logger.error("Error moving file! " + outFile.getPath(), download);
e.printStackTrace();
download.state = Download.DownloadState.ERROR;
exit();
return;
@ -473,13 +516,28 @@ public class DownloadService extends Service {
} catch (Exception e) {
logger.error("Error downloading cover! " + e.toString(), download);
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
try {
Deezer.tagTrack(outFile.getPath(), trackJson, albumJson, coverFile.getPath());
Deezer.tagTrack(outFile.getPath(), trackJson, albumJson, coverFile.getPath(), lyricsData);
} catch (Exception e) {
Log.e("ERR", "Tagging error!");
e.printStackTrace();
@ -491,21 +549,6 @@ public class DownloadService extends Service {
//Album cover
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;
@ -521,7 +564,7 @@ public class DownloadService extends Service {
File coverFile = new File(parentDir, "cover.jpg");
if (coverFile.exists()) return;
//Don't download if doesn't have album
if (!download.path.contains("/%album%/")) return;
if (!download.path.matches(".*/%album%.*/.*")) return;
try {
//Create to lock
@ -664,6 +707,7 @@ public class DownloadService extends Service {
//Load settings
case SERVICE_SETTINGS_UPDATE:
settings = DownloadSettings.fromBundle(msg.getData());
deezer.arl = settings.arl;
break;
//Stop downloads
@ -760,17 +804,19 @@ public class DownloadService extends Service {
boolean overwriteDownload;
boolean downloadLyrics;
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.overwriteDownload = overwriteDownload;
this.downloadLyrics = downloadLyrics;
this.trackCover = trackCover;
this.arl = arl;
}
//Parse settings from bundle sent from UI
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("downloadLyrics", (boolean)call.argument("downloadLyrics"));
bundle.putBoolean("trackCover", (boolean)call.argument("trackCover"));
bundle.putString("arl", (String)call.argument("arl"));
sendMessage(DownloadService.SERVICE_SETTINGS_UPDATE, bundle);
result.success(null);

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

View File

@ -428,7 +428,7 @@ class DownloadManager {
//Album folder / with disk number
if (settings.albumFolder) {
if (settings.albumDiscFolder) {
path = p.join(path, '%album%' + ' - Disk ' + track.diskNumber.toString());
path = p.join(path, '%album%' + ' - Disk ' + (track.diskNumber??null).toString());
} else {
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');
Future start() async {
//Subscribe to custom events
//Subscribe to custom events
_customEventSubscription = AudioService.customEventStream.listen((event) async {
if (!(event is Map)) return;
if (event['action'] == 'onLoad') {
@ -78,11 +78,10 @@ class PlayerHelper {
}
});
_mediaItemSubscription = AudioService.currentMediaItemStream.listen((event) {
if (event == null) return;
//Save queue
AudioService.customAction('saveQueue');
//Add to history
if (event == null) return;
if (cache.history == null) cache.history = [];
if (cache.history.length > 0 && cache.history.last.id == event.id) return;
cache.history.add(Track.fromMediaItem(event));
@ -90,21 +89,24 @@ class PlayerHelper {
});
//Start audio_service
startService();
await startService();
}
Future startService() async {
if (AudioService.running) return;
await AudioService.start(
backgroundTaskEntrypoint: backgroundTaskEntrypoint,
androidEnableQueue: true,
androidStopForegroundOnPause: false,
androidNotificationOngoing: false,
androidNotificationClickStartsActivity: false,
androidNotificationChannelDescription: 'Freezer',
androidNotificationChannelName: 'Freezer',
androidNotificationIcon: 'drawable/ic_logo',
);
if (AudioService.running && AudioService.connected) return;
if (!AudioService.connected)
await AudioService.connect();
if (!AudioService.running)
await AudioService.start(
backgroundTaskEntrypoint: backgroundTaskEntrypoint,
androidEnableQueue: true,
androidStopForegroundOnPause: false,
androidNotificationOngoing: false,
androidNotificationClickStartsActivity: true,
androidNotificationChannelDescription: 'Freezer',
androidNotificationChannelName: 'Freezer',
androidNotificationIcon: 'drawable/ic_logo',
);
}
Future toggleShuffle() async {

View File

@ -167,8 +167,8 @@ const language_ar_ar = {
"Language changed, please restart Freezer to apply!": "تم تغيير اللغة، الرجاء إعادة تشغيل فريزر لتطبيق!",
"Importing...": "جار الاستيراد...",
"Radio": "راديو",
//0.5.0 Strings:
//0.5.0 Strings:
"Storage permission denied!": "رفض إذن التخزين!",
"Failed": "فشل",
"Queued": "في قائمة الانتظار",
@ -198,6 +198,10 @@ const language_ar_ar = {
"Download Log": "سجل التنزيل",
"Repository": "Repository",
"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",
"Search": "Buscar",
"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",
"Download": "Descargar",
"Disk": "Disco",
@ -27,30 +28,39 @@ const language_es_es = {
"Post processing...": "Post procesamiento...",
"Done": "Hecho",
"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",
"Downloads": "Descargas",
"Clear queue": "Limpiar la cola",
"This won't delete currently downloading item": "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?",
"This won't delete currently downloading item":
"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",
"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).",
"Please check your connection and try again later...": "Por favor, compruebe su conexión y vuelva a intentarlo más tarde...",
"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).",
"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",
"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",
"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!",
"Convert": "Convertir",
"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",
"Albums": "Álbumes",
"Artists": "Artistas",
"Playlists": "Listas de reproducción",
"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",
"Offline tracks": "Pistas sin conexión",
"Offline albums": "Álbumes sin conexión",
@ -61,20 +71,25 @@ const language_es_es = {
"Favorites": "Favoritas",
"All offline tracks": "Todas las pistas fuera de línea",
"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 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",
"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 token": "Ingresar usando token",
"Enter ARL": "Ingrese ARL",
"Token (ARL)": "Token (ARL)",
"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",
"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",
"Add to queue": "Añadir a la cola",
"Add track to favorites": "Agregar pista a favoritos",
@ -95,7 +110,8 @@ const language_es_es = {
"Add to favorites": "Agregar a favoritos",
"Remove from library": "Eliminar de 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",
"Download playlist": "Descargar lista de reproducción",
"Create playlist": "Crear lista de reproducción",
@ -126,21 +142,25 @@ const language_es_es = {
"Deezer (Dark)": "Deezer (oscuro)",
"Primary color": "Color primario",
"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",
"Mobile streaming": "Transmisión móvil",
"Wifi streaming": "Transmisión WiFi",
"External downloads": "Descargas externas",
"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",
"Content country": "País del contenido",
"Country used in headers. Now": "País utilizado en los encabezados. Ahora",
"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",
"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...",
"Download path": "Ruta 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 albums": "Crear carpetas por álbumes",
"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 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",
"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)",
"Log out & Exit": "Cerrar sesión y salir",
"Pick-a-Path": "Escoja una ruta",
@ -164,13 +187,13 @@ const language_es_es = {
"Go up": "Subir",
"Permission denied": "Permiso denegado",
"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...",
"Radio": "Radio",
"Flow": "Flow",
//0.5.0 Strings:
"Storage permission denied!": "Permiso de almacenamiento denegado!",
"Failed": "Fallido",
"Queued": "Puesto en cola",
@ -185,20 +208,28 @@ const language_es_es = {
"Search or paste URL": "Buscar o pegar URL",
"History": "Historial",
"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",
"Telegram Channel": "Canal de Telegram",
"To get latest releases": "Para obtener los últimos lanzamientos",
"Official chat": "Chat oficial",
"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",
"Update": "Actualizar",
"Playlist updated!": "Lista de reproducción actualizada!",
"Downloads added!": "Descargas agregadas!"
"Save cover file for every track": "Guarde el archivo de portada para cada pista",
"Downloads added!": "Descargas agregadas!",
"Save cover file for every track":
"Guarde el archivo de portada para cada pista",
"Download Log": "Registro de Descarga",
"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",
"Library": "Libreria",
"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",
"Download": "Scarica",
"Disk": "Disco",
@ -29,31 +29,31 @@ const language_it_it = {
"Done": "Fatto",
"Delete": "Cancellare",
"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",
"Downloads": "Download",
"Clear queue": "Pulisci la coda",
"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?":
"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",
"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...":
"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ù",
"Importer": "Importa",
"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",
"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!",
"Convert": "Converti",
"Download only": "Solo Download",
"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",
"Albums": "Album",
"Artists": "Artisti",
@ -71,24 +71,24 @@ const language_it_it = {
"All offline tracks": "Tutte i brani offline",
"Create new playlist": "Crea una nuova playlist",
"Cannot create playlists in offline mode":
"Impossibile creare playlist in modalità offline",
"Impossibile creare playlist in modalità offline",
"Error": "Errore",
"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",
"Welcome to": "Benvenuto su",
"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 token": "Login utilizzando il token",
"Enter ARL": "Inserisci l'ARL",
"Token (ARL)": "Token (ARL)",
"Save": "Salva",
"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",
"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",
"Add to queue": "Aggiungi alla coda",
"Add track to favorites": "Aggiungi il brano ai preferiti",
@ -141,24 +141,24 @@ const language_it_it = {
"Primary color": "Colore Principale",
"Selected color": "Colore Selezionato",
"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",
"Mobile streaming": "Streaming con dati",
"Wifi streaming": "Streaming con WiFi",
"External downloads": "Download esterni",
"Content language": "Lingua dei contenuti",
"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",
"Content country": "Contenuto dal Paese",
"Country used in headers. Now": "Paese contenuto negli header. Ora",
"Log tracks": "Log delle tracce",
"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",
"Will be overwritten on start.": "Sarà sovrascritto all'avvio.",
"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...",
"Download path": "Percorso di download",
"Downloads naming": "Denominazione dei download",
@ -172,11 +172,11 @@ const language_it_it = {
"Overwrite already downloaded files": "Sovrascrivi i file già scaricati",
"Copy ARL": "Copia ARL",
"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",
"Log out": "Disconnettiti",
"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",
"Log out & Exit": "Disconnettiti e Esci",
"Pick-a-Path": "Scegli un percorso",
@ -185,14 +185,12 @@ const language_it_it = {
"Permission denied": "Permesso negato",
"Language": "Lingua",
"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...",
"Radio": "Radio",
"Flow": "Flow",
//0.5.0 Strings:
"Storage permission denied!": "Autorizzazione di archiviazione negata!",
"Failed": "Fallito",
"Queued": "In coda",
@ -207,22 +205,28 @@ const language_it_it = {
"Search or paste URL": "Cerca o incolla l'URL",
"History": "Storia",
"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",
"Telegram Channel": "Canale Telegram",
"To get latest releases": "Per ottenere le ultime versioni",
"Official chat": "Chat ufficiale",
"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",
"Update": "Aggiorna",
"Playlist updated!": "Playlist aggiornata!",
"Downloads added!": "Download aggiunti!"
"Save cover file for every track": "Salva la copertina dell'album per ogni traccia",
"Downloads added!": "Download aggiunti!",
"Save cover file for every track":
"Salva la copertina dell'album per ogni traccia",
"Download Log": "Download Log",
"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 = {
"ru_ru": {
"Home": "Главная",
"Search": "Поиск",
"Library": "Библиотека",
"Offline mode, can't play flow or smart track lists.": "Офлайн режим, нельзя воспроизводить потоки или умные списки треков.",
"Added to library": "Добавить в библиотеку",
"Library": "Избранное",
"Offline mode, can't play flow or smart track lists.":
"Режим офлайн. Невозможно воспроизвести персональные подборки",
"Added to library": "Добавлено в любимые треки",
"Download": "Скачать",
"Disk": "Диск",
"Offline": "Скачанные треки",
"Top Tracks": "Лучшие треки",
"Show more tracks": "Показать больше треков",
"Top": "Top",
"Offline": "Загрузить в кеш",
"Top Tracks": "Популярные треки",
"Show more tracks": "Показать все",
"Top": "Лучшее",
"Top Albums": "Лучшие альбомы",
"Show all albums": "Показать все альбомы",
"Show all albums": "Показать все",
"Discography": "Дискография",
"Default": "По умолчанию",
"Reverse": "Обратный",
"Reverse": "В обратном порядке",
"Alphabetic": "По алфавиту",
"Artist": "Исполнитель",
"Post processing...": "Постобработка...",
"Post processing...": "Делаем магию...",
"Done": "Готово",
"Delete": "Удалить",
"Are you sure you want to delete this download?":
@ -32,152 +32,198 @@ const language_ru_ru = {
"Cancel": "Отмена",
"Downloads": "Загрузки",
"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?":
"Вы действительно хотите удалить все загрузки в очереди?",
"Вы действительно хотите удалить все запланированные загрузки?",
"Clear downloads history": "Очистить историю загрузок",
"WARNING: This will only clear non-offline (external downloads)":
"ВНИМАНИЕ: Это очистит только не офлайн(external downloads)",
"Внимание! Это удалит только загрузки (не кеш)",
"Please check your connection and try again later...":
"Пожалуйста, проверьте ваше соединение и повторите попытку позже...",
"Проверьте соединение с Интернетом...",
"Show more": "Показать больше",
"Importer": "Импортер",
"Currently supporting only Spotify, with 100 tracks limit": "В настоящее время поддерживается только Spotify, с ограничением 100 треков",
"Due to API limitations": "Из-за ограничений API",
"Enter your playlist link below": "Введите ссылку на свой плейлист ниже",
"Error loading URL!": "Ошибка загрузки URL!",
"Convert": "Перерабатывать",
"Download only": "Только скачанные",
"Downloading is currently stopped, click here to resume.": "В настоящее время загрузка остановлена, нажмите здесь, чтобы возобновить.",
"Importer": "Импорт плейлистов",
"Currently supporting only Spotify, with 100 tracks limit":
"В настоящий момент поддерживается только Spotify",
"Due to API limitations": "Можно импортировать не более 100 треков за раз",
"Enter your playlist link below": "Ссылка на плейлист",
"Error loading URL!": "Ошибка загрузки!",
"Convert": "Импортировать",
"Download only": "Скачать",
"Downloading is currently stopped, click here to resume.":
"Загрузка приостановлена, нажмите, чтобы продолжить.",
"Tracks": "Треки",
"Albums": "Альбомы",
"Artists": "Артисты",
"Playlists": "Плейлисты",
"Import": "Импорт",
"Import playlists from Spotify": "Импортировать плейлисты из Spotify",
"Statistics": "Статистика",
"Offline tracks": "Автономные треки",
"Offline albums": "Автономные альбомы",
"Offline playlists": "Офлайн-плейлисты",
"Offline size": "Автономный размер",
"Free space": "Свободное место",
"Playlists": "Playlists",
"Import": "Импорт плейлистов",
"Import playlists from Spotify": "В настоящий момент поддерживается только Spotify",
"Statistics": "Размер кеша",
"Offline tracks": "Треки в кеше:",
"Offline albums": "Альбомы в кеше:",
"Offline playlists": "Плейлисты в кеше:",
"Offline size": "Размер кеша:",
"Free space": "Свободно:",
"Loved tracks": "Любимые треки",
"Favorites": "Избранное",
"All offline tracks": "Скачанные треки",
"Create new playlist": "Создать новый плейлист",
"Cannot create playlists in offline mode": "Невозможно создавать плейлисты в автономном режиме",
"All offline tracks": "Все треки в кеше",
"Create new playlist": "Новый плейлист",
"Cannot create playlists in offline mode":
"Нельзя создавать плейлисты в режиме офлайн",
"Error": "Ошибка",
"Error logging in! Please check your token and internet connection and try again.":
"Ошибка входа! Проверьте свой токен и подключение к Интернету и повторите попытку.",
"Dismiss": "Отклонить",
"Ошибка входа. Проверьте корректность ARL и соединение с Интернетом",
"Dismiss": "Я понял",
"Welcome to": "Добро пожаловать в",
"Please login using your Deezer account.":
"Пожалуйста, войдите, используя свою учетную запись Deezer.",
"Войдите, используя свой аккаунт Deezer.",
"Login using browser": "Войти через браузер",
"Login using token": "Войти с помощью токена",
"Login using token": "Войти по токену (ARL)",
"Enter ARL": "Введите ARL",
"Token (ARL)": "Токен (ARL)",
"Save": "Сохранить",
"If you don't have account, you can register on deezer.com for free.":
"Если у вас нет учетной записи, вы можете бесплатно зарегистрироваться на deezer.com.",
"Open in browser": "Открыть в браузере",
"Вы можете создать аккаунт на deezer.com. Это бесплатно.",
"Open in browser": "Зарегестрироваться",
"By using this app, you don't agree with the Deezer ToS":
"Используя это приложение, вы не соглашаетесь с Условиями использования Deezer.",
"Play next": "Следующая песня",
"Play next": "Играть следующим",
"Add to queue": "Добавить в очередь",
"Add track to favorites": "Добавить в избранное",
"Add track to favorites": "Добавить в любимые треки",
"Add to playlist": "Добавить в плейлист",
"Select playlist": "Выбрать плейлист",
"Select playlist": "Выберите плейлист",
"Track added to": "Трек добавлен в",
"Remove from playlist": "Удалить из плейлиста",
"Track removed from": "Трек удален из",
"Remove favorite": "Удалить избранное",
"Track removed from library": "Трек удален из библиотеки",
"Track removed from": "Трек удалён из",
"Remove favorite": "Удалить из любимых треков",
"Track removed from library": "Трек удален из Избранного",
"Go to": "Перейти к",
"Make offline": "Сделать офлайн",
"Add to library": "Добавить в библиотеку",
"Make offline": "Загрузить в кеш",
"Add to library": "Добавить в Избранное",
"Remove album": "Удалить альбом",
"Album removed": "Альбом удален",
"Remove from favorites": "Удалить из Избранного",
"Artist removed from library": "Артист удален из библиотеки",
"Add to favorites": "Добавить в избранное",
"Remove from library": "Удалить из библиотеки",
"Add playlist to library": "Добавить плейлист в библиотеку",
"Added playlist to library": "Добавлен плейлист в библиотеку",
"Make playlist offline": "Сделать плейлист офлайн",
"Artist removed from library": "Артист удалён",
"Add to favorites": "Добавить в Избранное",
"Remove from library": "Удалить из Избранного",
"Add playlist to library": "Добавить плейлист в Избранное",
"Added playlist to library": "Плейлист добавлен в Избранное",
"Make playlist offline": "Загрузить плейлист в кеш",
"Download playlist": "Скачать плейлист",
"Create playlist": "Создать плейлист",
"Title": "Название",
"Description": "Описание",
"Private": "Частный",
"Collaborative": "Совместная",
"Private": "Скрытый",
"Collaborative": "Общего пользования",
"Create": "Создать",
"Playlist created!": "Плейлист создан!",
"Playing from:": "Играя с:",
"Playing from:": "Сейчас играет:",
"Queue": "Очередь",
"Offline search": "Оффлайн поиск",
"Offline search": "Поиск по кешу",
"Search Results": "Результаты поиска",
"No results!": "Нет результатов!",
"No results!": "Ничего не найдено!",
"Show all tracks": "Показать все треки",
"Show all playlists": "Показать все плейлисты",
"Settings": "Настройки",
"General": "Общее",
"Appearance": "Интерфейс",
"Settings": "Настрокий",
"General": "Управление аккаунтом",
"Appearance": "Внешний вид",
"Quality": "Качество звука",
"Deezer": "Deezer",
"Deezer": "Взаимодействие с Deezer",
"Theme": "Тема",
"Currently": "Выбрана тема",
"Currently": "Используется:",
"Select theme": "Выберите тему",
"Light (default)": "Светлая (По умолчанию)",
"Dark": "Dark (Темная тема)",
"Dark": "Темная",
"Black (AMOLED)": "Черная (AMOLED)",
"Deezer (Dark)": "Deezer (Dark)",
"Primary color": "Основной цвет",
"Selected color": "Выбранный цвет",
"Use album art primary color": "Использовать цвет обложки",
"Warning: might be buggy": "Предупреждение: может быть ошибка",
"Mobile streaming": "Мобильная сеть",
"Wifi streaming": "Wifi сеть",
"External downloads": "Внешние загрузки",
"Content language": "Язык содержания",
"Not app language, used in headers. Now": "Используемый в заголовках. Сейчас",
"Deezer (Dark)": "Deezer (Темная)",
"Primary color": "Цвет акцента",
"Selected color": "Акцент будет выглядеть так",
"Use album art primary color": "Подбирать акцент в цвет обложки",
"Warning: might be buggy": "Осторожно, может вызвать баги",
"Mobile streaming": "Воспроизведение в мобильной сети",
"Wifi streaming": "Воспроизведение по Wi-Fi",
"External downloads": "Скачанные треки",
"Content language": "Язык контента",
"Not app language, used in headers. Now":
"Используется в тегах.",
"Select language": "Выберите язык",
"Content country": "Страна содержания",
"Country used in headers. Now": "Страна, используемая в заголовках. Сейчас",
"Log tracks": "Журнал треков",
"Content country": "Страна контента",
"Country used in headers. Now": "Также используется в тегах.",
"Log tracks": "Отправлять статистику",
"Send track listen logs to Deezer, enable it for features like Flow to work properly":
"Отправьте журналы прослушивания треков в Deezer, включите его, чтобы такие функции, как Flow, работали правильно",
"Offline mode": "Офлайн режим",
"Will be overwritten on start.": "Будет перезаписан при запуске.",
"Отправлять статистику прослушивания. Необходимо для правильной работы рекомендаций",
"Offline mode": "Режим офлайн",
"Will be overwritten on start.": "Можно слушать только кешированные треки. Работает до перезапуска.",
"Error logging in, check your internet connections.":
"Ошибка при входе, проверьте свои интернет-соединения.",
"Logging in...": "Происходит вход в систему...",
"Download path": "Путь сохранения файлов",
"Downloads naming": "Название при скачивании",
"Downloaded tracks filename": "Имя файла загруженных треков",
"Ошибка входа, проверьте соединение с Интернетом",
"Logging in...": "Вход...",
"Download path": "Папка загрузок",
"Downloads naming": "Шаблон для названия",
"Downloaded tracks filename": "Шаблон для названий загруженных треков",
"Valid variables are": "Допустимые переменные:",
"Reset": "Сброс",
"Clear": "Очистить",
"Create folders for artist": "Создавайте папки для исполнителя",
"Create folders for albums": "Создавайте папки для альбомов",
"Separate albums by discs": "Отдельные альбомы по дискам",
"Overwrite already downloaded files": "Перезаписать уже загруженные файлы",
"Copy ARL": "Копировать ARL",
"Create folders for artist": "Создавать папки для исполнителей",
"Create folders for albums": "Создавать папки для альбомов",
"Separate albums by discs": "Разделять альбомы по дискам",
"Overwrite already downloaded files": "Перезаписывать существующие",
"Copy ARL": "Скопировать токен (ARL)",
"Copy userToken/ARL Cookie for use in other apps.":
"Копировать userToken/ARL Cookie для использования в других приложениях.",
"Может быть полезно для использования в других приложениях. Не сообщайте токен никому!",
"Copied": "Скопировано",
"Log out": "Выйти",
"Due to plugin incompatibility, login using browser is unavailable without restart.":
"Из-за несовместимости плагинов вход через браузер без перезапуска невозможен.",
"(ARL ONLY) Continue": "(ARL ONLY) Продолжать",
"Log out & Exit": "Выйти и закрыть",
"Pick-a-Path": "Выбери путь",
"Select storage": "Выберите хранилище",
"Go up": "Подниматься",
"После авторизации/выхода через браузер требуется перезапуск.",
"(ARL ONLY) Continue": "(Вход по токену) Выйти",
"Log out & Exit": "Выйти и перезапустить",
"Pick-a-Path": "Выберите папку",
"Select storage": "Выбрерите хранилище",
"Go up": "На уровень вверх",
"Permission denied": "Доступ запрещен",
"Language": "Язык приложения",
"Language changed, please restart Freezer to apply!": "Язык изменен, перезапустите Freezer, чтобы применить!",
"Language": "Язык",
"Language changed, please restart Freezer to apply!":
"Язык изменен, перезапустите приложения для применения",
"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:flutter/scheduler.dart';
import 'package:freezer/api/download.dart';
import 'package:freezer/main.dart';
import 'package:freezer/ui/cached_image.dart';
@ -12,6 +11,7 @@ import 'package:flutter/material.dart';
import 'dart:io';
import 'dart:convert';
import 'dart:async';
part 'settings.g.dart';
@ -62,8 +62,10 @@ class Settings {
bool trackCover;
//Appearance
@JsonKey(defaultValue: Themes.Light)
@JsonKey(defaultValue: Themes.Dark)
Themes theme;
@JsonKey(defaultValue: false)
bool useSystemTheme;
//Colors
@JsonKey(toJson: _colorToJson, fromJson: _colorFromJson)
@ -76,7 +78,6 @@ class Settings {
bool useArtColor = false;
StreamSubscription _useArtColorSub;
//Deezer
@JsonKey(defaultValue: 'en')
String deezerLanguage;
@ -89,63 +90,18 @@ class Settings {
Settings({this.downloadPath, this.arl});
static const deezerBg = Color(0xFF1F1A16);
static const font = 'MabryPro';
ThemeData get themeData {
switch (theme??Themes.Light) {
case Themes.Light:
return ThemeData(
fontFamily: font,
primaryColor: primaryColor,
accentColor: primaryColor,
sliderTheme: _sliderTheme,
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
)
);
//System theme
if (useSystemTheme) {
if (SchedulerBinding.instance.window.platformBrightness == Brightness.light) {
return _themeData[Themes.Light];
} else {
if (theme == Themes.Light) return _themeData[Themes.Dark];
return _themeData[theme];
}
}
return ThemeData();
//Theme
return _themeData[theme]??ThemeData();
}
//JSON to forward into download service
@ -154,7 +110,8 @@ class Settings {
"downloadThreads": downloadThreads,
"overwriteDownload": overwriteDownload,
"downloadLyrics": downloadLyrics,
"trackCover": trackCover
"trackCover": trackCover,
"arl": arl
};
}
@ -221,6 +178,57 @@ class Settings {
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');
//JSON

View File

@ -35,7 +35,8 @@ Settings _$SettingsFromJson(Map<String, dynamic> json) {
..downloadLyrics = json['downloadLyrics'] as bool ?? true
..trackCover = json['trackCover'] as bool ?? false
..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)
..useArtColor = json['useArtColor'] as bool ?? false
..deezerLanguage = json['deezerLanguage'] as String ?? 'en'
@ -62,6 +63,7 @@ Map<String, dynamic> _$SettingsToJson(Settings instance) => <String, dynamic>{
'downloadLyrics': instance.downloadLyrics,
'trackCover': instance.trackCover,
'theme': _$ThemesEnumMap[instance.theme],
'useSystemTheme': instance.useSystemTheme,
'primaryColor': Settings._colorToJson(instance.primaryColor),
'useArtColor': instance.useArtColor,
'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/ko_ko.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/tr_tr.dart';
import 'package:i18n_extension/i18n_extension.dart';
const supportedLocales = [
@ -27,6 +29,8 @@ const supportedLocales = [
const Locale('ko', 'KO'),
const Locale('fr', 'FR'),
const Locale('he', 'IL'),
const Locale('tr', 'TR'),
const Locale('ro', 'RO'),
const Locale('fil', 'PH')
];
@ -34,7 +38,7 @@ extension Localization on String {
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_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);
}

View File

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

View File

@ -239,7 +239,7 @@ class LoginBrowser extends StatelessWidget {
onLoadStart: (InAppWebViewController controller, String url) async {
//Offers URL
if (url.contains('/offers')) {
if (!url.contains('/login') && !url.contains('/register')) {
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) {
Map _lang = defaultLanguagesList.firstWhere((lang) => lang['isoCode'] == l.languageCode);
return {
'name': _lang['name'] + ' (${l.toString()})',
'isoCode': _lang['isoCode']
'name': _lang['name'],
'isoCode': _lang['isoCode'],
'locale': l.toString()
};
}).toList();
return _l;
@ -101,33 +102,37 @@ class _SettingsScreenState extends State<SettingsScreen> {
onTap: () {
showDialog(
context: context,
builder: (context) => LanguagePickerDialog(
titlePadding: EdgeInsets.all(8.0),
builder: (context) => SimpleDialog(
title: Text('Select language'.i18n),
isSearchable: false,
languagesList: _languages(),
onValuePicked: (Language l) async {
setState(() {
Locale locale = supportedLocales.firstWhere((_l) => _l.languageCode == l.isoCode);
settings.language = locale.toString();
});
await settings.save();
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('Language'.i18n),
content: Text('Language changed, please restart Freezer to apply!'.i18n),
actions: [
FlatButton(
child: Text('OK'),
onPressed: () => Navigator.of(context).pop(),
)
],
children: List.generate(_languages().length, (int i) {
Map l = _languages()[i];
return ListTile(
title: Text(l['name']),
subtitle: Text(l['locale']),
onTap: () async {
setState(() => settings.language = l['locale']);
await settings.save();
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('Language'.i18n),
content: Text('Language changed, please restart Freezer to apply!'.i18n),
actions: [
FlatButton(
child: Text('OK'),
onPressed: () {
Navigator.of(context).pop();
Navigator.of(context).pop();
},
)
],
);
}
);
}
},
);
},
})
)
);
},
@ -173,7 +178,7 @@ class _AppearanceSettingsState extends State<AppearanceSettings> {
title: Text('Select theme'.i18n),
children: <Widget>[
SimpleDialogOption(
child: Text('Light (default)'.i18n),
child: Text('Light'.i18n),
onPressed: () {
setState(() => settings.theme = Themes.Light);
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(
title: Text('Primary color'.i18n),
leading: Icon(Icons.format_paint),
@ -1033,14 +1054,16 @@ class _CreditsScreenState extends State<CreditsScreen> {
['Markus', 'German'],
['Andrea', 'Italian'],
['Diego Hiro', 'Portuguese'],
['Annexhack', 'Russian'],
['Orfej', 'Russian'],
['Chino Pacia', 'Filipino'],
['ArcherDelta & PetFix', 'Spanish'],
['Shazzaam', 'Croatian'],
['VIRGIN_KLM', 'Greek'],
['koreezzz', 'Korean'],
['Fwwwwwwwwwweze', 'French'],
['kobyrevah', 'Hebrew']
['kobyrevah', 'Hebrew'],
['HoScHaKaL', 'Turkish'],
['MicroMihai', 'Romanian']
];
@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.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 0.5.1+1
version: 0.5.2+1
environment:
sdk: ">=2.8.0 <3.0.0"