From 1b237e4ea0a3eacd96ce8e543e86b2711adfc385 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 6 May 2020 21:46:11 +0200 Subject: [PATCH 01/20] pulled translations from transifex --- .../services/NotificationService.java | 4 - src/main/res/values-es/strings.xml | 33 +++ src/main/res/values-fr/strings.xml | 208 ++++++++++++------ src/main/res/values-ro-rRO/strings.xml | 38 ++-- src/quicksy/res/values-es/strings.xml | 2 + src/quicksy/res/values-fr/strings.xml | 2 + 6 files changed, 192 insertions(+), 95 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index ce2c8d6c9..17448fac3 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -426,10 +426,6 @@ public class NotificationService { cancel(INCOMING_CALL_NOTIFICATION_ID); } - public void cancelOngoingCallNotification() { - cancel(ONGOING_CALL_NOTIFICATION_ID); - } - private void pushNow(final Message message) { mXmppConnectionService.updateUnreadCountBadge(); if (!notify(message)) { diff --git a/src/main/res/values-es/strings.xml b/src/main/res/values-es/strings.xml index 20abbd248..58cae4f61 100644 --- a/src/main/res/values-es/strings.xml +++ b/src/main/res/values-es/strings.xml @@ -41,12 +41,14 @@ Moderador Participante Visitante + ¿Quieres eliminar a %s de tu lista de contactos? Las conversaciones con este contacto no se eliminarán. ¿Quieres bloquear a %s para que no pueda enviarte mensajes? ¿Quieres desbloquear a %s y permitirle que te envíe mensajes? ¿Bloquear todos los contactos de %s? ¿Desbloquear todos los contatos de %s? Contacto bloqueado Bloqueado + ¿Quieres eliminar %s de tus marcadores? Las conversaciones con este marcador no serán eliminadas. Registrar nueva cuenta en servidor Cambiar contraseña en servidor Compartir con... @@ -65,14 +67,22 @@ Guardar OK Conversations se ha detenido. + Usar tu cuenta XMPP para enviar trazas de error ayuda al desarrollo de Conversations. Enviar ahora No preguntar de nuevo + No se ha podido conectar a la cuenta + No se ha podido conectar a varias cuentas + Pulsa aquí para gestionar tus cuentas Adjuntar + El contacto no está en tu lista. ¿Te gustaría añadirlo? Añadir contacto Error al enviar + Preparando para enviar imagen + Preparando para enviar imágenes Compartiendo ficheros. Por favor, espera... Limpiar historial Limpiar historial de conversación + ¿Quieres borrar todos los mensajes de esta conversación?\n\nAviso: Esto no afectará a los mensajes guardados en otros dispositivos o servidores. Eliminar fichero ¿Estás seguro de que quieres borrar este fichero?\n\nAviso:Esto no borrará las copias de este fichero almacenado en otros dispositivos o servidores. Cerrar esta conversación después @@ -83,16 +93,20 @@ Enviar mensaje cifrado con OMEMO Enviar mensaje cifrado v\\OMEMO Enviar mensaje cifrado con OpenPGP + El apodo ha sido modificado Enviar sin cifrar Falló el descifrado. Tal vez no tengas la clave privada apropiada. OpenKeychain + Conversations utiliza OpenKeychain para cifrar y descifrar mensajes y gestionar tus claves públicas.\n\nEstá publicado bajo licencia GPLv3+ y disponible en F-Droid y Google Play.\n\n(Por favor, reinicie Conversations después). Reiniciar Instalar Por favor, instala OpenKeyChain ofreciendo… esperando… Clave OpenPGP no encontrada + No se ha podido cifrar tu mensaje porque tu contacto no está anunciando su clave pública.\n\nPor favor, pide a tu contacto que configure OpenPGP. Claves OpenPGP no encontradas + No se ha podido cifrar tu mensaje porque tus contactos no están anunciando sus claves públicas.\n\nPor favor, pide a tus contactos que configuren OpenPGP. General Aceptar archivos De forma automática aceptar archivos menores que… @@ -110,9 +124,11 @@ El periodo de tiempo en el que las notificaciones están silenciadas tras detectar actividad en otro de tus dispositivos. Avanzado Nunca informar de errores + Al enviar las trazas de error estás ayudando en el desarrollo Confirmar mensajes Permitir a tus contactos saber cuando has recibido y leído sus mensajes Pantalla + OpenKeychain causó un error. Clave errónea para el cifrado. Aceptar Ha ocurrido un error @@ -125,8 +141,10 @@ Hacer foto De forma automática conceder suscripción de presencia El archivo seleccionado no es una imagen + No se pudo comprimir el archivo de imagen Archivo no encontrado Error general. ¿Es posible que no tengas espacio en disco? + La aplicación usaste para seleccionar esta imagen no proporcionó suficientes permisos para leer el archivo.\n\nUtiliza un explorador de archivos diferente para seleccionar la imagen Desconocido Deshabilitado temporalmente Conectado @@ -138,6 +156,7 @@ Error en el registro El identificador ya está en uso Registro completado + El servidor no soporta registros Token de registro inválido Error de negociación TLS Policy violation @@ -154,14 +173,17 @@ Publicar clave pública OpenPGP Eliminar la clave pública OpenPGP ¿Estás seguro de que quieres eliminar tu clave pública OpenPGP de tu anuncio de presencia?\nTus contactos no podrán enviarte mensajes cifrados con OpenPGP. + La clave pública OpenPGP ha sido publicada. Habilitar ¿Estás seguro? + Si eliminas tu cuenta tu historial de conversaciones completo se perderá Grabar audio Dirección XMPP Bloquear dirección XMPP usuario@ejemplo.com Contraseña Esta no es una dirección XMPP válida + Sin memoria. La imagen es demasiado grande ¿Quieres añadir a %s a tus contactos? Información de servidor XEP-0313: MAM @@ -178,9 +200,14 @@ No Se han perdido las claves de anuncio públicas Visto última vez ahora + visto última vez hace un minuto Visto última vez hace %d minutos + visto última vez hace una hora Visto última vez hace %d horas + visto última vez hace un día Visto última vez hace %d días + Mensaje cifrado. Por favor instala OpenKeychain para descifrarlo. + Encontrado un nuevo mensaje cifrado con OpenPGP OpenPGP Key ID Huella digital OMEMO Huella digital v\\OMEMO @@ -220,18 +247,23 @@ Añadir contacto %s ha leído hasta aquí %s han leído hasta aquí + %1$s + %2$d han leído hasta aquí Todos han leído hasta aquí Publicar + Pulsa la imagen de perfil para seleccionar una imagen de la galería Publicando… El servidor rechazó la publicación + No se ha podido convertir su imagen No se ha podido guardar la imagen de perfil en disco (O pulsación prolongada para volver a tu imagen de la agenda) + Tu servidor no soporta la publicación de imágenes de perfil en privado en privado para %s Enviar mensaje privado a %s Conectar Esta cuenta ya existe Siguiente + Sesión establecida Omitir Deshabilitar notificaciones Habilitar @@ -280,6 +312,7 @@ Detalles de la cuenta Confirmar Intentar de nuevo + Servicio en primer plano Mantener el servicio en primer plano previene que el sistema cierre la conexión Crear una copia de respaldo Los ficheros de respaldo serán almacenados en %s diff --git a/src/main/res/values-fr/strings.xml b/src/main/res/values-fr/strings.xml index afe80ebad..7c1d473f4 100644 --- a/src/main/res/values-fr/strings.xml +++ b/src/main/res/values-fr/strings.xml @@ -6,7 +6,7 @@ Gérer le compte Fermer cette conversation Détails du contact - Détails du salon de discussion + Détails du groupe Détails du canal Conversation sécurisée Ajouter un compte @@ -32,7 +32,7 @@ Il y a %d minutes %d conversations non lues Envoi… - Déchiffrement du message. Veuillez patienter... + Déchiffrement du message. Veuillez patienter… Message chiffré avec OpenPGP Cet identifiant est déjà utilisé Identifiant non valide @@ -79,7 +79,7 @@ Échec de l\'envoi Préparation pour l’envoi de l\'image Préparation pour l\'envoi des images - Partage des fichiers. Veuillez patienter... + Partage des fichiers. Veuillez patienter… Vider l\'historique Vider l\'historique de la conversation Êtes-vous sûr de vouloir supprimer tous les messages de cette conversation ?\n\n Avertissement : Cela ne supprimera pas les copies des messages qui sont stockés sur d\'autres appareils ou serveurs. @@ -95,7 +95,7 @@ Envoyer un message chiffré avec OpenPGP Votre identifiant a été changé Envoyer en clair - Echec du déchiffrement. Avez-vous la bonne clef privée ? + Échec du déchiffrement. Avez-vous la bonne cré privée ? OpenKeychain Conversations utilise OpenKeychain pour chiffrer et déchiffrer les messages et pour gérer vos clés publiques.\n\nOpenKeychain est sous licence GPLv3 et est disponible sur F-Droid et Google Play.\n\n(Veuillez redémarrer Conversations après l\'installation de l\'application.) Redémarrer @@ -103,10 +103,10 @@ Veuillez installer OpenKeychain Proposition… Patientez… - Aucune clef OpenPGP trouvée. - Impossible de chiffrer vos messages car votre contact n\'a pas communiqué sa clef publique.\n\nDemandez-lui de configurer OpenPGP. - Aucune clef OpenPGP n\'a été trouvée. - Impossible de chiffrer votre message car vos contacts ne communiquent pas leur clef publique.\n\nDemandez-leur de configurer OpenPGP. + Aucune clé OpenPGP trouvée. + Impossible de chiffrer vos messages car votre contact n\'a pas communiqué sa clé publique.\n\nDemandez-lui de configurer OpenPGP. + Aucune clé OpenPGP n\'a été trouvée. + Impossible de chiffrer votre message car vos contacts ne communiquent pas leur clé publique.\n\nDemandez-leur de configurer OpenPGP. Général Accepter les fichiers Accepter automatiquement les fichiers plus petits que… @@ -129,7 +129,7 @@ Informer vos contacts quand vous avez reçu et lu leurs messages Interface OpenKeychain a signalé une erreur. - Mauvaise clef pour le chiffrement. + Mauvaise clé pour le chiffrement. Accepter Une erreur s\'est produite Erreur @@ -170,9 +170,9 @@ Supprimer Désactiver temporairement Publier un avatar - Publier la clef publique OpenPGP - Supprimer la clef publique OpenPGP - Êtes vous sûr de vouloir supprimer votre clef publique OpenPGP de votre annonce de présence ?\nVos contacts ne pourront plus vous envoyer de message chiffrés avec OpenPGP. + Publier la clé publique OpenPGP + Supprimer la clé publique OpenPGP + Êtes vous sûr de vouloir supprimer votre clé publique OpenPGP de votre annonce de présence ?\nVos contacts ne pourront plus vous envoyer de message chiffrés avec OpenPGP. Clé publique OpenPGP publiée Activer Êtes-vous sûr ? @@ -192,13 +192,13 @@ XEP-0191 : Commande de bloquage XEP-0237 : Révision contacts XEP-0198 : Gestion des flux - XEP-0215: Découverte de service externe + XEP-0215 : Découverte de service externe XEP-0163 : PEP (Avatars / OMEMO) XEP-0363 : Envoi de fichiers via HTTP XEP-0357 : Notifications Push - supporté - non supporté - Annonce de clef publique manquante + supportée + non supportée + Annonce de clé publique manquante en ligne à l\'instant en ligne il y a 1 minute en ligne il y a %d minutes @@ -208,14 +208,14 @@ en ligne il y a %d jours Message chiffré. Veuillez installer OpenKeychain pour le déchiffrer. Nouveaux messages chiffrés avec OpenPGP détectés. - ID Clef OpenPGP + ID de clé OpenPGP Empreinte OMEMO v\\Empreinte OMEMO Empreinte OMEMO du message v\\Empreinte OMEMO du message Autres appareils Faire confiance aux empreintes OMEMO - Récupération des clefs... + Récupération des clés… Terminé Déchiffrer Favoris @@ -229,19 +229,19 @@ Sélectionner Le contact existe déjà Rejoindre - channel@conference.example.com/nick - channel@conference.example.com + canal@conference.example.com/surnom + canal@conference.example.com Enregistrer comme favori Supprimer le favori - Détruire le salon + Détruire le groupe Détruire le canal - Voulez-vous vraiment détruire ce salon ?\n\nAvertissement: le salon sera complètement supprimée du serveur. + Voulez-vous vraiment détruire ce groupe ?\n\nAvertissement: le groupe sera complètement supprimée du serveur. Êtes-vous sûr de vouloir détruire ce canal public? \ On \ Avertissement: le canal sera complètement supprimé du serveur. - Impossible de détruire le salon + Impossible de détruire le groupe Impossible de détruire le canal - Modifier le sujet du salon + Modifier le sujet du groupe Sujet - Rejoindre la salon + Rejoindre le groupe Partir Votre correspondant vous a ajouté dans sa liste de contacts Ajouter en retour @@ -267,7 +267,7 @@ Passer Désactiver les notifications Activer - Le salon requière un mot de passe + Le groupe requière un mot de passe Entrer le mot de passe Veuillez demander à votre contact de partager ses mises à jour de disponibilité.\n\nElles seront utilisées pour déterminer l\'application qu\'il utilise. Demander maintenant @@ -286,14 +286,14 @@ Les notifications seront muettes pendant les heures tranquilles. Autres Synchroniser avec les signets - Rejoindre automatiquement les salons marqués en favoris + Rejoindre automatiquement les groupes marqués en favoris Empreinte OMEMO copiée dans le presse-papier - Vous êtes bannis de ce salon - Ce salon est réservé aux membres + Vous êtes bannis de ce groupe + Ce groupe est réservé aux membres Contrainte de ressource - Vous avez été éjecté de ce salon - Le salon a été fermé - Vous n\'appartenez plus à ce salon + Vous avez été éjecté de ce groupe + Le groupe a été fermé + Vous n\'appartenez plus à ce groupe avec le compte %s hébergé sur %s Vérification de %s sur l\'hôte HTTP @@ -326,7 +326,7 @@ Restauration de la sauvegarde Votre sauvegarde a été restaurée N\'oubliez pas d\'activer le compte. - Choix du fichier + Choisir un fichier Réception %1$s (%2$d%% complété) Télécharger %s Effacer %s @@ -345,12 +345,15 @@ Tags dynamiques Afficher des tags en lecture seule en dessous des contacts. Activer les notifications - Serveur de salon non trouvé - Impossible de créer le salon + Serveur de groupe non trouvé + Impossible de créer le groupe Avatar du compte Copier l\'empreinte OMEMO dans le presse-papier Régénérer l\'empreinte OMEMO Supprimer les appareils + Êtes-vous sûr de vouloir supprimer les autres appareils de l\'annonce OMEMO ? Ils s\'annonceront de nouveau à leur prochaine connexion, mais ils peuvent ne pas recevoir les messages envoyés entre temps. + Aucune clé utilisable n\'est disponible pour ce contact. \nImpossible d\'obtenir de nouvelles clés depuis le serveur. Pourrait-il y avoir un problème avec le serveur de votre contact ? + Il n\'y a aucune clé utilisable disponible pour ce contact.\nAssurez-vous d\'avoir un abonnement de présence mutuelle. Une erreur est survenue Récupération de l\'historique sur le serveur Plus d\'historique sur le serveur @@ -375,21 +378,22 @@ Révoquer des privilèges d\'administrateur Accorder des privilèges de propriétaire Révoquer les privilèges du propriétaire - Supprimer du salon + Supprimer du groupe Supprimer du canal Impossible de changer l\'affiliation de %s - Bannir du salon - Banni du channel + Bannir du groupe + Bannir du canal + Vous essayez de supprimer %s d\'un canal public. La seule façon de le faire est de bannir cet utilisateur pour toujours. Bannir maintenant Impossible de changer le rôle de %s - Configuration du salon + Configuration du groupe Configuration du canal public Privé, membres uniquement Rendre les adresses XMPP visibles à tout le monde Rendre le canal modéré Vous ne participez pas - Options du salon modifiées! - Impossible de modifier les options du salon + Options du groupe modifiées! + Impossible de modifier les options du groupe Jamais Jusqu\'à nouvel ordre Répéter les notifications @@ -412,7 +416,7 @@ Cacher contacts hors-ligne %s est en train d\'écrire %s a arrêté d\'écrire - %s sont en train d\'écrire... + %s sont en train d\'écrire… %s ont cessé d\'écrire Notifications d\'écriture Informer vos contacts quand vous leur écrivez des messages @@ -421,8 +425,8 @@ Aucune application trouvée pour afficher le lieu Position Conversation fermée - Quitter le salon privé - Quitte le channel public + Quitter le groupe privé + Quitte le canal public Ne pas utiliser les CAs système Tous les certificats doivent être approuvés manuellement. Retirer les certificats @@ -443,7 +447,7 @@ Rechercher dans les contacts Rechercher des favoris Envoyer un message privé - %1$s a quitté le salon + %1$s a quitté le groupe Identifiant Identifiant Cet identifiant n\'est pas valide @@ -453,6 +457,7 @@ Échec du téléchargement : Écriture impossible Réseau Tor inaccessible La liaison a échoué + Le serveur n\'est pas responsable pour ce domaine Détraqué Disponibilité Absent quand l\'écran est éteint @@ -469,20 +474,22 @@ Laisser vide pour s\'identifier avec un certificat Paramètres d\'archivage Paramètres d\'archivage du serveur - Récupération des paramètres d\'archivage en cours... + Récupération des paramètres d\'archivage en cours… Impossible d\'obtenir les préférences d\'archivage CAPTCHA exigé Entrez le texte de l\'image ci-dessus + Chaîne de certificats indigne de confiance L\'adresse XMPP ne correspond pas au certificat Renouveler le certificat - Erreur lors de la récupération de la clef OMEMO ! - Clef OMEMO vérifiée avec un certificat ! + Erreur lors de la récupération de la clé OMEMO ! + Clé OMEMO vérifiée avec un certificat ! Votre appareil ne supporte pas la sélection de certificats client ! Connexion Connexion via Tor Rediriger toutes les connexions via le réseau Tor. Nécessite Orbot. Nom d\'hôte Port + Adresse du serveur (ou .onion) Ce numéro de port n\'est pas valide Ce nom d\'hôte n\'est pas valide %1$d compte(s) sur %2$d connecté(s) @@ -491,27 +498,40 @@ %d messages Charger plus de messages + Fichier partagé avec %s + Image partagée avec %s + Images partagées avec %s + Texte partagé avec %s + Autoriser Conversations à accéder au stockage externe + Autoriser Conversations à accéder à la caméra Synchroniser avec contacts + Conversations souhaite associer vos contacts XMPP avec les contacts de votre appareil, pour utiliser leur nom complet et leur avatar.\n\nConversations va uniquement lire vos contacts et les associer localement, sans les envoyer à votre serveur XMPP.
Nous ne stockerons pas de copie de ces numéros.\n\nPour plus d\'informations, lisez notre politique de confidentialité.

maintenant être invité à donner la permission d\'accéder à vos contacts.]]>
Notifier pour tous les messages Notifier seulement en cas de mention Notifications désactivées Notifications en pause - Compression de l\'image - Remarque : Utiliser « Choisir un fichier » au lieu de « Choisir une image » pour envoyer des images individuelles non compressées sans tenir compte de ce paramètre. + Compression des images + Remarque : Utiliser « Choisir un fichier » au lieu de « Choisir une image » pour envoyer des images non compressées. Toujours Grandes images seulement Optimisations de batterie activées + Votre appareil applique d\'importantes optimisations de batterie pour Conversations pouvant entraîner des retards de notifications, voire des pertes de messages.\nIl est recommandé de les désactiver. + Votre appareil applique d\'importantes optimisations de batterie pour Conversations pouvant entraîner des retards de notifications, voire des pertes de messages.\nVous allez être invité à les désactiver. Désactiver La zone sélectionnée est trop grande (Aucun compte activé) Ce champ est requis Corriger le message Envoyer le message corrigé + Vous avez déjà validé l\'empreinte de cette personne pour accorder votre confiance. En sélectionnant \"Terminé\", vous confirmez simplement que %s fait partie de ce groupe. Vous avez désactivé ce compte - Partager l\'URI avec... + Erreur de sécurité : accès fichier invalide + Aucune application disponible pour partager l\'URI + Partager l\'URI avec…
Vous vous inscrivez avec votre numéro de téléphone et Quicksy va automatiquement, en fonction des numéros de votre carnet d’adresses, vous suggérer d’éventuels contacts.

en vous inscrivant, vous acceptez notre politique de confidentialité.]]>
Accepter et continuer + Nous vous guiderons tout au long du processus de création d\'un compte sur conversations.im.¹\nLorsque vous sélectionnerez conversations.im en tant que fournisseur, vous pourrez communiquer avec les utilisateurs d\'autres fournisseurs en leur fournissant votre adresse XMPP complète. Votre adresse XMPP complète sera : %s Créer un compte Utiliser votre propre fournisseur @@ -529,18 +549,23 @@ Échec de l\'inscription : Réessayer plus tard Échec de l\'inscription : le mot de passe n\'est pas assez fort Choisir les participants - Création d\'un salon... + Création d\'un groupe… Inviter à nouveau Désactiver Courte Moyenne Longue + Partage de l\'utilisation + Informer vos contacts lorsque vous utilisez Conversations Confidentialité Thème Choisir la palette de couleurs Automatique + Clair + Sombre Fond Vert Utiliser un fond vert pour les messages reçus + Impossible de se connecter à OpenKeyChain Cet appareil n\'est plus utilisé Ordinateur Smartphone @@ -548,39 +573,51 @@ Navigateur Internet Console Paiement requis + Autoriser à accéder à internet Moi Le contact demande la notification de présence Autoriser Permission d\'accéder à %s refusée Serveur distant non trouvé Dépassement du délai du serveur distant + Impossible de mettre à jour le compte + Signaler cette adresse XMPP comme émettrice de messages indésirables. Effacer les identités OMEMO - Supprimer les clefs sélectionnées + Régénérer vos clés OMEMO. Tous vos contacts devront vous vérifier à nouveau. À n\'utiliser qu\'en dernier recours. + Supprimer les clés sélectionnées Vous devez être connecté pour publier votre avatar. Afficher le message d\'erreur Message d\'erreur Économiseur de données activé + Votre système d\'exploitation empêche Conversations d’accéder à Internet lorsque l\'application est en arrière plan. Pour recevoir les notifications de nouveaux messages, vous devez autoriser Conversations à accéder au réseau sans restriction quand l\'économiseur de données est activé.\n Conversations tentera de consommer le moins de données possible. Votre appareil ne prend pas en charge la désactivation de l\'Économiseur de données pour Conversations. + Impossible de créer un fichier temporaire Cet appareil a été vérifié Copier l\'empreinte + Vous avez vérifié toutes les clés OMEMO en votre possession + Le code-barres ne contient pas d\'empreintes pour cette conversation. Empreintes vérifiées Utilisez l\'appareil photo pour scanner le code-barres d\'un contact - Veuillez attendre que les clefs soient récupérées + Veuillez attendre que les clés soient récupérées Partager par code-barres Partager par URI XMPP Partager par lien HTTP Faire aveuglément confiance avant vérification + Faire automatiquement confiance aux nouveaux appareils des contacts qui n\'ont pas été vérifiés auparavant mais demander une confirmation manuelle à chaque fois qu\'un contact vérifié auparavant utilise un nouvel appareil. + Les clés OMEMO ont fait l\'objet d\'une confiance aveugle, cela signifie qu\'il pourrait s\'agir de quelqu\'un d\'autre ou que quelqu\'un aurait pu intercepter l\'échange. Non approuvée Code-barres 2D invalide + Vide le dossier de cache (utilisé par l\'appplication caméra) Vider le cache Vider le stockage privé Vide le stockage privé, où les fichiers sont conservés (ils peuvent être re-téléchargés depuis le serveur) J\'ai obtenu ce lien d\'une source de confiance - Vous êtes sur le point de vérifier les clefs OMEMO de %1$s en cliquant sur un lien. Cette procédure n\'est sécurisée que si le lien en question n\'a pu être publié que par %2$s et que vous l\'avez obtenu d\'une source digne de confiance. - Vérifier les clefs OMEMO + Vous êtes sur le point de vérifier les clés OMEMO de %1$s en cliquant sur un lien. Cette procédure n\'est sécurisée que si le lien en question n\'a pu être publié que par %2$s et que vous l\'avez obtenu d\'une source digne de confiance. + Vérifier les clés OMEMO Afficher les comptes inactifs Cacher les comptes inactifs Ne plus faire confiance à cet appareil + Êtes-vous sûr de vouloir retirer la vérification pour cet appareil ?\nCet appareil et les messages qui en proviennent seront marqués comme \"indignes de confiance\". %d seconde %d secondes @@ -623,7 +660,9 @@ Mécanisme SASL dégradé Le serveur nécessite une identification sur son site web Ouvrir le site web + Aucune application disponible pour ouvrir le site web Notifications \"pop-up\" + Afficher les notifications \"pop-up\" Aujourd\'hui Hier Valider le nom de domaine avec DNSSEC @@ -651,12 +690,14 @@ Modifier le message de statut Désactiver le chiffrement Conversations n\'est pas capable d\'envoyer un message chiffré à %1$s. Ceci peut être lié au fait que votre contact utilise un serveur obsolète ou un client qui ne gère par OMEMO. + Impossible de récupérer la liste des appareils + Impossible de récupérer les clés de chiffrement Indication : Dans certains cas, cela peut être résolu en vous ajoutant respectivement dans votre liste de contacts. Êtes-vous sûr de vouloir désactiver le chiffrement OMEMO pour cette discussion ?\nCeci permettra à l\'administrateur de votre serveur de lire vos messages, mais cela peut être le seul moyen de communiquer avec des personnes utilisant un vieux client. Désactiver maintenant Brouillon : Chiffrement OMEMO - OMEMO sera toujours utilisé pour des discussions à deux ou les salons privés. + OMEMO sera toujours utilisé pour des discussions à deux ou les groupes privés. OMEMO sera utilisé par défaut pour les nouvelles discussions. OMEMO devra être activé manuellement pour chaque nouvelle discussion Créer un raccourci @@ -679,7 +720,9 @@ Partager la position Afficher la position Partager - Veuillez patienter... + Impossible de démarrer l\'enregistrement + Veuillez patienter… + Autoriser Conversations à accéder au microphone Rechercher dans les messages GIF Voir la conversation @@ -690,15 +733,16 @@ Partage de fichier HTTP pour S3 Recherche directe Sur l\'écran de démarrage de Conversation, afficher le clavier et placer le curseur sur le champ recherche - Avatar du salon - Le serveur ne prend pas en charge les avatars pour les salons - Seul le propriétaire peut changer l\'avatar d\'un salon + Avatar du groupe + Le serveur ne prend pas en charge les avatars pour les groupes + Seul le propriétaire peut changer l\'avatar d\'un groupe Nom du contact Surnom Nom Fournir un nom est facultatif - Nom du salon - Ce salon a été supprimé + Nom du groupe + Ce groupe a été supprimé + Impossible de sauvegarder l\'enregistrement Service au premier plan Cette catégorie de notification est utilisée pour afficher une notification permanente indiquant que Conversations est en cours. Information sur l\'état @@ -719,7 +763,7 @@ Participants Navigateur de média Fichier omis en raison d\'une violation de la sécurité. - Qualité de la vidéo + Qualité des vidéos Une qualité inférieure signifie des fichiers plus petits Moyenne (360p) Haute (720p) @@ -748,12 +792,15 @@ Êtes-vous sûr de vouloir quitter la procédure d\'inscription ? Oui Non - Vérification.... + Vérification… Demander un SMS… Le code PIN que vous avez entré est incorrect. Le code PIN que nous vous avons envoyé a expiré. Erreur réseau inconnue. Réponse inconnue du serveur. + Impossible de se connecter au serveur. + Impossible d\'établir une connexion sécurisée. + Impossible de trouver le serveur. Une erreur est survenue pendant le traitement de votre requête. Entrée utilisateur incorrecte Temporairement indisponible. Réessayez plus tard. @@ -775,27 +822,30 @@ Ce canal rendra votre adresse XMPP publique e-book Original (non compressé) - Ouvrir avec... + Ouvrir avec… Photo de profil pour Conversations Choisir un compte Restaurer la sauvegarde Restaurer Entrez votre mot de passe pour que le compte %s restaure la sauvegarde. N\'utilisez pas la fonctionnalité de sauvegarde de la restauration pour tenter de cloner (exécuter simultanément) une installation. La restauration d’une sauvegarde ne concerne que les migrations ou en cas de perte du périphérique d’origine. + Impossible de restaurer la sauvegarde. + Impossible de déchiffrer la sauvegarde. Le mot de passe est-il correct ? Sauvegarde & restauration Entrez l\'adresse XMPP - Créer un salon + Créer un groupe Rejoindre le canal public - Créer un salon privé + Créer un groupe privé Créer un canal public Nom du canal Adresse XMPP - Veuillez donner un nom au channel + Veuillez donner un nom au canal Veuillez renseigner une adresse XMPP Ceci est une adresse XMPP. Veuillez renseigner un nom. Création d\'un canal public… Ce canal existe déjà Vous avez rejoint un canal existant + Impossible de sauvegarder la configuration du canal Autoriser quiconque à éditer le sujet Permettre à quiconque d\'inviter d\'autres personnes N\'importe qui peut éditer le sujet. @@ -806,7 +856,7 @@ Les adresses XMPP sont visibles par les administrateurs. Les adresses XMPP sont visibles par tous. Ce canal public n\'a pas de participants. Invitez vos contacts ou utilisez le bouton de partage pour distribuer son adresse XMPP. - Ce salon privé n\'a aucun participant. + Ce groupe privé n\'a aucun participant. Gérer les privilèges Rechercher des participants Fichier trop volumineux @@ -828,8 +878,10 @@ Le fichier sélectionné n\'est pas une sauvegarde de Conversations Ce compte a déjà été configuré Veuillez saisir le mot de passe pour ce compte - Rejoindre le canal public ... - + Impossible de réaliser cette action + Rejoindre le canal public… + L\'application de partage n\'a pas accordé la permission d\'accéder à ce fichier. + jabber.network Serveur local La plupart des utilisateurs devraient choisir « jabber.network » pour de meilleures suggestions provenant de l’écosystème public entier de XMPP. @@ -842,11 +894,20 @@ Appel vidéo entrant Connexion en cours Connecté + Accepter les appels + Fin d\'appel Décrocher Ignorer + Recherche de l\'appareil + Ça sonne Occupé + Impossible de connecter l\'appel + Appel annulé + Échec de l\'application + Raccrocher Appel en cours Appel vidéo en cours + Désactivez Tor afin de passer des appels Appel entrant Appel entrant · %s Appel sortant @@ -855,6 +916,9 @@ Appel audio Appel vidéo Votre micro n\'est pas disponible + Vous ne pouvez prendre qu\'un appel à la fois. + Reprendre l\'appel en cours + Impossible de changer de caméra Voir %1$d participant Voir %1$d participants diff --git a/src/main/res/values-ro-rRO/strings.xml b/src/main/res/values-ro-rRO/strings.xml index 5d4e9c4f5..3d9f935ad 100644 --- a/src/main/res/values-ro-rRO/strings.xml +++ b/src/main/res/values-ro-rRO/strings.xml @@ -23,7 +23,7 @@ Setări Partajează într-o conversație Pornește o conversație - Alegeți contact + Alegeți contactul Alegeți contactele Partajează cu cont Listă contacte blocate @@ -82,7 +82,7 @@ Trimitere fișiere. Te rog asteaptă... Șterge istoric Șterge istoricul conversației - Doriți să ștergeți toate mesajele din această conversație?\n\nAtenție: Asta nu va afecta mesajele aflate pe alte dispozitive sau servere. + Doriți să ștergeți toate mesajele din această conversație?\n\nAtenție: Această acțiune nu va afecta mesajele aflate pe alte dispozitive sau servere. Șterge fișierul Sigur doriți să ștergeți acest fișier?\n\nAtenție: Această acțiune nu va șterge copiile acestui fișier care sunt stocate pe alte dispozitive sau servere. Închide conversația după ștergere @@ -121,7 +121,7 @@ Sunet de notificare pentru mesaje noi Ton pentru apelul primit Perioadă de grație - Durata de timp cât notificările sunt ascunse după ce s-a observat activitate pe un alt dispozitiv al dumneavoastră. + Durata de timp cât notificările sunt ascunse după ce s-a observat activitate pe un alt dispozitiv de al dumneavoastră. Opțiuni avansate Nu trimite rapoarte de erori Trimițând date despre erori ajutați la continuarea dezvoltării aplicației @@ -262,7 +262,7 @@ Trimite mesaj privat catre %s Conectare Acest cont există deja - Următoarea + Următorul Sesiune stabilită Omite Dezactivează notificările @@ -318,7 +318,7 @@ Încearcă din nou Serviciul activ în prim-plan Previne închiderea conexiunii de către sistemul de operare - Creează copie de siguranță + Creează o copie de siguranță Fișierele copiei de siguranță vor fi salvate în %s Se creează copia de siguranță Copia de siguranță a fost creată @@ -343,7 +343,7 @@ Nu s-a găsit nici o aplicație care să deschidă adresa Nu s-a găsit nici o aplicație care să deschidă contactul Etichete dinamice - Sub contacte arată etichete dinamice + Arată sub contacte etichete dinamice informative Activează notificările Nu s-a găsit serverul pentru discuția de grup Nu s-a putut crea discuția de grup @@ -361,7 +361,7 @@ Parolă schimbată Nu s-a putut schimba parola Schimbare parolă - Parolă curentă + Parola curentă Parolă nouă Parola nu poate să fie goală Activează toate conturile @@ -419,7 +419,7 @@ %s tastează... %s s-au oprit din scris Notificare tastare - Contactul este anunțat atunci când scrieți un nou mesaj + Contactele sunt anunțate atunci când le scrieți un nou mesaj Trimite locația Arată locația Nu s-a găsit nici o aplicație care să afișeze locația @@ -514,7 +514,7 @@ Notificări dezactivate Notificări suspendate Compresie imagini - Notă: Folosiți \'Alegeți un fișier\' în loc de \'Alegeți o imagine\' pentru a trimite imaginile necomprimate ignorând această setare. + Notă: Folosiți \'Alege un fișier\' în loc de \'Alege o imagine\' pentru a trimite imaginile necomprimate ignorând această setare. Mereu Doar imaginile mari Optimizare baterie activată @@ -533,7 +533,7 @@ Partajează adresa cu...
Vă înscrieți cu numărul de telefon și Quicksy—pe baza numerelor de telefon din agenda dumneavoastră—vă va sugera automat posibile contacte.

