fix: remove companion remote connection history

This commit is contained in:
edde746
2026-02-26 01:08:46 +01:00
parent acf91107ad
commit 659b59d450
23 changed files with 30 additions and 725 deletions
+1 -9
View File
@@ -732,11 +732,8 @@
"minimize": "Minimieren"
},
"pairing": {
"recent": "Zuletzt",
"scan": "Scannen",
"manual": "Manuell",
"recentConnections": "Letzte Verbindungen",
"quickReconnect": "Schnell mit zuvor gekoppelten Geräten verbinden",
"pairWithDesktop": "Mit Desktop koppeln",
"enterSessionDetails": "Gib die Sitzungsdetails ein, die auf deinem Desktop-Gerät angezeigt werden",
"hostAddressHint": "192.168.1.100:48632",
@@ -750,11 +747,7 @@
"cameraPermissionRequired": "Kameraberechtigung wird zum Scannen von QR-Codes benötigt.\nBitte erteile den Kamerazugriff in den Geräteeinstellungen.",
"cameraError": "Kamera konnte nicht gestartet werden: ${error}",
"scanInstruction": "Richte deine Kamera auf den QR-Code auf deinem Desktop",
"noRecentConnections": "Keine letzten Verbindungen",
"connectUsingManual": "Verbinde dich über die manuelle Eingabe, um loszulegen",
"invalidQrCode": "Ungültiges QR-Code-Format",
"removeRecentConnection": "Letzte Verbindung entfernen",
"removeConfirm": "\"${name}\" aus den letzten Verbindungen entfernen?",
"validationHostRequired": "Bitte Host-Adresse eingeben",
"validationHostFormat": "Format muss IP:Port sein (z.B. 192.168.1.100:48632)",
"validationSessionIdRequired": "Bitte Sitzungs-ID eingeben",
@@ -763,8 +756,7 @@
"validationPinLength": "PIN muss 6 Ziffern haben",
"connectionTimedOut": "Zeitüberschreitung. Bitte Sitzungs-ID und PIN überprüfen.",
"sessionNotFound": "Sitzung nicht gefunden. Bitte Zugangsdaten überprüfen.",
"failedToConnect": "Verbindung fehlgeschlagen: ${error}",
"failedToLoadRecent": "Letzte Sitzungen konnten nicht geladen werden: ${error}"
"failedToConnect": "Verbindung fehlgeschlagen: ${error}"
},
"remote": {
"disconnectConfirm": "Möchtest du die Verbindung zur Fernsteuerungssitzung trennen?",
+1 -9
View File
@@ -732,11 +732,8 @@
"minimize": "Minimize"
},
"pairing": {
"recent": "Recent",
"scan": "Scan",
"manual": "Manual",
"recentConnections": "Recent Connections",
"quickReconnect": "Quickly reconnect to previously paired devices",
"pairWithDesktop": "Pair with Desktop",
"enterSessionDetails": "Enter the session details shown on your desktop device",
"hostAddressHint": "192.168.1.100:48632",
@@ -750,11 +747,7 @@
"cameraPermissionRequired": "Camera permission is required to scan QR codes.\nPlease grant camera access in your device settings.",
"cameraError": "Could not start camera: ${error}",
"scanInstruction": "Point your camera at the QR code shown on your desktop",
"noRecentConnections": "No recent connections",
"connectUsingManual": "Connect to a device using Manual entry to get started",
"invalidQrCode": "Invalid QR code format",
"removeRecentConnection": "Remove Recent Connection",
"removeConfirm": "Remove \"${name}\" from recent connections?",
"validationHostRequired": "Please enter host address",
"validationHostFormat": "Format must be IP:port (e.g., 192.168.1.100:48632)",
"validationSessionIdRequired": "Please enter a session ID",
@@ -763,8 +756,7 @@
"validationPinLength": "PIN must be 6 digits",
"connectionTimedOut": "Connection timed out. Please check the session ID and PIN.",
"sessionNotFound": "Could not find the session. Please check your credentials.",
"failedToConnect": "Failed to connect: ${error}",
"failedToLoadRecent": "Failed to load recent sessions: ${error}"
"failedToConnect": "Failed to connect: ${error}"
},
"remote": {
"disconnectConfirm": "Do you want to disconnect from the remote session?",
+1 -9
View File
@@ -732,11 +732,8 @@
"minimize": "Minimizar"
},
"pairing": {
"recent": "Recientes",
"scan": "Escanear",
"manual": "Manual",
"recentConnections": "Conexiones recientes",
"quickReconnect": "Reconectar rápidamente con dispositivos emparejados anteriormente",
"pairWithDesktop": "Emparejar con escritorio",
"enterSessionDetails": "Introduce los datos de la sesión que aparecen en tu dispositivo de escritorio",
"hostAddressHint": "192.168.1.100:48632",
@@ -750,11 +747,7 @@
"cameraPermissionRequired": "Se necesita permiso de cámara para escanear códigos QR.\nPor favor, concede acceso a la cámara en los ajustes de tu dispositivo.",
"cameraError": "No se pudo iniciar la cámara: ${error}",
"scanInstruction": "Apunta tu cámara al código QR que aparece en tu escritorio",
"noRecentConnections": "No hay conexiones recientes",
"connectUsingManual": "Conéctate a un dispositivo usando la entrada manual para empezar",
"invalidQrCode": "Formato de código QR no válido",
"removeRecentConnection": "Eliminar conexión reciente",
"removeConfirm": "¿Eliminar \"${name}\" de las conexiones recientes?",
"validationHostRequired": "Por favor, introduce la dirección del host",
"validationHostFormat": "El formato debe ser IP:puerto (ej., 192.168.1.100:48632)",
"validationSessionIdRequired": "Por favor, introduce un ID de sesión",
@@ -763,8 +756,7 @@
"validationPinLength": "El PIN debe tener 6 dígitos",
"connectionTimedOut": "Tiempo de conexión agotado. Verifica el ID de sesión y el PIN.",
"sessionNotFound": "No se encontró la sesión. Verifica tus credenciales.",
"failedToConnect": "Error al conectar: ${error}",
"failedToLoadRecent": "Error al cargar sesiones recientes: ${error}"
"failedToConnect": "Error al conectar: ${error}"
},
"remote": {
"disconnectConfirm": "¿Quieres desconectarte de la sesión remota?",
+1 -9
View File
@@ -732,11 +732,8 @@
"minimize": "Réduire"
},
"pairing": {
"recent": "Récents",
"scan": "Scanner",
"manual": "Manuel",
"recentConnections": "Connexions récentes",
"quickReconnect": "Reconnexion rapide aux appareils précédemment jumelés",
"pairWithDesktop": "Jumeler avec un bureau",
"enterSessionDetails": "Saisissez les détails de la session affichés sur votre appareil de bureau",
"hostAddressHint": "192.168.1.100:48632",
@@ -750,11 +747,7 @@
"cameraPermissionRequired": "L'autorisation de la caméra est requise pour scanner les QR codes.\nVeuillez accorder l'accès à la caméra dans les paramètres de votre appareil.",
"cameraError": "Impossible de démarrer la caméra : ${error}",
"scanInstruction": "Pointez votre caméra vers le QR code affiché sur votre bureau",
"noRecentConnections": "Aucune connexion récente",
"connectUsingManual": "Connectez-vous à un appareil via la saisie manuelle pour commencer",
"invalidQrCode": "Format de QR code invalide",
"removeRecentConnection": "Supprimer la connexion récente",
"removeConfirm": "Supprimer \"${name}\" des connexions récentes ?",
"validationHostRequired": "Veuillez saisir l'adresse de l'hôte",
"validationHostFormat": "Le format doit être IP:port (ex : 192.168.1.100:48632)",
"validationSessionIdRequired": "Veuillez saisir un ID de session",
@@ -763,8 +756,7 @@
"validationPinLength": "Le PIN doit contenir 6 chiffres",
"connectionTimedOut": "Délai de connexion expiré. Veuillez vérifier l'ID de session et le PIN.",
"sessionNotFound": "Session introuvable. Veuillez vérifier vos identifiants.",
"failedToConnect": "Échec de la connexion : ${error}",
"failedToLoadRecent": "Échec du chargement des sessions récentes : ${error}"
"failedToConnect": "Échec de la connexion : ${error}"
},
"remote": {
"disconnectConfirm": "Voulez-vous vous déconnecter de la session distante ?",
+1 -9
View File
@@ -732,11 +732,8 @@
"minimize": "Riduci"
},
"pairing": {
"recent": "Recenti",
"scan": "Scansiona",
"manual": "Manuale",
"recentConnections": "Connessioni recenti",
"quickReconnect": "Riconnettiti rapidamente ai dispositivi associati in precedenza",
"pairWithDesktop": "Associa con desktop",
"enterSessionDetails": "Inserisci i dettagli della sessione mostrati sul tuo dispositivo desktop",
"hostAddressHint": "192.168.1.100:48632",
@@ -750,11 +747,7 @@
"cameraPermissionRequired": "L'autorizzazione della fotocamera è necessaria per scansionare i QR code.\nConcedi l'accesso alla fotocamera nelle impostazioni del dispositivo.",
"cameraError": "Impossibile avviare la fotocamera: ${error}",
"scanInstruction": "Punta la fotocamera verso il QR code mostrato sul tuo desktop",
"noRecentConnections": "Nessuna connessione recente",
"connectUsingManual": "Connettiti a un dispositivo tramite inserimento manuale per iniziare",
"invalidQrCode": "Formato QR code non valido",
"removeRecentConnection": "Rimuovi connessione recente",
"removeConfirm": "Rimuovere \"${name}\" dalle connessioni recenti?",
"validationHostRequired": "Inserisci l'indirizzo host",
"validationHostFormat": "Il formato deve essere IP:porta (es. 192.168.1.100:48632)",
"validationSessionIdRequired": "Inserisci un ID sessione",
@@ -763,8 +756,7 @@
"validationPinLength": "Il PIN deve essere di 6 cifre",
"connectionTimedOut": "Connessione scaduta. Verifica l'ID sessione e il PIN.",
"sessionNotFound": "Sessione non trovata. Verifica le tue credenziali.",
"failedToConnect": "Connessione fallita: ${error}",
"failedToLoadRecent": "Impossibile caricare le sessioni recenti: ${error}"
"failedToConnect": "Connessione fallita: ${error}"
},
"remote": {
"disconnectConfirm": "Vuoi disconnetterti dalla sessione remota?",
+1 -9
View File
@@ -732,11 +732,8 @@
"minimize": "최소화"
},
"pairing": {
"recent": "최근",
"scan": "스캔",
"manual": "수동",
"recentConnections": "최근 연결",
"quickReconnect": "이전에 페어링한 기기에 빠르게 재연결",
"pairWithDesktop": "데스크톱과 페어링",
"enterSessionDetails": "데스크톱 기기에 표시된 세션 정보를 입력하세요",
"hostAddressHint": "192.168.1.100:48632",
@@ -750,11 +747,7 @@
"cameraPermissionRequired": "QR 코드를 스캔하려면 카메라 권한이 필요합니다.\n기기 설정에서 카메라 접근을 허용해 주세요.",
"cameraError": "카메라를 시작할 수 없습니다: ${error}",
"scanInstruction": "데스크톱에 표시된 QR 코드에 카메라를 향하세요",
"noRecentConnections": "최근 연결 없음",
"connectUsingManual": "수동 입력으로 기기에 연결하여 시작하세요",
"invalidQrCode": "유효하지 않은 QR 코드 형식",
"removeRecentConnection": "최근 연결 삭제",
"removeConfirm": "\"${name}\"을(를) 최근 연결에서 삭제하시겠습니까?",
"validationHostRequired": "호스트 주소를 입력하세요",
"validationHostFormat": "IP:포트 형식이어야 합니다 (예: 192.168.1.100:48632)",
"validationSessionIdRequired": "세션 ID를 입력하세요",
@@ -763,8 +756,7 @@
"validationPinLength": "PIN은 6자리여야 합니다",
"connectionTimedOut": "연결 시간이 초과되었습니다. 세션 ID와 PIN을 확인하세요.",
"sessionNotFound": "세션을 찾을 수 없습니다. 자격 증명을 확인하세요.",
"failedToConnect": "연결 실패: ${error}",
"failedToLoadRecent": "최근 세션 로드 실패: ${error}"
"failedToConnect": "연결 실패: ${error}"
},
"remote": {
"disconnectConfirm": "원격 세션 연결을 해제하시겠습니까?",
+1 -9
View File
@@ -732,11 +732,8 @@
"minimize": "Minimaliseren"
},
"pairing": {
"recent": "Recent",
"scan": "Scannen",
"manual": "Handmatig",
"recentConnections": "Recente verbindingen",
"quickReconnect": "Snel opnieuw verbinden met eerder gekoppelde apparaten",
"pairWithDesktop": "Koppelen met desktop",
"enterSessionDetails": "Voer de sessiegegevens in die op je desktop-apparaat worden getoond",
"hostAddressHint": "192.168.1.100:48632",
@@ -750,11 +747,7 @@
"cameraPermissionRequired": "Cameratoestemming is vereist om QR-codes te scannen.\nGeef cameratoegang in je apparaatinstellingen.",
"cameraError": "Kan camera niet starten: ${error}",
"scanInstruction": "Richt je camera op de QR-code die op je desktop wordt getoond",
"noRecentConnections": "Geen recente verbindingen",
"connectUsingManual": "Verbind met een apparaat via Handmatige invoer om te beginnen",
"invalidQrCode": "Ongeldig QR-codeformaat",
"removeRecentConnection": "Recente verbinding verwijderen",
"removeConfirm": "\"${name}\" verwijderen uit recente verbindingen?",
"validationHostRequired": "Voer een hostadres in",
"validationHostFormat": "Formaat moet IP:poort zijn (bijv. 192.168.1.100:48632)",
"validationSessionIdRequired": "Voer een sessie-ID in",
@@ -763,8 +756,7 @@
"validationPinLength": "PIN moet 6 cijfers zijn",
"connectionTimedOut": "Verbinding verlopen. Controleer de sessie-ID en PIN.",
"sessionNotFound": "Kan de sessie niet vinden. Controleer je gegevens.",
"failedToConnect": "Verbinden mislukt: ${error}",
"failedToLoadRecent": "Kan recente sessies niet laden: ${error}"
"failedToConnect": "Verbinden mislukt: ${error}"
},
"remote": {
"disconnectConfirm": "Wil je de verbinding met de externe sessie verbreken?",
-16
View File
@@ -1214,11 +1214,8 @@ class _TranslationsCompanionRemotePairingDe implements TranslationsCompanionRemo
final TranslationsDe _root; // ignore: unused_field
// Translations
@override String get recent => 'Zuletzt';
@override String get scan => 'Scannen';
@override String get manual => 'Manuell';
@override String get recentConnections => 'Letzte Verbindungen';
@override String get quickReconnect => 'Schnell mit zuvor gekoppelten Geräten verbinden';
@override String get pairWithDesktop => 'Mit Desktop koppeln';
@override String get enterSessionDetails => 'Gib die Sitzungsdetails ein, die auf deinem Desktop-Gerät angezeigt werden';
@override String get hostAddressHint => '192.168.1.100:48632';
@@ -1232,11 +1229,7 @@ class _TranslationsCompanionRemotePairingDe implements TranslationsCompanionRemo
@override String get cameraPermissionRequired => 'Kameraberechtigung wird zum Scannen von QR-Codes benötigt.\nBitte erteile den Kamerazugriff in den Geräteeinstellungen.';
@override String cameraError({required Object error}) => 'Kamera konnte nicht gestartet werden: ${error}';
@override String get scanInstruction => 'Richte deine Kamera auf den QR-Code auf deinem Desktop';
@override String get noRecentConnections => 'Keine letzten Verbindungen';
@override String get connectUsingManual => 'Verbinde dich über die manuelle Eingabe, um loszulegen';
@override String get invalidQrCode => 'Ungültiges QR-Code-Format';
@override String get removeRecentConnection => 'Letzte Verbindung entfernen';
@override String removeConfirm({required Object name}) => '"${name}" aus den letzten Verbindungen entfernen?';
@override String get validationHostRequired => 'Bitte Host-Adresse eingeben';
@override String get validationHostFormat => 'Format muss IP:Port sein (z.B. 192.168.1.100:48632)';
@override String get validationSessionIdRequired => 'Bitte Sitzungs-ID eingeben';
@@ -1246,7 +1239,6 @@ class _TranslationsCompanionRemotePairingDe implements TranslationsCompanionRemo
@override String get connectionTimedOut => 'Zeitüberschreitung. Bitte Sitzungs-ID und PIN überprüfen.';
@override String get sessionNotFound => 'Sitzung nicht gefunden. Bitte Zugangsdaten überprüfen.';
@override String failedToConnect({required Object error}) => 'Verbindung fehlgeschlagen: ${error}';
@override String failedToLoadRecent({required Object error}) => 'Letzte Sitzungen konnten nicht geladen werden: ${error}';
}
// Path: companionRemote.remote
@@ -1950,11 +1942,8 @@ extension on TranslationsDe {
'companionRemote.session.copyToClipboard' => 'In Zwischenablage kopieren',
'companionRemote.session.newSession' => 'Neue Sitzung',
'companionRemote.session.minimize' => 'Minimieren',
'companionRemote.pairing.recent' => 'Zuletzt',
'companionRemote.pairing.scan' => 'Scannen',
'companionRemote.pairing.manual' => 'Manuell',
'companionRemote.pairing.recentConnections' => 'Letzte Verbindungen',
'companionRemote.pairing.quickReconnect' => 'Schnell mit zuvor gekoppelten Geräten verbinden',
'companionRemote.pairing.pairWithDesktop' => 'Mit Desktop koppeln',
'companionRemote.pairing.enterSessionDetails' => 'Gib die Sitzungsdetails ein, die auf deinem Desktop-Gerät angezeigt werden',
'companionRemote.pairing.hostAddressHint' => '192.168.1.100:48632',
@@ -1968,11 +1957,7 @@ extension on TranslationsDe {
'companionRemote.pairing.cameraPermissionRequired' => 'Kameraberechtigung wird zum Scannen von QR-Codes benötigt.\nBitte erteile den Kamerazugriff in den Geräteeinstellungen.',
'companionRemote.pairing.cameraError' => ({required Object error}) => 'Kamera konnte nicht gestartet werden: ${error}',
'companionRemote.pairing.scanInstruction' => 'Richte deine Kamera auf den QR-Code auf deinem Desktop',
'companionRemote.pairing.noRecentConnections' => 'Keine letzten Verbindungen',
'companionRemote.pairing.connectUsingManual' => 'Verbinde dich über die manuelle Eingabe, um loszulegen',
'companionRemote.pairing.invalidQrCode' => 'Ungültiges QR-Code-Format',
'companionRemote.pairing.removeRecentConnection' => 'Letzte Verbindung entfernen',
'companionRemote.pairing.removeConfirm' => ({required Object name}) => '"${name}" aus den letzten Verbindungen entfernen?',
'companionRemote.pairing.validationHostRequired' => 'Bitte Host-Adresse eingeben',
'companionRemote.pairing.validationHostFormat' => 'Format muss IP:Port sein (z.B. 192.168.1.100:48632)',
'companionRemote.pairing.validationSessionIdRequired' => 'Bitte Sitzungs-ID eingeben',
@@ -1982,7 +1967,6 @@ extension on TranslationsDe {
'companionRemote.pairing.connectionTimedOut' => 'Zeitüberschreitung. Bitte Sitzungs-ID und PIN überprüfen.',
'companionRemote.pairing.sessionNotFound' => 'Sitzung nicht gefunden. Bitte Zugangsdaten überprüfen.',
'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Verbindung fehlgeschlagen: ${error}',
'companionRemote.pairing.failedToLoadRecent' => ({required Object error}) => 'Letzte Sitzungen konnten nicht geladen werden: ${error}',
'companionRemote.remote.disconnectConfirm' => 'Möchtest du die Verbindung zur Fernsteuerungssitzung trennen?',
'companionRemote.remote.reconnecting' => 'Verbindung wird wiederhergestellt...',
'companionRemote.remote.attemptOf' => ({required Object current}) => 'Versuch ${current} von 5',
-31
View File
@@ -2694,21 +2694,12 @@ class TranslationsCompanionRemotePairingEn {
// Translations
/// en: 'Recent'
String get recent => 'Recent';
/// en: 'Scan'
String get scan => 'Scan';
/// en: 'Manual'
String get manual => 'Manual';
/// en: 'Recent Connections'
String get recentConnections => 'Recent Connections';
/// en: 'Quickly reconnect to previously paired devices'
String get quickReconnect => 'Quickly reconnect to previously paired devices';
/// en: 'Pair with Desktop'
String get pairWithDesktop => 'Pair with Desktop';
@@ -2748,21 +2739,9 @@ class TranslationsCompanionRemotePairingEn {
/// en: 'Point your camera at the QR code shown on your desktop'
String get scanInstruction => 'Point your camera at the QR code shown on your desktop';
/// en: 'No recent connections'
String get noRecentConnections => 'No recent connections';
/// en: 'Connect to a device using Manual entry to get started'
String get connectUsingManual => 'Connect to a device using Manual entry to get started';
/// en: 'Invalid QR code format'
String get invalidQrCode => 'Invalid QR code format';
/// en: 'Remove Recent Connection'
String get removeRecentConnection => 'Remove Recent Connection';
/// en: 'Remove "${name}" from recent connections?'
String removeConfirm({required Object name}) => 'Remove "${name}" from recent connections?';
/// en: 'Please enter host address'
String get validationHostRequired => 'Please enter host address';
@@ -2790,8 +2769,6 @@ class TranslationsCompanionRemotePairingEn {
/// en: 'Failed to connect: ${error}'
String failedToConnect({required Object error}) => 'Failed to connect: ${error}';
/// en: 'Failed to load recent sessions: ${error}'
String failedToLoadRecent({required Object error}) => 'Failed to load recent sessions: ${error}';
}
// Path: companionRemote.remote
@@ -3553,11 +3530,8 @@ extension on Translations {
'companionRemote.session.copyToClipboard' => 'Copy to clipboard',
'companionRemote.session.newSession' => 'New Session',
'companionRemote.session.minimize' => 'Minimize',
'companionRemote.pairing.recent' => 'Recent',
'companionRemote.pairing.scan' => 'Scan',
'companionRemote.pairing.manual' => 'Manual',
'companionRemote.pairing.recentConnections' => 'Recent Connections',
'companionRemote.pairing.quickReconnect' => 'Quickly reconnect to previously paired devices',
'companionRemote.pairing.pairWithDesktop' => 'Pair with Desktop',
'companionRemote.pairing.enterSessionDetails' => 'Enter the session details shown on your desktop device',
'companionRemote.pairing.hostAddressHint' => '192.168.1.100:48632',
@@ -3571,11 +3545,7 @@ extension on Translations {
'companionRemote.pairing.cameraPermissionRequired' => 'Camera permission is required to scan QR codes.\nPlease grant camera access in your device settings.',
'companionRemote.pairing.cameraError' => ({required Object error}) => 'Could not start camera: ${error}',
'companionRemote.pairing.scanInstruction' => 'Point your camera at the QR code shown on your desktop',
'companionRemote.pairing.noRecentConnections' => 'No recent connections',
'companionRemote.pairing.connectUsingManual' => 'Connect to a device using Manual entry to get started',
'companionRemote.pairing.invalidQrCode' => 'Invalid QR code format',
'companionRemote.pairing.removeRecentConnection' => 'Remove Recent Connection',
'companionRemote.pairing.removeConfirm' => ({required Object name}) => 'Remove "${name}" from recent connections?',
'companionRemote.pairing.validationHostRequired' => 'Please enter host address',
'companionRemote.pairing.validationHostFormat' => 'Format must be IP:port (e.g., 192.168.1.100:48632)',
'companionRemote.pairing.validationSessionIdRequired' => 'Please enter a session ID',
@@ -3585,7 +3555,6 @@ extension on Translations {
'companionRemote.pairing.connectionTimedOut' => 'Connection timed out. Please check the session ID and PIN.',
'companionRemote.pairing.sessionNotFound' => 'Could not find the session. Please check your credentials.',
'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Failed to connect: ${error}',
'companionRemote.pairing.failedToLoadRecent' => ({required Object error}) => 'Failed to load recent sessions: ${error}',
'companionRemote.remote.disconnectConfirm' => 'Do you want to disconnect from the remote session?',
'companionRemote.remote.reconnecting' => 'Reconnecting...',
'companionRemote.remote.attemptOf' => ({required Object current}) => 'Attempt ${current} of 5',
-16
View File
@@ -1214,11 +1214,8 @@ class _TranslationsCompanionRemotePairingEs implements TranslationsCompanionRemo
final TranslationsEs _root; // ignore: unused_field
// Translations
@override String get recent => 'Recientes';
@override String get scan => 'Escanear';
@override String get manual => 'Manual';
@override String get recentConnections => 'Conexiones recientes';
@override String get quickReconnect => 'Reconectar rápidamente con dispositivos emparejados anteriormente';
@override String get pairWithDesktop => 'Emparejar con escritorio';
@override String get enterSessionDetails => 'Introduce los datos de la sesión que aparecen en tu dispositivo de escritorio';
@override String get hostAddressHint => '192.168.1.100:48632';
@@ -1232,11 +1229,7 @@ class _TranslationsCompanionRemotePairingEs implements TranslationsCompanionRemo
@override String get cameraPermissionRequired => 'Se necesita permiso de cámara para escanear códigos QR.\nPor favor, concede acceso a la cámara en los ajustes de tu dispositivo.';
@override String cameraError({required Object error}) => 'No se pudo iniciar la cámara: ${error}';
@override String get scanInstruction => 'Apunta tu cámara al código QR que aparece en tu escritorio';
@override String get noRecentConnections => 'No hay conexiones recientes';
@override String get connectUsingManual => 'Conéctate a un dispositivo usando la entrada manual para empezar';
@override String get invalidQrCode => 'Formato de código QR no válido';
@override String get removeRecentConnection => 'Eliminar conexión reciente';
@override String removeConfirm({required Object name}) => '¿Eliminar "${name}" de las conexiones recientes?';
@override String get validationHostRequired => 'Por favor, introduce la dirección del host';
@override String get validationHostFormat => 'El formato debe ser IP:puerto (ej., 192.168.1.100:48632)';
@override String get validationSessionIdRequired => 'Por favor, introduce un ID de sesión';
@@ -1246,7 +1239,6 @@ class _TranslationsCompanionRemotePairingEs implements TranslationsCompanionRemo
@override String get connectionTimedOut => 'Tiempo de conexión agotado. Verifica el ID de sesión y el PIN.';
@override String get sessionNotFound => 'No se encontró la sesión. Verifica tus credenciales.';
@override String failedToConnect({required Object error}) => 'Error al conectar: ${error}';
@override String failedToLoadRecent({required Object error}) => 'Error al cargar sesiones recientes: ${error}';
}
// Path: companionRemote.remote
@@ -1950,11 +1942,8 @@ extension on TranslationsEs {
'companionRemote.session.copyToClipboard' => 'Copiar al portapapeles',
'companionRemote.session.newSession' => 'Nueva sesión',
'companionRemote.session.minimize' => 'Minimizar',
'companionRemote.pairing.recent' => 'Recientes',
'companionRemote.pairing.scan' => 'Escanear',
'companionRemote.pairing.manual' => 'Manual',
'companionRemote.pairing.recentConnections' => 'Conexiones recientes',
'companionRemote.pairing.quickReconnect' => 'Reconectar rápidamente con dispositivos emparejados anteriormente',
'companionRemote.pairing.pairWithDesktop' => 'Emparejar con escritorio',
'companionRemote.pairing.enterSessionDetails' => 'Introduce los datos de la sesión que aparecen en tu dispositivo de escritorio',
'companionRemote.pairing.hostAddressHint' => '192.168.1.100:48632',
@@ -1968,11 +1957,7 @@ extension on TranslationsEs {
'companionRemote.pairing.cameraPermissionRequired' => 'Se necesita permiso de cámara para escanear códigos QR.\nPor favor, concede acceso a la cámara en los ajustes de tu dispositivo.',
'companionRemote.pairing.cameraError' => ({required Object error}) => 'No se pudo iniciar la cámara: ${error}',
'companionRemote.pairing.scanInstruction' => 'Apunta tu cámara al código QR que aparece en tu escritorio',
'companionRemote.pairing.noRecentConnections' => 'No hay conexiones recientes',
'companionRemote.pairing.connectUsingManual' => 'Conéctate a un dispositivo usando la entrada manual para empezar',
'companionRemote.pairing.invalidQrCode' => 'Formato de código QR no válido',
'companionRemote.pairing.removeRecentConnection' => 'Eliminar conexión reciente',
'companionRemote.pairing.removeConfirm' => ({required Object name}) => '¿Eliminar "${name}" de las conexiones recientes?',
'companionRemote.pairing.validationHostRequired' => 'Por favor, introduce la dirección del host',
'companionRemote.pairing.validationHostFormat' => 'El formato debe ser IP:puerto (ej., 192.168.1.100:48632)',
'companionRemote.pairing.validationSessionIdRequired' => 'Por favor, introduce un ID de sesión',
@@ -1982,7 +1967,6 @@ extension on TranslationsEs {
'companionRemote.pairing.connectionTimedOut' => 'Tiempo de conexión agotado. Verifica el ID de sesión y el PIN.',
'companionRemote.pairing.sessionNotFound' => 'No se encontró la sesión. Verifica tus credenciales.',
'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Error al conectar: ${error}',
'companionRemote.pairing.failedToLoadRecent' => ({required Object error}) => 'Error al cargar sesiones recientes: ${error}',
'companionRemote.remote.disconnectConfirm' => '¿Quieres desconectarte de la sesión remota?',
'companionRemote.remote.reconnecting' => 'Reconectando...',
'companionRemote.remote.attemptOf' => ({required Object current}) => 'Intento ${current} de 5',
-16
View File
@@ -1214,11 +1214,8 @@ class _TranslationsCompanionRemotePairingFr implements TranslationsCompanionRemo
final TranslationsFr _root; // ignore: unused_field
// Translations
@override String get recent => 'Récents';
@override String get scan => 'Scanner';
@override String get manual => 'Manuel';
@override String get recentConnections => 'Connexions récentes';
@override String get quickReconnect => 'Reconnexion rapide aux appareils précédemment jumelés';
@override String get pairWithDesktop => 'Jumeler avec un bureau';
@override String get enterSessionDetails => 'Saisissez les détails de la session affichés sur votre appareil de bureau';
@override String get hostAddressHint => '192.168.1.100:48632';
@@ -1232,11 +1229,7 @@ class _TranslationsCompanionRemotePairingFr implements TranslationsCompanionRemo
@override String get cameraPermissionRequired => 'L\'autorisation de la caméra est requise pour scanner les QR codes.\nVeuillez accorder l\'accès à la caméra dans les paramètres de votre appareil.';
@override String cameraError({required Object error}) => 'Impossible de démarrer la caméra : ${error}';
@override String get scanInstruction => 'Pointez votre caméra vers le QR code affiché sur votre bureau';
@override String get noRecentConnections => 'Aucune connexion récente';
@override String get connectUsingManual => 'Connectez-vous à un appareil via la saisie manuelle pour commencer';
@override String get invalidQrCode => 'Format de QR code invalide';
@override String get removeRecentConnection => 'Supprimer la connexion récente';
@override String removeConfirm({required Object name}) => 'Supprimer "${name}" des connexions récentes ?';
@override String get validationHostRequired => 'Veuillez saisir l\'adresse de l\'hôte';
@override String get validationHostFormat => 'Le format doit être IP:port (ex : 192.168.1.100:48632)';
@override String get validationSessionIdRequired => 'Veuillez saisir un ID de session';
@@ -1246,7 +1239,6 @@ class _TranslationsCompanionRemotePairingFr implements TranslationsCompanionRemo
@override String get connectionTimedOut => 'Délai de connexion expiré. Veuillez vérifier l\'ID de session et le PIN.';
@override String get sessionNotFound => 'Session introuvable. Veuillez vérifier vos identifiants.';
@override String failedToConnect({required Object error}) => 'Échec de la connexion : ${error}';
@override String failedToLoadRecent({required Object error}) => 'Échec du chargement des sessions récentes : ${error}';
}
// Path: companionRemote.remote
@@ -1950,11 +1942,8 @@ extension on TranslationsFr {
'companionRemote.session.copyToClipboard' => 'Copier dans le presse-papiers',
'companionRemote.session.newSession' => 'Nouvelle session',
'companionRemote.session.minimize' => 'Réduire',
'companionRemote.pairing.recent' => 'Récents',
'companionRemote.pairing.scan' => 'Scanner',
'companionRemote.pairing.manual' => 'Manuel',
'companionRemote.pairing.recentConnections' => 'Connexions récentes',
'companionRemote.pairing.quickReconnect' => 'Reconnexion rapide aux appareils précédemment jumelés',
'companionRemote.pairing.pairWithDesktop' => 'Jumeler avec un bureau',
'companionRemote.pairing.enterSessionDetails' => 'Saisissez les détails de la session affichés sur votre appareil de bureau',
'companionRemote.pairing.hostAddressHint' => '192.168.1.100:48632',
@@ -1968,11 +1957,7 @@ extension on TranslationsFr {
'companionRemote.pairing.cameraPermissionRequired' => 'L\'autorisation de la caméra est requise pour scanner les QR codes.\nVeuillez accorder l\'accès à la caméra dans les paramètres de votre appareil.',
'companionRemote.pairing.cameraError' => ({required Object error}) => 'Impossible de démarrer la caméra : ${error}',
'companionRemote.pairing.scanInstruction' => 'Pointez votre caméra vers le QR code affiché sur votre bureau',
'companionRemote.pairing.noRecentConnections' => 'Aucune connexion récente',
'companionRemote.pairing.connectUsingManual' => 'Connectez-vous à un appareil via la saisie manuelle pour commencer',
'companionRemote.pairing.invalidQrCode' => 'Format de QR code invalide',
'companionRemote.pairing.removeRecentConnection' => 'Supprimer la connexion récente',
'companionRemote.pairing.removeConfirm' => ({required Object name}) => 'Supprimer "${name}" des connexions récentes ?',
'companionRemote.pairing.validationHostRequired' => 'Veuillez saisir l\'adresse de l\'hôte',
'companionRemote.pairing.validationHostFormat' => 'Le format doit être IP:port (ex : 192.168.1.100:48632)',
'companionRemote.pairing.validationSessionIdRequired' => 'Veuillez saisir un ID de session',
@@ -1982,7 +1967,6 @@ extension on TranslationsFr {
'companionRemote.pairing.connectionTimedOut' => 'Délai de connexion expiré. Veuillez vérifier l\'ID de session et le PIN.',
'companionRemote.pairing.sessionNotFound' => 'Session introuvable. Veuillez vérifier vos identifiants.',
'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Échec de la connexion : ${error}',
'companionRemote.pairing.failedToLoadRecent' => ({required Object error}) => 'Échec du chargement des sessions récentes : ${error}',
'companionRemote.remote.disconnectConfirm' => 'Voulez-vous vous déconnecter de la session distante ?',
'companionRemote.remote.reconnecting' => 'Reconnexion...',
'companionRemote.remote.attemptOf' => ({required Object current}) => 'Tentative ${current} sur 5',
-16
View File
@@ -1214,11 +1214,8 @@ class _TranslationsCompanionRemotePairingIt implements TranslationsCompanionRemo
final TranslationsIt _root; // ignore: unused_field
// Translations
@override String get recent => 'Recenti';
@override String get scan => 'Scansiona';
@override String get manual => 'Manuale';
@override String get recentConnections => 'Connessioni recenti';
@override String get quickReconnect => 'Riconnettiti rapidamente ai dispositivi associati in precedenza';
@override String get pairWithDesktop => 'Associa con desktop';
@override String get enterSessionDetails => 'Inserisci i dettagli della sessione mostrati sul tuo dispositivo desktop';
@override String get hostAddressHint => '192.168.1.100:48632';
@@ -1232,11 +1229,7 @@ class _TranslationsCompanionRemotePairingIt implements TranslationsCompanionRemo
@override String get cameraPermissionRequired => 'L\'autorizzazione della fotocamera è necessaria per scansionare i QR code.\nConcedi l\'accesso alla fotocamera nelle impostazioni del dispositivo.';
@override String cameraError({required Object error}) => 'Impossibile avviare la fotocamera: ${error}';
@override String get scanInstruction => 'Punta la fotocamera verso il QR code mostrato sul tuo desktop';
@override String get noRecentConnections => 'Nessuna connessione recente';
@override String get connectUsingManual => 'Connettiti a un dispositivo tramite inserimento manuale per iniziare';
@override String get invalidQrCode => 'Formato QR code non valido';
@override String get removeRecentConnection => 'Rimuovi connessione recente';
@override String removeConfirm({required Object name}) => 'Rimuovere "${name}" dalle connessioni recenti?';
@override String get validationHostRequired => 'Inserisci l\'indirizzo host';
@override String get validationHostFormat => 'Il formato deve essere IP:porta (es. 192.168.1.100:48632)';
@override String get validationSessionIdRequired => 'Inserisci un ID sessione';
@@ -1246,7 +1239,6 @@ class _TranslationsCompanionRemotePairingIt implements TranslationsCompanionRemo
@override String get connectionTimedOut => 'Connessione scaduta. Verifica l\'ID sessione e il PIN.';
@override String get sessionNotFound => 'Sessione non trovata. Verifica le tue credenziali.';
@override String failedToConnect({required Object error}) => 'Connessione fallita: ${error}';
@override String failedToLoadRecent({required Object error}) => 'Impossibile caricare le sessioni recenti: ${error}';
}
// Path: companionRemote.remote
@@ -1950,11 +1942,8 @@ extension on TranslationsIt {
'companionRemote.session.copyToClipboard' => 'Copia negli appunti',
'companionRemote.session.newSession' => 'Nuova sessione',
'companionRemote.session.minimize' => 'Riduci',
'companionRemote.pairing.recent' => 'Recenti',
'companionRemote.pairing.scan' => 'Scansiona',
'companionRemote.pairing.manual' => 'Manuale',
'companionRemote.pairing.recentConnections' => 'Connessioni recenti',
'companionRemote.pairing.quickReconnect' => 'Riconnettiti rapidamente ai dispositivi associati in precedenza',
'companionRemote.pairing.pairWithDesktop' => 'Associa con desktop',
'companionRemote.pairing.enterSessionDetails' => 'Inserisci i dettagli della sessione mostrati sul tuo dispositivo desktop',
'companionRemote.pairing.hostAddressHint' => '192.168.1.100:48632',
@@ -1968,11 +1957,7 @@ extension on TranslationsIt {
'companionRemote.pairing.cameraPermissionRequired' => 'L\'autorizzazione della fotocamera è necessaria per scansionare i QR code.\nConcedi l\'accesso alla fotocamera nelle impostazioni del dispositivo.',
'companionRemote.pairing.cameraError' => ({required Object error}) => 'Impossibile avviare la fotocamera: ${error}',
'companionRemote.pairing.scanInstruction' => 'Punta la fotocamera verso il QR code mostrato sul tuo desktop',
'companionRemote.pairing.noRecentConnections' => 'Nessuna connessione recente',
'companionRemote.pairing.connectUsingManual' => 'Connettiti a un dispositivo tramite inserimento manuale per iniziare',
'companionRemote.pairing.invalidQrCode' => 'Formato QR code non valido',
'companionRemote.pairing.removeRecentConnection' => 'Rimuovi connessione recente',
'companionRemote.pairing.removeConfirm' => ({required Object name}) => 'Rimuovere "${name}" dalle connessioni recenti?',
'companionRemote.pairing.validationHostRequired' => 'Inserisci l\'indirizzo host',
'companionRemote.pairing.validationHostFormat' => 'Il formato deve essere IP:porta (es. 192.168.1.100:48632)',
'companionRemote.pairing.validationSessionIdRequired' => 'Inserisci un ID sessione',
@@ -1982,7 +1967,6 @@ extension on TranslationsIt {
'companionRemote.pairing.connectionTimedOut' => 'Connessione scaduta. Verifica l\'ID sessione e il PIN.',
'companionRemote.pairing.sessionNotFound' => 'Sessione non trovata. Verifica le tue credenziali.',
'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Connessione fallita: ${error}',
'companionRemote.pairing.failedToLoadRecent' => ({required Object error}) => 'Impossibile caricare le sessioni recenti: ${error}',
'companionRemote.remote.disconnectConfirm' => 'Vuoi disconnetterti dalla sessione remota?',
'companionRemote.remote.reconnecting' => 'Riconnessione...',
'companionRemote.remote.attemptOf' => ({required Object current}) => 'Tentativo ${current} di 5',
-16
View File
@@ -1214,11 +1214,8 @@ class _TranslationsCompanionRemotePairingKo implements TranslationsCompanionRemo
final TranslationsKo _root; // ignore: unused_field
// Translations
@override String get recent => '최근';
@override String get scan => '스캔';
@override String get manual => '수동';
@override String get recentConnections => '최근 연결';
@override String get quickReconnect => '이전에 페어링한 기기에 빠르게 재연결';
@override String get pairWithDesktop => '데스크톱과 페어링';
@override String get enterSessionDetails => '데스크톱 기기에 표시된 세션 정보를 입력하세요';
@override String get hostAddressHint => '192.168.1.100:48632';
@@ -1232,11 +1229,7 @@ class _TranslationsCompanionRemotePairingKo implements TranslationsCompanionRemo
@override String get cameraPermissionRequired => 'QR 코드를 스캔하려면 카메라 권한이 필요합니다.\n기기 설정에서 카메라 접근을 허용해 주세요.';
@override String cameraError({required Object error}) => '카메라를 시작할 수 없습니다: ${error}';
@override String get scanInstruction => '데스크톱에 표시된 QR 코드에 카메라를 향하세요';
@override String get noRecentConnections => '최근 연결 없음';
@override String get connectUsingManual => '수동 입력으로 기기에 연결하여 시작하세요';
@override String get invalidQrCode => '유효하지 않은 QR 코드 형식';
@override String get removeRecentConnection => '최근 연결 삭제';
@override String removeConfirm({required Object name}) => '"${name}"을(를) 최근 연결에서 삭제하시겠습니까?';
@override String get validationHostRequired => '호스트 주소를 입력하세요';
@override String get validationHostFormat => 'IP:포트 형식이어야 합니다 (예: 192.168.1.100:48632)';
@override String get validationSessionIdRequired => '세션 ID를 입력하세요';
@@ -1246,7 +1239,6 @@ class _TranslationsCompanionRemotePairingKo implements TranslationsCompanionRemo
@override String get connectionTimedOut => '연결 시간이 초과되었습니다. 세션 ID와 PIN을 확인하세요.';
@override String get sessionNotFound => '세션을 찾을 수 없습니다. 자격 증명을 확인하세요.';
@override String failedToConnect({required Object error}) => '연결 실패: ${error}';
@override String failedToLoadRecent({required Object error}) => '최근 세션 로드 실패: ${error}';
}
// Path: companionRemote.remote
@@ -1950,11 +1942,8 @@ extension on TranslationsKo {
'companionRemote.session.copyToClipboard' => '클립보드에 복사',
'companionRemote.session.newSession' => '새 세션',
'companionRemote.session.minimize' => '최소화',
'companionRemote.pairing.recent' => '최근',
'companionRemote.pairing.scan' => '스캔',
'companionRemote.pairing.manual' => '수동',
'companionRemote.pairing.recentConnections' => '최근 연결',
'companionRemote.pairing.quickReconnect' => '이전에 페어링한 기기에 빠르게 재연결',
'companionRemote.pairing.pairWithDesktop' => '데스크톱과 페어링',
'companionRemote.pairing.enterSessionDetails' => '데스크톱 기기에 표시된 세션 정보를 입력하세요',
'companionRemote.pairing.hostAddressHint' => '192.168.1.100:48632',
@@ -1968,11 +1957,7 @@ extension on TranslationsKo {
'companionRemote.pairing.cameraPermissionRequired' => 'QR 코드를 스캔하려면 카메라 권한이 필요합니다.\n기기 설정에서 카메라 접근을 허용해 주세요.',
'companionRemote.pairing.cameraError' => ({required Object error}) => '카메라를 시작할 수 없습니다: ${error}',
'companionRemote.pairing.scanInstruction' => '데스크톱에 표시된 QR 코드에 카메라를 향하세요',
'companionRemote.pairing.noRecentConnections' => '최근 연결 없음',
'companionRemote.pairing.connectUsingManual' => '수동 입력으로 기기에 연결하여 시작하세요',
'companionRemote.pairing.invalidQrCode' => '유효하지 않은 QR 코드 형식',
'companionRemote.pairing.removeRecentConnection' => '최근 연결 삭제',
'companionRemote.pairing.removeConfirm' => ({required Object name}) => '"${name}"을(를) 최근 연결에서 삭제하시겠습니까?',
'companionRemote.pairing.validationHostRequired' => '호스트 주소를 입력하세요',
'companionRemote.pairing.validationHostFormat' => 'IP:포트 형식이어야 합니다 (예: 192.168.1.100:48632)',
'companionRemote.pairing.validationSessionIdRequired' => '세션 ID를 입력하세요',
@@ -1982,7 +1967,6 @@ extension on TranslationsKo {
'companionRemote.pairing.connectionTimedOut' => '연결 시간이 초과되었습니다. 세션 ID와 PIN을 확인하세요.',
'companionRemote.pairing.sessionNotFound' => '세션을 찾을 수 없습니다. 자격 증명을 확인하세요.',
'companionRemote.pairing.failedToConnect' => ({required Object error}) => '연결 실패: ${error}',
'companionRemote.pairing.failedToLoadRecent' => ({required Object error}) => '최근 세션 로드 실패: ${error}',
'companionRemote.remote.disconnectConfirm' => '원격 세션 연결을 해제하시겠습니까?',
'companionRemote.remote.reconnecting' => '재연결 중...',
'companionRemote.remote.attemptOf' => ({required Object current}) => '${current}/5 시도 중',
-16
View File
@@ -1214,11 +1214,8 @@ class _TranslationsCompanionRemotePairingNl implements TranslationsCompanionRemo
final TranslationsNl _root; // ignore: unused_field
// Translations
@override String get recent => 'Recent';
@override String get scan => 'Scannen';
@override String get manual => 'Handmatig';
@override String get recentConnections => 'Recente verbindingen';
@override String get quickReconnect => 'Snel opnieuw verbinden met eerder gekoppelde apparaten';
@override String get pairWithDesktop => 'Koppelen met desktop';
@override String get enterSessionDetails => 'Voer de sessiegegevens in die op je desktop-apparaat worden getoond';
@override String get hostAddressHint => '192.168.1.100:48632';
@@ -1232,11 +1229,7 @@ class _TranslationsCompanionRemotePairingNl implements TranslationsCompanionRemo
@override String get cameraPermissionRequired => 'Cameratoestemming is vereist om QR-codes te scannen.\nGeef cameratoegang in je apparaatinstellingen.';
@override String cameraError({required Object error}) => 'Kan camera niet starten: ${error}';
@override String get scanInstruction => 'Richt je camera op de QR-code die op je desktop wordt getoond';
@override String get noRecentConnections => 'Geen recente verbindingen';
@override String get connectUsingManual => 'Verbind met een apparaat via Handmatige invoer om te beginnen';
@override String get invalidQrCode => 'Ongeldig QR-codeformaat';
@override String get removeRecentConnection => 'Recente verbinding verwijderen';
@override String removeConfirm({required Object name}) => '"${name}" verwijderen uit recente verbindingen?';
@override String get validationHostRequired => 'Voer een hostadres in';
@override String get validationHostFormat => 'Formaat moet IP:poort zijn (bijv. 192.168.1.100:48632)';
@override String get validationSessionIdRequired => 'Voer een sessie-ID in';
@@ -1246,7 +1239,6 @@ class _TranslationsCompanionRemotePairingNl implements TranslationsCompanionRemo
@override String get connectionTimedOut => 'Verbinding verlopen. Controleer de sessie-ID en PIN.';
@override String get sessionNotFound => 'Kan de sessie niet vinden. Controleer je gegevens.';
@override String failedToConnect({required Object error}) => 'Verbinden mislukt: ${error}';
@override String failedToLoadRecent({required Object error}) => 'Kan recente sessies niet laden: ${error}';
}
// Path: companionRemote.remote
@@ -1950,11 +1942,8 @@ extension on TranslationsNl {
'companionRemote.session.copyToClipboard' => 'Kopieer naar klembord',
'companionRemote.session.newSession' => 'Nieuwe sessie',
'companionRemote.session.minimize' => 'Minimaliseren',
'companionRemote.pairing.recent' => 'Recent',
'companionRemote.pairing.scan' => 'Scannen',
'companionRemote.pairing.manual' => 'Handmatig',
'companionRemote.pairing.recentConnections' => 'Recente verbindingen',
'companionRemote.pairing.quickReconnect' => 'Snel opnieuw verbinden met eerder gekoppelde apparaten',
'companionRemote.pairing.pairWithDesktop' => 'Koppelen met desktop',
'companionRemote.pairing.enterSessionDetails' => 'Voer de sessiegegevens in die op je desktop-apparaat worden getoond',
'companionRemote.pairing.hostAddressHint' => '192.168.1.100:48632',
@@ -1968,11 +1957,7 @@ extension on TranslationsNl {
'companionRemote.pairing.cameraPermissionRequired' => 'Cameratoestemming is vereist om QR-codes te scannen.\nGeef cameratoegang in je apparaatinstellingen.',
'companionRemote.pairing.cameraError' => ({required Object error}) => 'Kan camera niet starten: ${error}',
'companionRemote.pairing.scanInstruction' => 'Richt je camera op de QR-code die op je desktop wordt getoond',
'companionRemote.pairing.noRecentConnections' => 'Geen recente verbindingen',
'companionRemote.pairing.connectUsingManual' => 'Verbind met een apparaat via Handmatige invoer om te beginnen',
'companionRemote.pairing.invalidQrCode' => 'Ongeldig QR-codeformaat',
'companionRemote.pairing.removeRecentConnection' => 'Recente verbinding verwijderen',
'companionRemote.pairing.removeConfirm' => ({required Object name}) => '"${name}" verwijderen uit recente verbindingen?',
'companionRemote.pairing.validationHostRequired' => 'Voer een hostadres in',
'companionRemote.pairing.validationHostFormat' => 'Formaat moet IP:poort zijn (bijv. 192.168.1.100:48632)',
'companionRemote.pairing.validationSessionIdRequired' => 'Voer een sessie-ID in',
@@ -1982,7 +1967,6 @@ extension on TranslationsNl {
'companionRemote.pairing.connectionTimedOut' => 'Verbinding verlopen. Controleer de sessie-ID en PIN.',
'companionRemote.pairing.sessionNotFound' => 'Kan de sessie niet vinden. Controleer je gegevens.',
'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Verbinden mislukt: ${error}',
'companionRemote.pairing.failedToLoadRecent' => ({required Object error}) => 'Kan recente sessies niet laden: ${error}',
'companionRemote.remote.disconnectConfirm' => 'Wil je de verbinding met de externe sessie verbreken?',
'companionRemote.remote.reconnecting' => 'Opnieuw verbinden...',
'companionRemote.remote.attemptOf' => ({required Object current}) => 'Poging ${current} van 5',
-16
View File
@@ -1214,11 +1214,8 @@ class _TranslationsCompanionRemotePairingSv implements TranslationsCompanionRemo
final TranslationsSv _root; // ignore: unused_field
// Translations
@override String get recent => 'Senaste';
@override String get scan => 'Skanna';
@override String get manual => 'Manuell';
@override String get recentConnections => 'Senaste anslutningar';
@override String get quickReconnect => 'Återanslut snabbt till tidigare parkopplade enheter';
@override String get pairWithDesktop => 'Parkoppla med dator';
@override String get enterSessionDetails => 'Ange sessionsuppgifterna som visas på din datorenhet';
@override String get hostAddressHint => '192.168.1.100:48632';
@@ -1232,11 +1229,7 @@ class _TranslationsCompanionRemotePairingSv implements TranslationsCompanionRemo
@override String get cameraPermissionRequired => 'Kamerabehörighet krävs för att skanna QR-koder.\nVänligen ge kameraåtkomst i enhetsinställningarna.';
@override String cameraError({required Object error}) => 'Kunde inte starta kameran: ${error}';
@override String get scanInstruction => 'Rikta kameran mot QR-koden som visas på din dator';
@override String get noRecentConnections => 'Inga senaste anslutningar';
@override String get connectUsingManual => 'Anslut till en enhet via Manuell inmatning för att komma igång';
@override String get invalidQrCode => 'Ogiltigt QR-kodformat';
@override String get removeRecentConnection => 'Ta bort senaste anslutning';
@override String removeConfirm({required Object name}) => 'Ta bort "${name}" från senaste anslutningar?';
@override String get validationHostRequired => 'Ange en värdadress';
@override String get validationHostFormat => 'Format måste vara IP:port (t.ex. 192.168.1.100:48632)';
@override String get validationSessionIdRequired => 'Ange ett sessions-ID';
@@ -1246,7 +1239,6 @@ class _TranslationsCompanionRemotePairingSv implements TranslationsCompanionRemo
@override String get connectionTimedOut => 'Anslutningen tog för lång tid. Kontrollera sessions-ID och PIN.';
@override String get sessionNotFound => 'Kunde inte hitta sessionen. Kontrollera dina uppgifter.';
@override String failedToConnect({required Object error}) => 'Kunde inte ansluta: ${error}';
@override String failedToLoadRecent({required Object error}) => 'Kunde inte ladda senaste sessioner: ${error}';
}
// Path: companionRemote.remote
@@ -1950,11 +1942,8 @@ extension on TranslationsSv {
'companionRemote.session.copyToClipboard' => 'Kopiera till urklipp',
'companionRemote.session.newSession' => 'Ny session',
'companionRemote.session.minimize' => 'Minimera',
'companionRemote.pairing.recent' => 'Senaste',
'companionRemote.pairing.scan' => 'Skanna',
'companionRemote.pairing.manual' => 'Manuell',
'companionRemote.pairing.recentConnections' => 'Senaste anslutningar',
'companionRemote.pairing.quickReconnect' => 'Återanslut snabbt till tidigare parkopplade enheter',
'companionRemote.pairing.pairWithDesktop' => 'Parkoppla med dator',
'companionRemote.pairing.enterSessionDetails' => 'Ange sessionsuppgifterna som visas på din datorenhet',
'companionRemote.pairing.hostAddressHint' => '192.168.1.100:48632',
@@ -1968,11 +1957,7 @@ extension on TranslationsSv {
'companionRemote.pairing.cameraPermissionRequired' => 'Kamerabehörighet krävs för att skanna QR-koder.\nVänligen ge kameraåtkomst i enhetsinställningarna.',
'companionRemote.pairing.cameraError' => ({required Object error}) => 'Kunde inte starta kameran: ${error}',
'companionRemote.pairing.scanInstruction' => 'Rikta kameran mot QR-koden som visas på din dator',
'companionRemote.pairing.noRecentConnections' => 'Inga senaste anslutningar',
'companionRemote.pairing.connectUsingManual' => 'Anslut till en enhet via Manuell inmatning för att komma igång',
'companionRemote.pairing.invalidQrCode' => 'Ogiltigt QR-kodformat',
'companionRemote.pairing.removeRecentConnection' => 'Ta bort senaste anslutning',
'companionRemote.pairing.removeConfirm' => ({required Object name}) => 'Ta bort "${name}" från senaste anslutningar?',
'companionRemote.pairing.validationHostRequired' => 'Ange en värdadress',
'companionRemote.pairing.validationHostFormat' => 'Format måste vara IP:port (t.ex. 192.168.1.100:48632)',
'companionRemote.pairing.validationSessionIdRequired' => 'Ange ett sessions-ID',
@@ -1982,7 +1967,6 @@ extension on TranslationsSv {
'companionRemote.pairing.connectionTimedOut' => 'Anslutningen tog för lång tid. Kontrollera sessions-ID och PIN.',
'companionRemote.pairing.sessionNotFound' => 'Kunde inte hitta sessionen. Kontrollera dina uppgifter.',
'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Kunde inte ansluta: ${error}',
'companionRemote.pairing.failedToLoadRecent' => ({required Object error}) => 'Kunde inte ladda senaste sessioner: ${error}',
'companionRemote.remote.disconnectConfirm' => 'Vill du koppla från fjärrsessionen?',
'companionRemote.remote.reconnecting' => 'Återansluter...',
'companionRemote.remote.attemptOf' => ({required Object current}) => 'Försök ${current} av 5',
-16
View File
@@ -1214,11 +1214,8 @@ class _TranslationsCompanionRemotePairingZh implements TranslationsCompanionRemo
final TranslationsZh _root; // ignore: unused_field
// Translations
@override String get recent => '最近';
@override String get scan => '扫描';
@override String get manual => '手动';
@override String get recentConnections => '最近连接';
@override String get quickReconnect => '快速重新连接之前配对的设备';
@override String get pairWithDesktop => '与桌面配对';
@override String get enterSessionDetails => '输入桌面设备上显示的会话信息';
@override String get hostAddressHint => '192.168.1.100:48632';
@@ -1232,11 +1229,7 @@ class _TranslationsCompanionRemotePairingZh implements TranslationsCompanionRemo
@override String get cameraPermissionRequired => '扫描 QR 码需要相机权限。\n请在设备设置中授予相机访问权限。';
@override String cameraError({required Object error}) => '无法启动相机:${error}';
@override String get scanInstruction => '将相机对准桌面上显示的 QR 码';
@override String get noRecentConnections => '没有最近的连接';
@override String get connectUsingManual => '使用手动输入连接设备以开始使用';
@override String get invalidQrCode => '无效的 QR 码格式';
@override String get removeRecentConnection => '删除最近连接';
@override String removeConfirm({required Object name}) => '确定要从最近连接中删除 "${name}" 吗?';
@override String get validationHostRequired => '请输入主机地址';
@override String get validationHostFormat => '格式必须为 IP:端口(例如 192.168.1.100:48632';
@override String get validationSessionIdRequired => '请输入会话 ID';
@@ -1246,7 +1239,6 @@ class _TranslationsCompanionRemotePairingZh implements TranslationsCompanionRemo
@override String get connectionTimedOut => '连接超时。请检查会话 ID 和 PIN。';
@override String get sessionNotFound => '找不到会话。请检查您的凭据。';
@override String failedToConnect({required Object error}) => '连接失败:${error}';
@override String failedToLoadRecent({required Object error}) => '加载最近会话失败:${error}';
}
// Path: companionRemote.remote
@@ -1950,11 +1942,8 @@ extension on TranslationsZh {
'companionRemote.session.copyToClipboard' => '复制到剪贴板',
'companionRemote.session.newSession' => '新建会话',
'companionRemote.session.minimize' => '最小化',
'companionRemote.pairing.recent' => '最近',
'companionRemote.pairing.scan' => '扫描',
'companionRemote.pairing.manual' => '手动',
'companionRemote.pairing.recentConnections' => '最近连接',
'companionRemote.pairing.quickReconnect' => '快速重新连接之前配对的设备',
'companionRemote.pairing.pairWithDesktop' => '与桌面配对',
'companionRemote.pairing.enterSessionDetails' => '输入桌面设备上显示的会话信息',
'companionRemote.pairing.hostAddressHint' => '192.168.1.100:48632',
@@ -1968,11 +1957,7 @@ extension on TranslationsZh {
'companionRemote.pairing.cameraPermissionRequired' => '扫描 QR 码需要相机权限。\n请在设备设置中授予相机访问权限。',
'companionRemote.pairing.cameraError' => ({required Object error}) => '无法启动相机:${error}',
'companionRemote.pairing.scanInstruction' => '将相机对准桌面上显示的 QR 码',
'companionRemote.pairing.noRecentConnections' => '没有最近的连接',
'companionRemote.pairing.connectUsingManual' => '使用手动输入连接设备以开始使用',
'companionRemote.pairing.invalidQrCode' => '无效的 QR 码格式',
'companionRemote.pairing.removeRecentConnection' => '删除最近连接',
'companionRemote.pairing.removeConfirm' => ({required Object name}) => '确定要从最近连接中删除 "${name}" 吗?',
'companionRemote.pairing.validationHostRequired' => '请输入主机地址',
'companionRemote.pairing.validationHostFormat' => '格式必须为 IP:端口(例如 192.168.1.100:48632',
'companionRemote.pairing.validationSessionIdRequired' => '请输入会话 ID',
@@ -1982,7 +1967,6 @@ extension on TranslationsZh {
'companionRemote.pairing.connectionTimedOut' => '连接超时。请检查会话 ID 和 PIN。',
'companionRemote.pairing.sessionNotFound' => '找不到会话。请检查您的凭据。',
'companionRemote.pairing.failedToConnect' => ({required Object error}) => '连接失败:${error}',
'companionRemote.pairing.failedToLoadRecent' => ({required Object error}) => '加载最近会话失败:${error}',
'companionRemote.remote.disconnectConfirm' => '是否要断开远程会话的连接?',
'companionRemote.remote.reconnecting' => '重新连接中...',
'companionRemote.remote.attemptOf' => ({required Object current}) => '${current} 次尝试,共 5 次',
+1 -9
View File
@@ -732,11 +732,8 @@
"minimize": "Minimera"
},
"pairing": {
"recent": "Senaste",
"scan": "Skanna",
"manual": "Manuell",
"recentConnections": "Senaste anslutningar",
"quickReconnect": "Återanslut snabbt till tidigare parkopplade enheter",
"pairWithDesktop": "Parkoppla med dator",
"enterSessionDetails": "Ange sessionsuppgifterna som visas på din datorenhet",
"hostAddressHint": "192.168.1.100:48632",
@@ -750,11 +747,7 @@
"cameraPermissionRequired": "Kamerabehörighet krävs för att skanna QR-koder.\nVänligen ge kameraåtkomst i enhetsinställningarna.",
"cameraError": "Kunde inte starta kameran: ${error}",
"scanInstruction": "Rikta kameran mot QR-koden som visas på din dator",
"noRecentConnections": "Inga senaste anslutningar",
"connectUsingManual": "Anslut till en enhet via Manuell inmatning för att komma igång",
"invalidQrCode": "Ogiltigt QR-kodformat",
"removeRecentConnection": "Ta bort senaste anslutning",
"removeConfirm": "Ta bort \"${name}\" från senaste anslutningar?",
"validationHostRequired": "Ange en värdadress",
"validationHostFormat": "Format måste vara IP:port (t.ex. 192.168.1.100:48632)",
"validationSessionIdRequired": "Ange ett sessions-ID",
@@ -763,8 +756,7 @@
"validationPinLength": "PIN måste vara 6 siffror",
"connectionTimedOut": "Anslutningen tog för lång tid. Kontrollera sessions-ID och PIN.",
"sessionNotFound": "Kunde inte hitta sessionen. Kontrollera dina uppgifter.",
"failedToConnect": "Kunde inte ansluta: ${error}",
"failedToLoadRecent": "Kunde inte ladda senaste sessioner: ${error}"
"failedToConnect": "Kunde inte ansluta: ${error}"
},
"remote": {
"disconnectConfirm": "Vill du koppla från fjärrsessionen?",
+1 -9
View File
@@ -732,11 +732,8 @@
"minimize": "最小化"
},
"pairing": {
"recent": "最近",
"scan": "扫描",
"manual": "手动",
"recentConnections": "最近连接",
"quickReconnect": "快速重新连接之前配对的设备",
"pairWithDesktop": "与桌面配对",
"enterSessionDetails": "输入桌面设备上显示的会话信息",
"hostAddressHint": "192.168.1.100:48632",
@@ -750,11 +747,7 @@
"cameraPermissionRequired": "扫描 QR 码需要相机权限。\n请在设备设置中授予相机访问权限。",
"cameraError": "无法启动相机:${error}",
"scanInstruction": "将相机对准桌面上显示的 QR 码",
"noRecentConnections": "没有最近的连接",
"connectUsingManual": "使用手动输入连接设备以开始使用",
"invalidQrCode": "无效的 QR 码格式",
"removeRecentConnection": "删除最近连接",
"removeConfirm": "确定要从最近连接中删除 \"${name}\" 吗?",
"validationHostRequired": "请输入主机地址",
"validationHostFormat": "格式必须为 IP:端口(例如 192.168.1.100:48632",
"validationSessionIdRequired": "请输入会话 ID",
@@ -763,8 +756,7 @@
"validationPinLength": "PIN 必须为6位数字",
"connectionTimedOut": "连接超时。请检查会话 ID 和 PIN。",
"sessionNotFound": "找不到会话。请检查您的凭据。",
"failedToConnect": "连接失败:${error}",
"failedToLoadRecent": "加载最近会话失败:${error}"
"failedToConnect": "连接失败:${error}"
},
"remote": {
"disconnectConfirm": "是否要断开远程会话的连接?",
@@ -1,55 +0,0 @@
import 'package:json_annotation/json_annotation.dart';
part 'recent_remote_session.g.dart';
/// Recent Companion Remote session for quick reconnection
@JsonSerializable()
class RecentRemoteSession {
final String sessionId;
final String pin;
final String deviceName;
final String platform;
final DateTime lastConnected;
final String? hostAddress; // Format: "ip:port"
RecentRemoteSession({
required this.sessionId,
required this.pin,
required this.deviceName,
required this.platform,
required this.lastConnected,
this.hostAddress,
});
factory RecentRemoteSession.fromJson(Map<String, dynamic> json) => _$RecentRemoteSessionFromJson(json);
Map<String, dynamic> toJson() => _$RecentRemoteSessionToJson(this);
/// Create from QR code data (format: "ip1,ip2|port|sessionId|pin" or legacy "ip|port|sessionId|pin")
factory RecentRemoteSession.fromQrData(String qrData) {
final parts = qrData.split('|');
if (parts.length < 4) {
throw FormatException('Invalid QR code format - expected ip|port|sessionId|pin');
}
final ipsField = parts.first;
final port = parts[1];
final sessionId = parts[2];
final pin = parts[3];
// Use the first IP for storage (comma-separated IPs supported in QR)
final firstIp = ipsField.split(',').first;
return RecentRemoteSession(
sessionId: sessionId,
pin: pin,
deviceName: 'Unknown Device',
platform: 'unknown',
lastConnected: DateTime.now(),
hostAddress: '$firstIp:$port',
);
}
@override
String toString() => '$deviceName ($platform) - Last: ${lastConnected.toLocal()}';
}
@@ -1,25 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'recent_remote_session.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
RecentRemoteSession _$RecentRemoteSessionFromJson(Map<String, dynamic> json) => RecentRemoteSession(
sessionId: json['sessionId'] as String,
pin: json['pin'] as String,
deviceName: json['deviceName'] as String,
platform: json['platform'] as String,
lastConnected: DateTime.parse(json['lastConnected'] as String),
hostAddress: json['hostAddress'] as String?,
);
Map<String, dynamic> _$RecentRemoteSessionToJson(RecentRemoteSession instance) => <String, dynamic>{
'sessionId': instance.sessionId,
'pin': instance.pin,
'deviceName': instance.deviceName,
'platform': instance.platform,
'lastConnected': instance.lastConnected.toIso8601String(),
'hostAddress': instance.hostAddress,
};
+1 -91
View File
@@ -10,8 +10,6 @@ import '../models/companion_remote/remote_command_type.dart';
import '../models/companion_remote/remote_session.dart';
import '../models/companion_remote/trusted_device.dart';
import '../services/companion_remote/companion_remote_peer_service.dart';
import '../models/companion_remote/recent_remote_session.dart';
import '../services/companion_remote/companion_remote_discovery_service.dart';
import '../services/storage_service.dart';
import '../utils/app_logger.dart';
@@ -21,11 +19,9 @@ typedef DeviceApprovalCallback = Future<bool> Function(RemoteDevice device);
class CompanionRemoteProvider with ChangeNotifier {
RemoteSession? _session;
CompanionRemotePeerService? _peerService;
CompanionRemoteDiscoveryService? _discoveryService;
String _deviceName = 'Unknown Device';
String _platform = 'unknown';
final List<TrustedDevice> _trustedDevices = [];
final List<RecentRemoteSession> _recentSessions = [];
bool _isPlayerActive = false;
static const String _storageKey = 'companion_remote_trusted_devices';
@@ -46,7 +42,6 @@ class CompanionRemoteProvider with ChangeNotifier {
StreamSubscription<void>? _deviceDisconnectedSubscription;
StreamSubscription<RemotePeerError>? _errorSubscription;
StreamSubscription<RemoteSessionStatus>? _statusSubscription;
StreamSubscription<List<RecentRemoteSession>>? _recentSessionsSubscription;
CommandReceivedCallback? onCommandReceived;
DeviceApprovalCallback? onDeviceApprovalRequired;
@@ -61,7 +56,6 @@ class CompanionRemoteProvider with ChangeNotifier {
String? get pin => _session?.pin;
RemoteDevice? get connectedDevice => _session?.connectedDevice;
List<TrustedDevice> get trustedDevices => List.unmodifiable(_trustedDevices);
List<RecentRemoteSession> get recentSessions => List.unmodifiable(_recentSessions);
bool get isPlayerActive => _isPlayerActive;
CompanionRemoteProvider() {
@@ -165,7 +159,7 @@ class CompanionRemoteProvider with ChangeNotifier {
});
}
Future<void> _handleDeviceInfo(RemoteCommand command) async {
void _handleDeviceInfo(RemoteCommand command) {
if (command.data != null) {
final id = command.data!['id'] as String? ?? 'unknown';
final name = command.data!['name'] as String? ?? 'Unknown Device';
@@ -178,9 +172,6 @@ class CompanionRemoteProvider with ChangeNotifier {
_session = _session?.copyWith(connectedDevice: device);
notifyListeners();
// Save to recent sessions now that we have the remote device's real identity
await _addToRecentSessions();
}
}
@@ -470,91 +461,10 @@ class CompanionRemoteProvider with ChangeNotifier {
return storage.prefs.getString(_lastDeviceKey);
}
/// Load recent sessions
Future<void> loadRecentSessions() async {
try {
// Dispose previous discovery service and subscription to avoid leaks
_recentSessionsSubscription?.cancel();
_recentSessionsSubscription = null;
_discoveryService?.dispose();
_discoveryService = CompanionRemoteDiscoveryService();
// Listen for recent sessions updates
_recentSessionsSubscription = _discoveryService!.recentSessions.listen((sessions) {
_recentSessions.clear();
_recentSessions.addAll(sessions);
notifyListeners();
});
// Initial load happens in constructor, just notify
_recentSessions.clear();
_recentSessions.addAll(_discoveryService!.currentSessions);
notifyListeners();
appLogger.d('CompanionRemote: Loaded ${_recentSessions.length} recent sessions');
} catch (e) {
appLogger.e('CompanionRemote: Failed to load recent sessions', error: e);
}
}
/// Add current session to recent list (called after successful connection)
Future<void> _addToRecentSessions() async {
if (_session == null || _session!.sessionId.isEmpty) return;
// For mobile (remote role), save the connected desktop device
// For desktop (host role), this doesn't really apply but save connected mobile device
final deviceToSave = _session!.connectedDevice;
if (deviceToSave == null) {
appLogger.w('CompanionRemote: No connected device to save to recent sessions');
return;
}
final recentSession = RecentRemoteSession(
sessionId: _session!.sessionId,
pin: _session!.pin,
deviceName: deviceToSave.name,
platform: deviceToSave.platform,
lastConnected: DateTime.now(),
hostAddress: _peerService?.hostAddress,
);
if (_discoveryService != null) {
await _discoveryService!.addRecentSession(recentSession);
}
}
/// Connect to a recent session
Future<void> connectToRecentSession(RecentRemoteSession session) async {
if (session.hostAddress == null) {
throw const RemotePeerError(
type: RemotePeerErrorType.invalidSession,
message: 'No host address available for this session. Please scan a new QR code.',
);
}
await joinSession(session.sessionId, session.pin, session.hostAddress!);
}
/// Remove a recent session
Future<void> removeRecentSession(String sessionId) async {
if (_discoveryService != null) {
await _discoveryService!.removeRecentSession(sessionId);
}
}
/// Clear all recent sessions
Future<void> clearRecentSessions() async {
if (_discoveryService != null) {
await _discoveryService!.clearRecentSessions();
}
}
@override
void dispose() {
_reconnectTimer?.cancel();
leaveSession();
_recentSessionsSubscription?.cancel();
_discoveryService?.dispose();
super.dispose();
}
}
+20 -219
View File
@@ -5,11 +5,8 @@ import 'package:flutter/services.dart';
import 'package:mobile_scanner/mobile_scanner.dart';
import 'package:provider/provider.dart';
import '../../focus/focusable_button.dart';
import '../../i18n/strings.g.dart';
import '../../providers/companion_remote_provider.dart';
import '../../utils/formatters.dart';
import '../../models/companion_remote/recent_remote_session.dart';
import '../../utils/app_logger.dart';
class PairingScreen extends StatefulWidget {
@@ -25,8 +22,6 @@ class _PairingScreenState extends State<PairingScreen> {
final _pinController = TextEditingController();
final _formKey = GlobalKey<FormState>();
bool _isConnecting = false;
String? _connectingSessionId;
bool _isDiscovering = false;
String? _errorMessage;
int _selectedTab = 0;
@@ -36,15 +31,9 @@ class _PairingScreenState extends State<PairingScreen> {
bool get _isMobile => Platform.isAndroid || Platform.isIOS;
// Tab indices shift when scan tab is present
int get _scanTabIndex => _isMobile ? 1 : -1;
int get _manualTabIndex => _isMobile ? 2 : 1;
@override
void initState() {
super.initState();
_loadRecentSessions();
}
// Tab indices: mobile gets Scan (0) + Manual (1), desktop gets Manual (0)
int get _scanTabIndex => _isMobile ? 0 : -1;
int get _manualTabIndex => _isMobile ? 1 : 0;
@override
void dispose() {
@@ -55,51 +44,6 @@ class _PairingScreenState extends State<PairingScreen> {
super.dispose();
}
Future<void> _loadRecentSessions() async {
setState(() {
_isDiscovering = true;
_errorMessage = null;
});
try {
await context.read<CompanionRemoteProvider>().loadRecentSessions();
if (!mounted) return;
setState(() {
_isDiscovering = false;
});
} catch (e) {
appLogger.e('Failed to load recent sessions', error: e);
if (!mounted) return;
setState(() {
_isDiscovering = false;
_errorMessage = t.companionRemote.pairing.failedToLoadRecent(error: e.toString());
});
}
}
Future<void> _connectToRecentSession(RecentRemoteSession session) async {
setState(() {
_isConnecting = true;
_connectingSessionId = session.sessionId;
_errorMessage = null;
});
try {
await context.read<CompanionRemoteProvider>().connectToRecentSession(session);
if (mounted) {
Navigator.of(context).pop();
}
} catch (e) {
appLogger.e('Failed to connect to recent session', error: e);
setState(() {
_isConnecting = false;
_connectingSessionId = null;
_errorMessage = _parseErrorMessage(e.toString());
});
}
}
Future<void> _connect() async {
if (!_formKey.currentState!.validate()) {
return;
@@ -209,39 +153,30 @@ class _PairingScreenState extends State<PairingScreen> {
return Scaffold(
appBar: AppBar(
title: Text(t.companionRemote.connectToDevice),
actions: [
if (_selectedTab == 0)
IconButton(
icon: const Icon(Icons.refresh),
onPressed: _isDiscovering ? null : _loadRecentSessions,
tooltip: t.common.refresh,
),
],
),
body: Column(
children: [
SegmentedButton<int>(
segments: [
ButtonSegment(value: 0, label: Text(t.companionRemote.pairing.recent), icon: const Icon(Icons.history)),
if (_isMobile)
if (_isMobile)
SegmentedButton<int>(
segments: [
ButtonSegment(
value: _scanTabIndex,
label: Text(t.companionRemote.pairing.scan),
icon: const Icon(Icons.qr_code_scanner),
),
ButtonSegment(
value: _manualTabIndex,
label: Text(t.companionRemote.pairing.manual),
icon: const Icon(Icons.keyboard),
),
],
selected: {_selectedTab},
onSelectionChanged: (Set<int> selection) {
setState(() {
_selectedTab = selection.first;
});
},
),
ButtonSegment(
value: _manualTabIndex,
label: Text(t.companionRemote.pairing.manual),
icon: const Icon(Icons.keyboard),
),
],
selected: {_selectedTab},
onSelectionChanged: (Set<int> selection) {
setState(() {
_selectedTab = selection.first;
});
},
),
Expanded(child: _buildTabContent()),
],
),
@@ -249,8 +184,7 @@ class _PairingScreenState extends State<PairingScreen> {
}
Widget _buildTabContent() {
if (_selectedTab == 0) return _buildDiscoveryTab();
if (_selectedTab == _scanTabIndex) return _buildScanTab();
if (_selectedTab == _scanTabIndex && _isMobile) return _buildScanTab();
return _buildManualEntryTab();
}
@@ -337,139 +271,6 @@ class _PairingScreenState extends State<PairingScreen> {
);
}
Widget _buildDiscoveryTab() {
return Consumer<CompanionRemoteProvider>(
builder: (context, provider, child) {
final sessions = provider.recentSessions;
return SingleChildScrollView(
padding: const EdgeInsets.all(24.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Icon(Icons.history, size: 64, color: Colors.blue),
const SizedBox(height: 24),
Text(
t.companionRemote.pairing.recentConnections,
style: Theme.of(context).textTheme.headlineMedium,
textAlign: TextAlign.center,
),
const SizedBox(height: 8),
Text(
t.companionRemote.pairing.quickReconnect,
style: Theme.of(context).textTheme.bodyMedium,
textAlign: TextAlign.center,
),
const SizedBox(height: 32),
if (_isDiscovering) ...[
const Center(child: CircularProgressIndicator()),
const SizedBox(height: 16),
Text(t.common.loading, style: Theme.of(context).textTheme.bodyMedium, textAlign: TextAlign.center),
] else if (sessions.isEmpty) ...[
Card(
child: Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
children: [
Icon(Icons.devices_other, size: 48, color: Theme.of(context).colorScheme.outline),
const SizedBox(height: 16),
Text(
t.companionRemote.pairing.noRecentConnections,
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 8),
Text(
t.companionRemote.pairing.connectUsingManual,
style: Theme.of(context).textTheme.bodySmall,
textAlign: TextAlign.center,
),
],
),
),
),
] else ...[
...sessions.map((session) {
final isThisConnecting = _isConnecting && _connectingSessionId == session.sessionId;
return Card(
margin: const EdgeInsets.only(bottom: 8),
child: ListTile(
leading: const Icon(Icons.computer, size: 40),
title: Text(session.deviceName),
subtitle: Text(
'${session.platform}\n'
'Session: ${session.sessionId}\n'
'Last used: ${_formatDate(session.lastConnected)}',
),
isThreeLine: true,
trailing: isThisConnecting
? const SizedBox(width: 24, height: 24, child: CircularProgressIndicator(strokeWidth: 2))
: const Icon(Icons.arrow_forward),
onTap: _isConnecting ? null : () => _connectToRecentSession(session),
onLongPress: () => _showRemoveSessionDialog(session),
),
);
}),
],
if (_errorMessage != null) ...[
const SizedBox(height: 16),
Card(
color: Theme.of(context).colorScheme.errorContainer,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
children: [
Icon(Icons.error_outline, color: Theme.of(context).colorScheme.onErrorContainer),
const SizedBox(width: 12),
Expanded(
child: Text(
_errorMessage!,
style: TextStyle(color: Theme.of(context).colorScheme.onErrorContainer),
),
),
],
),
),
),
],
],
),
);
},
);
}
String _formatDate(DateTime date) {
return formatRelativeTime(date);
}
Future<void> _showRemoveSessionDialog(RecentRemoteSession session) async {
final confirmed = await showDialog<bool>(
context: context,
builder: (context) => AlertDialog(
title: Text(t.companionRemote.pairing.removeRecentConnection),
content: Text(t.companionRemote.pairing.removeConfirm(name: session.deviceName)),
actions: [
FocusableButton(
autofocus: true,
onPressed: () => Navigator.pop(context, false),
child: TextButton(
onPressed: () => Navigator.pop(context, false),
child: Text(t.common.cancel),
),
),
FocusableButton(
onPressed: () => Navigator.pop(context, true),
child: TextButton(onPressed: () => Navigator.pop(context, true), child: Text(t.common.remove)),
),
],
),
);
if (confirmed == true && mounted) {
await context.read<CompanionRemoteProvider>().removeRecentSession(session.sessionId);
}
}
Widget _buildManualEntryTab() {
return SingleChildScrollView(
padding: const EdgeInsets.all(24.0),
@@ -1,95 +0,0 @@
import 'dart:async';
import 'dart:convert';
import '../../models/companion_remote/recent_remote_session.dart';
import '../../services/storage_service.dart';
import '../../utils/app_logger.dart';
/// Service for managing recent Companion Remote sessions
class CompanionRemoteDiscoveryService {
static const String _storageKey = 'companion_remote_recent_sessions';
static const int _maxRecentSessions = 5;
final _recentSessions = <RecentRemoteSession>[];
final _recentSessionsController = StreamController<List<RecentRemoteSession>>.broadcast();
/// Stream of recent sessions
Stream<List<RecentRemoteSession>> get recentSessions => _recentSessionsController.stream;
/// Get current list of recent sessions
List<RecentRemoteSession> get currentSessions => List.unmodifiable(_recentSessions);
CompanionRemoteDiscoveryService() {
_loadRecentSessions();
}
/// Load recent sessions from storage
Future<void> _loadRecentSessions() async {
try {
final storage = await StorageService.getInstance();
final json = storage.prefs.getString(_storageKey);
if (json != null) {
final List<dynamic> list = jsonDecode(json);
_recentSessions.clear();
_recentSessions.addAll(list.map((e) => RecentRemoteSession.fromJson(e as Map<String, dynamic>)));
// Sort by last connected (most recent first)
_recentSessions.sort((a, b) => b.lastConnected.compareTo(a.lastConnected));
_recentSessionsController.add(currentSessions);
appLogger.d('Loaded ${_recentSessions.length} recent remote sessions');
}
} catch (e) {
appLogger.e('Failed to load recent sessions', error: e);
}
}
/// Save recent sessions to storage
Future<void> _saveRecentSessions() async {
try {
final storage = await StorageService.getInstance();
final json = jsonEncode(_recentSessions.map((e) => e.toJson()).toList());
await storage.prefs.setString(_storageKey, json);
appLogger.d('Saved ${_recentSessions.length} recent remote sessions');
} catch (e) {
appLogger.e('Failed to save recent sessions', error: e);
}
}
/// Add a session to recent list
Future<void> addRecentSession(RecentRemoteSession session) async {
// Remove existing entry for this session ID
_recentSessions.removeWhere((s) => s.sessionId == session.sessionId);
// Add new entry at the beginning
_recentSessions.insert(0, session);
// Limit to max sessions
if (_recentSessions.length > _maxRecentSessions) {
_recentSessions.removeRange(_maxRecentSessions, _recentSessions.length);
}
await _saveRecentSessions();
_recentSessionsController.add(currentSessions);
}
/// Remove a session from recent list
Future<void> removeRecentSession(String sessionId) async {
_recentSessions.removeWhere((s) => s.sessionId == sessionId);
await _saveRecentSessions();
_recentSessionsController.add(currentSessions);
}
/// Clear all recent sessions
Future<void> clearRecentSessions() async {
_recentSessions.clear();
await _saveRecentSessions();
_recentSessionsController.add(currentSessions);
}
/// Dispose resources
Future<void> dispose() async {
await _recentSessionsController.close();
}
}