fix(videocall): apply PR review fixes and add i18n translations

- Replace setState with FutureBuilder in VideoViewWidget
- Remove comments from datasource impl
- Replace GetIt.I with ref.read(provider) in controllers
- Fix state comparison using isTalking getter
- Add hangUp/stopAudio/stopCamera cleanup on dispose
- Remove duplicate SafeArea from IncomingCallOverlay
- Add missedCall error event to enum
- Replace Colors.white70 with theme colorScheme
- Move VIDEOCALL_INTEGRATION.md to apps/mobile_app/docs/
- Gitignore config JSON files with app keys
- Add 28 i18n keys in 6 locales for all videocall strings
- Map error events to specific i18n messages
This commit is contained in:
2026-04-26 10:27:25 +02:00
parent 57f0f64d08
commit 5aa0c0acc7
26 changed files with 329 additions and 180 deletions

View File

@@ -683,6 +683,34 @@
"locationRevealSkip": "Überspringen",
"locationDeleteGeofenceConfirm": "Möchten Sie diese sichere Zone wirklich löschen?",
"locationDeleteFrequentPlaceConfirm": "Möchten Sie diesen häufigen Ort wirklich löschen?",
"videocallTitle": "Videoanruf",
"videocallInitializingSdk": "SDK wird initialisiert...",
"videocallRecipientUserId": "Benutzer-ID des Empfängers",
"videocallStart": "Videoanruf starten",
"videocallLoggedInAs": "Angemeldet als: {userId}",
"videocallCalling": "{userId} wird angerufen...",
"videocallUserCalling": "{userId} ruft dich an",
"videocallIncomingVideo": "Eingehender Videoanruf",
"videocallIncomingAudio": "Eingehender Anruf",
"videocallReject": "Ablehnen",
"videocallAccept": "Annehmen",
"videocallMicOn": "Mikro an",
"videocallMicOff": "Mikro aus",
"videocallSpeaker": "Lautsprecher",
"videocallEarpiece": "Hörer",
"videocallCameraFront": "Vorne",
"videocallCameraBack": "Hinten",
"videocallHangUp": "Auflegen",
"videocallWaitingParticipants": "Warten auf Teilnehmer...",
"videocallWaitingRemoteVideo": "Warten auf Remote-Video...",
"videocallYou": "Du",
"videocallErrorSdkInit": "Fehler beim Initialisieren des Videoanrufs",
"videocallErrorAuth": "Authentifizierungsfehler beim Videoanruf",
"videocallErrorCallStart": "Fehler beim Starten des Anrufs",
"videocallErrorCallAnswer": "Fehler beim Annehmen des Anrufs",
"videocallErrorCamera": "Kameraberechtigung erforderlich",
"videocallErrorMic": "Mikrofonberechtigung erforderlich",
"videocallErrorMissedCall": "Verpasster Anruf",
"positionUpdated": "Letzte verfügbare Position aktualisiert",
"locationMapStyleLight": "Hell",
"locationMapStyleDark": "Dunkel",
@@ -757,7 +785,7 @@
"frequentPlaceCreated": "Häufiger Ort erstellt",
"frequentPlaceUpdated": "Häufiger Ort aktualisiert",
"frequentPlaceDeleted": "Häufiger Ort gelöscht",
"errorGeneric": "Etwas ist schiefgelaufen. Bitte versuchen Sie es erneut.",
"errorGeneric": "Ein unerwarteter Fehler ist aufgetreten.",
"pullDownToRetry": "Zum Wiederholen nach unten ziehen",
"errorGeofenceCreate": "Die Sicherheitszone konnte nicht erstellt werden",
"errorGeofenceUpdate": "Die Sicherheitszone konnte nicht aktualisiert werden",
@@ -1060,6 +1088,5 @@
"errorSessionExpired": "Deine Sitzung ist abgelaufen. Bitte melde dich erneut an.",
"errorValidation": "Die eingegebenen Daten sind ungültig.",
"errorScaRequired": "Eine zusätzliche Authentifizierung ist erforderlich.",
"errorDeviceNotOwned": "Du hast keine Berechtigung, auf dieses Gerät zuzugreifen.",
"errorGeneric": "Ein unerwarteter Fehler ist aufgetreten."
"errorDeviceNotOwned": "Du hast keine Berechtigung, auf dieses Gerät zuzugreifen."
}

View File