Înscriindu-vă sunteți de acord cu politica noastră de confidențialitate.]]>
Sunt de acord și continuă - Vă vom ghida prin procesul de creare al unui cont pe conversations.im.¹\nCând alegeți conversations.im ca furnizor veți putea comunica cu utilizatorii altor furnizori oferindu-le adresa dumneavoastră completă XMPP. + Ghidul va configura un cont pe conversations.im.¹\nCând alegeți conversations.im ca furnizor veți putea comunica cu utilizatorii altor furnizori oferindu-le adresa dumneavoastră completă XMPP. Adresa dumneavoastră XMPP completă va fi: %s Creează cont Folosește furnizorul meu @@ -558,10 +558,10 @@ Medie Lungă Publică utilizarea - Contactele vă sunt informate atunci când folosiți Conversations + Contactele sunt anunțate atunci când folosiți Conversations Intimitate Temă - Selecție paletă culori interfață + Selecție paletă de culori interfață Automată Luminoasă Întunecată @@ -651,16 +651,16 @@ %d de luni
Ștergerea automată a mesajelor - De pe acest dispozitiv se vor șterge dacă sunt mai vechi de perioada selectată. + De pe acest dispozitiv se vor șterge dacă sunt mai vechi decât perioada selectată. Mesajul se criptează Politica de retenție locală împiedică descărcarea altor mesaje. Se comprimă clipul video Conversațiile corespunzătoare au fost închise. Contact blocat. Notificări de la persoane necunoscute - Primire notificări pentru mesaje și apeluri de la persoane care nu sunt în lista de contacte. + Permite notificări pentru mesaje și apeluri de la persoane care nu sunt în lista de contacte. Mesaj primit de la o persoană necunoscută - Blocare contact necunoscut + Blocare persoană necunoscută Blocare tot domeniu conectat acum Reîncearcă decriptarea @@ -673,7 +673,7 @@ Arată notificările în prim-plan Azi Ieri - Validează numele domeniului cu ajutorul DNSSEC + Validează domeniul prin DNSSEC Certificatele serverelor care conțin nume de domenii validate sunt considerate verificate Certificatul nu conține o adresă XMPP parțial @@ -772,7 +772,7 @@ Vizualizare fișiere media Fișier omis ca urmare a unei probleme de securitate. Calitate video - O calitate mică înseamnă fișiere mai mici + O calitate mai mică înseamnă fișiere mai mici Medie (360p) Mare (720p) anulat @@ -833,7 +833,7 @@ Deschide cu… Poză profil Conversations Alegeți contul - Restaurează copie de siguranță + Restaurează o copie de siguranță Restaurează Introduceți parola contului %s pentru a restaura copia de siguranță. Nu folosiți funcția de restaurare a copiei de siguranță pentru a încerca clonarea (rularea simultană a) instalării. Restaurarea copiei de siguranță este gândită doar pentru a migra pe un alt dispozitiv sau în cazul în care ați pierdut dispozitivul original. @@ -906,7 +906,7 @@ Se încheie apelul Răspunde Respinge - Localizare dispozitive + Căutare dispozitive Sună Ocupat Nu s-a putut conecta apelul diff --git a/src/quicksy/res/values-es/strings.xml b/src/quicksy/res/values-es/strings.xml index b9fd5ceba..1234523c4 100644 --- a/src/quicksy/res/values-es/strings.xml +++ b/src/quicksy/res/values-es/strings.xml @@ -9,6 +9,8 @@ Si envías registros de error ayudas al desarrollo de Quicksy Quicksy necesita acceder al almacenamiento externo Quicksy necesita acceder a la cámara + Tu dispositivo está realizando optimizaciones de uso de batería en Quicksy que pueden hacer que los mensajes se retrasen o incluso hacer que se pierdan.\nEs recomendable deshabilitarlas. + Tu dispositivo está realizando optimizaciones de uso de batería en Quicksy que pueden hacer que los mensajes se retrasen o incluso hacer que se pierdan.\n\nA continuación se le preguntará si quiere deshabilitarlas. Informar a tus contactos cuando usas Quicksy Tu sistema operativo está restringiendo a Quicksy acceder a internet cuando está en segundo plano. Para recibir notificaciones de nuevos mensajes deberías permitir a Quicksy acceder a internet cuando la optimización de datos está habilitada.\nQuicksy realizará igualmente optimizaciones para ahorrar datos cuando sea posible. Tu dispositivo no soporta la opción de deshabilitar la optimización de datos para Quicksy diff --git a/src/quicksy/res/values-fr/strings.xml b/src/quicksy/res/values-fr/strings.xml index 88ab64da0..d6feadc4d 100644 --- a/src/quicksy/res/values-fr/strings.xml +++ b/src/quicksy/res/values-fr/strings.xml @@ -9,6 +9,8 @@ En envoyant des traces d’appels, vous aidez le développement de Quicksy Quicksy a besoin d’accéder au stockage externe Quicksy a besoin d’accéder à la caméra + Votre appareil applique d\'importantes optimisations de batterie pour Quicksy pouvant entraîner des retards de notifications, voire des pertes de messages.\nIl est recommandé de les désactiver. + Votre appareil applique d\'importantes optimisations de batterie pour Quicksy pouvant entraîner des retards de notifications, voire des pertes de messages.\nVous allez être invité à les désactiver. Faites savoir à tous vos contacts quand vous utilisez Quicksy Votre système d’exploitation restreint l’accès à Internet à Quicksy lorsqu’il est en arrière-plan. Pour recevoir les notifications des nouveaux messages reçus, vous devriez accorder à Quicksy un accès illimité lorsque l’économie de la consommation des données est activée.\nQuicksy essaiera quand même d’économiser la consommation lorsque c’est possible. Votre appareil ne prend pas en charge la désactivation du mode économie de données pour Quicksy. From 1ece8e077e71d2537223d03ee6b322690db030b2 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 8 May 2020 16:26:58 +0200 Subject: [PATCH 02/20] pulled translations from transifex --- .../res/values-zh-rCN/strings.xml | 2 +- src/main/res/values-fr/strings.xml | 128 ++--- src/main/res/values-it/strings.xml | 108 ++++ src/main/res/values-zh-rCN/strings.xml | 516 +++++++++++------- src/quicksy/res/values-it/strings.xml | 2 + src/quicksy/res/values-zh-rCN/strings.xml | 2 + 6 files changed, 489 insertions(+), 269 deletions(-) diff --git a/src/conversations/res/values-zh-rCN/strings.xml b/src/conversations/res/values-zh-rCN/strings.xml index d554df1a0..66f21b7a9 100644 --- a/src/conversations/res/values-zh-rCN/strings.xml +++ b/src/conversations/res/values-zh-rCN/strings.xml @@ -1,7 +1,7 @@ 选择您的XMPP提供者 - 使用 conversations.im + 使用conversations.im 创建新账户 您已经拥有一个XMPP账户了吗?如果您之前使用过其他的XMPP客户端的话,那么您已经拥有这种账户了。如果没有账户的话,您可以现在创建一个。\n提示:有些电子邮件服务也提供XMPP账户。 XMPP是独立于提供程序的即时消息网络。 您可以将此客户端与所选的任何XMPP服务器一起使用。\ n不过,为了您的方便,我们很容易在对话中创建帐户。im¹; 特别适合与“对话”配合使用的提供商。 diff --git a/src/main/res/values-fr/strings.xml b/src/main/res/values-fr/strings.xml index 7c1d473f4..77bb6c5ad 100644 --- a/src/main/res/values-fr/strings.xml +++ b/src/main/res/values-fr/strings.xml @@ -21,7 +21,7 @@ Débloquer le participant Gestion des comptes Paramètres - Partager avec Conversation + Partager avec Conversations Démarrer une conversation Choisir un contact Choisir les contacts @@ -41,14 +41,14 @@ Modérateur Participant Visiteur - Voulez-vous supprimer %s de votre liste de contacts ? Les conversations associées à ce contact ne seront pas supprimées. - Voulez-vous bloquer %s pour l\'empêcher de vous envoyer des messages ? - Voulez-vous débloquer %s et lui permettre de vous envoyer des messages ? - Bloquer tous les contacts de %s ? - Débloquer tous les contacts de %s ? + Voulez-vous supprimer %s de votre liste de contacts ? Les conversations associées à ce contact ne seront pas supprimées. + Voulez-vous bloquer %s pour l\'empêcher de vous envoyer des messages ? + Voulez-vous débloquer %s et lui permettre de vous envoyer des messages ? + Bloquer tous les contacts de %s ? + Débloquer tous les contacts de %s ? Contact bloqué Bloqué - Voulez-vous retirer %s des favoris ? La conversation associée à ce favori ne sera pas supprimée. + Voulez-vous retirer %s des favoris ? La conversation associée à ce favori ne sera pas supprimée. Créer un nouveau compte sur le serveur Changer de mot de passe sur le serveur Partager avec… @@ -74,7 +74,7 @@ Impossible de se connecter aux comptes. Appuyez pour gérer vos comptes. Joindre un fichier - Ajouter ce contact manquant à votre liste de contact ? + Ajouter ce contact manquant à votre liste de contact ? Ajouter un contact Échec de l\'envoi Préparation pour l’envoi de l\'image @@ -82,9 +82,9 @@ Partage des fichiers. Veuillez patienter… Vider l\'historique Vider l\'historique de la conversation - Êtes-vous sûr de vouloir supprimer tous les messages de cette conversation ?\n\n Avertissement : Cela ne supprimera pas les copies des messages qui sont stockés sur d\'autres appareils ou serveurs. + Êtes-vous sûr de vouloir supprimer tous les messages de cette conversation ?\n\n Avertissement : Cela ne supprimera pas les copies des messages qui sont stockés sur d\'autres appareils ou serveurs. Supprimer le fichier - Êtes-vous sûr de vouloir supprimer ce fichier ?\n\n Avertissement : Cela ne supprimera pas les copies de ce fichier qui sont stockés sur d\'autres appareils ou serveurs. + Êtes-vous sûr de vouloir supprimer ce fichier ?\n\n Avertissement : Cela ne supprimera pas les copies de ce fichier qui sont stockés sur d\'autres appareils ou serveurs. Fermez cette conversation après Choisir l\'appareil Envoyer un message en clair @@ -95,7 +95,7 @@ Envoyer un message chiffré avec OpenPGP Votre identifiant a été changé Envoyer en clair - Échec du déchiffrement. Avez-vous la bonne cré privée ? + Échec du déchiffrement. Avez-vous la bonne clé privée ? OpenKeychain Conversations utilise OpenKeychain pour chiffrer et déchiffrer les messages et pour gérer vos clés publiques.\n\nOpenKeychain est sous licence GPLv3 et est disponible sur F-Droid et Google Play.\n\n(Veuillez redémarrer Conversations après l\'installation de l\'application.) Redémarrer @@ -143,12 +143,12 @@ Le fichier choisi n\'est pas une image Impossible de convertir l\'image Impossible de trouver le fichier - Erreur générale d\'E/S. Avez-vous encore de l\'espace libre ? + Erreur générale d\'E/S. Avez-vous encore de l\'espace libre ? L\'application utilisée ne donne pas la permission de lire l\'image.\n\nUtilisez une autre application pour choisir une image. Inconnu Désactivé temporairement En ligne - Connexion\u2026 + Connexion… Hors-ligne Non autorisé Impossible de trouver le serveur @@ -158,7 +158,7 @@ Inscription réussie Inscription non supportée par le serveur Jeton d’inscription invalide - La négociation TLS a echoué + La négociation TLS a échoué Violation de politique Serveur incompatible Erreur de flux @@ -172,10 +172,10 @@ Publier un avatar Publier la clé publique OpenPGP Supprimer la clé publique OpenPGP - Êtes vous sûr de vouloir supprimer votre clé publique OpenPGP de votre annonce de présence ?\nVos contacts ne pourront plus vous envoyer de message chiffrés avec OpenPGP. + Êtes-vous sûr de vouloir supprimer votre clé publique OpenPGP de votre annonce de présence ?\nVos contacts ne pourront plus vous envoyer de message chiffrés avec OpenPGP. Clé publique OpenPGP publiée Activer - Êtes-vous sûr ? + Êtes-vous sûr ? Supprimer votre compte effacera l\'historique de vos conversations Enregistrer un son Adresse XMPP @@ -184,18 +184,18 @@ Mot de passe Ce n\'est pas une adresse XMPP valide Plus de mémoire disponible. L\'image est trop volumineuse. - Voulez-vous ajouter %s à votre carnet d\'adresses ? + Voulez-vous ajouter %s à votre carnet d\'adresses ? Infos sur le serveur - XEP-0313 : MAM - XEP-0280 : Copies carbone - XEP-0352 : Indication statut client - XEP-0191 : Commande de bloquage - XEP-0237 : Révision contacts - XEP-0198 : Gestion des flux - XEP-0215 : Découverte de service externe - XEP-0163 : PEP (Avatars / OMEMO) - XEP-0363 : Envoi de fichiers via HTTP - XEP-0357 : Notifications Push + XEP-0313 : MAM + XEP-0280 : Copies carbone + XEP-0352 : Indication statut client + XEP-0191 : Commande de blocage + XEP-0237 : Révision contacts + XEP-0198 : Gestion des flux + XEP-0215 : Découverte de service externe + XEP-0163 : PEP (Avatars / OMEMO) + XEP-0363 : Envoi de fichiers via HTTP + XEP-0357 : Notifications Push supportée non supportée Annonce de clé publique manquante @@ -235,8 +235,8 @@ Supprimer le favori Détruire le groupe Détruire le canal - Voulez-vous vraiment détruire ce groupe ?\n\nAvertissement: le groupe sera complètement supprimée du serveur. - Êtes-vous sûr de vouloir détruire ce canal public? \ On \ Avertissement: le canal sera complètement supprimé du serveur. + Voulez-vous vraiment détruire ce groupe ?\n\nAvertissement : le groupe sera complètement supprimé du serveur. + Êtes-vous sûr de vouloir détruire ce canal public ? \ On \ Avertissement : le canal sera complètement supprimé du serveur. Impossible de détruire le groupe Impossible de détruire le canal Modifier le sujet du groupe @@ -267,12 +267,12 @@ Passer Désactiver les notifications Activer - Le groupe requière un mot de passe + Le groupe requiert un mot de passe Entrer le mot de passe Veuillez demander à votre contact de partager ses mises à jour de disponibilité.\n\nElles seront utilisées pour déterminer l\'application qu\'il utilise. Demander maintenant Ignorer - Attention : peut poser problème si l\'un des deux correspondants n\'a pas activé les mises à jour de disponibilité.\n\nVérifiez dans \"Détails du contact\" que vous y avez bien souscrit. + Attention : peut poser problème si l\'un des deux correspondants n\'a pas activé les mises à jour de disponibilité.\n\nVérifiez dans « Détails du contact » que vous y avez bien souscrit. Sécurité Autoriser la correction Permet à vos contacts d\'éditer leurs messages rétroactivement @@ -351,14 +351,14 @@ Copier l\'empreinte OMEMO dans le presse-papier Régénérer l\'empreinte OMEMO Supprimer les appareils - Êtes-vous sûr de vouloir supprimer les autres appareils de l\'annonce OMEMO ? Ils s\'annonceront de nouveau à leur prochaine connexion, mais ils peuvent ne pas recevoir les messages envoyés entre temps. - Aucune clé utilisable n\'est disponible pour ce contact. \nImpossible d\'obtenir de nouvelles clés depuis le serveur. Pourrait-il y avoir un problème avec le serveur de votre contact ? + Êtes-vous sûr de vouloir supprimer les autres appareils de l\'annonce OMEMO ? Ils s\'annonceront de nouveau à leur prochaine connexion, mais ils peuvent ne pas recevoir les messages envoyés entre temps. + Aucune clé utilisable n\'est disponible pour ce contact. \nImpossible d\'obtenir de nouvelles clés depuis le serveur. Pourrait-il y avoir un problème avec le serveur de votre contact ? Il n\'y a aucune clé utilisable disponible pour ce contact.\nAssurez-vous d\'avoir un abonnement de présence mutuelle. Une erreur est survenue Récupération de l\'historique sur le serveur Plus d\'historique sur le serveur Mise à jour… - Mot de passe modifié ! + Mot de passe modifié ! Impossible de changer le mot de passe Changer de mot de passe Mot de passe actuel @@ -392,7 +392,7 @@ Rendre les adresses XMPP visibles à tout le monde Rendre le canal modéré Vous ne participez pas - Options du groupe modifiées! + Options du groupe modifiées ! Impossible de modifier les options du groupe Jamais Jusqu\'à nouvel ordre @@ -410,11 +410,11 @@ document PDF Application Android Contact - L\'avatar a été publié ! + L\'avatar a été publié ! %s en cours d\'envoi En train de proposer un(e) %s Cacher contacts hors-ligne - %s est en train d\'écrire + %s est en train d\'écrire… %s a arrêté d\'écrire %s sont en train d\'écrire… %s ont cessé d\'écrire @@ -439,7 +439,7 @@ %d certificat supprimé %d certificats supprimés
- Remplacer le bouton \"Envoyer\" par une action rapide + Remplacer le bouton « Envoyer » par une action rapide Action Rapide Aucune Dernière utilisée @@ -451,10 +451,10 @@ Identifiant Identifiant Cet identifiant n\'est pas valide - Échec du téléchargement : impossible de trouver le serveur - Échec du téléchargement : impossible de trouver le fichier - Échec du téléchargement : impossible de se connecter à l\'hôte - Échec du téléchargement : Écriture impossible + Échec du téléchargement : impossible de trouver le serveur + Échec du téléchargement : impossible de trouver le fichier + Échec du téléchargement : impossible de se connecter à l\'hôte + Échec du téléchargement : Écriture impossible Réseau Tor inaccessible La liaison a échoué Le serveur n\'est pas responsable pour ce domaine @@ -481,9 +481,9 @@ Chaîne de certificats indigne de confiance L\'adresse XMPP ne correspond pas au certificat Renouveler le certificat - Erreur lors de la récupération de la clé OMEMO ! - Clé OMEMO vérifiée avec un certificat ! - Votre appareil ne supporte pas la sélection de certificats client ! + Erreur lors de la récupération de la clé OMEMO ! + Clé OMEMO vérifiée avec un certificat ! + Votre appareil ne supporte pas la sélection de certificats client ! Connexion Connexion via Tor Rediriger toutes les connexions via le réseau Tor. Nécessite Orbot. @@ -524,15 +524,15 @@ Ce champ est requis Corriger le message Envoyer le message corrigé - Vous avez déjà validé l\'empreinte de cette personne pour accorder votre confiance. En sélectionnant \"Terminé\", vous confirmez simplement que %s fait partie de ce groupe. + Vous avez déjà validé l\'empreinte de cette personne pour accorder votre confiance. En sélectionnant « Terminé », vous confirmez simplement que %s fait partie de ce groupe. Vous avez désactivé ce compte - Erreur de sécurité : accès fichier invalide + Erreur de sécurité : accès fichier invalide Aucune application disponible pour partager l\'URI Partager l\'URI avec…
Vous vous inscrivez avec votre numéro de téléphone et Quicksy va automatiquement, en fonction des numéros de votre carnet d’adresses, vous suggérer d’éventuels contacts.

