Compare commits

...
2 Commits
15 changed files with 814 additions and 292 deletions
+5 -5
View File
@@ -30,16 +30,16 @@ if (keystorePropertiesFile.exists()) {
android {
namespace "com.musicassistant.music_assistant"
compileSdk 35
compileSdk 36
ndkVersion flutter.ndkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = '1.8'
jvmTarget = '17'
}
sourceSets {
@@ -59,7 +59,7 @@ android {
defaultConfig {
applicationId "com.musicassistant.music_assistant"
minSdk 21
minSdkVersion flutter.minSdkVersion
targetSdk 35
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
+2 -2
View File
@@ -1,5 +1,5 @@
buildscript {
ext.kotlin_version = '1.9.10'
ext.kotlin_version = '2.1.0'
repositories {
google()
// Use Maven Central mirrors as fallback for 403 errors
@@ -9,7 +9,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:8.1.0'
classpath 'com.android.tools.build:gradle:8.7.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
+1 -1
View File
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip
+2 -2
View File
@@ -22,8 +22,8 @@ pluginManagement {
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "8.1.0" apply false
id "org.jetbrains.kotlin.android" version "1.9.10" apply false
id "com.android.application" version "8.7.0" apply false
id "org.jetbrains.kotlin.android" version "2.1.0" apply false
}
include ":app"
+18 -14
View File
@@ -64,7 +64,8 @@ import 'app_localizations_fr.dart';
/// be consistent with the languages listed in the S.supportedLocales
/// property.
abstract class S {
S(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString());
S(String locale)
: localeName = intl.Intl.canonicalizedLocale(locale.toString());
final String localeName;
@@ -84,7 +85,8 @@ abstract class S {
/// Additional delegates can be added by appending to this list in
/// MaterialApp. This list does not have to be used at all if a custom list
/// of delegates is preferred or required.
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates = <LocalizationsDelegate<dynamic>>[
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates =
<LocalizationsDelegate<dynamic>>[
delegate,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
@@ -2131,27 +2133,29 @@ class _SDelegate extends LocalizationsDelegate<S> {
}
@override
bool isSupported(Locale locale) => <String>['de', 'en', 'es', 'fr'].contains(locale.languageCode);
bool isSupported(Locale locale) =>
<String>['de', 'en', 'es', 'fr'].contains(locale.languageCode);
@override
bool shouldReload(_SDelegate old) => false;
}
S lookupS(Locale locale) {
// Lookup logic when only language code is specified.
switch (locale.languageCode) {
case 'de': return SDe();
case 'en': return SEn();
case 'es': return SEs();
case 'fr': return SFr();
case 'de':
return SDe();
case 'en':
return SEn();
case 'es':
return SEs();
case 'fr':
return SFr();
}
throw FlutterError(
'S.delegate failed to load unsupported locale "$locale". This is likely '
'an issue with the localizations generation tool. Please file an issue '
'on GitHub with a reproducible sample app and the gen-l10n configuration '
'that was used.'
);
'S.delegate failed to load unsupported locale "$locale". This is likely '
'an issue with the localizations generation tool. Please file an issue '
'on GitHub with a reproducible sample app and the gen-l10n configuration '
'that was used.');
}
+87 -44
View File
@@ -1,5 +1,5 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
@@ -39,7 +39,8 @@ class SDe extends S {
String get portHint => 'z.B. 8095 oder leer lassen';
@override
String get portDescription => 'Leer lassen bei Reverse Proxy oder Standardports. 8095 eingeben bei Direktverbindung.';
String get portDescription =>
'Leer lassen bei Reverse Proxy oder Standardports. 8095 eingeben bei Direktverbindung.';
@override
String get username => 'Benutzername';
@@ -60,10 +61,12 @@ class SDe extends S {
String get authServerUrlOptional => 'Auth-Server URL (Optional)';
@override
String get authServerUrlHint => 'z.B. auth.example.com (wenn abweichend vom Server)';
String get authServerUrlHint =>
'z.B. auth.example.com (wenn abweichend vom Server)';
@override
String get authServerUrlDescription => 'Leer lassen, wenn Authentifizierung auf demselben Server';
String get authServerUrlDescription =>
'Leer lassen, wenn Authentifizierung auf demselben Server';
@override
String detectedAuthType(String authType) {
@@ -80,40 +83,49 @@ class SDe extends S {
String get unencryptedConnection => 'Unverschlusselte Verbindung';
@override
String get usingHttpOverTailscale => 'HTTP uber Tailscale (verschlusselter Tunnel)';
String get usingHttpOverTailscale =>
'HTTP uber Tailscale (verschlusselter Tunnel)';
@override
String get httpsFailedUsingHttp => 'HTTPS fehlgeschlagen, verwende HTTP';
@override
String get httpNotEncrypted => 'HTTP-Verbindung - Daten sind nicht verschlusselt';
String get httpNotEncrypted =>
'HTTP-Verbindung - Daten sind nicht verschlusselt';
@override
String get pleaseEnterServerAddress => 'Bitte gib deine Music Assistant Serveradresse ein';
String get pleaseEnterServerAddress =>
'Bitte gib deine Music Assistant Serveradresse ein';
@override
String get pleaseEnterName => 'Bitte gib deinen Namen ein';
@override
String get pleaseEnterValidPort => 'Bitte gib eine gultige Portnummer ein (1-65535)';
String get pleaseEnterValidPort =>
'Bitte gib eine gultige Portnummer ein (1-65535)';
@override
String get pleaseEnterCredentials => 'Bitte gib Benutzername und Passwort ein';
String get pleaseEnterCredentials =>
'Bitte gib Benutzername und Passwort ein';
@override
String get authFailed => 'Authentifizierung fehlgeschlagen. Bitte uberprufe deine Anmeldedaten.';
String get authFailed =>
'Authentifizierung fehlgeschlagen. Bitte uberprufe deine Anmeldedaten.';
@override
String get maLoginFailed => 'Music Assistant Anmeldung fehlgeschlagen. Bitte uberprufe deine Anmeldedaten.';
String get maLoginFailed =>
'Music Assistant Anmeldung fehlgeschlagen. Bitte uberprufe deine Anmeldedaten.';
@override
String get connectionFailed => 'Verbindung zum Server fehlgeschlagen. Bitte uberprufe die Adresse und versuche es erneut.';
String get connectionFailed =>
'Verbindung zum Server fehlgeschlagen. Bitte uberprufe die Adresse und versuche es erneut.';
@override
String get detectingAuth => 'Erkenne Authentifizierung...';
@override
String get cannotDetermineAuth => 'Authentifizierungsanforderungen konnten nicht ermittelt werden. Bitte uberprufe die Server-URL.';
String get cannotDetermineAuth =>
'Authentifizierungsanforderungen konnten nicht ermittelt werden. Bitte uberprufe die Server-URL.';
@override
String get noAuthentication => 'Keine Authentifizierung';
@@ -221,10 +233,12 @@ class SDe extends S {
String get noRadioStations => 'Keine Radiosender';
@override
String get addRadioStationsHint => 'Füge Radiosender in Music Assistant hinzu';
String get addRadioStationsHint =>
'Füge Radiosender in Music Assistant hinzu';
@override
String get searchFailed => 'Suche fehlgeschlagen. Bitte überprüfe deine Verbindung.';
String get searchFailed =>
'Suche fehlgeschlagen. Bitte überprüfe deine Verbindung.';
@override
String get queue => 'Warteschlange';
@@ -471,37 +485,43 @@ class SDe extends S {
String get noFavoriteAudiobooks => 'Keine Lieblingshörbücher';
@override
String get tapHeartAudiobook => 'Tippe auf das Herz bei einem Hörbuch, um es zu Favoriten hinzuzufügen';
String get tapHeartAudiobook =>
'Tippe auf das Herz bei einem Hörbuch, um es zu Favoriten hinzuzufügen';
@override
String get noAudiobooks => 'Keine Hörbücher';
@override
String get addAudiobooksHint => 'Füge Hörbücher zu deiner Bibliothek hinzu, um sie hier zu sehen';
String get addAudiobooksHint =>
'Füge Hörbücher zu deiner Bibliothek hinzu, um sie hier zu sehen';
@override
String get noFavoriteArtists => 'Keine Lieblingskünstler';
@override
String get tapHeartArtist => 'Tippe auf das Herz bei einem Künstler, um ihn zu Favoriten hinzuzufügen';
String get tapHeartArtist =>
'Tippe auf das Herz bei einem Künstler, um ihn zu Favoriten hinzuzufügen';
@override
String get noFavoriteAlbums => 'Keine Lieblingsalben';
@override
String get tapHeartAlbum => 'Tippe auf das Herz bei einem Album, um es zu Favoriten hinzuzufügen';
String get tapHeartAlbum =>
'Tippe auf das Herz bei einem Album, um es zu Favoriten hinzuzufügen';
@override
String get noFavoritePlaylists => 'Keine Lieblings-Wiedergabelisten';
@override
String get tapHeartPlaylist => 'Tippe auf das Herz bei einer Wiedergabeliste, um sie zu Favoriten hinzuzufügen';
String get tapHeartPlaylist =>
'Tippe auf das Herz bei einer Wiedergabeliste, um sie zu Favoriten hinzuzufügen';
@override
String get noFavoriteTracks => 'Keine Lieblingssongs';
@override
String get longPressTrackHint => 'Halte einen Song gedrückt und tippe auf das Herz, um ihn zu Favoriten hinzuzufügen';
String get longPressTrackHint =>
'Halte einen Song gedrückt und tippe auf das Herz, um ihn zu Favoriten hinzuzufügen';
@override
String get loadSeries => 'Serien laden';
@@ -513,7 +533,8 @@ class SDe extends S {
String get notConnectedTitle => 'Nicht verbunden';
@override
String get connectHint => 'Verbinde dich mit deinem Music Assistant Server, um Musik zu hören';
String get connectHint =>
'Verbinde dich mit deinem Music Assistant Server, um Musik zu hören';
@override
String get configureServer => 'Server konfigurieren';
@@ -549,7 +570,8 @@ class SDe extends S {
String get noLogsToCopy => 'Keine Protokolle zum Kopieren';
@override
String get noDebugLogsYet => 'Noch keine Debug-Protokolle. Versuche Authentifizierung zu erkennen.';
String get noDebugLogsYet =>
'Noch keine Debug-Protokolle. Versuche Authentifizierung zu erkennen.';
@override
String get showDebug => 'Debug anzeigen';
@@ -649,10 +671,12 @@ class SDe extends S {
String get showAudiobooksInProgress => 'Hörbücher in Bearbeitung anzeigen';
@override
String get showRandomAudiobooks => 'Zufällige Hörbücher zum Entdecken anzeigen';
String get showRandomAudiobooks =>
'Zufällige Hörbücher zum Entdecken anzeigen';
@override
String get showRandomSeries => 'Zufällige Hörbuchserien zum Entdecken anzeigen';
String get showRandomSeries =>
'Zufällige Hörbuchserien zum Entdecken anzeigen';
@override
String get showFavoriteAlbums => 'Lieblingsalben anzeigen';
@@ -667,16 +691,19 @@ class SDe extends S {
String get showFavoritePlaylists => 'Show a row of your favorite playlists';
@override
String get showFavoriteRadioStations => 'Show a row of your favorite radio stations';
String get showFavoriteRadioStations =>
'Show a row of your favorite radio stations';
@override
String get showFavoritePodcasts => 'Show a row of your favorite podcasts';
@override
String get extractColorsFromArtwork => 'Farben aus Album- und Künstlercover extrahieren';
String get extractColorsFromArtwork =>
'Farben aus Album- und Künstlercover extrahieren';
@override
String get chooseHomeScreenRows => 'Wähle welche Zeilen auf dem Startbildschirm angezeigt werden';
String get chooseHomeScreenRows =>
'Wähle welche Zeilen auf dem Startbildschirm angezeigt werden';
@override
String get addedToFavorites => 'Zu Favoriten hinzugefügt';
@@ -785,13 +812,15 @@ class SDe extends S {
String get theAudioDbApiKey => 'TheAudioDB API-Schlüssel';
@override
String get theAudioDbApiKeyHint => '\"2\" für kostenlosen Zugang oder Premium-Schlüssel';
String get theAudioDbApiKeyHint =>
'\"2\" für kostenlosen Zugang oder Premium-Schlüssel';
@override
String get audiobookLibraries => 'Hörbuch-Bibliotheken';
@override
String get chooseAudiobookLibraries => 'Wähle welche Audiobookshelf-Bibliotheken einbezogen werden';
String get chooseAudiobookLibraries =>
'Wähle welche Audiobookshelf-Bibliotheken einbezogen werden';
@override
String get unknownLibrary => 'Unbekannte Bibliothek';
@@ -800,7 +829,8 @@ class SDe extends S {
String get musicProviders => 'Music Providers';
@override
String get musicProvidersDescription => 'Choose which accounts to show in your library';
String get musicProvidersDescription =>
'Choose which accounts to show in your library';
@override
String get libraryRefreshing => 'Refreshing library...';
@@ -820,16 +850,19 @@ class SDe extends S {
}
@override
String get noSeriesAvailable => 'Keine Serien in deiner Hörbuch-Bibliothek verfügbar.\nZiehe zum Aktualisieren.';
String get noSeriesAvailable =>
'Keine Serien in deiner Hörbuch-Bibliothek verfügbar.\nZiehe zum Aktualisieren.';
@override
String get pullToLoadSeries => 'Ziehe nach unten um Serien\nvon Music Assistant zu laden';
String get pullToLoadSeries =>
'Ziehe nach unten um Serien\nvon Music Assistant zu laden';
@override
String get search => 'Suche';
@override
String get metadataApisDescription => 'Künstlerbilder werden automatisch von Deezer abgerufen. Füge unten API-Schlüssel für Künstlerbiografien und Albenbeschreibungen hinzu.';
String get metadataApisDescription =>
'Künstlerbilder werden automatisch von Deezer abgerufen. Füge unten API-Schlüssel für Künstlerbiografien und Albenbeschreibungen hinzu.';
@override
String get lastFmApiKey => 'Last.fm API-Schlüssel';
@@ -901,19 +934,22 @@ class SDe extends S {
String get preferLocalPlayer => 'Lokales Gerät bevorzugen';
@override
String get preferLocalPlayerDescription => 'Dieses Gerät immer zuerst auswählen, wenn verfügbar';
String get preferLocalPlayerDescription =>
'Dieses Gerät immer zuerst auswählen, wenn verfügbar';
@override
String get smartSortPlayers => 'Intelligente Sortierung';
@override
String get smartSortPlayersDescription => 'Nach Status sortieren (spielt, an, aus) statt alphabetisch';
String get smartSortPlayersDescription =>
'Nach Status sortieren (spielt, an, aus) statt alphabetisch';
@override
String get disableAutoSwitch => 'Disable Auto-Switch';
@override
String get disableAutoSwitchDescription => 'Never automatically switch to a different player';
String get disableAutoSwitchDescription =>
'Never automatically switch to a different player';
@override
String get playerStateUnavailable => 'Nicht verfügbar';
@@ -945,7 +981,8 @@ class SDe extends S {
String get showHints => 'Hinweise anzeigen';
@override
String get showHintsDescription => 'Hilfreiche Tipps zum Entdecken von Funktionen anzeigen';
String get showHintsDescription =>
'Hilfreiche Tipps zum Entdecken von Funktionen anzeigen';
@override
String get display => 'Display';
@@ -954,7 +991,8 @@ class SDe extends S {
String get showProviderIcons => 'Show Provider Icons';
@override
String get showProviderIconsDescription => 'Display provider logos on album art';
String get showProviderIconsDescription =>
'Display provider logos on album art';
@override
String get pullToSelectPlayers => 'Ziehen um Geräte auszuwählen';
@@ -972,13 +1010,15 @@ class SDe extends S {
String get welcomeToEnsemble => 'Welcome to Ensemble';
@override
String get welcomeMessage => 'By default your phone is the selected player.\nPull the mini player down to select another player.';
String get welcomeMessage =>
'By default your phone is the selected player.\nPull the mini player down to select another player.';
@override
String get skip => 'Skip';
@override
String get dismissPlayerHint => 'Swipe down, tap outside, or press back to return';
String get dismissPlayerHint =>
'Swipe down, tap outside, or press back to return';
@override
String playingAlbum(String albumName) {
@@ -994,19 +1034,22 @@ class SDe extends S {
String get noTracks => 'No tracks';
@override
String get addTracksHint => 'Add some music to your library to see tracks here';
String get addTracksHint =>
'Add some music to your library to see tracks here';
@override
String get noFavoriteRadioStations => 'No favorite radio stations';
@override
String get longPressRadioHint => 'Long-press a station and tap the heart to add it to favorites';
String get longPressRadioHint =>
'Long-press a station and tap the heart to add it to favorites';
@override
String get noFavoritePodcasts => 'No favorite podcasts';
@override
String get longPressPodcastHint => 'Long-press a podcast and tap the heart to add it to favorites';
String get longPressPodcastHint =>
'Long-press a podcast and tap the heart to add it to favorites';
@override
String failedToPlayRadioStation(String error) {
+71 -36
View File
@@ -1,5 +1,5 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
@@ -39,7 +39,8 @@ class SEn extends S {
String get portHint => 'e.g., 8095 or leave blank';
@override
String get portDescription => 'Leave blank for reverse proxy or standard ports. Enter 8095 for direct connection.';
String get portDescription =>
'Leave blank for reverse proxy or standard ports. Enter 8095 for direct connection.';
@override
String get username => 'Username';
@@ -60,10 +61,12 @@ class SEn extends S {
String get authServerUrlOptional => 'Auth Server URL (Optional)';
@override
String get authServerUrlHint => 'e.g., auth.example.com (if different from server)';
String get authServerUrlHint =>
'e.g., auth.example.com (if different from server)';
@override
String get authServerUrlDescription => 'Leave empty if authentication is on the same server';
String get authServerUrlDescription =>
'Leave empty if authentication is on the same server';
@override
String detectedAuthType(String authType) {
@@ -80,7 +83,8 @@ class SEn extends S {
String get unencryptedConnection => 'Unencrypted Connection';
@override
String get usingHttpOverTailscale => 'Using HTTP over Tailscale (encrypted tunnel)';
String get usingHttpOverTailscale =>
'Using HTTP over Tailscale (encrypted tunnel)';
@override
String get httpsFailedUsingHttp => 'HTTPS failed, using HTTP fallback';
@@ -89,31 +93,37 @@ class SEn extends S {
String get httpNotEncrypted => 'HTTP connection - data is not encrypted';
@override
String get pleaseEnterServerAddress => 'Please enter your Music Assistant server address';
String get pleaseEnterServerAddress =>
'Please enter your Music Assistant server address';
@override
String get pleaseEnterName => 'Please enter your name';
@override
String get pleaseEnterValidPort => 'Please enter a valid port number (1-65535)';
String get pleaseEnterValidPort =>
'Please enter a valid port number (1-65535)';
@override
String get pleaseEnterCredentials => 'Please enter username and password';
@override
String get authFailed => 'Authentication failed. Please check your credentials.';
String get authFailed =>
'Authentication failed. Please check your credentials.';
@override
String get maLoginFailed => 'Music Assistant login failed. Please check your credentials.';
String get maLoginFailed =>
'Music Assistant login failed. Please check your credentials.';
@override
String get connectionFailed => 'Could not connect to server. Please check the address and try again.';
String get connectionFailed =>
'Could not connect to server. Please check the address and try again.';
@override
String get detectingAuth => 'Detecting authentication...';
@override
String get cannotDetermineAuth => 'Cannot determine authentication requirements. Please check server URL.';
String get cannotDetermineAuth =>
'Cannot determine authentication requirements. Please check server URL.';
@override
String get noAuthentication => 'No Authentication';
@@ -471,37 +481,43 @@ class SEn extends S {
String get noFavoriteAudiobooks => 'No favorite audiobooks';
@override
String get tapHeartAudiobook => 'Tap the heart on an audiobook to add it to favorites';
String get tapHeartAudiobook =>
'Tap the heart on an audiobook to add it to favorites';
@override
String get noAudiobooks => 'No audiobooks';
@override
String get addAudiobooksHint => 'Add audiobooks to your library to see them here';
String get addAudiobooksHint =>
'Add audiobooks to your library to see them here';
@override
String get noFavoriteArtists => 'No favorite artists';
@override
String get tapHeartArtist => 'Tap the heart on an artist to add them to favorites';
String get tapHeartArtist =>
'Tap the heart on an artist to add them to favorites';
@override
String get noFavoriteAlbums => 'No favorite albums';
@override
String get tapHeartAlbum => 'Tap the heart on an album to add it to favorites';
String get tapHeartAlbum =>
'Tap the heart on an album to add it to favorites';
@override
String get noFavoritePlaylists => 'No favorite playlists';
@override
String get tapHeartPlaylist => 'Tap the heart on a playlist to add it to favorites';
String get tapHeartPlaylist =>
'Tap the heart on a playlist to add it to favorites';
@override
String get noFavoriteTracks => 'No favorite tracks';
@override
String get longPressTrackHint => 'Long-press a track and tap the heart to add it to favorites';
String get longPressTrackHint =>
'Long-press a track and tap the heart to add it to favorites';
@override
String get loadSeries => 'Load Series';
@@ -513,7 +529,8 @@ class SEn extends S {
String get notConnectedTitle => 'Not Connected';
@override
String get connectHint => 'Connect to your Music Assistant server to start listening';
String get connectHint =>
'Connect to your Music Assistant server to start listening';
@override
String get configureServer => 'Configure Server';
@@ -667,16 +684,19 @@ class SEn extends S {
String get showFavoritePlaylists => 'Show a row of your favorite playlists';
@override
String get showFavoriteRadioStations => 'Show a row of your favorite radio stations';
String get showFavoriteRadioStations =>
'Show a row of your favorite radio stations';
@override
String get showFavoritePodcasts => 'Show a row of your favorite podcasts';
@override
String get extractColorsFromArtwork => 'Extract colors from album and artist artwork';
String get extractColorsFromArtwork =>
'Extract colors from album and artist artwork';
@override
String get chooseHomeScreenRows => 'Choose which rows to display on the home screen';
String get chooseHomeScreenRows =>
'Choose which rows to display on the home screen';
@override
String get addedToFavorites => 'Added to favorites';
@@ -791,7 +811,8 @@ class SEn extends S {
String get audiobookLibraries => 'Audiobook Libraries';
@override
String get chooseAudiobookLibraries => 'Choose which Audiobookshelf libraries to include';
String get chooseAudiobookLibraries =>
'Choose which Audiobookshelf libraries to include';
@override
String get unknownLibrary => 'Unknown Library';
@@ -800,7 +821,8 @@ class SEn extends S {
String get musicProviders => 'Music Providers';
@override
String get musicProvidersDescription => 'Choose which accounts to show in your library';
String get musicProvidersDescription =>
'Choose which accounts to show in your library';
@override
String get libraryRefreshing => 'Refreshing library...';
@@ -820,16 +842,19 @@ class SEn extends S {
}
@override
String get noSeriesAvailable => 'No series available from your audiobook library.\nPull to refresh.';
String get noSeriesAvailable =>
'No series available from your audiobook library.\nPull to refresh.';
@override
String get pullToLoadSeries => 'Pull down to load series\nfrom Music Assistant';
String get pullToLoadSeries =>
'Pull down to load series\nfrom Music Assistant';
@override
String get search => 'Search';
@override
String get metadataApisDescription => 'Artist images are automatically fetched from Deezer. Add API keys below for artist biographies and album descriptions.';
String get metadataApisDescription =>
'Artist images are automatically fetched from Deezer. Add API keys below for artist biographies and album descriptions.';
@override
String get lastFmApiKey => 'Last.fm API Key';
@@ -901,19 +926,22 @@ class SEn extends S {
String get preferLocalPlayer => 'Prefer Local Player';
@override
String get preferLocalPlayerDescription => 'Always select this device first when available';
String get preferLocalPlayerDescription =>
'Always select this device first when available';
@override
String get smartSortPlayers => 'Smart Sort';
@override
String get smartSortPlayersDescription => 'Sort by status (playing, on, off) instead of alphabetically';
String get smartSortPlayersDescription =>
'Sort by status (playing, on, off) instead of alphabetically';
@override
String get disableAutoSwitch => 'Disable Auto-Switch';
@override
String get disableAutoSwitchDescription => 'Never automatically switch to a different player';
String get disableAutoSwitchDescription =>
'Never automatically switch to a different player';
@override
String get playerStateUnavailable => 'Unavailable';
@@ -945,7 +973,8 @@ class SEn extends S {
String get showHints => 'Show Hints';
@override
String get showHintsDescription => 'Display helpful tips for discovering features';
String get showHintsDescription =>
'Display helpful tips for discovering features';
@override
String get display => 'Display';
@@ -954,7 +983,8 @@ class SEn extends S {
String get showProviderIcons => 'Show Provider Icons';
@override
String get showProviderIconsDescription => 'Display provider logos on album art';
String get showProviderIconsDescription =>
'Display provider logos on album art';
@override
String get pullToSelectPlayers => 'Pull to select players';
@@ -972,13 +1002,15 @@ class SEn extends S {
String get welcomeToEnsemble => 'Welcome to Ensemble';
@override
String get welcomeMessage => 'By default your phone is the selected player.\nPull the mini player down to select another player.';
String get welcomeMessage =>
'By default your phone is the selected player.\nPull the mini player down to select another player.';
@override
String get skip => 'Skip';
@override
String get dismissPlayerHint => 'Swipe down, tap outside, or press back to return';
String get dismissPlayerHint =>
'Swipe down, tap outside, or press back to return';
@override
String playingAlbum(String albumName) {
@@ -994,19 +1026,22 @@ class SEn extends S {
String get noTracks => 'No tracks';
@override
String get addTracksHint => 'Add some music to your library to see tracks here';
String get addTracksHint =>
'Add some music to your library to see tracks here';
@override
String get noFavoriteRadioStations => 'No favorite radio stations';
@override
String get longPressRadioHint => 'Long-press a station and tap the heart to add it to favorites';
String get longPressRadioHint =>
'Long-press a station and tap the heart to add it to favorites';
@override
String get noFavoritePodcasts => 'No favorite podcasts';
@override
String get longPressPodcastHint => 'Long-press a podcast and tap the heart to add it to favorites';
String get longPressPodcastHint =>
'Long-press a podcast and tap the heart to add it to favorites';
@override
String failedToPlayRadioStation(String error) {
+103 -52
View File
@@ -1,5 +1,5 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
@@ -39,7 +39,8 @@ class SEs extends S {
String get portHint => 'ej., 8095 o dejar en blanco';
@override
String get portDescription => 'Dejar en blanco para proxy inverso o puertos estándar. Introduce 8095 para conexión directa.';
String get portDescription =>
'Dejar en blanco para proxy inverso o puertos estándar. Introduce 8095 para conexión directa.';
@override
String get username => 'Usuario';
@@ -57,13 +58,16 @@ class SEs extends S {
String get disconnect => 'Desconectar';
@override
String get authServerUrlOptional => 'URL del servidor de autenticación (Opcional)';
String get authServerUrlOptional =>
'URL del servidor de autenticación (Opcional)';
@override
String get authServerUrlHint => 'ej., auth.example.com (si es diferente del servidor)';
String get authServerUrlHint =>
'ej., auth.example.com (si es diferente del servidor)';
@override
String get authServerUrlDescription => 'Dejar vacío si la autenticación está en el mismo servidor';
String get authServerUrlDescription =>
'Dejar vacío si la autenticación está en el mismo servidor';
@override
String detectedAuthType(String authType) {
@@ -80,40 +84,49 @@ class SEs extends S {
String get unencryptedConnection => 'Conexión sin cifrar';
@override
String get usingHttpOverTailscale => 'Usando HTTP sobre Tailscale (túnel cifrado)';
String get usingHttpOverTailscale =>
'Usando HTTP sobre Tailscale (túnel cifrado)';
@override
String get httpsFailedUsingHttp => 'HTTPS falló, usando HTTP como alternativa';
String get httpsFailedUsingHttp =>
'HTTPS falló, usando HTTP como alternativa';
@override
String get httpNotEncrypted => 'Conexión HTTP - los datos no están cifrados';
@override
String get pleaseEnterServerAddress => 'Por favor, introduce la dirección de tu servidor Music Assistant';
String get pleaseEnterServerAddress =>
'Por favor, introduce la dirección de tu servidor Music Assistant';
@override
String get pleaseEnterName => 'Por favor, introduce tu nombre';
@override
String get pleaseEnterValidPort => 'Por favor, introduce un número de puerto válido (1-65535)';
String get pleaseEnterValidPort =>
'Por favor, introduce un número de puerto válido (1-65535)';
@override
String get pleaseEnterCredentials => 'Por favor, introduce usuario y contraseña';
String get pleaseEnterCredentials =>
'Por favor, introduce usuario y contraseña';
@override
String get authFailed => 'Autenticación fallida. Por favor, verifica tus credenciales.';
String get authFailed =>
'Autenticación fallida. Por favor, verifica tus credenciales.';
@override
String get maLoginFailed => 'Inicio de sesión en Music Assistant fallido. Por favor, verifica tus credenciales.';
String get maLoginFailed =>
'Inicio de sesión en Music Assistant fallido. Por favor, verifica tus credenciales.';
@override
String get connectionFailed => 'No se pudo conectar al servidor. Por favor, verifica la dirección e inténtalo de nuevo.';
String get connectionFailed =>
'No se pudo conectar al servidor. Por favor, verifica la dirección e inténtalo de nuevo.';
@override
String get detectingAuth => 'Detectando autenticación...';
@override
String get cannotDetermineAuth => 'No se pueden determinar los requisitos de autenticación. Por favor, verifica la URL del servidor.';
String get cannotDetermineAuth =>
'No se pueden determinar los requisitos de autenticación. Por favor, verifica la URL del servidor.';
@override
String get noAuthentication => 'Sin autenticación';
@@ -221,10 +234,12 @@ class SEs extends S {
String get noRadioStations => 'No hay emisoras de radio';
@override
String get addRadioStationsHint => 'Añade emisoras de radio en Music Assistant';
String get addRadioStationsHint =>
'Añade emisoras de radio en Music Assistant';
@override
String get searchFailed => 'Búsqueda fallida. Por favor, verifica tu conexión.';
String get searchFailed =>
'Búsqueda fallida. Por favor, verifica tu conexión.';
@override
String get queue => 'Cola';
@@ -264,7 +279,8 @@ class SEs extends S {
String get system => 'Sistema';
@override
String get pullToRefresh => 'Desliza hacia abajo para actualizar la biblioteca y aplicar los cambios';
String get pullToRefresh =>
'Desliza hacia abajo para actualizar la biblioteca y aplicar los cambios';
@override
String get viewDebugLogs => 'Ver registros de depuración';
@@ -301,7 +317,8 @@ class SEs extends S {
String get logsCleared => 'Registros borrados';
@override
String get playerListCopied => 'Lista de reproductores copiada al portapapeles';
String get playerListCopied =>
'Lista de reproductores copiada al portapapeles';
@override
String get noLogsYet => 'Aún no hay registros';
@@ -471,37 +488,43 @@ class SEs extends S {
String get noFavoriteAudiobooks => 'No hay audiolibros favoritos';
@override
String get tapHeartAudiobook => 'Toca el corazón en un audiolibro para añadirlo a favoritos';
String get tapHeartAudiobook =>
'Toca el corazón en un audiolibro para añadirlo a favoritos';
@override
String get noAudiobooks => 'No hay audiolibros';
@override
String get addAudiobooksHint => 'Añade audiolibros a tu biblioteca para verlos aquí';
String get addAudiobooksHint =>
'Añade audiolibros a tu biblioteca para verlos aquí';
@override
String get noFavoriteArtists => 'No hay artistas favoritos';
@override
String get tapHeartArtist => 'Toca el corazón en un artista para añadirlo a favoritos';
String get tapHeartArtist =>
'Toca el corazón en un artista para añadirlo a favoritos';
@override
String get noFavoriteAlbums => 'No hay álbumes favoritos';
@override
String get tapHeartAlbum => 'Toca el corazón en un álbum para añadirlo a favoritos';
String get tapHeartAlbum =>
'Toca el corazón en un álbum para añadirlo a favoritos';
@override
String get noFavoritePlaylists => 'No hay listas de reproducción favoritas';
@override
String get tapHeartPlaylist => 'Toca el corazón en una lista para añadirla a favoritos';
String get tapHeartPlaylist =>
'Toca el corazón en una lista para añadirla a favoritos';
@override
String get noFavoriteTracks => 'No hay canciones favoritas';
@override
String get longPressTrackHint => 'Mantén presionada una canción y toca el corazón para añadirla a favoritos';
String get longPressTrackHint =>
'Mantén presionada una canción y toca el corazón para añadirla a favoritos';
@override
String get loadSeries => 'Cargar series';
@@ -513,7 +536,8 @@ class SEs extends S {
String get notConnectedTitle => 'No conectado';
@override
String get connectHint => 'Conéctate a tu servidor Music Assistant para empezar a escuchar';
String get connectHint =>
'Conéctate a tu servidor Music Assistant para empezar a escuchar';
@override
String get configureServer => 'Configurar servidor';
@@ -549,7 +573,8 @@ class SEs extends S {
String get noLogsToCopy => 'No hay registros para copiar';
@override
String get noDebugLogsYet => 'Aún no hay registros de depuración. Intenta detectar autenticación.';
String get noDebugLogsYet =>
'Aún no hay registros de depuración. Intenta detectar autenticación.';
@override
String get showDebug => 'Mostrar depuración';
@@ -564,7 +589,8 @@ class SEs extends S {
String get noChapters => 'Sin capítulos';
@override
String get noChapterInfo => 'Este audiolibro no tiene información de capítulos';
String get noChapterInfo =>
'Este audiolibro no tiene información de capítulos';
@override
String errorSeeking(String error) {
@@ -637,7 +663,8 @@ class SEs extends S {
String get artist => 'Artista';
@override
String get showRecentlyPlayedAlbums => 'Mostrar álbumes reproducidos recientemente';
String get showRecentlyPlayedAlbums =>
'Mostrar álbumes reproducidos recientemente';
@override
String get showRandomArtists => 'Mostrar artistas aleatorios para descubrir';
@@ -649,34 +676,41 @@ class SEs extends S {
String get showAudiobooksInProgress => 'Mostrar audiolibros en progreso';
@override
String get showRandomAudiobooks => 'Mostrar audiolibros aleatorios para descubrir';
String get showRandomAudiobooks =>
'Mostrar audiolibros aleatorios para descubrir';
@override
String get showRandomSeries => 'Mostrar series de audiolibros aleatorias para descubrir';
String get showRandomSeries =>
'Mostrar series de audiolibros aleatorias para descubrir';
@override
String get showFavoriteAlbums => 'Mostrar una fila de tus álbumes favoritos';
@override
String get showFavoriteArtists => 'Mostrar una fila de tus artistas favoritos';
String get showFavoriteArtists =>
'Mostrar una fila de tus artistas favoritos';
@override
String get showFavoriteTracks => 'Mostrar una fila de tus canciones favoritas';
String get showFavoriteTracks =>
'Mostrar una fila de tus canciones favoritas';
@override
String get showFavoritePlaylists => 'Show a row of your favorite playlists';
@override
String get showFavoriteRadioStations => 'Show a row of your favorite radio stations';
String get showFavoriteRadioStations =>
'Show a row of your favorite radio stations';
@override
String get showFavoritePodcasts => 'Show a row of your favorite podcasts';
@override
String get extractColorsFromArtwork => 'Extraer colores de las portadas de álbumes y artistas';
String get extractColorsFromArtwork =>
'Extraer colores de las portadas de álbumes y artistas';
@override
String get chooseHomeScreenRows => 'Elige qué filas mostrar en la pantalla de inicio';
String get chooseHomeScreenRows =>
'Elige qué filas mostrar en la pantalla de inicio';
@override
String get addedToFavorites => 'Añadido a favoritos';
@@ -774,7 +808,8 @@ class SEs extends S {
String get loadingChapters => 'Cargando capítulos...';
@override
String get noChapterInfoAvailable => 'No hay información de capítulos disponible';
String get noChapterInfoAvailable =>
'No hay información de capítulos disponible';
@override
String percentComplete(int percent) {
@@ -785,13 +820,15 @@ class SEs extends S {
String get theAudioDbApiKey => 'Clave API de TheAudioDB';
@override
String get theAudioDbApiKeyHint => 'Usa \"2\" para nivel gratuito o clave premium';
String get theAudioDbApiKeyHint =>
'Usa \"2\" para nivel gratuito o clave premium';
@override
String get audiobookLibraries => 'Bibliotecas de audiolibros';
@override
String get chooseAudiobookLibraries => 'Elige qué bibliotecas de Audiobookshelf incluir';
String get chooseAudiobookLibraries =>
'Elige qué bibliotecas de Audiobookshelf incluir';
@override
String get unknownLibrary => 'Biblioteca desconocida';
@@ -800,7 +837,8 @@ class SEs extends S {
String get musicProviders => 'Music Providers';
@override
String get musicProvidersDescription => 'Choose which accounts to show in your library';
String get musicProvidersDescription =>
'Choose which accounts to show in your library';
@override
String get libraryRefreshing => 'Refreshing library...';
@@ -820,16 +858,19 @@ class SEs extends S {
}
@override
String get noSeriesAvailable => 'No hay series disponibles en tu biblioteca de audiolibros.\nDesliza para actualizar.';
String get noSeriesAvailable =>
'No hay series disponibles en tu biblioteca de audiolibros.\nDesliza para actualizar.';
@override
String get pullToLoadSeries => 'Desliza hacia abajo para cargar series\ndesde Music Assistant';
String get pullToLoadSeries =>
'Desliza hacia abajo para cargar series\ndesde Music Assistant';
@override
String get search => 'Buscar';
@override
String get metadataApisDescription => 'Las imágenes de artistas se obtienen automáticamente de Deezer. Añade claves API a continuación para biografías de artistas y descripciones de álbumes.';
String get metadataApisDescription =>
'Las imágenes de artistas se obtienen automáticamente de Deezer. Añade claves API a continuación para biografías de artistas y descripciones de álbumes.';
@override
String get lastFmApiKey => 'Clave API de Last.fm';
@@ -901,19 +942,22 @@ class SEs extends S {
String get preferLocalPlayer => 'Preferir dispositivo local';
@override
String get preferLocalPlayerDescription => 'Seleccionar siempre este dispositivo primero cuando esté disponible';
String get preferLocalPlayerDescription =>
'Seleccionar siempre este dispositivo primero cuando esté disponible';
@override
String get smartSortPlayers => 'Orden inteligente';
@override
String get smartSortPlayersDescription => 'Ordenar por estado (reproduciendo, encendido, apagado) en lugar de alfabéticamente';
String get smartSortPlayersDescription =>
'Ordenar por estado (reproduciendo, encendido, apagado) en lugar de alfabéticamente';
@override
String get disableAutoSwitch => 'Disable Auto-Switch';
@override
String get disableAutoSwitchDescription => 'Never automatically switch to a different player';
String get disableAutoSwitchDescription =>
'Never automatically switch to a different player';
@override
String get playerStateUnavailable => 'No disponible';
@@ -945,7 +989,8 @@ class SEs extends S {
String get showHints => 'Mostrar Sugerencias';
@override
String get showHintsDescription => 'Mostrar consejos útiles para descubrir funciones';
String get showHintsDescription =>
'Mostrar consejos útiles para descubrir funciones';
@override
String get display => 'Display';
@@ -954,7 +999,8 @@ class SEs extends S {
String get showProviderIcons => 'Show Provider Icons';
@override
String get showProviderIconsDescription => 'Display provider logos on album art';
String get showProviderIconsDescription =>
'Display provider logos on album art';
@override
String get pullToSelectPlayers => 'Desliza para seleccionar dispositivos';
@@ -972,13 +1018,15 @@ class SEs extends S {
String get welcomeToEnsemble => 'Welcome to Ensemble';
@override
String get welcomeMessage => 'By default your phone is the selected player.\nPull the mini player down to select another player.';
String get welcomeMessage =>
'By default your phone is the selected player.\nPull the mini player down to select another player.';
@override
String get skip => 'Skip';
@override
String get dismissPlayerHint => 'Swipe down, tap outside, or press back to return';
String get dismissPlayerHint =>
'Swipe down, tap outside, or press back to return';
@override
String playingAlbum(String albumName) {
@@ -994,19 +1042,22 @@ class SEs extends S {
String get noTracks => 'No tracks';
@override
String get addTracksHint => 'Add some music to your library to see tracks here';
String get addTracksHint =>
'Add some music to your library to see tracks here';
@override
String get noFavoriteRadioStations => 'No favorite radio stations';
@override
String get longPressRadioHint => 'Long-press a station and tap the heart to add it to favorites';
String get longPressRadioHint =>
'Long-press a station and tap the heart to add it to favorites';
@override
String get noFavoritePodcasts => 'No favorite podcasts';
@override
String get longPressPodcastHint => 'Long-press a podcast and tap the heart to add it to favorites';
String get longPressPodcastHint =>
'Long-press a podcast and tap the heart to add it to favorites';
@override
String failedToPlayRadioStation(String error) {
+121 -61
View File
@@ -1,5 +1,5 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
@@ -39,7 +39,8 @@ class SFr extends S {
String get portHint => 'ex., 8095 ou laisser vide';
@override
String get portDescription => 'Laisser vide pour les proxys inverses ou les ports standards. Entrer 8095 pour une connexion directe.';
String get portDescription =>
'Laisser vide pour les proxys inverses ou les ports standards. Entrer 8095 pour une connexion directe.';
@override
String get username => 'Nom d\'utilisateur';
@@ -60,10 +61,12 @@ class SFr extends S {
String get authServerUrlOptional => 'URL du serveur d\'auth (Facultatif)';
@override
String get authServerUrlHint => 'ex., auth.example.com (si different du serveur)';
String get authServerUrlHint =>
'ex., auth.example.com (si different du serveur)';
@override
String get authServerUrlDescription => 'Laisser vide si l\'authentification est sur le meme serveur';
String get authServerUrlDescription =>
'Laisser vide si l\'authentification est sur le meme serveur';
@override
String detectedAuthType(String authType) {
@@ -80,40 +83,50 @@ class SFr extends S {
String get unencryptedConnection => 'Connexion non chiffrée';
@override
String get usingHttpOverTailscale => 'Utilisation de HTTP via Tailscale (tunnel chiffre)';
String get usingHttpOverTailscale =>
'Utilisation de HTTP via Tailscale (tunnel chiffre)';
@override
String get httpsFailedUsingHttp => 'HTTPS a échoué, utilisation de HTTP en repli';
String get httpsFailedUsingHttp =>
'HTTPS a échoué, utilisation de HTTP en repli';
@override
String get httpNotEncrypted => 'Connexion HTTP - les donnees ne sont pas chiffrées';
String get httpNotEncrypted =>
'Connexion HTTP - les donnees ne sont pas chiffrées';
@override
String get pleaseEnterServerAddress => 'Veuillez entrer l\'adresse de votre serveur Music Assistant';
String get pleaseEnterServerAddress =>
'Veuillez entrer l\'adresse de votre serveur Music Assistant';
@override
String get pleaseEnterName => 'Veuillez entrer votre nom';
@override
String get pleaseEnterValidPort => 'Veuillez entrer un numero de port valide (1-65535)';
String get pleaseEnterValidPort =>
'Veuillez entrer un numero de port valide (1-65535)';
@override
String get pleaseEnterCredentials => 'Veuillez entrer le nom d\'utilisateur et le mot de passe';
String get pleaseEnterCredentials =>
'Veuillez entrer le nom d\'utilisateur et le mot de passe';
@override
String get authFailed => 'Echec de l\'authentification. Veuillez verifier vos identifiants.';
String get authFailed =>
'Echec de l\'authentification. Veuillez verifier vos identifiants.';
@override
String get maLoginFailed => 'Echec de la connexion a Music Assistant. Veuillez verifier vos identifiants.';
String get maLoginFailed =>
'Echec de la connexion a Music Assistant. Veuillez verifier vos identifiants.';
@override
String get connectionFailed => 'Impossible de se connecter au serveur. Veuillez verifier l\'adresse et reessayer.';
String get connectionFailed =>
'Impossible de se connecter au serveur. Veuillez verifier l\'adresse et reessayer.';
@override
String get detectingAuth => 'Detection de l\'authentification...';
@override
String get cannotDetermineAuth => 'Impossible de determiner les exigences d\'authentification. Veuillez verifier l\'URL du serveur.';
String get cannotDetermineAuth =>
'Impossible de determiner les exigences d\'authentification. Veuillez verifier l\'URL du serveur.';
@override
String get noAuthentication => 'Pas d\'authentification';
@@ -128,7 +141,8 @@ class SFr extends S {
String get musicAssistantLogin => 'Connexion Music Assistant';
@override
String get pressBackToMinimize => 'Appuyez a nouveau sur retour pour minimiser';
String get pressBackToMinimize =>
'Appuyez a nouveau sur retour pour minimiser';
@override
String get recentlyPlayed => 'Ecoutes recemment';
@@ -221,10 +235,12 @@ class SFr extends S {
String get noRadioStations => 'Aucune station de radio';
@override
String get addRadioStationsHint => 'Ajouter des stations de radio dans Music Assistant';
String get addRadioStationsHint =>
'Ajouter des stations de radio dans Music Assistant';
@override
String get searchFailed => 'La recherche a échoué. Veuillez verifier votre connexion.';
String get searchFailed =>
'La recherche a échoué. Veuillez verifier votre connexion.';
@override
String get queue => 'File d\'attente';
@@ -264,7 +280,8 @@ class SFr extends S {
String get system => 'Système';
@override
String get pullToRefresh => 'Tirez pour rafraichir la bibliothèque et appliquer les modifications';
String get pullToRefresh =>
'Tirez pour rafraichir la bibliothèque et appliquer les modifications';
@override
String get viewDebugLogs => 'Voir les journaux de debogage';
@@ -301,7 +318,8 @@ class SFr extends S {
String get logsCleared => 'Journaux effaces';
@override
String get playerListCopied => 'Liste des lecteurs copiee dans le presse-papiers !';
String get playerListCopied =>
'Liste des lecteurs copiee dans le presse-papiers !';
@override
String get noLogsYet => 'Pas encore de journaux';
@@ -471,37 +489,43 @@ class SFr extends S {
String get noFavoriteAudiobooks => 'Aucun livre audio favori';
@override
String get tapHeartAudiobook => 'Appuyez sur le coeur d\'un livre audio pour l\'ajoutér aux favoris';
String get tapHeartAudiobook =>
'Appuyez sur le coeur d\'un livre audio pour l\'ajoutér aux favoris';
@override
String get noAudiobooks => 'Aucun livre audio';
@override
String get addAudiobooksHint => 'Ajoutez des livres audio a votre bibliothèque pour les voir ici';
String get addAudiobooksHint =>
'Ajoutez des livres audio a votre bibliothèque pour les voir ici';
@override
String get noFavoriteArtists => 'Aucun artiste favori';
@override
String get tapHeartArtist => 'Appuyez sur le coeur d\'un artiste pour l\'ajoutér aux favoris';
String get tapHeartArtist =>
'Appuyez sur le coeur d\'un artiste pour l\'ajoutér aux favoris';
@override
String get noFavoriteAlbums => 'Aucun album favori';
@override
String get tapHeartAlbum => 'Appuyez sur le coeur d\'un album pour l\'ajoutér aux favoris';
String get tapHeartAlbum =>
'Appuyez sur le coeur d\'un album pour l\'ajoutér aux favoris';
@override
String get noFavoritePlaylists => 'Aucune playlist favorite';
@override
String get tapHeartPlaylist => 'Appuyez sur le coeur d\'une playlist pour l\'ajoutér aux favoris';
String get tapHeartPlaylist =>
'Appuyez sur le coeur d\'une playlist pour l\'ajoutér aux favoris';
@override
String get noFavoriteTracks => 'Aucune piste favorite';
@override
String get longPressTrackHint => 'Appuyez longuement sur une piste et touchez le coeur pour l\'ajoutér aux favoris';
String get longPressTrackHint =>
'Appuyez longuement sur une piste et touchez le coeur pour l\'ajoutér aux favoris';
@override
String get loadSeries => 'Charger les séries';
@@ -513,7 +537,8 @@ class SFr extends S {
String get notConnectedTitle => 'Not Connected';
@override
String get connectHint => 'Connectéz-vous a votre serveur Music Assistant pour commencer a écouter';
String get connectHint =>
'Connectéz-vous a votre serveur Music Assistant pour commencer a écouter';
@override
String get configureServer => 'Configurer le serveur';
@@ -549,7 +574,8 @@ class SFr extends S {
String get noLogsToCopy => 'Aucun journal a copier';
@override
String get noDebugLogsYet => 'Pas encore de journaux de debogage. Essayez de détectér l\'authentification.';
String get noDebugLogsYet =>
'Pas encore de journaux de debogage. Essayez de détectér l\'authentification.';
@override
String get showDebug => 'Afficher le debogage';
@@ -564,7 +590,8 @@ class SFr extends S {
String get noChapters => 'Aucun chapitre';
@override
String get noChapterInfo => 'Ce livre audio n\'a pas d\'informations de chapitre';
String get noChapterInfo =>
'Ce livre audio n\'a pas d\'informations de chapitre';
@override
String errorSeeking(String error) {
@@ -637,10 +664,12 @@ class SFr extends S {
String get artist => 'Artiste';
@override
String get showRecentlyPlayedAlbums => 'Afficher les albums écoutes recemment';
String get showRecentlyPlayedAlbums =>
'Afficher les albums écoutes recemment';
@override
String get showRandomArtists => 'Afficher des artistes aléatoires a découvrir';
String get showRandomArtists =>
'Afficher des artistes aléatoires a découvrir';
@override
String get showRandomAlbums => 'Afficher des albums aléatoires a découvrir';
@@ -649,34 +678,43 @@ class SFr extends S {
String get showAudiobooksInProgress => 'Afficher les livres audio en cours';
@override
String get showRandomAudiobooks => 'Afficher des livres audio aléatoires a découvrir';
String get showRandomAudiobooks =>
'Afficher des livres audio aléatoires a découvrir';
@override
String get showRandomSeries => 'Afficher des séries de livres audio aléatoires a découvrir';
String get showRandomSeries =>
'Afficher des séries de livres audio aléatoires a découvrir';
@override
String get showFavoriteAlbums => 'Afficher une rangee de vos albums favoris';
@override
String get showFavoriteArtists => 'Afficher une rangee de vos artistes favoris';
String get showFavoriteArtists =>
'Afficher une rangee de vos artistes favoris';
@override
String get showFavoriteTracks => 'Afficher une rangee de vos pistes favorites';
String get showFavoriteTracks =>
'Afficher une rangee de vos pistes favorites';
@override
String get showFavoritePlaylists => 'Afficher une rangee de vos playlists favorites';
String get showFavoritePlaylists =>
'Afficher une rangee de vos playlists favorites';
@override
String get showFavoriteRadioStations => 'Afficher une rangee de vos stations de radio favorites';
String get showFavoriteRadioStations =>
'Afficher une rangee de vos stations de radio favorites';
@override
String get showFavoritePodcasts => 'Afficher une rangee de vos podcasts favoris';
String get showFavoritePodcasts =>
'Afficher une rangee de vos podcasts favoris';
@override
String get extractColorsFromArtwork => 'Extraire les couleurs des pochettes d\'albums et d\'artistes';
String get extractColorsFromArtwork =>
'Extraire les couleurs des pochettes d\'albums et d\'artistes';
@override
String get chooseHomeScreenRows => 'Choisir les rangees a afficher sur l\'ecran d\'accueil';
String get chooseHomeScreenRows =>
'Choisir les rangees a afficher sur l\'ecran d\'accueil';
@override
String get addedToFavorites => 'Ajoute aux favoris';
@@ -721,13 +759,15 @@ class SFr extends S {
String get podcasts => 'Podcasts';
@override
String get podcastSupportComingSoon => 'Prise en charge des podcasts bientot disponible';
String get podcastSupportComingSoon =>
'Prise en charge des podcasts bientot disponible';
@override
String get noPodcasts => 'Aucun podcast';
@override
String get addPodcastsHint => 'Abonnez-vous a des podcasts dans Music Assistant';
String get addPodcastsHint =>
'Abonnez-vous a des podcasts dans Music Assistant';
@override
String get episodes => 'Episodes';
@@ -774,7 +814,8 @@ class SFr extends S {
String get loadingChapters => 'Chargement des chapitres...';
@override
String get noChapterInfoAvailable => 'Aucune information de chapitre disponible';
String get noChapterInfoAvailable =>
'Aucune information de chapitre disponible';
@override
String percentComplete(int percent) {
@@ -785,13 +826,15 @@ class SFr extends S {
String get theAudioDbApiKey => 'Cle API TheAudioDB';
@override
String get theAudioDbApiKeyHint => 'Utilisez \"2\" pour le niveau gratuit ou une cle premium';
String get theAudioDbApiKeyHint =>
'Utilisez \"2\" pour le niveau gratuit ou une cle premium';
@override
String get audiobookLibraries => 'Bibliothèques de livres audio';
@override
String get chooseAudiobookLibraries => 'Choisir quelles bibliothèques Audiobookshelf inclure';
String get chooseAudiobookLibraries =>
'Choisir quelles bibliothèques Audiobookshelf inclure';
@override
String get unknownLibrary => 'Bibliothèque inconnue';
@@ -800,7 +843,8 @@ class SFr extends S {
String get musicProviders => 'Music Providers';
@override
String get musicProvidersDescription => 'Choose which accounts to show in your library';
String get musicProvidersDescription =>
'Choose which accounts to show in your library';
@override
String get libraryRefreshing => 'Refreshing library...';
@@ -820,16 +864,19 @@ class SFr extends S {
}
@override
String get noSeriesAvailable => 'Aucune série disponible dans votre bibliothèque de livres audio.\nTirez pour rafraichir.';
String get noSeriesAvailable =>
'Aucune série disponible dans votre bibliothèque de livres audio.\nTirez pour rafraichir.';
@override
String get pullToLoadSeries => 'Tirez vers le bas pour charger les séries\ndepuis Music Assistant';
String get pullToLoadSeries =>
'Tirez vers le bas pour charger les séries\ndepuis Music Assistant';
@override
String get search => 'Rechercher';
@override
String get metadataApisDescription => 'Les images d\'artistes sont automatiquement recuperees depuis Deezer. Ajoutez les cles API ci-dessous pour les biographies d\'artistes et les descriptions d\'albums.';
String get metadataApisDescription =>
'Les images d\'artistes sont automatiquement recuperees depuis Deezer. Ajoutez les cles API ci-dessous pour les biographies d\'artistes et les descriptions d\'albums.';
@override
String get lastFmApiKey => 'Cle API Last.fm';
@@ -852,7 +899,8 @@ class SFr extends S {
String get playOn => 'Lire sur...';
@override
String get addAlbumToQueueOn => 'Ajouter l\'album a la file d\'attente sur...';
String get addAlbumToQueueOn =>
'Ajouter l\'album a la file d\'attente sur...';
@override
String get addToQueueOn => 'Ajouter a la file d\'attente sur...';
@@ -889,7 +937,8 @@ class SFr extends S {
}
@override
String get materialYouDescription => 'Utiliser les couleurs systeme (Android 12+)';
String get materialYouDescription =>
'Utiliser les couleurs systeme (Android 12+)';
@override
String get accentColor => 'Couleur d\'accentuation';
@@ -901,19 +950,22 @@ class SFr extends S {
String get preferLocalPlayer => 'Préférer le lecteur local';
@override
String get preferLocalPlayerDescription => 'Toujours sélectionner cet appareil en premier si disponible';
String get preferLocalPlayerDescription =>
'Toujours sélectionner cet appareil en premier si disponible';
@override
String get smartSortPlayers => 'Tri intelligent';
@override
String get smartSortPlayersDescription => 'Trier par statut (en lecture, allume, eteint) au lieu d\'alphabétiquement';
String get smartSortPlayersDescription =>
'Trier par statut (en lecture, allume, eteint) au lieu d\'alphabétiquement';
@override
String get disableAutoSwitch => 'Disable Auto-Switch';
@override
String get disableAutoSwitchDescription => 'Never automatically switch to a different player';
String get disableAutoSwitchDescription =>
'Never automatically switch to a different player';
@override
String get playerStateUnavailable => 'Indisponible';
@@ -945,7 +997,8 @@ class SFr extends S {
String get showHints => 'Afficher les astuces';
@override
String get showHintsDescription => 'Afficher des conseils utiles pour découvrir les fonctionnalites';
String get showHintsDescription =>
'Afficher des conseils utiles pour découvrir les fonctionnalites';
@override
String get display => 'Display';
@@ -954,7 +1007,8 @@ class SFr extends S {
String get showProviderIcons => 'Show Provider Icons';
@override
String get showProviderIconsDescription => 'Display provider logos on album art';
String get showProviderIconsDescription =>
'Display provider logos on album art';
@override
String get pullToSelectPlayers => 'Tirez pour sélectionner les lecteurs';
@@ -966,19 +1020,22 @@ class SFr extends S {
String get swipeToAdjustVolume => 'Balayez pour ajuster le volume';
@override
String get selectPlayerHint => 'Choisissez un lecteur ou fermez en balayant vers le bas';
String get selectPlayerHint =>
'Choisissez un lecteur ou fermez en balayant vers le bas';
@override
String get welcomeToEnsemble => 'Bienvenue dans Ensemble';
@override
String get welcomeMessage => 'Par defaut, votre telephone est le lecteur selectionne.\nTirez le mini-lecteur vers le bas pour sélectionner un autre lecteur.';
String get welcomeMessage =>
'Par defaut, votre telephone est le lecteur selectionne.\nTirez le mini-lecteur vers le bas pour sélectionner un autre lecteur.';
@override
String get skip => 'Passer';
@override
String get dismissPlayerHint => 'Balayez vers le bas, touchez a l\'exterieur ou appuyez sur retour pour revenir';
String get dismissPlayerHint =>
'Balayez vers le bas, touchez a l\'exterieur ou appuyez sur retour pour revenir';
@override
String playingAlbum(String albumName) {
@@ -994,19 +1051,22 @@ class SFr extends S {
String get noTracks => 'No tracks';
@override
String get addTracksHint => 'Add some music to your library to see tracks here';
String get addTracksHint =>
'Add some music to your library to see tracks here';
@override
String get noFavoriteRadioStations => 'No favorite radio stations';
@override
String get longPressRadioHint => 'Long-press a station and tap the heart to add it to favorites';
String get longPressRadioHint =>
'Long-press a station and tap the heart to add it to favorites';
@override
String get noFavoritePodcasts => 'No favorite podcasts';
@override
String get longPressPodcastHint => 'Long-press a podcast and tap the heart to add it to favorites';
String get longPressPodcastHint =>
'Long-press a podcast and tap the heart to add it to favorites';
@override
String failedToPlayRadioStation(String error) {
@@ -24,6 +24,7 @@ import '../services/position_tracker.dart';
import '../services/sendspin_service.dart';
import '../services/pcm_audio_player.dart';
import '../services/offline_action_queue.dart';
import '../services/remote/remote_bridge.dart';
import '../constants/timings.dart';
import '../services/database_service.dart';
import '../main.dart' show audioHandler;
@@ -105,6 +106,10 @@ class MusicAssistantProvider with ChangeNotifier {
SendspinService? _sendspinService;
bool _sendspinConnected = false;
// Remote connection (WebRTC-to-WS bridge for remote access)
RemoteBridge? _remoteBridge;
bool get isRemoteConnection => _remoteBridge != null && _remoteBridge!.isRunning;
// PCM audio player for raw Sendspin audio streaming
PcmAudioPlayer? _pcmAudioPlayer;
@@ -1125,6 +1130,61 @@ class MusicAssistantProvider with ChangeNotifier {
}
}
/// Connect to a remote MA server via WebRTC using Remote Access ID.
/// Uses a WebRTC-to-WebSocket bridge so MusicAssistantAPI works unchanged.
Future<bool> connectRemote(String remoteId, String username, String password) async {
_logger.log('🌐 Attempting remote connection to: $remoteId');
try {
_error = null;
_connectionState = MAConnectionState.connecting;
notifyListeners();
// Start the WebRTC-to-WS bridge
_remoteBridge = RemoteBridge();
final port = await _remoteBridge!.start(remoteId, username, password);
if (port == null) {
_logger.log('❌ Remote bridge failed to start');
_remoteBridge = null;
_connectionState = MAConnectionState.error;
_error = 'Remote connection failed';
notifyListeners();
return false;
}
_logger.log('✅ Remote bridge started on port $port');
// Connect via normal API - it will hit the local bridge
// The bridge already authenticated, so we use the same credentials
await SettingsService.setUsername(username);
await SettingsService.setPassword(password);
await connectToServer('ws://localhost:$port');
// Wait a moment for connection to establish
await Future.delayed(const Duration(milliseconds: 500));
if (isConnected) {
_logger.log('✅ Remote connection via bridge successful!');
return true;
} else {
_logger.log('❌ Connection to bridge failed, stopping bridge');
await _remoteBridge?.stop();
_remoteBridge = null;
return false;
}
} catch (e) {
_logger.log('❌ Remote connection error: $e');
await _remoteBridge?.stop();
_remoteBridge = null;
_error = e.toString();
_connectionState = MAConnectionState.error;
notifyListeners();
return false;
}
}
Future<bool> _handleMaAuthentication() async {
if (_api == null) return false;
@@ -1816,6 +1876,11 @@ class MusicAssistantProvider with ChangeNotifier {
_sendspinConnected = false;
}
await _api?.disconnect();
// Stop remote bridge if running
if (_remoteBridge != null) {
await _remoteBridge!.stop();
_remoteBridge = null;
}
_connectionState = MAConnectionState.disconnected;
// DON'T clear caches or player state - keep for instant reconnect
_logger.log('📡 Explicit disconnect - keeping cached data for instant resume');
+228 -5
View File
@@ -5,11 +5,12 @@ import '../services/settings_service.dart';
import '../services/database_service.dart';
import '../services/profile_service.dart';
import '../services/auth/auth_strategy.dart';
import '../services/debug_logger.dart';
import '../widgets/debug/debug_console.dart';
import '../l10n/app_localizations.dart';
import 'home_screen.dart';
enum ConnectionMode { local, remote }
class LoginScreen extends StatefulWidget {
const LoginScreen({super.key});
@@ -24,8 +25,10 @@ class _LoginScreenState extends State<LoginScreen> {
final TextEditingController _authServerUrlController = TextEditingController(); // For separate auth server (Authelia)
final TextEditingController _usernameController = TextEditingController();
final TextEditingController _passwordController = TextEditingController();
final TextEditingController _remoteIdController = TextEditingController(); // Remote Access ID
final FocusNode _usernameFocusNode = FocusNode();
ConnectionMode _connectionMode = ConnectionMode.local;
bool _isConnecting = false;
bool _isDetectingAuth = false;
AuthStrategy? _detectedAuthStrategy;
@@ -74,6 +77,7 @@ class _LoginScreenState extends State<LoginScreen> {
_authServerUrlController.dispose();
_usernameController.dispose();
_passwordController.dispose();
_remoteIdController.dispose();
_usernameFocusNode.dispose();
super.dispose();
}
@@ -477,6 +481,68 @@ class _LoginScreenState extends State<LoginScreen> {
}
}
Future<void> _connectRemote() async {
final remoteId = _remoteIdController.text.trim();
if (remoteId.isEmpty) {
setState(() {
_error = 'Please enter a Remote Access ID';
});
return;
}
final username = _usernameController.text.trim();
final password = _passwordController.text.trim();
if (username.isEmpty || password.isEmpty) {
setState(() {
_error = S.of(context)!.pleaseEnterCredentials;
});
return;
}
setState(() {
_isConnecting = true;
_error = null;
});
_addDebugLog('Connecting to remote server: $remoteId');
try {
final provider = context.read<MusicAssistantProvider>();
// Connect via remote access
final success = await provider.connectRemote(remoteId, username, password);
if (success) {
_addDebugLog('Remote connection successful');
// Save credentials for future use
await SettingsService.setRemoteAccessId(remoteId);
await SettingsService.setUsername(username);
await SettingsService.setPassword(password);
// Navigate to home screen
if (mounted) {
FocusScope.of(context).unfocus();
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => const HomeScreen()),
);
}
} else {
setState(() {
_error = 'Remote connection failed. Check your credentials and Remote Access ID.';
_isConnecting = false;
});
}
} catch (e) {
_addDebugLog('Remote connection error: $e');
setState(() {
_error = 'Connection failed: ${e.toString()}';
_isConnecting = false;
});
}
}
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
@@ -509,8 +575,160 @@ class _LoginScreenState extends State<LoginScreen> {
},
),
const SizedBox(height: 48),
const SizedBox(height: 32),
// Connection mode selector
SegmentedButton<ConnectionMode>(
segments: [
ButtonSegment<ConnectionMode>(
value: ConnectionMode.local,
label: Text('Local'),
icon: Icon(Icons.home_rounded),
),
ButtonSegment<ConnectionMode>(
value: ConnectionMode.remote,
label: Text('Remote'),
icon: Icon(Icons.cloud_rounded),
),
],
selected: {_connectionMode},
onSelectionChanged: _isConnecting || _isDetectingAuth
? null
: (Set<ConnectionMode> selection) {
setState(() {
_connectionMode = selection.first;
_error = null;
_detectedAuthStrategy = null;
_detectedAuthType = null;
});
},
style: ButtonStyle(
backgroundColor: WidgetStateProperty.resolveWith((states) {
if (states.contains(WidgetState.selected)) {
return colorScheme.primaryContainer;
}
return colorScheme.surfaceVariant.withOpacity(0.3);
}),
),
),
const SizedBox(height: 32),
// Remote Access UI
if (_connectionMode == ConnectionMode.remote) ...[
Text(
'Remote Access ID',
style: textTheme.titleMedium?.copyWith(
color: colorScheme.onBackground,
fontWeight: FontWeight.w500,
),
),
const SizedBox(height: 8),
Text(
'Find this in Music Assistant Settings → Remote Access',
style: TextStyle(
color: colorScheme.onBackground.withOpacity(0.6),
fontSize: 12,
),
),
const SizedBox(height: 12),
TextField(
controller: _remoteIdController,
style: TextStyle(color: colorScheme.onSurface),
decoration: InputDecoration(
hintText: 'XXXX-XXXX-XXXX-XXXX',
hintStyle: TextStyle(color: colorScheme.onSurface.withOpacity(0.38)),
filled: true,
fillColor: colorScheme.surfaceVariant.withOpacity(0.3),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide.none,
),
prefixIcon: Icon(
Icons.vpn_key_rounded,
color: colorScheme.onSurface.withOpacity(0.54),
),
),
enabled: !_isConnecting,
textCapitalization: TextCapitalization.characters,
textInputAction: TextInputAction.next,
),
const SizedBox(height: 24),
// Username
Text(
S.of(context)!.username,
style: textTheme.titleMedium?.copyWith(
color: colorScheme.onBackground,
fontWeight: FontWeight.w500,
),
),
const SizedBox(height: 12),
TextField(
controller: _usernameController,
focusNode: _usernameFocusNode,
style: TextStyle(color: colorScheme.onSurface),
decoration: InputDecoration(
hintText: S.of(context)!.username,
hintStyle: TextStyle(color: colorScheme.onSurface.withOpacity(0.38)),
filled: true,
fillColor: colorScheme.surfaceVariant.withOpacity(0.3),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide.none,
),
prefixIcon: Icon(
Icons.person_rounded,
color: colorScheme.onSurface.withOpacity(0.54),
),
),
enabled: !_isConnecting,
textInputAction: TextInputAction.next,
),
const SizedBox(height: 16),
// Password
Text(
S.of(context)!.password,
style: textTheme.titleMedium?.copyWith(
color: colorScheme.onBackground,
fontWeight: FontWeight.w500,
),
),
const SizedBox(height: 12),
TextField(
controller: _passwordController,
style: TextStyle(color: colorScheme.onSurface),
decoration: InputDecoration(
hintText: S.of(context)!.password,
hintStyle: TextStyle(color: colorScheme.onSurface.withOpacity(0.38)),
filled: true,
fillColor: colorScheme.surfaceVariant.withOpacity(0.3),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide.none,
),
prefixIcon: Icon(
Icons.lock_rounded,
color: colorScheme.onSurface.withOpacity(0.54),
),
),
obscureText: true,
enabled: !_isConnecting,
textInputAction: TextInputAction.done,
onSubmitted: (_) => _connectRemote(),
),
const SizedBox(height: 24),
],
// Local connection UI
if (_connectionMode == ConnectionMode.local) ...[
// Server URL
Text(
S.of(context)!.serverAddress,
@@ -856,6 +1074,7 @@ class _LoginScreenState extends State<LoginScreen> {
const SizedBox(height: 16),
],
], // End of local connection UI
const SizedBox(height: 16),
@@ -898,11 +1117,13 @@ class _LoginScreenState extends State<LoginScreen> {
const SizedBox(height: 16),
],
// Connect button (changes based on state)
// Connect button (changes based on state and mode)
ElevatedButton(
onPressed: (_isConnecting || _isDetectingAuth)
? null
: (_detectedAuthStrategy == null ? _detectAuthRequirements : _connect),
: _connectionMode == ConnectionMode.remote
? _connectRemote
: (_detectedAuthStrategy == null ? _detectAuthRequirements : _connect),
style: ElevatedButton.styleFrom(
backgroundColor: colorScheme.primary,
foregroundColor: colorScheme.onPrimary,
@@ -944,7 +1165,9 @@ class _LoginScreenState extends State<LoginScreen> {
),
)
: Text(
_detectedAuthStrategy == null ? S.of(context)!.detectAndConnect : S.of(context)!.connect,
_connectionMode == ConnectionMode.remote
? S.of(context)!.connect
: (_detectedAuthStrategy == null ? S.of(context)!.detectAndConnect : S.of(context)!.connect),
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
+19
View File
@@ -178,6 +178,9 @@ class SettingsService {
// Podcast Cover Cache (iTunes URLs for high-res artwork)
static const String _keyPodcastCoverCache = 'podcast_cover_cache';
// Remote Access Settings
static const String _keyRemoteAccessId = 'remote_access_id';
static Future<String?> getServerUrl() async {
final prefs = await _getPrefs();
return prefs.getString(_keyServerUrl);
@@ -265,6 +268,22 @@ class SettingsService {
await SecureStorageService.clearAuthCredentials();
}
// Get Remote Access ID for remote connections
static Future<String?> getRemoteAccessId() async {
final prefs = await _getPrefs();
return prefs.getString(_keyRemoteAccessId);
}
// Set Remote Access ID for remote connections
static Future<void> setRemoteAccessId(String? id) async {
final prefs = await _getPrefs();
if (id == null || id.isEmpty) {
await prefs.remove(_keyRemoteAccessId);
} else {
await prefs.setString(_keyRemoteAccessId, id);
}
}
// Get username for authentication
static Future<String?> getUsername() async {
final prefs = await _getPrefs();
+2 -2
View File
@@ -68,7 +68,7 @@ class AppTheme {
foregroundColor: scheme.onBackground,
iconTheme: IconThemeData(color: scheme.onBackground),
),
cardTheme: CardTheme(
cardTheme: CardThemeData(
color: scheme.surface,
elevation: 2,
),
@@ -91,7 +91,7 @@ class AppTheme {
foregroundColor: scheme.onBackground,
iconTheme: IconThemeData(color: scheme.onBackground),
),
cardTheme: CardTheme(
cardTheme: CardThemeData(
color: scheme.surface,
elevation: 2,
),
+86 -67
View File
@@ -5,23 +5,18 @@ packages:
dependency: transitive
description:
name: _fe_analyzer_shared
sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834
sha256: c209688d9f5a5f26b2fb47a188131a6fb9e876ae9e47af3737c0b4f58a93470d
url: "https://pub.dev"
source: hosted
version: "72.0.0"
_macros:
dependency: transitive
description: dart
source: sdk
version: "0.3.2"
version: "91.0.0"
analyzer:
dependency: transitive
description:
name: analyzer
sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139
sha256: f51c8499b35f9b26820cfe914828a6a98a94efd5cc78b37bb7d03debae3a1d08
url: "https://pub.dev"
source: hosted
version: "6.7.0"
version: "8.4.1"
archive:
dependency: transitive
description:
@@ -90,10 +85,10 @@ packages:
dependency: transitive
description:
name: build
sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0"
sha256: "7174c5d84b0fed00a1f5e7543597b35d67560465ae3d909f0889b8b20419d5e3"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
version: "3.0.1"
build_config:
dependency: transitive
description:
@@ -114,26 +109,26 @@ packages:
dependency: transitive
description:
name: build_resolvers
sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a"
sha256: "82730bf3d9043366ba8c02e4add05842a10739899520a6a22ddbd22d333bd5bb"
url: "https://pub.dev"
source: hosted
version: "2.4.2"
version: "3.0.1"
build_runner:
dependency: "direct dev"
description:
name: build_runner
sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d"
sha256: "32c6b3d172f1f46b7c4df6bc4a47b8d88afb9e505dd4ace4af80b3c37e89832b"
url: "https://pub.dev"
source: hosted
version: "2.4.13"
version: "2.6.1"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0
sha256: "4b188774b369104ad96c0e4ca2471e5162f0566ce277771b179bed5eabf2d048"
url: "https://pub.dev"
source: hosted
version: "7.3.2"
version: "9.2.1"
built_collection:
dependency: transitive
description:
@@ -178,10 +173,10 @@ packages:
dependency: transitive
description:
name: characters
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
url: "https://pub.dev"
source: hosted
version: "1.3.0"
version: "1.4.0"
charcode:
dependency: transitive
description:
@@ -210,10 +205,10 @@ packages:
dependency: transitive
description:
name: clock
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
url: "https://pub.dev"
source: hosted
version: "1.1.1"
version: "1.1.2"
code_builder:
dependency: transitive
description:
@@ -226,10 +221,10 @@ packages:
dependency: transitive
description:
name: collection
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
url: "https://pub.dev"
source: hosted
version: "1.18.0"
version: "1.19.1"
convert:
dependency: transitive
description:
@@ -258,10 +253,18 @@ packages:
dependency: transitive
description:
name: dart_style
sha256: "7856d364b589d1f08986e140938578ed36ed948581fbc3bc9aef1805039ac5ab"
sha256: a9c30492da18ff84efe2422ba2d319a89942d93e58eb0b73d32abe822ef54b7b
url: "https://pub.dev"
source: hosted
version: "2.3.7"
version: "3.1.3"
dart_webrtc:
dependency: transitive
description:
name: dart_webrtc
sha256: "51bcda4ba5d7dd9e65a309244ce3ac0b58025e6e1f6d7442cee4cd02134ef65f"
url: "https://pub.dev"
source: hosted
version: "1.6.0"
device_info_plus:
dependency: "direct main"
description:
@@ -282,18 +285,18 @@ packages:
dependency: "direct main"
description:
name: drift
sha256: af3941e4d544727b2eb80590eb64e9cb8d77cd68c7690265502ea6a2427aa621
sha256: "5ea2f718558c0b31d4b8c36a3d8e5b7016f1265f46ceb5a5920e16117f0c0d6a"
url: "https://pub.dev"
source: hosted
version: "2.23.1"
version: "2.30.1"
drift_dev:
dependency: "direct dev"
description:
name: drift_dev
sha256: fa98fdbb7303a1b5b2dc110cb516eda2253a5d291680f8cbc72b1af24099f7f9
sha256: "892dfb5d69d9e604bdcd102a9376de8b41768cf7be93fd26b63cfc4d8f91ad5f"
url: "https://pub.dev"
source: hosted
version: "2.23.1"
version: "2.30.1"
drift_flutter:
dependency: "direct main"
description:
@@ -314,10 +317,10 @@ packages:
dependency: transitive
description:
name: fake_async
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
url: "https://pub.dev"
source: hosted
version: "1.3.1"
version: "1.3.3"
ffi:
dependency: transitive
description:
@@ -466,6 +469,14 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_webrtc:
dependency: "direct main"
description:
name: flutter_webrtc
sha256: "71a38363a5b50603e405c275f30de2eb90f980b0cc94b0e1e9d8b9d6a6b03bf0"
url: "https://pub.dev"
source: hosted
version: "1.2.1"
frontend_server_client:
dependency: transitive
description:
@@ -526,10 +537,10 @@ packages:
dependency: "direct main"
description:
name: intl
sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5"
url: "https://pub.dev"
source: hosted
version: "0.19.0"
version: "0.20.2"
io:
dependency: transitive
description:
@@ -582,26 +593,26 @@ packages:
dependency: transitive
description:
name: leak_tracker
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
url: "https://pub.dev"
source: hosted
version: "10.0.5"
version: "11.0.2"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
url: "https://pub.dev"
source: hosted
version: "3.0.5"
version: "3.0.10"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
url: "https://pub.dev"
source: hosted
version: "3.0.1"
version: "3.0.2"
lints:
dependency: transitive
description:
@@ -610,6 +621,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.0"
logger:
dependency: transitive
description:
name: logger
sha256: a7967e31b703831a893bbc3c3dd11db08126fe5f369b5c648a36f821979f5be3
url: "https://pub.dev"
source: hosted
version: "2.6.2"
logging:
dependency: transitive
description:
@@ -618,22 +637,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.0"
macros:
dependency: transitive
description:
name: macros
sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536"
url: "https://pub.dev"
source: hosted
version: "0.1.2-main.4"
matcher:
dependency: transitive
description:
name: matcher
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
url: "https://pub.dev"
source: hosted
version: "0.12.16+1"
version: "0.12.17"
material_color_utilities:
dependency: transitive
description:
@@ -654,10 +665,10 @@ packages:
dependency: transitive
description:
name: meta
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
url: "https://pub.dev"
source: hosted
version: "1.15.0"
version: "1.17.0"
mime:
dependency: transitive
description:
@@ -718,10 +729,10 @@ packages:
dependency: transitive
description:
name: path
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
url: "https://pub.dev"
source: hosted
version: "1.9.0"
version: "1.9.1"
path_parsing:
dependency: transitive
description:
@@ -950,15 +961,15 @@ packages:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
version: "0.0.0"
source_gen:
dependency: transitive
description:
name: source_gen
sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832"
sha256: "1d562a3c1f713904ebbed50d2760217fd8a51ca170ac4b05b0db490699dbac17"
url: "https://pub.dev"
source: hosted
version: "1.5.0"
version: "4.2.0"
source_span:
dependency: transitive
description:
@@ -1027,26 +1038,26 @@ packages:
dependency: transitive
description:
name: sqlparser
sha256: "4cad4b2c5f63dc9ea1a8dcffb58cf762322bea5dd8836870164a65e913bdae41"
sha256: f52f5d5649dcc13ed198c4176ddef74bf6851c30f4f31603f1b37788695b93e2
url: "https://pub.dev"
source: hosted
version: "0.40.0"
version: "0.43.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
url: "https://pub.dev"
source: hosted
version: "1.11.1"
version: "1.12.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
version: "2.1.4"
stream_transform:
dependency: transitive
description:
@@ -1083,10 +1094,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
url: "https://pub.dev"
source: hosted
version: "0.7.2"
version: "0.7.7"
timing:
dependency: transitive
description:
@@ -1171,10 +1182,10 @@ packages:
dependency: transitive
description:
name: vector_math
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
url: "https://pub.dev"
source: hosted
version: "2.1.4"
version: "2.2.0"
vm_service:
dependency: transitive
description:
@@ -1207,6 +1218,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.4.0"
webrtc_interface:
dependency: transitive
description:
name: webrtc_interface
sha256: "2e604a31703ad26781782fb14fa8a4ee621154ee2c513d2b9938e486fa695233"
url: "https://pub.dev"
source: hosted
version: "1.3.0"
win32:
dependency: transitive
description:
@@ -1248,5 +1267,5 @@ packages:
source: hosted
version: "3.1.3"
sdks:
dart: ">=3.5.0 <4.0.0"
dart: ">=3.9.0 <4.0.0"
flutter: ">=3.24.0"
+4 -1
View File
@@ -11,7 +11,7 @@ dependencies:
sdk: flutter
flutter_localizations:
sdk: flutter
intl: ^0.19.0
intl: ^0.20.2
# UI
material_design_icons_flutter: ^7.0.7296
@@ -27,6 +27,9 @@ dependencies:
http: ^1.1.0
cached_network_image: ^3.3.1
# WebRTC (for remote access)
flutter_webrtc: ^1.2.1
# Storage
shared_preferences: ^2.2.2
flutter_secure_storage: ^9.2.2