@@ -863,6 +863,34 @@
"locationRevealSkip": "Skip",
"locationDeleteGeofenceConfirm": "Are you sure you want to delete this safe zone?",
"locationDeleteFrequentPlaceConfirm": "Are you sure you want to delete this frequent place?",
"videocallTitle": "Video Call",
"videocallInitializingSdk": "Initializing SDK...",
"videocallRecipientUserId": "Recipient User ID",
"videocallStart": "Start video call",
"videocallLoggedInAs": "Logged in as: {userId}",
"videocallCalling": "Calling {userId}...",
"videocallUserCalling": "{userId} is calling you",
"videocallIncomingVideo": "Incoming video call",
"videocallIncomingAudio": "Incoming call",
"videocallReject": "Reject",
"videocallAccept": "Accept",
"videocallMicOn": "Mic On",
"videocallMicOff": "Mic Off",
"videocallSpeaker": "Speaker",
"videocallEarpiece": "Earpiece",
"videocallCameraFront": "Front",
"videocallCameraBack": "Back",
"videocallHangUp": "Hang Up",
"videocallWaitingParticipants": "Waiting for participants...",
"videocallWaitingRemoteVideo": "Waiting for remote video...",
"videocallYou": "You",
"videocallErrorSdkInit": "Error initializing video call",
"videocallErrorAuth": "Video call authentication error",
"videocallErrorCallStart": "Error starting the call",
"videocallErrorCallAnswer": "Error answering the call",
"videocallErrorCamera": "Camera permission required",
"videocallErrorMic": "Microphone permission required",
"videocallErrorMissedCall": "Missed call",
"positionUpdated": "Updated to latest available position",
"locationMapStyleLight": "Light",
"locationMapStyleDark": "Dark",
@@ -931,7 +959,7 @@
"frequentPlaceCreated": "Frequent place created",
"frequentPlaceUpdated": "Frequent place updated",
"frequentPlaceDeleted": "Frequent place deleted",
"errorGeneric": "Something went wrong. Please try again.",
"errorGeneric": "An unexpected error occurred.",
"pullDownToRetry": "Pull down to retry",
"errorGeofenceCreate": "Could not create the safety zone",
"errorGeofenceUpdate": "Could not update the safety zone",
@@ -1060,6 +1088,5 @@
"errorSessionExpired": "Your session has expired. Please sign in again.",
"errorValidation": "The information you entered is not valid.",
"errorScaRequired": "Additional authentication is required to continue.",
"errorDeviceNotOwned": "You don't have permission to access this device.",
"errorGeneric": "An unexpected error occurred."
"errorDeviceNotOwned": "You don't have permission to access this device."
}

View File

@@ -864,6 +864,34 @@
"locationRevealSkip": "Saltar",
"locationDeleteGeofenceConfirm": "¿Seguro que quieres eliminar esta zona segura?",
"locationDeleteFrequentPlaceConfirm": "¿Seguro que quieres eliminar este lugar frecuente?",
"videocallTitle": "Videollamada",
"videocallInitializingSdk": "Inicializando SDK...",
"videocallRecipientUserId": "User ID del destinatario",
"videocallStart": "Iniciar videollamada",
"videocallLoggedInAs": "Conectado como: {userId}",
"videocallCalling": "Llamando a {userId}...",
"videocallUserCalling": "{userId} te está llamando",
"videocallIncomingVideo": "Videollamada entrante",
"videocallIncomingAudio": "Llamada entrante",
"videocallReject": "Rechazar",
"videocallAccept": "Aceptar",
"videocallMicOn": "Mic On",
"videocallMicOff": "Mic Off",
"videocallSpeaker": "Altavoz",
"videocallEarpiece": "Auricular",
"videocallCameraFront": "Frontal",
"videocallCameraBack": "Trasera",
"videocallHangUp": "Colgar",
"videocallWaitingParticipants": "Esperando participantes...",
"videocallWaitingRemoteVideo": "Esperando video remoto...",
"videocallYou": "Tú",
"videocallErrorSdkInit": "Error al inicializar videollamada",
"videocallErrorAuth": "Error de autenticación de videollamada",
"videocallErrorCallStart": "Error al iniciar la llamada",
"videocallErrorCallAnswer": "Error al contestar la llamada",
"videocallErrorCamera": "Se requiere permiso de cámara",
"videocallErrorMic": "Se requiere permiso de micrófono",
"videocallErrorMissedCall": "Llamada perdida",
"positionUpdated": "Última posición disponible actualizada",
"locationMapStyleLight": "Claro",
"locationMapStyleDark": "Oscuro",
@@ -932,7 +960,7 @@
"frequentPlaceCreated": "Lugar frecuente creado",
"frequentPlaceUpdated": "Lugar frecuente actualizado",
"frequentPlaceDeleted": "Lugar frecuente eliminado",
"errorGeneric": "Algo salió mal. Inténtalo de nuevo.",
"errorGeneric": "Ha ocurrido un error inesperado.",
"pullDownToRetry": "Desliza hacia abajo para reintentar",
"errorGeofenceCreate": "No se pudo crear la zona de seguridad",
"errorGeofenceUpdate": "No se pudo actualizar la zona de seguridad",
@@ -1060,6 +1088,5 @@
"errorSessionExpired": "Tu sesión ha caducado. Vuelve a iniciar sesión.",
"errorValidation": "Los datos introducidos no son válidos.",
"errorScaRequired": "Se requiere autenticación adicional para continuar.",
"errorDeviceNotOwned": "No tienes permiso para acceder a este dispositivo.",
"errorGeneric": "Ha ocurrido un error inesperado."
"errorDeviceNotOwned": "No tienes permiso para acceder a este dispositivo."
}