en vous inscrivant, vous acceptez notre politique de confidentialité.]]>
Accepter et continuer Nous vous guiderons tout au long du processus de création d\'un compte sur conversations.im.¹\nLorsque vous sélectionnerez conversations.im en tant que fournisseur, vous pourrez communiquer avec les utilisateurs d\'autres fournisseurs en leur fournissant votre adresse XMPP complète. - Votre adresse XMPP complète sera : %s + Votre adresse XMPP complète sera : %s Créer un compte Utiliser votre propre fournisseur Choisissez votre nom d\'utilisateur @@ -546,8 +546,8 @@ Occupé Un mot de passe fort a été généré Les optimisations de batterie ne peuvent pas être désactivées sur votre appareil - Échec de l\'inscription : Réessayer plus tard - Échec de l\'inscription : le mot de passe n\'est pas assez fort + Échec de l\'inscription : Réessayer plus tard + Échec de l\'inscription : le mot de passe n\'est pas assez fort Choisir les participants Création d\'un groupe… Inviter à nouveau @@ -563,7 +563,7 @@ Automatique Clair Sombre - Fond Vert + Fond vert Utiliser un fond vert pour les messages reçus Impossible de se connecter à OpenKeyChain Cet appareil n\'est plus utilisé @@ -617,7 +617,7 @@ Afficher les comptes inactifs Cacher les comptes inactifs Ne plus faire confiance à cet appareil - Êtes-vous sûr de vouloir retirer la vérification pour cet appareil ?\nCet appareil et les messages qui en proviennent seront marqués comme \"indignes de confiance\". + Êtes-vous sûr de vouloir retirer la vérification pour cet appareil ?\nCet appareil et les messages qui en proviennent seront marqués comme « indignes de confiance ». %d seconde %d secondes @@ -661,8 +661,8 @@ Le serveur nécessite une identification sur son site web Ouvrir le site web Aucune application disponible pour ouvrir le site web - Notifications \"pop-up\" - Afficher les notifications \"pop-up\" + Notifications « pop-up » + Afficher les notifications « pop-up » Aujourd\'hui Hier Valider le nom de domaine avec DNSSEC @@ -676,11 +676,11 @@ Les messages privés sont désactivés Applications protégées Pour recevoir les notifications, même lorsque l\'écran est éteint, vous devez ajouter Conversations à la liste des applications protégées. - Accepter les certificats inconnus ? + Accepter les certificats inconnus ? Le certificat du serveur n\'est pas signé par une Autorité de Certification connue. - Accepter un nom de serveur qui ne correspond pas ? - Le serveur n\'a pu s\'authentifier en tant que \"%s\". Le certificat est valide uniquement pour : - Désirez-vous quand-même vous connecter ? + Accepter un nom de serveur qui ne correspond pas ? + Le serveur n\'a pu s\'authentifier en tant que « %s ». Le certificat est valide uniquement pour : + Désirez-vous quand-même vous connecter ? Détails du certificat : Une fois La lecture d\'un QR Code nécessite l\'accès à l\'appareil photo @@ -693,9 +693,9 @@ Impossible de récupérer la liste des appareils Impossible de récupérer les clés de chiffrement Indication : Dans certains cas, cela peut être résolu en vous ajoutant respectivement dans votre liste de contacts. - Êtes-vous sûr de vouloir désactiver le chiffrement OMEMO pour cette discussion ?\nCeci permettra à l\'administrateur de votre serveur de lire vos messages, mais cela peut être le seul moyen de communiquer avec des personnes utilisant un vieux client. + Êtes-vous sûr de vouloir désactiver le chiffrement OMEMO pour cette discussion ?\nCeci permettra à l\'administrateur de votre serveur de lire vos messages, mais cela peut être le seul moyen de communiquer avec des personnes utilisant un vieux client. Désactiver maintenant - Brouillon : + Brouillon : Chiffrement OMEMO OMEMO sera toujours utilisé pour des discussions à deux ou les groupes privés. OMEMO sera utilisé par défaut pour les nouvelles discussions. @@ -775,7 +775,7 @@ Numéro de téléphone Vérifier votre numéro de téléphone Quicksy va envoyer un message SMS (des frais opérateurs sont possibles) pour vérifier votre numéro de téléphone. Entrez votre code pays et votre No de téléphone. -
%s

. Est-ce correct ou souhaitez-vous modifier le numéro?]]>
+
%s

. Est-ce correct ou souhaitez-vous modifier le numéro ?]]>
%s n\'est pas un numéro de téléphone valide. Veuillez saisir votre numéro de téléphone. Recherche de pays @@ -789,7 +789,7 @@ retour Collage possible des broches possibles du presse-papiers. Veuillez entrer votre code PIN à 6 chiffres. - Êtes-vous sûr de vouloir quitter la procédure d\'inscription ? + Êtes-vous sûr de vouloir quitter la procédure d\'inscription ? Oui Non Vérification… @@ -830,7 +830,7 @@ Entrez votre mot de passe pour que le compte %s restaure la sauvegarde. N\'utilisez pas la fonctionnalité de sauvegarde de la restauration pour tenter de cloner (exécuter simultanément) une installation. La restauration d’une sauvegarde ne concerne que les migrations ou en cas de perte du périphérique d’origine. Impossible de restaurer la sauvegarde. - Impossible de déchiffrer la sauvegarde. Le mot de passe est-il correct ? + Impossible de déchiffrer la sauvegarde. Le mot de passe est-il correct ? Sauvegarde & restauration Entrez l\'adresse XMPP Créer un groupe @@ -863,7 +863,7 @@ Joindre Découverte des canaux Recherche des canaux - Violation possible de la confidentialité ! + Violation possible de la confidentialité ! search.jabber.network.

L\'utilisation de cette fonction transmettra votre adresse IP et les termes de recherche à ce service. Veuillez consulter leur Politique de confidentialité pour plus d\'information.]]>
J\'ai déjà un compte Ajouter un compte existant diff --git a/src/main/res/values-it/strings.xml b/src/main/res/values-it/strings.xml index b8a64c858..9c6ec8666 100644 --- a/src/main/res/values-it/strings.xml +++ b/src/main/res/values-it/strings.xml @@ -41,12 +41,14 @@ Moderatore Partecipante Visitatore + Vuoi rimuovere %s dalla lista dei contatti? Le conversazioni con questo contatto non verranno rimosse. Vorresti impedire a %s di inviarti messaggi? Vorresti permettere a %s di inviarti messaggi? Bloccare tutti i contatti da %s? Sbloccare tutti i contatti da %s? Contatto bloccato Bloccato + Vuoi rimuovere %s dai segnalibri? Le conversazioni con questo segnalibro non verranno rimosse. Registra un nuovo account sul server Cambia la password sul server Condividi con @@ -65,14 +67,22 @@ Salva OK Errore di Conversations + Usare il tuo account XMPP per inviare segnalazioni di errore aiuta lo sviluppo in corso di Conversations. Invia adesso Non chiedere più + Impossibile connettersi all\'account + Impossibile connettersi a più account + Tocca per gestire i tuoi account Allega file + Aggiungere questo contatto alla lista dei contatti? Aggiungi contatto Invio fallito + Preparazione per l\'invio dell\'immagine + Preparazione per l\'invio delle immagini Condivisione file. Attendere prego... Pulisci la cronologia Pulisci la cronologia della conversazione + Vuoi eliminare tutti i messaggi in questa conversazione?\n\nAttenzione: ciò non influenzerà i messaggi salvati su altri dispositivi o server. Elimina file Sei sicuro di voler eliminare questo file?\n\nAttenzione: non verranno eliminate copie di questo file memorizzate in altri dispositivi o server. Chiudi questa conversazione successivamente @@ -83,16 +93,20 @@ Invia messaggio cifrato OMEMO Invia messaggio cifrato v\\OMEMO Messaggio OpenPGP + Nuovo nome utente in uso Invia non cifrato Decifrazione fallita. Forse non disponi della chiave privata corretta. OpenKeychain + Conversations usa OpenKeychain per cifrare e decifrare i messaggi e gestire le tue chiavi pubbliche.\n\nÈ pubblicato secondo i termini della GPLv3+ ed è disponibile su F-Droid e Google Play.\n\n(Riavvia Conversations in seguito.) Riavvia Installa Per favore installa OpenKeychain offrendo… in attesa… Nessuna chiave OpenPGP trovata + Impossibile decifrare il messaggio perchè il contatto non sta annunciando la sua chiave pubblica.\n\nChiedi al contatto di configurare OpenPGP. Nessuna chiave OpenPGP trovata + Impossibile cifrare il messaggio perchè i contatti non stanno annunciando la sua chiave pubblica.\n\nChiedi loro di configurare OpenPGP. Generale Accetta i file Accetta automaticamente i file più piccoli di… @@ -110,9 +124,11 @@ Il periodo di tempo in cui le notifiche vengono silenziate dopo aver rilevato attività su uno dei tuoi altri dispositivi. Avanzate Non inviare mai segnalazioni di errore + Se scegli di inviare una segnalazione dell’errore aiuterai lo sviluppo Conferma messaggi Fai sapere ai tuoi contatti quando hai ricevuto e letto i loro messaggi Interfaccia utente + OpenKeychain ha generato un errore. Chiave di cifratura non valida. Accetta Si è verificato un errore @@ -125,8 +141,10 @@ Scatta una foto Concedi aggiornamenti della presenza preventivamente Il file selezionato non è un’immagine + Impossibile convertire l\'immagine File non trovato Errore di I/O generico. Forse hai esaurito lo spazio? + L’app che hai usato per selezionare questa immagine non ha fornito autorizzazioni sufficienti per leggere il file.\n\nUsa un gestore di file differente per scegliere un’immagine Sconosciuto Disattivato temporaneamente Online @@ -138,6 +156,7 @@ Registrazione fallita Nome utente già in uso Registrazione completata + Registrazione non supportata dal server Token di registrazione non valido Negoziazione TLS fallita Violazione della policy @@ -154,14 +173,17 @@ Pubblica chiave pubblica OpenPGP Rimuovi chiave pubblica OpenPGP Sei sicuro di volere rimuovere la tua chiave pubblica OpenPGP dalla dichiarazione di presenza?\nI tuoi contatti non potranno più inviarti messaggi cifrati con OpenPGP. + Chiave pubblica OpenPGP pubblicata. Attiva utente Sei sicuro? + L\'eliminazione del tuo account cancellerà tutta la cronologia dielle conversazioni Registra la voce Indirizzo XMPP Blocca indirizzo XMPP utente@esempio.com Password Questo non è un indirizzo XMPP valido + Memoria esaurita. Immagine troppo grande Vuoi aggiungere %s alla tua rubrica? Info server XEP-0313: MAM @@ -178,9 +200,14 @@ non disponibile Annuncio chiave pubblica non effettuato visto adesso + visto un minuto fa visto %d minuti fa + visto un\'ora fa visto %d ore fa + visto un giorno fa visto %d giorni fa + Messaggio cifrato. Installa OpenKeychain per decifrarlo. + Nuovi messaggi cifrati con OpenPGP trovati ID chiave OpenPGP Impronta OMEMO v\\OMEMO impronta @@ -220,25 +247,32 @@ Aggiungi anche tu %s ha letto fino a questo punto %s ha letto fino a questo punto + %1$s + altri %2$d hanno letto fino a questo punto Tutti hanno letto fino a questo punto Pubblica + Tocca l\'avatar per scegliere un\'immagine dalla galleria Pubblicazione… Il server ha rifiutato la tua pubblicazione + Impossibile convertire la tua immagine Impossibile salvare l’avatar sulla memoria interna (O premi a lungo per ripristinare le impostazioni di default) + Il tuo server non supporta la pubblicazione di avatar sussurrato a %s Invia messaggio privato a %s Connetti Questo utente esiste già Successivo + Sessione stabilita Salta Disattiva le notifiche Attiva La chat di gruppo richiede una password Inserisci la password + Richiedi gli aggiornamenti della presenza dal tuo contatto.\n\nCiò verrà usato per determinare quale app sta usando il tuo contatto. Rechiedi adesso Ignora + Attenzione: inviarlo senza aggiornamenti della presenza reciproci può causare problemi inaspettati.\n\nVai nei dettagli del contatto per verificare le tue sottoscrizioni alla presenza. Sicurezza Permetti correzione del messaggio Consenti ai tuoi contatti di modificare retroattivamente i loro messaggi @@ -252,6 +286,8 @@ Le notifiche verranno silenziate durante le ore di quiete Altro Sincronizza con i segnalibri + Entra nelle chat di gruppo automaticamente se il segnalibro dice così + Impronta OMEMO copiata negli appunti Sei stato bandito da questa chat di gruppo Questa chat di gruppo è solo per membri Risorse limitate @@ -280,6 +316,7 @@ Dettagli account Conferma Prova di nuovo + Servizio in primo piano Evita che il sistema operativo chiuda la connessione Crea backup I file di backup verranno salvati in %s @@ -296,17 +333,27 @@ file Apri %s invio (%1$d%% completato) + Preparazione per condividere il file %s offerto da scaricare Annulla trasmissione + impossibile condividere il file trasmissione file annullata + File eliminato + Nessuna app trovata per aprire il file + Nessuna app trovata per aprire il link + Nessuna app trovata per vedere il contatto Etichette dinamiche Mostra etichette in sola lettura sotto i contatti Attiva le notifiche Nessun server per chat di gruppo trovato + Impossibile creare la chat di gruppo Avatar utente Copia impronta OMEMO negli appunti Rigenera chiave OMEMO Pulisci dispositivi + Sei sicuro di voler rimuovere tutti gli altri dispositivi dall\'annuncio OMEMO? La prossima volta che si connetteranno si riannunceranno, ma potrebbero non ricevere i messaggi inviati nel frattempo. + Non ci sono chiavi utilizzabili per questo contatto.\nRicezione di nuove chiavi dal server non riuscita. Forse qualcosa non va con il server del tuo contatto? + Non ci sono chiavi utilizzabili per questo contatto.\nAssicurati di avere reciprocamente la sottoscrizione sulla presenza. Qualcosa è andato storto Caricamento della cronologia dal server Fine cronologia sul server @@ -316,6 +363,7 @@ Cambia password Password attuale Nuova password + La password non può essere vuota Attiva tutti gli account Disattiva tutti gli account Esegui azione con @@ -335,6 +383,7 @@ Impossibile cambiare l’affiliazione di %s Bandisci dalla chat di gruppo Bandisci dal canale + Stai tentando di rimuovere %s da un canale pubblico. L\'unico modo per farlo è di bandire quell\'utente per sempre. Bandisci Impossibile cambiare ruolo di %s Configurazione chat di gruppo privata @@ -373,6 +422,7 @@ Fai sapere ai tuoi contatti quando stai scrivendo loro un messaggio Invia la posizione Mostra la posizione + Nessuna app trovata per mostrare la posizione Posizione Conversazione interrotta Chat di gruppo privata abbandonata @@ -389,6 +439,7 @@ Cancellato il %d certificato Cancellati %d certificati
+ Sostituisci il tasto \"Invio\" con un\'azione rapida Azione rapida Nessuno Usati recentemente @@ -396,6 +447,7 @@ Cerca contatti Cerca segnalibri Invia messaggio privato + %1$s ha abbandonato la chat di gruppo Utente Utente Questo non è un nome utente valido @@ -405,6 +457,7 @@ Scaricamento fallito: scrittura del file impossibile Rete Tor non disponibile Bind fallito + Il server non è responsabile per questo dominio Rotto Disponibilità \"Non disponibile\" a schermo spento @@ -417,11 +470,15 @@ Mostra nome host e impostazioni della porta quando configuri un account xmpp.esempio.it Aggiungi account con certificato + Impossibile analizzare il certificato Lasciare vuoto per autenticarsi con certificato Preferenze di archiviazione Preferenze di archiviazione lato server Raccolta preferenze di archiviazione. Attendere prego... + Impossibile recuperare le preferenze di archiviazione + CAPTCHA necessario Inserisci il testo dell\'immagine soprastante + Catena di certificati non fidata L\'indirizzo XMPP non corrisponde al certificato Rinnova certificato Errore ricezione chiave OMEMO! @@ -432,6 +489,7 @@ Indirizza tutte le connessioni attraverso la rete Tor. Richiede Orbot Nome host Porta + Indirizzo server o .onion Questo non è un numero di porta valido Questo non è un nome host valido %1$d su %2$d account connessi @@ -440,7 +498,14 @@ %d messaggi Carica altri messaggi + File condiviso con %s + Immagine condivisa con %s + Immagini condivise con %s + Testo condiviso con %s + Dai a Conversations l\'accesso all\'archiviazione esterna + Dai a Conversations l\'accesso alla fotocamera Sincronizza con i contatti + Conversations vuole l\'autorizzazione ad accedere ai tuoi contatti per confrontarli con la lista in XMPP per mostrare i loro nomi ed avatar.\n\nLeggerà solamente i contatti e li confronterà localmente senza inviarli sul tuo server.
Non salveremo una copia di quei numeri di telefono.\n\nPer maggiori informazioni leggi la nostra politica sulla privacy.

