From 1dd3593c9756dbc00bb9e3aa81a775a41ec0885e Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Tue, 29 Jun 2021 10:21:33 -0700 Subject: [PATCH 1/5] Add tooltips to contact request. Fixes: #59 --- lib/l10n/intl_de.arb | 6 +- lib/l10n/intl_en.arb | 4 +- lib/l10n/intl_es.arb | 4 +- lib/l10n/intl_fr.arb | 306 ++++++++++++++++++------------------ lib/l10n/intl_it.arb | 4 +- lib/l10n/intl_pt.arb | 4 +- lib/widgets/contactrow.dart | 4 +- 7 files changed, 173 insertions(+), 159 deletions(-) diff --git a/lib/l10n/intl_de.arb b/lib/l10n/intl_de.arb index 8648c314..17575393 100644 --- a/lib/l10n/intl_de.arb +++ b/lib/l10n/intl_de.arb @@ -1,6 +1,8 @@ { "@@locale": "de", - "@@last_modified": "2021-06-25T21:14:59+02:00", + "@@last_modified": "2021-06-29T19:15:43+02:00", + "tooltipRejectContactRequest": "Reject this contact request", + "tooltipAcceptContactRequest": "Accept this contact request.", "notificationNewMessageFromGroup": "Neue Nachricht in einer Gruppe!", "notificationNewMessageFromPeer": "Neue Nachricht von einem Kontakt!", "tooltipHidePassword": "Password verstecken", @@ -192,4 +194,4 @@ "createGroupBtn": "Anlegen", "defaultGroupName": "Tolle Gruppe", "createGroupTitle": "Gruppe Anlegen" -} +} \ No newline at end of file diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index 123a9eb8..7d6a2fac 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -1,6 +1,8 @@ { "@@locale": "en", - "@@last_modified": "2021-06-25T18:57:59+02:00", + "@@last_modified": "2021-06-29T19:15:43+02:00", + "tooltipRejectContactRequest": "Reject this contact request", + "tooltipAcceptContactRequest": "Accept this contact request.", "notificationNewMessageFromGroup": "New message in a group!", "notificationNewMessageFromPeer": "New message from a contact!", "tooltipHidePassword": "Hide Password", diff --git a/lib/l10n/intl_es.arb b/lib/l10n/intl_es.arb index 9a4b88de..9046ba26 100644 --- a/lib/l10n/intl_es.arb +++ b/lib/l10n/intl_es.arb @@ -1,6 +1,8 @@ { "@@locale": "es", - "@@last_modified": "2021-06-25T18:57:59+02:00", + "@@last_modified": "2021-06-29T19:15:43+02:00", + "tooltipRejectContactRequest": "Reject this contact request", + "tooltipAcceptContactRequest": "Accept this contact request.", "notificationNewMessageFromGroup": "New message in a group!", "notificationNewMessageFromPeer": "New message from a contact!", "tooltipHidePassword": "Hide Password", diff --git a/lib/l10n/intl_fr.arb b/lib/l10n/intl_fr.arb index 5af33cab..a08e85e1 100644 --- a/lib/l10n/intl_fr.arb +++ b/lib/l10n/intl_fr.arb @@ -1,138 +1,140 @@ { "@@locale": "fr", - "@@last_modified": "2021-06-25T18:57:59+02:00", - "notificationNewMessageFromGroup": "New message in a group!", - "notificationNewMessageFromPeer": "New message from a contact!", - "tooltipHidePassword": "Hide Password", - "tooltipShowPassword": "Show Password", - "serverNotSynced": "Syncing New Messages (This can take some time)...", - "groupInviteSettingsWarning": "You have been invited to join a group! Please enable the Group Chat Experiment in Settings to view this Invitation.", - "shutdownCwtchAction": "Shutdown Cwtch", - "shutdownCwtchDialog": "Are you sure you want to shutdown Cwtch? This will close all connections, and exit the application.", - "shutdownCwtchDialogTitle": "Shutdown Cwtch?", - "shutdownCwtchTooltip": "Shutdown Cwtch", - "malformedMessage": "Malformed message", - "profileDeleteSuccess": "Successfully deleted profile", - "debugLog": "Turn on console debug logging", - "torNetworkStatus": "Tor network status", - "addContactFirst": "Add or pick a contact to begin chatting.", - "createProfileToBegin": "Please create or unlock a profile to begin", - "nickChangeSuccess": "Profile nickname changed successfully", - "addServerFirst": "You need to add a server before you can create a group", - "deleteProfileSuccess": "Successfully deleted profile", - "sendInvite": "Send a contact or group invite", - "sendMessage": "Send Message", - "cancel": "Cancel", - "resetTor": "Reset", - "torStatus": "Tor Status", - "torVersion": "Tor Version", - "sendAnInvitation": "You sent an invitation for: ", - "contactSuggestion": "This is a contact suggestion for: ", - "rejected": "Rejected!", - "accepted": "Accepted!", - "chatHistoryDefault": "This conversation will be deleted when Cwtch is closed! Message history can be enabled per-conversation via the Settings menu in the upper right.", - "newPassword": "New Password", - "yesLeave": "Yes, Leave This Conversation", - "reallyLeaveThisGroupPrompt": "Are you sure you want to leave this conversation? All messages and attributes will be deleted.", - "leaveGroup": "Leave This Conversation", - "inviteToGroup": "You have been invited to join a group:", - "pasteAddressToAddContact": "... coller une adresse ici pour ajouter un contact...", - "tooltipAddContact": "Add a new contact or conversation", + "@@last_modified": "2021-06-29T19:15:43+02:00", + "tooltipRejectContactRequest": "Reject this contact request", + "tooltipAcceptContactRequest": "Accept this contact request.", + "notificationNewMessageFromGroup": "Nouveau message dans un groupe !", + "notificationNewMessageFromPeer": "Nouveau message d'un contact !", + "tooltipHidePassword": "Masquer le mot de passe", + "tooltipShowPassword": "Afficher le mot de passe", + "serverNotSynced": "Synchronisation des nouveaux messages (Cela peut prendre un certain temps)...", + "groupInviteSettingsWarning": "Vous avez été invité à rejoindre un groupe ! Veuillez activer l'expérience de discussion de groupe dans les paramètres pour afficher cette invitation.", + "shutdownCwtchAction": "Arrêt Cwtch", + "shutdownCwtchDialog": "Êtes-vous sûr de vouloir arrêter Cwtch ? Ceci fermera toutes les connexions, et quittera l'application.", + "shutdownCwtchDialogTitle": "Arrêter Cwtch ?", + "shutdownCwtchTooltip": "Arrêt Cwtch", + "malformedMessage": "Message mal formé", + "profileDeleteSuccess": "Le profil a été supprimé avec succès", + "debugLog": "Activer le journal de la console de débogage", + "torNetworkStatus": "Statut du réseau Tor", + "addContactFirst": "Ajoutez ou choisissez un contact pour commencer à discuter.", + "createProfileToBegin": "Veuillez créer ou déverrouiller un profil pour commencer", + "nickChangeSuccess": "Le pseudo du profil a été modifié avec succès", + "addServerFirst": "Vous devez ajouter un serveur avant de pouvoir créer un groupe.", + "deleteProfileSuccess": "Le profil a été supprimé avec succès", + "sendInvite": "Envoyer une invitation à un contact ou à un groupe", + "sendMessage": "Envoyer un message", + "cancel": "Annuler", + "resetTor": "Réinitialiser", + "torStatus": "Statut de Tor", + "torVersion": "Version de Tor", + "sendAnInvitation": "Vous avez envoyé une invitation pour : ", + "contactSuggestion": "Il s'agit d'une suggestion de contact pour : ", + "rejected": "Rejeté !", + "accepted": "Accepté !", + "chatHistoryDefault": "Cette conversation sera supprimée lorsque Cwtch sera fermé ! L'historique des messages peut être activé pour la conversation via le menu Paramètres en haut à droite.", + "newPassword": "Nouveau mot de passe", + "yesLeave": "Oui, quittez cette conversation", + "reallyLeaveThisGroupPrompt": "Êtes-vous sûr de vouloir quitter cette conversation ? Tous les messages et attributs seront supprimés.", + "leaveGroup": "Quittez cette conversation", + "inviteToGroup": "Vous avez été invité à rejoindre un groupe :", + "pasteAddressToAddContact": "Collez une adresse cwtch, une invitation ou un ensemble de clés ici pour ajouter une nouvelle conversation", + "tooltipAddContact": "Ajouter un nouveau contact ou une nouvelle conversation", "titleManageContacts": "Conversations", - "titleManageServers": "Manage Servers", - "dateMonthsAgo": "Months Ago", - "dateNever": "Never", - "dateYearsAgo": "X Years Ago (displayed next to a contact row to indicate time of last action)", - "dateLastYear": "Last Year", - "dateYesterday": "Yesterday", - "dateLastMonth": "Last Month", - "dateWeeksAgo": "Weeks Ago", - "dateDaysAgo": "Days Ago", - "dateHoursAgo": "Hours Ago", - "dateMinutesAgo": "Minutes Ago", - "dateRightNow": "Right Now", - "successfullAddedContact": "Successfully added ", - "descriptionBlockUnknownConnections": "If turned on, this option will automatically close connections from Cwtch users that have not been added to your contact list.", - "descriptionExperimentsGroups": "The group experiment allows Cwtch to connect with untrusted server infrastructure to facilitate communication with more than one contact.", - "descriptionExperiments": "Cwtch experiments are optional, opt-in features that add additional functionality to Cwtch that may have different privacy considerations than traditional 1:1 metadata resistant chat e.g. group chat, bot integration etc.", - "titleManageProfiles": "Manage Cwtch Profiles", - "tooltipUnlockProfiles": "Unlock encrypted profiles by entering their password.", - "tooltipOpenSettings": "Open the settings pane", - "invalidImportString": "Invalid import string", - "contactAlreadyExists": "Contact Already Exists", - "conversationSettings": "Conversation Settings", - "enterCurrentPasswordForDelete": "Please enter current password to delete this profile.", - "enableGroups": "Enable Group Chat", - "experimentsEnabled": "Enable Experiments", - "localeIt": "Italiana", - "localeEs": "Espanol", - "addListItem": "Ajouter un nouvel élément", + "titleManageServers": "Gérer les serveurs", + "dateMonthsAgo": "Il y a plusieurs mois", + "dateNever": "Jamais", + "dateYearsAgo": "Il y a X ans (affiché à côté d'une ligne de contact pour indiquer l'heure de la dernière action)", + "dateLastYear": "L'année dernière", + "dateYesterday": "Hier", + "dateLastMonth": "Le mois dernier", + "dateWeeksAgo": "Il y a quelques semaines", + "dateDaysAgo": "Il y a quelques jours", + "dateHoursAgo": "Il y a quelques heures", + "dateMinutesAgo": "Il y a quelques minutes", + "dateRightNow": "Maintenant", + "successfullAddedContact": "Ajouté avec succès ", + "descriptionBlockUnknownConnections": "Si elle est activée, cette option fermera automatiquement les connexions des utilisateurs de Cwtch qui n'ont pas été ajoutés à votre liste de contacts.", + "descriptionExperimentsGroups": "L'expérience de groupe permet à Cwtch de se connecter à une infrastructure de serveurs non fiables pour faciliter la communication avec plus d'un contact.", + "descriptionExperiments": "Les expériences de Cwtch sont des fonctionnalités optionnelles et facultatives qui ajoutent des fonctionnalités supplémentaires à Cwtch et qui peuvent avoir des considérations de confidentialité différentes de celles du chat traditionnel résistant aux métadonnées 1:1, par exemple le chat de groupe, l'intégration de robots, etc.", + "titleManageProfiles": "Gérer les profils Cwtch", + "tooltipUnlockProfiles": "Déverrouillez les profils chiffrés en saisissant leur mot de passe.", + "tooltipOpenSettings": "Ouvrez le volet des paramètres", + "invalidImportString": "Chaîne d'importation non valide", + "contactAlreadyExists": "Le contact existe déjà", + "conversationSettings": "Paramètres de conversation", + "enterCurrentPasswordForDelete": "Veuillez entrer le mot de passe actuel pour supprimer ce profil.", + "enableGroups": "Activer la discussion de groupe", + "experimentsEnabled": "Activer les expériences", + "localeIt": "Italienne", + "localeEs": "Espagnol", + "addListItem": "Ajouter un nouvel élément de liste", "addNewItem": "Ajouter un nouvel élément à la liste", - "todoPlaceholder": "A faire...", - "newConnectionPaneTitle": "New Connection", - "networkStatusOnline": "Online", - "networkStatusConnecting": "Connecting to network and peers...", - "networkStatusAttemptingTor": "Attempting to connect to Tor network", - "networkStatusDisconnected": "Disconnected from the internet, check your connection", - "viewGroupMembershipTooltip": "View Group Membership", - "loadingTor": "Loading tor...", + "todoPlaceholder": "À faire...", + "newConnectionPaneTitle": "Nouvelle connexion", + "networkStatusOnline": "En ligne", + "networkStatusConnecting": "Se connecter au réseau et aux pairs...", + "networkStatusAttemptingTor": "Tentative de connexion au réseau Tor", + "networkStatusDisconnected": "Déconnecté d'Internet, vérifiez votre connexion", + "viewGroupMembershipTooltip": "Afficher les membres du groupe", + "loadingTor": "Chargement de tor...", "smallTextLabel": "Petit", "defaultScalingText": "Taille par défaut du texte (échelle:", - "builddate": "Built on: %2", - "version": "Version %1", - "versionTor": "Version %1 with tor %2", - "themeDark": "Dark", - "themeLight": "Light", - "settingTheme": "Theme", + "builddate": "Construit sur : 2%", + "version": "Version 1%", + "versionTor": "Version 1% avec tor 2%", + "themeDark": "Sombre", + "themeLight": "Clair", + "settingTheme": "Thème", "largeTextLabel": "Large", - "settingInterfaceZoom": "Zoom level", - "localeDe": "Deutsche", - "localePt": "Portuguesa", - "localeFr": "Frances", - "localeEn": "English", - "settingLanguage": "Language", - "blockUnknownLabel": "Block Unknown Peers", + "settingInterfaceZoom": "Niveau de zoom", + "localeDe": "Allemand", + "localePt": "Portugais", + "localeFr": "Français", + "localeEn": "Anglais", + "settingLanguage": "Langue", + "blockUnknownLabel": "Bloquer les pairs inconnus", "zoomLabel": "Interface zoom (essentiellement la taille du texte et des composants de l'interface)", - "versionBuilddate": "Version: %1 Built on: %2", + "versionBuilddate": "Version 1% avec tor 2%", "cwtchSettingsTitle": "Préférences Cwtch", - "unlock": "Unlock", - "yourServers": "Your Servers", - "yourProfiles": "Your Profiles", - "error0ProfilesLoadedForPassword": "0 profiles loaded with that password", - "password": "Password", - "enterProfilePassword": "Enter a password to view your profiles", - "addNewProfileBtn": "Add new profile", - "deleteConfirmText": "DELETE", - "deleteProfileConfirmBtn": "Really Delete Profile", - "deleteConfirmLabel": "Type DELETE to confirm", - "deleteProfileBtn": "Delete Profile", - "passwordChangeError": "Error changing password: Supplied password rejected", - "passwordErrorMatch": "Passwords do not match", - "saveProfileBtn": "Save Profile", - "createProfileBtn": "Create Profile", - "passwordErrorEmpty": "Password cannot be empty", - "password2Label": "Reenter password", - "password1Label": "Password", - "currentPasswordLabel": "Current Password", - "yourDisplayName": "Your Display Name", - "profileOnionLabel": "Send this address to peers you want to connect with", - "noPasswordWarning": "Not using a password on this account means that all data stored locally will not be encrypted", - "radioNoPassword": "Unencrypted (No password)", - "radioUsePassword": "Password", + "unlock": "Déverrouiller", + "yourServers": "Vos serveurs", + "yourProfiles": "Vos profils", + "error0ProfilesLoadedForPassword": "Aucun profils chargés avec ce mot de passe", + "password": "Mot de passe", + "enterProfilePassword": "Entrez un mot de passe pour consulter vos profils", + "addNewProfileBtn": "Ajouter un nouveau profil", + "deleteConfirmText": "SUPPRIMER", + "deleteProfileConfirmBtn": "Vraiment supprimer le profil", + "deleteConfirmLabel": "Tapez SUPPRIMER pour confirmer", + "deleteProfileBtn": "Supprimer le profil", + "passwordChangeError": "Erreur lors de la modification du mot de passe : le mot de passe fourni est rejeté", + "passwordErrorMatch": "Les mots de passe ne correspondent pas", + "saveProfileBtn": "Sauvegarder le profil", + "createProfileBtn": "Créer un profil", + "passwordErrorEmpty": "Le mot de passe ne peut pas être vide", + "password2Label": "Saisissez à nouveau le mot de passe", + "password1Label": "Mot de passe", + "currentPasswordLabel": "Mot de passe actuel", + "yourDisplayName": "Pseudo", + "profileOnionLabel": "Envoyez cette adresse aux personnes avec lesquelles vous souhaitez entrer en contact.", + "noPasswordWarning": "Ne pas utiliser de mot de passe sur ce compte signifie que toutes les données stockées localement ne seront pas chiffrées.", + "radioNoPassword": "Non chiffré (pas de mot de passe)", + "radioUsePassword": "Mot de passe", "copiedToClipboardNotification": "Copié dans le presse-papier", "copyBtn": "Copier", - "editProfile": "Edit Profille", - "newProfile": "New Profile", + "editProfile": "Modifier le profil", + "newProfile": "Nouveau profil", "defaultProfileName": "Alice", - "profileName": "Display name", - "editProfileTitle": "Edit Profile", - "addProfileTitle": "Add new profile", + "profileName": "Pseudo", + "editProfileTitle": "Modifier le profil", + "addProfileTitle": "Ajouter un nouveau profil", "deleteBtn": "Effacer", - "unblockBtn": "Unblock Peer", - "dontSavePeerHistory": "Delete Peer History", - "savePeerHistoryDescription": "Determines whether or not to delete any history associated with the peer.", - "savePeerHistory": "Save Peer History", - "blockBtn": "Block Peer", + "unblockBtn": "Débloquer le pair", + "dontSavePeerHistory": "Supprimer l'historique des pairs", + "savePeerHistoryDescription": "Détermine s'il faut ou non supprimer tout historique associé au pair.", + "savePeerHistory": "Sauvegarder l'historique des pairs", + "blockBtn": "Bloquer le pair", "saveBtn": "Sauvegarder", "displayNameLabel": "Pseudo", "addressLabel": "Adresse", @@ -145,50 +147,50 @@ "acceptGroupInviteLabel": "Voulez-vous accepter l'invitation au groupe", "newGroupBtn": "Créer un nouveau groupe", "copiedClipboardNotification": "Copié dans le presse-papier", - "peerOfflineMessage": "Peer is offline, messages can't be delivered right now", - "peerBlockedMessage": "Peer is blocked", + "peerOfflineMessage": "Le pair est hors ligne, les messages ne peuvent pas être remis pour le moment", + "peerBlockedMessage": "Le pair est bloqué", "pendingLabel": "En attente", "acknowledgedLabel": "Confirmé", "couldNotSendMsgError": "Impossible d'envoyer ce message", "dmTooltip": "Envoyer un message privé", "membershipDescription": "Liste des utilisateurs ayant envoyés un ou plusieurs messages au groupe. Cette liste peut ne pas être representatives de l'ensemble des membres du groupe.", - "addListItemBtn": "Add Item", - "peerNotOnline": "Peer is Offline. Applications cannot be used right now.", - "searchList": "Search List", - "update": "Update", + "addListItemBtn": "Ajouter un élément", + "peerNotOnline": "Le pair est hors ligne, les messages ne peuvent pas être remis pour le moment", + "searchList": "Liste de recherche", + "update": "Mise à jour", "inviteBtn": "Invitation", "inviteToGroupLabel": "Inviter quelqu'un", "groupNameLabel": "Nom du groupe", - "viewServerInfo": "Server Info", - "serverSynced": "Synced", - "serverConnectivityDisconnected": "Server Disconnected", - "serverConnectivityConnected": "Server Connected", - "serverInfo": "Server Information", + "viewServerInfo": "Informations sur le serveur", + "serverSynced": "Synchronisé", + "serverConnectivityDisconnected": "Serveur déconnecté", + "serverConnectivityConnected": "Serveur connecté", + "serverInfo": "Informations sur le serveur", "invitationLabel": "Invitation", "serverLabel": "Serveur", - "search": "Search...", - "cycleColoursDesktop": "Click to cycle colours.\nRight-click to reset.", - "cycleColoursAndroid": "Click to cycle colours.\nLong-press to reset.", - "cycleMorphsDesktop": "Click to cycle morphs.\nRight-click to reset.", - "cycleMorphsAndroid": "Click to cycle morphs.\nLong-press to reset.", - "cycleCatsDesktop": "Click to cycle category.\nRight-click to reset.", - "cycleCatsAndroid": "Click to cycle category.\nLong-press to reset.", - "blocked": "Blocked", + "search": "Recherche...", + "cycleColoursDesktop": "Cliquez pour faire défiler les couleurs.\nCliquez avec le bouton droit de la souris pour réinitialiser.", + "cycleColoursAndroid": "Cliquez pour faire défiler les couleurs.\nAppuyez longuement pour réinitialiser.", + "cycleMorphsDesktop": "Cliquez pour faire défiler les morphes.\n Faites un clic droit pour réinitialiser.", + "cycleMorphsAndroid": "Cliquez pour faire défiler les morphes.\n Appuyez longuement pour réinitialiser.", + "cycleCatsDesktop": "Cliquez pour parcourir la catégorie.\n Faites un clic droit pour réinitialiser.", + "cycleCatsAndroid": "Cliquez pour faire défiler les catégories.\nAppuyez longuement pour réinitialiser.", + "blocked": "Bloqué", "titlePlaceholder": "titre...", "postNewBulletinLabel": "Envoyer un nouveau bulletin", "newBulletinLabel": "Nouveau bulletin", - "joinGroup": "Join group", - "createGroup": "Create group", - "addPeer": "Add Peer", - "groupAddr": "Address", + "joinGroup": "Rejoindre le groupe", + "createGroup": "Créer un groupe", + "addPeer": "Ajouter un pair", + "groupAddr": "Adresse", "invitation": "Invitation", - "server": "Server", - "groupName": "Group name", - "peerName": "Name", - "peerAddress": "Address", - "joinGroupTab": "Join a group", - "createGroupTab": "Create a group", - "addPeerTab": "Add a peer", + "server": "Serveur", + "groupName": "Nom du groupe", + "peerName": "Nom", + "peerAddress": "Adresse", + "joinGroupTab": "Rejoindre un groupe", + "createGroupTab": "Créer un groupe", + "addPeerTab": "Ajouter un pair", "createGroupBtn": "Créer", "defaultGroupName": "Un super groupe", "createGroupTitle": "Créer un groupe" diff --git a/lib/l10n/intl_it.arb b/lib/l10n/intl_it.arb index 32ad2726..d4300a5b 100644 --- a/lib/l10n/intl_it.arb +++ b/lib/l10n/intl_it.arb @@ -1,6 +1,8 @@ { "@@locale": "it", - "@@last_modified": "2021-06-25T18:57:59+02:00", + "@@last_modified": "2021-06-29T19:15:43+02:00", + "tooltipRejectContactRequest": "Reject this contact request", + "tooltipAcceptContactRequest": "Accept this contact request.", "notificationNewMessageFromGroup": "New message in a group!", "notificationNewMessageFromPeer": "New message from a contact!", "tooltipHidePassword": "Hide Password", diff --git a/lib/l10n/intl_pt.arb b/lib/l10n/intl_pt.arb index 0b2b4593..ab682cfa 100644 --- a/lib/l10n/intl_pt.arb +++ b/lib/l10n/intl_pt.arb @@ -1,6 +1,8 @@ { "@@locale": "pt", - "@@last_modified": "2021-06-25T18:57:59+02:00", + "@@last_modified": "2021-06-29T19:15:43+02:00", + "tooltipRejectContactRequest": "Reject this contact request", + "tooltipAcceptContactRequest": "Accept this contact request.", "notificationNewMessageFromGroup": "New message in a group!", "notificationNewMessageFromPeer": "New message from a contact!", "tooltipHidePassword": "Hide Password", diff --git a/lib/widgets/contactrow.dart b/lib/widgets/contactrow.dart index 5b7f4687..296ae406 100644 --- a/lib/widgets/contactrow.dart +++ b/lib/widgets/contactrow.dart @@ -60,13 +60,15 @@ class _ContactRowState extends State { IconButton( padding: EdgeInsets.zero, iconSize: 16, - icon: Icon(Icons.favorite, color: Provider.of(context).theme.mainTextColor()), + icon: Icon(Icons.favorite, color: Provider.of(context).theme.mainTextColor(),), + tooltip: AppLocalizations.of(context)!.tooltipAcceptContactRequest, onPressed: _btnApprove, ), IconButton( padding: EdgeInsets.zero, iconSize: 16, icon: Icon(Icons.delete, color: Provider.of(context).theme.mainTextColor()), + tooltip: AppLocalizations.of(context)!.tooltipRejectContactRequest, onPressed: _btnReject, ) ]) From 7648916f6a673e517307ac5d6e897aeeed0a94e1 Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Tue, 29 Jun 2021 11:49:29 -0700 Subject: [PATCH 2/5] Don't attempt to load messages on group syncing (Fixes: #56) Also should help with #32 --- .../main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt | 8 +++++--- .../main/kotlin/im/cwtch/flwtch/MainActivity.kt | 6 +++--- lib/main.dart | 8 ++++---- lib/widgets/messagelist.dart | 16 ++++++++++++---- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/android/app/src/main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt b/android/app/src/main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt index 08d60cc8..7cb33d71 100644 --- a/android/app/src/main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt +++ b/android/app/src/main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt @@ -60,10 +60,11 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) : val evt = MainActivity.AppbusEvent(Cwtch.getAppBusEvent()) if (evt.EventType == "NewMessageFromPeer" || evt.EventType == "NewMessageFromGroup") { val data = JSONObject(evt.Data) + val handle = if (evt.EventType == "NewMessageFromPeer") data.getString("RemotePeer") else data.getString("GroupID"); if (data["RemotePeer"] != data["ProfileOnion"]) { val channelId = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - createMessageNotificationChannel(data.getString("RemotePeer"), data.getString("RemotePeer")) + createMessageNotificationChannel(handle, handle) } else { // If earlier version channel ID is not used // https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context) @@ -74,11 +75,12 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) : val key = loader.getLookupKeyForAsset("assets/" + data.getString("Picture"))//"assets/profiles/001-centaur.png") val fh = applicationContext.assets.open(key) + val clickIntent = Intent(applicationContext, MainActivity::class.java).also { intent -> intent.action = Intent.ACTION_RUN intent.putExtra("EventType", "NotificationClicked") intent.putExtra("ProfileOnion", data.getString("ProfileOnion")) - intent.putExtra("RemotePeer", if (evt.EventType == "NewMessageFromPeer") data.getString("RemotePeer") else data.getString("GroupID")) + intent.putExtra("Handle", handle) } val newNotification = NotificationCompat.Builder(applicationContext, channelId) @@ -89,7 +91,7 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) : .setContentIntent(PendingIntent.getActivity(applicationContext, 1, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT)) .setAutoCancel(true) .build() - notificationManager.notify(getNotificationID(data.getString("ProfileOnion"), data.getString("RemotePeer")), newNotification) + notificationManager.notify(getNotificationID(data.getString("ProfileOnion"), handle), newNotification) } } diff --git a/android/app/src/main/kotlin/im/cwtch/flwtch/MainActivity.kt b/android/app/src/main/kotlin/im/cwtch/flwtch/MainActivity.kt index 9f2ff6e6..4025131f 100644 --- a/android/app/src/main/kotlin/im/cwtch/flwtch/MainActivity.kt +++ b/android/app/src/main/kotlin/im/cwtch/flwtch/MainActivity.kt @@ -52,13 +52,13 @@ class MainActivity: FlutterActivity() { if (notificationClickChannel == null || intent.extras == null) return if (intent.extras!!.getString("EventType") == "NotificationClicked") { - if (!intent.extras!!.containsKey("ProfileOnion") || !intent.extras!!.containsKey("RemotePeer")) { + if (!intent.extras!!.containsKey("ProfileOnion") || !intent.extras!!.containsKey("Handle")) { Log.i("onNewIntent", "got notification clicked intent with no onions") return } val profile = intent.extras!!.getString("ProfileOnion") - val handle = intent.extras!!.getString("RemotePeer") - val mappo = mapOf("ProfileOnion" to profile, "RemotePeer" to handle) + val handle = intent.extras!!.getString("Handle") + val mappo = mapOf("ProfileOnion" to profile, "Handle" to handle) val j = JSONObject(mappo) notificationClickChannel!!.invokeMethod("NotificationClicked", j.toString()) } else if (intent.extras!!.getString("EventType") == "ShutdownClicked") { diff --git a/lib/main.dart b/lib/main.dart index 9bf7c380..f74ddbdc 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -167,8 +167,8 @@ class FlwtchState extends State { Future _externalNotificationClicked(MethodCall call) async { var args = jsonDecode(call.arguments); var profile = profs.getProfile(args["ProfileOnion"])!; - var contact = profile.contactList.getContact(args["RemotePeer"])!; - contact.unreadMessages = 0; + var convo = profile.contactList.getContact(args["Handle"])!; + convo.unreadMessages = 0; // single pane mode pushes; double pane mode reads AppState.selectedProfile/Conversation var isLandscape = Provider.of(navKey.currentContext!, listen: false).isLandscape(navKey.currentContext!); @@ -183,7 +183,7 @@ class FlwtchState extends State { return MultiProvider( providers: [ ChangeNotifierProvider.value(value: profile), - ChangeNotifierProvider.value(value: contact), + ChangeNotifierProvider.value(value: convo), ], builder: (context, child) => MessageView(), ); @@ -192,7 +192,7 @@ class FlwtchState extends State { ); } else { //dual pane Provider.of(navKey.currentContext!, listen: false).selectedProfile = args["ProfileOnion"]; - Provider.of(navKey.currentContext!, listen: false).selectedConversation = args["RemotePeer"]; + Provider.of(navKey.currentContext!, listen: false).selectedConversation = args["Handle"]; } } diff --git a/lib/widgets/messagelist.dart b/lib/widgets/messagelist.dart index a6b2e265..67158294 100644 --- a/lib/widgets/messagelist.dart +++ b/lib/widgets/messagelist.dart @@ -16,10 +16,18 @@ class _MessageListState extends State { @override Widget build(BuildContext outerContext) { - bool showEphemeralWarning = (Provider.of(context).isGroup == false && Provider.of(context).savePeerHistory != "SaveHistory"); + + bool isP2P = !Provider.of(context).isGroup; + bool isGroupAndSyncing = Provider.of(context).isGroup == true && Provider.of(context).status == "Authenticated"; + bool isGroupAndSynced = Provider.of(context).isGroup && Provider.of(context).status == "Synced"; + bool isGroupAndNotAuthenticated= Provider.of(context).isGroup && Provider.of(context).status != "Authenticated"; + + bool showEphemeralWarning = (isP2P && Provider.of(context).savePeerHistory != "SaveHistory"); bool showOfflineWarning = Provider.of(context).isOnline() == false; bool showMessageWarning = showEphemeralWarning || showOfflineWarning; - bool showSyncing = Provider.of(context).isGroup == true && Provider.of(context).status != "Synced"; + bool showSyncing = isGroupAndSyncing; + // Only load historical messages when the conversation is with a p2p contact OR the conversation is a server and *not* syncing. + bool loadMessages = isP2P || (isGroupAndSynced || isGroupAndNotAuthenticated); return RepaintBoundary( child: Container( @@ -56,7 +64,7 @@ class _MessageListState extends State { image: AssetImage("assets/core/negative_heart_512px.png"), colorFilter: ColorFilter.mode(Provider.of(context).theme.hilightElementTextColor(), BlendMode.srcIn))), // Don't load messages for syncing server... - child: ListView.builder( + child: loadMessages ? ListView.builder( controller: ctrlr1, itemCount: Provider.of(outerContext).totalMessages, reverse: true, // NOTE: There seems to be a bug in flutter that corrects the mouse wheel scroll, but not the drag direction... @@ -78,7 +86,7 @@ class _MessageListState extends State { return RepaintBoundary(child: MessageRow(key: Provider.of(bcontext).getMessageKey(idx))); }); }, - )))) + ) : null ))) ]))); } } From 45459cf76a5efd9c8298ebf7027058bbccf022aa Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Tue, 29 Jun 2021 16:41:38 -0700 Subject: [PATCH 3/5] Show Syncing Message + Update libcwtch-go to fix message fetching issues --- LIBCWTCH-GO.version | 2 +- lib/cwtch/cwtchNotifier.dart | 1 + lib/widgets/messagelist.dart | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/LIBCWTCH-GO.version b/LIBCWTCH-GO.version index 271b7350..59f1a531 100644 --- a/LIBCWTCH-GO.version +++ b/LIBCWTCH-GO.version @@ -1 +1 @@ -v1.0.0-7-g520d35a-2021-06-25-16-34 \ No newline at end of file +v1.0.0-12-g2e0b6ef-2021-06-29-23-42 \ No newline at end of file diff --git a/lib/cwtch/cwtchNotifier.dart b/lib/cwtch/cwtchNotifier.dart index d5597674..7551526a 100644 --- a/lib/cwtch/cwtchNotifier.dart +++ b/lib/cwtch/cwtchNotifier.dart @@ -245,6 +245,7 @@ class CwtchNotifier { break; case "ServerStateChange": // Update the Server Cache + EnvironmentConfig.debugLog("server state changes $data"); profileCN.getProfile(data["ProfileOnion"])?.updateServerStatusCache(data["GroupServer"], data["ConnectionState"]); profileCN.getProfile(data["ProfileOnion"])?.contactList.contacts.forEach((contact) { if (contact.isGroup == true && contact.server == data["GroupServer"]) { diff --git a/lib/widgets/messagelist.dart b/lib/widgets/messagelist.dart index 67158294..b17b7bbf 100644 --- a/lib/widgets/messagelist.dart +++ b/lib/widgets/messagelist.dart @@ -24,8 +24,8 @@ class _MessageListState extends State { bool showEphemeralWarning = (isP2P && Provider.of(context).savePeerHistory != "SaveHistory"); bool showOfflineWarning = Provider.of(context).isOnline() == false; - bool showMessageWarning = showEphemeralWarning || showOfflineWarning; bool showSyncing = isGroupAndSyncing; + bool showMessageWarning = showEphemeralWarning || showOfflineWarning || showSyncing; // Only load historical messages when the conversation is with a p2p contact OR the conversation is a server and *not* syncing. bool loadMessages = isP2P || (isGroupAndSynced || isGroupAndNotAuthenticated); From 9c9ea3845683357450ce47fea53f3cbbbf07db6a Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Tue, 29 Jun 2021 17:17:42 -0700 Subject: [PATCH 4/5] Propagate group name on Android properly --- android/app/src/main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/app/src/main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt b/android/app/src/main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt index 7cb33d71..35ebf16c 100644 --- a/android/app/src/main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt +++ b/android/app/src/main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt @@ -178,7 +178,7 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) : "CreateGroup" -> { val profile = (a.get("ProfileOnion") as? String) ?: "" val server = (a.get("server") as? String) ?: "" - val groupName = (a.get("groupname") as? String) ?: "" + val groupName = (a.get("groupName") as? String) ?: "" Cwtch.createGroup(profile, server, groupName) } "DeleteProfile" -> { From b832f71569e506c97d7e9b878e39a1fe1c1898cf Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Wed, 30 Jun 2021 11:35:07 -0700 Subject: [PATCH 5/5] Fix: #22 - Explictly pop to conversations after AddContact Also a few checks to prevent post-acceptence onChange events from breaking context. --- lib/views/addcontactview.dart | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/views/addcontactview.dart b/lib/views/addcontactview.dart index 5947d3fb..a8a1a422 100644 --- a/lib/views/addcontactview.dart +++ b/lib/views/addcontactview.dart @@ -152,9 +152,14 @@ class _AddContactViewState extends State { Future.delayed(const Duration(milliseconds: 500), () { if (globalErrorHandler.importBundleSuccess) { - final snackBar = SnackBar(content: Text(AppLocalizations.of(context)!.successfullAddedContact + importBundle)); - ScaffoldMessenger.of(context).showSnackBar(snackBar); - Navigator.pop(context); + // TODO: This isn't ideal, but because onChange can be fired during this future check + // and because the context can change after being popped we have this kind of double assertion... + // There is probably a better pattern to handle this... + if (AppLocalizations.of(context) != null) { + final snackBar = SnackBar(content: Text(AppLocalizations.of(context)!.successfullAddedContact + importBundle)); + ScaffoldMessenger.of(context).showSnackBar(snackBar); + Navigator.popUntil(context, (route) => route.settings.name == "conversations"); + } } }); },