View File

@@ -683,6 +683,34 @@
"locationRevealSkip": "Passer",
"locationDeleteGeofenceConfirm": "Voulez-vous supprimer cette zone sûre ?",
"locationDeleteFrequentPlaceConfirm": "Voulez-vous supprimer ce lieu fréquent ?",
"videocallTitle": "Appel vidéo",
"videocallInitializingSdk": "Initialisation du SDK...",
"videocallRecipientUserId": "ID utilisateur du destinataire",
"videocallStart": "Démarrer l'appel vidéo",
"videocallLoggedInAs": "Connecté en tant que : {userId}",
"videocallCalling": "Appel de {userId}...",
"videocallUserCalling": "{userId} vous appelle",
"videocallIncomingVideo": "Appel vidéo entrant",
"videocallIncomingAudio": "Appel entrant",
"videocallReject": "Rejeter",
"videocallAccept": "Accepter",
"videocallMicOn": "Micro activé",
"videocallMicOff": "Micro désactivé",
"videocallSpeaker": "Haut-parleur",
"videocallEarpiece": "Écouteur",
"videocallCameraFront": "Avant",
"videocallCameraBack": "Arrière",
"videocallHangUp": "Raccrocher",
"videocallWaitingParticipants": "En attente de participants...",
"videocallWaitingRemoteVideo": "En attente de la vidéo distante...",
"videocallYou": "Vous",
"videocallErrorSdkInit": "Erreur d'initialisation de l'appel vidéo",
"videocallErrorAuth": "Erreur d'authentification de l'appel vidéo",
"videocallErrorCallStart": "Erreur lors du démarrage de l'appel",
"videocallErrorCallAnswer": "Erreur lors de la réponse à l'appel",
"videocallErrorCamera": "Autorisation de la caméra requise",
"videocallErrorMic": "Autorisation du microphone requise",
"videocallErrorMissedCall": "Appel manqué",
"positionUpdated": "Dernière position disponible mise à jour",
"locationMapStyleLight": "Clair",
"locationMapStyleDark": "Sombre",
@@ -757,7 +785,7 @@
"frequentPlaceCreated": "Lieu fréquent créé",
"frequentPlaceUpdated": "Lieu fréquent mis à jour",
"frequentPlaceDeleted": "Lieu fréquent supprimé",
"errorGeneric": "Une erreur est survenue. Veuillez réessayer.",
"errorGeneric": "Une erreur inattendue s'est produite.",
"pullDownToRetry": "Tirez vers le bas pour réessayer",
"errorGeofenceCreate": "Impossible de créer la zone de sécurité",
"errorGeofenceUpdate": "Impossible de mettre à jour la zone de sécurité",
@@ -1060,6 +1088,5 @@
"errorSessionExpired": "Votre session a expiré. Veuillez vous reconnecter.",
"errorValidation": "Les données saisies ne sont pas valides.",
"errorScaRequired": "Une authentification supplémentaire est requise pour continuer.",
"errorDeviceNotOwned": "Vous n'avez pas l'autorisation d'accéder à cet appareil.",
"errorGeneric": "Une erreur inattendue s'est produite."
"errorDeviceNotOwned": "Vous n'avez pas l'autorisation d'accéder à cet appareil."
}