Ti verrà ora chiesta l\'autorizzazione di accedere ai tuoi contatti.]]>
Notifica per tutti i messaggi Notifica solo quando menzionato @@ -451,15 +516,22 @@ Sempre Solo immagini grandi Ottimizzazioni batteria attivate + Il tuo dispositivo sta facendo delle ingenti ottimizzazioni della batteria per Conversations che potrebbero portare ritardi alle notifiche o anche perdita di messaggi.\nSi consiglia di disattivarle. + Il tuo dispositivo sta facendo delle ingenti ottimizzazioni della batteria per Conversations che potrebbero portare ritardi alle notifiche o anche perdita di messaggi.\nTi verrà ora chiesto di disattivarle. Disattiva L\'area selezionata è troppo grande (Nessun account attivo) Questo campo è obbligatorio Correggi messaggio Invia messaggio corretto + Hai già validato l\'impronta di questa persona in modo sicuro per confermarne la fiducia. Selezionando “Fatto” stai solo confermando che %s fa parte di questa chat di gruppo. Hai disattivato questo account + Errore di sicurezza: accesso file non valido! + Nessuna app trovata per condividere l\'URI Condividi l\'URI con...
Ti registri con il tuo numero di telefono e Quicksy ti suggerirà—in base ai numeri di telefono nella tua rubrica—automaticamente i possibili contatti.

Registrandoti accetti la nostra politica sulla privacy.]]>
+ Accetta e continua + È disponibile una guida per la creazione di un account su conversations.im.¹\nQuando scegli conversations.im come fornitore potrai comunicare con utenti di altri fornitori dando il tuo indirizzo XMPP completo. Il tuo indirizzo XMPP completo sarà: %s Crea account Usa un altro provider @@ -483,12 +555,17 @@ Breve Medio Lungo + Trasmissione + Fa sapere ai tuoi contatti quando usi Conversations Privacy Tema Seleziona il colore Automatico + Chiaro + Scuro Sfondo verde Usa sfondo verde per messaggi ricevuti + Impossibile connettersi a OpenKeychain Questo dispositivo non è più in uso Computer Cellulare @@ -496,21 +573,29 @@ Browser web Console Necessario pagamento + Concedi l\'autorizzazione ad usare internet Io Il contatto chiede la sottoscrizione della presenza Consenti Nessuna autorizzazione per accedere a %s Server remoto non trovato Scadenza server remoto + Impossibile aggiornare l\'account + Segnala questo indirizzo XMPP per spam. Elimina identità OMEMO + Rigenera le tue chiavi OMEMO. I tuoi contatti dovranno verificare un\'altra volta la tua identità. Usalo solo come ultima spiaggia. Cancella le chiavi selezionate Devi essere connesso per pubblicare l\'avatar. Mostra messaggio di errore Messaggio di errore Risparmio dati attivato + Il tuo sistema operativo sta limitando l\'accesso internet a Conversations quando è in secondo piano. Per ricevere le notifiche di nuovi messaggi dovresti consentire l\'accesso senza limiti a Conversations quando il \"Risparmio dati\" è attivo.\nConversations cercherà comunque di risparmiare dati quando possibile. Il tuo dispositivo non supporta la disattivazione del Risparmio dati per Conversations. + Impossibile creare il file temporaneo Questo dispositivo è stato verificato Copia impronta + Hai verificato tutte le chiavi OMEMO in tuo possesso + Il codice a barre non contiene impronte per questa conversazione. Impronte verificate Usa la fotocamera per scansionare il codice a barre di un contatto Attendi la ricezione delle chiavi @@ -518,8 +603,11 @@ Condividi come URI XMPP Condividi come link HTTP Fiducia cieca prima della verifica + Fidati di nuovi dispositivi da contatti non verificati, ma chiedi una conferma manuale per nuovi dispositivi da contatti verificati. + Chiavi OMEMO accettate ciecamente, perciò potrebbero essere di qualcun altro o qualcuno potrebbe essersi intromesso. Non fidato Codice a barre 2D non valido + Svuota la cartella della cache (usata dall\'app fotocamera) Svuota cache Svuota archivio privato Svuota l\'archivio privato nella quale sono memorizzati i file (possono essere riscaricati dal server) @@ -529,6 +617,7 @@ Mostra inattivi Nascondi inattivi Diffida il dispositvo + Sei sicuro di volere rimuovere la verifica di questo dispositivo?\nIl dispositivo e i messaggi provenienti da esso verranno segnati come \"Non fidato\". %d secondo %d secondi @@ -571,7 +660,9 @@ Meccanismo SASL degradato Il server richiede la registrazione sul sito Apri sito + Nessuna app trovata per aprire il sito Notifiche avvisi + Mostra notifiche su avvisi Oggi Ieri Convalida hostname con DNSSEC @@ -599,6 +690,8 @@ Modifica il messaggio di stato Disattiva la cifratura Conversations non riesce a inviare messaggi criptati a %1$s. Potrebbe essere dovuto al tuo contatto che usa un server obsoleto o un client che non supporta OMEMO. + Impossibile ricevere l\'elenco dispositivi + Impossibile ricevere le chiavi di cifratura Suggerimento: in alcuni casi può essere risolto aggiungendo a vicenda la vostra lista di contatti. Sei sicuro di disattivare la cifratura OMEMO per questa conversazione?\nCiò permetterà all\'amministratore del server di leggere i tuoi messaggi, ma potrebbe essere il solo modo di comunicare con persone che usano client obsoleti. Disattiva adesso @@ -627,7 +720,9 @@ Condividi la posizione Mostra la posizione Condividi + Impossibile avviare la registrazione Attendere prego... + Dai a Conversations l\'accesso al microfono Cerca messaggi GIF Vedi conversazione @@ -647,6 +742,7 @@ Il nome è facoltativo Nome chat di gruppo Questa chat di gruppo è stata distrutta + Impossibile salvare la registrazione Servizio in primo piano Questa categoria di notifiche è usata per mostrare una notifica permanente per indicare che Conversations è in esecuzione. Informazioni di stato @@ -702,6 +798,9 @@ Il pin che ti abbiamo inviato è scaduto. Errore di rete sconosciuto. Risposta dal server sconosciuta. + Impossibile connettersi al server. + Impossibile stabilire una connessione sicura. + Impossibile trovare il server. Qualcosa è andato storto elaborando la tua richiesta. Input utente non valido Temporaneamente non disponibile. Riprova più tardi. @@ -730,6 +829,8 @@ Ripristina Inserisci la tua password per l\'account %s per ripristinare il backup. Non usare la funzione di ripristino del backup tentando di clonare (eseguire simultaneamente) un\'installazione. Il ripristino di un backup è inteso solo per migrazioni o in caso di smarrimento del dispositivo. + Impossibile ripristinare il backup. + Impossibile decifrare il backup. La password è giusta? Backup e ripristino Inserisci l\'indirizzo XMPP Crea chat di gruppo @@ -744,6 +845,7 @@ Creazione canale pubblico… Questo canale esiste già Sei entrato in un canale esistente + Impossibile salvare la configurazione del canale Permetti a chiunque di modificare l\'argomento Permetti a chiunque di invitare altri Chiunque può modificare l\'argomento. @@ -776,7 +878,9 @@ Il file selezionato non è un file di backup di Conversations Questo account è già stato configurato Inserisci la password per questo account + Impossibile eseguire questa azione Entra in un canale pubblico... + L\'app di condivisione non ha concesso l\'autorizzazione per accedere a questo file. jabber.network Server locale @@ -797,7 +901,9 @@ Localizzazione dispositivi Sta squillando Occupato + Impossibile connettere la chiamata Chiamata ritirata + Errore dell\'app Riaggancia Chiamata in corso Chiamata video in corso @@ -811,6 +917,8 @@ Chiamata video Il tuo microfono non è disponibile Puoi fare solo una chiamata alla volta. + Torna alla chiamata in corso + Impossibile cambiare fotocamera Vedi %1$d partecipante Vedi %1$d partecipanti diff --git a/src/main/res/values-zh-rCN/strings.xml b/src/main/res/values-zh-rCN/strings.xml index 99cb7c877..770cab0b2 100644 --- a/src/main/res/values-zh-rCN/strings.xml +++ b/src/main/res/values-zh-rCN/strings.xml @@ -7,12 +7,12 @@ 关闭聊天 联系人详情 群聊详情 - 群聊详情 - 安全聊天 + 频道详情 + 加密聊天 添加账号 - 编辑姓名 - 添加到联系人 - 从XMPP联系人中删除 + 编辑名称 + 添加到通讯录 + 从畅聊通讯录中删除 封禁联系人 解封联系人 封禁域名 @@ -28,33 +28,35 @@ 通过帐户分享 封禁列表 刚刚 - 1分钟前 + 一分钟前 %d分钟前 %d条未读消息 发送中… - 解密中. 请稍候… + 解密中。请稍候… OpenPGP加密的信息 - 该用户名已存在 + 用户名已存在 无效的用户名 管理员 所有者 版主 - 参与者 + 成员 访客 + 将 %s 从XMPP联系人中移除? 与该联系人的会话消息不会清除。 您想封禁%s吗? 您想解封 %s吗 ? 封禁 %s 中的所有联系人? 解封%s 中所有联系人? 联系人已封禁 已封禁 + 从书签中移除 %s ?相关会话消息不会被清除。 在服务器上注册新账户 在服务器上修改密码 分享… - 开始会话 + 开始聊天 邀请联系人 邀请 联系人 - 联系 + 联系人 取消 设置 添加 @@ -65,68 +67,84 @@ 保存 完成 畅聊已崩溃 + 通过您的账户发送堆栈跟踪,可以帮助畅聊持续发展。 立即发送 不再询问 - 添加文件 + 无法连接账户 + 无法连接多个账户 + 点击以管理账户 + 发送文件 + 该联系人不在您的列表中,需要添加吗 ? 添加联系人 传递失败 + 准备发送图片 + 准备发送图片 正在分享文件,请稍候… 清除历史记录 - 清除会话记录 + 清除聊天记录 + 您确定要删除此聊天中的所有消息吗?\n\n警告:这不会删除存储在其他设备或服务器上的那些消息的副本。 删除文件 您确定要删除此文件吗?\n\n 警告:这不会删除存储在其他设备或服务器上的此文件的副本。 - 之后关闭此对话 + 之后关闭此聊天 选择设备 发送未加密的信息 发送信息 发信息给 %s - 发送 OMEMO 加密信息 - 发送 v\\OMEMO 加密信息 - 发送 OpenPGP 加密信息 + 发送OMEMO加密信息 + 发送v\\OMEMO加密信息 + 发送OpenPGP加密信息 + 昵称已被使用 不加密发送 解密失败,可能是私钥不正确。 OpenKeychain + 畅聊使用了第三方app OpenKeychain 来加密、解密信息并管理您的密钥。\n\nOpenKeychain 遵循 GPLv3 并且可以在 F-Droid 和 Google Play 上获取。\n\n(之后请重启畅聊) 重启 安装 请安装OpenKeychain以解密 - 输入… + 提供… 等待… 未发现 OpenPGP 密钥 - 未找到 OpenPGP 密钥 + 因您的联系人未公布公钥,畅聊未能成功加密您的信息。\n\n请通知对方设置OpenPGP。 + 未找到OpenPGP密钥 + 因您的联系人未公布公钥,畅聊未能成功加密您的信息。\n\n请通知对方设置OpenPGP. 常规 接收文件 自动接收小于此大小的文件 附件 通知 - 震动 - 收到新消息时震动 - LED 灯提示 + 振动 + 收到新消息时振动 + 通知灯 收到新消息时闪烁通知灯 铃声 通知铃声 新消息通知铃声 来电铃声 - 静默期限 - 在您的其他设备之一上检测到活动之后,时间通知的长度将被静音。 + 静默时间段 + 在其他设备上检测到活动之后,通知在此时间段内将被静音。 高级 从不发送崩溃报告 + 通过发送堆栈跟踪,您可以帮助畅聊持续发展 确认消息 让对方知道你收到并阅读了他们的消息 用户界面 + OpenKeychain报告一个错误。 错误的密钥 接受 产生了一个错误 错误 - 你的账号 - 发送在线联系人列表更新 - 接收在线联系人列表更新 - 请求在线联系人列表更新 + 你的账户 + 发送在线状态更新 + 接收在线状态更新 + 请求在线状态更新 选择图片 - 拍摄图片 + 拍照 预先同意订阅请求 - 您选择的文件不是图像文件 + 您选择的文件不是图像 + 无法转换图片 未找到文件 常规的 I/O 错误。可能是存储空间不足? + 您用来选择图片的程序没有给予读取权限。\n\n </small>尝试其他文件管理器选择图片</small>。 未知 暂时不可用 在线 @@ -138,8 +156,9 @@ 注册失败 用户名已存在 注册完成 + 服务器不支持注册 无效的注册令牌 - TLS 协商失败 + TLS协商失败 违反政策 服务器不兼容 流错误 @@ -151,54 +170,62 @@ 删除账号 暂时不可用 发布头像 - 发布 OpenPGP 公钥 - 移除 OpenPGP 公钥 - 您确定要从在线通知中移除 OpenPGP 公钥吗?\n您的联系人将无法再向您发送 OpenPGP 加密信息。 + 发布OpenPGP公钥 + 移除OpenPGP公钥 + 您确定要从在线状态中移除OpenPGP公钥吗?\n您的联系人将无法再向您发送 OpenPGP 加密信息。 + OpenPGP公钥已发布 启用账户 确定? + 如果您删除帐户,您的所有聊天记录将会丢失 录音 XMPP地址 拦截XMPP地址 username@example.com 密码 这不是有效的XMPP地址 - 是否添加 %s 到地址薄? - 服务器信息 - XEP-0313:消息归档管理 - XEP-0280:消息复写 + 空间不足。图片过大 + 是否添加%s到通讯录? + 服务器属性 + XEP-0313:消息存档管理 + XEP-0280:消息抄送 XEP-0352:客户端状态指示 XEP-0191:屏蔽指令 - XEP-0237:名单版本 + XEP-0237:通讯录版本管理 XEP-0198:流管理 XEP-0215:发现外部服务 - XEP-0163:PEP(头像/OMEMO) + XEP-0163:个人事件协议(头像/OMEMO) XEP-0363:HTTP文件上传 XEP-0357:推送 有效 无效 缺少公钥通知 - 刚刚查看过 - %d分钟前查看过 - %d小时前查看过 - %d天前查看过 - OpenPGP 密钥 ID - OMEMO 指纹 - v\\OMEMO 指纹 - 消息的 OMEMO 指纹 - 消息的 OMEMO 指纹 + 刚来过 + 一分钟前来过 + %d分钟来过 + 一小时前来过 + %d小时前来过 + 一天前来过 + %d天前来过 + 加密信息。请安装OpenKeychain以解密。 + 发现新OpenPGP加密信息 + OpenPGP密钥ID + OMEMO指纹 + v\\OMEMO指纹 + 消息的OMEMO指纹 + 消息的OMEMO指纹 其他设备 - 信任的 OMEMO 指纹 + 信任的OMEMO指纹 获取密钥中 完成 解密 书签 - 查找 + 搜索 输入联系人 删除联系人 查看联系人详细信息 - 屏蔽联系人 - 解除联系人屏蔽 - 创建 + 封禁联系人 + 解封联系人 + 新建 选择 联系人已存在 加入 @@ -207,42 +234,49 @@ 保存为书签 删除书签 解散群聊 - 解散群聊 + 解散频道 您确定要解散此群聊吗?\n\n警告:此群聊将在服务器上完全删除。 - 您确定要解散此公共群聊吗?\n\n警告:该群聊将在服务器上完全删除。 + 您确定要解散此公共频道吗?\n\n警告:该频道将在服务器上完全删除。 无法解散群聊 - 无法解散群聊 + 无法解散频道 编辑群聊主题 主题 正在加入群聊… 离开 - 联系人已添加你到联系人列表 + 联系人已添加你到通讯录 反向添加 %s 读到这里了 %s 读到这里了 + %1$s 和另外%2$d人读到这里了 所有人都读到这里了 发布 + 点击头像以选择图片 正在发布… 服务器拒绝了您的发布请求 + 无法转换图片 不能将头像保存至磁盘 - (或长按按钮将返回默认头像) + (长按以恢复默认) + 服务器不支持头像 私聊 至 %s - 发送私密消息到 %s + 与%s私聊 连接 该账号已存在 下一步 + 会话已建立 跳过 关闭通知 - 打开通知 + 启用 需要密码才能进入该群聊 输入密码 - 现在发送请求 + 请先发送更新在线状态请求。\n\n以判断您的联系人所用的客户端类型。 + 现在请求 忽略 + 警告:在没有相互更新在线状态的情况下发送将会出现未知问题。\n\n前往联系人详情以验证您订阅的在线状态。 安全 允许更正消息 - 允许您的联系人追回编辑他们的信息 - 专家设置 + 允许对方发送后编辑信息 + 高级设置 请谨慎使用 关于%s 静默时间段 @@ -251,22 +285,24 @@ 启用静默时间段 在静默时间段内通知将保持静音 其他 - 同步书签 - 你已经被封禁了 - 这个群组只允许群组成员聊天 + 与书签同步 + 根据书签标记自动加入群聊。 + OMEMO指纹已拷贝到剪贴板 + 您被封禁了 + 这个群聊只允许成员聊天 资源限制 - 您已被移出该群组了 - 这个群组已被关闭 + 您被从此群聊踢出 + 这个群聊已被关闭 您已不在该群组 使用帐户%s 托管于%s - 正在 HTTP 服务器中检查 %s - 你没有连接。请稍后重试 - 检查 %s 大小 - 在 %2$s 上检查 %1$s 的大小 + 正在HTTP服务器中检查%s + 未连接。请稍后重试 + 检查%s的大小 + 在%2$s上检查%1$s的大小 消息选项 引用 - 粘贴引用 + 作为引用粘贴 复制原始URL 重新发送 文件URL @@ -276,39 +312,50 @@ web地址 扫描二维码 显示二维码 - 显示黑名单 + 显示封禁列表 账户详情 确认 - 再试一遍 - 防止操作系统中断你的连接 + 重试 + 前台服务 + 防止操作系统中断连接 创建备份 - 备份文件将存储在%s + 备份文件将保存在%s 正在备份文件 - 您的备份已创建完成 + 备份已创建 此备份文件已经存储在%s 正在恢复备份 - 您的备份已经恢复完成 - 不要忘记启用该帐号。 + 备份已恢复 + 别忘了启用帐号。 选择文件 - 接收中 %1$s (已完成 %2$d%%) + 正在接受%1$s (已完成%2$d%%) 下载 %s 删除 %s 文件 打开 %s 正在发送(已完成%1$d%%) + 准备传输文件 可以下载 %s 取消传输 + 文件传输失败 文件传输已取消 + 文件已经删除 + 没有可以打开此文件的应用 + 没有可以打开此链接的应用 + 未找到可以查看联系人的应用 动态标签 在联系人下方显示只读标签 启用通知 - 未找到该群聊的服务器 + 未找到群聊服务器 + 群聊创建失败 账户头像 复制OMEMO指纹到剪贴板 重新生成OMEMO密钥 清除设备 + 清除所有其他设备的 OMEMO 通告?下次设备连接时将重新通告,但可能收不到你发送的消息。 + 此联系人没有可用的密钥。\n从服务器获取密钥失败。也许你的联系人所在服务器发生问题。 + 没有可以用于这个账户的密钥。\n请确保你有相互的在线状态的订阅。 出错了 - 从服务器获取历史记录 + 正在从服务器获取历史记录 服务器上没有更多历史记录 更新中… 密码已修改! @@ -316,85 +363,90 @@ 修改密码 当前密码 新密码 + 密码不能为空 启用所有账户 禁用所有账户 选择一个操作 没有从属关系 离线 - 抛弃 + 已封禁 成员 高级模式 授予成员权限 - 撤销成员权限 + 吊销成员权限 授予管理员权限 吊销管理员权限 授予所有者权限 - 撤销所有者权限 + 吊销所有者权限 从群聊中移除 - 从群聊中移除 + 从频道中移除 不能修改 %s 的从属关系 - 屏蔽群聊 - 从群聊中屏蔽 - 现在屏蔽 + 从群聊中封禁 + 从频道中封禁 + %s将被从公共频道中移除。只有将此用户封禁才能将他永远移除。 + 立刻封禁 不能修改 %s 的角色 私密群聊设置 - 公开群聊设置 + 公开频道设置 私密,只有成员可以加入 使XMPP地址对所有人可见 - 使群聊受到管理 + 使频道受到管理 您尚未参与 - 群组设置修改成功! - 无法更改群组设置 + 群聊设置修改成功! + 无法更改群聊设置 从不 - 直到重新开启通知 + 直至另行通知 小睡 回复 标记为已读 输入 点击回车发送 - 用回车键来发送消息 + 回车键发送消息 显示回车键 - 改变表情键为回车键 + 将表情键改为回车键 音频 视频 图片 PDF文档 - Android应用 + Android程序 联系人 头像已经发布! 正在发送%s - 提供中 %s + 正在提供%s 隐藏离线联系人 - %s 正在输入 - %s 已停止输入 - %s 正在输入 - %s 已停止输入 - 键盘输入通知 + %s正在输入 + %s已停止输入 + %s正在输入 + %s已停止输入 + 输入通知 让对方知道你正在输入 - 发送位置 + 位置 显示位置 + 无法找到显示位置的应用 位置 - 会话已关闭 + 聊天已关闭 离开私密群聊 - 离开公开群聊 - 不相信系统 CA - 所有证书必须人工通过 + 离开公开频道 + 不信任系统CA + 所有证书必须手动通过 移除证书 - 删除人工通过的证书 - 没有人工通过的证书 + 删除手动通过的证书 + 没有手动通过的证书 移除证书 - 删除选项 + 删除已选 取消 - %d 个证书已被删除 + %d个证书已被删除 + 以快捷操作替代发送按钮 快捷操作 - 最近常用 + 刚用过的 选择快捷操作 搜索联系人 搜索书签 发送私密消息 + %1$s离开了群聊 用户名 用户名 该用户名无效 @@ -402,73 +454,93 @@ 下载失败:未找到文件 下载失败:无法连接到服务器 下载失败:不能写入文件 - Tor network 不可用 + Tor网络不可用 绑定失败 + 服务器不能为域名做出响应 损坏 可用性 - 关闭屏幕时离开 - 当屏幕关闭时将标记您的资源为离开状态 + 锁屏时显示离开 + 锁屏时标记为离开状态 静音模式时设为“请勿打扰” - 当设备进入静音模式时把资源标识改为“请勿打扰” - 静音模式开启振动 - 当设备进入震动模式时把资源标识改为“请勿打扰” + 当设备静音时标记为“请勿打扰”状态 + 将振动看作静音 + 使用振动模式时标记为“请勿打扰”状态 高级连接设置 注册账户时显示主机名和端口 xmpp.example.com 使用证书添加账户 + 无法解析证书 留空以使用证书认证 - 压缩设置 - 服务端压缩设置 - 正在获取压缩设置。请稍候…… - 输入上图中的文字 + 存档设置 + 服务端存档设置 + 正在获取存档设置。请稍候…… + 无法获取存档配置 + 需要验证码 + 输入上图文字 + 证书链不受信任 XMPP地址与证书不匹配 更新证书 - 获取 OMEMO 密钥错误! - 请用证书验证 OMEMO 密钥! - 您的设备不支持设备证书选择! + 获取OMEMO密钥时发生错误! + 请用证书验证OMEMO密钥! + 您的设备不支持客户端证书选择! 连接 - 通过 Tor 连接 - 所有连接使用 Tor 网络传输,需要 Orbot - 主机名 + 通过Tor连接 + 所有连接使用Tor网络传输,需要Orbot + 服务器名 端口 + 服务器或者.onion地址 该端口号无效 该主机名无效 - %2$d 个中的 %1$d 个账户已连接 + %2$d个账户中的%1$d个已连接 - %d 条消息 + %d条消息 - 载入更多消息 + 加载更多消息 + 文件已分享给%s + 图片已分享给%s + 图片已分享给%s + 文本已分享给%s + 允许畅聊访问外部储存 + 允许畅聊使用摄像头 同步联系人 + 将服务器端联系人与本地联系人匹配可以显示联系人的全名与头像。\n\n此应用只在本地读取并匹配联系人。\n\n现在应用将请求联系人权限。
我们并不储存这些号码。\n\n更多信息请阅读隐私政策。接下来将请求通讯录权限。]]>
为所有信息显示通知 只在被提到时通知 - 禁用通知 - 暂停通知 + 通知已禁用 + 通知已暂停 图像压缩 - 提示:使用“选择文件”而不是“选择图片”来发送未经压缩的单个图像,无论此设置如何。 + 提示:使用“选择文件”发送原图。这将忽略此设置。 总是 仅大图片 - 启用节电模式 + 节电模式已启用 + 你的设备正在为畅聊进行电池优化,这可能导致通知的延迟甚至消息的丢失。\n建议禁用电池优化。 + 你的设备正在为畅聊进行电池优化,这可能导致通知的延迟甚至消息的丢失。\n你将会被提示禁用该功能。 禁用 选择区域过大 - (没有激活的账户) + (没有启用的账户) 必填 更正消息 发送更正后的消息 + 您已经验证了该用户。点击“完成”让%s加入群聊。 你已经禁用了此账户 + 安全错误:文件访问无效 + 未找到可以分享此链接的应用 分享链接……
您注册了电话号码,Quicksy就会根据您的通讯录中的电话号码自动为您建议可能的联系人

签署即表示您同意我们的隐私政策。]]>
+ 同意并继续 + 此向导将为您在conversations.im¹上创建一个账户。\n您的联系人可以通过您的XMPP完整地址与您聊天。 您的XMPP完整地址将是:%s 创建账户 - 使用我自己的服务端 + 使用我自己的服务器 输入您的用户名 - 手动更改状态 + 手动更改在线状态 编辑状态信息时,您的状态 状态信息 - 免费聊天室 + 有空聊天 在线 离开 - 离线 + 没时间 忙碌 安全密码已生成 该设备不支持禁用电池优化 @@ -481,52 +553,69 @@ + 广播使用应用的时间 + 让联系人知道你使用畅聊的时间 隐私 主题 - 选择调色板 + 选择主题色彩 自动 + 明亮 + 灰暗 绿色背景 接收到的消息使用绿色背景 - 此设备不再使用 + 无法连接到OpenKeychain + 不再使用此设备 电脑 手机 平板 浏览器 控制台 需要付款 + 允许联网 - 联系人请求在线订阅 + 联系人请求在线状态订阅 允许 - 没有访问 %s 的许可 + 无权访问%s 找不到远程服务器 远程服务器超时 - 删除 OMEMO 身份 + 无法更新账户 + 举报此账户发送垃圾信息 + 删除OMEMO身份 + 重新生成OMEMO密钥。所有联系人都需要再次认证。请将此作为最后的办法。 删除选择的密钥 你需要连接才能发布头像 显示出错消息 - 出错消息 - 省流量模式已激活 + 出错信息 + 省流量模式已启用 + 您的操作系统禁止本程序在后台运行时访问互联网。为了收到新消息提示,您需要在省流量模式下允许本程序不受限制地访问互联网。\n本程序仍会尽可能节省流量。 该设备不支持禁用省流量模式 - 此设备已经验证 + 无法创建临时文件 + 已验证此设备 复制指纹 + 所有OMEMO密钥都已验证 + 条码不包含用于聊天的指纹。 已验证的指纹 - 使用相机扫描一个联系人的条码 - 请等待密钥被获取 - 分享条形码 + 使用相机扫描联系人条码 + 请等待获取密钥 + 分享条码 分享XMPP URI 分享HTTP链接 验证前盲目信任 - 不可信的 - 非法的二维码 + 自动信任陌生人的设备,但在验证过联系人添加设备时手动确认。 + 盲目信任OMEMO密钥,可能会有人冒充对方发送消息 + 不信任的 + 无效二维码 + 清除相机缓存 清除缓存 清除私密存储 - 清除保存私密文件的存储 (它们可以之后从服务器上重新下载) - 我从一个可信的源追踪的此链接 - 点击一个链接后将会开始校验 %1$s 的 OMEMO 密钥。此种情形只在你获得了一个从可信的源上只有 %2$s 能发布的该链接才是安全的。 - 校验 OMEMO 密钥 + 清除保存私密文件的存储 (可以从服务器上重新下载) + 此链接的源头是可信的 + 点击链接后将会开始校验%1$s的OMEMO密钥。只有%2$s发布的链接才是安全的。 + 校验OMEMO密钥 显示不活跃设备 隐藏不活跃设备 - 不信任的设备 + 不再信任设备 + 你确认要移除此设备的验证吗?\n此设备及从其发送的信息将会被标识为不可信。 %d秒 @@ -548,29 +637,31 @@ 自动删除消息 自动从此设备上删除超过配置时间段的消息 消息加密中 - 由于本地保留期限,因此无法提取消息。 + 由于本地保留期限设置,无法提取消息。 正在压缩视频 相应的对话已关闭。 - 联系人已屏蔽 - 陌生人也通知 + 联系人已封禁 + 陌生人的消息也通知 提醒来自陌生人的消息与通话 已收到陌生人的信息 - 屏蔽陌生人 - 屏蔽整个域名 + 封禁陌生人 + 封禁整个域名 当前在线 重试解密 会话失败 - 已降级的 SASL 机制 + 已降级的SASL机制 服务器要求在网站上注册 打开网站 + 没有可以打开网站的应用 顶部通知 + 显示顶部通知 今天 昨天 - 使用 DNSSEC 来验证主机名 - 包含已验证的主机名的服务器证书被认为是已验证的 + 通过DNSSEC验证主机名 + 包含主机名的服务器证书被认为是已验证的 证书不包含XMPP地址 - 部分的 - 录制视频 + 一部分 + 录像 复制 消息已被复制 消息 @@ -578,7 +669,7 @@ 受保护的应用 为了在屏幕关闭时也可收到消息提醒,您需要将畅聊加入受保护的应用列表。 接受未知的证书? - 服务器证书未经已知证书机构签发。 + 服务器证书未由已知证书机构签发。 接受不匹配的服务器名称? 由于 “%s”,服务器无法验证。证书仅对此有效: 您仍希望连接吗? @@ -591,9 +682,11 @@ 编辑状态信息 禁用加密 畅聊无法向%1$s发送加密信息。这可能是由于您的联系人使用了无法处理OMEMO的过时服务器或客户端。 + 无法获取设备列表 + 无法获取密钥 提示:某些情况下,可以将对方加入联系人列表,以解决此问题。 确认要禁用此会话的 OMEMO 加密吗?\n这会允许您的服务器管理员阅读你们的消息,但这可能是和使用过时客户端的人会话的唯一方式。 - 现在禁用 + 立即禁用 草稿: OMEMO加密 OMEMO将始终用于一对一和私人群组聊天。 @@ -619,12 +712,14 @@ 分享位置 显示位置 分享 + 无法开始录制 请等待…… + 允许畅聊使用麦克风 搜索消息 - GIF - 查看对话 - 分享位置插件 - 不使用内置地图,使用“分享位置”插件 + GIF动图 + 查看聊天 + 位置分享插件 + 不使用内置地图,使用“位置分享”插件 复制web地址 复制XMPP地址 用于S3的HTTP文件共享 @@ -639,11 +734,12 @@ 提供名称是可选的 群聊名称 群聊已被解散 + 无法保存录制的文件 前台服务 此通知类别用于显示表明畅聊正在运行的永久通知。 状态信息 连接问题 - 此通知类别用于显示一旦帐户连接出现问题的通知。 + 此通知类别用于显示帐户连接问题通知。 消息 通话 消息 @@ -653,7 +749,7 @@ 此通知组用于显示不应触发任何声音的通知。 例如,当在另一个设备上激活时(宽限期)。 消息通知设置 来电通知设置 - 重要性,声音,振动 + 重要程度、声音、振动 视频压缩 查看媒体文件 成员 @@ -694,6 +790,9 @@ 验证码已失效 未知网络错误 未知服务器应答 + 无法连接服务器。 + 无法建立安全连接。 + 找不到服务器 处理请求时出错 用户输入无效 暂时无法连接。请稍候再试。 @@ -712,7 +811,7 @@ 安装Orbot 启动Orbot 软件商店未安装 - 此群聊将公开你的XMPP地址 + 此频道将公开你的XMPP地址 电子书 原始(未压缩) 打开方式 @@ -721,21 +820,24 @@ 恢复备份 恢复 输入%s的密码以恢复备份 - 仅在迁移或丢失原设备时恢复备份。 + 仅在迁移或丢失设备时恢复备份。 + 无法恢复备份。 + 无法解密备份。密码是否正确? 备份与恢复 输入XMPP地址 创建群聊 - 加入公开群聊 + 加入公开频道 创建私密群聊 - 创建公开群聊 - 群聊名称 + 创建公开频道 + 频道名称 XMPP地址 - 请为群聊提供一个名称。 + 请为频道提供一个名称。 请提供XMPP地址。 这是一个XMPP地址。请提供一个名称。 - 创建公开群聊 - 群聊已存在 - 您加入了一个已经存在的群聊 + 创建公开频道 + 频道已存在 + 您加入了一个已经存在的频道 + 无法配置频道 允许任何成员修改主题 允许任何成员邀请其他人 允许任何成员修改主题 @@ -745,22 +847,22 @@ 允许任何成员邀请其他人 XMPP地址对管理员可见。 XMPP地址对所有人可见 - 此公开群聊无成员。邀请成员或使用分享按钮分享地址。 + 此公开频道无成员。邀请成员或使用分享按钮分享地址。 此私密群聊无成员 管理权限 搜索成员 文件过大 附加 - 发现群聊 - 搜索群聊 + 发现频道 + 搜索频道 可能侵犯隐私! - search.jabber.network。

的第三方服务。使用此功能会将您的IP地址和搜索字词传输到该服务。 有关更多信息,请参见其Privacy Policy。]]>
+ search.jabber.network。