View File

@@ -683,6 +683,34 @@
"locationRevealSkip": "Salta",
"locationDeleteGeofenceConfirm": "Sei sicuro di voler eliminare questa zona sicura?",
"locationDeleteFrequentPlaceConfirm": "Sei sicuro di voler eliminare questo luogo frequente?",
"videocallTitle": "Videochiamata",
"videocallInitializingSdk": "Inizializzazione SDK...",
"videocallRecipientUserId": "ID utente del destinatario",
"videocallStart": "Avvia videochiamata",
"videocallLoggedInAs": "Connesso come: {userId}",
"videocallCalling": "Chiamata a {userId}...",
"videocallUserCalling": "{userId} ti sta chiamando",
"videocallIncomingVideo": "Videochiamata in arrivo",
"videocallIncomingAudio": "Chiamata in arrivo",
"videocallReject": "Rifiuta",
"videocallAccept": "Accetta",
"videocallMicOn": "Micro attivo",
"videocallMicOff": "Micro disattivato",
"videocallSpeaker": "Altoparlante",
"videocallEarpiece": "Auricolare",
"videocallCameraFront": "Anteriore",
"videocallCameraBack": "Posteriore",
"videocallHangUp": "Riaggancia",
"videocallWaitingParticipants": "In attesa di partecipanti...",
"videocallWaitingRemoteVideo": "In attesa del video remoto...",
"videocallYou": "Tu",
"videocallErrorSdkInit": "Errore nell'inizializzazione della videochiamata",
"videocallErrorAuth": "Errore di autenticazione della videochiamata",
"videocallErrorCallStart": "Errore nell'avvio della chiamata",
"videocallErrorCallAnswer": "Errore nel rispondere alla chiamata",
"videocallErrorCamera": "Permesso fotocamera richiesto",
"videocallErrorMic": "Permesso microfono richiesto",
"videocallErrorMissedCall": "Chiamata persa",
"positionUpdated": "Ultima posizione disponibile aggiornata",
"locationMapStyleLight": "Chiaro",
"locationMapStyleDark": "Scuro",
@@ -757,7 +785,7 @@
"frequentPlaceCreated": "Luogo frequente creato",
"frequentPlaceUpdated": "Luogo frequente aggiornato",
"frequentPlaceDeleted": "Luogo frequente eliminato",
"errorGeneric": "Qualcosa è andato storto. Riprova.",
"errorGeneric": "Si è verificato un errore imprevisto.",
"pullDownToRetry": "Trascina verso il basso per riprovare",
"errorGeofenceCreate": "Impossibile creare la zona di sicurezza",
"errorGeofenceUpdate": "Impossibile aggiornare la zona di sicurezza",
@@ -1060,6 +1088,5 @@
"errorSessionExpired": "La tua sessione è scaduta. Accedi di nuovo.",
"errorValidation": "I dati inseriti non sono validi.",
"errorScaRequired": "È richiesta un'autenticazione aggiuntiva per continuare.",
"errorDeviceNotOwned": "Non hai il permesso di accedere a questo dispositivo.",
"errorGeneric": "Si è verificato un errore imprevisto."
"errorDeviceNotOwned": "Non hai il permesso di accedere a questo dispositivo."
}

View File