的第三方服务。使用此功能会将您的IP地址和搜索字词传输到该服务。 有关更多信息,请参见其隐私政策。]]>
我已有账户 添加已有账户 注册新账户 这好像是一个域名地址 仍然添加 - 这好像是一个群聊地址 + 这好像是一个频道地址 分享备份文件 备份文件 事件 @@ -768,41 +870,47 @@ 选择的文件不是备份文件 账户已设置 请输入此账户的密码 - 加入公开群聊 + 无法执行此操作 + 加入公开频道 + 分享程序没有访问文件的权限 jabber.network 本地服务器 大多数用户应该选择“ jabber.network”以从整个XMPP生态系统中获得更好的建议。 - 群聊发现方法 + 频道发现方法 备份 关于 请启用一个帐户 - 拨打电话 + 进行通话 来电 视频来电 正在连接 已连接 - 正在接受通话 - 正在结束通话 - 接电话 + 正在接通来电 + 正在结束来电 + 应答 忽略 正在确定设备位置 正在响铃 - 忙碌 - 撤销的通话 + 正忙 + 无法接通来电 + 通话已撤销 + 程序错误 挂断 正在进行的通话 正在进行的视频通话 禁用Tor以拨打电话 来电 - 来电%s + 来电 · %s 去电 - 去电%s + 去电 · %s 未接电话 语音通话 视频通话 麦克风不可用 - 在同一时间只能打一通电话 + 只能同时打一通电话 + 返回正在进行的通话 + 无法切换摄像头 查看%1$d成员 diff --git a/src/quicksy/res/values-it/strings.xml b/src/quicksy/res/values-it/strings.xml index f8cc256b8..41061f727 100644 --- a/src/quicksy/res/values-it/strings.xml +++ b/src/quicksy/res/values-it/strings.xml @@ -9,6 +9,8 @@ Se scegli di inviare una segnalazione dell’errore aiuterai lo sviluppo di Quicksy Quicksy ha bisogno di accedere all\'archiviazione esterna Quicksy ha bisogno di accedere alla fotocamera + Il tuo dispositivo sta facendo delle ingenti ottimizzazioni della batteria per Conversations che potrebbero portare ritardi alle notifiche o anche perdita di messaggi.\nSi consiglia di disattivarle. + Il tuo dispositivo sta facendo delle ingenti ottimizzazioni della batteria per Conversations che potrebbero portare ritardi alle notifiche o anche perdita di messaggi.\nTi verrà ora chiesto di disattivarle. Fai sapere ai tuoi contatti quando usi Quicksy Il tuo sistema operativo sta limitando l\'accesso internet a Quicksy quando è in background. Per ricevere le notifiche di nuovi messaggi dovresti consentire l\'accesso senza limiti a Quicksy quando il Risparmio dati è attivo.\nQuicksy cercherà comunque di risparmiare dati quando possibile. Il tuo dispositivo non supporta la disattivazione del Risparmio dati per Quicksy. diff --git a/src/quicksy/res/values-zh-rCN/strings.xml b/src/quicksy/res/values-zh-rCN/strings.xml index 21b5bcec4..b7ee2a23a 100644 --- a/src/quicksy/res/values-zh-rCN/strings.xml +++ b/src/quicksy/res/values-zh-rCN/strings.xml @@ -9,6 +9,8 @@ 通过发送堆栈跟踪,您可以帮助Quicksy持续发展 Quicksy需要外部存储权限 Quicksy需要摄像头权限 + 你的设备正在为Quicksy进行电池优化,这可能导致通知的延迟甚至消息的丢失。\n建议禁用电池优化。 + 你的设备正在为Quicksy进行电池优化,这可能导致通知的延迟甚至消息的丢失。\n建议禁用电池优化。 让你的所有联系人知道你使用Quicksy的时间 您的操作系统限制Quicksy在后台访问网络。 要接收新消息的通知,您应该在启用节省流量模式时允许Quicksy不受限制的访问网络。\nQuicksy仍会尽可能地节省流量。 该设备不支持禁用省流量模式 From 5af4c865a72c47faa953573e12c6ceb9212a1358 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 8 May 2020 17:22:27 +0200 Subject: [PATCH 03/20] make sure we finsh() the connection after transitioning into terminal state --- .../conversations/xmpp/jingle/JingleRtpConnection.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java index f74c738b8..01840189a 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java @@ -647,6 +647,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web //todo we haven’t actually initiated the session yet; so sending sessionTerminate makes no sense //todo either we don’t ring ever at all or maybe we should send a retract or something transitionOrThrow(State.TERMINATED_APPLICATION_FAILURE); + this.finish();; return; } try { @@ -662,6 +663,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web sendSessionTerminate(Reason.FAILED_APPLICATION); } else { transitionOrThrow(State.TERMINATED_APPLICATION_FAILURE); + this.finish(); } } } @@ -878,8 +880,8 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": ending call while in state PROCEED just means ending the connection"); this.jingleConnectionManager.endSession(id, State.TERMINATED_SUCCESS); this.webRTCWrapper.close(); - this.finish(); transitionOrThrow(State.TERMINATED_SUCCESS); //arguably this wasn't success; but not a real failure either + this.finish(); return; } if (isInitiator() && isInState(State.SESSION_INITIALIZED, State.SESSION_INITIALIZED_PRE_APPROVED)) { @@ -1180,7 +1182,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web return this.state; } - public boolean isTerminated() { + boolean isTerminated() { return TERMINATED.contains(this.state); } From 350fc57d87038f3bbd83552f176b07695ed8a81c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 8 May 2020 17:52:41 +0200 Subject: [PATCH 04/20] properly wrap IPv6 addresses --- src/main/java/eu/siacs/conversations/utils/IP.java | 8 ++++++++ .../conversations/xmpp/jingle/JingleRtpConnection.java | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/utils/IP.java b/src/main/java/eu/siacs/conversations/utils/IP.java index 2b7a3f888..a7182e207 100644 --- a/src/main/java/eu/siacs/conversations/utils/IP.java +++ b/src/main/java/eu/siacs/conversations/utils/IP.java @@ -19,4 +19,12 @@ public class IP { || PATTERN_IPV6_HEXCOMPRESSED.matcher(server).matches()); } + public static String wrapIPv6(final String host) { + if (matches(host)) { + return String.format("[%s]", host); + } else { + return host; + } + } + } diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java index 01840189a..5bb0e7b60 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java @@ -36,6 +36,7 @@ import eu.siacs.conversations.entities.Conversational; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.RtpSessionStatus; import eu.siacs.conversations.services.AppRTCAudioManager; +import eu.siacs.conversations.utils.IP; import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xml.Namespace; import eu.siacs.conversations.xmpp.jingle.stanzas.Group; @@ -1109,9 +1110,8 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": skipping invalid combination of udp/tls in external services"); continue; } - //TODO wrap ipv6 addresses final PeerConnection.IceServer.Builder iceServerBuilder = PeerConnection.IceServer - .builder(String.format("%s:%s:%s?transport=%s", type, host, port, transport)); + .builder(String.format("%s:%s:%s?transport=%s", type, IP.wrapIPv6(host), port, transport)); iceServerBuilder.setTlsCertPolicy(PeerConnection.TlsCertPolicy.TLS_CERT_POLICY_INSECURE_NO_CHECK); if (username != null && password != null) { iceServerBuilder.setUsername(username); From 285c750e69c99a47afd8644221f7fbefb6c17f1d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 8 May 2020 18:36:52 +0200 Subject: [PATCH 05/20] throw IllegalStateException when trying to finish from a non terminal state --- .../xmpp/jingle/JingleRtpConnection.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java index 5bb0e7b60..ecf2aff32 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java @@ -58,6 +58,9 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web ); private static final long BUSY_TIME_OUT = 30; private static final List TERMINATED = Arrays.asList( + State.ACCEPTED, + State.REJECTED, + State.RETRACTED, State.TERMINATED_SUCCESS, State.TERMINATED_DECLINED_OR_BUSY, State.TERMINATED_CONNECTIVITY_ERROR, @@ -642,13 +645,13 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web } try { setupWebRTC(media, iceServers); - } catch (WebRTCWrapper.InitializationException e) { + } catch (final WebRTCWrapper.InitializationException e) { Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": unable to initialize WebRTC"); webRTCWrapper.close(); //todo we haven’t actually initiated the session yet; so sending sessionTerminate makes no sense //todo either we don’t ring ever at all or maybe we should send a retract or something transitionOrThrow(State.TERMINATED_APPLICATION_FAILURE); - this.finish();; + this.finish(); return; } try { @@ -1142,9 +1145,13 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web } private void finish() { - this.cancelRingingTimeout(); - this.webRTCWrapper.verifyClosed(); - this.jingleConnectionManager.finishConnection(this); + if (isTerminated()) { + this.cancelRingingTimeout(); + this.webRTCWrapper.verifyClosed(); + this.jingleConnectionManager.finishConnection(this); + } else { + throw new IllegalStateException(String.format("Unable to call finish from %s", this.state)); + } } private void writeLogMessage(final State state) { From abfa4eae08e3c27fd85b4f0805f7a4d6c7422ff0 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 8 May 2020 19:33:49 +0200 Subject: [PATCH 06/20] remove white space before parsing omemo bundle base64 --- .../eu/siacs/conversations/parser/IqParser.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index ebcdfd8a3..dee740d9f 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -5,6 +5,7 @@ import android.text.TextUtils; import android.util.Log; import android.util.Pair; +import com.google.common.base.CharMatcher; import com.google.common.io.BaseEncoding; import org.whispersystems.libsignal.IdentityKey; @@ -206,7 +207,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { return null; } try { - publicKey = Curve.decodePoint(BaseEncoding.base64().decode(signedPreKeyPublic), 0); + publicKey = Curve.decodePoint(base64decode(signedPreKeyPublic), 0); } catch (final IllegalArgumentException | InvalidKeyException e) { Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX + " : " + "Invalid signedPreKeyPublic in PEP: " + e.getMessage()); } @@ -219,7 +220,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { return null; } try { - return BaseEncoding.base64().decode(signedPreKeySignature); + return base64decode(signedPreKeySignature); } catch (final IllegalArgumentException e) { Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX + " : Invalid base64 in signedPreKeySignature"); return null; @@ -232,7 +233,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { return null; } try { - return new IdentityKey(BaseEncoding.base64().decode(identityKey), 0); + return new IdentityKey(base64decode(identityKey), 0); } catch (final IllegalArgumentException | InvalidKeyException e) { Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX + " : " + "Invalid identityKey in PEP: " + e.getMessage()); return null; @@ -260,10 +261,14 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { Log.d(Config.LOGTAG, AxolotlService.LOGPREFIX + " : " + "Encountered unexpected tag in prekeys list: " + preKeyPublicElement); continue; } + final String preKey = preKeyPublicElement.getContent(); + if (preKey == null) { + continue; + } Integer preKeyId = null; try { preKeyId = Integer.valueOf(preKeyPublicElement.getAttribute("preKeyId")); - final ECPublicKey preKeyPublic = Curve.decodePoint(BaseEncoding.base64().decode(preKeyPublicElement.getContent()), 0); + final ECPublicKey preKeyPublic = Curve.decodePoint(base64decode(preKey), 0); preKeyRecords.put(preKeyId, preKeyPublic); } catch (NumberFormatException e) { Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX + " : " + "could not parse preKeyId from preKey " + preKeyPublicElement.toString()); @@ -274,6 +279,10 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { return preKeyRecords; } + private static byte[] base64decode(String input) { + return BaseEncoding.base64().decode(CharMatcher.whitespace().removeFrom(input)); + } + public Pair verification(final IqPacket packet) { Element item = getItem(packet); Element verification = item != null ? item.findChild("verification", AxolotlService.PEP_PREFIX) : null; From bd0234ba4d71d08142cafbf975db28f5891a5fb1 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 8 May 2020 19:34:20 +0200 Subject: [PATCH 07/20] dismiss incoming call notification on crash. fixes #3701 --- .../services/NotificationService.java | 9 ++++++++ .../conversations/utils/ExceptionHandler.java | 22 +++++++++++-------- .../conversations/utils/ExceptionHelper.java | 9 ++++---- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index 17448fac3..bd3df024a 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -426,6 +426,15 @@ public class NotificationService { cancel(INCOMING_CALL_NOTIFICATION_ID); } + public static void cancelIncomingCallNotification(final Context context) { + final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context); + try { + notificationManager.cancel(INCOMING_CALL_NOTIFICATION_ID); + } catch (RuntimeException e) { + Log.d(Config.LOGTAG, "unable to cancel incoming call notification after crash", e); + } + } + private void pushNow(final Message message) { mXmppConnectionService.updateUnreadCountBadge(); if (!notify(message)) { diff --git a/src/main/java/eu/siacs/conversations/utils/ExceptionHandler.java b/src/main/java/eu/siacs/conversations/utils/ExceptionHandler.java index b8a0fa511..68672156b 100644 --- a/src/main/java/eu/siacs/conversations/utils/ExceptionHandler.java +++ b/src/main/java/eu/siacs/conversations/utils/ExceptionHandler.java @@ -1,31 +1,35 @@ package eu.siacs.conversations.utils; import android.content.Context; +import android.support.annotation.NonNull; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; import java.lang.Thread.UncaughtExceptionHandler; +import eu.siacs.conversations.services.NotificationService; + public class ExceptionHandler implements UncaughtExceptionHandler { - private UncaughtExceptionHandler defaultHandler; - private Context context; + private final UncaughtExceptionHandler defaultHandler; + private final Context context; - public ExceptionHandler(Context context) { + ExceptionHandler(final Context context) { this.context = context; this.defaultHandler = Thread.getDefaultUncaughtExceptionHandler(); } @Override - public void uncaughtException(Thread thread, Throwable ex) { - Writer result = new StringWriter(); - PrintWriter printWriter = new PrintWriter(result); - ex.printStackTrace(printWriter); - String stacktrace = result.toString(); + public void uncaughtException(@NonNull Thread thread, final Throwable throwable) { + NotificationService.cancelIncomingCallNotification(context); + final Writer stringWriter = new StringWriter(); + final PrintWriter printWriter = new PrintWriter(stringWriter); + throwable.printStackTrace(printWriter); + final String stacktrace = stringWriter.toString(); printWriter.close(); ExceptionHelper.writeToStacktraceFile(context, stacktrace); - this.defaultHandler.uncaughtException(thread, ex); + this.defaultHandler.uncaughtException(thread, throwable); } } diff --git a/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java b/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java index e9f3bcb24..ca515e8fa 100644 --- a/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java @@ -1,12 +1,12 @@ package eu.siacs.conversations.utils; -import android.support.v7.app.AlertDialog; import android.content.Context; import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.Signature; import android.preference.PreferenceManager; +import android.support.v7.app.AlertDialog; import android.util.Log; import java.io.BufferedReader; @@ -16,7 +16,6 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.text.SimpleDateFormat; import java.util.Date; -import java.util.List; import java.util.Locale; import eu.siacs.conversations.Config; @@ -33,10 +32,10 @@ public class ExceptionHelper { private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH); public static void init(Context context) { - if (!(Thread.getDefaultUncaughtExceptionHandler() instanceof ExceptionHandler)) { - Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler( - context)); + if (Thread.getDefaultUncaughtExceptionHandler() instanceof ExceptionHandler) { + return; } + Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(context)); } public static boolean checkForCrash(XmppActivity activity) { From 072edc5a62a90f4225d76faf648d4992b4c9a0f2 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 8 May 2020 21:15:54 +0200 Subject: [PATCH 08/20] hide microphone button in video-only calls. fixes #3700 --- .../java/eu/siacs/conversations/ui/RtpSessionActivity.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java index 6b1d64bcf..405865734 100644 --- a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java @@ -580,7 +580,11 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe ); this.binding.inCallActionFarRight.setVisibility(View.GONE); } - updateInCallButtonConfigurationMicrophone(requireRtpConnection().isMicrophoneEnabled()); + if (media.contains(Media.AUDIO)) { + updateInCallButtonConfigurationMicrophone(requireRtpConnection().isMicrophoneEnabled()); + } else { + this.binding.inCallActionLeft.setVisibility(View.GONE); + } } else { this.binding.inCallActionLeft.setVisibility(View.GONE); this.binding.inCallActionRight.setVisibility(View.GONE); From 6daaca496b238cc83e74f6529cb857528d411ef0 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 9 May 2020 09:42:33 +0200 Subject: [PATCH 09/20] externalize time passed utils --- .../ui/ConversationFragment.java | 6 +- .../conversations/ui/RecordingActivity.java | 12 +-- .../conversations/ui/SettingsActivity.java | 4 +- .../ui/adapter/MessageAdapter.java | 6 +- .../conversations/utils/TimeFrameUtils.java | 97 +++++++++++++++++++ .../conversations/utils/TimeframeUtils.java | 75 -------------- 6 files changed, 108 insertions(+), 92 deletions(-) create mode 100644 src/main/java/eu/siacs/conversations/utils/TimeFrameUtils.java delete mode 100644 src/main/java/eu/siacs/conversations/utils/TimeframeUtils.java diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 9bd9ba63e..5bf02e102 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -84,7 +84,6 @@ import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.entities.TransferablePlaceholder; import eu.siacs.conversations.http.HttpDownloadConnection; import eu.siacs.conversations.persistance.FileBackend; -import eu.siacs.conversations.services.AppRTCAudioManager; import eu.siacs.conversations.services.MessageArchiveService; import eu.siacs.conversations.services.QuickConversationsService; import eu.siacs.conversations.services.XmppConnectionService; @@ -112,10 +111,9 @@ import eu.siacs.conversations.utils.GeoHelper; import eu.siacs.conversations.utils.MessageUtils; import eu.siacs.conversations.utils.NickValidityChecker; import eu.siacs.conversations.utils.Patterns; -import eu.siacs.conversations.utils.PermissionUtils; import eu.siacs.conversations.utils.QuickLoader; import eu.siacs.conversations.utils.StylingHelper; -import eu.siacs.conversations.utils.TimeframeUtils; +import eu.siacs.conversations.utils.TimeFrameUtils; import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.xmpp.XmppConnection; import eu.siacs.conversations.xmpp.chatstate.ChatState; @@ -1568,7 +1566,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke if (durations[i] == -1) { labels[i] = getString(R.string.until_further_notice); } else { - labels[i] = TimeframeUtils.resolve(activity, 1000L * durations[i]); + labels[i] = TimeFrameUtils.resolve(activity, 1000L * durations[i]); } } builder.setItems(labels, (dialog, which) -> { diff --git a/src/main/java/eu/siacs/conversations/ui/RecordingActivity.java b/src/main/java/eu/siacs/conversations/ui/RecordingActivity.java index 3cd5e8ed3..e38fb236c 100644 --- a/src/main/java/eu/siacs/conversations/ui/RecordingActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/RecordingActivity.java @@ -29,6 +29,7 @@ import eu.siacs.conversations.R; import eu.siacs.conversations.databinding.ActivityRecordingBinding; import eu.siacs.conversations.persistance.FileBackend; import eu.siacs.conversations.utils.ThemeHelper; +import eu.siacs.conversations.utils.TimeFrameUtils; public class RecordingActivity extends Activity implements View.OnClickListener { @@ -135,7 +136,7 @@ public class RecordingActivity extends Activity implements View.OnClickListener Log.d(Config.LOGTAG, "time out waiting for output file to be written"); } } catch (InterruptedException e) { - Log.d(Config.LOGTAG, "interrupted while waiting for output file to be written" ,e); + Log.d(Config.LOGTAG, "interrupted while waiting for output file to be written", e); } runOnUiThread(() -> { setResult(Activity.RESULT_OK, new Intent().setData(Uri.fromFile(mOutputFile))); @@ -181,14 +182,9 @@ public class RecordingActivity extends Activity implements View.OnClickListener }; mFileObserver.startWatching(); } - - @SuppressLint("SetTextI18n") + private void tick() { - long time = (mStartTime < 0) ? 0 : (SystemClock.elapsedRealtime() - mStartTime); - int minutes = (int) (time / 60000); - int seconds = (int) (time / 1000) % 60; - int milliseconds = (int) (time / 100) % 10; - this.binding.timer.setText(minutes + ":" + (seconds < 10 ? "0" + seconds : seconds) + "." + milliseconds); + this.binding.timer.setText(TimeFrameUtils.formatTimePassed(mStartTime, true)); } @Override diff --git a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java index 3d2b63d04..73c10a6ab 100644 --- a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java @@ -40,7 +40,7 @@ import eu.siacs.conversations.services.MemorizingTrustManager; import eu.siacs.conversations.services.QuickConversationsService; import eu.siacs.conversations.ui.util.StyledAttributes; import eu.siacs.conversations.utils.GeoHelper; -import eu.siacs.conversations.utils.TimeframeUtils; +import eu.siacs.conversations.utils.TimeFrameUtils; import rocks.xmpp.addr.Jid; public class SettingsActivity extends XmppActivity implements @@ -140,7 +140,7 @@ public class SettingsActivity extends XmppActivity implements if (choices[i] == 0) { entries[i] = getString(R.string.never); } else { - entries[i] = TimeframeUtils.resolve(this, 1000L * choices[i]); + entries[i] = TimeFrameUtils.resolve(this, 1000L * choices[i]); } } automaticMessageDeletionList.setEntries(entries); diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index d11d122d4..91162fd40 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -73,7 +73,7 @@ import eu.siacs.conversations.utils.Emoticons; import eu.siacs.conversations.utils.GeoHelper; import eu.siacs.conversations.utils.MessageUtils; import eu.siacs.conversations.utils.StylingHelper; -import eu.siacs.conversations.utils.TimeframeUtils; +import eu.siacs.conversations.utils.TimeFrameUtils; import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.xmpp.mam.MamReference; import rocks.xmpp.addr.Jid; @@ -703,7 +703,7 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie final long duration = rtpSessionStatus.duration; if (received) { if (duration > 0) { - viewHolder.status_message.setText(activity.getString(R.string.incoming_call_duration, TimeframeUtils.resolve(activity, duration))); + viewHolder.status_message.setText(activity.getString(R.string.incoming_call_duration, TimeFrameUtils.resolve(activity, duration))); } else if (rtpSessionStatus.successful) { viewHolder.status_message.setText(R.string.incoming_call); } else { @@ -711,7 +711,7 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie } } else { if (duration > 0) { - viewHolder.status_message.setText(activity.getString(R.string.outgoing_call_duration, TimeframeUtils.resolve(activity, duration))); + viewHolder.status_message.setText(activity.getString(R.string.outgoing_call_duration, TimeFrameUtils.resolve(activity, duration))); } else { viewHolder.status_message.setText(R.string.outgoing_call); } diff --git a/src/main/java/eu/siacs/conversations/utils/TimeFrameUtils.java b/src/main/java/eu/siacs/conversations/utils/TimeFrameUtils.java new file mode 100644 index 000000000..6ad1325be --- /dev/null +++ b/src/main/java/eu/siacs/conversations/utils/TimeFrameUtils.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2018, Daniel Gultsch All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package eu.siacs.conversations.utils; + +import android.content.Context; +import android.os.SystemClock; +import android.support.annotation.PluralsRes; + +import java.util.Locale; + +import eu.siacs.conversations.R; + +public class TimeFrameUtils { + + private static final TimeFrame[] TIME_FRAMES; + + static { + TIME_FRAMES = new TimeFrame[]{ + new TimeFrame(1000L, R.plurals.seconds), + new TimeFrame(60L * 1000, R.plurals.minutes), + new TimeFrame(60L * 60 * 1000, R.plurals.hours), + new TimeFrame(24L * 60 * 60 * 1000, R.plurals.days), + new TimeFrame(7L * 24 * 60 * 60 * 1000, R.plurals.weeks), + new TimeFrame(30L * 24 * 60 * 60 * 1000, R.plurals.months), + }; + } + + public static String resolve(Context context, long timeFrame) { + for (int i = TIME_FRAMES.length - 1; i >= 0; --i) { + long duration = TIME_FRAMES[i].duration; + long threshold = i > 0 ? (TIME_FRAMES[i - 1].duration / 2) : 0; + if (timeFrame >= duration - threshold) { + int count = (int) (timeFrame / duration + ((timeFrame % duration) > (duration / 2) ? 1 : 0)); + return context.getResources().getQuantityString(TIME_FRAMES[i].name, count, count); + } + } + return context.getResources().getQuantityString(TIME_FRAMES[0].name, 0, 0); + } + + public static String formatTimePassed(final long since, final boolean withMilliseconds) { + return formatTimePassed(since, SystemClock.elapsedRealtime(), withMilliseconds); + } + + public static String formatTimePassed(final long since, final long to, final boolean withMilliseconds) { + final long passed = (since < 0) ? 0 : (to - since); + final int hours = (int) (passed / 3600000); + final int minutes = (int) (passed / 60000) % 60; + final int seconds = (int) (passed / 1000) % 60; + final int milliseconds = (int) (passed / 100) % 10; + if (hours > 0) { + return String.format(Locale.ENGLISH, "%d:%02d:%02d", hours, minutes, seconds); + } else if (withMilliseconds) { + return String.format(Locale.ENGLISH, "%d:%02d.%d", minutes, seconds, milliseconds); + } else { + return String.format(Locale.ENGLISH, "%d:%02d", minutes, seconds); + } + } + + + private static class TimeFrame { + final long duration; + public final int name; + + private TimeFrame(long duration, @PluralsRes int name) { + this.duration = duration; + this.name = name; + } + } + +} \ No newline at end of file diff --git a/src/main/java/eu/siacs/conversations/utils/TimeframeUtils.java b/src/main/java/eu/siacs/conversations/utils/TimeframeUtils.java deleted file mode 100644 index 33b43c5c3..000000000 --- a/src/main/java/eu/siacs/conversations/utils/TimeframeUtils.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2018, Daniel Gultsch All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors - * may be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package eu.siacs.conversations.utils; - -import android.content.Context; -import android.support.annotation.PluralsRes; - -import eu.siacs.conversations.R; - -public class TimeframeUtils { - - private static final Timeframe[] TIMEFRAMES; - - static { - TIMEFRAMES = new Timeframe[]{ - new Timeframe(1000L, R.plurals.seconds), - new Timeframe(60L * 1000, R.plurals.minutes), - new Timeframe(60L * 60 * 1000, R.plurals.hours), - new Timeframe(24L * 60 * 60 * 1000, R.plurals.days), - new Timeframe(7L * 24 * 60 * 60 * 1000, R.plurals.weeks), - new Timeframe(30L * 24 * 60 * 60 * 1000, R.plurals.months), - }; - } - - public static String resolve(Context context, long timeframe) { - for(int i = TIMEFRAMES.length -1 ; i >= 0; --i) { - long duration = TIMEFRAMES[i].duration; - long threshold = i > 0 ? (TIMEFRAMES[i-1].duration / 2) : 0; - if (timeframe >= duration - threshold) { - int count = (int) (timeframe / duration + ((timeframe%duration)>(duration/2)?1:0)); - return context.getResources().getQuantityString(TIMEFRAMES[i].name,count,count); - } - } - return context.getResources().getQuantityString(TIMEFRAMES[0].name,0,0); - } - - - private static class Timeframe { - public final long duration; - public final int name; - - private Timeframe(long duration, @PluralsRes int name) { - this.duration = duration; - this.name = name; - } - } - -} \ No newline at end of file From 92fc22b313eb10f1b88749f42d6ef64c47aaac67 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 9 May 2020 11:14:39 +0200 Subject: [PATCH 10/20] show call duration in audio calls. fixes #3708 --- .../conversations/ui/RecordingActivity.java | 2 +- .../conversations/ui/RtpSessionActivity.java | 43 ++++++++++++++++++- .../xmpp/jingle/JingleRtpConnection.java | 12 ++++++ src/main/res/layout/activity_rtp_session.xml | 18 +++++--- src/main/res/values/styles.xml | 5 +++ 5 files changed, 72 insertions(+), 8 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/RecordingActivity.java b/src/main/java/eu/siacs/conversations/ui/RecordingActivity.java index e38fb236c..bcd564788 100644 --- a/src/main/java/eu/siacs/conversations/ui/RecordingActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/RecordingActivity.java @@ -182,7 +182,7 @@ public class RecordingActivity extends Activity implements View.OnClickListener }; mFileObserver.startWatching(); } - + private void tick() { this.binding.timer.setText(TimeFrameUtils.formatTimePassed(mStartTime, true)); } diff --git a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java index 405865734..2a1730c94 100644 --- a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java @@ -9,6 +9,7 @@ import android.content.pm.PackageManager; import android.databinding.DataBindingUtil; import android.os.Build; import android.os.Bundle; +import android.os.Handler; import android.os.PowerManager; import android.os.SystemClock; import android.support.annotation.NonNull; @@ -27,7 +28,6 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; import org.checkerframework.checker.nullness.compatqual.NullableDecl; import org.webrtc.SurfaceViewRenderer; @@ -49,6 +49,7 @@ import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.ui.util.AvatarWorkerTask; import eu.siacs.conversations.ui.util.MainThreadExecutor; import eu.siacs.conversations.utils.PermissionUtils; +import eu.siacs.conversations.utils.TimeFrameUtils; import eu.siacs.conversations.xmpp.jingle.AbstractJingleConnection; import eu.siacs.conversations.xmpp.jingle.JingleRtpConnection; import eu.siacs.conversations.xmpp.jingle.Media; @@ -67,6 +68,9 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe public static final String ACTION_ACCEPT_CALL = "action_accept_call"; public static final String ACTION_MAKE_VOICE_CALL = "action_make_voice_call"; public static final String ACTION_MAKE_VIDEO_CALL = "action_make_video_call"; + + private static final int CALL_DURATION_UPDATE_INTERVAL = 333; + private static final List END_CARD = Arrays.asList( RtpEndUserState.APPLICATION_ERROR, RtpEndUserState.DECLINED_OR_BUSY, @@ -79,6 +83,15 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe private ActivityRtpSessionBinding binding; private PowerManager.WakeLock mProximityWakeLock; + private Handler mHandler = new Handler(); + private Runnable mTickExecutor = new Runnable() { + @Override + public void run() { + updateCallDuration(); + mHandler.postDelayed(mTickExecutor, CALL_DURATION_UPDATE_INTERVAL); + } + }; + private static Set actionToMedia(final String action) { if (ACTION_MAKE_VIDEO_CALL.equals(action)) { return ImmutableSet.of(Media.AUDIO, Media.VIDEO); @@ -308,8 +321,15 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe } } + @Override + public void onStart() { + super.onStart(); + mHandler.postDelayed(mTickExecutor, CALL_DURATION_UPDATE_INTERVAL); + } + @Override public void onStop() { + mHandler.removeCallbacks(mTickExecutor); binding.remoteVideo.release(); binding.localVideo.release(); final WeakReference weakReference = this.rtpConnectionReference; @@ -655,7 +675,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe @Override public void onFailure(@NonNull final Throwable throwable) { - Log.d(Config.LOGTAG,"could not switch camera", Throwables.getRootCause(throwable)); + Log.d(Config.LOGTAG, "could not switch camera", Throwables.getRootCause(throwable)); Toast.makeText(RtpSessionActivity.this, R.string.could_not_switch_camera, Toast.LENGTH_LONG).show(); } }, MainThreadExecutor.getInstance()); @@ -684,6 +704,25 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe this.binding.inCallActionLeft.setVisibility(View.VISIBLE); } + private void updateCallDuration() { + Log.d(Config.LOGTAG,"updateCallDuration()"); + final JingleRtpConnection connection = this.rtpConnectionReference != null ? this.rtpConnectionReference.get() : null; + if (connection == null || connection.getMedia().contains(Media.VIDEO)) { + Log.d(Config.LOGTAG,"rtpConnection was null or contained video"); + this.binding.duration.setVisibility(View.GONE); + return; + } + final long rtpConnectionStarted = connection.getRtpConnectionStarted(); + final long rtpConnectionEnded = connection.getRtpConnectionEnded(); + if (rtpConnectionStarted != 0) { + final long ended = rtpConnectionEnded == 0 ? SystemClock.elapsedRealtime() : rtpConnectionEnded; + this.binding.duration.setText(TimeFrameUtils.formatTimePassed(rtpConnectionStarted, ended, false)); + this.binding.duration.setVisibility(View.VISIBLE); + } else { + this.binding.duration.setVisibility(View.GONE); + } + } + private void updateVideoViews(final RtpEndUserState state) { if (END_CARD.contains(state) || state == RtpEndUserState.ENDING_CALL) { binding.localVideo.setVisibility(View.GONE); diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java index ecf2aff32..af94cbd0b 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java @@ -125,6 +125,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web private RtpContentMap initiatorRtpContentMap; private RtpContentMap responderRtpContentMap; private long rtpConnectionStarted = 0; //time of 'connected' + private long rtpConnectionEnded = 0; private ScheduledFuture ringingTimeoutFuture; JingleRtpConnection(JingleConnectionManager jingleConnectionManager, Id id, Jid initiator) { @@ -1006,6 +1007,9 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web if (newState == PeerConnection.PeerConnectionState.CONNECTED && this.rtpConnectionStarted == 0) { this.rtpConnectionStarted = SystemClock.elapsedRealtime(); } + if (newState == PeerConnection.PeerConnectionState.CLOSED && this.rtpConnectionEnded == 0) { + this.rtpConnectionEnded = SystemClock.elapsedRealtime(); + } //TODO 'DISCONNECTED' might be an opportunity to renew the offer and send a transport-replace //TODO exact syntax is yet to be determined but transport-replace sounds like the most reasonable //as there is no content-replace @@ -1031,6 +1035,14 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web } } + public long getRtpConnectionStarted() { + return this.rtpConnectionStarted; + } + + public long getRtpConnectionEnded() { + return this.rtpConnectionEnded; + } + public AppRTCAudioManager getAudioManager() { return webRTCWrapper.getAudioManager(); } diff --git a/src/main/res/layout/activity_rtp_session.xml b/src/main/res/layout/activity_rtp_session.xml index 13e0e5d2e..cc4ea716e 100644 --- a/src/main/res/layout/activity_rtp_session.xml +++ b/src/main/res/layout/activity_rtp_session.xml @@ -62,21 +62,29 @@ - + android:layout_below="@id/app_bar_layout"> + + - + monospace + + From 04764eb989497c44d529fe8af9952ce42db8deec Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 9 May 2020 11:41:45 +0200 Subject: [PATCH 11/20] fix Quicksy build flavor --- .../java/eu/siacs/conversations/ui/VerifyActivity.java | 6 +++--- .../eu/siacs/conversations/ui/util/ApiDialogHelper.java | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/quicksy/java/eu/siacs/conversations/ui/VerifyActivity.java b/src/quicksy/java/eu/siacs/conversations/ui/VerifyActivity.java index f6be2d91f..7dc59845e 100644 --- a/src/quicksy/java/eu/siacs/conversations/ui/VerifyActivity.java +++ b/src/quicksy/java/eu/siacs/conversations/ui/VerifyActivity.java @@ -25,7 +25,7 @@ import eu.siacs.conversations.ui.util.ApiDialogHelper; import eu.siacs.conversations.ui.util.PinEntryWrapper; import eu.siacs.conversations.utils.AccountUtils; import eu.siacs.conversations.utils.PhoneNumberUtilWrapper; -import eu.siacs.conversations.utils.TimeframeUtils; +import eu.siacs.conversations.utils.TimeFrameUtils; import io.michaelrocks.libphonenumber.android.NumberParseException; import static android.content.ClipDescription.MIMETYPE_TEXT_PLAIN; @@ -67,7 +67,7 @@ public class VerifyActivity extends XmppActivity implements ClipboardManager.OnP long remaining = retrySmsAfter - SystemClock.elapsedRealtime(); if (remaining >= 0) { binding.resendSms.setEnabled(false); - binding.resendSms.setText(getString(R.string.resend_sms_in, TimeframeUtils.resolve(VerifyActivity.this, remaining))); + binding.resendSms.setText(getString(R.string.resend_sms_in, TimeFrameUtils.resolve(VerifyActivity.this, remaining))); return true; } } @@ -81,7 +81,7 @@ public class VerifyActivity extends XmppActivity implements ClipboardManager.OnP long remaining = retryVerificationAfter - SystemClock.elapsedRealtime(); if (remaining >= 0) { binding.next.setEnabled(false); - binding.next.setText(getString(R.string.wait_x, TimeframeUtils.resolve(VerifyActivity.this, remaining))); + binding.next.setText(getString(R.string.wait_x, TimeFrameUtils.resolve(VerifyActivity.this, remaining))); return true; } } diff --git a/src/quicksy/java/eu/siacs/conversations/ui/util/ApiDialogHelper.java b/src/quicksy/java/eu/siacs/conversations/ui/util/ApiDialogHelper.java index 995fe3fca..9bd7b2514 100644 --- a/src/quicksy/java/eu/siacs/conversations/ui/util/ApiDialogHelper.java +++ b/src/quicksy/java/eu/siacs/conversations/ui/util/ApiDialogHelper.java @@ -11,7 +11,7 @@ import android.support.annotation.StringRes; import eu.siacs.conversations.R; import eu.siacs.conversations.services.QuickConversationsService; -import eu.siacs.conversations.utils.TimeframeUtils; +import eu.siacs.conversations.utils.TimeFrameUtils; public class ApiDialogHelper { @@ -79,7 +79,7 @@ public class ApiDialogHelper { public static Dialog createRateLimited(final Context context, final long timestamp) { final AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle(R.string.rate_limited); - builder.setMessage(context.getString(R.string.try_again_in_x, TimeframeUtils.resolve(context, timestamp - SystemClock.elapsedRealtime()))); + builder.setMessage(context.getString(R.string.try_again_in_x, TimeFrameUtils.resolve(context, timestamp - SystemClock.elapsedRealtime()))); builder.setPositiveButton(R.string.ok, null); return builder.create(); } From 1d9b9e3bf025f759fa0c2544c5d343f9e2a55e2b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 9 May 2020 11:47:37 +0200 Subject: [PATCH 12/20] pulled translations from transifex --- src/main/res/values-es/strings.xml | 32 ++++++++++++++++++++++++++ src/main/res/values-zh-rCN/strings.xml | 8 +++---- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/main/res/values-es/strings.xml b/src/main/res/values-es/strings.xml index 58cae4f61..b62109602 100644 --- a/src/main/res/values-es/strings.xml +++ b/src/main/res/values-es/strings.xml @@ -269,8 +269,10 @@ Habilitar Esta conversación en grupo requiere contraseña Introduce la contraseña + Por favor, solicita la actualización de presencia a tu contacto primero.\n\nEsto se usará para determinar qué aplicación de mensajería está usando tu contacto. Solicitar ahora Ignorar + Aviso: Si envías esto sin actualización de presencia mutua con tu contacto se podrían producir problemas inesperados.\n\nVe a “Detalles del contacto” para verificar las actualizaciones de presencia. Seguridad Corrección de mensaje Permitir a tus contactos editar mensajes previamente enviados @@ -284,6 +286,8 @@ Las notificaciones serán silenciadas durante el horario de silencio Otros Sincronizar marcadores + Unirse a conversaciones en grupo automáticamente si el marcador así lo indica + Huella digital OMEMO copiada al portapapeles Tu entrada a esta conversación en grupo ha sido prohibida Esta conversación en grupo es solo para miembros Limitación de recursos @@ -329,17 +333,27 @@ archivo Abrir %s Enviando (%1$d%% completado) + Preparando para compartir archivo %s ofrecido para descarga Cancelar transferencia + no se ha podido compartir el archivo transferencia del fichero cancelada + Archivo eliminado + No se ha encontrado ninguna aplicación para abrir el archivo + No se ha encontrado aplicación para abrir el link + No se ha encontrado aplicación para ver el contacto Etiquetas dinámicas Mostrar información en forma de etiquetas debajo de los contactos Habilitar notificaciones No se ha encontrado el servidor de la conversación en grupo + No se ha podido crear la conversación en grupo Imagen de perfil Copiar huella digital OMEMO al portapapeles Regenerar clave OMEMO Limpiar dispositivos + ¿Estás seguro de que quieres limpiar todos los otros dispositivos del anuncio OMEMO? La próxima vez que tus dispositivos conecten, tendrán que volver a anunciarse, pero podrían no recibir los mensajes enviados mientras tanto. + No hay claves disponibles para este contacto.\nNo se ha podido obtener nuevas claves del servidor. ¿Es posible que haya algún problema con el servidor de tu contacto? + No hay claves disponibles para este contacto.\nAsegúrate que tenéis actualizaciones de presencia mutua. Se produjo un error Buscando historial en el servidor No hay más historial en el servidor @@ -349,6 +363,7 @@ Cambiar contraseña Contraseña actual Nueva contraseña + La contraseña no puede ser vacía Habilitar todas las cuentas Deshabilitar todas las cuentas Realizar acción con @@ -368,6 +383,7 @@ No se puede cambiar la afiliación de %s Prohibir entrada en la conversación Prohibir entrada al canal + Estás intentando eliminar a %s de un canal público. La única manera de hacerlo es prohibir su entrada para siempre. Prohibir ahora No se puede cambiar el rol de %s Configuración de conversación en grupo privada @@ -406,6 +422,7 @@ Permitir a tus contactos saber cuando estás escribiendo un mensaje Enviar ubicación Mostrar ubicación + No se ha encontrado ninguna aplicación para mostrar la ubicación Ubicación Conversación cerrada Dejar la conversación en grupo @@ -422,6 +439,7 @@ %d certificado eliminado %d certificados eliminados
+ Cambiar el botón de “Enviar” por el botón de acción rápida Acción rápida Ninguna Usada más recientemente @@ -429,6 +447,7 @@ Buscar contactos Buscar marcadores Enviar mensaje privado + %1$s ha dejado la conversación Usuario Usuario Esto no es un usuario válido @@ -438,6 +457,7 @@ Falló la descarga: No se puede escribir el fichero Red Tor no disponible. Fallo de enlace + El servidor no es responsable de este dominio Error Disponibilidad Ausente con pantalla apagada @@ -450,11 +470,15 @@ Mostrar el hostname y el puerto cuando se está creando una cuenta xmpp.ejemplo.com Añadir cuenta con certificado + No se ha podido leer el certificado Dejar vacío para autenticar certificado w/ Preferencias de archivado Preferencias de archivado en servidor Buscando preferencias de archivado. Por favor, espera... + No se ha podido conseguir las preferencias de archivado + Captcha requerido Introduce el texto de la imagen de arriba + El certificado no es de confianza La dirección XMPP no coincide con el certificado Renovar certificado ¡Error buscando clave OMEMO! @@ -465,6 +489,7 @@ Todas las conexiones se realizan a través de la red TOR. Requiere Orbot Hostname Puerto + Server- or .onion-address Éste no es un número de puerto válido Éste no es un hostame válido %1$d de %2$d cuentas conectadas @@ -473,7 +498,14 @@ %d mensajes
Cargar más mensajes + Archivo compartido con %s + Imagen compartida con %s + Imágenes compartidas con %s + Texto compartido con %s + Permitir a Conversations acceder al almacenamiento externo + Permitir a Conversations acceder a la cámara Sincronizar contactos + Conversations quiere permisos para acceder a tus contactos y cruzarlos con tu lista de contactos de XMPP para mostrar sus nombres completos y sus fotos de perfil.\n\Solo leerá tus contactos y los cruzará localmente sin subirlos a tu servidor.
No guardaremos una copia de estos números de teléfono.\n\nPara más información puedes leer nuestra política de privacidad.