@@ -683,6 +683,34 @@
"locationRevealSkip": "Saltar",
"locationDeleteGeofenceConfirm": "Tens a certeza que queres eliminar esta zona segura?",
"locationDeleteFrequentPlaceConfirm": "Tens a certeza que queres eliminar este lugar frequente?",
"videocallTitle": "Videochamada",
"videocallInitializingSdk": "A inicializar SDK...",
"videocallRecipientUserId": "ID do utilizador destinatário",
"videocallStart": "Iniciar videochamada",
"videocallLoggedInAs": "Conectado como: {userId}",
"videocallCalling": "A ligar para {userId}...",
"videocallUserCalling": "{userId} está a ligar-te",
"videocallIncomingVideo": "Videochamada recebida",
"videocallIncomingAudio": "Chamada recebida",
"videocallReject": "Rejeitar",
"videocallAccept": "Aceitar",
"videocallMicOn": "Micro ligado",
"videocallMicOff": "Micro desligado",
"videocallSpeaker": "Altifalante",
"videocallEarpiece": "Auricular",
"videocallCameraFront": "Frontal",
"videocallCameraBack": "Traseira",
"videocallHangUp": "Desligar",
"videocallWaitingParticipants": "A aguardar participantes...",
"videocallWaitingRemoteVideo": "A aguardar vídeo remoto...",
"videocallYou": "Tu",
"videocallErrorSdkInit": "Erro ao inicializar videochamada",
"videocallErrorAuth": "Erro de autenticação da videochamada",
"videocallErrorCallStart": "Erro ao iniciar a chamada",
"videocallErrorCallAnswer": "Erro ao atender a chamada",
"videocallErrorCamera": "Permissão de câmara necessária",
"videocallErrorMic": "Permissão de microfone necessária",
"videocallErrorMissedCall": "Chamada perdida",
"positionUpdated": "Última posição disponível atualizada",
"locationMapStyleLight": "Claro",
"locationMapStyleDark": "Escuro",
@@ -757,7 +785,7 @@
"frequentPlaceCreated": "Local frequente criado",
"frequentPlaceUpdated": "Local frequente atualizado",
"frequentPlaceDeleted": "Local frequente eliminado",
"errorGeneric": "Algo correu mal. Tente novamente.",
"errorGeneric": "Ocorreu um erro inesperado.",
"pullDownToRetry": "Deslize para baixo para tentar novamente",
"errorGeofenceCreate": "Não foi possível criar a zona de segurança",
"errorGeofenceUpdate": "Não foi possível atualizar a zona de segurança",
@@ -1060,6 +1088,5 @@
"errorSessionExpired": "A tua sessão expirou. Inicia sessão novamente.",
"errorValidation": "Os dados introduzidos não são válidos.",
"errorScaRequired": "É necessária autenticação adicional para continuar.",
"errorDeviceNotOwned": "Não tens permissão para aceder a este dispositivo.",
"errorGeneric": "Ocorreu um erro inesperado."
"errorDeviceNotOwned": "Não tens permissão para aceder a este dispositivo."
}

View File

@@ -1006,6 +1006,34 @@ class I18n {
static const String verifyAccount = 'verifyAccount';
static const String vibrationOnly = 'vibrationOnly';
static const String videoCall = 'videoCall';
static const String videocallAccept = 'videocallAccept';
static const String videocallCalling = 'videocallCalling';
static const String videocallCameraBack = 'videocallCameraBack';
static const String videocallCameraFront = 'videocallCameraFront';
static const String videocallEarpiece = 'videocallEarpiece';
static const String videocallErrorAuth = 'videocallErrorAuth';
static const String videocallErrorCallAnswer = 'videocallErrorCallAnswer';
static const String videocallErrorCallStart = 'videocallErrorCallStart';
static const String videocallErrorCamera = 'videocallErrorCamera';
static const String videocallErrorMic = 'videocallErrorMic';
static const String videocallErrorMissedCall = 'videocallErrorMissedCall';
static const String videocallErrorSdkInit = 'videocallErrorSdkInit';
static const String videocallHangUp = 'videocallHangUp';
static const String videocallIncomingAudio = 'videocallIncomingAudio';
static const String videocallIncomingVideo = 'videocallIncomingVideo';
static const String videocallInitializingSdk = 'videocallInitializingSdk';
static const String videocallLoggedInAs = 'videocallLoggedInAs';
static const String videocallMicOff = 'videocallMicOff';
static const String videocallMicOn = 'videocallMicOn';
static const String videocallRecipientUserId = 'videocallRecipientUserId';
static const String videocallReject = 'videocallReject';
static const String videocallSpeaker = 'videocallSpeaker';
static const String videocallStart = 'videocallStart';
static const String videocallTitle = 'videocallTitle';
static const String videocallUserCalling = 'videocallUserCalling';
static const String videocallWaitingParticipants = 'videocallWaitingParticipants';
static const String videocallWaitingRemoteVideo = 'videocallWaitingRemoteVideo';
static const String videocallYou = 'videocallYou';
static const String volumeAlarm = 'volumeAlarm';
static const String volumeControl = 'volumeControl';
static const String volumeHint = 'volumeHint';

View File

@@ -18,6 +18,8 @@ class VideocallItem {
final bool uploadVideoStreamSelf;
final bool uploadVideoStreamOther;
bool get isTalking => state == VideocallState.talking;
VideocallItem copyWith({
String? userId,
bool? isVideo,