El sistema te preguntará ahora para conceder los permisos de acceso a tus contactos del móvil.]]>
Notificar para todos los mensajes Notificar solo cuando eres mencionado diff --git a/src/main/res/values-zh-rCN/strings.xml b/src/main/res/values-zh-rCN/strings.xml index 770cab0b2..645f0e065 100644 --- a/src/main/res/values-zh-rCN/strings.xml +++ b/src/main/res/values-zh-rCN/strings.xml @@ -138,7 +138,7 @@ 接收在线状态更新 请求在线状态更新 选择图片 - 拍照 + 拍摄图片 预先同意订阅请求 您选择的文件不是图像 无法转换图片 @@ -177,7 +177,7 @@ 启用账户 确定? 如果您删除帐户,您的所有聊天记录将会丢失 - 录音 + 录制音频 XMPP地址 拦截XMPP地址 username@example.com @@ -420,7 +420,7 @@ %s已停止输入 输入通知 让对方知道你正在输入 - 位置 + 发送位置 显示位置 无法找到显示位置的应用 位置 @@ -661,7 +661,7 @@ 包含主机名的服务器证书被认为是已验证的 证书不包含XMPP地址 一部分 - 录像 + 录制视频 复制 消息已被复制 消息 From f4247379bd6c30ea6ee610b2d9f3f8afa68140cc Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 9 May 2020 19:48:54 +0200 Subject: [PATCH 13/20] catch UnsatisfiedLinkError when trying to init libwebrtc. fixes #3707 --- .../conversations/ui/RtpSessionActivity.java | 2 -- .../xmpp/jingle/JingleConnectionManager.java | 1 + .../xmpp/jingle/JingleRtpConnection.java | 1 + .../xmpp/jingle/WebRTCWrapper.java | 19 ++++++++++++++----- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java index 2a1730c94..b4ee00ca7 100644 --- a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java @@ -705,10 +705,8 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe } private void updateCallDuration() { - Log.d(Config.LOGTAG,"updateCallDuration()"); final JingleRtpConnection connection = this.rtpConnectionReference != null ? this.rtpConnectionReference.get() : null; if (connection == null || connection.getMedia().contains(Media.VIDEO)) { - Log.d(Config.LOGTAG,"rtpConnection was null or contained video"); this.binding.duration.setVisibility(View.GONE); return; } diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java index 1139e992c..e4abcd27e 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java @@ -262,6 +262,7 @@ public class JingleConnectionManager extends AbstractConnectionManager { rtpConnection.deliveryMessage(from, message, serverMsgId, timestamp); } else { Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": no rtp session proposal found for " + from + " to deliver proceed"); + //TODO return error message "item-not-found" } } } else if ("reject".equals(message.getName())) { diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java index af94cbd0b..3e66a219f 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java @@ -486,6 +486,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web } void deliverFailedProceed() { + //TODO do we want a special State.ITEM_NOT_FOUND to track retracted calls during network outages Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": receive message error for proceed message"); if (transition(State.TERMINATED_CONNECTIVITY_ERROR)) { webRTCWrapper.close(); diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/WebRTCWrapper.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/WebRTCWrapper.java index 99edf2853..96c98181a 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/WebRTCWrapper.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/WebRTCWrapper.java @@ -8,6 +8,7 @@ import android.util.Log; import com.google.common.base.Optional; import com.google.common.base.Preconditions; +import com.google.common.base.Throwables; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.util.concurrent.Futures; @@ -164,10 +165,14 @@ public class WebRTCWrapper { this.eventCallback = eventCallback; } - public void setup(final Context context, final AppRTCAudioManager.SpeakerPhonePreference speakerPhonePreference) { - PeerConnectionFactory.initialize( - PeerConnectionFactory.InitializationOptions.builder(context).createInitializationOptions() - ); + public void setup(final Context context, final AppRTCAudioManager.SpeakerPhonePreference speakerPhonePreference) throws InitializationException { + try { + PeerConnectionFactory.initialize( + PeerConnectionFactory.InitializationOptions.builder(context).createInitializationOptions() + ); + } catch (final UnsatisfiedLinkError e) { + throw new InitializationException(e); + } this.eglBase = EglBase.create(); this.context = context; mainHandler.post(() -> { @@ -555,7 +560,11 @@ public class WebRTCWrapper { static class InitializationException extends Exception { - private InitializationException(String message) { + private InitializationException(final Throwable throwable) { + super(throwable); + } + + private InitializationException(final String message) { super(message); } } From 526e9eab61b0ff87c438b7926f32b7cb77d482cc Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 9 May 2020 21:09:56 +0200 Subject: [PATCH 14/20] rename locating devices to discovering devices. closes #3699 --- src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index fa6a72d0b..8ec0be198 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -900,7 +900,7 @@ Ending call Answer Dismiss - Locating devices + Discovering devices Ringing Busy Could not connect call From 9b8b4f17913721eed442153749c1fcbfae0c2110 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 9 May 2020 21:10:35 +0200 Subject: [PATCH 15/20] move call icon to left. fixes #3709 --- src/main/res/menu/fragment_conversation.xml | 46 ++++++++++----------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/main/res/menu/fragment_conversation.xml b/src/main/res/menu/fragment_conversation.xml index 77306486a..91b965284 100644 --- a/src/main/res/menu/fragment_conversation.xml +++ b/src/main/res/menu/fragment_conversation.xml @@ -1,6 +1,29 @@ + + + + + + + - - - - - - - Date: Sat, 9 May 2020 21:35:21 +0200 Subject: [PATCH 16/20] introduce extra RTP state to handle going from sending proceed to receiving retract --- .../conversations/parser/MessageParser.java | 2 +- .../conversations/ui/RtpSessionActivity.java | 3 ++- .../xmpp/jingle/AbstractJingleConnection.java | 1 + .../xmpp/jingle/JingleConnectionManager.java | 20 +++++++++++++++---- .../xmpp/jingle/JingleRtpConnection.java | 12 ++++++++--- 5 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 8d11499d2..1019a708a 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -843,7 +843,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece if (serverMsgId == null) { serverMsgId = extractStanzaId(account, packet); } - mXmppConnectionService.getJingleConnectionManager().deliverMessage(account, packet.getTo(), packet.getFrom(), child, serverMsgId, timestamp); + mXmppConnectionService.getJingleConnectionManager().deliverMessage(account, packet.getTo(), packet.getFrom(), child, remoteMsgId, serverMsgId, timestamp); } else if (query.isCatchup()) { final String sessionId = child.getAttribute("id"); if (sessionId == null) { diff --git a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java index b4ee00ca7..56b622a92 100644 --- a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java @@ -74,7 +74,8 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe private static final List END_CARD = Arrays.asList( RtpEndUserState.APPLICATION_ERROR, RtpEndUserState.DECLINED_OR_BUSY, - RtpEndUserState.CONNECTIVITY_ERROR + RtpEndUserState.CONNECTIVITY_ERROR, + RtpEndUserState.RETRACTED ); private static final String PROXIMITY_WAKE_LOCK_TAG = "conversations:in-rtp-session"; private static final int REQUEST_ACCEPT_CALL = 0x1111; diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/AbstractJingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/AbstractJingleConnection.java index 99da9fa18..4b1fd5a36 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/AbstractJingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/AbstractJingleConnection.java @@ -113,6 +113,7 @@ public abstract class AbstractJingleConnection { PROCEED, REJECTED, RETRACTED, + RETRACTED_RACED, //used when receiving a retract after we already asked to proceed SESSION_INITIALIZED, //equal to 'PENDING' SESSION_INITIALIZED_PRE_APPROVED, SESSION_ACCEPTED, //equal to 'ACTIVE' diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java index e4abcd27e..682d9bc9a 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java @@ -154,7 +154,7 @@ public class JingleConnectionManager extends AbstractConnectionManager { account.getXmppConnection().sendIqPacket(response, null); } - public void deliverMessage(final Account account, final Jid to, final Jid from, final Element message, String serverMsgId, long timestamp) { + public void deliverMessage(final Account account, final Jid to, final Jid from, final Element message, String remoteMsgId, String serverMsgId, long timestamp) { Preconditions.checkArgument(Namespace.JINGLE_MESSAGE.equals(message.getNamespace())); final String sessionId = message.getAttribute("id"); if (sessionId == null) { @@ -174,6 +174,7 @@ public class JingleConnectionManager extends AbstractConnectionManager { return; } final boolean fromSelf = from.asBareJid().equals(account.getJid().asBareJid()); + final boolean addressedDirectly = to != null && to.equals(account.getJid()); final AbstractJingleConnection.Id id; if (fromSelf) { if (to != null && to.isFullJid()) { @@ -250,7 +251,7 @@ public class JingleConnectionManager extends AbstractConnectionManager { } else { Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": unable to react to proposed session with " + rtpDescriptions.size() + " rtp descriptions of " + descriptions.size() + " total descriptions"); } - } else if ("proceed".equals(message.getName())) { + } else if (addressedDirectly && "proceed".equals(message.getName())) { synchronized (rtpSessionProposals) { final RtpSessionProposal proposal = getRtpSessionProposal(account, from.asBareJid(), sessionId); if (proposal != null) { @@ -262,10 +263,21 @@ public class JingleConnectionManager extends AbstractConnectionManager { rtpConnection.deliveryMessage(from, message, serverMsgId, timestamp); } else { Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": no rtp session proposal found for " + from + " to deliver proceed"); - //TODO return error message "item-not-found" + if (remoteMsgId == null) { + return; + } + final MessagePacket errorMessage = new MessagePacket(); + errorMessage.setTo(from); + errorMessage.setId(remoteMsgId); + errorMessage.setType(MessagePacket.TYPE_ERROR); + final Element error = errorMessage.addChild("error"); + error.setAttribute("code", "404"); + error.setAttribute("type", "cancel"); + error.addChild("item-not-found", "urn:ietf:params:xml:ns:xmpp-stanzas"); + mXmppConnectionService.sendMessagePacket(account, errorMessage); } } - } else if ("reject".equals(message.getName())) { + } else if (addressedDirectly && "reject".equals(message.getName())) { final RtpSessionProposal proposal = new RtpSessionProposal(account, from.asBareJid(), sessionId); synchronized (rtpSessionProposals) { if (rtpSessionProposals.remove(proposal) != null) { diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java index 3e66a219f..97de5b3c1 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java @@ -61,6 +61,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web State.ACCEPTED, State.REJECTED, State.RETRACTED, + State.RETRACTED_RACED, State.TERMINATED_SUCCESS, State.TERMINATED_DECLINED_OR_BUSY, State.TERMINATED_CONNECTIVITY_ERROR, @@ -86,6 +87,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web State.TERMINATED_CONNECTIVITY_ERROR //only used when the xmpp connection rebinds )); transitionBuilder.put(State.PROCEED, ImmutableList.of( + State.RETRACTED_RACED, State.SESSION_INITIALIZED_PRE_APPROVED, State.TERMINATED_SUCCESS, State.TERMINATED_APPLICATION_FAILURE, @@ -486,7 +488,6 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web } void deliverFailedProceed() { - //TODO do we want a special State.ITEM_NOT_FOUND to track retracted calls during network outages Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": receive message error for proceed message"); if (transition(State.TERMINATED_CONNECTIVITY_ERROR)) { webRTCWrapper.close(); @@ -617,14 +618,17 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web private void receiveRetract(final Jid from, final String serverMsgId, final long timestamp) { if (from.equals(id.with)) { - if (transition(State.RETRACTED)) { + final State target = this.state == State.PROCEED ? State.RETRACTED_RACED : State.RETRACTED; + if (transition(target)) { xmppConnectionService.getNotificationService().cancelIncomingCallNotification(); Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": session with " + id.with + " has been retracted (serverMsgId=" + serverMsgId + ")"); if (serverMsgId != null) { this.message.setServerMsgId(serverMsgId); } this.message.setTime(timestamp); - this.message.markUnread(); + if (target == State.RETRACTED) { + this.message.markUnread(); + } writeLogMessageMissed(); finish(); } else { @@ -811,6 +815,8 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web case RETRACTED: case TERMINATED_CANCEL_OR_TIMEOUT: return RtpEndUserState.ENDED; + case RETRACTED_RACED: + return RtpEndUserState.RETRACTED; case TERMINATED_CONNECTIVITY_ERROR: return RtpEndUserState.CONNECTIVITY_ERROR; case TERMINATED_APPLICATION_FAILURE: From 4d3d3a703871be4fe78a9bcdfdf954c9d7aa375b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 10 May 2020 14:09:16 +0200 Subject: [PATCH 17/20] tie breaking racing jingle message proposals. fixes #3698 --- .../xmpp/jingle/JingleConnectionManager.java | 78 +++++++++++++++++-- .../xmpp/jingle/JingleRtpConnection.java | 7 +- 2 files changed, 74 insertions(+), 11 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java index 682d9bc9a..0de9f8606 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java @@ -9,6 +9,7 @@ import com.google.common.base.Preconditions; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.common.collect.Collections2; +import com.google.common.collect.ComparisonChain; import com.google.common.collect.ImmutableSet; import java.lang.ref.WeakReference; @@ -132,6 +133,40 @@ public class JingleConnectionManager extends AbstractConnectionManager { } } + public Optional findMatchingSessionProposal(final Account account, final Jid with, final Set media) { + synchronized (this.rtpSessionProposals) { + for (Map.Entry entry : this.rtpSessionProposals.entrySet()) { + final RtpSessionProposal proposal = entry.getKey(); + final DeviceDiscoveryState state = entry.getValue(); + final boolean openProposal = state == DeviceDiscoveryState.DISCOVERED || state == DeviceDiscoveryState.SEARCHING; + if (openProposal + && proposal.account == account + && proposal.with.equals(with.asBareJid()) + && proposal.media.equals(media)) { + return Optional.of(proposal); + } + } + } + return Optional.absent(); + } + + private boolean hasMatchingRtpSession(final Account account, final Jid with, final Set media) { + for (AbstractJingleConnection connection : this.connections.values()) { + if (connection instanceof JingleRtpConnection) { + final JingleRtpConnection rtpConnection = (JingleRtpConnection) connection; + if (rtpConnection.isTerminated()) { + continue; + } + if (rtpConnection.getId().account == account + && rtpConnection.getId().with.asBareJid().equals(with.asBareJid()) + && rtpConnection.getMedia().equals(media)) { + return true; + } + } + } + return false; + } + private boolean isWithStrangerAndStrangerNotificationsAreOff(final Account account, Jid with) { final boolean notifyForStrangers = mXmppConnectionService.getNotificationService().notificationsFromStrangers(); if (notifyForStrangers) { @@ -227,6 +262,26 @@ public class JingleConnectionManager extends AbstractConnectionManager { Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": encountered unknown media in session proposal. " + propose); return; } + final Optional matchingSessionProposal = findMatchingSessionProposal(account, id.with, ImmutableSet.copyOf(media)); + if (matchingSessionProposal.isPresent()) { + final String ourSessionId = matchingSessionProposal.get().sessionId; + final String theirSessionId = id.sessionId; + if (ComparisonChain.start() + .compare(ourSessionId, theirSessionId) + .compare(account.getJid().toEscapedString(), id.with.toEscapedString()) + .result() > 0) { + Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": our session lost tie break. automatically accepting their session. winning Session=" + theirSessionId); + //TODO a retract for this reason should probably include some indication of tie break + retractSessionProposal(matchingSessionProposal.get()); + final JingleRtpConnection rtpConnection = new JingleRtpConnection(this, id, from); + this.connections.put(id, rtpConnection); + rtpConnection.setProposedMedia(ImmutableSet.copyOf(media)); + rtpConnection.deliveryMessage(from, message, serverMsgId, timestamp); + } else { + Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": our session won tie break. waiting for other party to accept. winningSession=" + ourSessionId); + } + return; + } final boolean stranger = isWithStrangerAndStrangerNotificationsAreOff(account, id.with); if (isBusy() || stranger) { writeLogMissedIncoming(account, id.with.asBareJid(), id.sessionId, serverMsgId, timestamp); @@ -289,7 +344,7 @@ public class JingleConnectionManager extends AbstractConnectionManager { } } } else { - Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": retrieved out of order jingle message"); + Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": retrieved out of order jingle message"+message); } } @@ -449,16 +504,21 @@ public class JingleConnectionManager extends AbstractConnectionManager { } } if (matchingProposal != null) { - toneManager.transition(RtpEndUserState.ENDED); - Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": retracting rtp session proposal with " + with); - this.rtpSessionProposals.remove(matchingProposal); - final MessagePacket messagePacket = mXmppConnectionService.getMessageGenerator().sessionRetract(matchingProposal); - writeLogMissedOutgoing(account, matchingProposal.with, matchingProposal.sessionId, null, System.currentTimeMillis()); - mXmppConnectionService.sendMessagePacket(account, messagePacket); + retractSessionProposal(matchingProposal); } } } + private void retractSessionProposal(RtpSessionProposal rtpSessionProposal) { + final Account account = rtpSessionProposal.account; + toneManager.transition(RtpEndUserState.ENDED); + Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": retracting rtp session proposal with " + rtpSessionProposal.with); + this.rtpSessionProposals.remove(rtpSessionProposal); + final MessagePacket messagePacket = mXmppConnectionService.getMessageGenerator().sessionRetract(rtpSessionProposal); + writeLogMissedOutgoing(account, rtpSessionProposal.with, rtpSessionProposal.sessionId, null, System.currentTimeMillis()); + mXmppConnectionService.sendMessagePacket(account, messagePacket); + } + public void proposeJingleRtpSession(final Account account, final Jid with, final Set media) { synchronized (this.rtpSessionProposals) { for (Map.Entry entry : this.rtpSessionProposals.entrySet()) { @@ -479,6 +539,10 @@ public class JingleConnectionManager extends AbstractConnectionManager { } } if (isBusy()) { + if (hasMatchingRtpSession(account, with, media)) { + Log.d(Config.LOGTAG, "ignoring request to propose jingle session because the other party already created one for us"); + return; + } throw new IllegalStateException("There is already a running RTP session. This should have been caught by the UI"); } final RtpSessionProposal proposal = RtpSessionProposal.of(account, with.asBareJid(), media); diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java index 97de5b3c1..0376807c7 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java @@ -1066,6 +1066,9 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web return webRTCWrapper.isVideoEnabled(); } + public void setVideoEnabled(final boolean enabled) { + webRTCWrapper.setVideoEnabled(enabled); + } public boolean isCameraSwitchable() { return webRTCWrapper.isCameraSwitchable(); @@ -1079,10 +1082,6 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web return webRTCWrapper.switchCamera(); } - public void setVideoEnabled(final boolean enabled) { - webRTCWrapper.setVideoEnabled(enabled); - } - @Override public void onAudioDeviceChanged(AppRTCAudioManager.AudioDevice selectedAudioDevice, Set availableAudioDevices) { xmppConnectionService.notifyJingleRtpConnectionUpdate(selectedAudioDevice, availableAudioDevices); From 46579550e477360f246f3eaf9a1acf2ce6ff3cc1 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 10 May 2020 17:54:13 +0200 Subject: [PATCH 18/20] fixed weird ToneGenerator crash. fixes #3712 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit obviously tones won’t work then anymore --- .../xmpp/jingle/ToneManager.java | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/ToneManager.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/ToneManager.java index 38fc60388..b4e67cd36 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/ToneManager.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/ToneManager.java @@ -21,7 +21,14 @@ class ToneManager { private ScheduledFuture currentTone; ToneManager() { - this.toneGenerator = new ToneGenerator(AudioManager.STREAM_MUSIC, 35); + ToneGenerator toneGenerator; + try { + toneGenerator = new ToneGenerator(AudioManager.STREAM_MUSIC, 35); + } catch (final RuntimeException e) { + Log.e(Config.LOGTAG, "unable to instantiate ToneGenerator", e); + toneGenerator = null; + } + this.toneGenerator = toneGenerator; } void transition(final RtpEndUserState state) { @@ -86,25 +93,25 @@ class ToneManager { private void scheduleConnected() { this.currentTone = JingleConnectionManager.SCHEDULED_EXECUTOR_SERVICE.schedule(() -> { - this.toneGenerator.startTone(ToneGenerator.TONE_PROP_PROMPT, 200); + startTone(ToneGenerator.TONE_PROP_PROMPT, 200); }, 0, TimeUnit.SECONDS); } private void scheduleEnding() { this.currentTone = JingleConnectionManager.SCHEDULED_EXECUTOR_SERVICE.schedule(() -> { - this.toneGenerator.startTone(ToneGenerator.TONE_CDMA_CALLDROP_LITE, 375); + startTone(ToneGenerator.TONE_CDMA_CALLDROP_LITE, 375); }, 0, TimeUnit.SECONDS); } private void scheduleBusy() { this.currentTone = JingleConnectionManager.SCHEDULED_EXECUTOR_SERVICE.schedule(() -> { - this.toneGenerator.startTone(ToneGenerator.TONE_CDMA_NETWORK_BUSY, 2500); + startTone(ToneGenerator.TONE_CDMA_NETWORK_BUSY, 2500); }, 0, TimeUnit.SECONDS); } private void scheduleWaitingTone() { this.currentTone = JingleConnectionManager.SCHEDULED_EXECUTOR_SERVICE.scheduleAtFixedRate(() -> { - this.toneGenerator.startTone(ToneGenerator.TONE_CDMA_DIAL_TONE_LITE, 750); + startTone(ToneGenerator.TONE_CDMA_DIAL_TONE_LITE, 750); }, 0, 3, TimeUnit.SECONDS); } @@ -112,7 +119,17 @@ class ToneManager { if (currentTone != null) { currentTone.cancel(true); } - toneGenerator.stopTone(); + if (toneGenerator != null) { + toneGenerator.stopTone(); + } + } + + private void startTone(final int toneType, final int durationMs) { + if (toneGenerator != null) { + this.toneGenerator.startTone(toneType, durationMs); + } else { + Log.e(Config.LOGTAG, "failed to start tone. ToneGenerator doesn't exist"); + } } private enum ToneState { From 907b4d2b8a4c261d392cd3fd6e26b507596c0cd9 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 10 May 2020 18:42:24 +0200 Subject: [PATCH 19/20] pulled translations from transifex --- src/main/res/values-de/strings.xml | 2 +- src/main/res/values-es/strings.xml | 1 - src/main/res/values-fr/strings.xml | 2 +- src/main/res/values-gl/strings.xml | 2 +- src/main/res/values-hu/strings.xml | 1 - src/main/res/values-it/strings.xml | 1 - src/main/res/values-pl/strings.xml | 2 +- src/main/res/values-pt-rBR/strings.xml | 1 - src/main/res/values-ro-rRO/strings.xml | 1 - src/main/res/values-zh-rCN/strings.xml | 1 - 10 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml index 18d30033c..555143ecf 100644 --- a/src/main/res/values-de/strings.xml +++ b/src/main/res/values-de/strings.xml @@ -898,7 +898,7 @@ Anruf beenden Annehmen Ablehnen - Geräte lokalisieren + Entdecke Geräte Klingelt Besetzt Verbindungsaufbau fehlgeschlagen diff --git a/src/main/res/values-es/strings.xml b/src/main/res/values-es/strings.xml index b62109602..7116fc188 100644 --- a/src/main/res/values-es/strings.xml +++ b/src/main/res/values-es/strings.xml @@ -859,7 +859,6 @@ Terminar llamada Contestar Descartar - Localizando dispositivos Llamando Ocupado Llamada rechazada diff --git a/src/main/res/values-fr/strings.xml b/src/main/res/values-fr/strings.xml index 77bb6c5ad..4ce10acdd 100644 --- a/src/main/res/values-fr/strings.xml +++ b/src/main/res/values-fr/strings.xml @@ -898,7 +898,7 @@ Fin d\'appel Décrocher Ignorer - Recherche de l\'appareil + Découverte des appareils Ça sonne Occupé Impossible de connecter l\'appel diff --git a/src/main/res/values-gl/strings.xml b/src/main/res/values-gl/strings.xml index 6616c5271..5a10e7593 100644 --- a/src/main/res/values-gl/strings.xml +++ b/src/main/res/values-gl/strings.xml @@ -898,7 +898,7 @@ Rematando a chamada Responder Rexeitar - Localizando dispositivos + Atopando dispositivos Sonando Ocupado Non se pode establecer a chamada diff --git a/src/main/res/values-hu/strings.xml b/src/main/res/values-hu/strings.xml index c9bea04ce..0385cf3d9 100644 --- a/src/main/res/values-hu/strings.xml +++ b/src/main/res/values-hu/strings.xml @@ -808,7 +808,6 @@ Hívás befejezése Válasz Elutasítás - Eszközök keresése Csörgetés Elfoglalt Nem sikerült kapcsolódni a híváshoz diff --git a/src/main/res/values-it/strings.xml b/src/main/res/values-it/strings.xml index 9c6ec8666..8c509c2c3 100644 --- a/src/main/res/values-it/strings.xml +++ b/src/main/res/values-it/strings.xml @@ -898,7 +898,6 @@ Chiusura chiamata Rispondi Rifiuta - Localizzazione dispositivi Sta squillando Occupato Impossibile connettere la chiamata diff --git a/src/main/res/values-pl/strings.xml b/src/main/res/values-pl/strings.xml index 76114db4b..bf537e7e9 100644 --- a/src/main/res/values-pl/strings.xml +++ b/src/main/res/values-pl/strings.xml @@ -916,7 +916,7 @@ Administrator twojego serwera będzie mógł czytać twoje wiadomości, ale moż Kończenie połączenia Odbierz Odrzuć - Lokalizowanie urządzeń + Wyszukiwanie urządzeń Dzwonienie Zajęty Nie można wykonać połączenia diff --git a/src/main/res/values-pt-rBR/strings.xml b/src/main/res/values-pt-rBR/strings.xml index b14dfdb2a..8c669027d 100644 --- a/src/main/res/values-pt-rBR/strings.xml +++ b/src/main/res/values-pt-rBR/strings.xml @@ -898,7 +898,6 @@ Encerrando chamada Atender Dispensar - Procurando dispositivos Tocando Ocupado Não foi possível conectar à chamada diff --git a/src/main/res/values-ro-rRO/strings.xml b/src/main/res/values-ro-rRO/strings.xml index 3d9f935ad..6e8243cb1 100644 --- a/src/main/res/values-ro-rRO/strings.xml +++ b/src/main/res/values-ro-rRO/strings.xml @@ -906,7 +906,6 @@ Se încheie apelul Răspunde Respinge - Căutare dispozitive Sună Ocupat Nu s-a putut conecta apelul diff --git a/src/main/res/values-zh-rCN/strings.xml b/src/main/res/values-zh-rCN/strings.xml index 645f0e065..c8d0ce1cb 100644 --- a/src/main/res/values-zh-rCN/strings.xml +++ b/src/main/res/values-zh-rCN/strings.xml @@ -890,7 +890,6 @@ 正在结束来电 应答 忽略 - 正在确定设备位置 正在响铃 正忙 无法接通来电 From 11de70312cf215e54ad7158a91a75c63962c889e Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 11 May 2020 09:23:36 +0200 Subject: [PATCH 20/20] version bump to 2.8.3 + changelog --- CHANGELOG.md | 6 ++++++ build.gradle | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 360b1acd3..b51386d29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +### Version 2.8.3 + +* Move call icon to the left in order to keep other toolbar icons in a consistent place +* Show call duration during audio calls +* Tie breaking for A/V calls (the same two people calling each other at the same time) + ### Version 2.8.2 * Add button to switch camea during video call diff --git a/build.gradle b/build.gradle index 462d60db0..ceffbbad8 100644 --- a/build.gradle +++ b/build.gradle @@ -95,8 +95,8 @@ android { defaultConfig { minSdkVersion 16 targetSdkVersion 28 - versionCode 382 - versionName "2.8.2" + versionCode 383 + versionName "2.8.3" archivesBaseName += "-$versionName" applicationId "eu.siacs.conversations" resValue "string", "applicationId", applicationId