From 414f18b19f1c33d4cfaff8fa0440130b76d86dcf Mon Sep 17 00:00:00 2001 From: "@a2sc:matrix.org" Date: Fri, 26 Feb 2021 18:01:24 +0000 Subject: [PATCH 01/91] Translated using Weblate (German) Currently translated at 99.2% (2759 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 3f657e105b..269fef0da1 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -16,7 +16,7 @@ "Deops user with given id": "Setzt das Berechtigungslevel des/der Benutzer:in mit der angegebenen ID zurück", "Invites user with given id to current room": "Lädt den/die Benutzer:in mit der angegebenen ID in den aktuellen Raum ein", "Kicks user with given id": "Benutzer:in mit der angegebenen ID kicken", - "Changes your display nickname": "Ändert deinen angezeigten Nicknamen", + "Changes your display nickname": "Ändert deinen Anzeigenamen", "Change Password": "Passwort ändern", "Searches DuckDuckGo for results": "Verwendet DuckDuckGo für Suchergebnisse", "Commands": "Kommandos", @@ -115,7 +115,7 @@ "You are already in a call.": "Du bist bereits in einem Gespräch.", "You cannot place a call with yourself.": "Du kannst keinen Anruf mit dir selbst starten.", "You cannot place VoIP calls in this browser.": "VoIP-Gespräche werden von diesem Browser nicht unterstützt.", - "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Deine E-Mail-Adresse scheint nicht mit einer Matrix-ID auf diesem Home-Server verbunden zu sein.", + "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Deine E-Mail-Adresse scheint nicht mit einer Matrix-ID auf diesem Homeserver verbunden zu sein.", "Sun": "So", "Mon": "Mo", "Tue": "Di", @@ -636,7 +636,7 @@ "Which officially provided instance you are using, if any": "Welche offiziell angebotene Instanz du nutzt, wenn überhaupt eine", "In reply to ": "Als Antwort auf ", "This room is not public. You will not be able to rejoin without an invite.": "Dies ist kein öffentlicher Raum. Du wirst diesen nicht ohne Einladung wieder beitreten können.", - "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s änderte den Anzeigenamen auf %(displayName)s.", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s hat den Anzeigenamen zu %(displayName)s geändert.", "Failed to set direct chat tag": "Fehler beim Setzen der Direkt-Chat-Markierung", "Failed to remove tag %(tagName)s from room": "Entfernen der Raum-Kennzeichnung %(tagName)s fehlgeschlagen", "Failed to add tag %(tagName)s to room": "Fehler beim Hinzufügen des \"%(tagName)s\"-Tags an dem Raum", @@ -834,7 +834,7 @@ "This event could not be displayed": "Dieses Ereignis konnte nicht angezeigt werden", "A call is currently being placed!": "Ein Anruf wurde schon gestartet!", "Permission Required": "Berechtigung benötigt", - "You do not have permission to start a conference call in this room": "Du hast keine Berechtigung um ein Konferenzgespräch in diesem Raum zu starten", + "You do not have permission to start a conference call in this room": "Du hast keine Berechtigung ein Konferenzgespräch in diesem Raum zu starten", "Failed to remove widget": "Widget konnte nicht entfernt werden", "An error ocurred whilst trying to remove the widget from the room": "Ein Fehler trat auf während versucht wurde, das Widget aus diesem Raum zu entfernen", "System Alerts": "System-Benachrichtigung", @@ -2944,8 +2944,8 @@ "Homeserver": "Heimserver", "You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use Element with an existing Matrix account on a different homeserver.": "Du kannst in den benutzerdefinierten Serveroptionen eine andere Heimserver-URL angeben, um dich bei anderen Matrixservern anzumelden.", "Server Options": "Servereinstellungen", - "No other application is using the webcam": "Keine andere Anwendung auf die Webcam zugreift", - "Permission is granted to use the webcam": "Auf die Webcam zugegriffen werden darf", + "No other application is using the webcam": "keine andere Anwendung auf die Webcam zugreift", + "Permission is granted to use the webcam": "auf die Webcam zugegriffen werden darf", "A microphone and webcam are plugged in and set up correctly": "Mikrofon und Webcam eingesteckt und richtig eingerichtet sind", "Call failed because no microphone could not be accessed. Check that a microphone is plugged in and set up correctly.": "Der Anruf ist fehlgeschlagen weil nicht auf das Mikrofon zugegriffen werden konnte. Stelle sicher, dass das Mikrofon richtig eingesteckt und eingerichtet ist.", "Call failed because no webcam or microphone could not be accessed. Check that:": "Der Anruf ist fehlgeschlagen weil nicht auf das Mikrofon oder die Webcam zugegriffen werden konnte. Stelle sicher, dass:", From d83b935fc0f80bf9460b94254a54eb2cf0e52a63 Mon Sep 17 00:00:00 2001 From: libexus Date: Thu, 25 Feb 2021 07:30:54 +0000 Subject: [PATCH 02/91] Translated using Weblate (German) Currently translated at 99.2% (2759 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 269fef0da1..ff754e7d7e 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -181,7 +181,7 @@ "%(senderName)s unbanned %(targetName)s.": "%(senderName)s hat die Verbannung von %(targetName)s aufgehoben.", "Usage": "Verwendung", "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s hat die Einladung für %(targetName)s zurückgezogen.", - "You need to be able to invite users to do that.": "Du brauchst die Berechtigung Benutzer:innen einzuladen haben, um diese Aktion ausführen zu können.", + "You need to be able to invite users to do that.": "Du musst die Berechtigung \"Benutzer:innen einladen\" haben, um diese Aktion ausführen zu können.", "You need to be logged in.": "Du musst angemeldet sein.", "There are no visible files in this room": "Es gibt keine sichtbaren Dateien in diesem Raum", "Connectivity to the server has been lost.": "Verbindung zum Server wurde unterbrochen.", @@ -1636,7 +1636,7 @@ "Use Single Sign On to continue": "Single-Sign-On zum Fortfahren nutzen", "Confirm adding this email address by using Single Sign On to prove your identity.": "Bestätige die hinzugefügte E-Mail-Adresse mit Single Sign-On, um deine Identität nachzuweisen.", "Single Sign On": "Single Sign-On", - "Confirm adding email": "Bestätige hinzugefügte E-Mail-Addresse", + "Confirm adding email": "Hinzugefügte E-Mail-Addresse bestätigen", "Confirm adding this phone number by using Single Sign On to prove your identity.": "Bestätige die hinzugefügte Telefonnummer, indem du deine Identität mittels Single Sign-On nachweist.", "Click the button below to confirm adding this phone number.": "Klicke unten die Schaltfläche, um die hinzugefügte Telefonnummer zu bestätigen.", "If you cancel now, you won't complete your operation.": "Wenn du jetzt abbrichst, wirst du deinen Vorgang nicht fertigstellen.", @@ -3059,5 +3059,16 @@ "Cookie Policy": "Cookie-Richtlinie", "Learn more in our , and .": "Erfahren mehr in unserer , und .", "Failed to connect to your homeserver. Please close this dialog and try again.": "Verbindung zum Homeserver fehlgeschlagen. Bitte schließe diesen Dialog and versuche es erneut.", - "Abort": "Abbrechen" + "Abort": "Abbrechen", + "Upgrade to %(hostSignupBrand)s": "Zu %(hostSignupBrand)s upgraden", + "Edit Values": "Werte bearbeiten", + "Value in this room:": "Wert in diesem Raum:", + "Value:": "Wert:", + "Level": "Level", + "This UI does NOT check the types of the values. Use at your own risk.": "Diese Benutzeroberfläche prüft nicht auf richtige Datentypen. Benutzung auf eigene Gefahr.", + "Setting:": "Einstellung:", + "Value": "Wert", + "Setting ID": "Einstellungs-ID", + "Failed to save settings": "Einstellungen konnten nicht gespeichert werden", + "Show chat effects (animations when receiving e.g. confetti)": "Animierte Chateffekte zeigen, wenn z.B. Konfetti-Emojis erhalten werden" } From de73cef7e61ea57e1750f246e0a9f7d9ef785472 Mon Sep 17 00:00:00 2001 From: libexus Date: Fri, 26 Feb 2021 18:02:04 +0000 Subject: [PATCH 03/91] Translated using Weblate (German) Currently translated at 99.2% (2759 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index ff754e7d7e..29b86ac641 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -636,7 +636,7 @@ "Which officially provided instance you are using, if any": "Welche offiziell angebotene Instanz du nutzt, wenn überhaupt eine", "In reply to ": "Als Antwort auf ", "This room is not public. You will not be able to rejoin without an invite.": "Dies ist kein öffentlicher Raum. Du wirst diesen nicht ohne Einladung wieder beitreten können.", - "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s hat den Anzeigenamen zu %(displayName)s geändert.", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s hat den Anzeigenamen auf %(displayName)s geändert.", "Failed to set direct chat tag": "Fehler beim Setzen der Direkt-Chat-Markierung", "Failed to remove tag %(tagName)s from room": "Entfernen der Raum-Kennzeichnung %(tagName)s fehlgeschlagen", "Failed to add tag %(tagName)s to room": "Fehler beim Hinzufügen des \"%(tagName)s\"-Tags an dem Raum", From 905f5300f49e2770d77d8d3e9c86484735bcbdaa Mon Sep 17 00:00:00 2001 From: Nikita Epifanov Date: Thu, 25 Feb 2021 11:01:31 +0000 Subject: [PATCH 04/91] Translated using Weblate (Russian) Currently translated at 99.4% (2765 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index a72eef2c58..65aeaf82d9 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -3057,5 +3057,20 @@ "Your homeserver was unreachable and was not able to log you in. Please try again. If this continues, please contact your homeserver administrator.": "Ваш домашний сервер был недоступен, и мы не смогли войти в систему. Пожалуйста, попробуйте снова через пару минут. Если ситуация по-прежнему не меняется, обратитесь к администратору домашнего сервера за дополнительной информацией.", "Try again": "Попробовать ещё раз", "We asked the browser to remember which homeserver you use to let you sign in, but unfortunately your browser has forgotten it. Go to the sign in page and try again.": "Мы попросили браузер запомнить, какой домашний сервер вы используете для входа в систему, но, к сожалению, ваш браузер забыл об этом. Перейдите на страницу входа и попробуйте ещё раз.", - "We couldn't log you in": "Нам не удалось войти в систему" + "We couldn't log you in": "Нам не удалось войти в систему", + "Upgrade to %(hostSignupBrand)s": "Перейти на %(hostSignupBrand)s", + "Edit Values": "Изменить значения", + "Value in this room:": "Значение в этой комнате:", + "Value:": "Значение:", + "Setting:": "Настройки:", + "Setting ID": "ID настроек", + "Save setting values": "Сохранить значения настроек", + "Settable at room": "Устанавливается для комнаты", + "Settable at global": "Устанавливается на глобальном уровне", + "Level": "Уровень", + "This UI does NOT check the types of the values. Use at your own risk.": "Этот пользовательский интерфейс НЕ проверяет типы значений. Используйте на свой риск.", + "Value in this room": "Значение в этой комнате", + "Value": "Значение", + "Failed to save settings": "Не удалось сохранить настройки", + "Show chat effects (animations when receiving e.g. confetti)": "Показать эффекты чата (анимация при получении, например, конфетти)" } From 4b771b0634594dcc8205fcc19ac49e107079c24f Mon Sep 17 00:00:00 2001 From: libexus Date: Sat, 27 Feb 2021 14:58:24 +0000 Subject: [PATCH 05/91] Translated using Weblate (German) Currently translated at 99.2% (2759 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 29b86ac641..e2e2e0718a 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -1569,7 +1569,7 @@ "%(senderName)s removed the alternative addresses %(addresses)s for this room.|one": "%(senderName)s hat die alternative Adresse %(addresses)s für diesen Raum entfernt.", "%(senderName)s changed the alternative addresses for this room.": "%(senderName)s hat die alternative Adresse für diesen Raum geändert.", "%(senderName)s changed the main and alternative addresses for this room.": "%(senderName)s hat die Haupt- und Alternativadressen für diesen Raum geändert.", - "%(senderName)s removed the rule banning users matching %(glob)s": "%(senderName)s entfernte die Ausschluss-Regel für Nutzer!nnen, die %(glob)s entsprechen", + "%(senderName)s removed the rule banning users matching %(glob)s": "%(senderName)s entfernte die Ausschluss-Regel für Benutzer:innen, die %(glob)s entsprechen", "%(senderName)s removed the rule banning rooms matching %(glob)s": "%(senderName)s entfernte die Ausschluss-Regel für Räume, die %(glob)s entsprechen", "%(senderName)s removed the rule banning servers matching %(glob)s": "%(senderName)s entfernte die Ausschluss-Regel für Server, die %(glob)s entsprechen", "%(senderName)s removed a ban rule matching %(glob)s": "%(senderName)s entfernte die Ausschluss-Regel, die %(glob)s entspricht", @@ -2567,7 +2567,7 @@ "See when the name changes in this room": "Sehen wenn sich der Name in diesem Raum ändert", "Change the name of your active room": "Den Namen deines aktiven Raums ändern", "See when the name changes in your active room": "Sehen wenn der Name sich in deinem aktiven Raum ändert", - "Change the avatar of this room": "Avatar von diesem Raum ändern", + "Change the avatar of this room": "Icon von diesem Raum ändern", "See when the avatar changes in this room": "Sehen wenn der Avatar sich in diesem Raum ändert", "Change the avatar of your active room": "Den Avatar deines aktiven Raums ändern", "See when the avatar changes in your active room": "Sehen wenn ein Avatar in deinem aktiven Raum geändert wird", @@ -3036,7 +3036,7 @@ "Converts the room to a DM": "Wandelt den Raum zu Direktnachricht um", "Something went wrong in confirming your identity. Cancel and try again.": "Bei der Bestätigung deiner Identität ist ein Fehler aufgetreten. Abbrechen und erneut versuchen.", "Use app": "App verwenden", - "Element Web is experimental on mobile. For a better experience and the latest features, use our free native app.": "Element Web ist experimentell auf mobilen Endgeräten. Für eine bessere Erfahrung und die neuesten Erweiterungen, nutze unsere freie, native App.", + "Element Web is experimental on mobile. For a better experience and the latest features, use our free native app.": "Element Web ist auf mobilen Endgeräten experimentell. Für eine bessere Erfahrung und die neuesten Features, nutze unsere freie, native App.", "Use app for a better experience": "Nutze die App für eine bessere Erfahrung", "We asked the browser to remember which homeserver you use to let you sign in, but unfortunately your browser has forgotten it. Go to the sign in page and try again.": "Wir haben deinen Browser gebeten, sich zu merken, bei welchem Homeserver du dich anmeldest, aber dein Browser hat dies leider vergessen. Gehe zur Anmeldeseite und versuche es erneut.", "Show stickers button": "Sticker-Schaltfläche anzeigen", From 844ed6b0b9c5e8a99aad99192e9506b047d72904 Mon Sep 17 00:00:00 2001 From: "@a2sc:matrix.org" Date: Fri, 26 Feb 2021 18:04:45 +0000 Subject: [PATCH 06/91] Translated using Weblate (German) Currently translated at 99.2% (2759 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index e2e2e0718a..b615cda081 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -636,7 +636,7 @@ "Which officially provided instance you are using, if any": "Welche offiziell angebotene Instanz du nutzt, wenn überhaupt eine", "In reply to ": "Als Antwort auf ", "This room is not public. You will not be able to rejoin without an invite.": "Dies ist kein öffentlicher Raum. Du wirst diesen nicht ohne Einladung wieder beitreten können.", - "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s hat den Anzeigenamen auf %(displayName)s geändert.", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s hat den Anzeigenamen zu %(displayName)s geändert.", "Failed to set direct chat tag": "Fehler beim Setzen der Direkt-Chat-Markierung", "Failed to remove tag %(tagName)s from room": "Entfernen der Raum-Kennzeichnung %(tagName)s fehlgeschlagen", "Failed to add tag %(tagName)s to room": "Fehler beim Hinzufügen des \"%(tagName)s\"-Tags an dem Raum", @@ -2664,7 +2664,7 @@ "Fill Screen": "Bildschirm ausfüllen", "Voice Call": "Sprachanruf", "Video Call": "Videoanruf", - "Remain on your screen while running": "Bleiben Sie auf Ihrem Bildschirm während der Ausführung von", + "Remain on your screen while running": "Bleib auf deinem Bildschirm während der Ausführung von", "Remain on your screen when viewing another room, when running": "Bleiben Sie auf Ihrem Bildschirm, während Sie einen anderen Raum betrachten, wenn Sie ausführen", "Zimbabwe": "Simbabwe", "Zambia": "Sambia", From 94fbd7c9b127faaab1c668a101b6b0506798d767 Mon Sep 17 00:00:00 2001 From: "@a2sc:matrix.org" Date: Sat, 27 Feb 2021 14:58:41 +0000 Subject: [PATCH 07/91] Translated using Weblate (German) Currently translated at 99.2% (2759 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index b615cda081..8a07b6cd9f 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -3036,7 +3036,7 @@ "Converts the room to a DM": "Wandelt den Raum zu Direktnachricht um", "Something went wrong in confirming your identity. Cancel and try again.": "Bei der Bestätigung deiner Identität ist ein Fehler aufgetreten. Abbrechen und erneut versuchen.", "Use app": "App verwenden", - "Element Web is experimental on mobile. For a better experience and the latest features, use our free native app.": "Element Web ist auf mobilen Endgeräten experimentell. Für eine bessere Erfahrung und die neuesten Features, nutze unsere freie, native App.", + "Element Web is experimental on mobile. For a better experience and the latest features, use our free native app.": "Element Web ist auf mobilen Endgeräten experimentell. Für eine bessere Erfahrung und die neuesten Erweiterungen, nutze unsere freie, native App.", "Use app for a better experience": "Nutze die App für eine bessere Erfahrung", "We asked the browser to remember which homeserver you use to let you sign in, but unfortunately your browser has forgotten it. Go to the sign in page and try again.": "Wir haben deinen Browser gebeten, sich zu merken, bei welchem Homeserver du dich anmeldest, aber dein Browser hat dies leider vergessen. Gehe zur Anmeldeseite und versuche es erneut.", "Show stickers button": "Sticker-Schaltfläche anzeigen", From d6d5455a11915a313b137b4a8f98bde762441117 Mon Sep 17 00:00:00 2001 From: Thibault Martin Date: Thu, 25 Feb 2021 17:17:39 +0000 Subject: [PATCH 08/91] Translated using Weblate (French) Currently translated at 99.2% (2758 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 260 +++++++++++++++++++-------------------- 1 file changed, 130 insertions(+), 130 deletions(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index c942cae520..304599cd44 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -1,6 +1,6 @@ { "Disinvite": "Désinviter", - "Displays action": "Affiche l'action", + "Displays action": "Affiche l’action", "Download %(text)s": "Télécharger %(text)s", "Emoji": "Émojis", "%(senderName)s ended the call.": "%(senderName)s a terminé l’appel.", @@ -32,14 +32,14 @@ "%(senderName)s banned %(targetName)s.": "%(senderName)s a banni %(targetName)s.", "Ban": "Bannir", "Banned users": "Utilisateurs bannis", - "Bans user with given id": "Bannit l'utilisateur à partir de son identifiant", + "Bans user with given id": "Bannit l’utilisateur à partir de son identifiant", "Call Timeout": "L’appel a dépassé le délai d'attente maximal", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Impossible de se connecter au serveur d'accueil en HTTP si l'URL dans la barre de votre explorateur est en HTTPS. Utilisez HTTPS ou activez le support des scripts non-vérifiés.", "Change Password": "Changer le mot de passe", "%(senderName)s changed their profile picture.": "%(senderName)s a changé son image de profil.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s a changé le rang de %(powerLevelDiffText)s.", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s a changé le nom du salon en %(roomName)s.", - "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s a changé le sujet du salon en \"%(topic)s\".", + "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s a changé le sujet du salon en « %(topic)s ».", "Changes your display nickname": "Change votre nom affiché", "Click here to fix": "Cliquer ici pour réparer", "Click to mute audio": "Cliquer pour couper le son", @@ -54,7 +54,7 @@ "Create Room": "Créer un salon", "Cryptography": "Chiffrement", "Current password": "Mot de passe actuel", - "/ddg is not a command": "/ddg n'est pas une commande", + "/ddg is not a command": "/ddg n’est pas une commande", "Deactivate Account": "Fermer le compte", "Decrypt %(text)s": "Déchiffrer %(text)s", "Deops user with given id": "Retire le rang d’opérateur d’un utilisateur à partir de son identifiant", @@ -66,7 +66,7 @@ "Failed to reject invite": "Échec du rejet de l'invitation", "Failed to reject invitation": "Échec du rejet de l'invitation", "Failed to send email": "Échec de l’envoi de l’e-mail", - "Failed to send request.": "Échec de l'envoi de la requête.", + "Failed to send request.": "Échec de l’envoi de la requête.", "Failed to set display name": "Échec de l'enregistrement du nom affiché", "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s a accepté l’invitation de %(displayName)s.", "Access Token:": "Jeton d’accès :", @@ -101,17 +101,17 @@ "%(targetName)s joined the room.": "%(targetName)s a rejoint le salon.", "%(senderName)s kicked %(targetName)s.": "%(senderName)s a expulsé %(targetName)s.", "Kick": "Expulser", - "Kicks user with given id": "Expulse l'utilisateur à partir de son identifiant", + "Kicks user with given id": "Expulse l’utilisateur à partir de son identifiant", "Labs": "Labo", "Leave room": "Quitter le salon", "%(targetName)s left the room.": "%(targetName)s a quitté le salon.", "Logout": "Se déconnecter", "Low priority": "Priorité basse", - "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s a rendu l'historique visible à tous les membres du salon, depuis le moment où ils ont été invités.", - "%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s a rendu l'historique visible à tous les membres du salon, depuis le moment où ils ont rejoint.", - "%(senderName)s made future room history visible to all room members.": "%(senderName)s a rendu l'historique visible à tous les membres du salon.", - "%(senderName)s made future room history visible to anyone.": "%(senderName)s a rendu l'historique visible à n'importe qui.", - "%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s a rendu l'historique visible à inconnu (%(visibility)s).", + "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s a rendu l’historique visible à tous les membres du salon, depuis le moment où ils ont été invités.", + "%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s a rendu l’historique visible à tous les membres du salon, à partir de leur arrivée.", + "%(senderName)s made future room history visible to all room members.": "%(senderName)s a rendu l’historique visible à tous les membres du salon.", + "%(senderName)s made future room history visible to anyone.": "%(senderName)s a rendu l’historique visible à tout le monde.", + "%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s a rendu l’historique visible à inconnu (%(visibility)s).", "Manage Integrations": "Gestion des intégrations", "Missing room_id in request": "Absence du room_id dans la requête", "Missing user_id in request": "Absence du user_id dans la requête", @@ -120,7 +120,7 @@ "New passwords don't match": "Les mots de passe ne correspondent pas", "New passwords must match each other.": "Les nouveaux mots de passe doivent être identiques.", "not specified": "non spécifié", - "(not supported by this browser)": "(non supporté par ce navigateur)", + "(not supported by this browser)": "(non pris en charge par ce navigateur)", "": "", "No more results": "Fin des résultats", "No results": "Pas de résultat", @@ -141,7 +141,7 @@ "No users have specific privileges in this room": "Aucun utilisateur n’a de privilège spécifique dans ce salon", "olm version:": "version de olm :", "Please check your email and click on the link it contains. Once this is done, click continue.": "Veuillez vérifier vos e-mails et cliquer sur le lien que vous avez reçu. Puis cliquez sur continuer.", - "Power level must be positive integer.": "Le niveau d'autorité doit être un entier positif.", + "Power level must be positive integer.": "Le rang doit être un entier positif.", "Privileged Users": "Utilisateurs privilégiés", "Profile": "Profil", "Reason": "Raison", @@ -151,10 +151,10 @@ "%(senderName)s removed their profile picture.": "%(senderName)s a supprimé son image de profil.", "%(senderName)s requested a VoIP conference.": "%(senderName)s a demandé une téléconférence audio.", "Return to login screen": "Retourner à l’écran de connexion", - "%(brand)s does not have permission to send you notifications - please check your browser settings": "%(brand)s n’a pas la permission de vous envoyer des notifications - merci de vérifier les paramètres de votre navigateur", - "%(brand)s was not given permission to send notifications - please try again": "%(brand)s n’a pas reçu la permission de vous envoyer des notifications - veuillez réessayer", + "%(brand)s does not have permission to send you notifications - please check your browser settings": "%(brand)s n’a pas l’autorisation de vous envoyer des notifications - merci de vérifier les paramètres de votre navigateur", + "%(brand)s was not given permission to send notifications - please try again": "%(brand)s n’a pas reçu l’autorisation de vous envoyer des notifications - veuillez réessayer", "%(brand)s version:": "Version de %(brand)s :", - "Room %(roomId)s not visible": "Le salon %(roomId)s n'est pas visible", + "Room %(roomId)s not visible": "Le salon %(roomId)s n’est pas visible", "Room Colour": "Couleur du salon", "Rooms": "Salons", "Search": "Rechercher", @@ -165,7 +165,7 @@ "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s a invité %(targetDisplayName)s à rejoindre le salon.", "Server error": "Erreur du serveur", "Server may be unavailable, overloaded, or search timed out :(": "Le serveur semble être inaccessible, surchargé ou la recherche a expiré :(", - "Server may be unavailable, overloaded, or you hit a bug.": "Le serveur semble être indisponible, surchargé ou vous avez rencontré un problème.", + "Server may be unavailable, overloaded, or you hit a bug.": "Le serveur semble être indisponible, surchargé ou vous êtes tombé sur un bug.", "Server unavailable, overloaded, or something else went wrong.": "Le serveur semble être inaccessible, surchargé ou quelque chose s'est mal passé.", "Session ID": "Identifiant de session", "%(senderName)s set a profile picture.": "%(senderName)s a défini une image de profil.", @@ -175,7 +175,7 @@ "Sign in": "Se connecter", "Sign out": "Se déconnecter", "%(count)s of your messages have not been sent.|other": "Certains de vos messages n’ont pas été envoyés.", - "Someone": "Quelqu'un", + "Someone": "Quelqu’un", "Submit": "Soumettre", "Success": "Succès", "This email address is already in use": "Cette adresse e-mail est déjà utilisée", @@ -183,7 +183,7 @@ "The email address linked to your account must be entered.": "L’adresse e-mail liée à votre compte doit être renseignée.", "The remote side failed to pick up": "Le correspondant n’a pas décroché", "This room has no local addresses": "Ce salon n'a pas d'adresse locale", - "This room is not recognised.": "Ce salon n'est pas reconnu.", + "This room is not recognised.": "Ce salon n’est pas reconnu.", "This doesn't appear to be a valid email address": "Cette adresse e-mail ne semble pas valide", "This phone number is already in use": "Ce numéro de téléphone est déjà utilisé", "This room is not accessible by remote Matrix servers": "Ce salon n’est pas accessible par les serveurs Matrix distants", @@ -195,8 +195,8 @@ "Unable to verify email address.": "Impossible de vérifier l’adresse e-mail.", "Unban": "Révoquer le bannissement", "%(senderName)s unbanned %(targetName)s.": "%(senderName)s a révoqué le bannissement de %(targetName)s.", - "Unable to capture screen": "Impossible de faire une capture d'écran", - "Unable to enable Notifications": "Impossible d'activer les notifications", + "Unable to capture screen": "Impossible de faire une capture d’écran", + "Unable to enable Notifications": "Impossible d’activer les notifications", "Unmute": "Activer le son", "Upload avatar": "Télécharger une photo de profil", "Upload Failed": "Échec de l’envoi", @@ -208,19 +208,19 @@ "Voice call": "Appel vocal", "VoIP conference finished.": "Téléconférence VoIP terminée.", "VoIP conference started.": "Téléconférence VoIP démarrée.", - "VoIP is unsupported": "Voix sur IP non gérée", + "VoIP is unsupported": "Voix sur IP non prise en charge", "Warning!": "Attention !", "Who can access this room?": "Qui peut accéder au salon ?", "Who can read history?": "Qui peut lire l'historique ?", "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s a annulé l’invitation de %(targetName)s.", "You are already in a call.": "Vous avez déjà un appel en cours.", - "You cannot place a call with yourself.": "Vous ne pouvez pas passer d'appel avec vous-même.", - "You cannot place VoIP calls in this browser.": "Vous ne pouvez pas passer d'appel en Voix sur IP dans ce navigateur.", + "You cannot place a call with yourself.": "Vous ne pouvez pas passer d’appel avec vous-même.", + "You cannot place VoIP calls in this browser.": "Vous ne pouvez pas passer d’appel en Voix sur IP dans ce navigateur.", "You do not have permission to post to this room": "Vous n’avez pas la permission de poster dans ce salon", "You have no visible notifications": "Vous n'avez pas de notification visible", - "You need to be able to invite users to do that.": "Vous devez être capable d’inviter des utilisateurs pour faire ça.", + "You need to be able to invite users to do that.": "Vous devez avoir l’autorisation d’inviter des utilisateurs pour faire ceci.", "You need to be logged in.": "Vous devez être identifié.", - "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Votre adresse e-mail ne semble pas être associée à un identifiant Matrix sur ce serveur d'accueil.", + "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Votre adresse e-mail ne semble pas être associée à un identifiant Matrix sur ce serveur d’accueil.", "You seem to be in a call, are you sure you want to quit?": "Vous semblez avoir un appel en cours, voulez-vous vraiment partir ?", "You seem to be uploading files, are you sure you want to quit?": "Vous semblez être en train d'envoyer des fichiers, voulez-vous vraiment partir ?", "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Vous ne pourrez pas annuler cette modification car vous promouvez l’utilisateur au même rang que le vôtre.", @@ -377,7 +377,7 @@ "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (rang %(powerLevelNumber)s)", "(could not connect media)": "(impossible de se connecter au média)", "(no answer)": "(pas de réponse)", - "(unknown failure: %(reason)s)": "(erreur inconnue : %(reason)s)", + "(unknown failure: %(reason)s)": "(erreur inconnue : %(reason)s)", "Your browser does not support the required cryptography extensions": "Votre navigateur ne supporte pas les extensions cryptographiques nécessaires", "Not a valid %(brand)s keyfile": "Fichier de clé %(brand)s non valide", "Authentication check failed: incorrect password?": "Erreur d’authentification : mot de passe incorrect ?", @@ -388,13 +388,13 @@ "Add a widget": "Ajouter un widget", "Allow": "Autoriser", "Delete widget": "Supprimer le widget", - "Define the power level of a user": "Définir le rang d'un utilisateur", + "Define the power level of a user": "Définir le rang d’un utilisateur", "Edit": "Modifier", "Enable automatic language detection for syntax highlighting": "Activer la détection automatique de la langue pour la correction orthographique", "To get started, please pick a username!": "Pour commencer, choisissez un nom d'utilisateur !", "Unable to create widget.": "Impossible de créer le widget.", - "You are not in this room.": "Vous n'êtes pas dans ce salon.", - "You do not have permission to do that in this room.": "Vous n'avez pas la permission d'effectuer cette action dans ce salon.", + "You are not in this room.": "Vous n’êtes pas dans ce salon.", + "You do not have permission to do that in this room.": "Vous n’avez pas l’autorisation d’effectuer cette action dans ce salon.", "Example": "Exemple", "Create": "Créer", "Featured Rooms:": "Salons mis en avant :", @@ -411,21 +411,21 @@ "Copied!": "Copié !", "Failed to copy": "Échec de la copie", "%(widgetName)s widget modified by %(senderName)s": "Widget %(widgetName)s modifié par %(senderName)s", - "Who would you like to add to this community?": "Qui souhaitez-vous ajouter à cette communauté ?", - "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Attention : toute personne ajoutée à une communauté sera visible par tous ceux connaissant l'identifiant de la communauté", - "Invite new community members": "Inviter de nouveaux membres dans cette communauté", - "Which rooms would you like to add to this community?": "Quels salons souhaitez-vous ajouter à cette communauté ?", + "Who would you like to add to this community?": "Qui souhaitez-vous ajouter à cette communauté ?", + "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Attention : toute personne ajoutée à une communauté sera visible par tous ceux connaissant l’identifiant de la communauté", + "Invite new community members": "Inviter de nouvelles personnes dans cette communauté", + "Which rooms would you like to add to this community?": "Quels salons souhaitez-vous ajouter à cette communauté ?", "Add rooms to the community": "Ajouter des salons à la communauté", "Add to community": "Ajouter à la communauté", - "Failed to invite the following users to %(groupId)s:": "Échec de l'invitation des utilisateurs à %(groupId)s :", - "Failed to invite users to community": "Échec de l'invitation d'utilisateurs à la communauté", - "Failed to invite users to %(groupId)s": "Échec de l'invitation d'utilisateurs à %(groupId)s", - "Failed to add the following rooms to %(groupId)s:": "Échec de l'ajout des salons suivants à %(groupId)s :", + "Failed to invite the following users to %(groupId)s:": "Échec de l’invitation des utilisateurs suivants à %(groupId)s :", + "Failed to invite users to community": "Échec de l’invitation des utilisateurs à la communauté", + "Failed to invite users to %(groupId)s": "Échec de l’invitation des utilisateurs à %(groupId)s", + "Failed to add the following rooms to %(groupId)s:": "Échec de l’ajout des salons suivants à %(groupId)s :", "Ignored user": "Utilisateur ignoré", - "You are now ignoring %(userId)s": "Dorénavant vous ignorez %(userId)s", - "Unignored user": "Utilisateur n'étant plus ignoré", - "You are no longer ignoring %(userId)s": "Vous n'ignorez plus %(userId)s", - "Invite to Community": "Inviter dans la Communauté", + "You are now ignoring %(userId)s": "Vous ignorez désormais %(userId)s", + "Unignored user": "L’utilisateur n’est plus ignoré", + "You are no longer ignoring %(userId)s": "Vous n’ignorez plus %(userId)s", + "Invite to Community": "Inviter dans la communauté", "Communities": "Communautés", "Message Pinning": "Épingler un message", "Mention": "Mentionner", @@ -573,7 +573,7 @@ "Mirror local video feed": "Inverser horizontalement la vidéo locale (effet miroir)", "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "Un e-mail a été envoyé à %(emailAddress)s. Après avoir suivi le lien présent dans celui-ci, cliquez ci-dessous.", "Ignores a user, hiding their messages from you": "Ignore un utilisateur, en masquant ses messages", - "Stops ignoring a user, showing their messages going forward": "N'ignore plus un utilisateur, en affichant ses messages à partir de maintenant", + "Stops ignoring a user, showing their messages going forward": "Arrête d’ignorer un utilisateur, en affichant ses messages à partir de maintenant", "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "La visibilité de \"%(roomName)s\" dans %(groupId)s n'a pas pu être mise à jour.", "Visibility in Room List": "Visibilité dans la liste des salons", "Visible to everyone": "Visible pour tout le monde", @@ -609,7 +609,7 @@ "Display your community flair in rooms configured to show it.": "Sélectionnez les badges dans les paramètres de chaque salon pour les afficher.", "expand": "développer", "collapse": "réduire", - "Call Failed": "L'appel a échoué", + "Call Failed": "L’appel a échoué", "Send": "Envoyer", "Old cryptography data detected": "Anciennes données de chiffrement détectées", "Data from an older version of %(brand)s has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Nous avons détecté des données d'une ancienne version de %(brand)s. Le chiffrement de bout en bout n'aura pas fonctionné correctement sur l'ancienne version. Les messages chiffrés échangés récemment dans l'ancienne version ne sont peut-être pas déchiffrables dans cette version. Les échanges de message avec cette version peuvent aussi échouer. Si vous rencontrez des problèmes, déconnectez-vous puis reconnectez-vous. Pour conserver l'historique des messages, exportez puis réimportez vos clés de chiffrement.", @@ -625,13 +625,13 @@ "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Le respect de votre vie privée est important pour nous, donc nous ne collectons aucune donnée personnelle ou permettant de vous identifier pour nos statistiques.", "Learn more about how we use analytics.": "En savoir plus sur notre utilisation des statistiques.", "The information being sent to us to help make %(brand)s better includes:": "Les informations qui nous sont envoyées et qui nous aident à améliorer %(brand)s comportent :", - "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Si la page contient des informations permettant de vous identifier, comme un salon, un identifiant d'utilisateur ou de groupe, ces données sont enlevées avant qu'elle ne soit envoyée au serveur.", + "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Si la page contient des informations permettant de vous identifier, comme un salon, un identifiant d’utilisateur ou de groupe, ces données sont enlevées avant qu’elle ne soit envoyée au serveur.", "The platform you're on": "La plateforme que vous utilisez", "The version of %(brand)s": "La version de %(brand)s", "Your language of choice": "La langue que vous avez choisie", - "Which officially provided instance you are using, if any": "L'instance officielle que vous utilisez, si vous en utilisez une", - "Whether or not you're using the Richtext mode of the Rich Text Editor": "Si vous utilisez le mode « texte enrichi » de l'éditeur de texte enrichi", - "Your homeserver's URL": "L'URL de votre serveur d'accueil", + "Which officially provided instance you are using, if any": "L’instance officielle que vous utilisez, si vous en utilisez une", + "Whether or not you're using the Richtext mode of the Rich Text Editor": "Si vous utilisez le mode « texte enrichi » de l’éditeur de texte enrichi", + "Your homeserver's URL": "L’URL de votre serveur d’accueil", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s %(day)s %(monthName)s %(fullYear)s", "This room is not public. You will not be able to rejoin without an invite.": "Ce salon n'est pas public. Vous ne pourrez pas y revenir sans invitation.", "Community IDs cannot be empty.": "Les identifiants de communauté ne peuvent pas être vides.", @@ -648,7 +648,7 @@ "Code": "Code", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Si vous avez signalé un bug via GitHub, les journaux de débogage peuvent nous aider à identifier le problème. Les journaux de débogage contiennent des données d'utilisation de l'application dont votre nom d'utilisateur, les identifiants ou alias des salons ou groupes que vous avez visité et les noms d'utilisateur des autres participants. Ils ne contiennent pas les messages.", "Submit debug logs": "Envoyer les journaux de débogage", - "Opens the Developer Tools dialog": "Ouvre la fenêtre des Outils de développeur", + "Opens the Developer Tools dialog": "Ouvre la fenêtre des outils de développeur", "Unable to join community": "Impossible de rejoindre la communauté", "Unable to leave community": "Impossible de quitter la communauté", "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Les changements effectués au nom et à l'avatar de votre communauté peuvent prendre jusqu'à 30 minutes avant d'être vus par d'autres utilisateurs.", @@ -784,7 +784,7 @@ "Preparing to send logs": "Préparation d'envoi des journaux", "Missing roomId.": "Identifiant de salon manquant.", "Popout widget": "Détacher le widget", - "Every page you use in the app": "Toutes les pages que vous utilisez dans l'application", + "Every page you use in the app": "Toutes les pages que vous utilisez dans l’application", "e.g. ": "par ex. ", "Your device resolution": "La résolution de votre appareil", "Always show encryption icons": "Toujours afficher les icônes de chiffrement", @@ -832,8 +832,8 @@ "Demote yourself?": "Vous rétrograder ?", "Demote": "Rétrograder", "This event could not be displayed": "Cet événement n'a pas pu être affiché", - "Permission Required": "Permission requise", - "You do not have permission to start a conference call in this room": "Vous n'avez pas la permission de lancer un appel en téléconférence dans ce salon", + "Permission Required": "Autorisation requise", + "You do not have permission to start a conference call in this room": "Vous n’avez pas l’autorisation de lancer un appel en téléconférence dans ce salon", "A call is currently being placed!": "Un appel est en cours !", "Failed to remove widget": "Échec de la suppression du widget", "An error ocurred whilst trying to remove the widget from the room": "Une erreur est survenue lors de la suppression du widget du salon", @@ -862,8 +862,8 @@ "Upgrade this room to version %(version)s": "Mettre à niveau ce salon vers la version %(version)s", "Forces the current outbound group session in an encrypted room to be discarded": "Force la session de groupe sortante actuelle dans un salon chiffré à être rejetée", "Unable to connect to Homeserver. Retrying...": "Impossible de se connecter au serveur d'accueil. Reconnexion...", - "%(senderName)s set the main address for this room to %(address)s.": "%(senderName)s a défini l'adresse principale pour ce salon comme %(address)s.", - "%(senderName)s removed the main address for this room.": "%(senderName)s a supprimé l'adresse principale de ce salon.", + "%(senderName)s set the main address for this room to %(address)s.": "%(senderName)s a défini l’adresse principale pour ce salon comme %(address)s.", + "%(senderName)s removed the main address for this room.": "%(senderName)s a supprimé l’adresse principale de ce salon.", "%(brand)s now uses 3-5x less memory, by only loading information about other users when needed. Please wait whilst we resynchronise with the server!": "%(brand)s utilise maintenant 3 à 5 fois moins de mémoire, en ne chargeant les informations des autres utilisateurs que quand elles sont nécessaires. Veuillez patienter pendant que l'on se resynchronise avec le serveur !", "Updating %(brand)s": "Mise à jour de %(brand)s", "Before submitting logs, you must create a GitHub issue to describe your problem.": "Avant de soumettre vos journaux, vous devez créer une « issue » sur GitHub pour décrire votre problème.", @@ -934,7 +934,7 @@ "Common names and surnames are easy to guess": "Les noms et prénoms répandus sont faciles à deviner", "Use a longer keyboard pattern with more turns": "Utilisez un schéma plus long et avec plus de variations", "Failed to load group members": "Échec du chargement des membres du groupe", - "Failed to invite users to the room:": "Échec de l'invitation d'utilisateurs dans le salon :", + "Failed to invite users to the room:": "Échec de l’invitation d'utilisateurs dans le salon :", "There was an error joining the room": "Une erreur est survenue en rejoignant le salon", "You do not have permission to invite people to this room.": "Vous n'avez pas la permission d'envoyer des invitations dans ce salon.", "User %(user_id)s does not exist": "L'utilisateur %(user_id)s n'existe pas", @@ -968,14 +968,14 @@ "Unable to find profiles for the Matrix IDs listed below - would you like to invite them anyway?": "Impossible de trouver les profils pour les identifiants Matrix listés ci-dessous. Voulez-vous quand même les inviter ?", "Invite anyway and never warn me again": "Inviter quand même et ne plus me prévenir", "Invite anyway": "Inviter quand même", - "Whether or not you're logged in (we don't record your username)": "Si vous êtes connecté ou pas (votre nom d'utilisateur n'est pas enregistré)", + "Whether or not you're logged in (we don't record your username)": "Si vous êtes connecté ou pas (votre nom d'utilisateur n’est pas enregistré)", "Upgrades a room to a new version": "Met à niveau un salon vers une nouvelle version", "Sets the room name": "Définit le nom du salon", "%(senderDisplayName)s upgraded this room.": "%(senderDisplayName)s a mis à niveau ce salon.", "%(displayName)s is typing …": "%(displayName)s est en train d'écrire…", - "%(names)s and %(count)s others are typing …|other": "%(names)s et %(count)s autres sont en train d'écrire…", - "%(names)s and %(count)s others are typing …|one": "%(names)s et un autre sont en train d'écrire…", - "%(names)s and %(lastPerson)s are typing …": "%(names)s et %(lastPerson)s sont en train d'écrire…", + "%(names)s and %(count)s others are typing …|other": "%(names)s et %(count)s autres sont en train d’écrire…", + "%(names)s and %(count)s others are typing …|one": "%(names)s et un autre sont en train d’écrire…", + "%(names)s and %(lastPerson)s are typing …": "%(names)s et %(lastPerson)s sont en train d’écrire…", "Enable Emoji suggestions while typing": "Activer la suggestion d’émojis lors de la saisie", "Render simple counters in room header": "Afficher des compteurs simples dans l’en-tête des salons", "Show a placeholder for removed messages": "Afficher les messages supprimés", @@ -1084,7 +1084,7 @@ "A new recovery passphrase and key for Secure Messages have been detected.": "Un nouveau mot de passe et une nouvelle clé de récupération pour les messages sécurisés ont été détectés.", "Recovery Method Removed": "Méthode de récupération supprimée", "If you didn't remove the recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.": "Si vous n'avez pas supprimé la méthode de récupération, un attaquant peut être en train d'essayer d'accéder à votre compte. Modifiez le mot de passe de votre compte et configurez une nouvelle méthode de récupération dans les réglages.", - "The file '%(fileName)s' exceeds this homeserver's size limit for uploads": "Le fichier \"%(fileName)s\" dépasse la taille limite autorisée par ce serveur pour les téléchargements", + "The file '%(fileName)s' exceeds this homeserver's size limit for uploads": "Le fichier « %(fileName)s » dépasse la taille limite autorisée par ce serveur pour les envois", "Gets or sets the room topic": "Récupère ou définit le sujet du salon", "This room has no topic.": "Ce salon n'a pas de sujet.", "%(senderDisplayName)s made the room public to whoever knows the link.": "%(senderDisplayName)s a rendu le salon public à tous ceux qui en connaissent le lien.", @@ -1092,7 +1092,7 @@ "%(senderDisplayName)s changed the join rule to %(rule)s": "%(senderDisplayName)s a changé la règle d’adhésion en %(rule)s", "%(senderDisplayName)s has allowed guests to join the room.": "%(senderDisplayName)s a autorisé les visiteurs à rejoindre le salon.", "%(senderDisplayName)s has prevented guests from joining the room.": "%(senderDisplayName)s a empêché les visiteurs de rejoindre le salon.", - "%(senderDisplayName)s changed guest access to %(rule)s": "%(senderDisplayName)s a changé l'accès des visiteurs en %(rule)s", + "%(senderDisplayName)s changed guest access to %(rule)s": "%(senderDisplayName)s a changé l’accès des visiteurs en %(rule)s", "Group & filter rooms by custom tags (refresh to apply changes)": "Grouper et filtrer les salons grâce à des étiquettes personnalisées (actualiser pour appliquer les changements)", "Verify this user by confirming the following emoji appear on their screen.": "Vérifier cet utilisateur en confirmant que les émojis suivant apparaissent sur son écran.", "Unable to find a supported verification method.": "Impossible de trouver une méthode de vérification prise en charge.", @@ -1206,7 +1206,7 @@ "Create your Matrix account on %(serverName)s": "Créez votre compte Matrix sur %(serverName)s", "Could not load user profile": "Impossible de charger le profil de l’utilisateur", "Your Matrix account on %(serverName)s": "Votre compte Matrix sur %(serverName)s", - "Prepends ¯\\_(ツ)_/¯ to a plain-text message": "Ajoute ¯\\_(ツ)_/¯ devant un message en texte brut", + "Prepends ¯\\_(ツ)_/¯ to a plain-text message": "Ajoute ¯\\_(ツ)_/¯ en préfixe du message", "User %(userId)s is already in the room": "L’utilisateur %(userId)s est déjà membre du salon", "The user must be unbanned before they can be invited.": "Le bannissement de l’utilisateur doit être révoqué avant de pouvoir l’inviter.", "Upgrade to your own domain": "Mettre à niveau vers votre propre domaine", @@ -1452,7 +1452,7 @@ "If you don't want to use to discover and be discoverable by existing contacts you know, enter another identity server below.": "Si vous ne voulez pas utiliser pour découvrir et être découvrable par les contacts que vous connaissez, saisissez un autre serveur d’identité ci-dessous.", "Using an identity server is optional. If you choose not to use an identity server, you won't be discoverable by other users and you won't be able to invite others by email or phone.": "L’utilisation d’un serveur d’identité est optionnelle. Si vous ne choisissez pas d’utiliser un serveur d’identité, les autres utilisateurs ne pourront pas vous découvrir et vous ne pourrez pas en inviter par e-mail ou par téléphone.", "Do not use an identity server": "Ne pas utiliser de serveur d’identité", - "You do not have the required permissions to use this command.": "Vous n’avez pas les permissions nécessaires pour utiliser cette commande.", + "You do not have the required permissions to use this command.": "Vous n’avez pas les autorisations nécessaires pour utiliser cette commande.", "Upgrade the room": "Mettre à niveau le salon", "Set an email for account recovery. Use email or phone to optionally be discoverable by existing contacts.": "Renseignez un e-mail pour la récupération de compte. Utilisez un e-mail ou un téléphone pour être éventuellement découvrable par des contacts existants.", "Set an email for account recovery. Use email to optionally be discoverable by existing contacts.": "Renseignez un e-mail pour la récupération de compte. Utilisez un e-mail pour être éventuellement découvrable par des contacts existants.", @@ -1580,7 +1580,7 @@ "Unread messages.": "Messages non lus.", "Show tray icon and minimize window to it on close": "Afficher l’icône dans la barre d’état et minimiser la fenêtre lors de la fermeture", "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Cette action nécessite l’accès au serveur d’identité par défaut afin de valider une adresse e-mail ou un numéro de téléphone, mais le serveur n’a aucune condition de service.", - "Trust": "Confiance", + "Trust": "Faire confiance", "Message Actions": "Actions de message", "%(name)s (%(userId)s)": "%(name)s (%(userId)s)", "You verified %(name)s": "Vous avez vérifié %(name)s", @@ -1665,9 +1665,9 @@ "Verification Request": "Demande de vérification", "Match system theme": "S’adapter au thème du système", "%(senderName)s placed a voice call.": "%(senderName)s a passé un appel vocal.", - "%(senderName)s placed a voice call. (not supported by this browser)": "%(senderName)s a passé un appel vocal. (pas pris en charge par ce navigateur)", + "%(senderName)s placed a voice call. (not supported by this browser)": "%(senderName)s a passé un appel vocal. (non pris en charge par ce navigateur)", "%(senderName)s placed a video call.": "%(senderName)s a passé un appel vidéo.", - "%(senderName)s placed a video call. (not supported by this browser)": "%(senderName)s a passé un appel vidéo. (pas pris en charge par ce navigateur)", + "%(senderName)s placed a video call. (not supported by this browser)": "%(senderName)s a passé un appel vidéo. (non pris en charge par ce navigateur)", "Clear notifications": "Vider les notifications", "Customise your experience with experimental labs features. Learn more.": "Personnalisez votre expérience avec des fonctionnalités expérimentales du labo. En savoir plus.", "Error upgrading room": "Erreur lors de la mise à niveau du salon", @@ -1838,7 +1838,7 @@ "Unknown (user, session) pair:": "Paire (utilisateur, session) inconnue :", "Session already verified!": "Session déjà vérifiée !", "WARNING: Session already verified, but keys do NOT MATCH!": "ATTENTION : La session a déjà été vérifiée mais les clés NE CORRESPONDENT PAS !", - "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and session %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "ATTENTION : ÉCHEC DE LA VÉRIFICATION DE CLÉ ! La clé de signature pour %(userId)s et la session %(deviceId)s est « %(fprint)s » que ne correspond pas à la clé fournie « %(fingerprint)s ». Cela pourrait signifier que vos communications sont interceptées !", + "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and session %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "ATTENTION : ÉCHEC DE LA VÉRIFICATION DE CLÉ ! La clé de signature pour %(userId)s et la session %(deviceId)s est « %(fprint)s  ce qui ne correspond pas à la clé fournie « %(fingerprint)s ». Cela pourrait signifier que vos communications sont interceptées !", "The signing key you provided matches the signing key you received from %(userId)s's session %(deviceId)s. Session marked as verified.": "La clé de signature que vous avez fournie correspond à celle que vous avez reçue de la session %(deviceId)s de %(userId)s. Session marquée comme vérifiée.", "Never send encrypted messages to unverified sessions from this session": "Ne jamais envoyer de messages chiffrés aux sessions non vérifiées depuis cette session", "Never send encrypted messages to unverified sessions in this room from this session": "Ne jamais envoyer des messages chiffrés aux sessions non vérifiées dans ce salon depuis cette session", @@ -1940,7 +1940,7 @@ "%(name)s (%(userId)s) signed in to a new session without verifying it:": "%(name)s (%(userId)s) s’est connecté à une nouvelle session sans la vérifier :", "Ask this user to verify their session, or manually verify it below.": "Demandez à cet utilisateur de vérifier sa session, ou vérifiez-la manuellement ci-dessous.", "Verify by scanning": "Vérifier en scannant", - "Whether you're using %(brand)s on a device where touch is the primary input mechanism": "Si vous utilisez %(brand)s sur un appareil où le toucher est le mécanisme primaire de saisie", + "Whether you're using %(brand)s on a device where touch is the primary input mechanism": "Si vous utilisez %(brand)s sur un appareil où le tactile est le mode principal de saisie", "Whether you're using %(brand)s as an installed Progressive Web App": "Si vous utilisez %(brand)s en tant qu’application web progressive (PWA)", "Your user agent": "Votre agent utilisateur", "The session you are trying to verify doesn't support scanning a QR code or emoji verification, which is what %(brand)s supports. Try with a different client.": "La session que vous essayez de vérifier ne prend pas en charge les codes QR ou la vérification d’émojis, qui sont les méthodes prises en charge par %(brand)s. Essayez avec un autre client.", @@ -1960,7 +1960,7 @@ "The internet connection either session is using": "La connection internet de l'une des sessions", "We recommend you change your password and recovery key in Settings immediately": "Nous vous recommandons de changer votre mot de passe et la clé de récupération dans Paramètres dès que possible", "Sign In or Create Account": "Se connecter ou créer un compte", - "Use your account or create a new one to continue.": "Utilisez votre compte ou créez un nouveau compte pour continuer.", + "Use your account or create a new one to continue.": "Utilisez votre compte ou créez en un pour continuer.", "Create Account": "Créer un compte", "Order rooms by name": "Trier les salons par nom", "Show rooms with unread notifications first": "Afficher en premier les salons avec des notifications non lues", @@ -2378,7 +2378,7 @@ "%(brand)s Desktop": "%(brand)s Desktop", "%(brand)s iOS": "%(brand)s iOS", "%(brand)s X for Android": "%(brand)s X pour Android", - "Are you sure you want to cancel entering passphrase?": "Souhaitez-vous vraiment annuler l'entrée de la phrase de passe ?", + "Are you sure you want to cancel entering passphrase?": "Souhaitez-vous vraiment annuler la saisie de la phrase de passe ?", "Unexpected server error trying to leave the room": "Erreur de serveur inattendue en essayant de quitter le salon", "Error leaving room": "Erreur en essayant de quitter le salon", "The person who invited you already left the room.": "La personne vous ayant invité a déjà quitté le salon.", @@ -2400,18 +2400,18 @@ "The operation could not be completed": "L'opération n'a pas pu être terminée", "Failed to save your profile": "Erreur lors de l'enregistrement du profile", "Unknown App": "Application inconnue", - "%(senderName)s declined the call.": "%(senderName)s a refusé l'appel.", + "%(senderName)s declined the call.": "%(senderName)s a refusé l’appel.", "(an error occurred)": "(une erreur est survenue)", "(connection failed)": "(échec de connexion)", - "%(senderDisplayName)s changed the server ACLs for this room.": "%(senderDisplayName)s a changé les paramètres d'accès du serveur pour ce salon.", - "%(senderDisplayName)s set the server ACLs for this room.": "%(senderDisplayName)s a défini les paramètres d'accès du serveur pour ce salon.", - "Prepends ( ͡° ͜ʖ ͡°) to a plain-text message": "Ajoute ( ͡° ͜ʖ ͡°) devant un message en texte brut", + "%(senderDisplayName)s changed the server ACLs for this room.": "%(senderDisplayName)s a changé les paramètres d’accès du serveur pour ce salon.", + "%(senderDisplayName)s set the server ACLs for this room.": "%(senderDisplayName)s a défini les paramètres d’accès du serveur pour ce salon.", + "Prepends ( ͡° ͜ʖ ͡°) to a plain-text message": "Ajoute ( ͡° ͜ʖ ͡°) en préfixe du message", "This will end the conference for everyone. Continue?": "Ceci arrêtera la téléconférence pour tout le monde. Continuer ?", "End conference": "Finir la téléconférence", - "The call was answered on another device.": "L'appel a été répondu sur un autre appareil.", + "The call was answered on another device.": "L’appel a été répondu sur un autre appareil.", "Answered Elsewhere": "Répondu autre-part", - "The call could not be established": "L'appel n'a pas pu être établi", - "The other party declined the call.": "L'autre personne a décliné l'appel.", + "The call could not be established": "L’appel n’a pas pu être établi", + "The other party declined the call.": "Le correspondant a décliné l’appel.", "Call Declined": "Appel rejeté", "Ignored attempt to disable encryption": "Essai de désactiver le chiffrement ignoré", "Add users and servers you want to ignore here. Use asterisks to have %(brand)s match any characters. For example, @bot:* would ignore all users that have the name 'bot' on any server.": "Ajoutez les utilisateurs et les serveurs que vous voulez ignorer ici. Utilisez des astérisques pour que %(brand)s comprenne tous les caractères. Par exemple, @bot:* va ignorer tous les utilisateurs ayant le nom 'bot' sur n'importe quel serveur.", @@ -2428,8 +2428,8 @@ "Offline encrypted messaging using dehydrated devices": "Messagerie hors-ligne chiffrée utilisant des appareils déshydratés", "Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Prototype de communautés v2. Requiert un serveur d'accueil compatible. Très expérimental - à utiliser avec précaution.", "Safeguard against losing access to encrypted messages & data": "Sécurité contre la perte d'accès aux messages & données chiffrées", - "(their device couldn't start the camera / microphone)": "(son appareil ne peut pas démarrer la caméra / le microphone)", - "🎉 All servers are banned from participating! This room can no longer be used.": "🎉 Tous les serveurs sont interdits de participation ! Ce salon ne peut plus être utilisé.", + "(their device couldn't start the camera / microphone)": "(leur appareil ne peut pas démarrer la caméra/le microphone)", + "🎉 All servers are banned from participating! This room can no longer be used.": "🎉 Tous les serveurs ont été bannis ! Ce salon ne peut plus être utilisé.", "What's the name of your community or team?": "Quel est le nom de votre communauté ou équipe ?", "You can change this later if needed.": "Vous pouvez modifier ceci après si besoin.", "Use this when referencing your community to others. The community ID cannot be changed.": "Utilisez ceci lorsque vous faites référence à votre communauté aux autres. L'identifiant de la communauté ne peut pas être modifié.", @@ -2570,12 +2570,12 @@ "Afghanistan": "Afghanistan", "United States": "États-Unis", "United Kingdom": "Royaume-Uni", - "You've reached the maximum number of simultaneous calls.": "Vous avez atteint le nombre maximum d'appels en simultané.", - "No other application is using the webcam": "Aucune autre application n'est en train d'utiliser la caméra", - "A microphone and webcam are plugged in and set up correctly": "Un microphone et une caméra sont branchées et bien configurées", - "Unable to access webcam / microphone": "Impossible d'accéder à la caméra ou microphone", - "Call failed because microphone could not be accessed. Check that a microphone is plugged in and set up correctly.": "La fonction a échoué car le microphone n'a pas pu être accédé. Vérifiez qu'un microphone est branché et bien configuré.", - "Unable to access microphone": "Impossible d'accéder au microphone", + "You've reached the maximum number of simultaneous calls.": "Vous avez atteint le nombre maximum d’appels en simultané.", + "No other application is using the webcam": "Aucune autre application n’est en train d’utiliser la caméra", + "A microphone and webcam are plugged in and set up correctly": "Un microphone et une caméra sont branchées et bien configurés", + "Unable to access webcam / microphone": "Impossible d’accéder à la caméra ou au microphone", + "Call failed because microphone could not be accessed. Check that a microphone is plugged in and set up correctly.": "La fonction a échoué faute de pouvoir accéder au microphone. Vérifiez qu’un microphone est branché et bien configuré.", + "Unable to access microphone": "Impossible d’accéder au microphone", "Belgium": "Belgique", "Belarus": "Biélorussie", "Barbados": "Barbade", @@ -2591,15 +2591,15 @@ "Antigua & Barbuda": "Antigue-et-Barbude", "Antarctica": "Antarctique", "Anguilla": "Anguilla", - "Angola": "République d'Angola", + "Angola": "République d’Angola", "Andorra": "Andorre", "American Samoa": "Samoa américaines", "Invite someone using their name, email address, username (like ) or share this room.": "Invitez quelqu'un via leur nom, e-mail ou nom d'utilisateur (p. ex. ) ou partagez ce salon.", "Start a conversation with someone using their name, email address or username (like ).": "Commencer une conversation avec quelqu'un via leur nom, e-mail ou nom d'utilisateur (comme par exemple ).", - "Too Many Calls": "Trop d'appels", - "Permission is granted to use the webcam": "Permission accordée pour l'utilisation de la webcam", - "Call failed because webcam or microphone could not be accessed. Check that:": "La fonction a échoué car la webcam ou le microphone ne pouvait pas être accédé. Vérifiez que :", - "Send stickers to this room as you": "Envoyer des stickers dans ce salon en tant que vous", + "Too Many Calls": "Trop d’appels", + "Permission is granted to use the webcam": "L’autorisation d’accéder à la caméra a été accordée", + "Call failed because webcam or microphone could not be accessed. Check that:": "La fonction a échoué faute de pouvoir accéder à la caméra ou au microphone. Vérifiez que :", + "Send stickers to this room as you": "Envoyer des stickers dans ce salon en tant que vous-même", "Zambia": "Zambie", "Yemen": "Yémen", "Western Sahara": "Sahara occidental", @@ -2685,7 +2685,7 @@ "North Korea": "Corée du Nord", "Norfolk Island": "Île Norfolk", "Niue": "Niue", - "Nigeria": "Nigéria", + "Nigeria": "Nigeria", "Niger": "Niger", "Nicaragua": "Nicaragua", "New Zealand": "Nouvelle-Zélande", @@ -2703,7 +2703,7 @@ "Monaco": "Monaco", "Moldova": "Moldavie", "Micronesia": "États fédérés de Micronésie", - "Mexico": "Mexico", + "Mexico": "Mexique", "Mayotte": "Mayotte", "Mauritius": "République de Maurice", "Mauritania": "Mauritanie", @@ -2783,13 +2783,13 @@ "Equatorial Guinea": "Guinée équatoriale", "El Salvador": "Le Salvador", "Egypt": "Égypte", - "Ecuador": "République de l'Équateur", + "Ecuador": "République de l’Équateur", "Dominican Republic": "République dominicaine", "Dominica": "Dominique", "Djibouti": "Djibouti", "Denmark": "Danemark", - "Côte d’Ivoire": "Côte d’Ivoire (Terre d'Éburnie)", - "Czech Republic": "La République tchèque", + "Côte d’Ivoire": "Côte d’Ivoire", + "Czech Republic": "République tchèque", "Cyprus": "Chypre", "Curaçao": "Curaçao", "Cuba": "Cuba", @@ -2799,7 +2799,7 @@ "Congo - Kinshasa": "République démocratique du Congo", "Congo - Brazzaville": "République du Congo", "Comoros": "Comores", - "Colombia": "Colombia", + "Colombia": "Colombie", "Cocos (Keeling) Islands": "îles Cocos", "Christmas Island": "île Christmas", "China": "Chine", @@ -2812,12 +2812,12 @@ "Canada": "Canada", "Cameroon": "Cameroun", "Cambodia": "Cambodge", - "Burundi": "La république du Burundi", + "Burundi": "République du Burundi", "Burkina Faso": "Burkina Faso", "Bulgaria": "Bulgarie", "Brunei": "Brunéi", "British Virgin Islands": "Îles Vierges britanniques", - "British Indian Ocean Territory": "Territoire britannique de l'océan Indien", + "British Indian Ocean Territory": "Territoire britannique de l’océan Indien", "Brazil": "Brésil", "Bouvet Island": "Île Bouvet", "Botswana": "Botswana", @@ -2825,14 +2825,14 @@ "Bolivia": "Bolivie", "Bhutan": "Bhoutan", "Bermuda": "Bermudes", - "with state key %(stateKey)s": "avec la ou les clés d'état %(stateKey)s", - "with an empty state key": "avec une clé d'état vide", - "See when anyone posts a sticker to your active room": "Voir quand n'importe qui envoye un sticker dans le salon actuel", + "with state key %(stateKey)s": "avec la ou les clés d’état %(stateKey)s", + "with an empty state key": "avec une clé d’état vide", + "See when anyone posts a sticker to your active room": "Voir quand n’importe qui envoie un sticker dans le salon actuel", "See when a sticker is posted in this room": "Voir quand un sticker est envoyé dans ce salon", - "See when the avatar changes in your active room": "Voir quand l'avatar change dans le salon actuel", - "Change the avatar of your active room": "Changer l'avatar du salon actuel", - "See when the avatar changes in this room": "Voir quand l'avatar change dans ce salon", - "Change the avatar of this room": "Changer l'avatar de ce salon", + "See when the avatar changes in your active room": "Voir quand l’avatar change dans le salon actuel", + "Change the avatar of your active room": "Changer l’avatar du salon actuel", + "See when the avatar changes in this room": "Voir quand l’avatar change dans ce salon", + "Change the avatar of this room": "Changer l’avatar de ce salon", "Send stickers into your active room": "Envoyer des stickers dans le salon actuel", "See when the topic changes in this room": "Voir quand le sujet change dans ce salon", "See when the topic changes in your active room": "Voir quand le sujet change dans le salon actuel", @@ -2842,35 +2842,35 @@ "Change the topic of your active room": "Changer le sujet dans le salon actuel", "Change the topic of this room": "Changer le sujet de ce salon", "Send stickers into this room": "Envoyer des stickers dans ce salon", - "Remain on your screen when viewing another room, when running": "Reste sur votre écran quand vous regardez un autre salon lors de l'appel", - "Takes the call in the current room off hold": "Reprends l'appel en cours dans ce salon", - "Places the call in the current room on hold": "Met l'appel en pause dans ce salon", - "Prepends (╯°□°)╯︵ ┻━┻ to a plain-text message": "Ajoute \"(╯°□°)╯︵ ┻━┻\" en préfixe du message", - "Prepends ┬──┬ ノ( ゜-゜ノ) to a plain-text message": "Ajoute \"┬──┬ ノ( ゜-゜ノ)\" en préfixe du message", + "Remain on your screen when viewing another room, when running": "Reste sur votre écran quand vous regardez un autre salon lors de l’appel", + "Takes the call in the current room off hold": "Reprend l’appel en cours dans ce salon", + "Places the call in the current room on hold": "Met l’appel en pause dans ce salon", + "Prepends (╯°□°)╯︵ ┻━┻ to a plain-text message": "Ajoute (╯°□°)╯︵ ┻━┻ en préfixe du message", + "Prepends ┬──┬ ノ( ゜-゜ノ) to a plain-text message": "Ajoute ┬──┬ ノ( ゜-゜ノ) en préfixe du message", "Effects": "Effets", "Zimbabwe": "Zimbabwe", "Send images as you in your active room": "Envoie des images sous votre nom dans le salon actuel", "Send images as you in this room": "Envoie des images sous votre nom dans ce salon", - "See emotes posted to your active room": "Voir les émoticônes envoyées dans le salon actuel", - "See emotes posted to this room": "Voir les émoticônes envoyées dans ce salon", - "Send emotes as you in your active room": "Envoyer des émoticônes sous votre nom dans le salon actuel", - "Send emotes as you in this room": "Envoyer des émoticônes sous votre nom dans ce salon", - "See videos posted to your active room": "Voir les vidéos publiées dans votre salon actuel", + "See emotes posted to your active room": "Voir les réactions envoyées dans le salon actuel", + "See emotes posted to this room": "Voir les réactions envoyées dans ce salon", + "Send emotes as you in your active room": "Envoyer des réactions sous votre nom dans le salon actuel", + "Send emotes as you in this room": "Envoyer des réactions sous votre nom dans ce salon", + "See videos posted to your active room": "Voir les vidéos publiées dans votre salon actif", "See videos posted to this room": "Voir les vidéos publiées dans ce salon", - "Send videos as you in your active room": "Envoie des vidéos en tant que vous dans votre salon actuel", + "Send videos as you in your active room": "Envoie des vidéos en tant que vous-même dans votre salon actuel", "Send videos as you in this room": "Envoie des vidéos en tant que vous dans ce salon", "See images posted to this room": "Voir les images publiées dans ce salon", - "See images posted to your active room": "Voir les images publiées dans votre salon actuel", - "See messages posted to your active room": "Voir les messages publiés dans votre salon actuel", + "See images posted to your active room": "Voir les images publiées dans votre salon actif", + "See messages posted to your active room": "Voir les messages publiés dans votre salon actif", "See messages posted to this room": "Voir les messages publiés dans ce salon", - "Send messages as you in your active room": "Envoie des messages en tant que vous dans votre salon actuel", - "Send messages as you in this room": "Envoie des messages en tant que vous dans ce salon", + "Send messages as you in your active room": "Envoie des messages en tant que vous-même dans votre salon actif", + "Send messages as you in this room": "Envoie des messages en tant que vous-même dans ce salon", "The %(capability)s capability": "La capacité %(capability)s", "See %(eventType)s events posted to your active room": "Voir les événements %(eventType)s publiés dans votre salon actuel", - "Send %(eventType)s events as you in your active room": "Envoie des événements %(eventType)s en tant que vous dans votre salon actuel", + "Send %(eventType)s events as you in your active room": "Envoie des événements %(eventType)s en tant que vous-même dans votre salon actuel", "See %(eventType)s events posted to this room": "Voir les événements %(eventType)s publiés dans ce salon", - "Send %(eventType)s events as you in this room": "Envoie des événements %(eventType)s en tant que vous dans ce salon", - "Send stickers to your active room as you": "Envoie des stickers en tant que vous dans le salon actuel", + "Send %(eventType)s events as you in this room": "Envoie des événements %(eventType)s en tant que vous-même dans ce salon", + "Send stickers to your active room as you": "Envoie des stickers en tant que vous-même dans le salon actuel", "Continue with %(ssoButtons)s": "Continuer avec %(ssoButtons)s", "About homeservers": "À propos des serveurs d'accueils", "Learn more": "En savoir plus", @@ -2930,12 +2930,12 @@ "Don't miss a reply": "Ne ratez pas une réponse", "See %(msgtype)s messages posted to your active room": "Voir les messages de type %(msgtype)s publiés dans le salon actuel", "See %(msgtype)s messages posted to this room": "Voir les messages de type %(msgtype)s publiés dans ce salon", - "Send %(msgtype)s messages as you in this room": "Envoie des messages de type%(msgtype)s en tant que vous dans ce salon", - "Send %(msgtype)s messages as you in your active room": "Envoie des messages de type %(msgtype)s en tant que vous dans votre salon actuel", + "Send %(msgtype)s messages as you in this room": "Envoie des messages de type%(msgtype)s en tant que vous-même dans ce salon", + "Send %(msgtype)s messages as you in your active room": "Envoie des messages de type %(msgtype)s en tant que vous-même dans votre salon actif", "See general files posted to your active room": "Voir les fichiers postés dans votre salon actuel", "See general files posted to this room": "Voir les fichiers postés dans ce salon", - "Send general files as you in your active room": "Envoie des fichiers en tant que vous dans votre salon actuel", - "Send general files as you in this room": "Envoie des fichiers en tant que vous dans ce salon", + "Send general files as you in your active room": "Envoyer des fichiers en tant que vous-même dans votre salon actif", + "Send general files as you in this room": "Envoyer des fichiers en tant que vous-même dans ce salon", "Search (must be enabled)": "Recherche (si activée)", "This session has detected that your Security Phrase and key for Secure Messages have been removed.": "Cette session a détecté que votre phrase de passe et clé de sécurité pour les messages sécurisés ont été supprimées.", "A new Security Phrase and key for Secure Messages have been detected.": "Une nouvelle phrase de passe et clé pour les messages sécurisés ont été détectées.", @@ -3035,10 +3035,10 @@ "See when the name changes in your active room": "Suivre les changements de nom dans le salon actif", "Change which room, message, or user you're viewing": "Changer le salon, message, ou la personne que vous visualisez", "Change which room you're viewing": "Changer le salon que vous visualisez", - "Remain on your screen while running": "Restez sur votre écran pendant l’exécution", + "Remain on your screen while running": "Reste sur votre écran pendant l’exécution", "%(senderName)s has updated the widget layout": "%(senderName)s a mis à jour la disposition du widget", - "Converts the DM to a room": "Transformer le message privé en salon", - "Converts the room to a DM": "Transformer le salon en message privé", + "Converts the DM to a room": "Transforme le message privé en salon", + "Converts the room to a DM": "Transforme le salon en message privé", "Your homeserver rejected your log in attempt. This could be due to things just taking too long. Please try again. If this continues, please contact your homeserver administrator.": "Votre serveur d’accueil a rejeté la demande de connexion. Ceci pourrait être dû à une connexion qui prend trop de temps. Si cela persiste, merci de contacter l’administrateur de votre serveur d’accueil.", "Your homeserver was unreachable and was not able to log you in. Please try again. If this continues, please contact your homeserver administrator.": "Votre serveur d’accueil n’est pas accessible, nous n’avons pas pu vous connecter. Merci de réessayer. Si cela persiste, merci de contacter l’administrateur de votre serveur d’accueil.", "Try again": "Réessayez", From 83d10b827b0f75decc8959adb7c833fee5406afe Mon Sep 17 00:00:00 2001 From: Jean-Luc KABORE-TURQUIN Date: Thu, 25 Feb 2021 08:15:23 +0000 Subject: [PATCH 09/91] Translated using Weblate (French) Currently translated at 99.2% (2758 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 304599cd44..3d024f6e18 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -77,7 +77,7 @@ "Email": "E-mail", "Failed to unban": "Échec de la révocation du bannissement", "Failed to verify email address: make sure you clicked the link in the email": "La vérification de l’adresse e-mail a échoué : vérifiez que vous avez bien cliqué sur le lien dans l’e-mail", - "Failure to create room": "Échec de la création du salon", + "Failure to create room": "Échec de création du salon", "Favourites": "Favoris", "Fill screen": "Plein écran", "Filter room members": "Filtrer les membres du salon", From f75d98493d0fba3883cf355746d63e2ee6df6bba Mon Sep 17 00:00:00 2001 From: Szimszon Date: Wed, 24 Feb 2021 21:44:12 +0000 Subject: [PATCH 10/91] Translated using Weblate (Hungarian) Currently translated at 100.0% (2780 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 398dd04ec2..d0f8cc3b69 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -3060,5 +3060,27 @@ "Failed to connect to your homeserver. Please close this dialog and try again.": "A matrix szerverhez való csatlakozás nem sikerült. Zárja be ezt az ablakot és próbálja újra.", "Abort": "Megszakítás", "Are you sure you wish to abort creation of the host? The process cannot be continued.": "Biztos benne, hogy meg kívánja szakítani a gazdagép létrehozásának a folyamatát? A folyamat nem folytatható.", - "Confirm abort of host creation": "Erősítse meg a gazdagép készítés megszakítását" + "Confirm abort of host creation": "Erősítse meg a gazdagép készítés megszakítását", + "Upgrade to %(hostSignupBrand)s": "Frissítés erre: %(hostSignupBrand)s", + "Edit Values": "Értékek szerkesztése", + "Values at explicit levels in this room:": "Egyedi szinthez tartozó értékek ebben a szobában:", + "Values at explicit levels:": "Egyedi szinthez tartozó értékek:", + "Value in this room:": "Érték ebben a szobában:", + "Value:": "Érték:", + "Save setting values": "Beállított értékek mentése", + "Values at explicit levels in this room": "Egyedi szinthez tartozó értékek ebben a szobában", + "Values at explicit levels": "Egyedi szinthez tartozó értékek", + "Settable at room": "Szobára beállítható", + "Settable at global": "Általánosan beállítható", + "Level": "Szint", + "Setting definition:": "Beállítás leírása:", + "This UI does NOT check the types of the values. Use at your own risk.": "Ez a felület nem ellenőrzi az érték típusát. Csak saját felelősségére használja.", + "Caution:": "Figyelmeztetés:", + "Setting:": "Beállítás:", + "Value in this room": "Érték ebben a szobában", + "Value": "Érték", + "Setting ID": "Beállítás azon.", + "Failed to save settings": "A beállítások elmentése nem sikerült", + "Settings Explorer": "Beállítás Böngésző", + "Show chat effects (animations when receiving e.g. confetti)": "Csevegés effektek megjelenítése (mint a konfetti animáció)" } From 32ac7d7c8b98e26872bef1b707d05187d89405f4 Mon Sep 17 00:00:00 2001 From: jelv Date: Thu, 25 Feb 2021 13:56:38 +0000 Subject: [PATCH 11/91] Translated using Weblate (Dutch) Currently translated at 100.0% (2780 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/nl/ --- src/i18n/strings/nl.json | 44 ++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index 101d997d9c..0d80e520c8 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -689,7 +689,7 @@ "Messages in one-to-one chats": "Berichten in één-op-één gesprekken", "Unavailable": "Niet beschikbaar", "View Decrypted Source": "Ontsleutelde bron bekijken", - "Failed to update keywords": "Bijwerken van trefwoorden is mislukt", + "Failed to update keywords": "Updaten van trefwoorden is mislukt", "remove %(name)s from the directory.": "verwijder %(name)s uit de catalogus.", "Notifications on the following keywords follow rules which can’t be displayed here:": "Meldingen op de volgende trefwoorden volgen regels die hier niet getoond kunnen worden:", "Please set a password!": "Stel een wachtwoord in!", @@ -740,7 +740,7 @@ "What's new?": "Wat is er nieuw?", "Notify me for anything else": "Stuur een melding voor al het andere", "When I'm invited to a room": "Wanneer ik uitgenodigd word in een gesprek", - "Can't update user notification settings": "Kan de meldingsinstellingen van de gebruiker niet bijwerken", + "Can't update user notification settings": "Kan de meldingsinstellingen van de gebruiker niet updaten", "Notify for all other messages/rooms": "Stuur een melding voor alle andere berichten/gesprekken", "Unable to look up room ID from server": "Kon de gesprek-ID niet van de server ophalen", "Couldn't find a matching Matrix room": "Kon geen bijbehorend Matrix-gesprek vinden", @@ -852,7 +852,7 @@ "Gets or sets the room topic": "Verkrijgt het onderwerp van het gesprek of stelt het in", "This room has no topic.": "Dit gesprek heeft geen onderwerp.", "Sets the room name": "Stelt de gespreksnaam in", - "%(senderDisplayName)s upgraded this room.": "%(senderDisplayName)s heeft dit gesprek bijgewerkt.", + "%(senderDisplayName)s upgraded this room.": "%(senderDisplayName)s heeft dit gesprek geüpgraded.", "%(senderDisplayName)s made the room public to whoever knows the link.": "%(senderDisplayName)s heeft het gesprek toegankelijk gemaakt voor iedereen die de koppeling kent.", "%(senderDisplayName)s made the room invite only.": "%(senderDisplayName)s heeft het gesprek enkel op uitnodiging toegankelijk gemaakt.", "%(senderDisplayName)s changed the join rule to %(rule)s": "%(senderDisplayName)s heeft de toegangsregel veranderd naar ‘%(rule)s’", @@ -1240,7 +1240,7 @@ "%(senderName)s revoked the invitation for %(targetDisplayName)s to join the room.": "%(senderName)s heeft de uitnodiging aan %(targetDisplayName)s toe te treden tot het gesprek ingetrokken.", "Upgrade this room to the recommended room version": "Werk dit gesprek bij tot de aanbevolen versie", "This room is running room version , which this homeserver has marked as unstable.": "Dit gesprek draait op groepsgespreksversie , die door deze homeserver als onstabiel is gemarkeerd.", - "Upgrading this room will shut down the current instance of the room and create an upgraded room with the same name.": "Bijwerken zal de huidige versie van dit gesprek sluiten, en onder dezelfde naam een bijgewerkte versie starten.", + "Upgrading this room will shut down the current instance of the room and create an upgraded room with the same name.": "Upgraden zal de huidige versie van dit gesprek sluiten, en onder dezelfde naam een geüpgraded versie starten.", "Failed to revoke invite": "Intrekken van uitnodiging is mislukt", "Could not revoke the invite. The server may be experiencing a temporary problem or you do not have sufficient permissions to revoke the invite.": "Kon de uitnodiging niet intrekken. De server ondervindt mogelijk een tijdelijk probleem, of u heeft niet het recht de uitnodiging in te trekken.", "Revoke invite": "Uitnodiging intrekken", @@ -1289,7 +1289,7 @@ "Unexpected error resolving homeserver configuration": "Onverwachte fout bij het controleren van de homeserverconfiguratie", "The user's homeserver does not support the version of the room.": "De homeserver van de gebruiker biedt geen ondersteuning voor de gespreksversie.", "Show hidden events in timeline": "Verborgen gebeurtenissen op de tijdslijn weergeven", - "When rooms are upgraded": "Wanneer gesprekken bijgewerkt worden", + "When rooms are upgraded": "Wanneer gesprekken geüpgraded worden", "this room": "dit gesprek", "View older messages in %(roomName)s.": "Bekijk oudere berichten in %(roomName)s.", "Joining room …": "Deelnemen aan gesprek…", @@ -1316,7 +1316,7 @@ "This room doesn't exist. Are you sure you're at the right place?": "Dit gesprek bestaat niet. Weet u zeker dat u zich op de juiste plaats bevindt?", "Try again later, or ask a room admin to check if you have access.": "Probeer het later opnieuw, of vraag een gespreksbeheerder om te controleren of u wel toegang heeft.", "%(errcode)s was returned while trying to access the room. If you think you're seeing this message in error, please submit a bug report.": "De foutcode %(errcode)s is weergegeven bij het toetreden van het gesprek. Als u meent dat u dit bericht foutief te zien krijgt, gelieve dan een foutmelding in te dienen.", - "This room has already been upgraded.": "Dit gesprek is reeds bijgewerkt.", + "This room has already been upgraded.": "Dit gesprek is reeds geüpgraded.", "reacted with %(shortName)s": "heeft gereageerd met %(shortName)s", "edited": "bewerkt", "Rotate Left": "Links draaien", @@ -1557,7 +1557,7 @@ "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Dit vergt validatie van een e-mailadres of telefoonnummer middels de standaardidentiteitsserver , maar die server heeft geen gebruiksvoorwaarden.", "Trust": "Vertrouwen", "Custom (%(level)s)": "Aangepast (%(level)s)", - "Error upgrading room": "Bijwerken van gesprek mislukt", + "Error upgrading room": "Upgraden van gesprek mislukt", "Double check that your server supports the room version chosen and try again.": "Ga nogmaals na dat de server de gekozen gespreksversie ondersteunt, en probeer het dan opnieuw.", "Verifies a user, session, and pubkey tuple": "Verifieert een combinatie van gebruiker+sessie+publieke sleutel", "Unknown (user, session) pair:": "Onbekende combinatie gebruiker+sessie:", @@ -1618,7 +1618,7 @@ "Lock": "Hangslot", "Verify yourself & others to keep your chats safe": "Verifieer uzelf en anderen om uw gesprekken veilig te houden", "Other users may not trust it": "Mogelijk wantrouwen anderen het", - "Upgrade": "Bijwerken", + "Upgrade": "Upgraden", "Verify": "Verifiëren", "Later": "Later", "Review": "Controle", @@ -2377,7 +2377,7 @@ "Use between %(min)s pt and %(max)s pt": "Gebruik een getal tussen %(min)s pt en %(max)s pt", "Custom font size can only be between %(min)s pt and %(max)s pt": "Aangepaste lettergrootte kan alleen een getal tussen %(min)s pt en %(max)s pt zijn", "Size must be a number": "Grootte moet een getal zijn", - "New version available. Update now.": "Nieuwe versie beschikbaar. Nu bijwerken.", + "New version available. Update now.": "Nieuwe versie beschikbaar. Nu updaten.", "not ready": "Niet gereed", "ready": "Gereed", "unexpected type": "Onverwacht type", @@ -2445,7 +2445,7 @@ "The person who invited you already left the room, or their server is offline.": "De persoon door wie u ben uitgenodigd heeft het gesprek al verlaten, of hun server is offline.", "The person who invited you already left the room.": "De persoon door wie u ben uitgenodigd, heeft het gesprek reeds verlaten.", "New version of %(brand)s is available": "Nieuwe versie van %(brand)s is beschikbaar", - "Update %(brand)s": "%(brand)s bijwerken", + "Update %(brand)s": "%(brand)s updaten", "%(senderName)s has updated the widget layout": "%(senderName)s heeft de widget-indeling bijgewerkt", "%(senderName)s declined the call.": "%(senderName)s heeft de oproep afgewezen.", "(an error occurred)": "(een fout is opgetreden)", @@ -2950,5 +2950,27 @@ "Create a Group Chat": "Maak een groepsgesprek aan", "Send a Direct Message": "Start een direct gesprek", "Welcome to %(appName)s": "Welkom bij %(appName)s", - "Add a topic to help people know what it is about.": "Stel een gespreksonderwerp in zodat mensen weten waar het over gaat." + "Add a topic to help people know what it is about.": "Stel een gespreksonderwerp in zodat mensen weten waar het over gaat.", + "Upgrade to %(hostSignupBrand)s": "Upgrade naar %(hostSignupBrand)s", + "Edit Values": "Waarde wijzigen", + "Values at explicit levels in this room:": "Waarde op expliciete niveaus in dit gesprek:", + "Values at explicit levels:": "Waardes op expliciete niveaus:", + "Value in this room:": "Waarde in dit gesprek:", + "Value:": "Waarde:", + "Save setting values": "Instelling waardes opslaan", + "Values at explicit levels in this room": "Waardes op expliciete niveaus in dit gesprek", + "Values at explicit levels": "Waardes op expliciete niveaus", + "Settable at room": "Instelbaar op gesprek", + "Settable at global": "Instelbaar op globaal", + "Level": "Niveau", + "Setting definition:": "Instelling definitie:", + "This UI does NOT check the types of the values. Use at your own risk.": "De UI heeft GEEN controle op het type van de waardes. Gebruik op eigen risico.", + "Caution:": "Opgelet:", + "Setting:": "Instelling:", + "Value in this room": "Waarde van dit gesprek", + "Value": "Waarde", + "Setting ID": "Instellingen-ID", + "Failed to save settings": "Kan geen instellingen opslaan", + "Settings Explorer": "Instellingen Ontdekken", + "Show chat effects (animations when receiving e.g. confetti)": "Effecten tonen (animaties bij ontvangst bijv. confetti)" } From abbe51660438ad2baa92d88097a2c1f926ab71b9 Mon Sep 17 00:00:00 2001 From: Marcelo Filho Date: Fri, 26 Feb 2021 17:32:14 +0000 Subject: [PATCH 12/91] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2780 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/pt_BR/ --- src/i18n/strings/pt_BR.json | 38 ++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/pt_BR.json b/src/i18n/strings/pt_BR.json index b32fbf5094..ef748c5fd8 100644 --- a/src/i18n/strings/pt_BR.json +++ b/src/i18n/strings/pt_BR.json @@ -2983,5 +2983,41 @@ "Converts the DM to a room": "Converte a conversa para uma sala", "Converts the room to a DM": "Converte a sala para uma conversa", "Try again": "Tente novamente", - "We couldn't log you in": "Não foi possível fazer login" + "We couldn't log you in": "Não foi possível fazer login", + "%(hostSignupBrand)s Setup": "Configuração do %(hostSignupBrand)s", + "Continuing temporarily allows the %(hostSignupBrand)s setup process to access your account to fetch verified email addresses. This data is not stored.": "Ao continuar, você permite que o processo de configuração do %(hostSignupBrand)s acesse a sua conta para obter endereços de e-mail verificados, temporariamente. Esses dados não são armazenados.", + "Settable at room": "Definido em cada sala", + "Settable at global": "Definido globalmente", + "Settings Explorer": "Explorador de configurações", + "Level": "Nível", + "Setting definition:": "Definição da configuração:", + "Setting ID": "ID da configuração", + "Your homeserver rejected your log in attempt. This could be due to things just taking too long. Please try again. If this continues, please contact your homeserver administrator.": "Seu servidor local recusou a sua tentativa de login. Isso pode ocorrer quando a conexão de internet estiver demorando muito. Por favor, tente novamente. Se o problema continuar, entre em contato com o administrador do seu servidor local.", + "Your homeserver was unreachable and was not able to log you in. Please try again. If this continues, please contact your homeserver administrator.": "O seu servidor local está inacessível e não foi possível fazer o seu login. Tente novamente. Se o problema continuar, entre em contato com o administrador do seu servidor local.", + "We asked the browser to remember which homeserver you use to let you sign in, but unfortunately your browser has forgotten it. Go to the sign in page and try again.": "Anteriormente, pedimos ao seu navegador para lembrar qual servidor local você usa para fazer login, mas infelizmente o navegador se esqueceu disso. Vá para a página de login e tente novamente.", + "Upgrade to %(hostSignupBrand)s": "Atualizar para %(hostSignupBrand)s", + "Minimize dialog": "Minimizar a janela", + "Maximize dialog": "Maximizar a janela", + "You should know": "Você deveria saber", + "Cookie Policy": "Política de cookies", + "Failed to connect to your homeserver. Please close this dialog and try again.": "Falha ao se conectar ao seu servidor local. Feche esta caixa de diálogo e tente novamente.", + "Abort": "Cancelar", + "Are you sure you wish to abort creation of the host? The process cannot be continued.": "Tem certeza de que deseja cancelar a criação do host? O processo não pode ser continuado.", + "Confirm abort of host creation": "Confirmar o cancelamento da criação do host", + "Edit Values": "Editar valores", + "Values at explicit levels in this room:": "Valores em níveis explícitos nessa sala:", + "Values at explicit levels:": "Valores em níveis explícitos:", + "Value in this room:": "Valor nessa sala:", + "Value:": "Valor:", + "Save setting values": "Salvar valores de configuração", + "Values at explicit levels in this room": "Valores em níveis explícitos nessa sala", + "Values at explicit levels": "Valores em níveis explícitos", + "This UI does NOT check the types of the values. Use at your own risk.": "Esta interface de usuário NÃO verifica os tipos de valores. Use por sua conta e risco.", + "Caution:": "Atenção:", + "Setting:": "Configuração:", + "Value in this room": "Valor nessa sala", + "Value": "Valor", + "Failed to save settings": "Falha ao salvar as configurações", + "Show chat effects (animations when receiving e.g. confetti)": "Mostrar efeitos na conversa (por exemplo: animações ao receber confetes)", + "Element Web is experimental on mobile. For a better experience and the latest features, use our free native app.": "O Element Web é experimental para dispositivos móveis. Para uma melhor experiência e os recursos mais recentes, use nosso aplicativo gratuito." } From 3540bec046cc648f97699967439d81b1c5ed2027 Mon Sep 17 00:00:00 2001 From: rkfg Date: Sat, 27 Feb 2021 11:02:52 +0000 Subject: [PATCH 13/91] Translated using Weblate (Russian) Currently translated at 99.6% (2769 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 65aeaf82d9..8310676e69 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -1591,7 +1591,7 @@ "Error upgrading room": "Ошибка обновления комнаты", "Match system theme": "Тема системы", "Show tray icon and minimize window to it on close": "Показать иконку в трее и сворачивать окно при закрытии", - "Show typing notifications": "Показывать уведомления о наборе", + "Show typing notifications": "Показывать уведомления о наборе текста", "Delete %(count)s sessions|other": "Удалить %(count)s сессий", "Enable desktop notifications for this session": "Включить уведомления для рабочего стола для этой сессии", "Enable audible notifications for this session": "Включить звуковые уведомления для этой сессии", @@ -3031,7 +3031,7 @@ "Privacy Policy": "Политика конфиденциальности", "Cookie Policy": "Политика использования файлов cookie", "Learn more in our , and .": "Дополнительную информацию можно найти на страницах , и .", - "Continuing temporarily allows the %(hostSignupBrand)s setup process to access your account to fetch verified email addresses. This data is not stored.": "Продолжая процесс настройки %(hostSignupBrand)s, вы предоставите доступ к вашей учётной записи для получения проверенных адресов электронной почты. Эти данные не сохраняются.", + "Continuing temporarily allows the %(hostSignupBrand)s setup process to access your account to fetch verified email addresses. This data is not stored.": "Продолжая процесс настройки %(hostSignupBrand)s, вы предоставите временный доступ к вашей учётной записи для получения проверенных адресов электронной почты. Эти данные не сохраняются.", "Failed to connect to your homeserver. Please close this dialog and try again.": "Не удалось подключиться к домашнему серверу. Закройте это диалоговое окно и попробуйте ещё раз.", "Abort": "Отмена", "Are you sure you wish to abort creation of the host? The process cannot be continued.": "Вы уверены, что хотите прервать создание хоста? Процесс не может быть продолжен.", @@ -3072,5 +3072,7 @@ "Value in this room": "Значение в этой комнате", "Value": "Значение", "Failed to save settings": "Не удалось сохранить настройки", - "Show chat effects (animations when receiving e.g. confetti)": "Показать эффекты чата (анимация при получении, например, конфетти)" + "Show chat effects (animations when receiving e.g. confetti)": "Показать эффекты чата (анимация при получении, например, конфетти)", + "Caution:": "Предупреждение:", + "Settings Explorer": "Обзор настроек" } From 8d68cbdb142ab0f9f513d1b3583490824cbb49be Mon Sep 17 00:00:00 2001 From: A-l-exa-n-d-r Date: Sat, 27 Feb 2021 08:05:08 +0000 Subject: [PATCH 14/91] Translated using Weblate (Russian) Currently translated at 99.6% (2769 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 8310676e69..7cbcb08167 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -3068,7 +3068,7 @@ "Settable at room": "Устанавливается для комнаты", "Settable at global": "Устанавливается на глобальном уровне", "Level": "Уровень", - "This UI does NOT check the types of the values. Use at your own risk.": "Этот пользовательский интерфейс НЕ проверяет типы значений. Используйте на свой риск.", + "This UI does NOT check the types of the values. Use at your own risk.": "Этот пользовательский интерфейс НЕ проверяет типы значений. Используйте на свой страх и риск.", "Value in this room": "Значение в этой комнате", "Value": "Значение", "Failed to save settings": "Не удалось сохранить настройки", From b6d4e3fe9a247835d87337282ebc2eba7af26a20 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Fri, 26 Feb 2021 07:13:31 +0000 Subject: [PATCH 15/91] Translated using Weblate (Swedish) Currently translated at 100.0% (2780 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/sv/ --- src/i18n/strings/sv.json | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sv.json b/src/i18n/strings/sv.json index 916de9ecce..c8a5a41339 100644 --- a/src/i18n/strings/sv.json +++ b/src/i18n/strings/sv.json @@ -2996,5 +2996,27 @@ "Failed to connect to your homeserver. Please close this dialog and try again.": "Misslyckades att ansluta till din hemserver. Vänligen stäng den här dialogrutan och försök igen.", "Abort": "Avbryt", "Are you sure you wish to abort creation of the host? The process cannot be continued.": "Är du säker på att du vill avbryta skapande av värden? Processen kan inte fortsättas.", - "Confirm abort of host creation": "Bekräfta avbrytning av värdskapande" + "Confirm abort of host creation": "Bekräfta avbrytning av värdskapande", + "Upgrade to %(hostSignupBrand)s": "Uppgradera till %(hostSignupBrand)s", + "Edit Values": "Redigera värden", + "Values at explicit levels in this room:": "Värden vid explicita nivåer i det här rummet:", + "Values at explicit levels:": "Värden vid explicita nivåer:", + "Value in this room:": "Värde i det här rummet:", + "Value:": "Värde:", + "Save setting values": "Spara inställningsvärden", + "Values at explicit levels in this room": "Värden vid explicita nivåer i det här rummet", + "Values at explicit levels": "Värden vid explicita nivåer", + "Settable at room": "Inställningsbar per rum", + "Settable at global": "Inställningsbar globalt", + "Level": "Nivå", + "Setting definition:": "Inställningsdefinition:", + "This UI does NOT check the types of the values. Use at your own risk.": "Det här UI:t kontrollerar inte typer för värden. Använd på egen risk.", + "Caution:": "Varning:", + "Setting:": "Inställning:", + "Value in this room": "Värde i det här rummet", + "Value": "Värde", + "Setting ID": "Inställnings-ID", + "Failed to save settings": "Misslyckades att spara inställningar", + "Settings Explorer": "Inställningsutforskare", + "Show chat effects (animations when receiving e.g. confetti)": "Visa chatteffekter (animeringar när du tar emot t.ex. konfetti)" } From ad38f87287b13eb2ef835781287c16f26169a204 Mon Sep 17 00:00:00 2001 From: linsui Date: Fri, 26 Feb 2021 14:45:43 +0000 Subject: [PATCH 16/91] Translated using Weblate (Chinese (Simplified)) Currently translated at 80.7% (2245 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/zh_Hans/ --- src/i18n/strings/zh_Hans.json | 75 ++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index 167fea70e1..12fb5e2877 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -2409,5 +2409,78 @@ "The call was answered on another device.": "在另一台设备上应答了该通话。", "The call could not be established": "无法建立通话", "The other party declined the call.": "对方拒绝了通话。", - "Call Declined": "通话被拒绝" + "Call Declined": "通话被拒绝", + "(connection failed)": "(连接失败)", + "🎉 All servers are banned from participating! This room can no longer be used.": "🎉 所有服务器都已禁止参与!此聊天室不再可用。", + "%(senderDisplayName)s changed the server ACLs for this room.": "%(senderDisplayName)s 为此聊天室更改了服务器 ACL。", + "%(senderDisplayName)s set the server ACLs for this room.": "%(senderDisplayName)s 为此聊天室设置了服务器 ACL。", + "Hong Kong": "香港", + "Cook Islands": "库克群岛", + "Congo - Kinshasa": "刚果金", + "Congo - Brazzaville": "刚果布拉柴维尔", + "Comoros": "科摩罗", + "Colombia": "哥伦比亚", + "Cocos (Keeling) Islands": "科科斯基林群岛", + "Christmas Island": "圣诞岛", + "China": "中国", + "Chile": "智利", + "Chad": "乍得", + "Central African Republic": "中非共和国", + "Cayman Islands": "开曼群岛(英)", + "Caribbean Netherlands": "荷兰加勒比区", + "Cape Verde": "佛得角", + "Canada": "加拿大", + "Cameroon": "喀麦隆", + "Cambodia": "柬埔寨", + "Burundi": "布隆迪", + "Burkina Faso": "布基纳法索", + "Bulgaria": "保加利亚", + "Brunei": "文莱", + "British Virgin Islands": "英属维尔京群岛", + "British Indian Ocean Territory": "英属印度洋领地", + "Brazil": "巴西", + "Bouvet Island": "布维岛", + "Botswana": "博茨瓦纳", + "Bosnia": "波斯尼亚", + "Bolivia": "玻利维亚", + "Armenia": "亚美尼亚", + "Bhutan": "不丹", + "Bermuda": "百慕大群岛", + "Benin": "贝宁", + "Belize": "伯利兹", + "Belgium": "比利时", + "Belarus": "白俄罗斯", + "Barbados": "巴巴多斯", + "Bangladesh": "孟加拉国", + "Bahrain": "巴林", + "Bahamas": "巴哈马", + "Azerbaijan": "阿塞拜疆", + "Austria": "奥地利", + "Australia": "澳大利亚", + "Aruba": "阿鲁巴岛", + "Argentina": "阿根廷", + "Antigua & Barbuda": "安提瓜和巴布达", + "Antarctica": "南极洲", + "Anguilla": "安圭拉", + "Angola": "安哥拉", + "Andorra": "安道尔", + "American Samoa": "美属萨摩亚", + "Algeria": "阿尔及利亚", + "Albania": "阿尔巴尼亚", + "Åland Islands": "奥兰群岛", + "Afghanistan": "阿富汗", + "United States": "美国", + "United Kingdom": "英国", + "Your homeserver rejected your log in attempt. This could be due to things just taking too long. Please try again. If this continues, please contact your homeserver administrator.": "您的主服务器已拒绝您的登入尝试。请重试。如果此情况持续发生,请联系您的主服务器管理员。", + "Your homeserver was unreachable and was not able to log you in. Please try again. If this continues, please contact your homeserver administrator.": "您的主服务器不可达,无法使您登入。请重试。如果此情况持续发生,请联系您的主服务器管理员。", + "Try again": "重试", + "We asked the browser to remember which homeserver you use to let you sign in, but unfortunately your browser has forgotten it. Go to the sign in page and try again.": "我们已要求浏览器记住您使用的主服务器,但不幸的是您的浏览器已忘记。请前往登录页面重试。", + "We couldn't log you in": "我们无法使您登入", + "This will end the conference for everyone. Continue?": "这将结束所有人的会议。是否继续?", + "End conference": "结束会议", + "You've reached the maximum number of simultaneous calls.": "您已达到并行呼叫最大数量。", + "Too Many Calls": "太多呼叫", + "Call failed because webcam or microphone could not be accessed. Check that:": "通话失败,因为无法访问网络摄像头或麦克风。请检查:", + "Call failed because microphone could not be accessed. Check that a microphone is plugged in and set up correctly.": "呼叫失败,因为无法访问任何麦克风。 检查是否已插入麦克风并正确设置。", + "Answered Elsewhere": "在其他地方已回答" } From c4940d164381449f857a5c88cc9abbc62939a6aa Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Thu, 25 Feb 2021 01:41:18 +0000 Subject: [PATCH 17/91] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (2780 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/zh_Hant/ --- src/i18n/strings/zh_Hant.json | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index b11ff2274f..64dab74139 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -3068,5 +3068,27 @@ "Failed to connect to your homeserver. Please close this dialog and try again.": "無法連線到您的家伺服器。請關閉對話框並再試一次。", "Abort": "中止", "Are you sure you wish to abort creation of the host? The process cannot be continued.": "您確定您想要中止主機建立嗎?流程將無法繼續。", - "Confirm abort of host creation": "確認中止主機建立" + "Confirm abort of host creation": "確認中止主機建立", + "Upgrade to %(hostSignupBrand)s": "升級至 %(hostSignupBrand)s", + "Edit Values": "編輯值", + "Values at explicit levels in this room:": "此聊天室中明確等級的值:", + "Values at explicit levels:": "明確等級的值:", + "Value in this room:": "此聊天室中的值:", + "Value:": "值:", + "Save setting values": "儲存設定值", + "Values at explicit levels in this room": "此聊天室中明確等級的值", + "Values at explicit levels": "明確等級的值", + "Settable at room": "聊天室設定", + "Settable at global": "全域設定", + "Level": "等級", + "Setting definition:": "設定定義:", + "This UI does NOT check the types of the values. Use at your own risk.": "此使用者介面不會檢查值的類型。使用風險自負。", + "Caution:": "警告:", + "Setting:": "設定:", + "Value in this room": "此聊天室中的值", + "Value": "值", + "Setting ID": "設定 ID", + "Failed to save settings": "儲存設定失敗", + "Settings Explorer": "設定瀏覽程式", + "Show chat effects (animations when receiving e.g. confetti)": "顯示聊天效果(當收到如五彩紙屑時顯示動畫)" } From 66cf2075fe9457f5190eb43723efc6cefd327285 Mon Sep 17 00:00:00 2001 From: waclaw66 Date: Fri, 26 Feb 2021 08:30:59 +0000 Subject: [PATCH 18/91] Translated using Weblate (Czech) Currently translated at 100.0% (2780 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/cs/ --- src/i18n/strings/cs.json | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index 3ee9c73399..47a99ab670 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -231,7 +231,7 @@ "You do not have permission to do that in this room.": "V této místnosti nemáte na toto právo.", "You cannot place a call with yourself.": "Nemůžete volat sami sobě.", "You cannot place VoIP calls in this browser.": "V tomto prohlížeči nelze vytáčet VoIP hovory.", - "You do not have permission to post to this room": "Na přispívání do této místnosti nemáte právo", + "You do not have permission to post to this room": "Nemáte oprávnění zveřejňovat příspěvky v této místnosti", "Online": "Online", "Offline": "Offline", "Check for update": "Zkontrolovat aktualizace", @@ -1409,7 +1409,7 @@ "Use an identity server to invite by email. Use the default (%(defaultIdentityServerName)s) or manage in Settings.": "Odeslat pozvánku pomocí serveru identit. Použít výchozí (%(defaultIdentityServerName)s) nebo přenastavit Nastavení.", "Use an identity server to invite by email. Manage in Settings.": "Odeslat pozvánku pomocí serveru identit. Přenastavit v Nastavení.", "Close dialog": "Zavřít dialog", - "Please tell us what went wrong or, better, create a GitHub issue that describes the problem.": "Napište nám prosím co se pokazilo a nebo nám napište issue na GitHub, kde popíšete problém.", + "Please tell us what went wrong or, better, create a GitHub issue that describes the problem.": "Dejte nám vědět, prosím, co se pokazilo nebo vytvořte issue na GitHubu, kde problém popište.", "Removing…": "Odstaňování…", "Clear all data": "Smazat všechna data", "Please enter a name for the room": "Zadejte prosím název místnosti", @@ -1529,7 +1529,7 @@ "Flags": "Vlajky", "Quick Reactions": "Rychlé reakce", "Cancel search": "Zrušit hledání", - "Please create a new issue on GitHub so that we can investigate this bug.": "Vyrobte prosím nové issue na GitHubu abychom mohli chybu opravit.", + "Please create a new issue on GitHub so that we can investigate this bug.": "Vytvořte prosím novou issue na GitHubu abychom mohli chybu opravit.", "%(severalUsers)smade no changes %(count)s times|other": "%(severalUsers)s neudělali %(count)s krát žádnou změnu", "%(severalUsers)smade no changes %(count)s times|one": "%(severalUsers)s neudělali žádnou změnu", "%(oneUser)smade no changes %(count)s times|other": "%(oneUser)s neudělal(a) %(count)s krát žádnou změnu", @@ -2981,5 +2981,27 @@ "Failed to connect to your homeserver. Please close this dialog and try again.": "Připojení k domovskému serveru se nezdařilo. Zavřete toto dialogové okno a zkuste to znovu.", "Abort": "Přerušit", "Are you sure you wish to abort creation of the host? The process cannot be continued.": "Opravdu chcete přerušit vytváření hostitele? Proces nemůže být navázán.", - "Confirm abort of host creation": "Potvrďte přerušení vytváření hostitele" + "Confirm abort of host creation": "Potvrďte přerušení vytváření hostitele", + "Upgrade to %(hostSignupBrand)s": "Aktualizovat na %(hostSignupBrand)s", + "Edit Values": "Upravit hodnoty", + "Values at explicit levels in this room:": "Hodnoty na explicitních úrovních v této místnosti:", + "Values at explicit levels:": "Hodnoty na explicitních úrovních:", + "Value in this room:": "Hodnota v této místnosti:", + "Value:": "Hodnota:", + "Save setting values": "Uložit hodnoty nastavení", + "Values at explicit levels in this room": "Hodnoty na explicitních úrovních v této místnosti", + "Values at explicit levels": "Hodnoty na explicitních úrovních", + "Settable at room": "Nastavitelné v místnosti", + "Settable at global": "Nastavitelné na globální úrovni", + "Level": "Úroveň", + "Setting definition:": "Definice nastavení:", + "This UI does NOT check the types of the values. Use at your own risk.": "Toto uživatelské rozhraní NEKONTROLUJE typy hodnot. Použití na vlastní nebezpečí.", + "Caution:": "Pozor:", + "Setting:": "Nastavení:", + "Value in this room": "Hodnota v této místnosti", + "Value": "Hodnota", + "Setting ID": "ID nastavení", + "Failed to save settings": "Nastavení se nepodařilo uložit", + "Settings Explorer": "Průzkumník nastavení", + "Show chat effects (animations when receiving e.g. confetti)": "Zobrazit efekty chatu (animace např. při přijetí konfet)" } From b6a5b08a86cb466d7e11982c1f0b5a91c53bb5ae Mon Sep 17 00:00:00 2001 From: XoseM Date: Thu, 25 Feb 2021 06:09:06 +0000 Subject: [PATCH 19/91] Translated using Weblate (Galician) Currently translated at 100.0% (2780 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/gl/ --- src/i18n/strings/gl.json | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/gl.json b/src/i18n/strings/gl.json index b309f12245..98a984d860 100644 --- a/src/i18n/strings/gl.json +++ b/src/i18n/strings/gl.json @@ -3065,5 +3065,27 @@ "Failed to connect to your homeserver. Please close this dialog and try again.": "Fallou a conexión co teu servidor de inicio. Pecha esta información e inténtao outra vez.", "Abort": "Abortar", "Are you sure you wish to abort creation of the host? The process cannot be continued.": "Tes a certeza de querer cancelar a creación do servidor? O proceso non pode ser completado.", - "Confirm abort of host creation": "Corfirma que cancelas a creación do servidor" + "Confirm abort of host creation": "Corfirma que cancelas a creación do servidor", + "Upgrade to %(hostSignupBrand)s": "Actualizar a %(hostSignupBrand)s", + "Edit Values": "Editar valores", + "Values at explicit levels in this room:": "Valores a niveis explícitos nesta sala:", + "Values at explicit levels:": "Valores a niveis explícitos:", + "Value in this room:": "Valor nesta sala:", + "Value:": "Valor:", + "Save setting values": "Gardar valores configurados", + "Values at explicit levels in this room": "Valores a niveis explícitos nesta sala", + "Values at explicit levels": "Valores e niveis explícitos", + "Settable at room": "Configurable na sala", + "Settable at global": "Configurable como global", + "Level": "Nivel", + "Setting definition:": "Definición do axuste:", + "This UI does NOT check the types of the values. Use at your own risk.": "Esta IU non comproba os tipos dos valores. Usa baixo a túa responsabilidade.", + "Caution:": "Aviso:", + "Setting:": "Axuste:", + "Value in this room": "Valor nesta sala", + "Value": "Valor", + "Setting ID": "ID do axuste", + "Failed to save settings": "Non se gardaron os axustes", + "Settings Explorer": "Navegar nos axustes", + "Show chat effects (animations when receiving e.g. confetti)": "Mostrar efectos no chat (animacións na recepción, ex. confetti)" } From 73421597b63b7f3f266f7fcf94bb4030c70b9a12 Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Fri, 26 Feb 2021 17:16:44 +0000 Subject: [PATCH 20/91] Translated using Weblate (Albanian) Currently translated at 99.6% (2769 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/sq/ --- src/i18n/strings/sq.json | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/sq.json b/src/i18n/strings/sq.json index e8e47ac81b..dd58154b5a 100644 --- a/src/i18n/strings/sq.json +++ b/src/i18n/strings/sq.json @@ -2990,7 +2990,7 @@ "If you've forgotten your Security Key you can ": "Nëse keni harruar Kyçin tuaj të Sigurisë, mund të .", "Your Security Key has been copied to your clipboard, paste it to:": "Kyçi juaj i Sigurisë është kopjuar te e papastra juaj, ngjiteni te:", "Confirm your Security Phrase": "Ripohoni Frazën tuaj të Sigurisë", - "Secure your backup with a Security Phrase": "Sigurojeni kopjeruajtjen tuaj me një Frazë Sigurie.", + "Secure your backup with a Security Phrase": "Sigurojeni kopjeruajtjen tuaj me një Frazë Sigurie", "Repeat your Security Phrase...": "Përsëritni Frazën tuaj të Sigurisë…", "Please enter your Security Phrase a second time to confirm.": "Ju lutemi, që të ripohohet, rijepeni Frazën tuaj të Sigurisë.", "This session has detected that your Security Phrase and key for Secure Messages have been removed.": "Ky sesion ka pikasur se Fraza e Sigurisë dhe kyçi juaj për Mesazhe të Sigurt janë hequr.", @@ -3056,5 +3056,25 @@ "Failed to connect to your homeserver. Please close this dialog and try again.": "S’u arrit të lidhej me shërbyesin tuaj Home. Ju lutemi, mbylleni këtë dialog dhe riprovoni.", "Abort": "Ndërprite", "Are you sure you wish to abort creation of the host? The process cannot be continued.": "Jeni i sigurt se doni të ndërpritet krijimi i strehës? Procesi s’mund të vazhdohet.", - "Confirm abort of host creation": "Ripohoni ndërprerjen e krijimit të strehës" + "Confirm abort of host creation": "Ripohoni ndërprerjen e krijimit të strehës", + "Upgrade to %(hostSignupBrand)s": "Përmirësojeni me %(hostSignupBrand)s", + "Edit Values": "Përpunoni Vlera", + "Values at explicit levels in this room:": "Vlera në nivele shprehimisht në këtë dhomë:", + "Values at explicit levels:": "Vlera në nivele shprehimisht:", + "Value in this room:": "Vlerë në këtë dhomë:", + "Value:": "Vlerë:", + "Save setting values": "Ruaj vlera rregullimi", + "Values at explicit levels in this room": "Vlera në nivele shprehimisht në këtë dhomë", + "Values at explicit levels": "Vlera në nivele shprehimisht", + "Settable at room": "I caktueshëm për dhomën", + "Settable at global": "I caktueshëm te të përgjithshmet", + "Level": "Nivel", + "Setting definition:": "Përkufizim rregullimi:", + "This UI does NOT check the types of the values. Use at your own risk.": "Kjo UI NUK kontrollon llojet e vlerave. Përdorini me përgjegjësinë tuaj.", + "Setting:": "Rregullim:", + "Value in this room": "Vlerë në këtë dhomë", + "Value": "Vlerë", + "Failed to save settings": "S’u arrit të ruhen rregullimet", + "Settings Explorer": "Eksplorues Rregullimesh", + "Show chat effects (animations when receiving e.g. confetti)": "Shfaq efekte fjalosjeje (animacione kur merren bonbone, për shembull)" } From 55bfe21df0ed8827b7dca40cd580ac91cf202f82 Mon Sep 17 00:00:00 2001 From: Trendyne Date: Thu, 25 Feb 2021 14:25:53 +0000 Subject: [PATCH 21/91] Translated using Weblate (Icelandic) Currently translated at 14.8% (413 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/is/ --- src/i18n/strings/is.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/is.json b/src/i18n/strings/is.json index 6f561331f6..ddb3bbc66d 100644 --- a/src/i18n/strings/is.json +++ b/src/i18n/strings/is.json @@ -458,5 +458,7 @@ "Passphrases must match": "Lykilfrasar verða að stemma", "Passphrase must not be empty": "Lykilfrasi má ekki vera auður", "Create Account": "Stofna Reikning", - "Please install Chrome, Firefox, or Safari for the best experience.": "vinsamlegast setja upp Chrome, Firefox, eða Safari fyrir besta reynsluna." + "Please install Chrome, Firefox, or Safari for the best experience.": "vinsamlegast setja upp Chrome, Firefox, eða Safari fyrir besta reynsluna.", + "Explore rooms": "Kanna herbergi", + "Sign In": "Skrá inn" } From 36ef0be05b028a4e97afac0499491a20f9ae7ab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Thu, 25 Feb 2021 16:43:43 +0000 Subject: [PATCH 22/91] Translated using Weblate (Estonian) Currently translated at 100.0% (2780 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/et/ --- src/i18n/strings/et.json | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/et.json b/src/i18n/strings/et.json index 7769cf61c8..eb895f5f26 100644 --- a/src/i18n/strings/et.json +++ b/src/i18n/strings/et.json @@ -3066,5 +3066,27 @@ "Privacy Policy": "Privaatsuspoliitika", "Cookie Policy": "Küpsiste kasutamine", "Learn more in our , and .": "Lisateavet leiad , ja lehtedelt.", - "Failed to connect to your homeserver. Please close this dialog and try again.": "Ei õnnestunud ühendada koduserveriga. Palun sulge see aken ja proovi uuesti." + "Failed to connect to your homeserver. Please close this dialog and try again.": "Ei õnnestunud ühendada koduserveriga. Palun sulge see aken ja proovi uuesti.", + "Upgrade to %(hostSignupBrand)s": "Kui soovid, siis võta kasutusele %(hostSignupBrand)s", + "Edit Values": "Muuda väärtusi", + "Values at explicit levels in this room:": "Väärtused konkreetsel tasemel selles jututoas:", + "Values at explicit levels:": "Väärtused konkreetsel tasemel:", + "Value in this room:": "Väärtus selles jututoas:", + "Value:": "Väärtus:", + "Save setting values": "Salvesta seadistuste väärtused", + "Values at explicit levels in this room": "Väärtused konkreetsel tasemel selles jututoas", + "Values at explicit levels": "Väärtused konkreetsel tasemel", + "Settable at room": "Seadistatav jututoa-kohaselt", + "Settable at global": "Seadistatav üldiselt", + "Level": "Tase", + "Setting definition:": "Seadistuse määratlus:", + "This UI does NOT check the types of the values. Use at your own risk.": "See kasutajaliides ei oska kontrollida väärtuste tüüpi ja vormingut. Muudatusi teed omal vastutusel.", + "Caution:": "Hoiatus:", + "Setting:": "Seadistus:", + "Value in this room": "Väärtus selles jututoas", + "Value": "Väärtus", + "Setting ID": "Seadistuse tunnus", + "Failed to save settings": "Seadistuste salvestamine ei õnnestunud", + "Settings Explorer": "Seadistuste haldur", + "Show chat effects (animations when receiving e.g. confetti)": "Näita vestluses edevat graafikat (näiteks kui keegi on saatnud serpentiine)" } From d1a75885a7a65477ab106e65b745a6e2e972daf6 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 2 Mar 2021 15:35:02 +0000 Subject: [PATCH 23/91] Protect onAction dispatch handler on the SpaceStore with Spaces disabled --- src/stores/SpaceStore.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/stores/SpaceStore.tsx b/src/stores/SpaceStore.tsx index d675879138..8e0066da91 100644 --- a/src/stores/SpaceStore.tsx +++ b/src/stores/SpaceStore.tsx @@ -408,6 +408,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient { } protected async onAction(payload: ActionPayload) { + if (!SettingsStore.getValue("feature_spaces")) return; switch (payload.action) { case "view_room": { const room = this.matrixClient?.getRoom(payload.room_id); From d9a801910a44a80c63035fcaab5769450951c612 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 3 Mar 2021 11:34:29 +0000 Subject: [PATCH 24/91] Tweak spaces copy --- src/RoomInvite.js | 7 ++--- src/components/structures/SpaceRoomView.tsx | 2 +- src/components/views/dialogs/InviteDialog.tsx | 31 +++++++++++-------- .../views/spaces/SpaceCreateMenu.tsx | 11 +++---- src/i18n/strings/en_EN.json | 18 ++++++----- 5 files changed, 37 insertions(+), 32 deletions(-) diff --git a/src/RoomInvite.js b/src/RoomInvite.js index 503411d2b3..9ae41b851a 100644 --- a/src/RoomInvite.js +++ b/src/RoomInvite.js @@ -22,7 +22,7 @@ import MultiInviter from './utils/MultiInviter'; import Modal from './Modal'; import * as sdk from './'; import { _t } from './languageHandler'; -import InviteDialog, {KIND_DM, KIND_INVITE, KIND_SPACE_INVITE} from "./components/views/dialogs/InviteDialog"; +import InviteDialog, {KIND_DM, KIND_INVITE} from "./components/views/dialogs/InviteDialog"; import CommunityPrototypeInviteDialog from "./components/views/dialogs/CommunityPrototypeInviteDialog"; import {CommunityPrototypeStore} from "./stores/CommunityPrototypeStore"; @@ -50,11 +50,10 @@ export function showStartChatInviteDialog(initialText) { } export function showRoomInviteDialog(roomId) { - const isSpace = MatrixClientPeg.get()?.getRoom(roomId)?.isSpaceRoom(); // This dialog handles the room creation internally - we don't need to worry about it. Modal.createTrackedDialog( - "Invite Users", isSpace ? "Space" : "Room", InviteDialog, { - kind: isSpace ? KIND_SPACE_INVITE : KIND_INVITE, + "Invite Users", "", InviteDialog, { + kind: KIND_INVITE, roomId, }, /*className=*/null, /*isPriority=*/false, /*isStatic=*/true, diff --git a/src/components/structures/SpaceRoomView.tsx b/src/components/structures/SpaceRoomView.tsx index 5c91efc1c0..9bacdd975d 100644 --- a/src/components/structures/SpaceRoomView.tsx +++ b/src/components/structures/SpaceRoomView.tsx @@ -557,7 +557,7 @@ export default class SpaceRoomView extends React.PureComponent { case Phase.PublicCreateRooms: return this.setState({ phase: Phase.PublicShare })} />; diff --git a/src/components/views/dialogs/InviteDialog.tsx b/src/components/views/dialogs/InviteDialog.tsx index 9bc5b6476f..6d5cb8786e 100644 --- a/src/components/views/dialogs/InviteDialog.tsx +++ b/src/components/views/dialogs/InviteDialog.tsx @@ -48,7 +48,6 @@ import { MatrixCall } from 'matrix-js-sdk/src/webrtc/call'; export const KIND_DM = "dm"; export const KIND_INVITE = "invite"; -export const KIND_SPACE_INVITE = "space_invite"; export const KIND_CALL_TRANSFER = "call_transfer"; const INITIAL_ROOMS_SHOWN = 3; // Number of rooms to show at first @@ -310,7 +309,7 @@ interface IInviteDialogProps { // not provided. kind: string, - // The room ID this dialog is for. Only required for KIND_INVITE and KIND_SPACE_INVITE. + // The room ID this dialog is for. Only required for KIND_INVITE. roomId: string, // The call to transfer. Only required for KIND_CALL_TRANSFER. @@ -349,8 +348,8 @@ export default class InviteDialog extends React.PureComponent) or share this room."); + "(like ) or share this space."); } else { helpTextUntranslated = _td("Invite someone using their name, username " + - "(like ) or share this room."); + "(like ) or share this space."); } - } else { // KIND_SPACE_INVITE + } else { if (identityServersEnabled) { helpTextUntranslated = _td("Invite someone using their name, email address, username " + - "(like ) or share this space."); + "(like ) or share this room."); } else { helpTextUntranslated = _td("Invite someone using their name, username " + - "(like ) or share this space."); + "(like ) or share this room."); } } diff --git a/src/components/views/spaces/SpaceCreateMenu.tsx b/src/components/views/spaces/SpaceCreateMenu.tsx index 9d0543a6c5..88098d1b66 100644 --- a/src/components/views/spaces/SpaceCreateMenu.tsx +++ b/src/components/views/spaces/SpaceCreateMenu.tsx @@ -107,7 +107,8 @@ const SpaceCreateMenu = ({ onFinished }) => { if (visibility === null) { body =

{ _t("Create a space") }

-

{ _t("Organise rooms into spaces, for just you or anyone") }

+

{ _t("Spaces are new ways to group rooms and people. " + + "To join an existing space you’ll need an invite") }

{ /> setVisibility(Visibility.Private)} /> - {/*

{ _t("Looking to join an existing space?") }

*/} +

{ _t("You can change this later") }

; } else { body = @@ -134,9 +135,7 @@ const SpaceCreateMenu = ({ onFinished }) => {

{ - visibility === Visibility.Public - ? _t("Personalise your public space") - : _t("Personalise your private space") + visibility === Visibility.Public ? _t("Your public space") : _t("Your private space") }

diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 8609af6a71..e256e6bb2f 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -983,14 +983,15 @@ "Name": "Name", "Description": "Description", "Create a space": "Create a space", - "Organise rooms into spaces, for just you or anyone": "Organise rooms into spaces, for just you or anyone", + "Spaces are new ways to group rooms and people. To join an existing space you’ll need an invite": "Spaces are new ways to group rooms and people. To join an existing space you’ll need an invite", "Public": "Public", "Open space for anyone, best for communities": "Open space for anyone, best for communities", "Private": "Private", - "Invite only space, best for yourself or teams": "Invite only space, best for yourself or teams", + "Invite only, best for yourself or teams": "Invite only, best for yourself or teams", + "You can change this later": "You can change this later", "Go back": "Go back", - "Personalise your public space": "Personalise your public space", - "Personalise your private space": "Personalise your private space", + "Your public space": "Your public space", + "Your private space": "Your private space", "Give it a photo, name and description to help you identify it.": "Give it a photo, name and description to help you identify it.", "You can change these at any point.": "You can change these at any point.", "Creating...": "Creating...", @@ -2190,10 +2191,12 @@ "Start a conversation with someone using their name or username (like ).": "Start a conversation with someone using their name or username (like ).", "This won't invite them to %(communityName)s. To invite someone to %(communityName)s, click here": "This won't invite them to %(communityName)s. To invite someone to %(communityName)s, click here", "Go": "Go", - "Invite someone using their name, email address, username (like ) or share this room.": "Invite someone using their name, email address, username (like ) or share this room.", - "Invite someone using their name, username (like ) or share this room.": "Invite someone using their name, username (like ) or share this room.", + "Invite to %(spaceName)s": "Invite to %(spaceName)s", + "Unnamed Space": "Unnamed Space", "Invite someone using their name, email address, username (like ) or share this space.": "Invite someone using their name, email address, username (like ) or share this space.", "Invite someone using their name, username (like ) or share this space.": "Invite someone using their name, username (like ) or share this space.", + "Invite someone using their name, email address, username (like ) or share this room.": "Invite someone using their name, email address, username (like ) or share this room.", + "Invite someone using their name, username (like ) or share this room.": "Invite someone using their name, username (like ) or share this room.", "Transfer": "Transfer", "a new master key signature": "a new master key signature", "a new cross-signing key signature": "a new cross-signing key signature", @@ -2587,7 +2590,6 @@ "Failed to reject invite": "Failed to reject invite", "You have %(count)s unread notifications in a prior version of this room.|other": "You have %(count)s unread notifications in a prior version of this room.", "You have %(count)s unread notifications in a prior version of this room.|one": "You have %(count)s unread notification in a prior version of this room.", - "Unnamed Space": "Unnamed Space", "Undo": "Undo", "Remove from Space": "Remove from Space", "No permissions": "No permissions", @@ -2626,7 +2628,7 @@ "Invite your teammates": "Invite your teammates", "Invite by username": "Invite by username", "Inviting...": "Inviting...", - "What discussions do you want to have?": "What discussions do you want to have?", + "What are some things you want to discuss?": "What are some things you want to discuss?", "We'll create rooms for each topic.": "We'll create rooms for each topic.", "What projects are you working on?": "What projects are you working on?", "We'll create rooms for each of them. You can add existing rooms after setup.": "We'll create rooms for each of them. You can add existing rooms after setup.", From ab4220b20d98d4e47574f945baee64bbf2ec3b48 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 4 Mar 2021 13:04:58 +0000 Subject: [PATCH 25/91] Defer auto-joining within spaces and switch to using `suggested` --- .../structures/SpaceRoomDirectory.tsx | 33 ++++++++++--------- src/i18n/strings/en_EN.json | 2 +- src/stores/SpaceStore.tsx | 3 +- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/components/structures/SpaceRoomDirectory.tsx b/src/components/structures/SpaceRoomDirectory.tsx index 7f7b9dbb99..0a59ac0195 100644 --- a/src/components/structures/SpaceRoomDirectory.tsx +++ b/src/components/structures/SpaceRoomDirectory.tsx @@ -64,6 +64,7 @@ export interface ISpaceSummaryEvent { state_key: string; content: { order?: string; + suggested?: boolean; auto_join?: boolean; via?: string; }; @@ -91,7 +92,7 @@ const SubSpace: React.FC = ({ const name = space.name || space.canonical_alias || space.aliases?.[0] || _t("Unnamed Space"); const evContent = event?.getContent(); - const [autoJoin, _setAutoJoin] = useState(evContent?.auto_join); + const [suggested, _setSuggested] = useState(evContent?.suggested); const [removed, _setRemoved] = useState(!evContent?.via); const cli = MatrixClientPeg.get(); @@ -102,12 +103,12 @@ const SubSpace: React.FC = ({ let actions; if (editing && queueAction) { if (event && cli.getRoom(event.getRoomId())?.currentState.maySendStateEvent(event.getType(), cli.getUserId())) { - const setAutoJoin = () => { - _setAutoJoin(v => { + const setSuggested = () => { + _setSuggested(v => { queueAction({ event, removed, - autoJoin: !v, + suggested: !v, }); return !v; }); @@ -118,7 +119,7 @@ const SubSpace: React.FC = ({ queueAction({ event, removed: !v, - autoJoin, + suggested, }); return !v; }); @@ -131,7 +132,7 @@ const SubSpace: React.FC = ({ } else { actions = - + ; } } else { @@ -180,8 +181,8 @@ const SubSpace: React.FC = ({ interface IAction { event: MatrixEvent; + suggested: boolean; removed: boolean; - autoJoin: boolean; } interface IRoomTileProps { @@ -197,7 +198,7 @@ const RoomTile = ({ room, event, editing, queueAction, onPreviewClick, onJoinCli const name = room.name || room.canonical_alias || room.aliases?.[0] || _t("Unnamed Room"); const evContent = event?.getContent(); - const [autoJoin, _setAutoJoin] = useState(evContent?.auto_join); + const [suggested, _setSuggested] = useState(evContent?.suggested); const [removed, _setRemoved] = useState(!evContent?.via); const cli = MatrixClientPeg.get(); @@ -207,12 +208,12 @@ const RoomTile = ({ room, event, editing, queueAction, onPreviewClick, onJoinCli let actions; if (editing && queueAction) { if (event && cli.getRoom(event.getRoomId())?.currentState.maySendStateEvent(event.getType(), cli.getUserId())) { - const setAutoJoin = () => { - _setAutoJoin(v => { + const setSuggested = () => { + _setSuggested(v => { queueAction({ event, removed, - autoJoin: !v, + suggested: !v, }); return !v; }); @@ -223,7 +224,7 @@ const RoomTile = ({ room, event, editing, queueAction, onPreviewClick, onJoinCli queueAction({ event, removed: !v, - autoJoin, + suggested, }); return !v; }); @@ -236,7 +237,7 @@ const RoomTile = ({ room, event, editing, queueAction, onPreviewClick, onJoinCli } else { actions = - + ; } } else { @@ -441,10 +442,10 @@ const SpaceRoomDirectory: React.FC = ({ space, initialText = "", onFinis const onSaveButtonClicked = () => { // TODO setBusy - pendingActions.current.forEach(({event, autoJoin, removed}) => { + pendingActions.current.forEach(({event, suggested, removed}) => { const content = { ...event.getContent(), - auto_join: autoJoin, + suggested, }; if (removed) { @@ -459,7 +460,7 @@ const SpaceRoomDirectory: React.FC = ({ space, initialText = "", onFinis if (isEditing) { adminButton = - { _t("All users join by default") } + { _t("Promoted to users") } ; } else { adminButton = ; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index e256e6bb2f..7b680b6590 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2596,7 +2596,7 @@ "You're in this space": "You're in this space", "You're in this room": "You're in this room", "Save changes": "Save changes", - "All users join by default": "All users join by default", + "Promoted to users": "Promoted to users", "Manage rooms": "Manage rooms", "Find a room...": "Find a room...", "Accept Invite": "Accept Invite", diff --git a/src/stores/SpaceStore.tsx b/src/stores/SpaceStore.tsx index 8e0066da91..c334144d70 100644 --- a/src/stores/SpaceStore.tsx +++ b/src/stores/SpaceStore.tsx @@ -108,9 +108,10 @@ export class SpaceStoreClass extends AsyncStoreWithClient { } } - public addRoomToSpace(space: Room, roomId: string, via: string[], autoJoin = false) { + public addRoomToSpace(space: Room, roomId: string, via: string[], suggested = false, autoJoin = false) { return this.matrixClient.sendStateEvent(space.roomId, EventType.SpaceChild, { via, + suggested, auto_join: autoJoin, }, roomId); } From 1d8c9375cfb511b295dd6228963d8b5d0f687a2e Mon Sep 17 00:00:00 2001 From: libexus Date: Thu, 4 Mar 2021 20:35:28 +0000 Subject: [PATCH 26/91] Translated using Weblate (German) Currently translated at 99.3% (2761 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 8a07b6cd9f..13fc6fc3b7 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -3070,5 +3070,6 @@ "Value": "Wert", "Setting ID": "Einstellungs-ID", "Failed to save settings": "Einstellungen konnten nicht gespeichert werden", - "Show chat effects (animations when receiving e.g. confetti)": "Animierte Chateffekte zeigen, wenn z.B. Konfetti-Emojis erhalten werden" + "Show chat effects (animations when receiving e.g. confetti)": "Animierte Chateffekte zeigen, wenn z.B. Konfetti-Emojis erhalten werden", + "Save setting values": "Einstellungswerte speichern" } From ccb47285bc3030697fd88db50eca7d3742504ac7 Mon Sep 17 00:00:00 2001 From: "@a2sc:matrix.org" Date: Thu, 4 Mar 2021 20:34:54 +0000 Subject: [PATCH 27/91] Translated using Weblate (German) Currently translated at 99.3% (2761 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 13fc6fc3b7..07a1a4f805 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -3071,5 +3071,6 @@ "Setting ID": "Einstellungs-ID", "Failed to save settings": "Einstellungen konnten nicht gespeichert werden", "Show chat effects (animations when receiving e.g. confetti)": "Animierte Chateffekte zeigen, wenn z.B. Konfetti-Emojis erhalten werden", - "Save setting values": "Einstellungswerte speichern" + "Save setting values": "Einstellungswerte speichern", + "Caution:": "Vorsicht:" } From 395c010a84deb26d2fa812022376d2ef22825392 Mon Sep 17 00:00:00 2001 From: iaiz Date: Sat, 6 Mar 2021 21:01:51 +0000 Subject: [PATCH 28/91] Translated using Weblate (Spanish) Currently translated at 100.0% (2780 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/es/ --- src/i18n/strings/es.json | 439 +++++++++++++++++++++++---------------- 1 file changed, 261 insertions(+), 178 deletions(-) diff --git a/src/i18n/strings/es.json b/src/i18n/strings/es.json index cbe7e0a223..4b50d59f2a 100644 --- a/src/i18n/strings/es.json +++ b/src/i18n/strings/es.json @@ -45,7 +45,7 @@ "Cryptography": "Criptografía", "Current password": "Contraseña actual", "/ddg is not a command": "/ddg no es un comando", - "Deactivate Account": "Desactivar Cuenta", + "Deactivate Account": "Desactivar cuenta", "Decrypt %(text)s": "Descifrar %(text)s", "Deops user with given id": "Quita el poder de operador al usuario con la ID dada", "Default": "Por defecto", @@ -65,18 +65,18 @@ "Failed to change power level": "Falló al cambiar de nivel de acceso", "Failed to forget room %(errCode)s": "No se pudo olvidar la sala %(errCode)s", "Failed to join room": "No se pudo unir a la sala", - "Failed to kick": "Falló al expulsar", + "Failed to kick": "No se ha podido echar", "Failed to leave room": "No se pudo salir de la sala", - "Failed to load timeline position": "Falló al cargar el historico", + "Failed to load timeline position": "Fallo al cargar el historial", "Failed to mute user": "No se pudo silenciar al usuario", "Failed to reject invite": "Falló al rechazar invitación", "Failed to reject invitation": "Falló al rechazar la invitación", "Failed to send email": "No se pudo enviar el correo electrónico", "Failed to send request.": "El envío de la solicitud falló.", - "Failed to set display name": "No se pudo establecer el nombre público", + "Failed to set display name": "No se ha podido cambiar el nombre público", "Failed to unban": "No se pudo quitar veto", - "Failed to verify email address: make sure you clicked the link in the email": "No se pudo verificar la dirección de correo electrónico: asegúrate de hacer clic en el enlace del correo electrónico", - "Failure to create room": "No se pudo crear sala", + "Failed to verify email address: make sure you clicked the link in the email": "No se ha podido verificar la dirección de correo electrónico: asegúrate de hacer clic en el enlace del mensaje", + "Failure to create room": "No se ha podido crear la sala", "Favourite": "Añadir a favoritos", "Favourites": "Favoritos", "Fill screen": "Llenar pantalla", @@ -100,10 +100,10 @@ "Sign in with": "Quiero iniciar sesión con", "Join Room": "Unirse a la Sala", "%(targetName)s joined the room.": "%(targetName)s se unió a la sala.", - "%(senderName)s kicked %(targetName)s.": "%(senderName)s expulsó a %(targetName)s.", - "Kick": "Expulsar", - "Kicks user with given id": "Expulsa al usuario con la ID dada", - "Labs": "Laboratorios", + "%(senderName)s kicked %(targetName)s.": "%(senderName)s echó a %(targetName)s.", + "Kick": "Echar", + "Kicks user with given id": "Echa al usuario con la ID dada", + "Labs": "Experimentos", "Leave room": "Salir de la sala", "%(targetName)s left the room.": "%(targetName)s salió de la sala.", "Logout": "Cerrar sesión", @@ -134,7 +134,7 @@ "Incorrect username and/or password.": "Nombre de usuario y/o contraseña incorrectos.", "Invited": "Invitado", "Jump to first unread message.": "Ir al primer mensaje no leído.", - "Last seen": "Visto por última vez", + "Last seen": "Último uso", "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s hizo visible el historial futuro de la sala para todos los miembros de la sala, desde el momento en que son invitados.", "%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s hizo visible el historial futuro de la sala para todos los miembros de la sala, desde el momento en que se unieron.", "%(senderName)s made future room history visible to all room members.": "%(senderName)s hizo visible el historial futuro de la sala para todos los miembros de la sala.", @@ -173,7 +173,7 @@ "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s invitó a %(targetDisplayName)s a unirse a la sala.", "Server error": "Error del servidor", "Server may be unavailable, overloaded, or search timed out :(": "El servidor podría estar saturado o desconectado, o la búsqueda caducó :(", - "Server may be unavailable, overloaded, or you hit a bug.": "El servidor podría estar saturado o desconectado, o encontraste un fallo.", + "Server may be unavailable, overloaded, or you hit a bug.": "El servidor podría estar saturado o desconectado, o has encontrado un fallo.", "Server unavailable, overloaded, or something else went wrong.": "Servidor saturado, desconectado, o alguien ha roto algo.", "Session ID": "ID de Sesión", "%(senderName)s set a profile picture.": "%(senderName)s estableció una imagen de perfil.", @@ -182,7 +182,7 @@ "Signed Out": "Desconectado", "Sign in": "Conectar", "Sign out": "Cerrar sesión", - "%(count)s of your messages have not been sent.|other": "Algunos de sus mensajes no han sido enviados.", + "%(count)s of your messages have not been sent.|other": "Algunos de tus mensajes no han sido enviados.", "Someone": "Alguien", "Start authentication": "Iniciar autenticación", "Submit": "Enviar", @@ -191,8 +191,8 @@ "Active call (%(roomName)s)": "Llamada activa (%(roomName)s)", "Add a topic": "Añadir un tema", "No media permissions": "Sin permisos para el medio", - "You may need to manually permit %(brand)s to access your microphone/webcam": "Probablemente necesite dar permisos manualmente a %(brand)s para su micrófono/cámara", - "Are you sure you want to leave the room '%(roomName)s'?": "¿Seguro que quieres salir de la sala '%(roomName)s'?", + "You may need to manually permit %(brand)s to access your microphone/webcam": "Probablemente necesites dar permisos manualmente a %(brand)s para tu micrófono/cámara", + "Are you sure you want to leave the room '%(roomName)s'?": "¿Salir de la sala «%(roomName)s?", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "No se puede conectar al servidor base. Por favor, comprueba tu conexión, asegúrate de que el certificado SSL del servidor es de confiaza, y comprueba que no haya extensiones de navegador bloqueando las peticiones.", "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s eliminó el nombre de la sala.", "Drop File Here": "Deje el fichero aquí", @@ -214,7 +214,7 @@ "No results": "No hay resultados", "No users have specific privileges in this room": "Ningún usuario tiene permisos específicos en esta sala", "OK": "Vale", - "olm version:": "versión de olm:", + "olm version:": "Versión de olm:", "Only people who have been invited": "Solo las personas que hayan sido invitadas", "Operation failed": "Falló la operación", "Password": "Contraseña", @@ -238,19 +238,19 @@ "Results from DuckDuckGo": "Resultados desde DuckDuckGo", "Return to login screen": "Regresar a la pantalla de inicio de sesión", "%(brand)s does not have permission to send you notifications - please check your browser settings": "%(brand)s no tiene permiso para enviarte notificaciones - por favor, comprueba los ajustes de tu navegador", - "%(brand)s was not given permission to send notifications - please try again": "No se le dio permiso a %(brand)s para enviar notificaciones - por favor, inténtalo nuevamente", + "%(brand)s was not given permission to send notifications - please try again": "No le has dado permiso a %(brand)s para enviar notificaciones. Por favor, inténtalo de nuevo", "%(brand)s version:": "Versión de %(brand)s:", "Room %(roomId)s not visible": "La sala %(roomId)s no está visible", "Searches DuckDuckGo for results": "Busca resultados en DuckDuckGo", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Mostrar marcas temporales en formato de 12 horas (ej. 2:30pm)", "This email address is already in use": "Esta dirección de correo electrónico ya está en uso", - "This email address was not found": "No se encontró esta dirección de correo electrónico", + "This email address was not found": "No se ha encontrado la dirección de correo electrónico", "The email address linked to your account must be entered.": "Debes ingresar la dirección de correo electrónico vinculada a tu cuenta.", - "The remote side failed to pick up": "El lado remoto no contestó", + "The remote side failed to pick up": "El otro lado no ha respondido a la llamada", "This room has no local addresses": "Esta sala no tiene direcciones locales", "This room is not recognised.": "No se reconoce esta sala.", "This doesn't appear to be a valid email address": "Esto no parece un e-mail váido", - "This phone number is already in use": "Este número telefónico ya está en uso", + "This phone number is already in use": "Este número de teléfono ya está en uso", "This room": "Esta sala", "This room is not accessible by remote Matrix servers": "Esta sala no es accesible por otros servidores Matrix", "Cancel": "Cancelar", @@ -308,9 +308,9 @@ "You are already in a call.": "Ya estás participando en una llamada.", "You are not in this room.": "No estás en esta sala.", "You do not have permission to do that in this room.": "No tienes permiso para realizar esa acción en esta sala.", - "You cannot place a call with yourself.": "No puedes realizar una llamada contigo mismo.", + "You cannot place a call with yourself.": "No puedes llamarte a ti mismo.", "Cannot add any more widgets": "no es posible agregar mas widgets", - "Publish this room to the public in %(domain)s's room directory?": "¿Quieres que esta sala aparezca en el directorio de salas de %(domain)s?", + "Publish this room to the public in %(domain)s's room directory?": "¿Quieres que la sala aparezca en el directorio de salas de %(domain)s?", "AM": "AM", "PM": "PM", "The maximum permitted number of widgets have already been added to this room.": "La cantidad máxima de widgets permitida ha sido alcanzada en esta sala.", @@ -323,20 +323,20 @@ "You have disabled URL previews by default.": "Has desactivado la vista previa de URLs por defecto.", "You have enabled URL previews by default.": "Has activado las vista previa de URLs por defecto.", "You have no visible notifications": "No tiene notificaciones visibles", - "You must register to use this functionality": "Usted debe ser un registrar para usar esta funcionalidad", + "You must register to use this functionality": "Regístrate para usar esta funcionalidad", "You need to be able to invite users to do that.": "Debes ser capaz de invitar usuarios para realizar esa acción.", "You need to be logged in.": "Necesitas haber iniciado sesión.", "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Tu dirección de correo electrónico no parece estar asociada a una ID de Matrix en este servidor base.", "You seem to be in a call, are you sure you want to quit?": "Parece estar en medio de una llamada, ¿esta seguro que desea salir?", "You seem to be uploading files, are you sure you want to quit?": "Pareces estar subiendo archivos, ¿seguro que quieres salir?", "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "No podrás deshacer este cambio porque estás promoviendo al usuario para tener el mismo nivel de autoridad que tú.", - "Sun": "Dom", - "Mon": "Lun", - "Tue": "Mar", - "Wed": "Mie", - "Thu": "Jue", - "Fri": "Vie", - "Sat": "Sab", + "Sun": "dom.", + "Mon": "lun.", + "Tue": "mar.", + "Wed": "mié.", + "Thu": "jue.", + "Fri": "vie.", + "Sat": "sáb.", "Jan": "Ene", "Feb": "Feb", "Mar": "Mar", @@ -346,25 +346,25 @@ "Jul": "Jul", "Aug": "Ago", "Add rooms to this community": "Agregar salas a esta comunidad", - "Call Failed": "La Llamada Falló", + "Call Failed": "Llamada fallida", "Sep": "Sep", "Oct": "Oct", "Nov": "Nov", "Dec": "Dic", "Warning": "Advertencia", - "Unpin Message": "Desmarcar Mensaje", + "Unpin Message": "Desanclar mensaje", "Online": "En línea", "Submit debug logs": "Enviar registros de depuración", "The platform you're on": "La plataforma en la que te encuentras", - "The version of %(brand)s": "La version de %(brand)s", - "Your language of choice": "El idioma de tu elección", + "The version of %(brand)s": "La versión de %(brand)s", + "Your language of choice": "Idioma elegido", "Your homeserver's URL": "La URL de tu servidor base", "The information being sent to us to help make %(brand)s better includes:": "La información que se nos envía para ayudarnos a mejorar %(brand)s incluye:", "Whether or not you're using the Richtext mode of the Rich Text Editor": "Estés utilizando o no el modo de Texto Enriquecido del Editor de Texto Enriquecido", "Who would you like to add to this community?": "¿A quién te gustaría añadir a esta comunidad?", "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Advertencia: cualquier persona que añadas a una comunidad será públicamente visible a cualquiera que conozca la ID de la comunidad", "Invite new community members": "Invita nuevos miembros a la comunidad", - "Invite to Community": "Invitar a la Comunidad", + "Invite to Community": "Invitar a la comunidad", "Which rooms would you like to add to this community?": "¿Qué salas te gustaría añadir a esta comunidad?", "Fetching third party location failed": "Falló la obtención de la ubicación de un tercero", "I understand the risks and wish to continue": "Entiendo los riesgos y deseo continuar", @@ -487,7 +487,7 @@ "Event Type": "Tipo de Evento", "No rooms to show": "No hay salas para mostrar", "Download this file": "Descargar este archivo", - "Pin Message": "Fijar Mensaje", + "Pin Message": "Anclar mensaje", "Failed to change settings": "Error al cambiar los ajustes", "View Community": "Ver la comunidad", "Developer Tools": "Herramientas de desarrollo", @@ -500,13 +500,13 @@ "Every page you use in the app": "Cada página que utilizas en la aplicación", "Your device resolution": "La resolución de tu dispositivo", "Which officially provided instance you are using, if any": "Qué instancia proporcionada oficialmente estás utilizando, si estás utilizando alguna", - "e.g. %(exampleValue)s": "ej. %(exampleValue)s", - "e.g. ": "ej. ", + "e.g. %(exampleValue)s": "ej.: %(exampleValue)s", + "e.g. ": "ej.: ", "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Donde esta página incluya información identificable, como una sala, usuario o ID de grupo, esos datos se eliminan antes de enviarse al servidor.", - "Call in Progress": "Llamada en Curso", + "Call in Progress": "Llamada en curso", "A call is currently being placed!": "¡Se está realizando una llamada en este momento!", "A call is already in progress!": "¡Ya hay una llamada en curso!", - "Permission Required": "Permiso Requerido", + "Permission Required": "Se necesita permiso", "You do not have permission to start a conference call in this room": "No tienes permiso para iniciar una llamada de conferencia en esta sala", "%(weekDayName)s %(time)s": "%(weekDayName)s a las %(time)s", "%(weekDayName)s, %(monthName)s %(day)s %(time)s": "%(weekDayName)s %(day)s de %(monthName)s a las %(time)s", @@ -529,13 +529,13 @@ "You are no longer ignoring %(userId)s": "Ya no ignoras a %(userId)s", "Opens the Developer Tools dialog": "Abre el diálogo de Herramientas de Desarrollador", "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s cambió su nombre público a %(displayName)s.", - "%(senderName)s changed the pinned messages for the room.": "%(senderName)s cambió los mensajes con chincheta en la sala.", + "%(senderName)s changed the pinned messages for the room.": "%(senderName)s cambió los mensajes anclados de la sala.", "%(widgetName)s widget modified by %(senderName)s": "el widget %(widgetName)s fue modificado por %(senderName)s", "%(widgetName)s widget added by %(senderName)s": "componente %(widgetName)s añadido por %(senderName)s", "%(widgetName)s widget removed by %(senderName)s": "componente %(widgetName)s eliminado por %(senderName)s", "Your browser does not support the required cryptography extensions": "Su navegador no soporta las extensiones de criptografía requeridas", "Not a valid %(brand)s keyfile": "No es un archivo de claves de %(brand)s válido", - "Message Pinning": "Mensajes con chincheta", + "Message Pinning": "Mensajes anclados", "Always show encryption icons": "Mostrar siempre iconos de cifrado", "Automatically replace plain text Emoji": "Reemplazar automáticamente texto por Emojis", "Mirror local video feed": "Clonar transmisión de video local", @@ -556,9 +556,9 @@ "Kick this user?": "¿Echar a este usuario?", "Unban this user?": "¿Quitarle el veto a este usuario?", "Ban this user?": "¿Vetar a este usuario?", - "Demote yourself?": "¿Degradarse a ud mismo?", - "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "No podrá deshacer este cambio ya que está degradándose a usted mismo, si es el usuario con menos privilegios de la sala le resultará imposible recuperarlos.", - "Demote": "Degradar", + "Demote yourself?": "¿Quitarte permisos a ti mismo?", + "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "No podrás deshacer este cambio ya que estás quitándote permisos a ti mismo, si eres el último usuario con privilegios de la sala te resultará imposible recuperarlos.", + "Demote": "Quitar permisos", "Unignore": "Dejar de ignorar", "Ignore": "Ignorar", "Jump to read receipt": "Saltar a recibo leído", @@ -567,10 +567,10 @@ "Share Link to User": "Compartir enlace al usuario", "Send an encrypted reply…": "Enviar una respuesta cifrada…", "Send an encrypted message…": "Enviar un mensaje cifrado…", - "Jump to message": "Ir a mensaje", - "No pinned messages.": "No hay mensajes con chincheta.", + "Jump to message": "Ir al mensaje", + "No pinned messages.": "No hay mensajes anclados.", "Loading...": "Cargando...", - "Pinned Messages": "Mensajes con chincheta", + "Pinned Messages": "Mensajes anclados", "%(duration)ss": "%(duration)ss", "%(duration)sm": "%(duration)sm", "%(duration)sh": "%(duration)sh", @@ -590,18 +590,18 @@ "Community Invites": "Invitaciones a comunidades", "Banned by %(displayName)s": "Vetado por %(displayName)s", "Muted Users": "Usuarios silenciados", - "Members only (since the point in time of selecting this option)": "Solo miembros (desde el momento en que se selecciona esta opción)", - "Members only (since they were invited)": "Solo miembros (desde que fueron invitados)", - "Members only (since they joined)": "Solo miembros (desde que se unieron)", + "Members only (since the point in time of selecting this option)": "Solo participantes (desde el momento en que se selecciona esta opción)", + "Members only (since they were invited)": "Solo participantes (desde que fueron invitados)", + "Members only (since they joined)": "Solo participantes (desde que se unieron)", "You don't currently have any stickerpacks enabled": "Actualmente no tienes ningún paquete de pegatinas activado", "Stickerpack": "Paquete de pegatinas", "Hide Stickers": "Ocultar Pegatinas", - "Show Stickers": "Mostrar Pegatinas", + "Show Stickers": "Pegatinas", "Invalid community ID": "ID de comunidad inválida", "'%(groupId)s' is not a valid community ID": "'%(groupId)s' no es una ID de comunidad válida", "Flair": "Insignia", "Showing flair for these communities:": "Mostrar insignias de las siguientes comunidades:", - "This room is not showing flair for any communities": "Esta sala no está mostrando insignias para ninguna comunidad", + "This room is not showing flair for any communities": "Esta sala no está mostrando insignias de ninguna comunidad", "New community ID (e.g. +foo:%(localDomain)s)": "Nueva ID de comunidad (ej. +foo:%(localDomain)s)", "URL previews are enabled by default for participants in this room.": "La vista previa de URL se activa por defecto en los participantes de esta sala.", "URL previews are disabled by default for participants in this room.": "La vista previa se desactiva por defecto para los participantes de esta sala.", @@ -617,7 +617,7 @@ "Copied!": "¡Copiado!", "Failed to copy": "Falló la copia", "Add an Integration": "Añadir una Integración", - "You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "Está a punto de ir a un sitio de terceros de modo que pueda autenticar su cuenta para usarla con %(integrationsUrl)s. ¿Desea continuar?", + "You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "Estás a punto de ir a un sitio de terceros de modo que pueda autenticar su cuenta para usarla con %(integrationsUrl)s. ¿Quieres continuar?", "An email has been sent to %(emailAddress)s": "Se envió un correo electrónico a %(emailAddress)s", "Please check your email to continue registration.": "Por favor consulta tu correo electrónico para continuar con el registro.", "Token incorrect": "Token incorrecto", @@ -648,7 +648,7 @@ "You're not currently a member of any communities.": "Actualmente no formas parte de ninguna comunidad.", "Unknown Address": "Dirección desconocida", "Delete Widget": "Eliminar Componente", - "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Al borrar un widget se elimina para todos usuarios de la sala. ¿Está seguro?", + "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Al borrar un widget se elimina para todos usuarios de la sala. ¿Estás seguro?", "Failed to remove widget": "Falló la eliminación del widget", "An error ocurred whilst trying to remove the widget from the room": "Ocurrió un error mientras se intentaba eliminar el widget de la sala", "Minimize apps": "Minimizar apps", @@ -717,8 +717,8 @@ "email address": "dirección de correo electrónico", "You have entered an invalid address.": "No ha introducido una dirección correcta.", "Try using one of the following valid address types: %(validTypesList)s.": "Intente usar uno de los tipos de direcciones válidos: %(validTypesList)s.", - "Confirm Removal": "Confirmar Eliminación", - "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "¿Seguro que quieres eliminar (borrar) este evento? Ten en cuenta que si borras un cambio de nombre o tema de sala, podrías deshacer el cambio.", + "Confirm Removal": "Confirmar eliminación", + "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "¿Seguro que quieres eliminar este evento? Ten en cuenta que, si borras un cambio de nombre o tema de sala, podrías deshacer el cambio.", "Community IDs cannot be empty.": "Las IDs de comunidad no pueden estar vacías.", "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "Las IDs de comunidad sólo pueden contener caracteres a-z, 0-9, ó '=_-./'", "Something went wrong whilst creating your community": "Algo fue mal mientras se creaba la comunidad", @@ -728,8 +728,8 @@ "Community ID": "ID de Comunidad", "example": "ejemplo", "Create": "Crear", - "This will make your account permanently unusable. You will not be able to log in, and no one will be able to re-register the same user ID. This will cause your account to leave all rooms it is participating in, and it will remove your account details from your identity server. This action is irreversible.": "Esto hará que tu cuenta quede permanentemente inutilizable. No podrás iniciar sesión, y nadie podrá volver a registrar la misma ID de usuario. Esto hará que tu cuenta salga de todas las salas en las cuales participa, y eliminará los datos de tu cuenta de tu servidor de identidad. Esta acción es irreversible.", - "Deactivating your account does not by default cause us to forget messages you have sent. If you would like us to forget your messages, please tick the box below.": "Desactivar tu cuenta no hace que por defecto olvidemos los mensajes que has enviado. Si quieres que olvidemos tus mensajes, por favor marca la casilla a continuación.", + "This will make your account permanently unusable. You will not be able to log in, and no one will be able to re-register the same user ID. This will cause your account to leave all rooms it is participating in, and it will remove your account details from your identity server. This action is irreversible.": "Esto hará que tu cuenta quede permanentemente inutilizable. No podrás iniciar sesión, y nadie podrá volver a registrar la misma ID de usuario. Saldrás de todas salas en las que participas, y eliminará los datos de tu cuenta de tu servidor de identidad. Esta acción es irreversible.", + "Deactivating your account does not by default cause us to forget messages you have sent. If you would like us to forget your messages, please tick the box below.": "Desactivar tu cuenta no hace que por defecto olvidemos los mensajes que has enviado. Si quieres que olvidemos tus mensajes, marca la casilla a continuación, por favor.", "Message visibility in Matrix is similar to email. Our forgetting your messages means that messages you have sent will not be shared with any new or unregistered users, but registered users who already have access to these messages will still have access to their copy.": "La visibilidad de mensajes en Matrix es similar a la del correo electrónico. Que olvidemos tus mensajes implica que los mensajes que hayas enviado no se compartirán con ningún usuario nuevo o no registrado, pero aquellos usuarios registrados que ya tengan acceso a estos mensajes seguirán teniendo acceso a su copia.", "Please forget all messages I have sent when my account is deactivated (Warning: this will cause future users to see an incomplete view of conversations)": "Por favor, olvida todos los mensajes enviados al desactivar mi cuenta. (Advertencia: esto provocará que los usuarios futuros vean conversaciones incompletas)", "To continue, please enter your password:": "Para continuar, introduce tu contraseña, por favor:", @@ -784,7 +784,7 @@ "%(inviter)s has invited you to join this community": "%(inviter)s te invitó a unirte a esta comunidad", "Join this community": "Unirse a esta comunidad", "Leave this community": "Salir de esta comunidad", - "You are an administrator of this community": "Usted es un administrador de esta comunidad", + "You are an administrator of this community": "Eres administrador de esta comunidad", "You are a member of this community": "Usted es un miembro de esta comunidad", "Who can join this community?": "¿Quién puede unirse a esta comunidad?", "Everyone": "Todo el mundo", @@ -793,7 +793,7 @@ "Description": "Descripción", "Community %(groupId)s not found": "No se encontraron %(groupId)s de la comunidad", "Failed to load %(groupId)s": "Falló la carga de %(groupId)s", - "This room is not public. You will not be able to rejoin without an invite.": "Esta sala no es pública. No podrá volver a unirse sin una invitación.", + "This room is not public. You will not be able to rejoin without an invite.": "Esta sala no es pública. No podrás volver a unirte sin una invitación.", "Can't leave Server Notices room": "No se puede salir de la sala de avisos del servidor", "This room is used for important messages from the Homeserver, so you cannot leave it.": "La sala se usa para mensajes importantes del servidor base, así que no puedes abandonarla.", "Terms and Conditions": "Términos y condiciones", @@ -807,11 +807,11 @@ "Error whilst fetching joined communities": "Error al recuperar las comunidades a las que estás unido", "Create a new community": "Crear una comunidad nueva", "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Crear una comunidad para agrupar usuarios y salas. Construye una página de inicio personalizada para destacarla.", - "You can't send any messages until you review and agree to our terms and conditions.": "No puede enviar ningún mensaje hasta que revise y esté de acuerdo con nuestros términos y condiciones.", - "%(count)s of your messages have not been sent.|one": "No se envió su mensaje.", + "You can't send any messages until you review and agree to our terms and conditions.": "No puedes enviar ningún mensaje hasta que revises y estés de acuerdo con nuestros términos y condiciones.", + "%(count)s of your messages have not been sent.|one": "No se ha enviado tu mensaje.", "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "Reenviar todo o cancelar todo ahora. También puedes seleccionar mensajes individuales para reenviar o cancelar.", "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Reenviar mensaje o cancelar mensaje ahora.", - "Connectivity to the server has been lost.": "Se perdió la conexión con el servidor.", + "Connectivity to the server has been lost.": "Se ha perdido la conexión con el servidor.", "Sent messages will be stored until your connection has returned.": "Los mensajes enviados se almacenarán hasta que vuelva la conexión.", "Active call": "Llamada activa", "There's no one else here! Would you like to invite others or stop warning about the empty room?": "¡No hay nadie aquí! ¿Le gustaría invitar a otros o dejar de advertir sobre la sala vacía?", @@ -823,8 +823,8 @@ "Learn more about how we use analytics.": "Más información sobre el uso de los análisis de estadísticas.", "Check for update": "Comprobar actualizaciones", "Start automatically after system login": "Ejecutar automáticamente después de iniciar sesión en el sistema", - "No Audio Outputs detected": "No se detectaron Salidas de Sonido", - "Audio Output": "Salida de Sonido", + "No Audio Outputs detected": "No se han detectado salidas de sonido", + "Audio Output": "Salida de sonido", "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "Se envió un correo electrónico a %(emailAddress)s. Una vez hayas seguido el enlace que contiene, haz clic a continuación.", "Please note you are logging into the %(hs)s server, not matrix.org.": "Por favor, ten en cuenta que estás iniciando sesión en el servidor %(hs)s, y no en matrix.org.", "This homeserver doesn't offer any login flows which are supported by this client.": "Este servidor base no ofrece ningún flujo de inicio de sesión soportado por este cliente.", @@ -849,7 +849,7 @@ "Your message wasn't sent because this homeserver has hit its Monthly Active User Limit. Please contact your service administrator to continue using the service.": "Tu mensaje no se ha enviado porque este servidor base ha alcanzado su límite mensual de usuarios activos. Por favor, contacta con el administrador de tu servicio para continuar utilizándolo.", "Your message wasn't sent because this homeserver has exceeded a resource limit. Please contact your service administrator to continue using the service.": "Tu mensaje no se ha enviado porque este servidor base ha excedido un límite de recursos. Por favor contacta con el administrador de tu servicio para continuar utilizándolo.", "Please contact your service administrator to continue using this service.": "Por favor, contacta al administrador de tu servicio para continuar utilizando este servicio.", - "System Alerts": "Alertas de Sistema", + "System Alerts": "Alertas del sistema", "Forces the current outbound group session in an encrypted room to be discarded": "Obliga a que la sesión de salida grupal actual en una sala cifrada se descarte", "Sorry, your homeserver is too old to participate in this room.": "Lo sentimos, tu servidor base tiene una versión demasiado antigua como para participar en esta sala.", "Please contact your homeserver administrator.": "Por favor, contacta con la administración de tu servidor base.", @@ -880,7 +880,7 @@ "Email addresses": "Correos electrónicos", "Language and region": "Idioma y región", "The file '%(fileName)s' exceeds this homeserver's size limit for uploads": "El fichero %(fileName)s supera el tamaño límite del servidor para subidas", - "Unable to load! Check your network connectivity and try again.": "¡No es posible cargar! Comprueba tu conexión de red e inténtalo de nuevo.", + "Unable to load! Check your network connectivity and try again.": "No se ha podido cargar. Comprueba tu conexión de red e inténtalo de nuevo.", "Failed to invite users to the room:": "Fallo al invitar usuarios a la sala:", "Upgrades a room to a new version": "Actualiza una sala a una nueva versión", "%(senderDisplayName)s upgraded this room.": "%(senderDisplayName)s actualizó esta sala.", @@ -888,10 +888,10 @@ "%(senderDisplayName)s made the room invite only.": "%(senderDisplayName)s restringió la sala a invitados.", "%(senderDisplayName)s has allowed guests to join the room.": "%(senderDisplayName)s ha permitido a los invitados unirse a la sala.", "%(senderDisplayName)s has prevented guests from joining the room.": "%(senderDisplayName)s ha prohibido que los invitados se unan a la sala.", - "%(displayName)s is typing …": "%(displayName)s está escribiendo …", - "%(names)s and %(count)s others are typing …|other": "%(names)s y otros %(count)s están escribiendo …", - "%(names)s and %(count)s others are typing …|one": "%(names)s y otro están escribiendo …", - "%(names)s and %(lastPerson)s are typing …": "%(names)s y %(lastPerson)s están escribiendo …", + "%(displayName)s is typing …": "%(displayName)s está escribiendo…", + "%(names)s and %(count)s others are typing …|other": "%(names)s y otros %(count)s están escribiendo…", + "%(names)s and %(count)s others are typing …|one": "%(names)s y otra persona están escribiendo…", + "%(names)s and %(lastPerson)s are typing …": "%(names)s y %(lastPerson)s están escribiendo…", "Unrecognised address": "Dirección desconocida", "You do not have permission to invite people to this room.": "No tienes permisos para inviitar gente a esta sala.", "User %(user_id)s does not exist": "El usuario %(user_id)s no existe", @@ -1036,9 +1036,9 @@ "Open Devtools": "Abrir devtools", "General": "General", "Room Addresses": "Direcciones de sala", - "Set a new account password...": "Establecer una nueva contraseña para la cuenta...", + "Set a new account password...": "Elegir una nueva contraseña para la cuenta...", "Account management": "Gestión de la cuenta", - "Deactivating your account is a permanent action - be careful!": "Desactivar tu cuenta es permanente - ¡Cuidado!", + "Deactivating your account is a permanent action - be careful!": "Desactivar tu cuenta es permanente. ¡Cuidado!", "Credits": "Créditos", "For help with using %(brand)s, click here.": "Si necesitas ayuda usando %(brand)s, haz clic aquí.", "For help with using %(brand)s, click here or start a chat with our bot using the button below.": "Si necesitas ayuda usando %(brand)s, haz clic aquí o abre un chat con nuestro bot usando el botón de abajo.", @@ -1051,7 +1051,7 @@ "Room list": "Lista de salas", "Autocomplete delay (ms)": "Retardo autocompletado (ms)", "Roles & Permissions": "Roles y permisos", - "Changes to who can read history will only apply to future messages in this room. The visibility of existing history will be unchanged.": "Los cambios que se hagan sobre quien puede leer el historial se aplicarán solo a nuevos mensajes en esta sala. La visibilidad del historial actual no cambiará.", + "Changes to who can read history will only apply to future messages in this room. The visibility of existing history will be unchanged.": "Los cambios que se hagan sobre quién puede leer el historial se aplicarán solo a nuevos mensajes. La visibilidad del historial actual no cambiará.", "Security & Privacy": "Seguridad y privacidad", "Encryption": "Cifrado", "Once enabled, encryption cannot be disabled.": "Una vez activado, el cifrado no se puede desactivar.", @@ -1066,7 +1066,7 @@ "Securely back up your keys to avoid losing them. Learn more.": "Haz copia de manera segura de tus claves para evitar perderlas. Lee más.", "Not now": "Ahora no", "Don't ask me again": "No preguntarme más", - "Add some now": "Añadir algunos ahora", + "Add some now": "Añadir alguno ahora", "Main address": "Dirección principal", "Room avatar": "Avatar de la sala", "Room Name": "Nombre de sala", @@ -1082,7 +1082,7 @@ "To avoid losing your chat history, you must export your room keys before logging out. You will need to go back to the newer version of %(brand)s to do this": "Para evitar perder tu historial de chat, debes exportar las claves de la sala antes de salir. Debes volver a la versión actual de %(brand)s para esto", "Incompatible Database": "Base de datos incompatible", "Continue With Encryption Disabled": "Seguir con cifrado desactivado", - "Verify this user to mark them as trusted. Trusting users gives you extra peace of mind when using end-to-end encrypted messages.": "Verifica ese usuario para marcar como confiable. Confiar en usuarios aporta mucha tranquilidad en los mensajes cifrados de extremo a extremo.", + "Verify this user to mark them as trusted. Trusting users gives you extra peace of mind when using end-to-end encrypted messages.": "Verifica a este usuario para marcarlo como de confianza. Confiar en usuarios aporta tranquilidad en los mensajes cifrados de extremo a extremo.", "Waiting for partner to confirm...": "Esperando que confirme el compañero...", "Incoming Verification Request": "Petición de verificación entrante", "%(senderDisplayName)s changed the join rule to %(rule)s": "%(senderDisplayName)s cambió la regla para unirse a %(rule)s", @@ -1092,12 +1092,12 @@ "Verify this user by confirming the following emoji appear on their screen.": "Verifica este usuario confirmando que los siguientes emojis aparecen en su pantalla.", "Your %(brand)s is misconfigured": "Tu %(brand)s tiene un error de configuración", "Whether or not you're logged in (we don't record your username)": "Hayas o no iniciado sesión (no guardamos tu nombre de usuario)", - "Whether or not you're using the 'breadcrumbs' feature (avatars above the room list)": "Uses o no los 'breadcrumbs' (iconos sobre la lista de salas)", + "Whether or not you're using the 'breadcrumbs' feature (avatars above the room list)": "Uses o no las «migas de pan» (iconos sobre la lista de salas)", "Replying With Files": "Respondiendo con archivos", "At this time it is not possible to reply with a file. Would you like to upload this file without replying?": "En este momento no es posible responder con un archivo. ¿Te gustaría subir el archivo sin responder?", - "The file '%(fileName)s' failed to upload.": "Falló en subir el archivo '%(fileName)s'.", + "The file '%(fileName)s' failed to upload.": "La subida del archivo '%(fileName)s' ha fallado.", "The server does not support the room version specified.": "El servidor no soporta la versión de sala especificada.", - "Name or Matrix ID": "Nombre o Matrix ID", + "Name or Matrix ID": "Nombre o ID de Matrix", "Prepends ¯\\_(ツ)_/¯ to a plain-text message": "Añade ¯\\_(ツ)_/¯ al principio de un mensaje de texto plano", "Warning: Upgrading a room will not automatically migrate room members to the new version of the room. We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.": "Aviso: Actualizar una sala no migrará automáticamente a sus miembros a la nueva versión de la sala. Incluiremos un enlace a la nueva sala en la versión antigüa de la misma - los miembros tendrán que seguir ese enlace para unirse a la nueva sala.", "Changes your display nickname in the current room only": "Cambia tu apodo sólo en la sala actual", @@ -1129,16 +1129,16 @@ "Low bandwidth mode": "Modo de ancho de banda bajo", "Got It": "Entendido", "Scissors": "Tijeras", - "Call failed due to misconfigured server": "Llamada fallida debido a la mala configuración del servidor", + "Call failed due to misconfigured server": "La llamada ha fallado debido a una mala configuración del servidor", "Please ask the administrator of your homeserver (%(homeserverDomain)s) to configure a TURN server in order for calls to work reliably.": "Por favor, pídele al administrador de tu servidor base (%(homeserverDomain)s) que configure un servidor TURN para que las llamadas funcionen correctamente.", "Alternatively, you can try to use the public server at turn.matrix.org, but this will not be as reliable, and it will share your IP address with that server. You can also manage this in Settings.": "Como alternativa, puedes intentar usar el servidor público turn.matrix.org, pero éste no será igual de confiable, y compartirá tu dirección IP con ese servidor. También puedes configurar esto en ajustes.", - "Try using turn.matrix.org": "Trata de usar turn.matrix.org", + "Try using turn.matrix.org": "Probar usando turn.matrix.org", "Messages": "Mensajes", "Actions": "Acciones", "Other": "Otros", "Sends a message as plain text, without interpreting it as markdown": "Envía un mensaje como texto estándar, sin interpretarlo como Markdown", "You do not have the required permissions to use this command.": "No tienes los permisos requeridos para usar este comando.", - "Changes the avatar of the current room": "Cambia el ávatar de la sala actual", + "Changes the avatar of the current room": "Cambia la imagen de la sala actual", "Use an identity server": "Usar un servidor de identidad", "Use an identity server to invite by email. Click continue to use the default identity server (%(defaultIdentityServerName)s) or manage in Settings.": "Usar un servidor de identidad para invitar por correo. Presiona continuar par usar el servidor de identidad por defecto (%(defaultIdentityServerName)s) o adminístralo en Ajustes.", "Use an identity server to invite by email. Manage in Settings.": "Usar un servidor de identidad para invitar por correo. Gestiónalo en ajustes.", @@ -1166,10 +1166,10 @@ "Show previews/thumbnails for images": "Mostrar vistas previas para las imágenes", "When rooms are upgraded": "Cuando las salas son actualizadas", "My Ban List": "Mi lista de baneos", - "This is your list of users/servers you have blocked - don't leave the room!": "Esta es la lista de usuarios y servidores que ha bloqueado - ¡No deje la sala!", + "This is your list of users/servers you have blocked - don't leave the room!": "Esta es la lista de usuarios y/o servidores que has bloqueado. ¡No te salgas de la sala!", "Decline (%(counter)s)": "Declinar (%(counter)s)", "Accept to continue:": "Aceptar para continuar:", - "ID": "Identificación", + "ID": "ID", "Public Name": "Nombre público", "Connecting to integration manager...": "Conectando al gestor de integraciones...", "Cannot connect to integration manager": "No se puede conectar al gestor de integraciones", @@ -1201,10 +1201,10 @@ "%(senderName)s updated the rule banning users matching %(glob)s for %(reason)s": "%(senderName)s actualizó una regla que bloquea a usuarios que coinciden con %(glob)s por %(reason)s", "They match": "Coinciden", "They don't match": "No coinciden", - "To be secure, do this in person or use a trusted way to communicate.": "Para ser seguro, haz esto en persona o usando una forma de comunicación de confianza.", + "To be secure, do this in person or use a trusted way to communicate.": "Para mayor seguridad, haz esto en persona o usando una forma de comunicación de confianza.", "Lock": "Bloquear", "Verify yourself & others to keep your chats safe": "Verifícate y verifica a otros para mantener tus conversaciones seguras", - "Other users may not trust it": "Puede que otros usuarios no confíen en ello", + "Other users may not trust it": "Puede que otros usuarios no confíen en ella", "Upgrade": "Actualizar", "Verify": "Verificar", "Later": "Más tarde", @@ -1216,11 +1216,11 @@ "Changing password will currently reset any end-to-end encryption keys on all sessions, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Cambiar la contraseña reiniciará cualquier clave de cifrado end-to-end en todas las sesiones, haciendo el historial de conversaciones encriptado ilegible, a no ser que primero exportes tus claves de sala y después las reimportes. En un futuro esto será mejorado.", "in memory": "en memoria", "not found": "no encontrado", - "Identity Server (%(server)s)": "Servidor de Identidad %(server)s", + "Identity Server (%(server)s)": "Servidor de identidad %(server)s", "You are currently using to discover and be discoverable by existing contacts you know. You can change your identity server below.": "Estás usando actualmente para descubrir y ser descubierto por contactos existentes que conoces. Puedes cambiar tu servidor de identidad más abajo.", "If you don't want to use to discover and be discoverable by existing contacts you know, enter another identity server below.": "Si no quieres usar para descubrir y ser descubierto por contactos existentes que conoces, introduce otro servidor de identidad más abajo.", "Identity Server": "Servidor de Identidad", - "You are not currently using an identity server. To discover and be discoverable by existing contacts you know, add one below.": "No estás usando actualmente un servidor de identidad. Para descubrir y ser descubierto por contactos existentes que conoces, introduce uno más abajo.", + "You are not currently using an identity server. To discover and be discoverable by existing contacts you know, add one below.": "No estás usando un servidor de identidad ahora mismo. Para descubrir y ser descubierto por contactos existentes que conoces, introduce uno más abajo.", "Disconnecting from your identity server will mean you won't be discoverable by other users and you won't be able to invite others by email or phone.": "Desconectarte de tu servidor de identidad significa que no podrás ser descubierto por otros usuarios y no podrás invitar a otros por email o teléfono.", "Using an identity server is optional. If you choose not to use an identity server, you won't be discoverable by other users and you won't be able to invite others by email or phone.": "Usar un servidor de identidad es opcional. Si eliges no usar un servidor de identidad, no podrás ser descubierto por otros usuarios y no podrás invitar a otros por email o teléfono.", "Do not use an identity server": "No usar un servidor de identidad", @@ -1234,7 +1234,7 @@ "The following users might not exist or are invalid, and cannot be invited: %(csvNames)s": "Puede que los siguientes usuarios no existan o sean inválidos, y no pueden ser invitados: %(csvNames)s", "Recent Conversations": "Conversaciones recientes", "Suggestions": "Sugerencias", - "Recently Direct Messaged": "Enviado Mensaje Directo recientemente", + "Recently Direct Messaged": "Mensajes directos recientes", "Go": "Ir", "You've previously used %(brand)s on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, %(brand)s needs to resync your account.": "Has usado %(brand)s anteriormente en %(host)s con carga diferida de usuarios activada. En esta versión la carga diferida está desactivada. Como el caché local no es compatible entre estas dos configuraciones, %(brand)s tiene que resincronizar tu cuenta.", "If the other version of %(brand)s is still open in another tab, please close it as using %(brand)s on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "Si la otra versión de %(brand)s esta todavía abierta en otra pestaña, por favor, ciérrala, ya que usar %(brand)s en el mismo host con la opción de carga diferida activada y desactivada simultáneamente causará problemas.", @@ -1394,7 +1394,7 @@ "Send messages": "Enviar mensajes", "Invite users": "Invitar usuarios", "Change settings": "Cambiar la configuración", - "Kick users": "Expulsar usuarios", + "Kick users": "Echar usuarios", "Ban users": "Bloquear a usuarios", "Remove messages": "Eliminar mensajes", "Notify everyone": "Notificar a todos", @@ -1422,17 +1422,17 @@ "Disconnect from the identity server ?": "¿Desconectarse del servidor de identidad ?", "Disconnect": "Desconectarse", "You should:": "Deberías:", - "Use Single Sign On to continue": "Procede con Registro Único para continuar", - "Confirm adding this email address by using Single Sign On to prove your identity.": "Confirma la adición de esta dirección de correo electrónico usando el Registro Único para probar tu identidad.", - "Single Sign On": "Registro Único", - "Confirm adding email": "Confirmar la adición del correo electrónico", - "Click the button below to confirm adding this email address.": "Haz clic en el botón de abajo para confirmar la adición de esta dirección de correo electrónico.", + "Use Single Sign On to continue": "Continuar con SSO", + "Confirm adding this email address by using Single Sign On to prove your identity.": "Confirma la nueva dirección de correo usando SSO para probar tu identidad.", + "Single Sign On": "Single Sign On", + "Confirm adding email": "Confirmar un nuevo correo electrónico", + "Click the button below to confirm adding this email address.": "Haz clic en el botón de abajo para confirmar esta nueva dirección de correo electrónico.", "Confirm": "Confirmar", - "Confirm adding this phone number by using Single Sign On to prove your identity.": "Confirme la adición de este número de teléfono usando el Registro Único para probar su identidad...", - "Confirm adding phone number": "Confirmar la adición del número de teléfono", - "Click the button below to confirm adding this phone number.": "Haga clic en el botón de abajo para confirmar la adición de este número de teléfono.", + "Confirm adding this phone number by using Single Sign On to prove your identity.": "Confirma el nuevo número de teléfono usando SSO para probar tu identidad.", + "Confirm adding phone number": "Confirmar nuevo número de teléfono", + "Click the button below to confirm adding this phone number.": "Haz clic en el botón de abajo para confirmar este nuevo número de teléfono.", "Whether you're using %(brand)s on a device where touch is the primary input mechanism": "Si estés usando %(brand)s en un dispositivo donde una pantalla táctil es el principal mecanismo de entrada", - "Whether you're using %(brand)s as an installed Progressive Web App": "Si estás usando %(brand)s como una Aplicación Web Progresiva instalada", + "Whether you're using %(brand)s as an installed Progressive Web App": "Si estás usando %(brand)s como una aplicación web progresiva (PWA) instalada", "If you cancel now, you won't complete your operation.": "Si cancela ahora, no completará la operación.", "Review where you’re logged in": "Revise dónde hizo su registro", "New login. Was this you?": "Nuevo inicio de sesión. ¿Has sido tú?", @@ -1442,7 +1442,7 @@ "Create Account": "Crear cuenta", "Sign In": "Iniciar sesión", "Sends a message as html, without interpreting it as markdown": "Envía un mensaje como html, sin interpretarlo en markdown", - "Failed to set topic": "No se ha podido establecer el tema", + "Failed to set topic": "No se ha podido cambiar el tema", "Command failed": "El comando falló", "Could not find user in room": "No se ha encontrado el usuario en la sala", "Please supply a widget URL or embed code": "Por favor, proporcione una URL del widget o un código de incrustación", @@ -1457,9 +1457,9 @@ "%(senderName)s changed the main and alternative addresses for this room.": "%(senderName)s cambió la dirección principal y las alternativas de esta sala.", "%(senderName)s changed the addresses for this room.": "%(senderName)s cambió las direcciones de esta sala.", "You signed in to a new session without verifying it:": "Iniciaste una nueva sesión sin verificarla:", - "Verify your other session using one of the options below.": "Verifique su otra sesión utilizando una de las siguientes opciones.", + "Verify your other session using one of the options below.": "Verificar la otra sesión utilizando una de las siguientes opciones.", "%(name)s (%(userId)s) signed in to a new session without verifying it:": "%(name)s (%(userId)s) inició una nueva sesión sin verificarla:", - "Ask this user to verify their session, or manually verify it below.": "Pídale a este usuario que verifique su sesión, o verifíquela manualmente a continuación.", + "Ask this user to verify their session, or manually verify it below.": "Pídele al usuario que verifique su sesión, o verifícala manualmente a continuación.", "Not Trusted": "No es de confianza", "Manually Verify by Text": "Verificar manualmente mediante texto", "Interactively verify by Emoji": "Verifica interactivamente con unEmoji", @@ -1473,7 +1473,7 @@ "Send read receipts for messages (requires compatible homeserver to disable)": "Enviar recibos de lectura de mensajes (requiere un servidor local compatible para desactivarlo)", "Manually verify all remote sessions": "Verificar manualmente todas las sesiones remotas", "Confirm the emoji below are displayed on both sessions, in the same order:": "Confirma que los emoji de abajo se muestran en el mismo orden en ambas sesiones:", - "Verify this session by confirming the following number appears on its screen.": "Verifique esta sesión confirmando que el siguiente número aparece en su pantalla.", + "Verify this session by confirming the following number appears on its screen.": "Verifica esta sesión confirmando que el siguiente número aparece en su pantalla.", "Waiting for your other session, %(deviceName)s (%(deviceId)s), to verify…": "Esperando a que su otra sesión, %(deviceName)s (%(deviceId)s), verifica…", "Cancelling…": "Anulando…", "Verify all your sessions to ensure your account & messages are safe": "Verifica todas tus sesiones abiertas para asegurarte de que tu cuenta y tus mensajes estén seguros", @@ -1503,8 +1503,8 @@ "Confirm deleting these sessions by using Single Sign On to prove your identity.|other": "Confirme eliminar estas sesiones, probando su identidad con el Registro Único.", "Confirm deleting these sessions by using Single Sign On to prove your identity.|one": "Confirme eliminar esta sesión, probando su identidad con el Registro Único.", "Confirm deleting these sessions": "Confirmar la eliminación de estas sesiones", - "Click the button below to confirm deleting these sessions.|other": "Haga clic en el botón de abajo para confirmar la eliminación de estas sesiones.", - "Click the button below to confirm deleting these sessions.|one": "Haga clic en el botón de abajo para confirmar la eliminación de esta sesión.", + "Click the button below to confirm deleting these sessions.|other": "Haz clic en el botón de abajo para confirmar la eliminación de estas sesiones.", + "Click the button below to confirm deleting these sessions.|one": "Haz clic en el botón de abajo para confirmar la eliminación de esta sesión.", "Delete sessions|other": "Eliminar sesiones", "Delete sessions|one": "Eliminar sesión", "Individually verify each session used by a user to mark it as trusted, not trusting cross-signed devices.": "Verificar individualmente cada sesión utilizada por un usuario para marcarla como de confianza, no confiando en dispositivos de firma cruzada.", @@ -1525,7 +1525,7 @@ "Backup has a valid signature from unverified session ": "La copia de seguridad tiene una firma de válida de sesión no verificada ", "Backup has an invalid signature from verified session ": "La copia de seguridad tiene una firma de no válida de sesión verificada ", "Backup has an invalid signature from unverified session ": "La copia de seguridad tiene una firma de no válida de sesión no verificada ", - "Upgrade to your own domain": "Contratar el uso de un dominio personalizado", + "Upgrade to your own domain": "Contratar dominio personalizado", "Identity Server URL must be HTTPS": "La URL del servidor de identidad debe ser tipo HTTPS", "Not a valid Identity Server (status code %(code)s)": "No es un servidor de identidad válido (código de estado %(code)s)", "Could not connect to Identity Server": "No se ha podido conectar al servidor de identidad", @@ -1546,7 +1546,7 @@ "Add theme": "Añadir tema", "To report a Matrix-related security issue, please read the Matrix.org Security Disclosure Policy.": "Para informar de un problema de seguridad relacionado con Matrix, por favor lea Security Disclosure Policy de Matrix.or.", "Keyboard Shortcuts": "Atajos de teclado", - "Customise your experience with experimental labs features. Learn more.": "Personaliza tu experiencia con las funciones de los laboratorios experimentales. Learn more.", + "Customise your experience with experimental labs features. Learn more.": "Personaliza tu experiencia con funciones experimentales. Más información.", "Something went wrong. Please try again or view your console for hints.": "Algo salió mal. Por favor, inténtalo de nuevo o mira tu consola para encontrar pistas.", "Please try again or view your console for hints.": "Por favor, inténtalo de nuevo o mira tu consola para encontrar pistas.", "Ban list rules - %(roomName)s": "Reglas de la lista negra - %(roomName)s", @@ -1568,7 +1568,7 @@ "Accept all %(invitedRooms)s invites": "Aceptar todas las invitaciones de %(invitedRooms)s", "Cross-signing": "Firma cruzada", "Where you’re logged in": "Sesiones", - "Manage the names of and sign out of your sessions below or verify them in your User Profile.": "Administre los nombres de sus sesiones y salga de las sesiones abajo o verifíquelos en su Perfil de Usuario.", + "Manage the names of and sign out of your sessions below or verify them in your User Profile.": "Gestiona los nombres de sus sesiones y ciérralas abajo o verifícalas en tu perfil de usuario.", "A session's public name is visible to people you communicate with": "El nombre público de una sesión es visible para las personas con las que te comunicas", "This room is bridging messages to the following platforms. Learn more.": "Esta sala está haciendo puente con las siguientes plataformas. Aprende más.", "This room isn’t bridging messages to any platforms. Learn more.": "Esta sala no está haciendo puente con ninguna plataforma. Aprende más", @@ -1577,7 +1577,7 @@ "Reset": "Resetear", "Unable to revoke sharing for email address": "No se logró revocar el compartir para la dirección de correo electrónico", "Unable to share email address": "No se logró compartir la dirección de correo electrónico", - "Click the link in the email you received to verify and then click continue again.": "Haga clic en el enlace del correo electrónico que recibió para verificar y luego nuevamente haga clic en continuar.", + "Click the link in the email you received to verify and then click continue again.": "Haz clic en el enlace del correo electrónico para verificar, y luego nuevamente haz clic en continuar.", "Revoke": "Revocar", "Discovery options will appear once you have added an email above.": "Las opciones de descubrimiento aparecerán una vez que haya añadido un correo electrónico arriba.", "Unable to revoke sharing for phone number": "No se logró revocar el intercambio de un número de teléfono", @@ -1645,14 +1645,14 @@ "Create a public room": "Crear una sala pública", "Create a private room": "Crear una sala privada", "Topic (optional)": "Tema (opcional)", - "Make this room public": "Convierte esta sala en pública", + "Make this room public": "Haz la sala pública", "Hide advanced": "Ocultar ajustes avanzados", "Show advanced": "Mostrar ajustes avanzados", "Block users on other matrix homeservers from joining this room (This setting cannot be changed later!)": "Evitar que usuarios de otros servidores Matrix se unan a esta sala (¡Este ajuste no puede ser cambiada más tarde!)", "Server did not require any authentication": "El servidor no requirió ninguna autenticación", "Server did not return valid authentication information.": "El servidor no devolvió información de autenticación válida.", "Confirm your account deactivation by using Single Sign On to prove your identity.": "Confirme la desactivación de su cuenta, usando Registro Único para probar su identidad.", - "Are you sure you want to deactivate your account? This is irreversible.": "¿Está seguro de que quiere desactivar su cuenta? Es irreversible.", + "Are you sure you want to deactivate your account? This is irreversible.": "¿Estás seguro de que quieres desactivar su cuenta? No se puede deshacer.", "Confirm account deactivation": "Confirmar la desactivación de la cuenta", "There was a problem communicating with the server. Please try again.": "Hubo un problema de comunicación con el servidor. Por favor, inténtelo de nuevo.", "Verify session": "Verificar sesión", @@ -1660,8 +1660,8 @@ "Session key": "Código de sesión", "View Servers in Room": "Ver servidores en la sala", "Verification Requests": "Solicitudes de verificación", - "Verifying this user will mark their session as trusted, and also mark your session as trusted to them.": "Verificar que este usuario marcará su sesión como de confianza, y también que marcará su sesión como de confianza para él.", - "Verify this device to mark it as trusted. Trusting this device gives you and other users extra peace of mind when using end-to-end encrypted messages.": "Verifique este dispositivo para marcarlo como confiable. Confiar en este dispositivo le da a usted y a otros usuarios tranquilidad adicional cuando utilizan mensajes cifrados de extremo a extremo.", + "Verifying this user will mark their session as trusted, and also mark your session as trusted to them.": "Verificar este usuario marcará su sesión como de confianza, y también marcará tu sesión como de confianza para él.", + "Verify this device to mark it as trusted. Trusting this device gives you and other users extra peace of mind when using end-to-end encrypted messages.": "Verifica este dispositivo para marcarlo como confiable. Confiar en este dispositivo te da a ti y a otros usuarios tranquilidad adicional cuando utilizáis mensajes cifrados de extremo a extremo.", "Verifying this device will mark it as trusted, and users who have verified with you will trust this device.": "La verificación de este dispositivo lo marcará como de confianza. Los usuarios que te han verificado confiarán en este dispositivo.", "Integrations are disabled": "Las integraciones están desactivadas", "Enable 'Manage Integrations' in Settings to do this.": "Activa «Gestionar integraciones» en ajustes para hacer esto.", @@ -1678,23 +1678,23 @@ "%(brand)s encountered an error during upload of:": "%(brand)s encontró un error durante la carga de:", "End": "Fin", "Once enabled, encryption for a room cannot be disabled. Messages sent in an encrypted room cannot be seen by the server, only by the participants of the room. Enabling encryption may prevent many bots and bridges from working correctly. Learn more about encryption.": "Una vez activado, el cifrado de una sala no puede desactivarse. Los mensajes enviados a una sala cifrada no pueden ser vistos por el servidor, solo lo verán los participantes de la sala. Activar el cifrado puede hacer que muchos bots y bridges no funcionen correctamente. Más información sobre el cifrado", - "Joining room …": "Uniéndose a sala …", - "Loading …": "Cargando …", - "Rejecting invite …": "Rechazando invitación …", + "Joining room …": "Uniéndote a sala…", + "Loading …": "Cargando…", + "Rejecting invite …": "Rechazando invitación…", "Join the conversation with an account": "Unirse a la conversación con una cuenta", "Sign Up": "Registrarse", - "You were kicked from %(roomName)s by %(memberName)s": "%(memberName)s te ha explusado de la sala %(roomName)s", + "You were kicked from %(roomName)s by %(memberName)s": "%(memberName)s te ha echado de la sala %(roomName)s", "Reason: %(reason)s": "Razón: %(reason)s", "Forget this room": "Olvidar esta sala", - "Re-join": "Re-entrar", - "You were banned from %(roomName)s by %(memberName)s": "%(memberName)s te ha expulsado de %(roomName)s", + "Re-join": "Volver a entrar", + "You were banned from %(roomName)s by %(memberName)s": "%(memberName)s te ha echado de %(roomName)s", "Something went wrong with your invite to %(roomName)s": "Algo salió a mal invitando a %(roomName)s", "You can only join it with a working invite.": "Sólo puedes unirte con una invitación que funciona.", "Try to join anyway": "Intentar unirse de todas formas", "You can still join it because this is a public room.": "Todavía puedes unirte, ya que es una sala pública.", "Join the discussion": "Unirse a la sala", "Do you want to chat with %(user)s?": "¿Quieres chatear con %(user)s?", - "Do you want to join %(roomName)s?": "¿Quieres unirte a la sala %(roomName)s?", + "Do you want to join %(roomName)s?": "¿Quieres unirte a %(roomName)s?", " invited you": " te ha invitado", "You're previewing %(roomName)s. Want to join it?": "Estás previsualizando %(roomName)s. ¿Quieres unirte?", "%(roomName)s can't be previewed. Do you want to join it?": "La sala %(roomName)s no permite previsualización. ¿Quieres unirte?", @@ -1712,25 +1712,25 @@ "No recent messages by %(user)s found": "No se han encontrado mensajes recientes de %(user)s", "Try scrolling up in the timeline to see if there are any earlier ones.": "Intente desplazarse hacia arriba en la línea de tiempo para ver si hay alguna anterior.", "Remove recent messages by %(user)s": "Eliminar mensajes recientes de %(user)s", - "You are about to remove %(count)s messages by %(user)s. This cannot be undone. Do you wish to continue?|other": "Estás a punto de eliminar %(count)s mensajes de %(user)s. Esto no se puede deshacer. ¿Desea continuar?", - "You are about to remove %(count)s messages by %(user)s. This cannot be undone. Do you wish to continue?|one": "Estás a punto de eliminar 1 mensaje de %(user)s. Esto no se puede deshacer. ¿Desea continuar?", - "For a large amount of messages, this might take some time. Please don't refresh your client in the meantime.": "Para una gran cantidad de mensajes, esto podría llevar algún tiempo. Por favor, no refresque a su cliente mientras tanto.", + "You are about to remove %(count)s messages by %(user)s. This cannot be undone. Do you wish to continue?|other": "Estás a punto de eliminar %(count)s mensajes de %(user)s. No se puede deshacer. ¿Quieres continuar?", + "You are about to remove %(count)s messages by %(user)s. This cannot be undone. Do you wish to continue?|one": "Estás a punto de eliminar 1 mensaje de %(user)s. No se puede deshacer. ¿Quieres continuar?", + "For a large amount of messages, this might take some time. Please don't refresh your client in the meantime.": "Para una gran cantidad de mensajes, esto podría llevar algún tiempo. Por favor, no recargues tu aplicación mientras tanto.", "Remove %(count)s messages|other": "Eliminar %(count)s mensajes", "Remove %(count)s messages|one": "Eliminar 1 mensaje", "Deactivate user?": "¿Desactivar usuario?", - "Deactivating this user will log them out and prevent them from logging back in. Additionally, they will leave all the rooms they are in. This action cannot be reversed. Are you sure you want to deactivate this user?": "Desactivando a este usuario, este será desconectado y no podrá volver a ingresar. Además, saldrá de todas las salas a que se había unido. Esta acción no puede ser revertida. ¿Está seguro de desactivar este usuario?", + "Deactivating this user will log them out and prevent them from logging back in. Additionally, they will leave all the rooms they are in. This action cannot be reversed. Are you sure you want to deactivate this user?": "Desactivar este usuario le cerrará la sesión y desconectará. No podrá volver a iniciar sesión. Además, saldrá de todas las salas a que se había unido. Esta acción no puede deshacerse. ¿Desactivar este usuario?", "Deactivate user": "Desactivar usuario", "Failed to deactivate user": "Error en desactivar usuario", "Remove recent messages": "Eliminar mensajes recientes", "Send a reply…": "Enviar una respuesta …", "Send a message…": "Enviar un mensaje…", "Bold": "Negrita", - "Italics": "Cursivo", + "Italics": "Cursiva", "Strikethrough": "Tachado", "Code block": "Bloque de código", "Room %(name)s": "Sala %(name)s", "Recent rooms": "Salas recientes", - "Direct Messages": "Mensaje Directo", + "Direct Messages": "Mensajes directos", "Loading room preview": "Cargando vista previa de la sala", "An error (%(errcode)s) was returned while trying to validate your invite. You could try to pass this information on to a room admin.": "Un código de error (%(errcode)s) fue devuelto al tratar de validar su invitación. Podrías intentar pasar esta información a un administrador de la sala.", "This invite to %(roomName)s was sent to %(email)s which is not associated with your account": "Esta invitación a la sala %(roomName)s fue enviada a %(email)s que no está asociada a su cuenta", @@ -1739,7 +1739,7 @@ "Use an identity server in Settings to receive invites directly in %(brand)s.": "Utilice un servidor de identidad en Configuración para recibir invitaciones directamente en %(brand)s.", "Share this email in Settings to receive invites directly in %(brand)s.": "Comparte este correo electrónico en Configuración para recibir invitaciones directamente en %(brand)s.", " wants to chat": " quiere chatear", - "Start chatting": "Empieza a chatear", + "Start chatting": "Empieza una conversación", "Reject & Ignore user": "Rechazar e ignorar usuario", "Upgrading this room will shut down the current instance of the room and create an upgraded room with the same name.": "Actualizar esta sala cerrará la instancia actual de la sala y creará una sala actualizada con el mismo nombre.", "This room has already been upgraded.": "Esta sala ya ha sido actualizada.", @@ -1760,7 +1760,7 @@ "There was an error updating the room's alternative addresses. It may not be allowed by the server or a temporary failure occurred.": "Hubo un error al actualizar la dirección alternativa de la sala. Posiblemente el servidor no lo permita o se produjo un error temporal.", "Local address": "Dirección local", "Published Addresses": "Direcciones publicadas", - "Published addresses can be used by anyone on any server to join your room. To publish an address, it needs to be set as a local address first.": "Las direcciones publicadas pueden ser usadas por cualquier usuario en cualquier servidor para unirse a tu salas. Para publicar una dirección, primero hay que establecerla como una dirección local.", + "Published addresses can be used by anyone on any server to join your room. To publish an address, it needs to be set as a local address first.": "Las direcciones publicadas pueden ser usadas por cualquier usuario en cualquier servidor para unirse a tu salas. Para publicar una dirección, primero hay que establecerla como dirección local.", "Other published addresses:": "Otras direcciones publicadas:", "No other published addresses yet, add one below": "Todavía no hay direcciones publicadas, puedes añadir una más abajo", "New published address (e.g. #alias:server)": "Nueva dirección publicada (p.ej.. #alias:server)", @@ -1773,12 +1773,12 @@ "Accepting…": "Aceptando…", "Start Verification": "Iniciar verificación", "Messages in this room are end-to-end encrypted.": "Los mensajes de esta sala están cifrados de extremo a extremo.", - "Your messages are secured and only you and the recipient have the unique keys to unlock them.": "Sus mensajes son seguros y sólo usted y el destinatario tienen las claves únicas para desbloquearlos.", + "Your messages are secured and only you and the recipient have the unique keys to unlock them.": "Los mensajes son seguros y sólo tú y el destinatario tienen las claves únicas para desbloquearlos.", "Messages in this room are not end-to-end encrypted.": "Los mensajes en esta sala no están cifrados de extremo a extremo.", "In encrypted rooms, your messages are secured and only you and the recipient have the unique keys to unlock them.": "En las salas cifradas, tus mensajes están seguros y solo tú y el destinatario tienen las claves únicas para desbloquearlos.", "Verify User": "Verificar usuario", - "For extra security, verify this user by checking a one-time code on both of your devices.": "Para mayor seguridad, verifique este usuario comprobando un código temporal vez en ambos dispositivos.", - "Your messages are not secure": "Sus mensajes no son seguros", + "For extra security, verify this user by checking a one-time code on both of your devices.": "Para mayor seguridad, verifica a este usuario comprobando un código temporal vez dos de tus dispositivos.", + "Your messages are not secure": "Los mensajes no son seguros", "One of the following may be compromised:": "Uno de los siguientes puede estar comprometido:", "Your homeserver": "Tu servidor base", "The homeserver the user you’re verifying is connected to": "El servidor base del usuario a que está verificando está conectado a", @@ -1807,15 +1807,15 @@ "Verify all users in a room to ensure it's secure.": "Verifica a todos los usuarios de una sala para asegurar que es segura.", "In encrypted rooms, verify all users to ensure it’s secure.": "En las salas cifrar, verificar a todos los usuarios para asegurarse de son seguras.", "You've successfully verified %(deviceName)s (%(deviceId)s)!": "¡Has verificado con éxito los %(deviceName)s (%(deviceId)s)!", - "You've successfully verified %(displayName)s!": "¡Has verificado con éxito los %(displayName)s!", + "You've successfully verified %(displayName)s!": "¡Has verificado con éxito a %(displayName)s!", "Verified": "Verificado", - "Got it": "Lo he entendido", + "Got it": "Aceptar", "Start verification again from the notification.": "Inicie la verificación nuevamente a partir de la notificación.", "Start verification again from their profile.": "Empieza la verificación de nuevo desde su perfil.", "Verification timed out.": "El tiempo máximo para la verificación se ha agotado.", "You cancelled verification on your other session.": "Canceló la verificación de su otra sesión.", "%(displayName)s cancelled verification.": "%(displayName)s canceló la verificación.", - "You cancelled verification.": "Usted canceló la verificación.", + "You cancelled verification.": "Has cancelado la verificación.", "Verification cancelled": "Verificación cancelada", "Compare emoji": "Comparar emoji", "Encryption enabled": "Cifrado activado", @@ -1826,33 +1826,33 @@ "Message Actions": "Acciones de mensaje", "Show image": "Mostrar imagen", "You have ignored this user, so their message is hidden. Show anyways.": "Ha ignorado a este usuario, así que su mensaje se ha ocultado. Mostrar de todos modos.", - "You verified %(name)s": "Usted verificó %(name)s", - "You cancelled verifying %(name)s": "Usted canceló la verificación de %(name)s", + "You verified %(name)s": "Has verificado a %(name)s", + "You cancelled verifying %(name)s": "Has cancelado la verificación de %(name)s", "%(name)s cancelled verifying": "%(name)s canceló la verificación", - "You accepted": "Usted aceptó", + "You accepted": "Aceptaste", "%(name)s accepted": "%(name)s aceptó", - "You declined": "Usted declinó", - "You cancelled": "Usted canceló", + "You declined": "Declinaste", + "You cancelled": "Cancelaste", "%(name)s declined": "%(name)s declinó", "%(name)s cancelled": "%(name)s canceló", "Accepting …": "Aceptando…", "Declining …": "Declinando…", "%(name)s wants to verify": "%(name)s quiere verificar", - "You sent a verification request": "Usted envió una solicitud de verificación", + "You sent a verification request": "Has enviado solicitud de verificación", "Show all": "Mostrar todo", "Reactions": "Reacciones", " reacted with %(content)s": " reaccionó con %(content)s", "reacted with %(shortName)s": " reaccionó con %(shortName)s", "Message deleted": "Mensaje eliminado", "Message deleted by %(name)s": "Mensaje eliminado por %(name)s", - "Edited at %(date)s. Click to view edits.": "Editado el día %(date)s. Haga clic para ver las ediciones.", + "Edited at %(date)s. Click to view edits.": "Editado el día %(date)s. Haz clic para ver las ediciones.", "edited": "editado", "Can't load this message": "No puedo cargar este mensaje", "Submit logs": "Enviar registros", - "Frequently Used": "Usado con frecuencia", + "Frequently Used": "Frecuente", "Smileys & People": "Caritas y personas", "Animals & Nature": "Animales y naturaleza", - "Food & Drink": "Comidas y bebidas", + "Food & Drink": "Comida y bebida", "Activities": "Actividades", "Travel & Places": "Viajes y lugares", "Objects": "Objetos", @@ -1862,17 +1862,17 @@ "Cancel search": "Cancelar búsqueda", "Any of the following data may be shared:": "Cualquiera de los siguientes datos puede ser compartido:", "Your display name": "Su nombre mostrado", - "Your avatar URL": "La URL de su avatar", - "Your user ID": "Su identificación (ID) de usuario", + "Your avatar URL": "La URL de tu avatar", + "Your user ID": "Tu ID de usuario", "Your theme": "Su tema", "%(brand)s URL": "URL de %(brand)s", "Room ID": "Identidad (ID) de la sala", - "Widget ID": "Identificación (ID) de widget", - "Using this widget may share data with %(widgetDomain)s & your Integration Manager.": "Usar este widget puede resultar en compartir datos con %(widgetDomain)s y su Administrador de Integración.", - "Using this widget may share data with %(widgetDomain)s.": "Usar este widget puede resultar en compartir datos con %(widgetDomain)s.", + "Widget ID": "ID del widget", + "Using this widget may share data with %(widgetDomain)s & your Integration Manager.": "Usar este widget puede resultar en que se compartan datos con %(widgetDomain)s y su administrador de integración.", + "Using this widget may share data with %(widgetDomain)s.": "Usar este widget puede resultar en que se compartan datos con %(widgetDomain)s.", "Widgets do not use message encryption.": "Los widgets no utilizan el cifrado de mensajes.", "Widget added by": "Widget añadido por", - "This widget may use cookies.": "Este widget posiblemente utilice cookies.", + "This widget may use cookies.": "Puede que el widget use cookies.", "Maximize apps": "Maximizar apps", "More options": "Mas opciones", "Please create a new issue on GitHub so that we can investigate this bug.": "Por favor, crea un nuevo nodo en GitHub para que podamos investigar este error.", @@ -1883,7 +1883,7 @@ "Signature upload success": "Subida de firma exitosa", "Signature upload failed": "Subida de firma falló", "Confirm by comparing the following with the User Settings in your other session:": "Confirme comparando lo siguiente con los ajustes de usuario de su otra sesión:", - "Confirm this user's session by comparing the following with their User Settings:": "Confirme la sesión de este usuario comparando lo siguiente con la configuración de usuario de él/ella:", + "Confirm this user's session by comparing the following with their User Settings:": "Confirma la sesión de este usuario comparando lo siguiente con su configuración:", "If they don't match, the security of your communication may be compromised.": "Si no coinciden, la seguridad de su comunicación puede estar comprometida.", "Your homeserver doesn't seem to support this feature.": "Tu servidor base no parece soportar esta funcionalidad.", "Your account is not secure": "Su cuenta no es segura", @@ -1895,7 +1895,7 @@ "Reporting this message will send its unique 'event ID' to the administrator of your homeserver. If messages in this room are encrypted, your homeserver administrator will not be able to read the message text or view any files or images.": "Reportar este mensaje enviará su único 'event ID' al administrador de tu servidor base. Si los mensajes en esta sala están cifrados, el administrador de tu servidor no podrá leer el texto del mensaje ni ver ningún archivo o imagen.", "Command Help": "Ayuda del comando", "Integration Manager": "Administrador de integración", - "Verify other session": "Verifique otra sesión", + "Verify other session": "Verificar otra sesión", "Verification Request": "Solicitud de verificación", "A widget located at %(widgetUrl)s would like to verify your identity. By allowing this, the widget will be able to verify your user ID, but not perform actions as you.": "Un widget localizado en %(widgetUrl)s desea verificar su identidad. Permitiendo esto, el widget podrá verificar su identidad de usuario, pero no realizar acciones como usted.", "Enter recovery passphrase": "Introduzca la contraseña de recuperación", @@ -1927,11 +1927,11 @@ "Resend removal": "Reenviar la eliminación", "Share Permalink": "Compartir enlace", "Report Content": "Reportar contenido", - "Notification settings": "Configuración de notificaciones", + "Notification settings": "Notificaciones", "Clear status": "Borrar estado", "Update status": "Actualizar estado", - "Set status": "Establecer estado", - "Set a new status...": "Establecer un estado nuevo...", + "Set status": "Cambiar estado", + "Set a new status...": "Elegir un estado nuevo...", "Hide": "Ocultar", "Help": "Ayuda", "Reload": "Recargar", @@ -1987,11 +1987,11 @@ "Sign in with SSO": "Ingrese con SSO", "Please install Chrome, Firefox, or Safari for the best experience.": "Por favor, instale Chrome, Firefox, o Safari para la mejor experiencia.", "Couldn't load page": "No pude cargar la página", - "You are an administrator of this community. You will not be able to rejoin without an invite from another administrator.": "Usted es un administrador de esta comunidad. No podrás volver a unirte sin una invitación de otro administrador.", + "You are an administrator of this community. You will not be able to rejoin without an invite from another administrator.": "Eres un administrador de esta comunidad. No podrás volver a unirte sin una invitación de otro administrador.", "Want more than a community? Get your own server": "¿Quieres más que una comunidad? Obtenga su propio servidor", "This homeserver does not support communities": "Este servidor base no permite las comunidades", - "Welcome to %(appName)s": "Bienvenido a %(appName)s", - "Liberate your communication": "Libere su comunicación", + "Welcome to %(appName)s": "Te damos la bienvenida a %(appName)s", + "Liberate your communication": "Libera tu comunicación", "Send a Direct Message": "Envía un mensaje directo", "Explore Public Rooms": "Explorar salas públicas", "Create a Group Chat": "Crear un chat grupal", @@ -2005,7 +2005,7 @@ "The homeserver may be unavailable or overloaded.": "Es posible el servidor de base no esté disponible o esté sobrecargado.", "Preview": "Ver", "View": "Ver", - "Find a room…": "Encuentre una sala…", + "Find a room…": "Encuentrar una sala…", "Find a room… (e.g. %(exampleRoom)s)": "Encuentra una sala... (ej.: %(exampleRoom)s)", "If you can't find the room you're looking for, ask for an invite or Create a new room.": "Si no encuentras la sala que buscas, pide que te inviten a ella o crea una nueva.", "Explore rooms": "Explorar salas", @@ -2014,7 +2014,7 @@ "Guest": "Invitado", "Your profile": "Su perfil", "Could not load user profile": "No se pudo cargar el perfil de usuario", - "Verify this login": "Verifique este inicio de sesión", + "Verify this login": "Verificar este inicio de sesión", "Session verified": "Sesión verificada", "Changing your password will reset any end-to-end encryption keys on all of your sessions, making encrypted chat history unreadable. Set up Key Backup or export your room keys from another session before resetting your password.": "Cambiar la contraseña restablecerá cualquier clave de cifrado de extremo a extremo en todas sus sesiones, haciendo ilegible el historial de chat cifrado. Configura la copia de seguridad de las claves o exporta las claves de la sala de otra sesión antes de restablecer la contraseña.", "Your Matrix account on %(serverName)s": "Su cuenta de Matrix en %(serverName)s", @@ -2077,7 +2077,7 @@ "%(senderName)s changed the room name": "%(senderName)s cambio el nombre de la sala", "You invited %(targetName)s": "Has invitado a %(targetName)s", "Are you sure you want to cancel entering passphrase?": "¿Estas seguro que quieres cancelar el ingresar tu contraseña de recuperación?", - "Go Back": "No cancelar", + "Go Back": "Volver", "Joins room with given address": "Entrar a la sala con la dirección especificada", "Unrecognised room address:": "No se encuentra la dirección de la sala:", "Opens chat with the given user": "Abrir una conversación con el usuario especificado", @@ -2107,7 +2107,7 @@ "System font name": "Nombre de la fuente", "Enable experimental, compact IRC style layout": "Activar el diseño experimental de IRC compacto", "Uploading logs": "Subiendo registros", - "Downloading logs": "Descargando registro", + "Downloading logs": "Descargando registros", "Incoming voice call": "Llamada de voz entrante", "Incoming video call": "Videollamada entrante", "Incoming call": "Llamada entrante", @@ -2125,16 +2125,16 @@ "Modern": "Moderno", "Set the name of a font installed on your system & %(brand)s will attempt to use it.": "Introduce el nombre de la fuente instalada en tu sistema y %(brand)s intentará utilizarla.", "Customise your appearance": "Personaliza la apariencia", - "Appearance Settings only affect this %(brand)s session.": "Cambiar las opciones de apariencia solo afecta esta %(brand)s sesión.", + "Appearance Settings only affect this %(brand)s session.": "Cambiar las opciones de apariencia solo afecta a esta sesión de %(brand)s.", "Please verify the room ID or address and try again.": "Por favor, verifica la ID o dirección de esta sala e inténtalo de nuevo.", "Your server admin has disabled end-to-end encryption by default in private rooms & Direct Messages.": "El administrador del servidor base ha desactivado el cifrado de extremo a extremo en salas privadas y mensajes directos.", - "To link to this room, please add an address.": "Para vincular esta sala, por favor añade una dirección.", + "To link to this room, please add an address.": "Para obtener un enlace a esta sala, añade una dirección.", "The authenticity of this encrypted message can't be guaranteed on this device.": "La autenticidad de este mensaje cifrado no puede ser garantizada en este dispositivo.", "No recently visited rooms": "No hay salas visitadas recientemente", "People": "Gente", "Explore public rooms": "Buscar salas públicas", "Can't see what you’re looking for?": "¿No encuentras nada de lo que buscas?", - "Explore all public rooms": "Buscar todas las salas publicas", + "Explore all public rooms": "Explorar salas públicas", "%(count)s results|other": "%(count)s resultados", "Prepends ( ͡° ͜ʖ ͡°) to a plain-text message": "Antepone ( ͡° ͜ʖ ͡°) a un mensaje de texto", "Group call modified by %(senderName)s": "Llamada grupal modificada por %(senderName)s", @@ -2204,7 +2204,7 @@ "You can only pin 2 apps at a time": "Solo puedes anclar 2 aplicaciones a la vez", "Message deleted on %(date)s": "Mensaje eliminado el %(date)s", "Edited at %(date)s": "Editado el %(date)s", - "Click to view edits": "Haga clic para ver las ediciones", + "Click to view edits": "Haz clic para ver las ediciones", "Categories": "Categorías", "Information": "Información", "QR Code": "Código QR", @@ -2222,24 +2222,24 @@ "Invite people to join %(communityName)s": "Invita a personas a unirse %(communityName)s", "There was an error creating your community. The name may be taken or the server is unable to process your request.": "Ha ocurrido un error al crear la comunidad. El nombre puede que ya esté siendo usado o el servidor no puede procesar la solicitud.", "Community ID: +:%(domain)s": "ID de comunidad: +:%(domain)s", - "Use this when referencing your community to others. The community ID cannot be changed.": "Use esto cuando haga referencia a su comunidad con otras. La identificación de la comunidad no se puede cambiar.", + "Use this when referencing your community to others. The community ID cannot be changed.": "Usa esto cuando hagas referencia a tu comunidad con otras. El ID de la comunidad no se puede cambiar.", "You can change this later if needed.": "Puede cambiar esto más tarde si es necesario.", "What's the name of your community or team?": "¿Cuál es el nombre de tu comunidad o equipo?", - "Enter name": "Ingrese su nombre", + "Enter name": "Introduce un nombre", "Add image (optional)": "Agregar imagen (opcional)", "An image will help people identify your community.": "Una imagen ayudará a las personas a identificar su comunidad.", "Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone.": "Las salas privadas se pueden encontrar y unirse solo con invitación. Cualquier persona puede encontrar y unirse a las salas públicas.", "Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone in this community.": "Las salas privadas se pueden encontrar y unirse solo con invitación. Cualquier persona de esta comunidad puede encontrar salas públicas y unirse a ellas.", - "You might enable this if the room will only be used for collaborating with internal teams on your homeserver. This cannot be changed later.": "Puede activar esto si la sala solo se usará para colaborar con equipos internos en tu servidor base. Esto no se puede cambiar después.", + "You might enable this if the room will only be used for collaborating with internal teams on your homeserver. This cannot be changed later.": "Puedes activar esto si la sala solo se usará para colaborar con equipos internos en tu servidor base. No se puede cambiar después.", "You might disable this if the room will be used for collaborating with external teams who have their own homeserver. This cannot be changed later.": "Puedes desactivar esto si la sala se utilizará para colaborar con equipos externos que tengan su propio servidor base. Esto no se puede cambiar después.", "Create a room in %(communityName)s": "Crea una sala en %(communityName)s", - "Block anyone not part of %(serverName)s from ever joining this room.": "Bloquea a cualquier persona que no sea parte de %(serverName)s para que no se una a esta sala.", + "Block anyone not part of %(serverName)s from ever joining this room.": "Evita que cualquier persona que no sea parte de %(serverName)s se una a esta sala.", "You've previously used a newer version of %(brand)s with this session. To use this version again with end to end encryption, you will need to sign out and back in again.": "Anteriormente usaste una versión más nueva de %(brand)s con esta sesión. Para volver a utilizar esta versión con cifrado de extremo a extremo, deberá cerrar sesión y volver a iniciar sesión.", "There was an error updating your community. The server is unable to process your request.": "Ha ocurrido un error al actualizar tu comunidad. El servidor no puede procesar la solicitud.", "Update community": "Actualizar comunidad", "To continue, use Single Sign On to prove your identity.": "Para continuar, utilice el inicio de sesión único para demostrar su identidad.", "Confirm to continue": "Confirmar para continuar", - "Click the button below to confirm your identity.": "Haga clic en el botón de abajo para confirmar su identidad.", + "Click the button below to confirm your identity.": "Haz clic en el botón de abajo para confirmar tu identidad.", "May include members not in %(communityName)s": "Puede incluir miembros que no están en %(communityName)s", "Start a conversation with someone using their name, username (like ) or email address. This won't invite them to %(communityName)s. To invite someone to %(communityName)s, click here.": "Inicie una conversación con alguien usando su nombre, nombre de usuario (como) o dirección de correo electrónico. Esto no los invitará a %(communityName)s Para invitar a alguien a %(communityName)s, haga clic aquí.", "You're all caught up.": "Estás al día.", @@ -2247,7 +2247,7 @@ "Your server isn't responding to some of your requests. Below are some of the most likely reasons.": "Su servidor no responde a algunas de sus solicitudes. A continuación se presentan algunas de las razones más probables.", "The server (%(serverName)s) took too long to respond.": "El servidor (%(serverName)s) tardó demasiado en responder.", "Your firewall or anti-virus is blocking the request.": "Tu firewall o antivirus está bloqueando la solicitud.", - "A browser extension is preventing the request.": "Una extensión del navegador está impidiendo que se haga la solicitud.", + "A browser extension is preventing the request.": "Una extensión del navegador está impidiendo la solicitud.", "The server is offline.": "El servidor está desconectado.", "The server has denied your request.": "El servidor ha rechazado la solicitud.", "Your area is experiencing difficulties connecting to the internet.": "Su área está experimentando dificultades para conectarse a Internet.", @@ -2269,7 +2269,7 @@ "You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use %(brand)s with an existing Matrix account on a different homeserver.": "Puede utilizar las opciones del servidor personalizado para iniciar sesión en otros servidores Matrix especificando una URL de servidor principal diferente. Esto le permite utilizar %(brand)s con una cuenta Matrix existente en un servidor doméstico diferente.", "Enter the location of your Element Matrix Services homeserver. It may use your own domain name or be a subdomain of element.io.": "Ingrese la ubicación de su servidor doméstico de Element Matrix Services. Puede usar su propio nombre de dominio o ser un subdominio de element.io.", "No files visible in this room": "No hay archivos visibles en esta sala", - "Attach files from chat or just drag and drop them anywhere in a room.": "Adjunte archivos desde el chat o simplemente arrástrelos y suéltelos en cualquier lugar de una sala.", + "Attach files from chat or just drag and drop them anywhere in a room.": "Adjunta archivos desde el chat o simplemente arrástralos y suéltalos en cualquier lugar de una sala.", "You’re all caught up": "Estás al día", "You have no visible notifications in this room.": "No tienes notificaciones visibles en esta sala.", "Delete the room address %(alias)s and remove %(name)s from the directory?": "¿Eliminar la dirección de la sala %(alias)s y eliminar %(name)s del directorio?", @@ -2278,7 +2278,7 @@ "Search rooms": "Buscar salas", "Create community": "Crear comunidad", "Failed to find the general chat for this community": "No se pudo encontrar el chat general de esta comunidad", - "Security & privacy": "Seguridad y Privacidad", + "Security & privacy": "Seguridad y privacidad", "All settings": "Todos los ajustes", "Feedback": "Realimentación", "Community settings": "Configuración de la comunidad", @@ -2310,7 +2310,7 @@ "%(brand)s iOS": "%(brand)s iOS", "%(brand)s Android": "%(brand)s Android", "or another cross-signing capable Matrix client": "u otro cliente Matrix con capacidad de firma cruzada", - "Without completing security on this session, it won’t have access to encrypted messages.": "Sin completar la seguridad en esta sesión, no tendrá acceso a los mensajes cifrados.", + "Without completing security on this session, it won’t have access to encrypted messages.": "Al no completar la seguridad en esta sesión, no tendrás acceso a los mensajes cifrados.", "Failed to re-authenticate due to a homeserver problem": "No ha sido posible volver a autenticarse debido a un problema con el servidor base", "Failed to re-authenticate": "No se pudo volver a autenticar", "Regain access to your account and recover encryption keys stored in this session. Without them, you won’t be able to read all of your secure messages in any session.": "Recupere el acceso a su cuenta y recupere las claves de cifrado almacenadas en esta sesión. Sin ellos, no podrá leer todos sus mensajes seguros en ninguna sesión.", @@ -2329,7 +2329,7 @@ "Room Autocomplete": "Autocompletar sala", "User Autocomplete": "Autocompletar de usuario", "Confirm encryption setup": "Confirmar la configuración de cifrado", - "Click the button below to confirm setting up encryption.": "Haga clic en el botón de abajo para confirmar la configuración del cifrado.", + "Click the button below to confirm setting up encryption.": "Haz clic en el botón de abajo para confirmar la configuración del cifrado.", "Safeguard against losing access to encrypted messages & data by backing up encryption keys on your server.": "Protéjase contra la pérdida de acceso a los mensajes y datos cifrados haciendo una copia de seguridad de las claves de cifrado en su servidor.", "Generate a Security Key": "Generar una llave de seguridad", "We’ll generate a Security Key for you to store somewhere safe, like a password manager or a safe.": "Generaremos una llave de seguridad para que la guardes en un lugar seguro, como un administrador de contraseñas o una caja fuerte.", @@ -2752,7 +2752,7 @@ "Active Widgets": "Widgets activos", "This version of %(brand)s does not support viewing some encrypted files": "Esta versión de %(brand)s no permite ver algunos archivos cifrados", "Use the Desktop app to search encrypted messages": "Usa la aplicación de ordenador para buscar en los mensajes cifrados", - "Use the Desktop app to see all encrypted files": "Usar la aplicación de ordenador para ver todos los archivos cifrados", + "Use the Desktop app to see all encrypted files": "Usa la aplicación de ordenador para ver todos los archivos cifrados", "Video conference started by %(senderName)s": "Videoconferencia iniciada por %(senderName)s", "Video conference updated by %(senderName)s": "Videoconferencia actualizada por %(senderName)s", "You held the call Resume": "Has puesto la llamada en espera Recuperar", @@ -2943,5 +2943,88 @@ "Answered Elsewhere": "Respondida en otra parte", "The call could not be established": "No se ha podido establecer la llamada", "The other party declined the call.": "La otra persona ha rechazado la llamada.", - "Call Declined": "Llamada rechazada" + "Call Declined": "Llamada rechazada", + "Your Security Key is a safety net - you can use it to restore access to your encrypted messages if you forget your Security Phrase.": "Tu clave de seguridad es una red de seguridad. Puedes usarla para volver a tener acceso a tus mensajes cifrados si te olvidas de tu frase de seguridad.", + "We'll store an encrypted copy of your keys on our server. Secure your backup with a Security Phrase.": "Almacenaremos una copia cifrada de tus claves en nuestros servidores. Asegura tu copia de seguridad con una frase de seguridad.", + "

HTML for your community's page

\n

\n Use the long description to introduce new members to the community, or distribute\n some important links\n

\n

\n You can even add images with Matrix URLs \n

\n": "

HTML para tu página de comunidad

\n

\n\tUsa la descripción extendida para presentar la comunidad a nuevos participantes, o difunde\n\tenlaces importantes\n

\n

\n\tPuedes incluso añadir imágenes con direcciones URL de Matrix \n

\n", + "If you've forgotten your Security Key you can ": "Si te has olvidado de tu clave de seguridad puedes ", + "Access your secure message history and set up secure messaging by entering your Security Key.": "Accede a tu historial de mensajes seguros y configúralos introduciendo tu clave de seguridad.", + "If you've forgotten your Security Phrase you can use your Security Key or set up new recovery options": "Si has olvidado tu frase de seguridad puedes usar tu clave de seguridad o configurar nuevos métodos de recuperación", + "Access your secure message history and set up secure messaging by entering your Security Phrase.": "Accede a tu historia de mensajes seguros o configúralos escribiendo tu frase de seguridad.", + "Backup could not be decrypted with this Security Phrase: please verify that you entered the correct Security Phrase.": "No se ha podido descifrar la copia de seguridad con esa frase. Por favor, comprueba que hayas escrito bien la frase de seguridad.", + "Set up with a Security Key": "Configurar una clave de seguridad", + "Backup could not be decrypted with this Security Key: please verify that you entered the correct Security Key.": "La copia de seguridad no se ha podido descifrar con esta clave: por favor, comprueba que la que has introducido es correcta.", + "Security Key mismatch": "Las claves de seguridad no coinciden", + "Invite someone using their name, username (like ) or share this room.": "Invita a alguien usando su nombre, nombre de usuario (ej.: ) o compartiendo esta sala.", + "Only the two of you are in this conversation, unless either of you invites anyone to join.": "En esta conversación no hay nadie más, hasta que uno de los dos invite a alguien.", + "Are you sure you wish to abort creation of the host? The process cannot be continued.": "¿Seguro que quieres cancelar la creación del host? El proceso no podrá continuarse.", + "Use email or phone to optionally be discoverable by existing contacts.": "Usa tu correo electrónico o teléfono para que, opcionalmente, tus contactos puedan descubrir tu cuenta.", + "Enter Security Key": "Introduce la clave de seguridad", + "Unable to access secret storage. Please verify that you entered the correct Security Phrase.": "No se ha podido acceder al almacenamiento seguro. Por favor, comprueba que la frase de seguridad es correcta.", + "Just a heads up, if you don't add an email and forget your password, you could permanently lose access to your account.": "Ten en cuenta que, si no añades un correo electrónico y olvidas tu contraseña, podrías perder accceso para siempre a tu cuenta.", + "We recommend you change your password and Security Key in Settings immediately": "Te recomendamos que cambies tu contraseña y clave de seguridad en ajustes inmediatamente", + "Invite someone using their name, email address, username (like ) or share this room.": "Invitar a alguien usando su nombre, dirección de correo, nombre de usuario (ej.: ) o compartiendo esta sala.", + "This won't invite them to %(communityName)s. To invite someone to %(communityName)s, click here": "Esto no les invitará a %(communityName)s. Para invitar a alguien a %(communityName)s, haz clic aquí", + "Continuing temporarily allows the %(hostSignupBrand)s setup process to access your account to fetch verified email addresses. This data is not stored.": "Al continuar con el proceso de configuración, %(hostSignupBrand)s podrá acceder a tu cuenta para comprobar las direcciones de correo verificadas. Los datos no se almacenan.", + "Failed to connect to your homeserver. Please close this dialog and try again.": "No se ha podido conectar con tu servidor base. Por favor, cierra este mensaje e inténtalo de nuevo.", + "Securely cache encrypted messages locally for them to appear in search results, using %(size)s to store messages from %(rooms)s rooms.|one": "Guardar mensajes cifrados de forma segura y local para que aparezcan en los resultados de búsqueda, usando %(size)s para almacenar mensajes de %(rooms)s sala.", + "Securely cache encrypted messages locally for them to appear in search results, using %(size)s to store messages from %(rooms)s rooms.|other": "Guardar mensajes cifrados de forma segura y local para que aparezcan en los resultados de búsqueda, usando %(size)s para almacenar mensajes de %(rooms)s salas.", + "Offline encrypted messaging using dehydrated devices": "Mensajería cifrada y offline usando dispositivos deshidratados", + "Send %(msgtype)s messages as you in your active room": "Enviar mensajes de tipo %(msgtype)s en tu nombre a tu sala activa", + "Send %(msgtype)s messages as you in this room": "Enviar mensajes de tipo %(msgtype)s en tu nombre a esta sala", + "See general files posted to your active room": "Ver archivos enviados a tu sala activa", + "See general files posted to this room": "Ver archivos enviados a esta sala", + "Send general files as you in your active room": "Enviar archivos en tu nombre a tu sala activa", + "See videos posted to your active room": "Ver los vídeos publicados a tu sala activa", + "Send videos as you in your active room": "Enviar vídeos en tu nombre a tu sala activa", + "See images posted to your active room": "Ver las imágenes enviadas a tu sala activa", + "Send images as you in your active room": "Enviar imágenes en tu nombre a tu sala activa", + "See emotes posted to your active room": "Ver las reacciones publicadas en tu sala activa", + "Send emotes as you in your active room": "Reaccionar en tu nombre a tu sala activa", + "See %(eventType)s events posted to your active room": "Ver los eventos de tipo %(eventType)s publicados en tu sala activa", + "Send stickers to your active room as you": "Enviar etiquetas a tu sala activa en tu nombre", + "Start a conversation with someone using their name or username (like ).": "Empieza una conversación con alguien usando su nombre o nombre de usuario (como ).", + "Start a conversation with someone using their name, email address or username (like ).": "Empieza una conversación con alguien usando su nombre, correo electrónico o nombre de usuario (como ).", + "Minimize dialog": "Minimizar", + "Maximize dialog": "Maximizar", + "See %(msgtype)s messages posted to your active room": "Ver mensajes de tipo %(msgtype)s enviados a tu sala activa", + "See %(msgtype)s messages posted to this room": "Ver mensajes de tipo %(msgtype)s enviados a esta sala", + "Show chat effects (animations when receiving e.g. confetti)": "Mostrar efectos de chat (animaciones al recibir ciertos mensajes, como confeti)", + "Expand code blocks by default": "Expandir bloques de ćodigo por defecto", + "Learn more in our , and .": "Más información en nuestra , y .", + "Cookie Policy": "Política de cookies", + "Privacy Policy": "Política de privacidad", + "%(hostSignupBrand)s Setup": "Configuración de %(hostSignupBrand)s", + "You should know": "Conviene saber", + "Upgrade to %(hostSignupBrand)s": "Contratar %(hostSignupBrand)s", + "Show line numbers in code blocks": "Mostrar números de línea en bloques de ćodigo", + "This is the beginning of your direct message history with .": "Este es el inicio de tu historial de mensajes directos con .", + "Recently visited rooms": "Salas visitadas recientemente", + "Abort": "Cancelar", + "Confirm abort of host creation": "Confirma que quieres cancelar la creación del host", + "PRO TIP: If you start a bug, please submit debug logs to help us track down the problem.": "CONSEJO: Si creas una incidencia, adjunta tus registros de depuración para ayudarnos a localizar el problema.", + "Please view existing bugs on Github first. No match? Start a new one.": "Por favor, echa un vistazo a las incidenias de Github primero. Si no encuentras nada relacionado, crea una nueva.", + "Edit Values": "Editar valores", + "Values at explicit levels in this room:": "Valores a niveles explícitos en esta sala:", + "Values at explicit levels:": "Valores a niveles explícitos:", + "Value in this room:": "Valor en esta sala:", + "Value:": "Valor:", + "Save setting values": "Guardar valores de ajustes", + "Values at explicit levels in this room": "Valores a niveles explícitos en esta sala", + "Values at explicit levels": "Valores a niveles explícitos", + "Settable at room": "Establecible a nivel de sala", + "Settable at global": "Establecible globalmente", + "Level": "Nivel", + "Setting definition:": "Definición del ajuste:", + "This UI does NOT check the types of the values. Use at your own risk.": "Esta interfaz NO comprueba los tipos de dato de los valores. Usar bajo tu responsabilidad.", + "Caution:": "Precaución:", + "Setting:": "Ajuste:", + "Value in this room": "Valor en esta sala", + "Value": "Valor", + "Setting ID": "ID de ajuste", + "Failed to save settings": "No se han podido guardar los ajustes", + "Settings Explorer": "Explorador de ajustes", + "Windows": "Ventanas", + "Share your screen": "Compartir pantalla", + "Screens": "Pantallas" } From 9d65f0ca41ff0431301036d2c4e41e3ac9fdf6f7 Mon Sep 17 00:00:00 2001 From: Thibault Martin Date: Fri, 5 Mar 2021 21:31:18 +0000 Subject: [PATCH 29/91] Translated using Weblate (French) Currently translated at 100.0% (2780 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 3d024f6e18..e170ec1414 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -3043,5 +3043,27 @@ "Your homeserver was unreachable and was not able to log you in. Please try again. If this continues, please contact your homeserver administrator.": "Votre serveur d’accueil n’est pas accessible, nous n’avons pas pu vous connecter. Merci de réessayer. Si cela persiste, merci de contacter l’administrateur de votre serveur d’accueil.", "Try again": "Réessayez", "We asked the browser to remember which homeserver you use to let you sign in, but unfortunately your browser has forgotten it. Go to the sign in page and try again.": "Nous avons demandé à votre navigateur de mémoriser votre serveur d’accueil, mais il semble l’avoir oublié. Rendez-vous à la page de connexion et réessayez.", - "We couldn't log you in": "Impossible de vous déconnecter" + "We couldn't log you in": "Impossible de vous déconnecter", + "Upgrade to %(hostSignupBrand)s": "Mettre à jour vers %(hostSignupBrand)s", + "Edit Values": "Modifier les valeurs", + "Values at explicit levels in this room:": "Valeurs pour les rangs explicites de ce salon :", + "Values at explicit levels:": "Valeurs pour les rangs explicites :", + "Value in this room:": "Valeur pour ce salon :", + "Value:": "Valeur :", + "Save setting values": "Enregistrer les valeurs des paramètres", + "Values at explicit levels in this room": "Valeurs pour des rangs explicites dans ce salon", + "Values at explicit levels": "Valeurs pour des rangs explicites", + "Settable at room": "Définissable par salon", + "Settable at global": "Définissable de manière globale", + "Level": "Rang", + "Setting definition:": "Définition du paramètre :", + "This UI does NOT check the types of the values. Use at your own risk.": "Cette interface ne vérifie pas les types des valeurs. Utilisez la à vos propres risques.", + "Caution:": "Attention :", + "Setting:": "Paramètre :", + "Value in this room": "Valeur pour ce salon", + "Value": "Valeur", + "Setting ID": "Identifiant de paramètre", + "Failed to save settings": "Échec lors de la sauvegarde des paramètres", + "Settings Explorer": "Explorateur de paramètres", + "Show chat effects (animations when receiving e.g. confetti)": "Afficher les animations de conversation (animations lors de la réception par ex. de confettis)" } From 49c40e662ce40ba2f967708e07e92579a37de7e6 Mon Sep 17 00:00:00 2001 From: Roel ter Maat Date: Tue, 2 Mar 2021 21:10:34 +0000 Subject: [PATCH 30/91] Translated using Weblate (Dutch) Currently translated at 100.0% (2780 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/nl/ --- src/i18n/strings/nl.json | 48 ++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index 0d80e520c8..db3255c051 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -165,7 +165,7 @@ "Failed to set display name": "Instellen van weergavenaam is mislukt", "Failed to unban": "Ontbannen mislukt", "Failed to upload profile picture!": "Uploaden van profielfoto is mislukt!", - "Failed to verify email address: make sure you clicked the link in the email": "Kan het e-mailadres niet verifiëren: zorg ervoor dat u de koppeling in de e-mail heeft aangeklikt", + "Failed to verify email address: make sure you clicked the link in the email": "Kan het e-mailadres niet verifiëren: zorg ervoor dat je de koppeling in de e-mail hebt aangeklikt", "Failure to create room": "Aanmaken van gesprek is mislukt", "Favourites": "Favorieten", "Fill screen": "Scherm vullen", @@ -240,7 +240,7 @@ "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s heeft %(targetDisplayName)s in het gesprek uitgenodigd.", "Server error": "Serverfout", "Server may be unavailable, overloaded, or search timed out :(": "De server is misschien onbereikbaar of overbelast, of het zoeken duurde te lang :(", - "Server may be unavailable, overloaded, or you hit a bug.": "De server is misschien onbereikbaar of overbelast, of u bent een fout tegengekomen.", + "Server may be unavailable, overloaded, or you hit a bug.": "De server is misschien onbereikbaar of overbelast, of je bent een fout tegengekomen.", "Server unavailable, overloaded, or something else went wrong.": "De server is onbereikbaar of overbelast, of er is iets anders foutgegaan.", "Session ID": "Sessie-ID", "%(senderName)s kicked %(targetName)s.": "%(senderName)s heeft %(targetName)s het gesprek uitgestuurd.", @@ -304,8 +304,8 @@ "Who can read history?": "Wie kan de geschiedenis lezen?", "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s heeft de uitnodiging van %(targetName)s ingetrokken.", "You are already in a call.": "U bent al in gesprek.", - "You cannot place a call with yourself.": "U kunt uzelf niet bellen.", - "You cannot place VoIP calls in this browser.": "U kunt in deze browser geen VoIP-oproepen plegen.", + "You cannot place a call with yourself.": "Je kunt jezelf niet bellen.", + "You cannot place VoIP calls in this browser.": "Je kunt in deze browser geen VoIP-oproepen plegen.", "You do not have permission to post to this room": "U heeft geen toestemming actief aan dit gesprek deel te nemen", "You have disabled URL previews by default.": "U heeft URL-voorvertoningen standaard uitgeschakeld.", "You have enabled URL previews by default.": "U heeft URL-voorvertoningen standaard ingeschakeld.", @@ -420,7 +420,7 @@ "Which rooms would you like to add to this community?": "Welke gesprekken wilt u toevoegen aan deze gemeenschap?", "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Widgets verwijderen geldt voor alle deelnemers aan dit gesprek. Weet u zeker dat u deze widget wilt verwijderen?", "Delete Widget": "Widget verwijderen", - "Who would you like to add to this community?": "Wie wilt u toevoegen aan deze gemeenschap?", + "Who would you like to add to this community?": "Wie wil je toevoegen aan deze gemeenschap?", "Invite to Community": "Uitnodigen tot gemeenschap", "Show these rooms to non-members on the community page and room list?": "Deze gesprekken tonen aan niet-leden op de gemeenschapspagina en gesprekslijst?", "Add rooms to the community": "Voeg gesprekken toe aan de gemeenschap", @@ -628,12 +628,12 @@ "Room Notification": "Groepsgespreksmelding", "The information being sent to us to help make %(brand)s better includes:": "De informatie die naar ons wordt verstuurd om %(brand)s te verbeteren bevat:", "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Waar deze pagina identificeerbare informatie bevat, zoals een gespreks-, gebruikers- of groeps-ID, zullen deze gegevens verwijderd worden voordat ze naar de server gestuurd worden.", - "The platform you're on": "Het platform dat u gebruikt", + "The platform you're on": "Het platform dat je gebruikt", "The version of %(brand)s": "De versie van %(brand)s", - "Your language of choice": "De door u gekozen taal", - "Which officially provided instance you are using, if any": "Welke officieel aangeboden instantie u eventueel gebruikt", - "Whether or not you're using the Richtext mode of the Rich Text Editor": "Of u de tekstverwerker al dan niet in de modus voor opgemaakte tekst gebruikt", - "Your homeserver's URL": "De URL van uw homeserver", + "Your language of choice": "De door jou gekozen taal", + "Which officially provided instance you are using, if any": "Welke officieel aangeboden instantie je eventueel gebruikt", + "Whether or not you're using the Richtext mode of the Rich Text Editor": "Of je de tekstverwerker al dan niet in de modus voor opgemaakte tekst gebruikt", + "Your homeserver's URL": "De URL van je homeserver", "In reply to ": "Als antwoord op ", "This room is not public. You will not be able to rejoin without an invite.": "Dit is geen openbaar gesprek. Slechts op uitnodiging zult u opnieuw kunnen toetreden.", "were unbanned %(count)s times|one": "zijn ontbannen", @@ -783,9 +783,9 @@ "Failed to send logs: ": "Versturen van logboeken mislukt: ", "Preparing to send logs": "Logboeken worden voorbereid voor versturen", "e.g. %(exampleValue)s": "bv. %(exampleValue)s", - "Every page you use in the app": "Iedere bladzijde die u in de toepassing gebruikt", + "Every page you use in the app": "Iedere bladzijde die je in de toepassing gebruikt", "e.g. ": "bv. ", - "Your device resolution": "De resolutie van uw apparaat", + "Your device resolution": "De resolutie van je apparaat", "Missing roomId.": "roomId ontbreekt.", "Always show encryption icons": "Versleutelingspictogrammen altijd tonen", "Send analytics data": "Statistische gegevens versturen", @@ -813,7 +813,7 @@ "A call is currently being placed!": "Er wordt al een oproep gemaakt!", "A call is already in progress!": "Er is al een gesprek actief!", "Permission Required": "Toestemming vereist", - "You do not have permission to start a conference call in this room": "U heeft geen toestemming in dit groepsgesprek een vergadergesprek te starten", + "You do not have permission to start a conference call in this room": "Je hebt geen toestemming in dit groepsgesprek een vergadergesprek te starten", "This event could not be displayed": "Deze gebeurtenis kon niet weergegeven worden", "Demote yourself?": "Uzelf degraderen?", "Demote": "Degraderen", @@ -842,9 +842,9 @@ "Bulk options": "Bulkopties", "This homeserver has hit its Monthly Active User limit.": "Deze homeserver heeft zijn limiet voor maandelijks actieve gebruikers bereikt.", "This homeserver has exceeded one of its resource limits.": "Deze homeserver heeft één van zijn systeembronlimieten overschreden.", - "Whether or not you're logged in (we don't record your username)": "Of u al dan niet ingelogd bent (we slaan uw gebruikersnaam niet op)", + "Whether or not you're logged in (we don't record your username)": "Of je al dan niet ingelogd bent (we slaan je gebruikersnaam niet op)", "The file '%(fileName)s' exceeds this homeserver's size limit for uploads": "Het bestand ‘%(fileName)s’ is groter dan de uploadlimiet van de homeserver", - "Unable to load! Check your network connectivity and try again.": "Laden mislukt! Controleer uw netwerktoegang en probeer het nogmaals.", + "Unable to load! Check your network connectivity and try again.": "Laden mislukt! Controleer je netwerktoegang en probeer het nogmaals.", "Failed to invite users to the room:": "Kon de volgende gebruikers hier niet uitnodigen:", "Prepends ¯\\_(ツ)_/¯ to a plain-text message": "Plakt ¯\\_(ツ)_/¯ vóór een bericht zonder opmaak", "Upgrades a room to a new version": "Actualiseert het gesprek tot een nieuwe versie", @@ -1255,9 +1255,9 @@ "The homeserver may be unavailable or overloaded.": "De homeserver is mogelijk onbereikbaar of overbelast.", "You have %(count)s unread notifications in a prior version of this room.|other": "U heeft %(count)s ongelezen meldingen in een vorige versie van dit gesprek.", "You have %(count)s unread notifications in a prior version of this room.|one": "U heeft %(count)s ongelezen meldingen in een vorige versie van dit gesprek.", - "Whether or not you're using the 'breadcrumbs' feature (avatars above the room list)": "Of u de icoontjes voor recente gesprekken (boven de gesprekkenlijst) al dan niet gebruikt", + "Whether or not you're using the 'breadcrumbs' feature (avatars above the room list)": "Of je de icoontjes voor recente gesprekken (boven de gesprekkenlijst) al dan niet gebruikt", "Replying With Files": "Beantwoorden met bestanden", - "At this time it is not possible to reply with a file. Would you like to upload this file without replying?": "Het is momenteel niet mogelijk met een bestand te antwoorden. Wilt u dit bestand uploaden zonder te antwoorden?", + "At this time it is not possible to reply with a file. Would you like to upload this file without replying?": "Het is momenteel niet mogelijk met een bestand te antwoorden. Wil je dit bestand uploaden zonder te antwoorden?", "The file '%(fileName)s' failed to upload.": "Het bestand ‘%(fileName)s’ kon niet geüpload worden.", "Rotate counter-clockwise": "Tegen de klok in draaien", "Rotate clockwise": "Met de klok mee draaien", @@ -1433,8 +1433,8 @@ "Command Help": "Hulp bij opdrachten", "No identity server is configured: add one in server settings to reset your password.": "Er is geen identiteitsserver geconfigureerd: voeg er één toe in de serverinstellingen om uw wachtwoord opnieuw in te stellen.", "Call failed due to misconfigured server": "Oproep mislukt door verkeerd geconfigureerde server", - "Please ask the administrator of your homeserver (%(homeserverDomain)s) to configure a TURN server in order for calls to work reliably.": "Vraag uw homeserverbeheerder (%(homeserverDomain)s) een TURN-server te configureren voor de betrouwbaarheid van de oproepen.", - "Alternatively, you can try to use the public server at turn.matrix.org, but this will not be as reliable, and it will share your IP address with that server. You can also manage this in Settings.": "U kunt ook de publieke server op turn.matrix.org gebruiken, maar dit zal minder betrouwbaar zijn, en zal uw IP-adres met die server delen. U kunt dit ook beheren in de Instellingen.", + "Please ask the administrator of your homeserver (%(homeserverDomain)s) to configure a TURN server in order for calls to work reliably.": "Vraag je homeserverbeheerder (%(homeserverDomain)s) een TURN-server te configureren voor de betrouwbaarheid van de oproepen.", + "Alternatively, you can try to use the public server at turn.matrix.org, but this will not be as reliable, and it will share your IP address with that server. You can also manage this in Settings.": "Je kunt ook de publieke server op turn.matrix.org gebruiken, maar dit zal minder betrouwbaar zijn, en zal uw IP-adres met die server delen. Je kunt dit ook beheren in de Instellingen.", "Try using turn.matrix.org": "Probeer turn.matrix.org te gebruiken", "Allow fallback call assist server turn.matrix.org when your homeserver does not offer one (your IP address would be shared during a call)": "Sta de terugvalserver voor oproepbijstand turn.matrix.org toe wanneer uw homeserver er geen aanbiedt (uw IP-adres wordt gedeeld gedurende een oproep)", "Identity server has no terms of service": "De identiteitsserver heeft geen dienstvoorwaarden", @@ -1636,9 +1636,9 @@ "Unable to load session list": "Kan sessielijst niet laden", "Delete %(count)s sessions|other": "%(count)s sessies verwijderen", "Delete %(count)s sessions|one": "%(count)s sessie verwijderen", - "Whether you're using %(brand)s on a device where touch is the primary input mechanism": "Of u %(brand)s op een apparaat gebruikt waarop een aanraakscherm de voornaamste invoermethode is", - "Whether you're using %(brand)s as an installed Progressive Web App": "Of u %(brand)s gebruikt als een geïnstalleerde Progressive-Web-App", - "Your user agent": "Uw gebruikersagent", + "Whether you're using %(brand)s on a device where touch is the primary input mechanism": "Of je %(brand)s op een apparaat gebruikt waarop een aanraakscherm de voornaamste invoermethode is", + "Whether you're using %(brand)s as an installed Progressive Web App": "Of je %(brand)s gebruikt als een geïnstalleerde Progressive-Web-App", + "Your user agent": "Jouw gebruikersagent", "If you cancel now, you won't complete verifying the other user.": "Als u nu annuleert zult u de andere gebruiker niet verifiëren.", "If you cancel now, you won't complete verifying your other session.": "Als u nu annuleert zult u uw andere sessie niet verifiëren.", "Cancel entering passphrase?": "Wachtwoordinvoer annuleren?", @@ -1973,11 +1973,11 @@ "Where you’re logged in": "Waar u ingelogd bent", "Manage the names of and sign out of your sessions below or verify them in your User Profile.": "Beheer hieronder de namen van uw sessies en meld ze af. Of verifieer ze in uw gebruikersprofiel.", "Use Single Sign On to continue": "Ga verder met eenmalige aanmelding", - "Confirm adding this email address by using Single Sign On to prove your identity.": "Bevestig uw identiteit met uw eenmalige aanmelding om dit e-mailadres toe te voegen.", + "Confirm adding this email address by using Single Sign On to prove your identity.": "Bevestig je identiteit met je eenmalige aanmelding om dit e-mailadres toe te voegen.", "Single Sign On": "Eenmalige aanmelding", "Confirm adding email": "Bevestig toevoegen van het e-mailadres", "Click the button below to confirm adding this email address.": "Klik op de knop hieronder om dit e-mailadres toe te voegen.", - "Confirm adding this phone number by using Single Sign On to prove your identity.": "Bevestig uw identiteit met uw eenmalige aanmelding om dit telefoonnummer toe te voegen.", + "Confirm adding this phone number by using Single Sign On to prove your identity.": "Bevestig je identiteit met je eenmalige aanmelding om dit telefoonnummer toe te voegen.", "Confirm adding phone number": "Bevestig toevoegen van het telefoonnummer", "Click the button below to confirm adding this phone number.": "Klik op de knop hieronder om het toevoegen van dit telefoonnummer te bevestigen.", "If you cancel now, you won't complete your operation.": "Als u de operatie afbreekt kunt u haar niet voltooien.", From 592bd427a5995fe61b24b9ea40c1931c55eef015 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Mon, 1 Mar 2021 21:11:40 +0000 Subject: [PATCH 31/91] Translated using Weblate (Ukrainian) Currently translated at 53.6% (1492 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/uk/ --- src/i18n/strings/uk.json | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/uk.json b/src/i18n/strings/uk.json index adb830c123..5f392295c3 100644 --- a/src/i18n/strings/uk.json +++ b/src/i18n/strings/uk.json @@ -325,7 +325,7 @@ "Displays action": "Відбиває дію", "Reason": "Причина", "%(senderName)s requested a VoIP conference.": "%(senderName)s бажає розпочати дзвінок-конференцію.", - "%(senderName)s invited %(targetName)s.": "%(senderName)s запросив/ла %(targetName)s.", + "%(senderName)s invited %(targetName)s.": "%(senderName)s запрошує %(targetName)s.", "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s змінює своє видиме ім'я на %(displayName)s.", "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s зазначив(-ла) своє видиме ім'я: %(displayName)s.", "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s видалив(-ла) своє видиме ім'я (%(oldDisplayName)s).", @@ -1164,7 +1164,7 @@ "Show hidden events in timeline": "Показувати приховані події у часоряді", "Show previews/thumbnails for images": "Показувати попередній перегляд зображень", "Compare a unique set of emoji if you don't have a camera on either device": "Порівняйте унікальну низку емодзі якщо ви не маєте камери на жодному пристрої", - "Confirm the emoji below are displayed on both sessions, in the same order:": "Підтвердьте, що нижчевказані емодзі відбиваються в обох сеансах в однаковому порядку:", + "Confirm the emoji below are displayed on both sessions, in the same order:": "Підтвердьте, що емодзі внизу показано в обох сеансах в однаковому порядку:", "Verify this user by confirming the following emoji appear on their screen.": "Звірте цього користувача підтвердженням того, що наступні емодзі з'являються на його екрані.", "Emoji picker": "Обирач емодзі", "The session you are trying to verify doesn't support scanning a QR code or emoji verification, which is what %(brand)s supports. Try with a different client.": "Сеанс, який ви намагаєтесь звірити, не підтримує сканування QR-коду або звіряння за допомогою емодзі, що є підтримувані %(brand)s. Спробуйте використати інший клієнт.", @@ -1597,5 +1597,8 @@ "Enable encryption?": "Увімкнути шифрування?", "Enable room encryption": "Увімкнути шифрування кімнати", "Encryption": "Шифрування", - "Try again": "Спробувати ще раз" + "Try again": "Спробувати ще раз", + "%(creator)s created this DM.": "%(creator)s створює цю приватну розмову.", + "Share Link to User": "Поділитися посиланням на користувача", + "Messages here are end-to-end encrypted. Verify %(displayName)s in their profile - tap on their avatar.": "Повідомлення тут захищено наскрізним шифруванням. Підтвердьте %(displayName)s у їхньому профілі — натиснувши на їх аватар." } From ca729d35aa90eb55b908dd4101768f44d7589701 Mon Sep 17 00:00:00 2001 From: random Date: Tue, 2 Mar 2021 12:00:40 +0000 Subject: [PATCH 32/91] Translated using Weblate (Italian) Currently translated at 100.0% (2780 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/it/ --- src/i18n/strings/it.json | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/it.json b/src/i18n/strings/it.json index 2764863e77..3e5ad9296b 100644 --- a/src/i18n/strings/it.json +++ b/src/i18n/strings/it.json @@ -3065,5 +3065,27 @@ "Recently visited rooms": "Stanze visitate di recente", "Show line numbers in code blocks": "Mostra numeri di riga nei blocchi di codice", "Expand code blocks by default": "Espandi blocchi di codice in modo predefinito", - "Show stickers button": "Mostra pulsante adesivi" + "Show stickers button": "Mostra pulsante adesivi", + "Upgrade to %(hostSignupBrand)s": "Aggiorna a %(hostSignupBrand)s", + "Edit Values": "Modifica valori", + "Values at explicit levels in this room:": "Valori a livelli espliciti in questa stanza:", + "Values at explicit levels:": "Valori a livelli espliciti:", + "Value in this room:": "Valore in questa stanza:", + "Value:": "Valore:", + "Save setting values": "Salva valori impostazione", + "Values at explicit levels in this room": "Valori a livelli espliciti in questa stanza", + "Values at explicit levels": "Valori a livelli espliciti", + "Settable at room": "Impostabile per stanza", + "Settable at global": "Impostabile globalmente", + "Level": "Livello", + "Setting definition:": "Definizione impostazione:", + "This UI does NOT check the types of the values. Use at your own risk.": "Questa interfaccia NON controlla i tipi dei valori. Usa a tuo rischio.", + "Caution:": "Attenzione:", + "Setting:": "Impostazione:", + "Value in this room": "Valore in questa stanza", + "Value": "Valore", + "Setting ID": "ID impostazione", + "Failed to save settings": "Impossibile salvare le impostazioni", + "Settings Explorer": "Esploratore di impostazioni", + "Show chat effects (animations when receiving e.g. confetti)": "Mostra effetti chat (animazioni quando si ricevono ad es. coriandoli)" } From 6b098a2bafbf49acea769a17be976370c067cfbd Mon Sep 17 00:00:00 2001 From: Kaede Date: Tue, 2 Mar 2021 06:04:12 +0000 Subject: [PATCH 33/91] Translated using Weblate (Japanese) Currently translated at 50.2% (1398 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/ja/ --- src/i18n/strings/ja.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/ja.json b/src/i18n/strings/ja.json index bab9d94935..b5e28a9c1e 100644 --- a/src/i18n/strings/ja.json +++ b/src/i18n/strings/ja.json @@ -416,8 +416,8 @@ "Share Link to User": "ユーザーへのリンクを共有する", "Unmute": "ミュート解除", "Admin Tools": "管理者ツール", - "and %(count)s others...|other": "そして、他 %(count)s ...", - "and %(count)s others...|one": "そして、もう1つ...", + "and %(count)s others...|other": "他 %(count)s 人...", + "and %(count)s others...|one": "他1人...", "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (権限レベル: %(powerLevelNumber)s )", "Attachment": "付属品", "Hangup": "電話を切る", @@ -625,7 +625,7 @@ "Custom level": "カスタムレベル", "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "返信されたイベントを読み込めません。存在しないか、表示する権限がありません。", "In reply to ": "返信 ", - "And %(count)s more...|other": "そして %(count)s もっと...", + "And %(count)s more...|other": "他 %(count)s 人以上...", "ex. @bob:example.com": "例 @bob:example.com", "Add User": "ユーザーを追加", "Matrix ID": "Matirx ID", From d3af6b840a5993d3684e190c6d478fb6218d144c Mon Sep 17 00:00:00 2001 From: Rintan Date: Mon, 1 Mar 2021 04:42:56 +0000 Subject: [PATCH 34/91] Translated using Weblate (Japanese) Currently translated at 50.2% (1398 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/ja/ --- src/i18n/strings/ja.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ja.json b/src/i18n/strings/ja.json index b5e28a9c1e..ea7d51ae05 100644 --- a/src/i18n/strings/ja.json +++ b/src/i18n/strings/ja.json @@ -1533,5 +1533,7 @@ "Re-request encryption keys from your other sessions.": "あなたの他のセッションに暗号鍵を再リクエストする。", "Block anyone not part of %(serverName)s from ever joining this room.": "%(serverName)s 以外からの参加をブロック", "Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone.": "プライベートな部屋は招待者のみが参加できます。公開された部屋は誰でも検索・参加できます。", - "To report a Matrix-related security issue, please read the Matrix.org Security Disclosure Policy.": "Matrix 関連のセキュリティ問題を報告するには、Matrix.org の Security Disclosure Policy をご覧ください。" + "To report a Matrix-related security issue, please read the Matrix.org Security Disclosure Policy.": "Matrix 関連のセキュリティ問題を報告するには、Matrix.org の Security Disclosure Policy をご覧ください。", + "Confirm adding email": "メールアドレスの追加を確認する", + "Confirm adding this email address by using Single Sign On to prove your identity.": "シングルサインオンを使用して本人確認を行い、メールアドレスの追加を承認してください。" } From a82ac0cc90f427988d236f4065e13716adf34b97 Mon Sep 17 00:00:00 2001 From: waclaw66 Date: Wed, 3 Mar 2021 09:51:41 +0000 Subject: [PATCH 35/91] Translated using Weblate (Czech) Currently translated at 100.0% (2780 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/cs/ --- src/i18n/strings/cs.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index 47a99ab670..db01caed97 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -490,7 +490,7 @@ "were invited %(count)s times|other": "byli %(count)s krát pozváni", "were invited %(count)s times|one": "byli pozváni", "was invited %(count)s times|other": "byl %(count)s krát pozván", - "was invited %(count)s times|one": "byl pozván", + "was invited %(count)s times|one": "byl(a) pozván(a)", "were banned %(count)s times|other": "mělid %(count)s krát zakázaný vstup", "were banned %(count)s times|one": "měli zakázaný vstup", "was banned %(count)s times|other": "měl %(count)s krát zakázaný vstup", From b71695d803d2c80998e7597e8e17c8c538ff4b3d Mon Sep 17 00:00:00 2001 From: MamasLT Date: Wed, 3 Mar 2021 20:57:29 +0000 Subject: [PATCH 36/91] Translated using Weblate (Lithuanian) Currently translated at 68.5% (1905 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/lt/ --- src/i18n/strings/lt.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/lt.json b/src/i18n/strings/lt.json index 7edb8f0c55..80b70e67e4 100644 --- a/src/i18n/strings/lt.json +++ b/src/i18n/strings/lt.json @@ -429,7 +429,7 @@ "Unban this user?": "Atblokuoti šį vartotoją?", "Ban this user?": "Užblokuoti šį vartotoją?", "Failed to ban user": "Nepavyko užblokuoti vartotojo", - "Invited": "Pakviestas", + "Invited": "Pakviesta", "Filter room members": "Filtruoti kambario dalyvius", "Server unavailable, overloaded, or something else went wrong.": "Serveris neprieinamas, perkrautas arba nutiko kažkas kito.", "%(duration)ss": "%(duration)s sek", From 0f5f1132a5617c9dce893d4cc99e2750a48b0a97 Mon Sep 17 00:00:00 2001 From: HelaBasa Date: Tue, 2 Mar 2021 17:15:57 +0000 Subject: [PATCH 37/91] Translated using Weblate (Sinhala) Currently translated at 0.2% (7 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/si/ --- src/i18n/strings/si.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/si.json b/src/i18n/strings/si.json index 11da7b7e4c..5a81da879f 100644 --- a/src/i18n/strings/si.json +++ b/src/i18n/strings/si.json @@ -4,5 +4,6 @@ "Use Single Sign On to continue": "ඉදිරියට යාමට තනි පුරනය වීම භාවිතා කරන්න", "Confirm adding this email address by using Single Sign On to prove your identity.": "ඔබගේ අනන්‍යතාවය සනාථ කිරීම සඳහා තනි පුරනය භාවිතා කිරීමෙන් මෙම විද්‍යුත් තැපැල් ලිපිනය එක් කිරීම තහවුරු කරන්න.", "Confirm": "තහවුරු කරන්න", - "Add Email Address": "විද්‍යුත් තැපැල් ලිපිනය එක් කරන්න" + "Add Email Address": "විද්‍යුත් තැපැල් ලිපිනය එක් කරන්න", + "Sign In": "පිවිසෙන්න" } From 1427aa4203a5610be22bdb43eaab391cf83d88cb Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 04:41:51 +0000 Subject: [PATCH 38/91] fix mx_EncryptionInfo_spinner padding in dialogs --- res/css/views/right_panel/_EncryptionInfo.scss | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/res/css/views/right_panel/_EncryptionInfo.scss b/res/css/views/right_panel/_EncryptionInfo.scss index e13b1b6802..b3d4275f60 100644 --- a/res/css/views/right_panel/_EncryptionInfo.scss +++ b/res/css/views/right_panel/_EncryptionInfo.scss @@ -14,13 +14,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -.mx_UserInfo { - .mx_EncryptionInfo_spinner { - .mx_Spinner { - margin-top: 25px; - margin-bottom: 15px; - } - - text-align: center; +.mx_EncryptionInfo_spinner { + .mx_Spinner { + margin-top: 25px; + margin-bottom: 15px; } + + text-align: center; } From 76738184003e1e2ad8d24ad2fbbab3b5dab2afc2 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 04:43:59 +0000 Subject: [PATCH 39/91] switch to using an explicit verify button when cross-signing a new login --- .../structures/auth/SetupEncryptionBody.js | 46 +++++++++++-------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/src/components/structures/auth/SetupEncryptionBody.js b/src/components/structures/auth/SetupEncryptionBody.js index 3e7264dfec..d2b3fbd3b9 100644 --- a/src/components/structures/auth/SetupEncryptionBody.js +++ b/src/components/structures/auth/SetupEncryptionBody.js @@ -19,6 +19,8 @@ import PropTypes from 'prop-types'; import { _t } from '../../../languageHandler'; import SdkConfig from '../../../SdkConfig'; import { MatrixClientPeg } from '../../../MatrixClientPeg'; +import Modal from '../../../Modal'; +import VerificationRequestDialog from '../../views/dialogs/VerificationRequestDialog'; import * as sdk from '../../../index'; import { SetupEncryptionStore, @@ -81,6 +83,22 @@ export default class SetupEncryptionBody extends React.Component { store.usePassPhrase(); } + _onVerifyClick = () => { + const cli = MatrixClientPeg.get(); + const userId = cli.getUserId(); + const requestPromise = cli.requestVerification(userId); + + this.props.onFinished(true); + Modal.createTrackedDialog('New Session Verification', 'Starting dialog', VerificationRequestDialog, { + verificationRequestPromise: requestPromise, + member: cli.getUser(userId), + onFinished: async () => { + const request = await requestPromise; + request.cancel(); + }, + }); + } + onSkipClick = () => { const store = SetupEncryptionStore.sharedInstance(); store.skip(); @@ -132,32 +150,24 @@ export default class SetupEncryptionBody extends React.Component { ; } + let verifyButton; + if (store.hasDevicesToVerifyAgainst) { + verifyButton = + { _t("Verify against another session") } + ; + } + const brand = SdkConfig.get().brand; return (

{_t( - "Confirm your identity by verifying this login from one of your other sessions, " + - "granting it access to encrypted messages.", + "Verify this login to access your encrypted messages and " + + "prove to others that this login is really you." )}

-

{_t( - "This requires the latest %(brand)s on your other devices:", - { brand }, - )}

- -
-
-
{_t("%(brand)s Web", { brand })}
-
{_t("%(brand)s Desktop", { brand })}
-
-
-
{_t("%(brand)s iOS", { brand })}
-
{_t("%(brand)s Android", { brand })}
-
-

{_t("or another cross-signing capable Matrix client")}

-
+ {verifyButton} {useRecoveryKeyButton} {_t("Skip")} From 6df8157a40e6da23850ad5fd1a17294d6ba23382 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 04:45:44 +0000 Subject: [PATCH 40/91] cancel VRD at the Modal level, so clicking in the bg cancels it --- .../views/dialogs/NewSessionReviewDialog.js | 4 ++++ .../views/dialogs/VerificationRequestDialog.js | 13 ++----------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/components/views/dialogs/NewSessionReviewDialog.js b/src/components/views/dialogs/NewSessionReviewDialog.js index e17501da40..5172f29405 100644 --- a/src/components/views/dialogs/NewSessionReviewDialog.js +++ b/src/components/views/dialogs/NewSessionReviewDialog.js @@ -66,6 +66,10 @@ export default class NewSessionReviewDialog extends React.PureComponent { Modal.createTrackedDialog('New Session Verification', 'Starting dialog', VerificationRequestDialog, { verificationRequestPromise: requestPromise, member: cli.getUser(userId), + onFinished: async () => { + const request = await requestPromise; + request.cancel(); + }, }); } diff --git a/src/components/views/dialogs/VerificationRequestDialog.js b/src/components/views/dialogs/VerificationRequestDialog.js index 3a6e9a2d10..2a5b7ae699 100644 --- a/src/components/views/dialogs/VerificationRequestDialog.js +++ b/src/components/views/dialogs/VerificationRequestDialog.js @@ -25,11 +25,11 @@ export default class VerificationRequestDialog extends React.Component { verificationRequest: PropTypes.object, verificationRequestPromise: PropTypes.object, onFinished: PropTypes.func.isRequired, + member: PropTypes.string, }; constructor(...args) { super(...args); - this.onFinished = this.onFinished.bind(this); this.state = {}; if (this.props.verificationRequest) { this.state.verificationRequest = this.props.verificationRequest; @@ -50,7 +50,7 @@ export default class VerificationRequestDialog extends React.Component { const title = request && request.isSelfVerification ? _t("Verify other session") : _t("Verification Request"); - return ; } - - async onFinished() { - this.props.onFinished(); - let request = this.props.verificationRequest; - if (!request && this.props.verificationRequestPromise) { - request = await this.props.verificationRequestPromise; - } - request.cancel(); - } } From 5b48e13eb91760bd71b088d93da29e9e291301a9 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 04:46:15 +0000 Subject: [PATCH 41/91] add explicit link to edit devices from one's own UserInfo --- src/components/views/right_panel/UserInfo.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/components/views/right_panel/UserInfo.tsx b/src/components/views/right_panel/UserInfo.tsx index a4b5cd0fbb..ea8c467d13 100644 --- a/src/components/views/right_panel/UserInfo.tsx +++ b/src/components/views/right_panel/UserInfo.tsx @@ -46,6 +46,7 @@ import EncryptionPanel from "./EncryptionPanel"; import {useAsyncMemo} from '../../../hooks/useAsyncMemo'; import {legacyVerifyUser, verifyDevice, verifyUser} from '../../../verification'; import {Action} from "../../../dispatcher/actions"; +import { USER_SECURITY_TAB } from "../dialogs/UserSettingsDialog"; import {useIsEncrypted} from "../../../hooks/useIsEncrypted"; import BaseCard from "./BaseCard"; import {E2EStatus} from "../../../utils/ShieldUtils"; @@ -1362,6 +1363,20 @@ const BasicUserInfo: React.FC<{ } } + let editDevices; + if (member.userId == cli.getUserId()) { + editDevices = (

+ { + dis.dispatch({ + action: Action.ViewUserSettings, + initialTabId: USER_SECURITY_TAB, + }); + }}> + { _t("Edit devices") } + +

) + } + const securitySection = (

{ _t("Security") }

@@ -1371,6 +1386,7 @@ const BasicUserInfo: React.FC<{ loading={showDeviceListSpinner} devices={devices} userId={member.userId} /> } + { editDevices }
); From aa0cca9306f2e56f134a82937c87e397346cd8b9 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 04:46:47 +0000 Subject: [PATCH 42/91] report IP of self-verification reqs --- .../views/toasts/VerificationRequestToast.tsx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/components/views/toasts/VerificationRequestToast.tsx b/src/components/views/toasts/VerificationRequestToast.tsx index 8c8a74b2be..73440eb822 100644 --- a/src/components/views/toasts/VerificationRequestToast.tsx +++ b/src/components/views/toasts/VerificationRequestToast.tsx @@ -38,6 +38,7 @@ interface IProps { interface IState { counter: number; device?: DeviceInfo; + IP?: string; } export default class VerificationRequestToast extends React.PureComponent { @@ -66,9 +67,15 @@ export default class VerificationRequestToast extends React.PureComponent { + request.cancel(); + }, }, null, /* priority = */ false, /* static = */ true); } await request.accept(); @@ -131,9 +141,10 @@ export default class VerificationRequestToast extends React.PureComponent Date: Mon, 8 Mar 2021 04:49:59 +0000 Subject: [PATCH 43/91] only prompt to verify if we have an MSK or we have devices to verify against --- src/stores/SetupEncryptionStore.js | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/stores/SetupEncryptionStore.js b/src/stores/SetupEncryptionStore.js index 981ce6eca9..525678f9a3 100644 --- a/src/stores/SetupEncryptionStore.js +++ b/src/stores/SetupEncryptionStore.js @@ -49,6 +49,7 @@ export class SetupEncryptionStore extends EventEmitter { cli.on("crypto.verification.request", this.onVerificationRequest); cli.on('userTrustStatusChanged', this._onUserTrustStatusChanged); + const requestsInProgress = cli.getVerificationRequestsToDeviceInProgress(cli.getUserId()); if (requestsInProgress.length) { // If there are multiple, we take the most recent. Equally if the user sends another request from @@ -75,7 +76,8 @@ export class SetupEncryptionStore extends EventEmitter { } async fetchKeyInfo() { - const keys = await MatrixClientPeg.get().isSecretStored('m.cross_signing.master', false); + const cli = MatrixClientPeg.get(); + const keys = await cli.isSecretStored('m.cross_signing.master', false); if (keys === null || Object.keys(keys).length === 0) { this.keyId = null; this.keyInfo = null; @@ -85,7 +87,22 @@ export class SetupEncryptionStore extends EventEmitter { this.keyInfo = keys[this.keyId]; } - this.phase = PHASE_INTRO; + // do we have any other devices which are E2EE which we can verify against? + const dehydratedDevice = await cli.getDehydratedDevice(); + this.hasDevicesToVerifyAgainst = cli.getStoredDevicesForUser(cli.getUserId()).some( + device => + device.getIdentityKey() && + (!dehydratedDevice || (device.deviceId != dehydratedDevice.device_id)) + ); + + if (!this.hasDevicesToVerifyAgainst && !this.keyInfo) { + // skip before we can even render anything. + // XXX: this causes a dialog box flash + this.phase = PHASE_FINISHED; + } + else { + this.phase = PHASE_INTRO; + } this.emit("update"); } From c73097a5b0d48e648ffaae8b74b5949b4773335b Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 04:51:16 +0000 Subject: [PATCH 44/91] fix unhelpful 'Review...' toast wording --- src/toasts/BulkUnverifiedSessionsToast.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/toasts/BulkUnverifiedSessionsToast.ts b/src/toasts/BulkUnverifiedSessionsToast.ts index 41717e0804..bc129ebd54 100644 --- a/src/toasts/BulkUnverifiedSessionsToast.ts +++ b/src/toasts/BulkUnverifiedSessionsToast.ts @@ -39,7 +39,7 @@ export const showToast = (deviceIds: Set) => { ToastStore.sharedInstance().addOrReplaceToast({ key: TOAST_KEY, - title: _t("Review where you’re logged in"), + title: _t("You have unverified logins"), icon: "verification_warning", props: { description: _t("Verify all your sessions to ensure your account & messages are safe"), From 96ebbad959bf3a169a2d8911fba585bb61360919 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 04:54:44 +0000 Subject: [PATCH 45/91] switch UnverifiedSessionToast to route to check sessions rather than verify the new login given the chances are that the new login will be stuck doing initial sync, and won't be in position to be verified until its finished. --- src/i18n/strings/en_EN.json | 17 +++++++-------- src/toasts/UnverifiedSessionToast.ts | 31 +++++++++++++++------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index e8a4b86c77..0b6f68a738 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -725,7 +725,7 @@ "Send anonymous usage data which helps us improve %(brand)s. This will use a cookie.": "Send anonymous usage data which helps us improve %(brand)s. This will use a cookie.", "Yes": "Yes", "No": "No", - "Review where you’re logged in": "Review where you’re logged in", + "You have unverified logins": "You have unverified logins", "Verify all your sessions to ensure your account & messages are safe": "Verify all your sessions to ensure your account & messages are safe", "Review": "Review", "Later": "Later", @@ -749,7 +749,8 @@ "Safeguard against losing access to encrypted messages & data": "Safeguard against losing access to encrypted messages & data", "Other users may not trust it": "Other users may not trust it", "New login. Was this you?": "New login. Was this you?", - "Verify the new login accessing your account: %(name)s": "Verify the new login accessing your account: %(name)s", + "A new login is accessing your account: %(name)s (%(deviceID)s) from %(IP)s": "A new login is accessing your account: %(name)s (%(deviceID)s) from %(IP)s", + "Check your devices": "Check your devices", "What's new?": "What's new?", "What's New": "What's New", "Update": "Update", @@ -974,7 +975,7 @@ "Folder": "Folder", "Pin": "Pin", "Your server isn't responding to some requests.": "Your server isn't responding to some requests.", - "From %(deviceName)s (%(deviceId)s)": "From %(deviceName)s (%(deviceId)s)", + "From %(deviceName)s (%(deviceId)s) from %(IP)s": "From %(deviceName)s (%(deviceId)s) from %(IP)s", "Decline (%(counter)s)": "Decline (%(counter)s)", "Accept to continue:": "Accept to continue:", "Remove": "Remove", @@ -1711,6 +1712,7 @@ "Failed to deactivate user": "Failed to deactivate user", "Role": "Role", "This client does not support end-to-end encryption.": "This client does not support end-to-end encryption.", + "Edit devices": "Edit devices", "Security": "Security", "The session you are trying to verify doesn't support scanning a QR code or emoji verification, which is what %(brand)s supports. Try with a different client.": "The session you are trying to verify doesn't support scanning a QR code or emoji verification, which is what %(brand)s supports. Try with a different client.", "Verify by scanning": "Verify by scanning", @@ -2611,13 +2613,8 @@ "Decide where your account is hosted": "Decide where your account is hosted", "Use Security Key or Phrase": "Use Security Key or Phrase", "Use Security Key": "Use Security Key", - "Confirm your identity by verifying this login from one of your other sessions, granting it access to encrypted messages.": "Confirm your identity by verifying this login from one of your other sessions, granting it access to encrypted messages.", - "This requires the latest %(brand)s on your other devices:": "This requires the latest %(brand)s on your other devices:", - "%(brand)s Web": "%(brand)s Web", - "%(brand)s Desktop": "%(brand)s Desktop", - "%(brand)s iOS": "%(brand)s iOS", - "%(brand)s Android": "%(brand)s Android", - "or another cross-signing capable Matrix client": "or another cross-signing capable Matrix client", + "Verify against another session": "Verify against another session", + "Verify this login to access your encrypted messages and prove to others that this login is really you.": "Verify this login to access your encrypted messages and prove to others that this login is really you.", "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.": "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.", "Your new session is now verified. Other users will see it as trusted.": "Your new session is now verified. Other users will see it as trusted.", "Without completing security on this session, it won’t have access to encrypted messages.": "Without completing security on this session, it won’t have access to encrypted messages.", diff --git a/src/toasts/UnverifiedSessionToast.ts b/src/toasts/UnverifiedSessionToast.ts index 9dedd2b137..32635e689a 100644 --- a/src/toasts/UnverifiedSessionToast.ts +++ b/src/toasts/UnverifiedSessionToast.ts @@ -15,38 +15,36 @@ limitations under the License. */ import { _t } from '../languageHandler'; +import dis from "../dispatcher/dispatcher"; import { MatrixClientPeg } from '../MatrixClientPeg'; import Modal from '../Modal'; import DeviceListener from '../DeviceListener'; import NewSessionReviewDialog from '../components/views/dialogs/NewSessionReviewDialog'; import ToastStore from "../stores/ToastStore"; import GenericToast from "../components/views/toasts/GenericToast"; +import { Action } from "../dispatcher/actions"; +import { USER_SECURITY_TAB } from "../components/views/dialogs/UserSettingsDialog"; function toastKey(deviceId: string) { return "unverified_session_" + deviceId; } -export const showToast = (deviceId: string) => { +export const showToast = async (deviceId: string) => { const cli = MatrixClientPeg.get(); const onAccept = () => { - Modal.createTrackedDialog('New Session Review', 'Starting dialog', NewSessionReviewDialog, { - userId: cli.getUserId(), - device: cli.getStoredDevice(cli.getUserId(), deviceId), - onFinished: (r) => { - if (!r) { - /* This'll come back false if the user clicks "this wasn't me" and saw a warning dialog */ - DeviceListener.sharedInstance().dismissUnverifiedSessions([deviceId]); - } - }, - }, null, /* priority = */ false, /* static = */ true); + DeviceListener.sharedInstance().dismissUnverifiedSessions([deviceId]); + dis.dispatch({ + action: Action.ViewUserSettings, + initialTabId: USER_SECURITY_TAB, + }); }; const onReject = () => { DeviceListener.sharedInstance().dismissUnverifiedSessions([deviceId]); }; - const device = cli.getStoredDevice(cli.getUserId(), deviceId); + const device = await cli.getDevice(deviceId); ToastStore.sharedInstance().addOrReplaceToast({ key: toastKey(deviceId), @@ -54,8 +52,13 @@ export const showToast = (deviceId: string) => { icon: "verification_warning", props: { description: _t( - "Verify the new login accessing your account: %(name)s", { name: device.getDisplayName()}), - acceptLabel: _t("Verify"), + "A new login is accessing your account: %(name)s (%(deviceID)s) from %(IP)s", { + name: device.display_name, + deviceID: deviceId, + IP: device.last_seen_ip, + } + ), + acceptLabel: _t("Check your devices"), onAccept, rejectLabel: _t("Later"), onReject, From 997d6e12811015f3c60d3813f1018fd9d5ac10e8 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 05:08:01 +0000 Subject: [PATCH 46/91] lint --- src/components/structures/auth/SetupEncryptionBody.js | 4 +--- src/stores/SetupEncryptionStore.js | 5 ++--- src/toasts/UnverifiedSessionToast.ts | 10 ++++------ 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/components/structures/auth/SetupEncryptionBody.js b/src/components/structures/auth/SetupEncryptionBody.js index d2b3fbd3b9..d40192f9c1 100644 --- a/src/components/structures/auth/SetupEncryptionBody.js +++ b/src/components/structures/auth/SetupEncryptionBody.js @@ -157,13 +157,11 @@ export default class SetupEncryptionBody extends React.Component {
; } - const brand = SdkConfig.get().brand; - return (

{_t( "Verify this login to access your encrypted messages and " + - "prove to others that this login is really you." + "prove to others that this login is really you.", )}

diff --git a/src/stores/SetupEncryptionStore.js b/src/stores/SetupEncryptionStore.js index 525678f9a3..fdabfa8019 100644 --- a/src/stores/SetupEncryptionStore.js +++ b/src/stores/SetupEncryptionStore.js @@ -92,15 +92,14 @@ export class SetupEncryptionStore extends EventEmitter { this.hasDevicesToVerifyAgainst = cli.getStoredDevicesForUser(cli.getUserId()).some( device => device.getIdentityKey() && - (!dehydratedDevice || (device.deviceId != dehydratedDevice.device_id)) + (!dehydratedDevice || (device.deviceId != dehydratedDevice.device_id)), ); if (!this.hasDevicesToVerifyAgainst && !this.keyInfo) { // skip before we can even render anything. // XXX: this causes a dialog box flash this.phase = PHASE_FINISHED; - } - else { + } else { this.phase = PHASE_INTRO; } this.emit("update"); diff --git a/src/toasts/UnverifiedSessionToast.ts b/src/toasts/UnverifiedSessionToast.ts index 32635e689a..d375ef6112 100644 --- a/src/toasts/UnverifiedSessionToast.ts +++ b/src/toasts/UnverifiedSessionToast.ts @@ -17,9 +17,7 @@ limitations under the License. import { _t } from '../languageHandler'; import dis from "../dispatcher/dispatcher"; import { MatrixClientPeg } from '../MatrixClientPeg'; -import Modal from '../Modal'; import DeviceListener from '../DeviceListener'; -import NewSessionReviewDialog from '../components/views/dialogs/NewSessionReviewDialog'; import ToastStore from "../stores/ToastStore"; import GenericToast from "../components/views/toasts/GenericToast"; import { Action } from "../dispatcher/actions"; @@ -53,10 +51,10 @@ export const showToast = async (deviceId: string) => { props: { description: _t( "A new login is accessing your account: %(name)s (%(deviceID)s) from %(IP)s", { - name: device.display_name, - deviceID: deviceId, - IP: device.last_seen_ip, - } + name: device.display_name, + deviceID: deviceId, + IP: device.last_seen_ip, + }, ), acceptLabel: _t("Check your devices"), onAccept, From 7abc48a71679de4afa37fe73d8edf966f29af43e Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 05:30:02 +0000 Subject: [PATCH 47/91] lint --- src/components/structures/auth/SetupEncryptionBody.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/structures/auth/SetupEncryptionBody.js b/src/components/structures/auth/SetupEncryptionBody.js index d40192f9c1..4e3d106eb1 100644 --- a/src/components/structures/auth/SetupEncryptionBody.js +++ b/src/components/structures/auth/SetupEncryptionBody.js @@ -17,7 +17,6 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import { _t } from '../../../languageHandler'; -import SdkConfig from '../../../SdkConfig'; import { MatrixClientPeg } from '../../../MatrixClientPeg'; import Modal from '../../../Modal'; import VerificationRequestDialog from '../../views/dialogs/VerificationRequestDialog'; From 6a5efad1424c7b4accbfb4f83ec0f37b728c5f0c Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 8 Mar 2021 15:52:21 +0000 Subject: [PATCH 48/91] Show suggested rooms from the selected space --- src/components/views/rooms/RoomList.tsx | 74 +++++++++++++++++++- src/components/views/rooms/TemporaryTile.tsx | 19 ++--- src/i18n/strings/en_EN.json | 2 + src/stores/SpaceStore.tsx | 33 ++++++++- src/stores/room-list/models.ts | 2 + 5 files changed, 116 insertions(+), 14 deletions(-) diff --git a/src/components/views/rooms/RoomList.tsx b/src/components/views/rooms/RoomList.tsx index f7da6571da..beb85e50ce 100644 --- a/src/components/views/rooms/RoomList.tsx +++ b/src/components/views/rooms/RoomList.tsx @@ -19,6 +19,7 @@ limitations under the License. import * as React from "react"; import { Dispatcher } from "flux"; import { Room } from "matrix-js-sdk/src/models/room"; +import * as fbEmitter from "fbemitter"; import { _t, _td } from "../../../languageHandler"; import { RovingTabIndexProvider } from "../../../accessibility/RovingTabIndex"; @@ -47,9 +48,11 @@ import { IconizedContextMenuOption, IconizedContextMenuOptionList } from "../con import AccessibleButton from "../elements/AccessibleButton"; import { CommunityPrototypeStore } from "../../../stores/CommunityPrototypeStore"; import CallHandler from "../../../CallHandler"; -import SpaceStore from "../../../stores/SpaceStore"; +import SpaceStore, { SUGGESTED_ROOMS } from "../../../stores/SpaceStore"; import { showAddExistingRooms, showCreateNewRoom } from "../../../utils/space"; import { EventType } from "matrix-js-sdk/src/@types/event"; +import { ISpaceSummaryRoom } from "../../structures/SpaceRoomDirectory"; +import RoomAvatar from "../avatars/RoomAvatar"; interface IProps { onKeyDown: (ev: React.KeyboardEvent) => void; @@ -63,6 +66,8 @@ interface IProps { interface IState { sublists: ITagMap; isNameFiltering: boolean; + currentRoomId?: string; + suggestedRooms: ISpaceSummaryRoom[]; } const TAG_ORDER: TagID[] = [ @@ -75,6 +80,7 @@ const TAG_ORDER: TagID[] = [ DefaultTagID.LowPriority, DefaultTagID.ServerNotice, + DefaultTagID.Suggested, DefaultTagID.Archived, ]; const CUSTOM_TAGS_BEFORE_TAG = DefaultTagID.LowPriority; @@ -242,6 +248,12 @@ const TAG_AESTHETICS: ITagAestheticsMap = { isInvite: false, defaultHidden: true, }, + + [DefaultTagID.Suggested]: { + sectionLabel: _td("Suggested Rooms"), + isInvite: false, + defaultHidden: false, + }, }; function customTagAesthetics(tagId: TagID): ITagAesthetics { @@ -260,6 +272,7 @@ export default class RoomList extends React.PureComponent { private dispatcherRef; private customTagStoreRef; private tagAesthetics: ITagAestheticsMap; + private roomStoreToken: fbEmitter.EventSubscription; constructor(props: IProps) { super(props); @@ -267,6 +280,7 @@ export default class RoomList extends React.PureComponent { this.state = { sublists: {}, isNameFiltering: !!RoomListStore.instance.getFirstNameFilterCondition(), + suggestedRooms: SpaceStore.instance.suggestedRooms, }; // shallow-copy from the template as we need to make modifications to it @@ -274,20 +288,30 @@ export default class RoomList extends React.PureComponent { this.updateDmAddRoomAction(); this.dispatcherRef = defaultDispatcher.register(this.onAction); + this.roomStoreToken = RoomViewStore.addListener(this.onRoomViewStoreUpdate); } public componentDidMount(): void { + SpaceStore.instance.on(SUGGESTED_ROOMS, this.updateSuggestedRooms); RoomListStore.instance.on(LISTS_UPDATE_EVENT, this.updateLists); this.customTagStoreRef = CustomRoomTagStore.addListener(this.updateLists); this.updateLists(); // trigger the first update } public componentWillUnmount() { + SpaceStore.instance.off(SUGGESTED_ROOMS, this.updateSuggestedRooms); RoomListStore.instance.off(LISTS_UPDATE_EVENT, this.updateLists); defaultDispatcher.unregister(this.dispatcherRef); if (this.customTagStoreRef) this.customTagStoreRef.remove(); + if (this.roomStoreToken) this.roomStoreToken.remove(); } + private onRoomViewStoreUpdate = () => { + this.setState({ + currentRoomId: RoomViewStore.getRoomId(), + }); + }; + private updateDmAddRoomAction() { const dmTagAesthetics = objectShallowClone(TAG_AESTHETICS[DefaultTagID.DM]); if (CallHandler.sharedInstance().getSupportsPstnProtocol()) { @@ -319,7 +343,7 @@ export default class RoomList extends React.PureComponent { private getRoomDelta = (roomId: string, delta: number, unread = false) => { const lists = RoomListStore.instance.orderedLists; - const rooms: Room = []; + const rooms: Room[] = []; TAG_ORDER.forEach(t => { let listRooms = lists[t]; @@ -340,6 +364,10 @@ export default class RoomList extends React.PureComponent { return room; }; + private updateSuggestedRooms = (suggestedRooms: ISpaceSummaryRoom[]) => { + this.setState({ suggestedRooms }); + }; + private updateLists = () => { const newLists = RoomListStore.instance.orderedLists; if (SettingsStore.getValue("advancedRoomListLogging")) { @@ -394,6 +422,39 @@ export default class RoomList extends React.PureComponent { dis.dispatch({ action: Action.ViewRoomDirectory, initialText }); }; + private renderSuggestedRooms(): JSX.Element[] { + return this.state.suggestedRooms.map(room => { + const name = room.name || room.canonical_alias || room.aliases.pop() || _t("Empty room"); + const avatar = ( + + ); + const viewRoom = () => { + defaultDispatcher.dispatch({ + action: "view_room", + room_id: room.room_id, + }); + }; + return ( + + ); + }); + } + private renderCommunityInvites(): TemporaryTile[] { // TODO: Put community invites in a more sensible place (not in the room list) // See https://github.com/vector-im/element-web/issues/14456 @@ -447,7 +508,14 @@ export default class RoomList extends React.PureComponent { for (const orderedTagId of tagOrder) { const orderedRooms = this.state.sublists[orderedTagId] || []; - const extraTiles = orderedTagId === DefaultTagID.Invite ? this.renderCommunityInvites() : null; + + let extraTiles = null; + if (orderedTagId === DefaultTagID.Invite) { + extraTiles = this.renderCommunityInvites(); + } else if (orderedTagId === DefaultTagID.Suggested) { + extraTiles = this.renderSuggestedRooms(); + } + const totalTiles = orderedRooms.length + (extraTiles ? extraTiles.length : 0); if (totalTiles === 0 && !ALWAYS_VISIBLE_TAGS.includes(orderedTagId)) { continue; // skip tag - not needed diff --git a/src/components/views/rooms/TemporaryTile.tsx b/src/components/views/rooms/TemporaryTile.tsx index eec3105880..31d2acbc61 100644 --- a/src/components/views/rooms/TemporaryTile.tsx +++ b/src/components/views/rooms/TemporaryTile.tsx @@ -28,7 +28,7 @@ interface IProps { isSelected: boolean; displayName: string; avatar: React.ReactElement; - notificationState: NotificationState; + notificationState?: NotificationState; onClick: () => void; } @@ -63,12 +63,15 @@ export default class TemporaryTile extends React.Component { 'mx_RoomTile_minimized': this.props.isMinimized, }); - const badge = ( - - ); + let badge; + if (this.props.notificationState) { + badge = ( + + ); + } let name = this.props.displayName; if (typeof name !== 'string') name = ''; @@ -76,7 +79,7 @@ export default class TemporaryTile extends React.Component { const nameClasses = classNames({ "mx_RoomTile_name": true, - "mx_RoomTile_nameHasUnreadEvents": this.props.notificationState.isUnread, + "mx_RoomTile_nameHasUnreadEvents": this.props.notificationState?.isUnread, }); let nameContainer = ( diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 7b680b6590..71aae7fecd 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1529,7 +1529,9 @@ "Low priority": "Low priority", "System Alerts": "System Alerts", "Historical": "Historical", + "Suggested Rooms": "Suggested Rooms", "Custom Tag": "Custom Tag", + "Empty room": "Empty room", "Can't see what you’re looking for?": "Can't see what you’re looking for?", "Start a new chat": "Start a new chat", "Explore all public rooms": "Explore all public rooms", diff --git a/src/stores/SpaceStore.tsx b/src/stores/SpaceStore.tsx index c334144d70..1ada5d6361 100644 --- a/src/stores/SpaceStore.tsx +++ b/src/stores/SpaceStore.tsx @@ -14,8 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {throttle, sortBy} from "lodash"; -import {EventType} from "matrix-js-sdk/src/@types/event"; +import {sortBy, throttle} from "lodash"; +import {EventType, RoomType} from "matrix-js-sdk/src/@types/event"; import {Room} from "matrix-js-sdk/src/models/room"; import {MatrixEvent} from "matrix-js-sdk/src/models/event"; @@ -33,6 +33,7 @@ import {EnhancedMap, mapDiff} from "../utils/maps"; import {setHasDiff} from "../utils/sets"; import {objectDiff} from "../utils/objects"; import {arrayHasDiff} from "../utils/arrays"; +import {ISpaceSummaryEvent, ISpaceSummaryRoom} from "../components/structures/SpaceRoomDirectory"; type SpaceKey = string | symbol; @@ -41,11 +42,14 @@ interface IState {} const ACTIVE_SPACE_LS_KEY = "mx_active_space"; export const HOME_SPACE = Symbol("home-space"); +export const SUGGESTED_ROOMS = Symbol("suggested-rooms"); export const UPDATE_TOP_LEVEL_SPACES = Symbol("top-level-spaces"); export const UPDATE_SELECTED_SPACE = Symbol("selected-space"); // Space Room ID/HOME_SPACE will be emitted when a Space's children change +const MAX_SUGGESTED_ROOMS = 20; + const partitionSpacesAndRooms = (arr: Room[]): [Room[], Room[]] => { // [spaces, rooms] return arr.reduce((result, room: Room) => { result[room.isSpaceRoom() ? 0 : 1].push(room); @@ -85,6 +89,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient { private spaceFilteredRooms = new Map>(); // The space currently selected in the Space Panel - if null then `Home` is selected private _activeSpace?: Room = null; + private _suggestedRooms: ISpaceSummaryRoom[] = []; public get spacePanelSpaces(): Room[] { return this.rootSpaces; @@ -94,11 +99,16 @@ export class SpaceStoreClass extends AsyncStoreWithClient { return this._activeSpace || null; } - public setActiveSpace(space: Room | null) { + public get suggestedRooms(): ISpaceSummaryRoom[] { + return this._suggestedRooms; + } + + public async setActiveSpace(space: Room | null) { if (space === this.activeSpace) return; this._activeSpace = space; this.emit(UPDATE_SELECTED_SPACE, this.activeSpace); + this.emit(SUGGESTED_ROOMS, this._suggestedRooms = []); // persist space selected if (space) { @@ -106,6 +116,23 @@ export class SpaceStoreClass extends AsyncStoreWithClient { } else { window.localStorage.removeItem(ACTIVE_SPACE_LS_KEY); } + + if (space) { + try { + const data: { + rooms: ISpaceSummaryRoom[]; + events: ISpaceSummaryEvent[]; + } = await this.matrixClient.getSpaceSummary(space.roomId, 0, true, false, MAX_SUGGESTED_ROOMS); + if (this._activeSpace === space) { + this._suggestedRooms = data.rooms.filter(roomInfo => { + return roomInfo.room_type !== RoomType.Space && !this.matrixClient.getRoom(roomInfo.room_id); + }); + this.emit(SUGGESTED_ROOMS, this._suggestedRooms); + } + } catch (e) { + console.error(e); + } + } } public addRoomToSpace(space: Room, roomId: string, via: string[], suggested = false, autoJoin = false) { diff --git a/src/stores/room-list/models.ts b/src/stores/room-list/models.ts index 7d3902f552..54d49ea18a 100644 --- a/src/stores/room-list/models.ts +++ b/src/stores/room-list/models.ts @@ -24,6 +24,7 @@ export enum DefaultTagID { Favourite = "m.favourite", DM = "im.vector.fake.direct", ServerNotice = "m.server_notice", + Suggested = "im.vector.fake.suggested", } export const OrderedDefaultTagIDs = [ @@ -33,6 +34,7 @@ export const OrderedDefaultTagIDs = [ DefaultTagID.Untagged, DefaultTagID.LowPriority, DefaultTagID.ServerNotice, + DefaultTagID.Suggested, DefaultTagID.Archived, ]; From 1629b7e62a3179ca756717bd60cf25746871b16d Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 16:44:14 +0000 Subject: [PATCH 49/91] s/IP/ip/; s/from/at/ --- .../views/toasts/VerificationRequestToast.tsx | 10 +++++----- src/i18n/strings/en_EN.json | 4 ++-- src/toasts/UnverifiedSessionToast.ts | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/components/views/toasts/VerificationRequestToast.tsx b/src/components/views/toasts/VerificationRequestToast.tsx index 73440eb822..82c6b0b952 100644 --- a/src/components/views/toasts/VerificationRequestToast.tsx +++ b/src/components/views/toasts/VerificationRequestToast.tsx @@ -38,7 +38,7 @@ interface IProps { interface IState { counter: number; device?: DeviceInfo; - IP?: string; + ip?: string; } export default class VerificationRequestToast extends React.PureComponent { @@ -71,10 +71,10 @@ export default class VerificationRequestToast extends React.PureComponentrequests.": "Your server isn't responding to some requests.", - "From %(deviceName)s (%(deviceId)s) from %(IP)s": "From %(deviceName)s (%(deviceId)s) from %(IP)s", + "From %(deviceName)s (%(deviceId)s) at %(ip)s": "From %(deviceName)s (%(deviceId)s) at %(ip)s", "Decline (%(counter)s)": "Decline (%(counter)s)", "Accept to continue:": "Accept to continue:", "Delete": "Delete", diff --git a/src/toasts/UnverifiedSessionToast.ts b/src/toasts/UnverifiedSessionToast.ts index d375ef6112..e0ea323033 100644 --- a/src/toasts/UnverifiedSessionToast.ts +++ b/src/toasts/UnverifiedSessionToast.ts @@ -50,10 +50,10 @@ export const showToast = async (deviceId: string) => { icon: "verification_warning", props: { description: _t( - "A new login is accessing your account: %(name)s (%(deviceID)s) from %(IP)s", { + "A new login is accessing your account: %(name)s (%(deviceID)s) at %(ip)s", { name: device.display_name, deviceID: deviceId, - IP: device.last_seen_ip, + ip: device.last_seen_ip, }, ), acceptLabel: _t("Check your devices"), From 14b828ecc63652d7aac081c28bafd07fa8119d61 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 17:58:30 +0000 Subject: [PATCH 50/91] shorten verify button label --- src/components/structures/auth/SetupEncryptionBody.js | 2 +- src/i18n/strings/en_EN.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/structures/auth/SetupEncryptionBody.js b/src/components/structures/auth/SetupEncryptionBody.js index 4e3d106eb1..431762cade 100644 --- a/src/components/structures/auth/SetupEncryptionBody.js +++ b/src/components/structures/auth/SetupEncryptionBody.js @@ -152,7 +152,7 @@ export default class SetupEncryptionBody extends React.Component { let verifyButton; if (store.hasDevicesToVerifyAgainst) { verifyButton = - { _t("Verify against another session") } + { _t("Verify with another session") } ; } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 98a0ceb5d1..68664fa0dd 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2714,7 +2714,7 @@ "Decide where your account is hosted": "Decide where your account is hosted", "Use Security Key or Phrase": "Use Security Key or Phrase", "Use Security Key": "Use Security Key", - "Verify against another session": "Verify against another session", + "Verify with another session": "Verify with another session", "Verify this login to access your encrypted messages and prove to others that this login is really you.": "Verify this login to access your encrypted messages and prove to others that this login is really you.", "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.": "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.", "Your new session is now verified. Other users will see it as trusted.": "Your new session is now verified. Other users will see it as trusted.", From b3cd6fcc9bf11d5070dd5697ee8756dc6bde34f2 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 17:59:02 +0000 Subject: [PATCH 51/91] vertically align labels in AccessibleButtons if their height is pushed out by wrapped text elsewhere --- res/css/views/elements/_AccessibleButton.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/res/css/views/elements/_AccessibleButton.scss b/res/css/views/elements/_AccessibleButton.scss index 9c26f8f120..b115130c8f 100644 --- a/res/css/views/elements/_AccessibleButton.scss +++ b/res/css/views/elements/_AccessibleButton.scss @@ -26,7 +26,8 @@ limitations under the License. padding: 7px 18px; text-align: center; border-radius: 8px; - display: inline-block; + display: flex; + align-items: center; font-size: $font-14px; } From 9d99b2f239e1bb6c7179239aa0729bbac122f987 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 17:59:10 +0000 Subject: [PATCH 52/91] remove errand whitespace --- src/stores/SetupEncryptionStore.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/stores/SetupEncryptionStore.js b/src/stores/SetupEncryptionStore.js index fdabfa8019..2ed778b294 100644 --- a/src/stores/SetupEncryptionStore.js +++ b/src/stores/SetupEncryptionStore.js @@ -49,7 +49,6 @@ export class SetupEncryptionStore extends EventEmitter { cli.on("crypto.verification.request", this.onVerificationRequest); cli.on('userTrustStatusChanged', this._onUserTrustStatusChanged); - const requestsInProgress = cli.getVerificationRequestsToDeviceInProgress(cli.getUserId()); if (requestsInProgress.length) { // If there are multiple, we take the most recent. Equally if the user sends another request from From c543f0a2d0d7178e6c7efb271315c674b443fb28 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 22:29:08 +0000 Subject: [PATCH 53/91] fix AccessibleButton label positioning now they can wrap --- res/css/views/elements/_AccessibleButton.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/res/css/views/elements/_AccessibleButton.scss b/res/css/views/elements/_AccessibleButton.scss index b115130c8f..e13f765e63 100644 --- a/res/css/views/elements/_AccessibleButton.scss +++ b/res/css/views/elements/_AccessibleButton.scss @@ -28,6 +28,7 @@ limitations under the License. border-radius: 8px; display: flex; align-items: center; + justify-content: center; font-size: $font-14px; } From bb8fe62c5c77ebaa407e42b2fdb8f5228911a29a Mon Sep 17 00:00:00 2001 From: "@a2sc:matrix.org" Date: Mon, 8 Mar 2021 23:11:44 +0000 Subject: [PATCH 54/91] Translated using Weblate (German) Currently translated at 99.5% (2767 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 07a1a4f805..7304d35fcd 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -1433,7 +1433,7 @@ "Never send encrypted messages to unverified sessions in this room from this session": "Sende niemals verschlüsselte Nachrichten von dieser Sitzung zu unverifizierten Sitzungen in diesem Raum", "Changing password will currently reset any end-to-end encryption keys on all sessions, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Durch die Änderung des Passworts werden derzeit alle Ende-zu-Ende-Verschlüsselungsschlüssel in allen Sitzungen zurückgesetzt, sodass der verschlüsselte Chat-Verlauf nicht mehr lesbar ist, es sei denn, du exportierst zuerst deine Raumschlüssel und importierst sie anschließend wieder. In Zukunft wird dies verbessert werden.", "Delete %(count)s sessions|other": "%(count)s Sitzungen löschen", - "Backup is not signed by any of your sessions": "Die Sicherung wurde von keiner deiner Sitzungen unterzeichnet", + "Backup is not signed by any of your sessions": "Die Sicherung wurde von keiner deiner Sitzungen bestätigt", "Your password was successfully changed. You will not receive push notifications on other sessions until you log back in to them": "Dein Passwort wurde erfolgreich geändert. Du erhältst keine Push-Benachrichtigungen zu anderen Sitzungen, bis du dich wieder bei diesen anmeldest", "Notification sound": "Benachrichtigungston", "Set a new custom sound": "Setze einen neuen benutzerdefinierten Ton", @@ -2060,7 +2060,7 @@ "An error occurred changing the room's power level requirements. Ensure you have sufficient permissions and try again.": "Beim Ändern der Anforderungen für Benutzerrechte ist ein Fehler aufgetreten. Stelle sicher, dass du die nötigen Berechtigungen besitzt und versuche es erneut.", "An error occurred changing the user's power level. Ensure you have sufficient permissions and try again.": "Beim Ändern der Benutzerrechte ist ein Fehler aufgetreten. Stelle sicher, dass du die nötigen Berechtigungen besitzt und versuche es erneut.", "Unable to share email address": "E-Mail-Adresse kann nicht geteilt werden", - "Please enter verification code sent via text.": "Gib den Verifikationscode ein, den du empfangen hast.", + "Please enter verification code sent via text.": "Gib den Bestätigungscode ein, den du empfangen hast.", "Almost there! Is your other session showing the same shield?": "Fast geschafft! Zeigt deine andere Sitzung das gleiche Schild?", "Almost there! Is %(displayName)s showing the same shield?": "Fast geschafft! Wird bei %(displayName)s das gleiche Schild angezeigt?", "Click the link in the email you received to verify and then click continue again.": "Klicke auf den Link in der Bestätigungs-E-Mail, und dann auf Weiter.", @@ -3072,5 +3072,9 @@ "Failed to save settings": "Einstellungen konnten nicht gespeichert werden", "Show chat effects (animations when receiving e.g. confetti)": "Animierte Chateffekte zeigen, wenn z.B. Konfetti-Emojis erhalten werden", "Save setting values": "Einstellungswerte speichern", - "Caution:": "Vorsicht:" + "Caution:": "Vorsicht:", + "Settable at global": "Global festlegbar", + "Setting definition:": "Definition der Einstellung:", + "Value in this room": "Wert in diesem Raum", + "Settings Explorer": "Einstellungs-Explorer" } From d388f877b463cdc16dfb5e4cb0e649502871af81 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 23:28:44 +0000 Subject: [PATCH 55/91] add PHASE_LOADING to SetupEncryptionStore to avoid flashing cross-signing setup --- src/components/structures/auth/CompleteSecurity.js | 5 ++++- .../structures/auth/SetupEncryptionBody.js | 3 ++- src/stores/SetupEncryptionStore.js | 13 +++++++------ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/components/structures/auth/CompleteSecurity.js b/src/components/structures/auth/CompleteSecurity.js index c73691611d..b18776e0ea 100644 --- a/src/components/structures/auth/CompleteSecurity.js +++ b/src/components/structures/auth/CompleteSecurity.js @@ -20,6 +20,7 @@ import { _t } from '../../../languageHandler'; import * as sdk from '../../../index'; import { SetupEncryptionStore, + PHASE_LOADING, PHASE_INTRO, PHASE_BUSY, PHASE_DONE, @@ -58,7 +59,9 @@ export default class CompleteSecurity extends React.Component { let icon; let title; - if (phase === PHASE_INTRO) { + if (phase === PHASE_LOADING) { + return null; + } else if (phase === PHASE_INTRO) { icon = ; title = _t("Verify this login"); } else if (phase === PHASE_DONE) { diff --git a/src/components/structures/auth/SetupEncryptionBody.js b/src/components/structures/auth/SetupEncryptionBody.js index 431762cade..32f0f41024 100644 --- a/src/components/structures/auth/SetupEncryptionBody.js +++ b/src/components/structures/auth/SetupEncryptionBody.js @@ -23,6 +23,7 @@ import VerificationRequestDialog from '../../views/dialogs/VerificationRequestDi import * as sdk from '../../../index'; import { SetupEncryptionStore, + PHASE_LOADING, PHASE_INTRO, PHASE_BUSY, PHASE_DONE, @@ -222,7 +223,7 @@ export default class SetupEncryptionBody extends React.Component {
); - } else if (phase === PHASE_BUSY) { + } else if (phase === PHASE_BUSY || phase === PHASE_LOADING) { const Spinner = sdk.getComponent('views.elements.Spinner'); return ; } else { diff --git a/src/stores/SetupEncryptionStore.js b/src/stores/SetupEncryptionStore.js index 2ed778b294..28ab76edc0 100644 --- a/src/stores/SetupEncryptionStore.js +++ b/src/stores/SetupEncryptionStore.js @@ -19,11 +19,12 @@ import { MatrixClientPeg } from '../MatrixClientPeg'; import { accessSecretStorage, AccessCancelledError } from '../SecurityManager'; import { PHASE_DONE as VERIF_PHASE_DONE } from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest"; -export const PHASE_INTRO = 0; -export const PHASE_BUSY = 1; -export const PHASE_DONE = 2; //final done stage, but still showing UX -export const PHASE_CONFIRM_SKIP = 3; -export const PHASE_FINISHED = 4; //UX can be closed +export const PHASE_LOADING = 0; +export const PHASE_INTRO = 1; +export const PHASE_BUSY = 2; +export const PHASE_DONE = 3; //final done stage, but still showing UX +export const PHASE_CONFIRM_SKIP = 4; +export const PHASE_FINISHED = 5; //UX can be closed export class SetupEncryptionStore extends EventEmitter { static sharedInstance() { @@ -36,7 +37,7 @@ export class SetupEncryptionStore extends EventEmitter { return; } this._started = true; - this.phase = PHASE_BUSY; + this.phase = PHASE_LOADING; this.verificationRequest = null; this.backupInfo = null; From 72f28240aa7fc274e70035af24ce908633fc1630 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 23:28:54 +0000 Subject: [PATCH 56/91] fix AccessibleButton layout some more --- res/css/views/elements/_AccessibleButton.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/elements/_AccessibleButton.scss b/res/css/views/elements/_AccessibleButton.scss index e13f765e63..0075dcb511 100644 --- a/res/css/views/elements/_AccessibleButton.scss +++ b/res/css/views/elements/_AccessibleButton.scss @@ -26,7 +26,7 @@ limitations under the License. padding: 7px 18px; text-align: center; border-radius: 8px; - display: flex; + display: inline-flex; align-items: center; justify-content: center; font-size: $font-14px; From 92af111c930a067af0a287338f173cb1b876fb3e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 8 Mar 2021 19:19:52 -0700 Subject: [PATCH 57/91] Fix types for replaceableComponent This is to make it work in TS files --- src/utils/replaceableComponent.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/utils/replaceableComponent.ts b/src/utils/replaceableComponent.ts index 8c29fdf037..f8dd5f8ac6 100644 --- a/src/utils/replaceableComponent.ts +++ b/src/utils/replaceableComponent.ts @@ -30,9 +30,11 @@ import * as sdk from '../index'; * @param {string} name The dot-path name of the component being replaced. * @param {React.Component} origComponent The component that can be replaced * with a skinned version. If no skinned version is available, this component - * will be used. + * will be used. Note that this is automatically provided to the function and + * thus is optional for purposes of types. + * @returns {ClassDecorator} The decorator. */ -export function replaceableComponent(name: string, origComponent: React.Component) { +export function replaceableComponent(name: string, origComponent?: React.Component): ClassDecorator { // Decorators return a function to override the class (origComponent). This // ultimately assumes that `getComponent()` won't throw an error and instead // return a falsey value like `null` when the skin doesn't have a component. From a5f237dfd6094decab5defe71c75ba608973d262 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 8 Mar 2021 19:33:10 -0700 Subject: [PATCH 58/91] Make debugging skinning problems easier --- src/Skinner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Skinner.js b/src/Skinner.js index d17bc1782a..ef340e4052 100644 --- a/src/Skinner.js +++ b/src/Skinner.js @@ -23,7 +23,7 @@ class Skinner { if (!name) throw new Error(`Invalid component name: ${name}`); if (this.components === null) { throw new Error( - "Attempted to get a component before a skin has been loaded."+ + `Attempted to get a component (${name}) before a skin has been loaded.`+ " This is probably because either:"+ " a) Your app has not called sdk.loadSkin(), or"+ " b) A component has called getComponent at the root level", From c230a75eda74622df6b923eb6091286740094637 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 8 Mar 2021 19:35:10 -0700 Subject: [PATCH 59/91] Flag structural components as replaceable --- src/components/structures/ContextMenu.tsx | 3 +++ src/components/structures/CustomRoomTagPanel.js | 2 ++ src/components/structures/FilePanel.js | 2 ++ src/components/structures/GenericErrorPage.js | 2 ++ src/components/structures/GroupFilterPanel.js | 2 ++ src/components/structures/GroupView.js | 2 ++ src/components/structures/HostSignupAction.tsx | 2 ++ src/components/structures/IndicatorScrollbar.js | 2 ++ src/components/structures/InteractiveAuth.js | 2 ++ src/components/structures/LeftPanel.tsx | 2 ++ src/components/structures/LoggedInView.tsx | 2 ++ src/components/structures/MainSplit.js | 2 ++ src/components/structures/MatrixChat.tsx | 2 ++ src/components/structures/MessagePanel.js | 2 ++ src/components/structures/MyGroups.js | 2 ++ src/components/structures/NonUrgentToastContainer.tsx | 2 ++ src/components/structures/NotificationPanel.js | 2 ++ src/components/structures/RightPanel.js | 2 ++ src/components/structures/RoomDirectory.js | 2 ++ src/components/structures/RoomSearch.tsx | 2 ++ src/components/structures/RoomStatusBar.js | 2 ++ src/components/structures/RoomView.tsx | 2 ++ src/components/structures/ScrollPanel.js | 2 ++ src/components/structures/SearchBox.js | 2 ++ src/components/structures/TabbedView.tsx | 2 ++ src/components/structures/TimelinePanel.js | 2 ++ src/components/structures/ToastContainer.tsx | 2 ++ src/components/structures/UploadBar.tsx | 2 ++ src/components/structures/UserMenu.tsx | 2 ++ src/components/structures/UserView.js | 2 ++ src/components/structures/ViewSource.js | 2 ++ src/components/structures/auth/CompleteSecurity.js | 2 ++ src/components/structures/auth/E2eSetup.js | 2 ++ src/components/structures/auth/ForgotPassword.js | 2 ++ src/components/structures/auth/Login.tsx | 2 ++ src/components/structures/auth/Registration.tsx | 2 ++ src/components/structures/auth/SetupEncryptionBody.js | 2 ++ src/components/structures/auth/SoftLogout.js | 2 ++ 38 files changed, 77 insertions(+) diff --git a/src/components/structures/ContextMenu.tsx b/src/components/structures/ContextMenu.tsx index 726ff547ff..9d9d57d8a6 100644 --- a/src/components/structures/ContextMenu.tsx +++ b/src/components/structures/ContextMenu.tsx @@ -22,6 +22,7 @@ import classNames from "classnames"; import {Key} from "../../Keyboard"; import {Writeable} from "../../@types/common"; +import {replaceableComponent} from "../../utils/replaceableComponent"; // Shamelessly ripped off Modal.js. There's probably a better way // of doing reusable widgets like dialog boxes & menus where we go and @@ -91,6 +92,7 @@ interface IState { // Generic ContextMenu Portal wrapper // all options inside the menu should be of role=menuitem/menuitemcheckbox/menuitemradiobutton and have tabIndex={-1} // this will allow the ContextMenu to manage its own focus using arrow keys as per the ARIA guidelines. +@replaceableComponent("structures.ContextMenu") export class ContextMenu extends React.PureComponent { private initialFocus: HTMLElement; @@ -467,6 +469,7 @@ export const useContextMenu = (): ContextMenuTuple< return [isOpen, button, open, close, setIsOpen]; }; +@replaceableComponent("structures.LegacyContextMenu") export default class LegacyContextMenu extends ContextMenu { render() { return this.renderMenu(false); diff --git a/src/components/structures/CustomRoomTagPanel.js b/src/components/structures/CustomRoomTagPanel.js index a79bdafeb5..73359f17a5 100644 --- a/src/components/structures/CustomRoomTagPanel.js +++ b/src/components/structures/CustomRoomTagPanel.js @@ -21,7 +21,9 @@ import * as sdk from '../../index'; import dis from '../../dispatcher/dispatcher'; import classNames from 'classnames'; import * as FormattingUtils from '../../utils/FormattingUtils'; +import {replaceableComponent} from "../../utils/replaceableComponent"; +@replaceableComponent("structures.CustomRoomTagPanel") class CustomRoomTagPanel extends React.Component { constructor(props) { super(props); diff --git a/src/components/structures/FilePanel.js b/src/components/structures/FilePanel.js index 0e4df4621d..9f5a0b6211 100644 --- a/src/components/structures/FilePanel.js +++ b/src/components/structures/FilePanel.js @@ -26,10 +26,12 @@ import { _t } from '../../languageHandler'; import BaseCard from "../views/right_panel/BaseCard"; import {RightPanelPhases} from "../../stores/RightPanelStorePhases"; import DesktopBuildsNotice, {WarningKind} from "../views/elements/DesktopBuildsNotice"; +import {replaceableComponent} from "../../utils/replaceableComponent"; /* * Component which shows the filtered file using a TimelinePanel */ +@replaceableComponent("structures.FilePanel") class FilePanel extends React.Component { static propTypes = { roomId: PropTypes.string.isRequired, diff --git a/src/components/structures/GenericErrorPage.js b/src/components/structures/GenericErrorPage.js index ab7d4f9311..cfd2016d47 100644 --- a/src/components/structures/GenericErrorPage.js +++ b/src/components/structures/GenericErrorPage.js @@ -16,7 +16,9 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; +import {replaceableComponent} from "../../utils/replaceableComponent"; +@replaceableComponent("structures.GenericErrorPage") export default class GenericErrorPage extends React.PureComponent { static propTypes = { title: PropTypes.object.isRequired, // jsx for title diff --git a/src/components/structures/GroupFilterPanel.js b/src/components/structures/GroupFilterPanel.js index 96aa1ba728..976b2d81a5 100644 --- a/src/components/structures/GroupFilterPanel.js +++ b/src/components/structures/GroupFilterPanel.js @@ -30,7 +30,9 @@ import MatrixClientContext from "../../contexts/MatrixClientContext"; import AutoHideScrollbar from "./AutoHideScrollbar"; import SettingsStore from "../../settings/SettingsStore"; import UserTagTile from "../views/elements/UserTagTile"; +import {replaceableComponent} from "../../utils/replaceableComponent"; +@replaceableComponent("structures.GroupFilterPanel") class GroupFilterPanel extends React.Component { static contextType = MatrixClientContext; diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index bbc4187298..b4b871a0b4 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -39,6 +39,7 @@ import {Group} from "matrix-js-sdk"; import {allSettled, sleep} from "../../utils/promise"; import RightPanelStore from "../../stores/RightPanelStore"; import AutoHideScrollbar from "./AutoHideScrollbar"; +import {replaceableComponent} from "../../utils/replaceableComponent"; const LONG_DESC_PLACEHOLDER = _td( `

HTML for your community's page

@@ -391,6 +392,7 @@ class FeaturedUser extends React.Component { const GROUP_JOINPOLICY_OPEN = "open"; const GROUP_JOINPOLICY_INVITE = "invite"; +@replaceableComponent("structures.GroupView") export default class GroupView extends React.Component { static propTypes = { groupId: PropTypes.string.isRequired, diff --git a/src/components/structures/HostSignupAction.tsx b/src/components/structures/HostSignupAction.tsx index 9cf84a9379..769775d549 100644 --- a/src/components/structures/HostSignupAction.tsx +++ b/src/components/structures/HostSignupAction.tsx @@ -22,11 +22,13 @@ import { import { _t } from "../../languageHandler"; import { HostSignupStore } from "../../stores/HostSignupStore"; import SdkConfig from "../../SdkConfig"; +import {replaceableComponent} from "../../utils/replaceableComponent"; interface IProps {} interface IState {} +@replaceableComponent("structures.HostSignupAction") export default class HostSignupAction extends React.PureComponent { private openDialog = async () => { await HostSignupStore.instance.setHostSignupActive(true); diff --git a/src/components/structures/IndicatorScrollbar.js b/src/components/structures/IndicatorScrollbar.js index cd5510de9d..341ab2df71 100644 --- a/src/components/structures/IndicatorScrollbar.js +++ b/src/components/structures/IndicatorScrollbar.js @@ -17,7 +17,9 @@ limitations under the License. import React from "react"; import PropTypes from "prop-types"; import AutoHideScrollbar from "./AutoHideScrollbar"; +import {replaceableComponent} from "../../utils/replaceableComponent"; +@replaceableComponent("structures.IndicatorScrollbar") export default class IndicatorScrollbar extends React.Component { static propTypes = { // If true, the scrollbar will append mx_IndicatorScrollbar_leftOverflowIndicator diff --git a/src/components/structures/InteractiveAuth.js b/src/components/structures/InteractiveAuth.js index ac7049ed88..9b61f71fd7 100644 --- a/src/components/structures/InteractiveAuth.js +++ b/src/components/structures/InteractiveAuth.js @@ -22,9 +22,11 @@ import PropTypes from 'prop-types'; import getEntryComponentForLoginType from '../views/auth/InteractiveAuthEntryComponents'; import * as sdk from '../../index'; +import {replaceableComponent} from "../../utils/replaceableComponent"; export const ERROR_USER_CANCELLED = new Error("User cancelled auth session"); +@replaceableComponent("structures.InteractiveAuthComponent") export default class InteractiveAuthComponent extends React.Component { static propTypes = { // matrix client to use for UI auth requests diff --git a/src/components/structures/LeftPanel.tsx b/src/components/structures/LeftPanel.tsx index 82dd9443cc..88c7a71b35 100644 --- a/src/components/structures/LeftPanel.tsx +++ b/src/components/structures/LeftPanel.tsx @@ -40,6 +40,7 @@ import { MatrixClientPeg } from "../../MatrixClientPeg"; import RoomListNumResults from "../views/rooms/RoomListNumResults"; import LeftPanelWidget from "./LeftPanelWidget"; import SpacePanel from "../views/spaces/SpacePanel"; +import {replaceableComponent} from "../../utils/replaceableComponent"; interface IProps { isMinimized: boolean; @@ -60,6 +61,7 @@ const cssClasses = [ "mx_RoomSublist_showNButton", ]; +@replaceableComponent("structures.LeftPanel") export default class LeftPanel extends React.Component { private listContainerRef: React.RefObject = createRef(); private groupFilterPanelWatcherRef: string; diff --git a/src/components/structures/LoggedInView.tsx b/src/components/structures/LoggedInView.tsx index 3e6d56fd54..15e90a383a 100644 --- a/src/components/structures/LoggedInView.tsx +++ b/src/components/structures/LoggedInView.tsx @@ -56,6 +56,7 @@ import Modal from "../../Modal"; import { ICollapseConfig } from "../../resizer/distributors/collapse"; import HostSignupContainer from '../views/host_signup/HostSignupContainer'; import { IOpts } from "../../createRoom"; +import {replaceableComponent} from "../../utils/replaceableComponent"; // We need to fetch each pinned message individually (if we don't already have it) // so each pinned message may trigger a request. Limit the number per room for sanity. @@ -128,6 +129,7 @@ interface IState { * * Components mounted below us can access the matrix client via the react context. */ +@replaceableComponent("structures.LoggedInView") class LoggedInView extends React.Component { static displayName = 'LoggedInView'; diff --git a/src/components/structures/MainSplit.js b/src/components/structures/MainSplit.js index 47dfe83ad6..5818d303fc 100644 --- a/src/components/structures/MainSplit.js +++ b/src/components/structures/MainSplit.js @@ -17,7 +17,9 @@ limitations under the License. import React from 'react'; import { Resizable } from 're-resizable'; +import {replaceableComponent} from "../../utils/replaceableComponent"; +@replaceableComponent("structures.MainSplit") export default class MainSplit extends React.Component { _onResizeStart = () => { this.props.resizeNotifier.startResizing(); diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index 1700b627db..0272633e8f 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -84,6 +84,7 @@ import DialPadModal from "../views/voip/DialPadModal"; import { showToast as showMobileGuideToast } from '../../toasts/MobileGuideToast'; import SpaceStore from "../../stores/SpaceStore"; import SpaceRoomDirectory from "./SpaceRoomDirectory"; +import {replaceableComponent} from "../../utils/replaceableComponent"; /** constants for MatrixChat.state.view */ export enum Views { @@ -208,6 +209,7 @@ interface IState { roomJustCreatedOpts?: IOpts; } +@replaceableComponent("structures.MatrixChat") export default class MatrixChat extends React.PureComponent { static displayName = "MatrixChat"; diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index 9deda54bee..0f9ef70ec1 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -34,6 +34,7 @@ import {textForEvent} from "../../TextForEvent"; import IRCTimelineProfileResizer from "../views/elements/IRCTimelineProfileResizer"; import DMRoomMap from "../../utils/DMRoomMap"; import NewRoomIntro from "../views/rooms/NewRoomIntro"; +import {replaceableComponent} from "../../utils/replaceableComponent"; const CONTINUATION_MAX_INTERVAL = 5 * 60 * 1000; // 5 minutes const continuedTypes = ['m.sticker', 'm.room.message']; @@ -66,6 +67,7 @@ const isMembershipChange = (e) => e.getType() === 'm.room.member' || e.getType() /* (almost) stateless UI component which builds the event tiles in the room timeline. */ +@replaceableComponent("structures.MessagePanel") export default class MessagePanel extends React.Component { static propTypes = { // true to give the component a 'display: none' style. diff --git a/src/components/structures/MyGroups.js b/src/components/structures/MyGroups.js index e0551eecdb..2ab11dad25 100644 --- a/src/components/structures/MyGroups.js +++ b/src/components/structures/MyGroups.js @@ -24,7 +24,9 @@ import dis from '../../dispatcher/dispatcher'; import AccessibleButton from '../views/elements/AccessibleButton'; import MatrixClientContext from "../../contexts/MatrixClientContext"; import AutoHideScrollbar from "./AutoHideScrollbar"; +import {replaceableComponent} from "../../utils/replaceableComponent"; +@replaceableComponent("structures.MyGroups") export default class MyGroups extends React.Component { static contextType = MatrixClientContext; diff --git a/src/components/structures/NonUrgentToastContainer.tsx b/src/components/structures/NonUrgentToastContainer.tsx index 8d415df4dd..7c193ec9d7 100644 --- a/src/components/structures/NonUrgentToastContainer.tsx +++ b/src/components/structures/NonUrgentToastContainer.tsx @@ -18,6 +18,7 @@ import * as React from "react"; import { ComponentClass } from "../../@types/common"; import NonUrgentToastStore from "../../stores/NonUrgentToastStore"; import { UPDATE_EVENT } from "../../stores/AsyncStore"; +import {replaceableComponent} from "../../utils/replaceableComponent"; interface IProps { } @@ -26,6 +27,7 @@ interface IState { toasts: ComponentClass[], } +@replaceableComponent("structures.NonUrgentToastContainer") export default class NonUrgentToastContainer extends React.PureComponent { public constructor(props, context) { super(props, context); diff --git a/src/components/structures/NotificationPanel.js b/src/components/structures/NotificationPanel.js index b4eb6c187b..41aafc8b13 100644 --- a/src/components/structures/NotificationPanel.js +++ b/src/components/structures/NotificationPanel.js @@ -23,10 +23,12 @@ import { _t } from '../../languageHandler'; import {MatrixClientPeg} from "../../MatrixClientPeg"; import * as sdk from "../../index"; import BaseCard from "../views/right_panel/BaseCard"; +import {replaceableComponent} from "../../utils/replaceableComponent"; /* * Component which shows the global notification list using a TimelinePanel */ +@replaceableComponent("structures.NotificationPanel") class NotificationPanel extends React.Component { static propTypes = { onClose: PropTypes.func.isRequired, diff --git a/src/components/structures/RightPanel.js b/src/components/structures/RightPanel.js index 3d9df2e927..5bcb3b2450 100644 --- a/src/components/structures/RightPanel.js +++ b/src/components/structures/RightPanel.js @@ -34,7 +34,9 @@ import MatrixClientContext from "../../contexts/MatrixClientContext"; import {Action} from "../../dispatcher/actions"; import RoomSummaryCard from "../views/right_panel/RoomSummaryCard"; import WidgetCard from "../views/right_panel/WidgetCard"; +import {replaceableComponent} from "../../utils/replaceableComponent"; +@replaceableComponent("structures.RightPanel") export default class RightPanel extends React.Component { static get propTypes() { return { diff --git a/src/components/structures/RoomDirectory.js b/src/components/structures/RoomDirectory.js index 7387e1aac0..363c67262b 100644 --- a/src/components/structures/RoomDirectory.js +++ b/src/components/structures/RoomDirectory.js @@ -34,6 +34,7 @@ import GroupFilterOrderStore from "../../stores/GroupFilterOrderStore"; import GroupStore from "../../stores/GroupStore"; import FlairStore from "../../stores/FlairStore"; import CountlyAnalytics from "../../CountlyAnalytics"; +import {replaceableComponent} from "../../utils/replaceableComponent"; const MAX_NAME_LENGTH = 80; const MAX_TOPIC_LENGTH = 800; @@ -42,6 +43,7 @@ function track(action) { Analytics.trackEvent('RoomDirectory', action); } +@replaceableComponent("structures.RoomDirectory") export default class RoomDirectory extends React.Component { static propTypes = { initialText: PropTypes.string, diff --git a/src/components/structures/RoomSearch.tsx b/src/components/structures/RoomSearch.tsx index a64e40bc65..fda09f9774 100644 --- a/src/components/structures/RoomSearch.tsx +++ b/src/components/structures/RoomSearch.tsx @@ -25,6 +25,7 @@ import AccessibleButton from "../views/elements/AccessibleButton"; import { Action } from "../../dispatcher/actions"; import RoomListStore from "../../stores/room-list/RoomListStore"; import { NameFilterCondition } from "../../stores/room-list/filters/NameFilterCondition"; +import {replaceableComponent} from "../../utils/replaceableComponent"; interface IProps { isMinimized: boolean; @@ -37,6 +38,7 @@ interface IState { focused: boolean; } +@replaceableComponent("structures.RoomSearch") export default class RoomSearch extends React.PureComponent { private dispatcherRef: string; private inputRef: React.RefObject = createRef(); diff --git a/src/components/structures/RoomStatusBar.js b/src/components/structures/RoomStatusBar.js index aa4bceba74..8b70998be0 100644 --- a/src/components/structures/RoomStatusBar.js +++ b/src/components/structures/RoomStatusBar.js @@ -23,6 +23,7 @@ import Resend from '../../Resend'; import dis from '../../dispatcher/dispatcher'; import {messageForResourceLimitError, messageForSendError} from '../../utils/ErrorUtils'; import {Action} from "../../dispatcher/actions"; +import {replaceableComponent} from "../../utils/replaceableComponent"; const STATUS_BAR_HIDDEN = 0; const STATUS_BAR_EXPANDED = 1; @@ -35,6 +36,7 @@ function getUnsentMessages(room) { }); } +@replaceableComponent("structures.RoomStatusBar") export default class RoomStatusBar extends React.Component { static propTypes = { // the room this statusbar is representing. diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 90f6daf6cb..b57638413b 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -82,6 +82,7 @@ import { Container, WidgetLayoutStore } from "../../stores/widgets/WidgetLayoutS import { objectHasDiff } from "../../utils/objects"; import SpaceRoomView from "./SpaceRoomView"; import { IOpts } from "../../createRoom"; +import {replaceableComponent} from "../../utils/replaceableComponent"; const DEBUG = false; let debuglog = function(msg: string) {}; @@ -195,6 +196,7 @@ export interface IState { dragCounter: number; } +@replaceableComponent("structures.RoomView") export default class RoomView extends React.Component { private readonly dispatcherRef: string; private readonly roomStoreToken: EventSubscription; diff --git a/src/components/structures/ScrollPanel.js b/src/components/structures/ScrollPanel.js index 744400df3c..3a9b2b8a77 100644 --- a/src/components/structures/ScrollPanel.js +++ b/src/components/structures/ScrollPanel.js @@ -19,6 +19,7 @@ import PropTypes from 'prop-types'; import { Key } from '../../Keyboard'; import Timer from '../../utils/Timer'; import AutoHideScrollbar from "./AutoHideScrollbar"; +import {replaceableComponent} from "../../utils/replaceableComponent"; const DEBUG_SCROLL = false; @@ -83,6 +84,7 @@ if (DEBUG_SCROLL) { * offset as normal. */ +@replaceableComponent("structures.ScrollPanel") export default class ScrollPanel extends React.Component { static propTypes = { /* stickyBottom: if set to true, then once the user hits the bottom of diff --git a/src/components/structures/SearchBox.js b/src/components/structures/SearchBox.js index c1e3ad0cf2..6daa8526bc 100644 --- a/src/components/structures/SearchBox.js +++ b/src/components/structures/SearchBox.js @@ -22,7 +22,9 @@ import dis from '../../dispatcher/dispatcher'; import {throttle} from 'lodash'; import AccessibleButton from '../../components/views/elements/AccessibleButton'; import classNames from 'classnames'; +import {replaceableComponent} from "../../utils/replaceableComponent"; +@replaceableComponent("structures.SearchBox") export default class SearchBox extends React.Component { static propTypes = { onSearch: PropTypes.func, diff --git a/src/components/structures/TabbedView.tsx b/src/components/structures/TabbedView.tsx index 21f9f3f5d6..0097d55cf5 100644 --- a/src/components/structures/TabbedView.tsx +++ b/src/components/structures/TabbedView.tsx @@ -20,6 +20,7 @@ import * as React from "react"; import {_t} from '../../languageHandler'; import * as sdk from "../../index"; import AutoHideScrollbar from './AutoHideScrollbar'; +import {replaceableComponent} from "../../utils/replaceableComponent"; /** * Represents a tab for the TabbedView. @@ -45,6 +46,7 @@ interface IState { activeTabIndex: number; } +@replaceableComponent("structures.TabbedView") export default class TabbedView extends React.Component { constructor(props: IProps) { super(props); diff --git a/src/components/structures/TimelinePanel.js b/src/components/structures/TimelinePanel.js index 6bc1f70ba1..f32b8ed0a9 100644 --- a/src/components/structures/TimelinePanel.js +++ b/src/components/structures/TimelinePanel.js @@ -37,6 +37,7 @@ import EditorStateTransfer from '../../utils/EditorStateTransfer'; import {haveTileForEvent} from "../views/rooms/EventTile"; import {UIFeature} from "../../settings/UIFeature"; import {objectHasDiff} from "../../utils/objects"; +import {replaceableComponent} from "../../utils/replaceableComponent"; const PAGINATE_SIZE = 20; const INITIAL_SIZE = 20; @@ -55,6 +56,7 @@ if (DEBUG) { * * Also responsible for handling and sending read receipts. */ +@replaceableComponent("structures.TimelinePanel") class TimelinePanel extends React.Component { static propTypes = { // The js-sdk EventTimelineSet object for the timeline sequence we are diff --git a/src/components/structures/ToastContainer.tsx b/src/components/structures/ToastContainer.tsx index 513cca82c3..1fd3e3419f 100644 --- a/src/components/structures/ToastContainer.tsx +++ b/src/components/structures/ToastContainer.tsx @@ -17,12 +17,14 @@ limitations under the License. import * as React from "react"; import ToastStore, {IToast} from "../../stores/ToastStore"; import classNames from "classnames"; +import {replaceableComponent} from "../../utils/replaceableComponent"; interface IState { toasts: IToast[]; countSeen: number; } +@replaceableComponent("structures.ToastContainer") export default class ToastContainer extends React.Component<{}, IState> { constructor(props, context) { super(props, context); diff --git a/src/components/structures/UploadBar.tsx b/src/components/structures/UploadBar.tsx index b9d157ee00..4a1fd4313d 100644 --- a/src/components/structures/UploadBar.tsx +++ b/src/components/structures/UploadBar.tsx @@ -25,6 +25,7 @@ import { Action } from "../../dispatcher/actions"; import ProgressBar from "../views/elements/ProgressBar"; import AccessibleButton from "../views/elements/AccessibleButton"; import { IUpload } from "../../models/IUpload"; +import {replaceableComponent} from "../../utils/replaceableComponent"; interface IProps { room: Room; @@ -35,6 +36,7 @@ interface IState { uploadsHere: IUpload[]; } +@replaceableComponent("structures.UploadBar") export default class UploadBar extends React.Component { private dispatcherRef: string; private mounted: boolean; diff --git a/src/components/structures/UserMenu.tsx b/src/components/structures/UserMenu.tsx index b31a5f4b8e..0543cc4d07 100644 --- a/src/components/structures/UserMenu.tsx +++ b/src/components/structures/UserMenu.tsx @@ -56,6 +56,7 @@ import HostSignupAction from "./HostSignupAction"; import { IHostSignupConfig } from "../views/dialogs/HostSignupDialogTypes"; import SpaceStore, { UPDATE_SELECTED_SPACE } from "../../stores/SpaceStore"; import RoomName from "../views/elements/RoomName"; +import {replaceableComponent} from "../../utils/replaceableComponent"; interface IProps { isMinimized: boolean; @@ -69,6 +70,7 @@ interface IState { selectedSpace?: Room; } +@replaceableComponent("structures.UserMenu") export default class UserMenu extends React.Component { private dispatcherRef: string; private themeWatcherRef: string; diff --git a/src/components/structures/UserView.js b/src/components/structures/UserView.js index 8e21771bb9..dc05193ece 100644 --- a/src/components/structures/UserView.js +++ b/src/components/structures/UserView.js @@ -23,7 +23,9 @@ import * as sdk from "../../index"; import Modal from '../../Modal'; import { _t } from '../../languageHandler'; import HomePage from "./HomePage"; +import {replaceableComponent} from "../../utils/replaceableComponent"; +@replaceableComponent("structures.UserView") export default class UserView extends React.Component { static get propTypes() { return { diff --git a/src/components/structures/ViewSource.js b/src/components/structures/ViewSource.js index 0b969784e5..704a1e7275 100644 --- a/src/components/structures/ViewSource.js +++ b/src/components/structures/ViewSource.js @@ -21,8 +21,10 @@ import PropTypes from 'prop-types'; import SyntaxHighlight from '../views/elements/SyntaxHighlight'; import {_t} from "../../languageHandler"; import * as sdk from "../../index"; +import {replaceableComponent} from "../../utils/replaceableComponent"; +@replaceableComponent("structures.ViewSource") export default class ViewSource extends React.Component { static propTypes = { content: PropTypes.object.isRequired, diff --git a/src/components/structures/auth/CompleteSecurity.js b/src/components/structures/auth/CompleteSecurity.js index c73691611d..eee5667052 100644 --- a/src/components/structures/auth/CompleteSecurity.js +++ b/src/components/structures/auth/CompleteSecurity.js @@ -26,7 +26,9 @@ import { PHASE_CONFIRM_SKIP, } from '../../../stores/SetupEncryptionStore'; import SetupEncryptionBody from "./SetupEncryptionBody"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("structures.auth.CompleteSecurity") export default class CompleteSecurity extends React.Component { static propTypes = { onFinished: PropTypes.func.isRequired, diff --git a/src/components/structures/auth/E2eSetup.js b/src/components/structures/auth/E2eSetup.js index d97a972718..4e51ae828c 100644 --- a/src/components/structures/auth/E2eSetup.js +++ b/src/components/structures/auth/E2eSetup.js @@ -19,7 +19,9 @@ import PropTypes from 'prop-types'; import AuthPage from '../../views/auth/AuthPage'; import CompleteSecurityBody from '../../views/auth/CompleteSecurityBody'; import CreateCrossSigningDialog from '../../views/dialogs/security/CreateCrossSigningDialog'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("structures.auth.E2eSetup") export default class E2eSetup extends React.Component { static propTypes = { onFinished: PropTypes.func.isRequired, diff --git a/src/components/structures/auth/ForgotPassword.js b/src/components/structures/auth/ForgotPassword.js index 5a39fe9fd9..31a5de0222 100644 --- a/src/components/structures/auth/ForgotPassword.js +++ b/src/components/structures/auth/ForgotPassword.js @@ -27,6 +27,7 @@ import classNames from 'classnames'; import AuthPage from "../../views/auth/AuthPage"; import CountlyAnalytics from "../../../CountlyAnalytics"; import ServerPicker from "../../views/elements/ServerPicker"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; // Phases // Show the forgot password inputs @@ -38,6 +39,7 @@ const PHASE_EMAIL_SENT = 3; // User has clicked the link in email and completed reset const PHASE_DONE = 4; +@replaceableComponent("structures.auth.ForgotPassword") export default class ForgotPassword extends React.Component { static propTypes = { serverConfig: PropTypes.instanceOf(ValidatedServerConfig).isRequired, diff --git a/src/components/structures/auth/Login.tsx b/src/components/structures/auth/Login.tsx index 96fc39a437..3ab73fb9ac 100644 --- a/src/components/structures/auth/Login.tsx +++ b/src/components/structures/auth/Login.tsx @@ -35,6 +35,7 @@ import InlineSpinner from "../../views/elements/InlineSpinner"; import Spinner from "../../views/elements/Spinner"; import SSOButtons from "../../views/elements/SSOButtons"; import ServerPicker from "../../views/elements/ServerPicker"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; // These are used in several places, and come from the js-sdk's autodiscovery // stuff. We define them here so that they'll be picked up by i18n. @@ -99,6 +100,7 @@ interface IState { /* * A wire component which glues together login UI components and Login logic */ +@replaceableComponent("structures.auth.LoginComponent") export default class LoginComponent extends React.PureComponent { private unmounted = false; private loginLogic: Login; diff --git a/src/components/structures/auth/Registration.tsx b/src/components/structures/auth/Registration.tsx index f9d338902c..32bdddb82a 100644 --- a/src/components/structures/auth/Registration.tsx +++ b/src/components/structures/auth/Registration.tsx @@ -30,6 +30,7 @@ import Login, {ISSOFlow} from "../../../Login"; import dis from "../../../dispatcher/dispatcher"; import SSOButtons from "../../views/elements/SSOButtons"; import ServerPicker from '../../views/elements/ServerPicker'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { serverConfig: ValidatedServerConfig; @@ -109,6 +110,7 @@ interface IState { ssoFlow?: ISSOFlow; } +@replaceableComponent("structures.auth.Registration") export default class Registration extends React.Component { loginLogic: Login; diff --git a/src/components/structures/auth/SetupEncryptionBody.js b/src/components/structures/auth/SetupEncryptionBody.js index 3e7264dfec..f66c434edd 100644 --- a/src/components/structures/auth/SetupEncryptionBody.js +++ b/src/components/structures/auth/SetupEncryptionBody.js @@ -28,6 +28,7 @@ import { PHASE_CONFIRM_SKIP, PHASE_FINISHED, } from '../../../stores/SetupEncryptionStore'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; function keyHasPassphrase(keyInfo) { return ( @@ -37,6 +38,7 @@ function keyHasPassphrase(keyInfo) { ); } +@replaceableComponent("structures.auth.SetupEncryptionBody") export default class SetupEncryptionBody extends React.Component { static propTypes = { onFinished: PropTypes.func.isRequired, diff --git a/src/components/structures/auth/SoftLogout.js b/src/components/structures/auth/SoftLogout.js index a7fe340457..08db3b2efe 100644 --- a/src/components/structures/auth/SoftLogout.js +++ b/src/components/structures/auth/SoftLogout.js @@ -26,6 +26,7 @@ import {sendLoginRequest} from "../../../Login"; import AuthPage from "../../views/auth/AuthPage"; import {SSO_HOMESERVER_URL_KEY, SSO_ID_SERVER_URL_KEY} from "../../../BasePlatform"; import SSOButtons from "../../views/elements/SSOButtons"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const LOGIN_VIEW = { LOADING: 1, @@ -41,6 +42,7 @@ const FLOWS_TO_VIEWS = { "m.login.sso": LOGIN_VIEW.SSO, }; +@replaceableComponent("structures.auth.SoftLogout") export default class SoftLogout extends React.Component { static propTypes = { // Query parameters from MatrixChat From 3e189d2728393bb9b77cd55609679abd1bceba49 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 8 Mar 2021 19:45:39 -0700 Subject: [PATCH 60/91] Batch of views getting replaceableComponent decorators --- src/components/views/auth/AuthBody.js | 2 ++ src/components/views/auth/AuthFooter.js | 2 ++ src/components/views/auth/AuthHeader.js | 2 ++ src/components/views/auth/AuthHeaderLogo.js | 2 ++ src/components/views/auth/CaptchaForm.js | 2 ++ src/components/views/auth/CompleteSecurityBody.js | 2 ++ src/components/views/auth/CountryDropdown.js | 2 ++ .../views/auth/InteractiveAuthEntryComponents.js | 8 ++++++++ src/components/views/auth/PassphraseField.tsx | 2 ++ src/components/views/auth/PasswordLogin.tsx | 2 ++ src/components/views/auth/RegistrationForm.tsx | 2 ++ src/components/views/auth/Welcome.js | 2 ++ src/components/views/avatars/DecoratedRoomAvatar.tsx | 2 ++ src/components/views/avatars/GroupAvatar.tsx | 2 ++ src/components/views/avatars/MemberAvatar.tsx | 2 ++ src/components/views/avatars/MemberStatusMessageAvatar.js | 2 ++ src/components/views/avatars/RoomAvatar.tsx | 2 ++ src/components/views/context_menus/CallContextMenu.tsx | 2 ++ src/components/views/context_menus/DialpadContextMenu.tsx | 2 ++ .../views/context_menus/GenericElementContextMenu.js | 2 ++ .../views/context_menus/GenericTextContextMenu.js | 2 ++ .../views/context_menus/GroupInviteTileContextMenu.js | 2 ++ src/components/views/context_menus/MessageContextMenu.js | 2 ++ .../views/context_menus/StatusMessageContextMenu.js | 2 ++ src/components/views/context_menus/TagTileContextMenu.js | 2 ++ src/components/views/dialogs/AddressPickerDialog.js | 3 ++- src/components/views/dialogs/AskInviteAnywayDialog.js | 2 ++ src/components/views/dialogs/BaseDialog.js | 2 ++ src/components/views/dialogs/BugReportDialog.js | 2 ++ .../views/dialogs/CommunityPrototypeInviteDialog.tsx | 2 ++ .../views/dialogs/ConfirmAndWaitRedactDialog.js | 2 ++ src/components/views/dialogs/ConfirmRedactDialog.js | 2 ++ src/components/views/dialogs/ConfirmUserActionDialog.js | 2 ++ .../dialogs/security/ConfirmDestroyCrossSigningDialog.js | 2 ++ .../views/dialogs/security/CreateCrossSigningDialog.js | 2 ++ .../views/dialogs/security/SetupEncryptionDialog.js | 2 ++ 36 files changed, 78 insertions(+), 1 deletion(-) diff --git a/src/components/views/auth/AuthBody.js b/src/components/views/auth/AuthBody.js index 9a078efb52..fa7ad2b285 100644 --- a/src/components/views/auth/AuthBody.js +++ b/src/components/views/auth/AuthBody.js @@ -17,7 +17,9 @@ limitations under the License. 'use strict'; import React from 'react'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.auth.AuthBody") export default class AuthBody extends React.PureComponent { render() { return
diff --git a/src/components/views/auth/AuthFooter.js b/src/components/views/auth/AuthFooter.js index 3de5a19350..f167e16283 100644 --- a/src/components/views/auth/AuthFooter.js +++ b/src/components/views/auth/AuthFooter.js @@ -18,7 +18,9 @@ limitations under the License. import { _t } from '../../../languageHandler'; import React from 'react'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.auth.AuthFooter") export default class AuthFooter extends React.Component { render() { return ( diff --git a/src/components/views/auth/AuthHeader.js b/src/components/views/auth/AuthHeader.js index 57499e397c..323299b3a8 100644 --- a/src/components/views/auth/AuthHeader.js +++ b/src/components/views/auth/AuthHeader.js @@ -18,7 +18,9 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import * as sdk from '../../../index'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.auth.AuthHeader") export default class AuthHeader extends React.Component { static propTypes = { disableLanguageSelector: PropTypes.bool, diff --git a/src/components/views/auth/AuthHeaderLogo.js b/src/components/views/auth/AuthHeaderLogo.js index 9edf149a83..ea649893c6 100644 --- a/src/components/views/auth/AuthHeaderLogo.js +++ b/src/components/views/auth/AuthHeaderLogo.js @@ -17,7 +17,9 @@ limitations under the License. 'use strict'; import React from 'react'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.auth.AuthHeaderLogo") export default class AuthHeaderLogo extends React.PureComponent { render() { return
diff --git a/src/components/views/auth/CaptchaForm.js b/src/components/views/auth/CaptchaForm.js index e2d7d594fa..50de24d403 100644 --- a/src/components/views/auth/CaptchaForm.js +++ b/src/components/views/auth/CaptchaForm.js @@ -18,12 +18,14 @@ import React, {createRef} from 'react'; import PropTypes from 'prop-types'; import { _t } from '../../../languageHandler'; import CountlyAnalytics from "../../../CountlyAnalytics"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const DIV_ID = 'mx_recaptcha'; /** * A pure UI component which displays a captcha form. */ +@replaceableComponent("views.auth.CaptchaForm") export default class CaptchaForm extends React.Component { static propTypes = { sitePublicKey: PropTypes.string, diff --git a/src/components/views/auth/CompleteSecurityBody.js b/src/components/views/auth/CompleteSecurityBody.js index d757de9fe0..91cd66f150 100644 --- a/src/components/views/auth/CompleteSecurityBody.js +++ b/src/components/views/auth/CompleteSecurityBody.js @@ -17,7 +17,9 @@ limitations under the License. 'use strict'; import React from 'react'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.auth.CompleteSecurityBody") export default class CompleteSecurityBody extends React.PureComponent { render() { return
diff --git a/src/components/views/auth/CountryDropdown.js b/src/components/views/auth/CountryDropdown.js index 3296b574a4..e21f112865 100644 --- a/src/components/views/auth/CountryDropdown.js +++ b/src/components/views/auth/CountryDropdown.js @@ -22,6 +22,7 @@ import * as sdk from '../../../index'; import {COUNTRIES, getEmojiFlag} from '../../../phonenumber'; import SdkConfig from "../../../SdkConfig"; import { _t } from "../../../languageHandler"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const COUNTRIES_BY_ISO2 = {}; for (const c of COUNTRIES) { @@ -40,6 +41,7 @@ function countryMatchesSearchQuery(query, country) { return false; } +@replaceableComponent("views.auth.CountryDropdown") export default class CountryDropdown extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/auth/InteractiveAuthEntryComponents.js b/src/components/views/auth/InteractiveAuthEntryComponents.js index 7dc1976641..6cbecd22ee 100644 --- a/src/components/views/auth/InteractiveAuthEntryComponents.js +++ b/src/components/views/auth/InteractiveAuthEntryComponents.js @@ -26,6 +26,7 @@ import SettingsStore from "../../../settings/SettingsStore"; import AccessibleButton from "../elements/AccessibleButton"; import Spinner from "../elements/Spinner"; import CountlyAnalytics from "../../../CountlyAnalytics"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; /* This file contains a collection of components which are used by the * InteractiveAuth to prompt the user to enter the information needed @@ -75,6 +76,7 @@ import CountlyAnalytics from "../../../CountlyAnalytics"; export const DEFAULT_PHASE = 0; +@replaceableComponent("views.auth.PasswordAuthEntry") export class PasswordAuthEntry extends React.Component { static LOGIN_TYPE = "m.login.password"; @@ -173,6 +175,7 @@ export class PasswordAuthEntry extends React.Component { } } +@replaceableComponent("views.auth.RecaptchaAuthEntry") export class RecaptchaAuthEntry extends React.Component { static LOGIN_TYPE = "m.login.recaptcha"; @@ -235,6 +238,7 @@ export class RecaptchaAuthEntry extends React.Component { } } +@replaceableComponent("views.auth.TermsAuthEntry") export class TermsAuthEntry extends React.Component { static LOGIN_TYPE = "m.login.terms"; @@ -385,6 +389,7 @@ export class TermsAuthEntry extends React.Component { } } +@replaceableComponent("views.auth.EmailIdentityAuthEntry") export class EmailIdentityAuthEntry extends React.Component { static LOGIN_TYPE = "m.login.email.identity"; @@ -432,6 +437,7 @@ export class EmailIdentityAuthEntry extends React.Component { } } +@replaceableComponent("views.auth.MsisdnAuthEntry") export class MsisdnAuthEntry extends React.Component { static LOGIN_TYPE = "m.login.msisdn"; @@ -578,6 +584,7 @@ export class MsisdnAuthEntry extends React.Component { } } +@replaceableComponent("views.auth.SSOAuthEntry") export class SSOAuthEntry extends React.Component { static propTypes = { matrixClient: PropTypes.object.isRequired, @@ -708,6 +715,7 @@ export class SSOAuthEntry extends React.Component { } } +@replaceableComponent("views.auth.FallbackAuthEntry") export class FallbackAuthEntry extends React.Component { static propTypes = { matrixClient: PropTypes.object.isRequired, diff --git a/src/components/views/auth/PassphraseField.tsx b/src/components/views/auth/PassphraseField.tsx index e240ad61ca..274c244b2a 100644 --- a/src/components/views/auth/PassphraseField.tsx +++ b/src/components/views/auth/PassphraseField.tsx @@ -22,6 +22,7 @@ import SdkConfig from "../../../SdkConfig"; import withValidation, {IFieldState, IValidationResult} from "../elements/Validation"; import {_t, _td} from "../../../languageHandler"; import Field, {IInputProps} from "../elements/Field"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps extends Omit { autoFocus?: boolean; @@ -40,6 +41,7 @@ interface IProps extends Omit { onValidate(result: IValidationResult); } +@replaceableComponent("views.auth.PassphraseField") class PassphraseField extends PureComponent { static defaultProps = { label: _td("Password"), diff --git a/src/components/views/auth/PasswordLogin.tsx b/src/components/views/auth/PasswordLogin.tsx index b2a3d62f55..2a42804a61 100644 --- a/src/components/views/auth/PasswordLogin.tsx +++ b/src/components/views/auth/PasswordLogin.tsx @@ -26,6 +26,7 @@ import withValidation from "../elements/Validation"; import * as Email from "../../../email"; import Field from "../elements/Field"; import CountryDropdown from "./CountryDropdown"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; // For validating phone numbers without country codes const PHONE_NUMBER_REGEX = /^[0-9()\-\s]*$/; @@ -66,6 +67,7 @@ enum LoginField { * A pure UI component which displays a username/password form. * The email/username/phone fields are fully-controlled, the password field is not. */ +@replaceableComponent("views.auth.PasswordLogin") export default class PasswordLogin extends React.PureComponent { static defaultProps = { onUsernameChanged: function() {}, diff --git a/src/components/views/auth/RegistrationForm.tsx b/src/components/views/auth/RegistrationForm.tsx index e42ed88f99..85e0933be9 100644 --- a/src/components/views/auth/RegistrationForm.tsx +++ b/src/components/views/auth/RegistrationForm.tsx @@ -30,6 +30,7 @@ import PassphraseField from "./PassphraseField"; import CountlyAnalytics from "../../../CountlyAnalytics"; import Field from '../elements/Field'; import RegistrationEmailPromptDialog from '../dialogs/RegistrationEmailPromptDialog'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; enum RegistrationField { Email = "field_email", @@ -80,6 +81,7 @@ interface IState { /* * A pure UI component which displays a registration form. */ +@replaceableComponent("views.auth.RegistrationForm") export default class RegistrationForm extends React.PureComponent { static defaultProps = { onValidationChange: console.error, diff --git a/src/components/views/auth/Welcome.js b/src/components/views/auth/Welcome.js index 0205f4e0b9..fca66fcf9b 100644 --- a/src/components/views/auth/Welcome.js +++ b/src/components/views/auth/Welcome.js @@ -24,10 +24,12 @@ import {_td} from "../../../languageHandler"; import SettingsStore from "../../../settings/SettingsStore"; import {UIFeature} from "../../../settings/UIFeature"; import CountlyAnalytics from "../../../CountlyAnalytics"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; // translatable strings for Welcome pages _td("Sign in with SSO"); +@replaceableComponent("views.auth.Welcome") export default class Welcome extends React.PureComponent { constructor(props) { super(props); diff --git a/src/components/views/avatars/DecoratedRoomAvatar.tsx b/src/components/views/avatars/DecoratedRoomAvatar.tsx index d7e012467b..e95022687a 100644 --- a/src/components/views/avatars/DecoratedRoomAvatar.tsx +++ b/src/components/views/avatars/DecoratedRoomAvatar.tsx @@ -30,6 +30,7 @@ import {MatrixClientPeg} from "../../../MatrixClientPeg"; import {_t} from "../../../languageHandler"; import TextWithTooltip from "../elements/TextWithTooltip"; import DMRoomMap from "../../../utils/DMRoomMap"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { room: Room; @@ -68,6 +69,7 @@ function tooltipText(variant: Icon) { } } +@replaceableComponent("views.avatars.DecoratedRoomAvatar") export default class DecoratedRoomAvatar extends React.PureComponent { private _dmUser: User; private isUnmounted = false; diff --git a/src/components/views/avatars/GroupAvatar.tsx b/src/components/views/avatars/GroupAvatar.tsx index 51327605c0..a033257871 100644 --- a/src/components/views/avatars/GroupAvatar.tsx +++ b/src/components/views/avatars/GroupAvatar.tsx @@ -17,6 +17,7 @@ limitations under the License. import React from 'react'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; import BaseAvatar from './BaseAvatar'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; export interface IProps { groupId?: string; @@ -28,6 +29,7 @@ export interface IProps { onClick?: React.MouseEventHandler; } +@replaceableComponent("views.avatars.GroupAvatar") export default class GroupAvatar extends React.Component { public static defaultProps = { width: 36, diff --git a/src/components/views/avatars/MemberAvatar.tsx b/src/components/views/avatars/MemberAvatar.tsx index 60b043016b..641046aa55 100644 --- a/src/components/views/avatars/MemberAvatar.tsx +++ b/src/components/views/avatars/MemberAvatar.tsx @@ -22,6 +22,7 @@ import dis from "../../../dispatcher/dispatcher"; import {Action} from "../../../dispatcher/actions"; import {MatrixClientPeg} from "../../../MatrixClientPeg"; import BaseAvatar from "./BaseAvatar"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps extends Omit, "name" | "idName" | "url"> { member: RoomMember; @@ -42,6 +43,7 @@ interface IState { imageUrl?: string; } +@replaceableComponent("views.avatars.MemberAvatar") export default class MemberAvatar extends React.Component { public static defaultProps = { width: 40, diff --git a/src/components/views/avatars/MemberStatusMessageAvatar.js b/src/components/views/avatars/MemberStatusMessageAvatar.js index d5d927106c..acf190f17f 100644 --- a/src/components/views/avatars/MemberStatusMessageAvatar.js +++ b/src/components/views/avatars/MemberStatusMessageAvatar.js @@ -23,7 +23,9 @@ import classNames from 'classnames'; import StatusMessageContextMenu from "../context_menus/StatusMessageContextMenu"; import SettingsStore from "../../../settings/SettingsStore"; import {ContextMenu, ContextMenuButton} from "../../structures/ContextMenu"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.avatars.MemberStatusMessageAvatar") export default class MemberStatusMessageAvatar extends React.Component { static propTypes = { member: PropTypes.object.isRequired, diff --git a/src/components/views/avatars/RoomAvatar.tsx b/src/components/views/avatars/RoomAvatar.tsx index 952b9d4cb6..0a59f6e36a 100644 --- a/src/components/views/avatars/RoomAvatar.tsx +++ b/src/components/views/avatars/RoomAvatar.tsx @@ -23,6 +23,7 @@ import {MatrixClientPeg} from '../../../MatrixClientPeg'; import Modal from '../../../Modal'; import * as Avatar from '../../../Avatar'; import {ResizeMethod} from "../../../Avatar"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps extends Omit, "name" | "idName" | "url" | "onClick"> { // Room may be left unset here, but if it is, @@ -42,6 +43,7 @@ interface IState { urls: string[]; } +@replaceableComponent("views.avatars.RoomAvatar") export default class RoomAvatar extends React.Component { public static defaultProps = { width: 36, diff --git a/src/components/views/context_menus/CallContextMenu.tsx b/src/components/views/context_menus/CallContextMenu.tsx index 3557976326..97473059a6 100644 --- a/src/components/views/context_menus/CallContextMenu.tsx +++ b/src/components/views/context_menus/CallContextMenu.tsx @@ -22,11 +22,13 @@ import { MatrixCall } from 'matrix-js-sdk/src/webrtc/call'; import CallHandler from '../../../CallHandler'; import InviteDialog, { KIND_CALL_TRANSFER } from '../dialogs/InviteDialog'; import Modal from '../../../Modal'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps extends IContextMenuProps { call: MatrixCall; } +@replaceableComponent("views.context_menus.CallContextMenu") export default class CallContextMenu extends React.Component { static propTypes = { // js-sdk User object. Not required because it might not exist. diff --git a/src/components/views/context_menus/DialpadContextMenu.tsx b/src/components/views/context_menus/DialpadContextMenu.tsx index e3aed0179b..17abce0c61 100644 --- a/src/components/views/context_menus/DialpadContextMenu.tsx +++ b/src/components/views/context_menus/DialpadContextMenu.tsx @@ -19,6 +19,7 @@ import { _t } from '../../../languageHandler'; import { ContextMenu, IProps as IContextMenuProps } from '../../structures/ContextMenu'; import { MatrixCall } from 'matrix-js-sdk/src/webrtc/call'; import Dialpad from '../voip/DialPad'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps extends IContextMenuProps { call: MatrixCall; @@ -28,6 +29,7 @@ interface IState { value: string; } +@replaceableComponent("views.context_menus.DialpadContextMenu") export default class DialpadContextMenu extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/context_menus/GenericElementContextMenu.js b/src/components/views/context_menus/GenericElementContextMenu.js index cea684b663..e04e3f7695 100644 --- a/src/components/views/context_menus/GenericElementContextMenu.js +++ b/src/components/views/context_menus/GenericElementContextMenu.js @@ -16,6 +16,7 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; /* * This component can be used to display generic HTML content in a contextual @@ -23,6 +24,7 @@ import PropTypes from 'prop-types'; */ +@replaceableComponent("views.context_menus.GenericElementContextMenu") export default class GenericElementContextMenu extends React.Component { static propTypes = { element: PropTypes.element.isRequired, diff --git a/src/components/views/context_menus/GenericTextContextMenu.js b/src/components/views/context_menus/GenericTextContextMenu.js index 068f83be5f..3d3add006f 100644 --- a/src/components/views/context_menus/GenericTextContextMenu.js +++ b/src/components/views/context_menus/GenericTextContextMenu.js @@ -16,7 +16,9 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.context_menus.GenericTextContextMenu") export default class GenericTextContextMenu extends React.Component { static propTypes = { message: PropTypes.string.isRequired, diff --git a/src/components/views/context_menus/GroupInviteTileContextMenu.js b/src/components/views/context_menus/GroupInviteTileContextMenu.js index 27ef76452f..11a9d90ac2 100644 --- a/src/components/views/context_menus/GroupInviteTileContextMenu.js +++ b/src/components/views/context_menus/GroupInviteTileContextMenu.js @@ -23,7 +23,9 @@ import Modal from '../../../Modal'; import {Group} from 'matrix-js-sdk'; import GroupStore from "../../../stores/GroupStore"; import {MenuItem} from "../../structures/ContextMenu"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.context_menus.GroupInviteTileContextMenu") export default class GroupInviteTileContextMenu extends React.Component { static propTypes = { group: PropTypes.instanceOf(Group).isRequired, diff --git a/src/components/views/context_menus/MessageContextMenu.js b/src/components/views/context_menus/MessageContextMenu.js index 6b871e4f24..e19cfab809 100644 --- a/src/components/views/context_menus/MessageContextMenu.js +++ b/src/components/views/context_menus/MessageContextMenu.js @@ -32,11 +32,13 @@ import { isUrlPermitted } from '../../../HtmlUtils'; import { isContentActionable } from '../../../utils/EventUtils'; import {MenuItem} from "../../structures/ContextMenu"; import {EventType} from "matrix-js-sdk/src/@types/event"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; function canCancel(eventStatus) { return eventStatus === EventStatus.QUEUED || eventStatus === EventStatus.NOT_SENT; } +@replaceableComponent("views.context_menus.MessageContextMenu") export default class MessageContextMenu extends React.Component { static propTypes = { /* the MatrixEvent associated with the context menu */ diff --git a/src/components/views/context_menus/StatusMessageContextMenu.js b/src/components/views/context_menus/StatusMessageContextMenu.js index 5e6f06dd5d..41f0e0ba61 100644 --- a/src/components/views/context_menus/StatusMessageContextMenu.js +++ b/src/components/views/context_menus/StatusMessageContextMenu.js @@ -20,7 +20,9 @@ import { _t } from '../../../languageHandler'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; import * as sdk from '../../../index'; import AccessibleButton from '../elements/AccessibleButton'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.context_menus.StatusMessageContextMenu") export default class StatusMessageContextMenu extends React.Component { static propTypes = { // js-sdk User object. Not required because it might not exist. diff --git a/src/components/views/context_menus/TagTileContextMenu.js b/src/components/views/context_menus/TagTileContextMenu.js index 8d690483a8..8dea62690c 100644 --- a/src/components/views/context_menus/TagTileContextMenu.js +++ b/src/components/views/context_menus/TagTileContextMenu.js @@ -22,7 +22,9 @@ import dis from '../../../dispatcher/dispatcher'; import TagOrderActions from '../../../actions/TagOrderActions'; import {MenuItem} from "../../structures/ContextMenu"; import MatrixClientContext from "../../../contexts/MatrixClientContext"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.context_menus.TagTileContextMenu") export default class TagTileContextMenu extends React.Component { static propTypes = { tag: PropTypes.string.isRequired, diff --git a/src/components/views/dialogs/AddressPickerDialog.js b/src/components/views/dialogs/AddressPickerDialog.js index 2cd09874b2..929d688e47 100644 --- a/src/components/views/dialogs/AddressPickerDialog.js +++ b/src/components/views/dialogs/AddressPickerDialog.js @@ -33,6 +33,7 @@ import { abbreviateUrl } from '../../../utils/UrlUtils'; import {sleep} from "../../../utils/promise"; import {Key} from "../../../Keyboard"; import {Action} from "../../../dispatcher/actions"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const TRUNCATE_QUERY_LIST = 40; const QUERY_USER_DIRECTORY_DEBOUNCE_MS = 200; @@ -43,7 +44,7 @@ const addressTypeName = { 'email': _td("email address"), }; - +@replaceableComponent("views.dialogs.AddressPickerDialog") export default class AddressPickerDialog extends React.Component { static propTypes = { title: PropTypes.string.isRequired, diff --git a/src/components/views/dialogs/AskInviteAnywayDialog.js b/src/components/views/dialogs/AskInviteAnywayDialog.js index c69400977a..e6cd45ba6b 100644 --- a/src/components/views/dialogs/AskInviteAnywayDialog.js +++ b/src/components/views/dialogs/AskInviteAnywayDialog.js @@ -20,7 +20,9 @@ import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; import SettingsStore from "../../../settings/SettingsStore"; import {SettingLevel} from "../../../settings/SettingLevel"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.AskInviteAnywayDialog") export default class AskInviteAnywayDialog extends React.Component { static propTypes = { unknownProfileUsers: PropTypes.array.isRequired, // [ {userId, errorText}... ] diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index 9ba5368ee5..0858e53e50 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -26,6 +26,7 @@ import AccessibleButton from '../elements/AccessibleButton'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; import { _t } from "../../../languageHandler"; import MatrixClientContext from "../../../contexts/MatrixClientContext"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; /* * Basic container for modal dialogs. @@ -33,6 +34,7 @@ import MatrixClientContext from "../../../contexts/MatrixClientContext"; * Includes a div for the title, and a keypress handler which cancels the * dialog on escape. */ +@replaceableComponent("views.dialogs.BaseDialog") export default class BaseDialog extends React.Component { static propTypes = { // onFinished callback to call when Escape is pressed diff --git a/src/components/views/dialogs/BugReportDialog.js b/src/components/views/dialogs/BugReportDialog.js index c4dd0a1430..8948c14c7c 100644 --- a/src/components/views/dialogs/BugReportDialog.js +++ b/src/components/views/dialogs/BugReportDialog.js @@ -25,7 +25,9 @@ import Modal from '../../../Modal'; import { _t } from '../../../languageHandler'; import sendBugReport, {downloadBugReport} from '../../../rageshake/submit-rageshake'; import AccessibleButton from "../elements/AccessibleButton"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.BugReportDialog") export default class BugReportDialog extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/dialogs/CommunityPrototypeInviteDialog.tsx b/src/components/views/dialogs/CommunityPrototypeInviteDialog.tsx index 1c8a4ad6f6..d1080566ac 100644 --- a/src/components/views/dialogs/CommunityPrototypeInviteDialog.tsx +++ b/src/components/views/dialogs/CommunityPrototypeInviteDialog.tsx @@ -31,6 +31,7 @@ import {inviteMultipleToRoom, showAnyInviteErrors} from "../../../RoomInvite"; import StyledCheckbox from "../elements/StyledCheckbox"; import Modal from "../../../Modal"; import ErrorDialog from "./ErrorDialog"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps extends IDialogProps { roomId: string; @@ -52,6 +53,7 @@ interface IState { busy: boolean; } +@replaceableComponent("views.dialogs.CommunityPrototypeInviteDialog") export default class CommunityPrototypeInviteDialog extends React.PureComponent { constructor(props: IProps) { super(props); diff --git a/src/components/views/dialogs/ConfirmAndWaitRedactDialog.js b/src/components/views/dialogs/ConfirmAndWaitRedactDialog.js index 0622dd7dfb..37d5510756 100644 --- a/src/components/views/dialogs/ConfirmAndWaitRedactDialog.js +++ b/src/components/views/dialogs/ConfirmAndWaitRedactDialog.js @@ -17,6 +17,7 @@ limitations under the License. import React from 'react'; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; /* * A dialog for confirming a redaction. @@ -30,6 +31,7 @@ import { _t } from '../../../languageHandler'; * * To avoid this, we keep the dialog open as long as /redact is in progress. */ +@replaceableComponent("views.dialogs.ConfirmAndWaitRedactDialog") export default class ConfirmAndWaitRedactDialog extends React.PureComponent { constructor(props) { super(props); diff --git a/src/components/views/dialogs/ConfirmRedactDialog.js b/src/components/views/dialogs/ConfirmRedactDialog.js index 2216f9a93a..bd63d3acc1 100644 --- a/src/components/views/dialogs/ConfirmRedactDialog.js +++ b/src/components/views/dialogs/ConfirmRedactDialog.js @@ -17,10 +17,12 @@ limitations under the License. import React from 'react'; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; /* * A dialog for confirming a redaction. */ +@replaceableComponent("views.dialogs.ConfirmRedactDialog") export default class ConfirmRedactDialog extends React.Component { render() { const TextInputDialog = sdk.getComponent('views.dialogs.TextInputDialog'); diff --git a/src/components/views/dialogs/ConfirmUserActionDialog.js b/src/components/views/dialogs/ConfirmUserActionDialog.js index 44f57f047e..8827f161f1 100644 --- a/src/components/views/dialogs/ConfirmUserActionDialog.js +++ b/src/components/views/dialogs/ConfirmUserActionDialog.js @@ -20,6 +20,7 @@ import { MatrixClient } from 'matrix-js-sdk'; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; import { GroupMemberType } from '../../../groups'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; /* * A dialog for confirming an operation on another user. @@ -29,6 +30,7 @@ import { GroupMemberType } from '../../../groups'; * to make it obvious what is going to happen. * Also tweaks the style for 'dangerous' actions (albeit only with colour) */ +@replaceableComponent("views.dialogs.ConfirmUserActionDialog") export default class ConfirmUserActionDialog extends React.Component { static propTypes = { // matrix-js-sdk (room) member object. Supply either this or 'groupMember' diff --git a/src/components/views/dialogs/security/ConfirmDestroyCrossSigningDialog.js b/src/components/views/dialogs/security/ConfirmDestroyCrossSigningDialog.js index abc1586205..43fb25f152 100644 --- a/src/components/views/dialogs/security/ConfirmDestroyCrossSigningDialog.js +++ b/src/components/views/dialogs/security/ConfirmDestroyCrossSigningDialog.js @@ -18,7 +18,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import {_t} from "../../../../languageHandler"; import * as sdk from "../../../../index"; +import {replaceableComponent} from "../../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.security.ConfirmDestroyCrossSigningDialog") export default class ConfirmDestroyCrossSigningDialog extends React.Component { static propTypes = { onFinished: PropTypes.func.isRequired, diff --git a/src/components/views/dialogs/security/CreateCrossSigningDialog.js b/src/components/views/dialogs/security/CreateCrossSigningDialog.js index be546d2616..fedcc02f89 100644 --- a/src/components/views/dialogs/security/CreateCrossSigningDialog.js +++ b/src/components/views/dialogs/security/CreateCrossSigningDialog.js @@ -25,12 +25,14 @@ import DialogButtons from '../../elements/DialogButtons'; import BaseDialog from '../BaseDialog'; import Spinner from '../../elements/Spinner'; import InteractiveAuthDialog from '../InteractiveAuthDialog'; +import {replaceableComponent} from "../../../../utils/replaceableComponent"; /* * Walks the user through the process of creating a cross-signing keys. In most * cases, only a spinner is shown, but for more complex auth like SSO, the user * may need to complete some steps to proceed. */ +@replaceableComponent("views.dialogs.security.CreateCrossSigningDialog") export default class CreateCrossSigningDialog extends React.PureComponent { static propTypes = { accountPassword: PropTypes.string, diff --git a/src/components/views/dialogs/security/SetupEncryptionDialog.js b/src/components/views/dialogs/security/SetupEncryptionDialog.js index 9ce3144534..3c15ea9f1d 100644 --- a/src/components/views/dialogs/security/SetupEncryptionDialog.js +++ b/src/components/views/dialogs/security/SetupEncryptionDialog.js @@ -20,6 +20,7 @@ import SetupEncryptionBody from '../../../structures/auth/SetupEncryptionBody'; import BaseDialog from '../BaseDialog'; import { _t } from '../../../../languageHandler'; import { SetupEncryptionStore, PHASE_DONE } from '../../../../stores/SetupEncryptionStore'; +import {replaceableComponent} from "../../../../utils/replaceableComponent"; function iconFromPhase(phase) { if (phase === PHASE_DONE) { @@ -29,6 +30,7 @@ function iconFromPhase(phase) { } } +@replaceableComponent("views.dialogs.security.SetupEncryptionDialog") export default class SetupEncryptionDialog extends React.Component { static propTypes = { onFinished: PropTypes.func.isRequired, From c359dff73879ca231a7bbc970ff532a6973ef293 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 8 Mar 2021 19:59:41 -0700 Subject: [PATCH 61/91] Batch of views getting replaceableComponent decorators --- src/components/views/dialogs/ConfirmWipeDeviceDialog.js | 2 ++ .../views/dialogs/CreateCommunityPrototypeDialog.tsx | 2 ++ src/components/views/dialogs/CreateGroupDialog.js | 2 ++ src/components/views/dialogs/CreateRoomDialog.js | 2 ++ src/components/views/dialogs/DeactivateAccountDialog.js | 2 ++ src/components/views/dialogs/DevtoolsDialog.js | 2 ++ src/components/views/dialogs/EditCommunityPrototypeDialog.tsx | 2 ++ src/components/views/dialogs/ErrorDialog.js | 2 ++ src/components/views/dialogs/HostSignupDialog.tsx | 2 ++ src/components/views/dialogs/IncomingSasDialog.js | 2 ++ src/components/views/dialogs/IntegrationsDisabledDialog.js | 2 ++ src/components/views/dialogs/IntegrationsImpossibleDialog.js | 2 ++ src/components/views/dialogs/InteractiveAuthDialog.js | 2 ++ src/components/views/dialogs/InviteDialog.tsx | 2 ++ src/components/views/dialogs/LogoutDialog.js | 2 ++ .../views/dialogs/ManualDeviceKeyVerificationDialog.js | 2 ++ src/components/views/dialogs/MessageEditHistoryDialog.js | 2 ++ src/components/views/dialogs/ModalWidgetDialog.tsx | 2 ++ src/components/views/dialogs/ReportEventDialog.js | 2 ++ src/components/views/dialogs/RoomSettingsDialog.js | 2 ++ src/components/views/dialogs/RoomUpgradeDialog.js | 2 ++ src/components/views/dialogs/RoomUpgradeWarningDialog.js | 2 ++ src/components/views/dialogs/ServerOfflineDialog.tsx | 2 ++ src/components/views/dialogs/ServerPickerDialog.tsx | 2 ++ src/components/views/dialogs/SessionRestoreErrorDialog.js | 3 ++- src/components/views/dialogs/SetEmailDialog.js | 2 ++ src/components/views/dialogs/ShareDialog.tsx | 2 ++ src/components/views/dialogs/StorageEvictedDialog.js | 2 ++ src/components/views/dialogs/TabbedIntegrationManagerDialog.js | 2 ++ src/components/views/dialogs/TermsDialog.js | 2 ++ src/components/views/dialogs/TextInputDialog.js | 2 ++ src/components/views/dialogs/UploadConfirmDialog.js | 2 ++ src/components/views/dialogs/UploadFailureDialog.js | 2 ++ src/components/views/dialogs/UserSettingsDialog.js | 2 ++ src/components/views/dialogs/VerificationRequestDialog.js | 2 ++ .../views/dialogs/WidgetCapabilitiesPromptDialog.tsx | 2 ++ src/components/views/dialogs/WidgetOpenIDPermissionsDialog.js | 2 ++ src/components/views/elements/AccessibleTooltipButton.tsx | 2 ++ src/components/views/elements/ActionButton.js | 2 ++ src/components/views/elements/AddressSelector.js | 2 ++ src/components/views/elements/AddressTile.js | 3 ++- src/components/views/elements/AppPermission.js | 2 ++ src/components/views/elements/AppTile.js | 2 ++ src/components/views/elements/DesktopCapturerSourcePicker.tsx | 2 ++ src/components/views/elements/DialogButtons.js | 2 ++ src/components/views/elements/DirectorySearchBox.js | 2 ++ src/components/views/elements/Draggable.tsx | 2 ++ src/components/views/elements/Dropdown.js | 2 ++ src/components/views/elements/EditableItemList.js | 2 ++ src/components/views/elements/EditableText.js | 2 ++ src/components/views/elements/EditableTextContainer.js | 2 ++ src/components/views/elements/ErrorBoundary.js | 2 ++ src/components/views/elements/EventTilePreview.tsx | 2 ++ src/components/views/elements/Flair.js | 2 ++ src/components/views/elements/IRCTimelineProfileResizer.tsx | 2 ++ src/components/views/elements/ImageView.js | 2 ++ src/components/views/elements/InfoTooltip.tsx | 2 ++ src/components/views/elements/InlineSpinner.js | 2 ++ src/components/views/elements/LabelledToggleSwitch.js | 2 ++ src/components/views/elements/LanguageDropdown.js | 2 ++ src/components/views/elements/LazyRenderList.js | 2 ++ src/components/views/elements/MemberEventListSummary.tsx | 2 ++ src/components/views/elements/PersistedElement.js | 2 ++ src/components/views/elements/PersistentApp.js | 2 ++ src/components/views/elements/Pill.js | 2 ++ src/components/views/elements/PowerSelector.js | 2 ++ src/components/views/elements/ReplyThread.js | 2 ++ src/components/views/elements/RoomAliasField.js | 2 ++ src/components/views/elements/SettingsFlag.tsx | 2 ++ src/components/views/elements/Slider.tsx | 2 ++ src/components/views/elements/SpellCheckLanguagesDropdown.tsx | 2 ++ src/components/views/elements/Spoiler.js | 2 ++ src/components/views/elements/StyledCheckbox.tsx | 2 ++ src/components/views/elements/StyledRadioButton.tsx | 2 ++ src/components/views/elements/SyntaxHighlight.js | 2 ++ src/components/views/elements/TagTile.js | 2 ++ src/components/views/elements/TextWithTooltip.js | 2 ++ src/components/views/elements/TintableSvg.js | 2 ++ src/components/views/elements/Tooltip.tsx | 2 ++ src/components/views/elements/TooltipButton.js | 2 ++ src/components/views/elements/TruncatedList.js | 2 ++ src/components/views/elements/UserTagTile.tsx | 2 ++ 82 files changed, 164 insertions(+), 2 deletions(-) diff --git a/src/components/views/dialogs/ConfirmWipeDeviceDialog.js b/src/components/views/dialogs/ConfirmWipeDeviceDialog.js index 41ef9131fa..4faaad0f7e 100644 --- a/src/components/views/dialogs/ConfirmWipeDeviceDialog.js +++ b/src/components/views/dialogs/ConfirmWipeDeviceDialog.js @@ -18,7 +18,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import {_t} from "../../../languageHandler"; import * as sdk from "../../../index"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.ConfirmWipeDeviceDialog") export default class ConfirmWipeDeviceDialog extends React.Component { static propTypes = { onFinished: PropTypes.func.isRequired, diff --git a/src/components/views/dialogs/CreateCommunityPrototypeDialog.tsx b/src/components/views/dialogs/CreateCommunityPrototypeDialog.tsx index 1d9d92b9c9..9b4484d661 100644 --- a/src/components/views/dialogs/CreateCommunityPrototypeDialog.tsx +++ b/src/components/views/dialogs/CreateCommunityPrototypeDialog.tsx @@ -25,6 +25,7 @@ import InfoTooltip from "../elements/InfoTooltip"; import dis from "../../../dispatcher/dispatcher"; import {showCommunityRoomInviteDialog} from "../../../RoomInvite"; import GroupStore from "../../../stores/GroupStore"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps extends IDialogProps { } @@ -38,6 +39,7 @@ interface IState { avatarPreview: string; } +@replaceableComponent("views.dialogs.CreateCommunityPrototypeDialog") export default class CreateCommunityPrototypeDialog extends React.PureComponent { private avatarUploadRef: React.RefObject = React.createRef(); diff --git a/src/components/views/dialogs/CreateGroupDialog.js b/src/components/views/dialogs/CreateGroupDialog.js index 6636153c98..e6c7a67aca 100644 --- a/src/components/views/dialogs/CreateGroupDialog.js +++ b/src/components/views/dialogs/CreateGroupDialog.js @@ -20,7 +20,9 @@ import * as sdk from '../../../index'; import dis from '../../../dispatcher/dispatcher'; import { _t } from '../../../languageHandler'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.CreateGroupDialog") export default class CreateGroupDialog extends React.Component { static propTypes = { onFinished: PropTypes.func.isRequired, diff --git a/src/components/views/dialogs/CreateRoomDialog.js b/src/components/views/dialogs/CreateRoomDialog.js index 0771b0ec45..e9dc6e2be0 100644 --- a/src/components/views/dialogs/CreateRoomDialog.js +++ b/src/components/views/dialogs/CreateRoomDialog.js @@ -27,7 +27,9 @@ import {MatrixClientPeg} from '../../../MatrixClientPeg'; import {Key} from "../../../Keyboard"; import {privateShouldBeEncrypted} from "../../../createRoom"; import {CommunityPrototypeStore} from "../../../stores/CommunityPrototypeStore"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.CreateRoomDialog") export default class CreateRoomDialog extends React.Component { static propTypes = { onFinished: PropTypes.func.isRequired, diff --git a/src/components/views/dialogs/DeactivateAccountDialog.js b/src/components/views/dialogs/DeactivateAccountDialog.js index fca8c42546..4e52549d51 100644 --- a/src/components/views/dialogs/DeactivateAccountDialog.js +++ b/src/components/views/dialogs/DeactivateAccountDialog.js @@ -26,7 +26,9 @@ import { _t } from '../../../languageHandler'; import InteractiveAuth, {ERROR_USER_CANCELLED} from "../../structures/InteractiveAuth"; import {DEFAULT_PHASE, PasswordAuthEntry, SSOAuthEntry} from "../auth/InteractiveAuthEntryComponents"; import StyledCheckbox from "../elements/StyledCheckbox"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.DeactivateAccountDialog") export default class DeactivateAccountDialog extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/dialogs/DevtoolsDialog.js b/src/components/views/dialogs/DevtoolsDialog.js index 814378bb51..9b24aaa571 100644 --- a/src/components/views/dialogs/DevtoolsDialog.js +++ b/src/components/views/dialogs/DevtoolsDialog.js @@ -38,6 +38,7 @@ import {SETTINGS} from "../../../settings/Settings"; import SettingsStore, {LEVEL_ORDER} from "../../../settings/SettingsStore"; import Modal from "../../../Modal"; import ErrorDialog from "./ErrorDialog"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; class GenericEditor extends React.PureComponent { // static propTypes = {onBack: PropTypes.func.isRequired}; @@ -1089,6 +1090,7 @@ const Entries = [ SettingsExplorer, ]; +@replaceableComponent("views.dialogs.DevtoolsDialog") export default class DevtoolsDialog extends React.PureComponent { static propTypes = { roomId: PropTypes.string.isRequired, diff --git a/src/components/views/dialogs/EditCommunityPrototypeDialog.tsx b/src/components/views/dialogs/EditCommunityPrototypeDialog.tsx index 3071854b3e..504d563bd9 100644 --- a/src/components/views/dialogs/EditCommunityPrototypeDialog.tsx +++ b/src/components/views/dialogs/EditCommunityPrototypeDialog.tsx @@ -23,6 +23,7 @@ import AccessibleButton from "../elements/AccessibleButton"; import { MatrixClientPeg } from "../../../MatrixClientPeg"; import { CommunityPrototypeStore } from "../../../stores/CommunityPrototypeStore"; import FlairStore from "../../../stores/FlairStore"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps extends IDialogProps { communityId: string; @@ -38,6 +39,7 @@ interface IState { } // XXX: This is a lot of duplication from the create dialog, just in a different shape +@replaceableComponent("views.dialogs.EditCommunityPrototypeDialog") export default class EditCommunityPrototypeDialog extends React.PureComponent { private avatarUploadRef: React.RefObject = React.createRef(); diff --git a/src/components/views/dialogs/ErrorDialog.js b/src/components/views/dialogs/ErrorDialog.js index 3bfa635adf..5197c68b5a 100644 --- a/src/components/views/dialogs/ErrorDialog.js +++ b/src/components/views/dialogs/ErrorDialog.js @@ -29,7 +29,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.ErrorDialog") export default class ErrorDialog extends React.Component { static propTypes = { title: PropTypes.string, diff --git a/src/components/views/dialogs/HostSignupDialog.tsx b/src/components/views/dialogs/HostSignupDialog.tsx index 45a03b7cf0..c8bc907136 100644 --- a/src/components/views/dialogs/HostSignupDialog.tsx +++ b/src/components/views/dialogs/HostSignupDialog.tsx @@ -31,6 +31,7 @@ import { IPostmessageResponseData, PostmessageAction, } from "./HostSignupDialogTypes"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const HOST_SIGNUP_KEY = "host_signup"; @@ -42,6 +43,7 @@ interface IState { minimized: boolean; } +@replaceableComponent("views.dialogs.HostSignupDialog") export default class HostSignupDialog extends React.PureComponent { private iframeRef: React.RefObject = React.createRef(); private readonly config: IHostSignupConfig; diff --git a/src/components/views/dialogs/IncomingSasDialog.js b/src/components/views/dialogs/IncomingSasDialog.js index 2a4ff9cec3..d65ec7563f 100644 --- a/src/components/views/dialogs/IncomingSasDialog.js +++ b/src/components/views/dialogs/IncomingSasDialog.js @@ -19,6 +19,7 @@ import PropTypes from 'prop-types'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const PHASE_START = 0; const PHASE_SHOW_SAS = 1; @@ -26,6 +27,7 @@ const PHASE_WAIT_FOR_PARTNER_TO_CONFIRM = 2; const PHASE_VERIFIED = 3; const PHASE_CANCELLED = 4; +@replaceableComponent("views.dialogs.IncomingSasDialog") export default class IncomingSasDialog extends React.Component { static propTypes = { verifier: PropTypes.object.isRequired, diff --git a/src/components/views/dialogs/IntegrationsDisabledDialog.js b/src/components/views/dialogs/IntegrationsDisabledDialog.js index 7c996fbeab..0e9878f4bc 100644 --- a/src/components/views/dialogs/IntegrationsDisabledDialog.js +++ b/src/components/views/dialogs/IntegrationsDisabledDialog.js @@ -20,7 +20,9 @@ import {_t} from "../../../languageHandler"; import * as sdk from "../../../index"; import dis from '../../../dispatcher/dispatcher'; import {Action} from "../../../dispatcher/actions"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.IntegrationsDisabledDialog") export default class IntegrationsDisabledDialog extends React.Component { static propTypes = { onFinished: PropTypes.func.isRequired, diff --git a/src/components/views/dialogs/IntegrationsImpossibleDialog.js b/src/components/views/dialogs/IntegrationsImpossibleDialog.js index 68bedc711d..9bc9d02ba6 100644 --- a/src/components/views/dialogs/IntegrationsImpossibleDialog.js +++ b/src/components/views/dialogs/IntegrationsImpossibleDialog.js @@ -19,7 +19,9 @@ import PropTypes from 'prop-types'; import {_t} from "../../../languageHandler"; import SdkConfig from "../../../SdkConfig"; import * as sdk from "../../../index"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.IntegrationsImpossibleDialog") export default class IntegrationsImpossibleDialog extends React.Component { static propTypes = { onFinished: PropTypes.func.isRequired, diff --git a/src/components/views/dialogs/InteractiveAuthDialog.js b/src/components/views/dialogs/InteractiveAuthDialog.js index 22291225ad..28a9bf673a 100644 --- a/src/components/views/dialogs/InteractiveAuthDialog.js +++ b/src/components/views/dialogs/InteractiveAuthDialog.js @@ -25,7 +25,9 @@ import { _t } from '../../../languageHandler'; import AccessibleButton from '../elements/AccessibleButton'; import {ERROR_USER_CANCELLED} from "../../structures/InteractiveAuth"; import {SSOAuthEntry} from "../auth/InteractiveAuthEntryComponents"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.InteractiveAuthDialog") export default class InteractiveAuthDialog extends React.Component { static propTypes = { // matrix client to use for UI auth requests diff --git a/src/components/views/dialogs/InviteDialog.tsx b/src/components/views/dialogs/InviteDialog.tsx index 9bc5b6476f..db9077291e 100644 --- a/src/components/views/dialogs/InviteDialog.tsx +++ b/src/components/views/dialogs/InviteDialog.tsx @@ -42,6 +42,7 @@ import {UIFeature} from "../../../settings/UIFeature"; import CountlyAnalytics from "../../../CountlyAnalytics"; import {Room} from "matrix-js-sdk/src/models/room"; import { MatrixCall } from 'matrix-js-sdk/src/webrtc/call'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; // we have a number of types defined from the Matrix spec which can't reasonably be altered here. /* eslint-disable camelcase */ @@ -337,6 +338,7 @@ interface IInviteDialogState { errorText: string, } +@replaceableComponent("views.dialogs.InviteDialog") export default class InviteDialog extends React.PureComponent { static defaultProps = { kind: KIND_DM, diff --git a/src/components/views/dialogs/LogoutDialog.js b/src/components/views/dialogs/LogoutDialog.js index af36dba2b6..7bced46d43 100644 --- a/src/components/views/dialogs/LogoutDialog.js +++ b/src/components/views/dialogs/LogoutDialog.js @@ -22,7 +22,9 @@ import dis from '../../../dispatcher/dispatcher'; import { _t } from '../../../languageHandler'; import { MatrixClientPeg } from '../../../MatrixClientPeg'; import RestoreKeyBackupDialog from './security/RestoreKeyBackupDialog'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.LogoutDialog") export default class LogoutDialog extends React.Component { defaultProps = { onFinished: function() {}, diff --git a/src/components/views/dialogs/ManualDeviceKeyVerificationDialog.js b/src/components/views/dialogs/ManualDeviceKeyVerificationDialog.js index 4b9d7239e6..3151edd796 100644 --- a/src/components/views/dialogs/ManualDeviceKeyVerificationDialog.js +++ b/src/components/views/dialogs/ManualDeviceKeyVerificationDialog.js @@ -24,7 +24,9 @@ import {MatrixClientPeg} from '../../../MatrixClientPeg'; import * as sdk from '../../../index'; import * as FormattingUtils from '../../../utils/FormattingUtils'; import { _t } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.ManualDeviceKeyVerificationDialog") export default class ManualDeviceKeyVerificationDialog extends React.Component { static propTypes = { userId: PropTypes.string.isRequired, diff --git a/src/components/views/dialogs/MessageEditHistoryDialog.js b/src/components/views/dialogs/MessageEditHistoryDialog.js index 2bdf2be35c..7585561c0c 100644 --- a/src/components/views/dialogs/MessageEditHistoryDialog.js +++ b/src/components/views/dialogs/MessageEditHistoryDialog.js @@ -21,7 +21,9 @@ import { _t } from '../../../languageHandler'; import * as sdk from "../../../index"; import {wantsDateSeparator} from '../../../DateUtils'; import SettingsStore from '../../../settings/SettingsStore'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.MessageEditHistoryDialog") export default class MessageEditHistoryDialog extends React.PureComponent { static propTypes = { mxEvent: PropTypes.object.isRequired, diff --git a/src/components/views/dialogs/ModalWidgetDialog.tsx b/src/components/views/dialogs/ModalWidgetDialog.tsx index 92fb406965..59eaab7b81 100644 --- a/src/components/views/dialogs/ModalWidgetDialog.tsx +++ b/src/components/views/dialogs/ModalWidgetDialog.tsx @@ -38,6 +38,7 @@ import {MatrixClientPeg} from "../../../MatrixClientPeg"; import {OwnProfileStore} from "../../../stores/OwnProfileStore"; import { arrayFastClone } from "../../../utils/arrays"; import { ElementWidget } from "../../../stores/widgets/StopGapWidget"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { widgetDefinition: IModalWidgetOpenRequestData; @@ -53,6 +54,7 @@ interface IState { const MAX_BUTTONS = 3; +@replaceableComponent("views.dialogs.ModalWidgetDialog") export default class ModalWidgetDialog extends React.PureComponent { private readonly widget: Widget; private readonly possibleButtons: ModalButtonID[]; diff --git a/src/components/views/dialogs/ReportEventDialog.js b/src/components/views/dialogs/ReportEventDialog.js index f5509dec4d..67ed0f8f53 100644 --- a/src/components/views/dialogs/ReportEventDialog.js +++ b/src/components/views/dialogs/ReportEventDialog.js @@ -22,10 +22,12 @@ import {MatrixEvent} from "matrix-js-sdk"; import {MatrixClientPeg} from "../../../MatrixClientPeg"; import SdkConfig from '../../../SdkConfig'; import Markdown from '../../../Markdown'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; /* * A dialog for reporting an event. */ +@replaceableComponent("views.dialogs.ReportEventDialog") export default class ReportEventDialog extends PureComponent { static propTypes = { mxEvent: PropTypes.instanceOf(MatrixEvent).isRequired, diff --git a/src/components/views/dialogs/RoomSettingsDialog.js b/src/components/views/dialogs/RoomSettingsDialog.js index 9d9313f08f..045d11404a 100644 --- a/src/components/views/dialogs/RoomSettingsDialog.js +++ b/src/components/views/dialogs/RoomSettingsDialog.js @@ -30,6 +30,7 @@ import {MatrixClientPeg} from "../../../MatrixClientPeg"; import dis from "../../../dispatcher/dispatcher"; import SettingsStore from "../../../settings/SettingsStore"; import {UIFeature} from "../../../settings/UIFeature"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; export const ROOM_GENERAL_TAB = "ROOM_GENERAL_TAB"; export const ROOM_SECURITY_TAB = "ROOM_SECURITY_TAB"; @@ -38,6 +39,7 @@ export const ROOM_NOTIFICATIONS_TAB = "ROOM_NOTIFICATIONS_TAB"; export const ROOM_BRIDGES_TAB = "ROOM_BRIDGES_TAB"; export const ROOM_ADVANCED_TAB = "ROOM_ADVANCED_TAB"; +@replaceableComponent("views.dialogs.RoomSettingsDialog") export default class RoomSettingsDialog extends React.Component { static propTypes = { roomId: PropTypes.string.isRequired, diff --git a/src/components/views/dialogs/RoomUpgradeDialog.js b/src/components/views/dialogs/RoomUpgradeDialog.js index 85e97444ed..8f9ed42ada 100644 --- a/src/components/views/dialogs/RoomUpgradeDialog.js +++ b/src/components/views/dialogs/RoomUpgradeDialog.js @@ -20,7 +20,9 @@ import * as sdk from '../../../index'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; import Modal from '../../../Modal'; import { _t } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.RoomUpgradeDialog") export default class RoomUpgradeDialog extends React.Component { static propTypes = { room: PropTypes.object.isRequired, diff --git a/src/components/views/dialogs/RoomUpgradeWarningDialog.js b/src/components/views/dialogs/RoomUpgradeWarningDialog.js index c83528c5ba..452ac56dff 100644 --- a/src/components/views/dialogs/RoomUpgradeWarningDialog.js +++ b/src/components/views/dialogs/RoomUpgradeWarningDialog.js @@ -22,7 +22,9 @@ import * as sdk from "../../../index"; import LabelledToggleSwitch from "../elements/LabelledToggleSwitch"; import {MatrixClientPeg} from "../../../MatrixClientPeg"; import Modal from "../../../Modal"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.RoomUpgradeWarningDialog") export default class RoomUpgradeWarningDialog extends React.Component { static propTypes = { onFinished: PropTypes.func.isRequired, diff --git a/src/components/views/dialogs/ServerOfflineDialog.tsx b/src/components/views/dialogs/ServerOfflineDialog.tsx index 81f628343b..52ff056907 100644 --- a/src/components/views/dialogs/ServerOfflineDialog.tsx +++ b/src/components/views/dialogs/ServerOfflineDialog.tsx @@ -28,10 +28,12 @@ import AccessibleButton from "../elements/AccessibleButton"; import { UPDATE_EVENT } from "../../../stores/AsyncStore"; import { MatrixClientPeg } from "../../../MatrixClientPeg"; import { IDialogProps } from "./IDialogProps"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps extends IDialogProps { } +@replaceableComponent("views.dialogs.ServerOfflineDialog") export default class ServerOfflineDialog extends React.PureComponent { public componentDidMount() { EchoStore.instance.on(UPDATE_EVENT, this.onEchosUpdated); diff --git a/src/components/views/dialogs/ServerPickerDialog.tsx b/src/components/views/dialogs/ServerPickerDialog.tsx index 7ca115760e..4abc0a88b1 100644 --- a/src/components/views/dialogs/ServerPickerDialog.tsx +++ b/src/components/views/dialogs/ServerPickerDialog.tsx @@ -26,6 +26,7 @@ import Field from "../elements/Field"; import StyledRadioButton from "../elements/StyledRadioButton"; import TextWithTooltip from "../elements/TextWithTooltip"; import withValidation, {IFieldState} from "../elements/Validation"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { title?: string; @@ -38,6 +39,7 @@ interface IState { otherHomeserver: string; } +@replaceableComponent("views.dialogs.ServerPickerDialog") export default class ServerPickerDialog extends React.PureComponent { private readonly defaultServer: ValidatedServerConfig; private readonly fieldRef = createRef(); diff --git a/src/components/views/dialogs/SessionRestoreErrorDialog.js b/src/components/views/dialogs/SessionRestoreErrorDialog.js index bae6b19fbe..50d7fbea09 100644 --- a/src/components/views/dialogs/SessionRestoreErrorDialog.js +++ b/src/components/views/dialogs/SessionRestoreErrorDialog.js @@ -22,8 +22,9 @@ import * as sdk from '../../../index'; import SdkConfig from '../../../SdkConfig'; import Modal from '../../../Modal'; import { _t } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; - +@replaceableComponent("views.dialogs.SessionRestoreErrorDialog") export default class SessionRestoreErrorDialog extends React.Component { static propTypes = { error: PropTypes.string.isRequired, diff --git a/src/components/views/dialogs/SetEmailDialog.js b/src/components/views/dialogs/SetEmailDialog.js index 6514d94dc9..0f8f410a6a 100644 --- a/src/components/views/dialogs/SetEmailDialog.js +++ b/src/components/views/dialogs/SetEmailDialog.js @@ -22,6 +22,7 @@ import * as Email from '../../../email'; import AddThreepid from '../../../AddThreepid'; import { _t } from '../../../languageHandler'; import Modal from '../../../Modal'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; /* @@ -29,6 +30,7 @@ import Modal from '../../../Modal'; * * On success, `onFinished(true)` is called. */ +@replaceableComponent("views.dialogs.SetEmailDialog") export default class SetEmailDialog extends React.Component { static propTypes = { onFinished: PropTypes.func.isRequired, diff --git a/src/components/views/dialogs/ShareDialog.tsx b/src/components/views/dialogs/ShareDialog.tsx index 5264031cc6..df1206a4f0 100644 --- a/src/components/views/dialogs/ShareDialog.tsx +++ b/src/components/views/dialogs/ShareDialog.tsx @@ -34,6 +34,7 @@ import AccessibleTooltipButton from '../elements/AccessibleTooltipButton'; import { IDialogProps } from "./IDialogProps"; import SettingsStore from "../../../settings/SettingsStore"; import {UIFeature} from "../../../settings/UIFeature"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const socials = [ { @@ -73,6 +74,7 @@ interface IState { permalinkCreator: RoomPermalinkCreator; } +@replaceableComponent("views.dialogs.ShareDialog") export default class ShareDialog extends React.PureComponent { static propTypes = { onFinished: PropTypes.func.isRequired, diff --git a/src/components/views/dialogs/StorageEvictedDialog.js b/src/components/views/dialogs/StorageEvictedDialog.js index a22f302807..15c5347644 100644 --- a/src/components/views/dialogs/StorageEvictedDialog.js +++ b/src/components/views/dialogs/StorageEvictedDialog.js @@ -20,7 +20,9 @@ import * as sdk from '../../../index'; import SdkConfig from '../../../SdkConfig'; import Modal from '../../../Modal'; import { _t } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.StorageEvictedDialog") export default class StorageEvictedDialog extends React.Component { static propTypes = { onFinished: PropTypes.func.isRequired, diff --git a/src/components/views/dialogs/TabbedIntegrationManagerDialog.js b/src/components/views/dialogs/TabbedIntegrationManagerDialog.js index 9f5c9f6a11..07e29adcff 100644 --- a/src/components/views/dialogs/TabbedIntegrationManagerDialog.js +++ b/src/components/views/dialogs/TabbedIntegrationManagerDialog.js @@ -22,7 +22,9 @@ import * as sdk from '../../../index'; import {dialogTermsInteractionCallback, TermsNotSignedError} from "../../../Terms"; import classNames from 'classnames'; import * as ScalarMessaging from "../../../ScalarMessaging"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.TabbedIntegrationManagerDialog") export default class TabbedIntegrationManagerDialog extends React.Component { static propTypes = { /** diff --git a/src/components/views/dialogs/TermsDialog.js b/src/components/views/dialogs/TermsDialog.js index 402605c545..72e6c3f3a0 100644 --- a/src/components/views/dialogs/TermsDialog.js +++ b/src/components/views/dialogs/TermsDialog.js @@ -21,6 +21,7 @@ import * as sdk from '../../../index'; import { _t, pickBestLanguage } from '../../../languageHandler'; import Matrix from 'matrix-js-sdk'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; class TermsCheckbox extends React.PureComponent { static propTypes = { @@ -41,6 +42,7 @@ class TermsCheckbox extends React.PureComponent { } } +@replaceableComponent("views.dialogs.TermsDialog") export default class TermsDialog extends React.PureComponent { static propTypes = { /** diff --git a/src/components/views/dialogs/TextInputDialog.js b/src/components/views/dialogs/TextInputDialog.js index 69cc4390be..97abd209c0 100644 --- a/src/components/views/dialogs/TextInputDialog.js +++ b/src/components/views/dialogs/TextInputDialog.js @@ -19,7 +19,9 @@ import PropTypes from 'prop-types'; import * as sdk from '../../../index'; import Field from "../elements/Field"; import { _t, _td } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.TextInputDialog") export default class TextInputDialog extends React.Component { static propTypes = { title: PropTypes.string, diff --git a/src/components/views/dialogs/UploadConfirmDialog.js b/src/components/views/dialogs/UploadConfirmDialog.js index e3521eb282..2ff16b9440 100644 --- a/src/components/views/dialogs/UploadConfirmDialog.js +++ b/src/components/views/dialogs/UploadConfirmDialog.js @@ -20,7 +20,9 @@ import PropTypes from 'prop-types'; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; import filesize from "filesize"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.UploadConfirmDialog") export default class UploadConfirmDialog extends React.Component { static propTypes = { file: PropTypes.object.isRequired, diff --git a/src/components/views/dialogs/UploadFailureDialog.js b/src/components/views/dialogs/UploadFailureDialog.js index 4be1656f66..d220d6c684 100644 --- a/src/components/views/dialogs/UploadFailureDialog.js +++ b/src/components/views/dialogs/UploadFailureDialog.js @@ -21,12 +21,14 @@ import PropTypes from 'prop-types'; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; import ContentMessages from '../../../ContentMessages'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; /* * Tells the user about files we know cannot be uploaded before we even try uploading * them. This is named fairly generically but the only thing we check right now is * the size of the file. */ +@replaceableComponent("views.dialogs.UploadFailureDialog") export default class UploadFailureDialog extends React.Component { static propTypes = { badFiles: PropTypes.arrayOf(PropTypes.object).isRequired, diff --git a/src/components/views/dialogs/UserSettingsDialog.js b/src/components/views/dialogs/UserSettingsDialog.js index 7164540aea..32abef874b 100644 --- a/src/components/views/dialogs/UserSettingsDialog.js +++ b/src/components/views/dialogs/UserSettingsDialog.js @@ -33,6 +33,7 @@ import * as sdk from "../../../index"; import SdkConfig from "../../../SdkConfig"; import MjolnirUserSettingsTab from "../settings/tabs/user/MjolnirUserSettingsTab"; import {UIFeature} from "../../../settings/UIFeature"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; export const USER_GENERAL_TAB = "USER_GENERAL_TAB"; export const USER_APPEARANCE_TAB = "USER_APPEARANCE_TAB"; @@ -45,6 +46,7 @@ export const USER_LABS_TAB = "USER_LABS_TAB"; export const USER_MJOLNIR_TAB = "USER_MJOLNIR_TAB"; export const USER_HELP_TAB = "USER_HELP_TAB"; +@replaceableComponent("views.dialogs.UserSettingsDialog") export default class UserSettingsDialog extends React.Component { static propTypes = { onFinished: PropTypes.func.isRequired, diff --git a/src/components/views/dialogs/VerificationRequestDialog.js b/src/components/views/dialogs/VerificationRequestDialog.js index 3a6e9a2d10..574beebbc6 100644 --- a/src/components/views/dialogs/VerificationRequestDialog.js +++ b/src/components/views/dialogs/VerificationRequestDialog.js @@ -19,7 +19,9 @@ import PropTypes from 'prop-types'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.VerificationRequestDialog") export default class VerificationRequestDialog extends React.Component { static propTypes = { verificationRequest: PropTypes.object, diff --git a/src/components/views/dialogs/WidgetCapabilitiesPromptDialog.tsx b/src/components/views/dialogs/WidgetCapabilitiesPromptDialog.tsx index 535e0b7b8e..70fe7fe5e3 100644 --- a/src/components/views/dialogs/WidgetCapabilitiesPromptDialog.tsx +++ b/src/components/views/dialogs/WidgetCapabilitiesPromptDialog.tsx @@ -29,6 +29,7 @@ import StyledCheckbox from "../elements/StyledCheckbox"; import DialogButtons from "../elements/DialogButtons"; import LabelledToggleSwitch from "../elements/LabelledToggleSwitch"; import { CapabilityText } from "../../../widgets/CapabilityText"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; export function getRememberedCapabilitiesForWidget(widget: Widget): Capability[] { return JSON.parse(localStorage.getItem(`widget_${widget.id}_approved_caps`) || "[]"); @@ -54,6 +55,7 @@ interface IState { rememberSelection: boolean; } +@replaceableComponent("views.dialogs.WidgetCapabilitiesPromptDialog") export default class WidgetCapabilitiesPromptDialog extends React.PureComponent { private eventPermissionsMap = new Map(); diff --git a/src/components/views/dialogs/WidgetOpenIDPermissionsDialog.js b/src/components/views/dialogs/WidgetOpenIDPermissionsDialog.js index c01d3d39b8..f45adf9738 100644 --- a/src/components/views/dialogs/WidgetOpenIDPermissionsDialog.js +++ b/src/components/views/dialogs/WidgetOpenIDPermissionsDialog.js @@ -21,7 +21,9 @@ import * as sdk from "../../../index"; import LabelledToggleSwitch from "../elements/LabelledToggleSwitch"; import {Widget} from "matrix-widget-api"; import {OIDCState, WidgetPermissionStore} from "../../../stores/widgets/WidgetPermissionStore"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.WidgetOpenIDPermissionsDialog") export default class WidgetOpenIDPermissionsDialog extends React.Component { static propTypes = { onFinished: PropTypes.func.isRequired, diff --git a/src/components/views/elements/AccessibleTooltipButton.tsx b/src/components/views/elements/AccessibleTooltipButton.tsx index b7c7b78e63..3bb264fb3e 100644 --- a/src/components/views/elements/AccessibleTooltipButton.tsx +++ b/src/components/views/elements/AccessibleTooltipButton.tsx @@ -20,6 +20,7 @@ import classNames from 'classnames'; import AccessibleButton from "./AccessibleButton"; import Tooltip from './Tooltip'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface ITooltipProps extends React.ComponentProps { title: string; @@ -33,6 +34,7 @@ interface IState { hover: boolean; } +@replaceableComponent("views.elements.AccessibleTooltipButton") export default class AccessibleTooltipButton extends React.PureComponent { constructor(props: ITooltipProps) { super(props); diff --git a/src/components/views/elements/ActionButton.js b/src/components/views/elements/ActionButton.js index bec016bce0..1714891cb5 100644 --- a/src/components/views/elements/ActionButton.js +++ b/src/components/views/elements/ActionButton.js @@ -20,7 +20,9 @@ import AccessibleButton from './AccessibleButton'; import dis from '../../../dispatcher/dispatcher'; import * as sdk from '../../../index'; import Analytics from '../../../Analytics'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.ActionButton") export default class ActionButton extends React.Component { static propTypes = { size: PropTypes.string, diff --git a/src/components/views/elements/AddressSelector.js b/src/components/views/elements/AddressSelector.js index 2a71622bb8..33b2906870 100644 --- a/src/components/views/elements/AddressSelector.js +++ b/src/components/views/elements/AddressSelector.js @@ -20,7 +20,9 @@ import PropTypes from 'prop-types'; import * as sdk from '../../../index'; import classNames from 'classnames'; import { UserAddressType } from '../../../UserAddress'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.AddressSelector") export default class AddressSelector extends React.Component { static propTypes = { onSelected: PropTypes.func.isRequired, diff --git a/src/components/views/elements/AddressTile.js b/src/components/views/elements/AddressTile.js index dc6c6b2914..4a216dbae4 100644 --- a/src/components/views/elements/AddressTile.js +++ b/src/components/views/elements/AddressTile.js @@ -22,8 +22,9 @@ import * as sdk from "../../../index"; import {MatrixClientPeg} from "../../../MatrixClientPeg"; import { _t } from '../../../languageHandler'; import { UserAddressType } from '../../../UserAddress.js'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; - +@replaceableComponent("views.elements.AddressTile") export default class AddressTile extends React.Component { static propTypes = { address: UserAddressType.isRequired, diff --git a/src/components/views/elements/AppPermission.js b/src/components/views/elements/AppPermission.js index ec8bffc32f..65e40ef19a 100644 --- a/src/components/views/elements/AppPermission.js +++ b/src/components/views/elements/AppPermission.js @@ -24,7 +24,9 @@ import { _t } from '../../../languageHandler'; import SdkConfig from '../../../SdkConfig'; import WidgetUtils from "../../../utils/WidgetUtils"; import {MatrixClientPeg} from "../../../MatrixClientPeg"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.AppPermission") export default class AppPermission extends React.Component { static propTypes = { url: PropTypes.string.isRequired, diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 2a72621ccc..e206fda797 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -38,7 +38,9 @@ import {ElementWidgetActions} from "../../../stores/widgets/ElementWidgetActions import {MatrixCapabilities} from "matrix-widget-api"; import RoomWidgetContextMenu from "../context_menus/WidgetContextMenu"; import WidgetAvatar from "../avatars/WidgetAvatar"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.AppTile") export default class AppTile extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/elements/DesktopCapturerSourcePicker.tsx b/src/components/views/elements/DesktopCapturerSourcePicker.tsx index 6ae465c362..2d066a7ed7 100644 --- a/src/components/views/elements/DesktopCapturerSourcePicker.tsx +++ b/src/components/views/elements/DesktopCapturerSourcePicker.tsx @@ -19,6 +19,7 @@ import { _t } from '../../../languageHandler'; import BaseDialog from "..//dialogs/BaseDialog" import AccessibleButton from './AccessibleButton'; import {getDesktopCapturerSources} from "matrix-js-sdk/src/webrtc/call"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; export interface DesktopCapturerSource { id: string; @@ -69,6 +70,7 @@ export interface DesktopCapturerSourcePickerIProps { onFinished(source: DesktopCapturerSource): void; } +@replaceableComponent("views.elements.DesktopCapturerSourcePicker") export default class DesktopCapturerSourcePicker extends React.Component< DesktopCapturerSourcePickerIProps, DesktopCapturerSourcePickerIState diff --git a/src/components/views/elements/DialogButtons.js b/src/components/views/elements/DialogButtons.js index 3417485eb8..dcb1cee077 100644 --- a/src/components/views/elements/DialogButtons.js +++ b/src/components/views/elements/DialogButtons.js @@ -19,10 +19,12 @@ limitations under the License. import React from "react"; import PropTypes from "prop-types"; import { _t } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; /** * Basic container for buttons in modal dialogs. */ +@replaceableComponent("views.elements.DialogButtons") export default class DialogButtons extends React.Component { static propTypes = { // The primary button which is styled differently and has default focus. diff --git a/src/components/views/elements/DirectorySearchBox.js b/src/components/views/elements/DirectorySearchBox.js index 644b69417b..6447bb3cd8 100644 --- a/src/components/views/elements/DirectorySearchBox.js +++ b/src/components/views/elements/DirectorySearchBox.js @@ -18,7 +18,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.DirectorySearchBox") export default class DirectorySearchBox extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/elements/Draggable.tsx b/src/components/views/elements/Draggable.tsx index a6eb8323f3..6032721a48 100644 --- a/src/components/views/elements/Draggable.tsx +++ b/src/components/views/elements/Draggable.tsx @@ -15,6 +15,7 @@ limitations under the License. */ import React from 'react'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { className: string; @@ -33,6 +34,7 @@ export interface ILocationState { currentY: number; } +@replaceableComponent("views.elements.Draggable") export default class Draggable extends React.Component { constructor(props: IProps) { super(props); diff --git a/src/components/views/elements/Dropdown.js b/src/components/views/elements/Dropdown.js index 6b3efb5ee1..981c0becc0 100644 --- a/src/components/views/elements/Dropdown.js +++ b/src/components/views/elements/Dropdown.js @@ -22,6 +22,7 @@ import classnames from 'classnames'; import AccessibleButton from './AccessibleButton'; import { _t } from '../../../languageHandler'; import {Key} from "../../../Keyboard"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; class MenuOption extends React.Component { constructor(props) { @@ -83,6 +84,7 @@ MenuOption.propTypes = { * * TODO: Port NetworkDropdown to use this. */ +@replaceableComponent("views.elements.Dropdown") export default class Dropdown extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/elements/EditableItemList.js b/src/components/views/elements/EditableItemList.js index 5a07a400d7..ff62f169fa 100644 --- a/src/components/views/elements/EditableItemList.js +++ b/src/components/views/elements/EditableItemList.js @@ -19,6 +19,7 @@ import PropTypes from 'prop-types'; import {_t} from '../../../languageHandler'; import Field from "./Field"; import AccessibleButton from "./AccessibleButton"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; export class EditableItem extends React.Component { static propTypes = { @@ -85,6 +86,7 @@ export class EditableItem extends React.Component { } } +@replaceableComponent("views.elements.EditableItemList") export default class EditableItemList extends React.Component { static propTypes = { id: PropTypes.string.isRequired, diff --git a/src/components/views/elements/EditableText.js b/src/components/views/elements/EditableText.js index 49eb331aef..638fd02553 100644 --- a/src/components/views/elements/EditableText.js +++ b/src/components/views/elements/EditableText.js @@ -18,7 +18,9 @@ limitations under the License. import React, {createRef} from 'react'; import PropTypes from 'prop-types'; import {Key} from "../../../Keyboard"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.EditableText") export default class EditableText extends React.Component { static propTypes = { onValueChanged: PropTypes.func, diff --git a/src/components/views/elements/EditableTextContainer.js b/src/components/views/elements/EditableTextContainer.js index bbc5560557..e925220089 100644 --- a/src/components/views/elements/EditableTextContainer.js +++ b/src/components/views/elements/EditableTextContainer.js @@ -17,6 +17,7 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import * as sdk from '../../../index'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; /** * A component which wraps an EditableText, with a spinner while updates take @@ -29,6 +30,7 @@ import * as sdk from '../../../index'; * similarly asynchronous way. If this is not provided, the initial value is * taken from the 'initialValue' property. */ +@replaceableComponent("views.elements.EditableTextContainer") export default class EditableTextContainer extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/elements/ErrorBoundary.js b/src/components/views/elements/ErrorBoundary.js index 9fe6861250..9037287f49 100644 --- a/src/components/views/elements/ErrorBoundary.js +++ b/src/components/views/elements/ErrorBoundary.js @@ -21,11 +21,13 @@ import {MatrixClientPeg} from '../../../MatrixClientPeg'; import PlatformPeg from '../../../PlatformPeg'; import Modal from '../../../Modal'; import SdkConfig from "../../../SdkConfig"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; /** * This error boundary component can be used to wrap large content areas and * catch exceptions during rendering in the component tree below them. */ +@replaceableComponent("views.elements.ErrorBoundary") export default class ErrorBoundary extends React.PureComponent { constructor(props) { super(props); diff --git a/src/components/views/elements/EventTilePreview.tsx b/src/components/views/elements/EventTilePreview.tsx index 49c97831bc..c539f2be1c 100644 --- a/src/components/views/elements/EventTilePreview.tsx +++ b/src/components/views/elements/EventTilePreview.tsx @@ -24,6 +24,7 @@ import EventTile from '../rooms/EventTile'; import SettingsStore from "../../../settings/SettingsStore"; import {Layout} from "../../../settings/Layout"; import {UIFeature} from "../../../settings/UIFeature"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { /** @@ -52,6 +53,7 @@ interface IState { const AVATAR_SIZE = 32; +@replaceableComponent("views.elements.EventTilePreview") export default class EventTilePreview extends React.Component { constructor(props: IProps) { super(props); diff --git a/src/components/views/elements/Flair.js b/src/components/views/elements/Flair.js index 0f06904b68..04eba5bc42 100644 --- a/src/components/views/elements/Flair.js +++ b/src/components/views/elements/Flair.js @@ -21,6 +21,7 @@ import PropTypes from 'prop-types'; import FlairStore from '../../../stores/FlairStore'; import dis from '../../../dispatcher/dispatcher'; import MatrixClientContext from "../../../contexts/MatrixClientContext"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; class FlairAvatar extends React.Component { @@ -64,6 +65,7 @@ FlairAvatar.propTypes = { FlairAvatar.contextType = MatrixClientContext; +@replaceableComponent("views.elements.Flair") export default class Flair extends React.Component { constructor() { super(); diff --git a/src/components/views/elements/IRCTimelineProfileResizer.tsx b/src/components/views/elements/IRCTimelineProfileResizer.tsx index ecd63816de..cd1ccf2fc4 100644 --- a/src/components/views/elements/IRCTimelineProfileResizer.tsx +++ b/src/components/views/elements/IRCTimelineProfileResizer.tsx @@ -18,6 +18,7 @@ import React from 'react'; import SettingsStore from "../../../settings/SettingsStore"; import Draggable, {ILocationState} from './Draggable'; import { SettingLevel } from "../../../settings/SettingLevel"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { // Current room @@ -31,6 +32,7 @@ interface IState { IRCLayoutRoot: HTMLElement; } +@replaceableComponent("views.elements.IRCTimelineProfileResizer") export default class IRCTimelineProfileResizer extends React.Component { constructor(props: IProps) { super(props); diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index e39075cedc..96b6de832d 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -26,7 +26,9 @@ import Modal from "../../../Modal"; import * as sdk from "../../../index"; import {Key} from "../../../Keyboard"; import FocusLock from "react-focus-lock"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.ImageView") export default class ImageView extends React.Component { static propTypes = { src: PropTypes.string.isRequired, // the source of the image being displayed diff --git a/src/components/views/elements/InfoTooltip.tsx b/src/components/views/elements/InfoTooltip.tsx index dd21c95b74..8f7f1ea53f 100644 --- a/src/components/views/elements/InfoTooltip.tsx +++ b/src/components/views/elements/InfoTooltip.tsx @@ -20,6 +20,7 @@ import classNames from 'classnames'; import Tooltip from './Tooltip'; import { _t } from "../../../languageHandler"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface ITooltipProps { tooltip?: React.ReactNode; @@ -30,6 +31,7 @@ interface IState { hover: boolean; } +@replaceableComponent("views.elements.InfoTooltip") export default class InfoTooltip extends React.PureComponent { constructor(props: ITooltipProps) { super(props); diff --git a/src/components/views/elements/InlineSpinner.js b/src/components/views/elements/InlineSpinner.js index 73316157f4..3654a1f34c 100644 --- a/src/components/views/elements/InlineSpinner.js +++ b/src/components/views/elements/InlineSpinner.js @@ -17,7 +17,9 @@ limitations under the License. import React from "react"; import {_t} from "../../../languageHandler"; import SettingsStore from "../../../settings/SettingsStore"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.InlineSpinner") export default class InlineSpinner extends React.Component { render() { const w = this.props.w || 16; diff --git a/src/components/views/elements/LabelledToggleSwitch.js b/src/components/views/elements/LabelledToggleSwitch.js index 78beb2aa91..e6378f0e6a 100644 --- a/src/components/views/elements/LabelledToggleSwitch.js +++ b/src/components/views/elements/LabelledToggleSwitch.js @@ -17,7 +17,9 @@ limitations under the License. import React from 'react'; import PropTypes from "prop-types"; import ToggleSwitch from "./ToggleSwitch"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.LabelledToggleSwitch") export default class LabelledToggleSwitch extends React.Component { static propTypes = { // The value for the toggle switch diff --git a/src/components/views/elements/LanguageDropdown.js b/src/components/views/elements/LanguageDropdown.js index 03ec456af5..2e961be700 100644 --- a/src/components/views/elements/LanguageDropdown.js +++ b/src/components/views/elements/LanguageDropdown.js @@ -22,6 +22,7 @@ import * as sdk from '../../../index'; import * as languageHandler from '../../../languageHandler'; import SettingsStore from "../../../settings/SettingsStore"; import { _t } from "../../../languageHandler"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; function languageMatchesSearchQuery(query, language) { if (language.label.toUpperCase().includes(query.toUpperCase())) return true; @@ -29,6 +30,7 @@ function languageMatchesSearchQuery(query, language) { return false; } +@replaceableComponent("views.elements.LanguageDropdown") export default class LanguageDropdown extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/elements/LazyRenderList.js b/src/components/views/elements/LazyRenderList.js index 7572dced0b..f2c8148cd2 100644 --- a/src/components/views/elements/LazyRenderList.js +++ b/src/components/views/elements/LazyRenderList.js @@ -16,6 +16,7 @@ limitations under the License. import React from "react"; import PropTypes from 'prop-types'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; class ItemRange { constructor(topCount, renderCount, bottomCount) { @@ -55,6 +56,7 @@ class ItemRange { } } +@replaceableComponent("views.elements.LazyRenderList") export default class LazyRenderList extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/elements/MemberEventListSummary.tsx b/src/components/views/elements/MemberEventListSummary.tsx index 073bedf207..0290ef6d83 100644 --- a/src/components/views/elements/MemberEventListSummary.tsx +++ b/src/components/views/elements/MemberEventListSummary.tsx @@ -24,6 +24,7 @@ import { _t } from '../../../languageHandler'; import { formatCommaSeparatedList } from '../../../utils/FormattingUtils'; import { isValid3pidInvite } from "../../../RoomInvite"; import EventListSummary from "./EventListSummary"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { // An array of member events to summarise @@ -69,6 +70,7 @@ enum TransitionType { const SEP = ","; +@replaceableComponent("views.elements.MemberEventListSummary") export default class MemberEventListSummary extends React.Component { static defaultProps = { summaryLength: 1, diff --git a/src/components/views/elements/PersistedElement.js b/src/components/views/elements/PersistedElement.js index 3732f644b8..f504b3e97f 100644 --- a/src/components/views/elements/PersistedElement.js +++ b/src/components/views/elements/PersistedElement.js @@ -24,6 +24,7 @@ import dis from '../../../dispatcher/dispatcher'; import MatrixClientContext from "../../../contexts/MatrixClientContext"; import {MatrixClientPeg} from "../../../MatrixClientPeg"; import {isNullOrUndefined} from "matrix-js-sdk/src/utils"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; // Shamelessly ripped off Modal.js. There's probably a better way // of doing reusable widgets like dialog boxes & menus where we go and @@ -56,6 +57,7 @@ function getOrCreateContainer(containerId) { * children are made visible and are positioned into a div that is given the same * bounding rect as the parent of PE. */ +@replaceableComponent("views.elements.PersistedElement") export default class PersistedElement extends React.Component { static propTypes = { // Unique identifier for this PersistedElement instance diff --git a/src/components/views/elements/PersistentApp.js b/src/components/views/elements/PersistentApp.js index 7801076c66..5df373e4fe 100644 --- a/src/components/views/elements/PersistentApp.js +++ b/src/components/views/elements/PersistentApp.js @@ -21,7 +21,9 @@ import ActiveWidgetStore from '../../../stores/ActiveWidgetStore'; import WidgetUtils from '../../../utils/WidgetUtils'; import * as sdk from '../../../index'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.PersistentApp") export default class PersistentApp extends React.Component { state = { roomId: RoomViewStore.getRoomId(), diff --git a/src/components/views/elements/Pill.js b/src/components/views/elements/Pill.js index c6806c289e..b0d4fc7fa2 100644 --- a/src/components/views/elements/Pill.js +++ b/src/components/views/elements/Pill.js @@ -27,7 +27,9 @@ import {getPrimaryPermalinkEntity, parseAppLocalLink} from "../../../utils/perma import MatrixClientContext from "../../../contexts/MatrixClientContext"; import {Action} from "../../../dispatcher/actions"; import Tooltip from './Tooltip'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.Pill") class Pill extends React.Component { static roomNotifPos(text) { return text.indexOf("@room"); diff --git a/src/components/views/elements/PowerSelector.js b/src/components/views/elements/PowerSelector.js index 66922df0f8..622bed9890 100644 --- a/src/components/views/elements/PowerSelector.js +++ b/src/components/views/elements/PowerSelector.js @@ -20,7 +20,9 @@ import * as Roles from '../../../Roles'; import { _t } from '../../../languageHandler'; import Field from "./Field"; import {Key} from "../../../Keyboard"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.PowerSelector") export default class PowerSelector extends React.Component { static propTypes = { value: PropTypes.number.isRequired, diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 27d773b099..2e0cc50435 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -31,10 +31,12 @@ import {Action} from "../../../dispatcher/actions"; import sanitizeHtml from "sanitize-html"; import {UIFeature} from "../../../settings/UIFeature"; import {PERMITTED_URL_SCHEMES} from "../../../HtmlUtils"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; // This component does no cycle detection, simply because the only way to make such a cycle would be to // craft event_id's, using a homeserver that generates predictable event IDs; even then the impact would // be low as each event being loaded (after the first) is triggered by an explicit user action. +@replaceableComponent("views.elements.ReplyThread") export default class ReplyThread extends React.Component { static propTypes = { // the latest event in this chain of replies diff --git a/src/components/views/elements/RoomAliasField.js b/src/components/views/elements/RoomAliasField.js index 04bbe1c3de..1db154c2cd 100644 --- a/src/components/views/elements/RoomAliasField.js +++ b/src/components/views/elements/RoomAliasField.js @@ -19,8 +19,10 @@ import PropTypes from 'prop-types'; import * as sdk from '../../../index'; import withValidation from './Validation'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; // Controlled form component wrapping Field for inputting a room alias scoped to a given domain +@replaceableComponent("views.elements.RoomAliasField") export default class RoomAliasField extends React.PureComponent { static propTypes = { domain: PropTypes.string.isRequired, diff --git a/src/components/views/elements/SettingsFlag.tsx b/src/components/views/elements/SettingsFlag.tsx index 03e91fac62..4f885ab47d 100644 --- a/src/components/views/elements/SettingsFlag.tsx +++ b/src/components/views/elements/SettingsFlag.tsx @@ -21,6 +21,7 @@ import { _t } from '../../../languageHandler'; import ToggleSwitch from "./ToggleSwitch"; import StyledCheckbox from "./StyledCheckbox"; import { SettingLevel } from "../../../settings/SettingLevel"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { // The setting must be a boolean @@ -39,6 +40,7 @@ interface IState { value: boolean; } +@replaceableComponent("views.elements.SettingsFlag") export default class SettingsFlag extends React.Component { constructor(props: IProps) { super(props); diff --git a/src/components/views/elements/Slider.tsx b/src/components/views/elements/Slider.tsx index b7c8e1b533..b513f90460 100644 --- a/src/components/views/elements/Slider.tsx +++ b/src/components/views/elements/Slider.tsx @@ -15,6 +15,7 @@ limitations under the License. */ import * as React from 'react'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { // A callback for the selected value @@ -34,6 +35,7 @@ interface IProps { disabled: boolean; } +@replaceableComponent("views.elements.Slider") export default class Slider extends React.Component { // offset is a terrible inverse approximation. // if the values represents some function f(x) = y where x is the diff --git a/src/components/views/elements/SpellCheckLanguagesDropdown.tsx b/src/components/views/elements/SpellCheckLanguagesDropdown.tsx index c647f6e410..06e1efe415 100644 --- a/src/components/views/elements/SpellCheckLanguagesDropdown.tsx +++ b/src/components/views/elements/SpellCheckLanguagesDropdown.tsx @@ -21,6 +21,7 @@ import * as sdk from '../../../index'; import PlatformPeg from "../../../PlatformPeg"; import SettingsStore from "../../../settings/SettingsStore"; import { _t } from "../../../languageHandler"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; function languageMatchesSearchQuery(query, language) { if (language.label.toUpperCase().includes(query.toUpperCase())) return true; @@ -39,6 +40,7 @@ interface SpellCheckLanguagesDropdownIState { languages: any, } +@replaceableComponent("views.elements.SpellCheckLanguagesDropdown") export default class SpellCheckLanguagesDropdown extends React.Component { constructor(props) { diff --git a/src/components/views/elements/Spoiler.js b/src/components/views/elements/Spoiler.js index b75967b225..33b4382a2c 100644 --- a/src/components/views/elements/Spoiler.js +++ b/src/components/views/elements/Spoiler.js @@ -15,7 +15,9 @@ */ import React from 'react'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.Spoiler") export default class Spoiler extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/elements/StyledCheckbox.tsx b/src/components/views/elements/StyledCheckbox.tsx index f8d2665d07..2454d1336b 100644 --- a/src/components/views/elements/StyledCheckbox.tsx +++ b/src/components/views/elements/StyledCheckbox.tsx @@ -16,6 +16,7 @@ limitations under the License. import React from "react"; import { randomString } from "matrix-js-sdk/src/randomstring"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps extends React.InputHTMLAttributes { } @@ -23,6 +24,7 @@ interface IProps extends React.InputHTMLAttributes { interface IState { } +@replaceableComponent("views.elements.StyledCheckbox") export default class StyledCheckbox extends React.PureComponent { private id: string; diff --git a/src/components/views/elements/StyledRadioButton.tsx b/src/components/views/elements/StyledRadioButton.tsx index 2efd084861..835394e055 100644 --- a/src/components/views/elements/StyledRadioButton.tsx +++ b/src/components/views/elements/StyledRadioButton.tsx @@ -16,6 +16,7 @@ limitations under the License. import React from 'react'; import classnames from 'classnames'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps extends React.InputHTMLAttributes { outlined?: boolean; @@ -24,6 +25,7 @@ interface IProps extends React.InputHTMLAttributes { interface IState { } +@replaceableComponent("views.elements.StyledRadioButton") export default class StyledRadioButton extends React.PureComponent { public static readonly defaultProps = { className: '', diff --git a/src/components/views/elements/SyntaxHighlight.js b/src/components/views/elements/SyntaxHighlight.js index a4dc97d46e..f9874c5367 100644 --- a/src/components/views/elements/SyntaxHighlight.js +++ b/src/components/views/elements/SyntaxHighlight.js @@ -17,7 +17,9 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import {highlightBlock} from 'highlight.js'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.SyntaxHighlight") export default class SyntaxHighlight extends React.Component { static propTypes = { className: PropTypes.string, diff --git a/src/components/views/elements/TagTile.js b/src/components/views/elements/TagTile.js index 6c9a01a840..663acd6329 100644 --- a/src/components/views/elements/TagTile.js +++ b/src/components/views/elements/TagTile.js @@ -30,12 +30,14 @@ import GroupFilterOrderStore from '../../../stores/GroupFilterOrderStore'; import MatrixClientContext from "../../../contexts/MatrixClientContext"; import AccessibleButton from "./AccessibleButton"; import SettingsStore from "../../../settings/SettingsStore"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; // A class for a child of GroupFilterPanel (possibly wrapped in a DNDTagTile) that represents // a thing to click on for the user to filter the visible rooms in the RoomList to: // - Rooms that are part of the group // - Direct messages with members of the group // with the intention that this could be expanded to arbitrary tags in future. +@replaceableComponent("views.elements.TagTile") export default class TagTile extends React.Component { static propTypes = { // A string tag such as "m.favourite" or a group ID such as "+groupid:domain.bla" diff --git a/src/components/views/elements/TextWithTooltip.js b/src/components/views/elements/TextWithTooltip.js index b0405dc4c9..e4ad234ae2 100644 --- a/src/components/views/elements/TextWithTooltip.js +++ b/src/components/views/elements/TextWithTooltip.js @@ -17,7 +17,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import * as sdk from '../../../index'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.TextWithTooltip") export default class TextWithTooltip extends React.Component { static propTypes = { class: PropTypes.string, diff --git a/src/components/views/elements/TintableSvg.js b/src/components/views/elements/TintableSvg.js index df55b0a854..690deeedcd 100644 --- a/src/components/views/elements/TintableSvg.js +++ b/src/components/views/elements/TintableSvg.js @@ -18,7 +18,9 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import Tinter from "../../../Tinter"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.TintableSvg") class TintableSvg extends React.Component { static propTypes = { src: PropTypes.string.isRequired, diff --git a/src/components/views/elements/Tooltip.tsx b/src/components/views/elements/Tooltip.tsx index 03b9eb08d0..b2dd00de18 100644 --- a/src/components/views/elements/Tooltip.tsx +++ b/src/components/views/elements/Tooltip.tsx @@ -21,6 +21,7 @@ limitations under the License. import React, {Component, CSSProperties} from 'react'; import ReactDOM from 'react-dom'; import classNames from 'classnames'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const MIN_TOOLTIP_HEIGHT = 25; @@ -39,6 +40,7 @@ interface IProps { yOffset?: number; } +@replaceableComponent("views.elements.Tooltip") export default class Tooltip extends React.Component { private tooltipContainer: HTMLElement; private tooltip: void | Element | Component; diff --git a/src/components/views/elements/TooltipButton.js b/src/components/views/elements/TooltipButton.js index 240d763bdc..c5ebb3b1aa 100644 --- a/src/components/views/elements/TooltipButton.js +++ b/src/components/views/elements/TooltipButton.js @@ -17,7 +17,9 @@ limitations under the License. import React from 'react'; import * as sdk from '../../../index'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.TooltipButton") export default class TooltipButton extends React.Component { state = { hover: false, diff --git a/src/components/views/elements/TruncatedList.js b/src/components/views/elements/TruncatedList.js index 81eb057e36..0509775545 100644 --- a/src/components/views/elements/TruncatedList.js +++ b/src/components/views/elements/TruncatedList.js @@ -18,7 +18,9 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import { _t } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.TruncatedList") export default class TruncatedList extends React.Component { static propTypes = { // The number of elements to show before truncating. If negative, no truncation is done. diff --git a/src/components/views/elements/UserTagTile.tsx b/src/components/views/elements/UserTagTile.tsx index e7c74bb10e..d3e07a0a34 100644 --- a/src/components/views/elements/UserTagTile.tsx +++ b/src/components/views/elements/UserTagTile.tsx @@ -21,6 +21,7 @@ import GroupFilterOrderStore from "../../../stores/GroupFilterOrderStore"; import AccessibleTooltipButton from "./AccessibleTooltipButton"; import classNames from "classnames"; import { _t } from "../../../languageHandler"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { } @@ -29,6 +30,7 @@ interface IState { selected: boolean; } +@replaceableComponent("views.elements.UserTagTile") export default class UserTagTile extends React.PureComponent { private tagStoreRef: fbEmitter.EventSubscription; From fc5b1ed9d686f2d297f44872eb47812a5648dea3 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 8 Mar 2021 20:04:46 -0700 Subject: [PATCH 62/91] Batch of views getting replaceableComponent decorators --- src/components/views/emojipicker/Category.tsx | 2 ++ src/components/views/emojipicker/Emoji.tsx | 2 ++ src/components/views/emojipicker/EmojiPicker.tsx | 2 ++ src/components/views/emojipicker/Header.tsx | 2 ++ src/components/views/emojipicker/Preview.tsx | 2 ++ src/components/views/emojipicker/QuickReactions.tsx | 2 ++ src/components/views/emojipicker/ReactionPicker.tsx | 2 ++ src/components/views/emojipicker/Search.tsx | 2 ++ src/components/views/groups/GroupInviteTile.js | 2 ++ src/components/views/groups/GroupMemberList.js | 2 ++ src/components/views/groups/GroupMemberTile.js | 2 ++ src/components/views/groups/GroupPublicityToggle.js | 2 ++ src/components/views/groups/GroupRoomInfo.js | 2 ++ src/components/views/groups/GroupRoomList.js | 2 ++ src/components/views/groups/GroupRoomTile.js | 2 ++ src/components/views/groups/GroupTile.js | 2 ++ src/components/views/groups/GroupUserSettings.js | 2 ++ src/components/views/messages/DateSeparator.js | 2 ++ src/components/views/messages/EditHistoryMessage.js | 2 ++ src/components/views/messages/MAudioBody.js | 2 ++ src/components/views/messages/MFileBody.js | 2 ++ src/components/views/messages/MImageBody.js | 2 ++ src/components/views/messages/MJitsiWidgetEvent.tsx | 2 ++ src/components/views/messages/MKeyVerificationConclusion.js | 2 ++ src/components/views/messages/MKeyVerificationRequest.js | 2 ++ src/components/views/messages/MStickerBody.js | 2 ++ src/components/views/messages/MVideoBody.tsx | 2 ++ src/components/views/messages/MessageActionBar.js | 2 ++ src/components/views/messages/MessageEvent.js | 2 ++ src/components/views/messages/MessageTimestamp.js | 2 ++ src/components/views/messages/MjolnirBody.js | 2 ++ src/components/views/messages/ReactionsRow.js | 2 ++ src/components/views/messages/ReactionsRowButton.js | 2 ++ src/components/views/messages/ReactionsRowButtonTooltip.js | 2 ++ src/components/views/messages/RoomAvatarEvent.js | 2 ++ src/components/views/messages/RoomCreate.js | 2 ++ src/components/views/messages/SenderProfile.js | 2 ++ src/components/views/messages/TextualBody.js | 2 ++ src/components/views/messages/TextualEvent.js | 2 ++ src/components/views/messages/TileErrorBoundary.js | 2 ++ src/components/views/messages/ViewSourceEvent.js | 2 ++ 41 files changed, 82 insertions(+) diff --git a/src/components/views/emojipicker/Category.tsx b/src/components/views/emojipicker/Category.tsx index c4feaac8ae..4c7852def3 100644 --- a/src/components/views/emojipicker/Category.tsx +++ b/src/components/views/emojipicker/Category.tsx @@ -21,6 +21,7 @@ import { CATEGORY_HEADER_HEIGHT, EMOJI_HEIGHT, EMOJIS_PER_ROW } from "./EmojiPic import LazyRenderList from "../elements/LazyRenderList"; import {DATA_BY_CATEGORY, IEmoji} from "../../../emoji"; import Emoji from './Emoji'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const OVERFLOW_ROWS = 3; @@ -47,6 +48,7 @@ interface IProps { onMouseLeave(emoji: IEmoji): void; } +@replaceableComponent("views.emojipicker.Category") class Category extends React.PureComponent { private renderEmojiRow = (rowIndex: number) => { const { onClick, onMouseEnter, onMouseLeave, selectedEmojis, emojis } = this.props; diff --git a/src/components/views/emojipicker/Emoji.tsx b/src/components/views/emojipicker/Emoji.tsx index 5d715fb935..5d7665ce98 100644 --- a/src/components/views/emojipicker/Emoji.tsx +++ b/src/components/views/emojipicker/Emoji.tsx @@ -19,6 +19,7 @@ import React from 'react'; import {MenuItem} from "../../structures/ContextMenu"; import {IEmoji} from "../../../emoji"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { emoji: IEmoji; @@ -28,6 +29,7 @@ interface IProps { onMouseLeave(emoji: IEmoji): void; } +@replaceableComponent("views.emojipicker.Emoji") class Emoji extends React.PureComponent { render() { const { onClick, onMouseEnter, onMouseLeave, emoji, selectedEmojis } = this.props; diff --git a/src/components/views/emojipicker/EmojiPicker.tsx b/src/components/views/emojipicker/EmojiPicker.tsx index bf0481c51c..6d7b90c8a6 100644 --- a/src/components/views/emojipicker/EmojiPicker.tsx +++ b/src/components/views/emojipicker/EmojiPicker.tsx @@ -26,6 +26,7 @@ import Search from "./Search"; import Preview from "./Preview"; import QuickReactions from "./QuickReactions"; import Category, {ICategory, CategoryKey} from "./Category"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; export const CATEGORY_HEADER_HEIGHT = 22; export const EMOJI_HEIGHT = 37; @@ -47,6 +48,7 @@ interface IState { viewportHeight: number; } +@replaceableComponent("views.emojipicker.EmojiPicker") class EmojiPicker extends React.Component { private readonly recentlyUsed: IEmoji[]; private readonly memoizedDataByCategory: Record; diff --git a/src/components/views/emojipicker/Header.tsx b/src/components/views/emojipicker/Header.tsx index 9a93722483..693f86ad73 100644 --- a/src/components/views/emojipicker/Header.tsx +++ b/src/components/views/emojipicker/Header.tsx @@ -21,12 +21,14 @@ import classNames from "classnames"; import {_t} from "../../../languageHandler"; import {Key} from "../../../Keyboard"; import {CategoryKey, ICategory} from "./Category"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { categories: ICategory[]; onAnchorClick(id: CategoryKey): void } +@replaceableComponent("views.emojipicker.Header") class Header extends React.PureComponent { private findNearestEnabled(index: number, delta: number) { index += this.props.categories.length; diff --git a/src/components/views/emojipicker/Preview.tsx b/src/components/views/emojipicker/Preview.tsx index 69bfdf4d1c..e0952ec73e 100644 --- a/src/components/views/emojipicker/Preview.tsx +++ b/src/components/views/emojipicker/Preview.tsx @@ -18,11 +18,13 @@ limitations under the License. import React from 'react'; import {IEmoji} from "../../../emoji"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { emoji: IEmoji; } +@replaceableComponent("views.emojipicker.Preview") class Preview extends React.PureComponent { render() { const { diff --git a/src/components/views/emojipicker/QuickReactions.tsx b/src/components/views/emojipicker/QuickReactions.tsx index 0477ecfb93..a250aca458 100644 --- a/src/components/views/emojipicker/QuickReactions.tsx +++ b/src/components/views/emojipicker/QuickReactions.tsx @@ -20,6 +20,7 @@ import React from 'react'; import { _t } from '../../../languageHandler'; import {getEmojiFromUnicode, IEmoji} from "../../../emoji"; import Emoji from "./Emoji"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; // We use the variation-selector Heart in Quick Reactions for some reason const QUICK_REACTIONS = ["👍", "👎", "😄", "🎉", "😕", "❤️", "🚀", "👀"].map(emoji => { @@ -39,6 +40,7 @@ interface IState { hover?: IEmoji; } +@replaceableComponent("views.emojipicker.QuickReactions") class QuickReactions extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/emojipicker/ReactionPicker.tsx b/src/components/views/emojipicker/ReactionPicker.tsx index dbef0eadbe..e86d183aba 100644 --- a/src/components/views/emojipicker/ReactionPicker.tsx +++ b/src/components/views/emojipicker/ReactionPicker.tsx @@ -21,6 +21,7 @@ import {MatrixEvent} from "matrix-js-sdk/src/models/event"; import EmojiPicker from "./EmojiPicker"; import {MatrixClientPeg} from "../../../MatrixClientPeg"; import dis from "../../../dispatcher/dispatcher"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { mxEvent: MatrixEvent; @@ -32,6 +33,7 @@ interface IState { selectedEmojis: Set; } +@replaceableComponent("views.emojipicker.ReactionPicker") class ReactionPicker extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/emojipicker/Search.tsx b/src/components/views/emojipicker/Search.tsx index fe1fecec7b..abe3e026be 100644 --- a/src/components/views/emojipicker/Search.tsx +++ b/src/components/views/emojipicker/Search.tsx @@ -19,6 +19,7 @@ import React from 'react'; import { _t } from '../../../languageHandler'; import {Key} from "../../../Keyboard"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { query: string; @@ -26,6 +27,7 @@ interface IProps { onEnter(): void; } +@replaceableComponent("views.emojipicker.Search") class Search extends React.PureComponent { private inputRef = React.createRef(); diff --git a/src/components/views/groups/GroupInviteTile.js b/src/components/views/groups/GroupInviteTile.js index 0c09b6ed05..dc48c01acb 100644 --- a/src/components/views/groups/GroupInviteTile.js +++ b/src/components/views/groups/GroupInviteTile.js @@ -26,8 +26,10 @@ import {MatrixClientPeg} from "../../../MatrixClientPeg"; import {ContextMenu, ContextMenuButton, toRightOf} from "../../structures/ContextMenu"; import MatrixClientContext from "../../../contexts/MatrixClientContext"; import {RovingTabIndexWrapper} from "../../../accessibility/RovingTabIndex"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; // XXX this class copies a lot from RoomTile.js +@replaceableComponent("views.groups.GroupInviteTile") export default class GroupInviteTile extends React.Component { static propTypes: { group: PropTypes.object.isRequired, diff --git a/src/components/views/groups/GroupMemberList.js b/src/components/views/groups/GroupMemberList.js index 600a466601..d5b3f9aec7 100644 --- a/src/components/views/groups/GroupMemberList.js +++ b/src/components/views/groups/GroupMemberList.js @@ -26,9 +26,11 @@ import AccessibleButton from '../elements/AccessibleButton'; import {RightPanelPhases} from "../../../stores/RightPanelStorePhases"; import AutoHideScrollbar from "../../structures/AutoHideScrollbar"; import {Action} from "../../../dispatcher/actions"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const INITIAL_LOAD_NUM_MEMBERS = 30; +@replaceableComponent("views.groups.GroupMemberList") export default class GroupMemberList extends React.Component { static propTypes = { groupId: PropTypes.string.isRequired, diff --git a/src/components/views/groups/GroupMemberTile.js b/src/components/views/groups/GroupMemberTile.js index 13617cf681..e8285803b0 100644 --- a/src/components/views/groups/GroupMemberTile.js +++ b/src/components/views/groups/GroupMemberTile.js @@ -22,7 +22,9 @@ import * as sdk from '../../../index'; import dis from '../../../dispatcher/dispatcher'; import { GroupMemberType } from '../../../groups'; import MatrixClientContext from "../../../contexts/MatrixClientContext"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.groups.GroupMemberTile") export default class GroupMemberTile extends React.Component { static propTypes = { groupId: PropTypes.string.isRequired, diff --git a/src/components/views/groups/GroupPublicityToggle.js b/src/components/views/groups/GroupPublicityToggle.js index d42059551e..5399125d9f 100644 --- a/src/components/views/groups/GroupPublicityToggle.js +++ b/src/components/views/groups/GroupPublicityToggle.js @@ -19,7 +19,9 @@ import PropTypes from 'prop-types'; import * as sdk from '../../../index'; import GroupStore from '../../../stores/GroupStore'; import ToggleSwitch from "../elements/ToggleSwitch"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.groups.GroupPublicityTile") export default class GroupPublicityToggle extends React.Component { static propTypes = { groupId: PropTypes.string.isRequired, diff --git a/src/components/views/groups/GroupRoomInfo.js b/src/components/views/groups/GroupRoomInfo.js index 50bbd26029..227a17e995 100644 --- a/src/components/views/groups/GroupRoomInfo.js +++ b/src/components/views/groups/GroupRoomInfo.js @@ -24,7 +24,9 @@ import { _t } from '../../../languageHandler'; import GroupStore from '../../../stores/GroupStore'; import MatrixClientContext from "../../../contexts/MatrixClientContext"; import AutoHideScrollbar from "../../structures/AutoHideScrollbar"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.groups.GroupRoomInfo") export default class GroupRoomInfo extends React.Component { static contextType = MatrixClientContext; diff --git a/src/components/views/groups/GroupRoomList.js b/src/components/views/groups/GroupRoomList.js index 9bb46db47c..f8a90f9222 100644 --- a/src/components/views/groups/GroupRoomList.js +++ b/src/components/views/groups/GroupRoomList.js @@ -21,9 +21,11 @@ import PropTypes from 'prop-types'; import { showGroupAddRoomDialog } from '../../../GroupAddressPicker'; import AccessibleButton from '../elements/AccessibleButton'; import AutoHideScrollbar from "../../structures/AutoHideScrollbar"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const INITIAL_LOAD_NUM_ROOMS = 30; +@replaceableComponent("views.groups.GroupRoomList") export default class GroupRoomList extends React.Component { static propTypes = { groupId: PropTypes.string.isRequired, diff --git a/src/components/views/groups/GroupRoomTile.js b/src/components/views/groups/GroupRoomTile.js index 85aa56d055..8b25437f71 100644 --- a/src/components/views/groups/GroupRoomTile.js +++ b/src/components/views/groups/GroupRoomTile.js @@ -20,7 +20,9 @@ import * as sdk from '../../../index'; import dis from '../../../dispatcher/dispatcher'; import { GroupRoomType } from '../../../groups'; import MatrixClientContext from "../../../contexts/MatrixClientContext"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.groups.GroupRoomTile") class GroupRoomTile extends React.Component { static propTypes = { groupId: PropTypes.string.isRequired, diff --git a/src/components/views/groups/GroupTile.js b/src/components/views/groups/GroupTile.js index dcc749b01f..bb1714c9f2 100644 --- a/src/components/views/groups/GroupTile.js +++ b/src/components/views/groups/GroupTile.js @@ -21,9 +21,11 @@ import * as sdk from '../../../index'; import dis from '../../../dispatcher/dispatcher'; import FlairStore from '../../../stores/FlairStore'; import MatrixClientContext from "../../../contexts/MatrixClientContext"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; function nop() {} +@replaceableComponent("views.groups.GroupTile") class GroupTile extends React.Component { static propTypes = { groupId: PropTypes.string.isRequired, diff --git a/src/components/views/groups/GroupUserSettings.js b/src/components/views/groups/GroupUserSettings.js index 9209106c8f..5b537d7377 100644 --- a/src/components/views/groups/GroupUserSettings.js +++ b/src/components/views/groups/GroupUserSettings.js @@ -18,7 +18,9 @@ import React from 'react'; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; import MatrixClientContext from "../../../contexts/MatrixClientContext"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.groups.GroupUserSettings") export default class GroupUserSettings extends React.Component { static contextType = MatrixClientContext; diff --git a/src/components/views/messages/DateSeparator.js b/src/components/views/messages/DateSeparator.js index ef4b5d16d1..82ce8dc4ae 100644 --- a/src/components/views/messages/DateSeparator.js +++ b/src/components/views/messages/DateSeparator.js @@ -19,6 +19,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { _t } from '../../../languageHandler'; import {formatFullDateNoTime} from '../../../DateUtils'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; function getdaysArray() { return [ @@ -32,6 +33,7 @@ function getdaysArray() { ]; } +@replaceableComponent("views.messages.DateSeparator") export default class DateSeparator extends React.Component { static propTypes = { ts: PropTypes.number.isRequired, diff --git a/src/components/views/messages/EditHistoryMessage.js b/src/components/views/messages/EditHistoryMessage.js index 0967be937a..7f100fbb92 100644 --- a/src/components/views/messages/EditHistoryMessage.js +++ b/src/components/views/messages/EditHistoryMessage.js @@ -27,12 +27,14 @@ import {MatrixClientPeg} from '../../../MatrixClientPeg'; import Modal from '../../../Modal'; import classNames from 'classnames'; import RedactedBody from "./RedactedBody"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; function getReplacedContent(event) { const originalContent = event.getOriginalContent(); return originalContent["m.new_content"] || originalContent; } +@replaceableComponent("views.messages.EditHistoryMessage") export default class EditHistoryMessage extends React.PureComponent { static propTypes = { // the message event being edited diff --git a/src/components/views/messages/MAudioBody.js b/src/components/views/messages/MAudioBody.js index 587dee4513..59a10e17f3 100644 --- a/src/components/views/messages/MAudioBody.js +++ b/src/components/views/messages/MAudioBody.js @@ -23,7 +23,9 @@ import {MatrixClientPeg} from '../../../MatrixClientPeg'; import { decryptFile } from '../../../utils/DecryptFile'; import { _t } from '../../../languageHandler'; import InlineSpinner from '../elements/InlineSpinner'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.messages.MAudioBody") export default class MAudioBody extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/messages/MFileBody.js b/src/components/views/messages/MFileBody.js index 676f0b7986..e9893f99b6 100644 --- a/src/components/views/messages/MFileBody.js +++ b/src/components/views/messages/MFileBody.js @@ -26,6 +26,7 @@ import Tinter from '../../../Tinter'; import request from 'browser-request'; import Modal from '../../../Modal'; import AccessibleButton from "../elements/AccessibleButton"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; // A cached tinted copy of require("../../../../res/img/download.svg") @@ -116,6 +117,7 @@ function computedStyle(element) { return cssText; } +@replaceableComponent("views.messages.MFileBody") export default class MFileBody extends React.Component { static propTypes = { /* the MatrixEvent to show */ diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index 771d12accd..59c5b4e66b 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -27,7 +27,9 @@ import { _t } from '../../../languageHandler'; import SettingsStore from "../../../settings/SettingsStore"; import MatrixClientContext from "../../../contexts/MatrixClientContext"; import InlineSpinner from '../elements/InlineSpinner'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.messages.MImageBody") export default class MImageBody extends React.Component { static propTypes = { /* the MatrixEvent to show */ diff --git a/src/components/views/messages/MJitsiWidgetEvent.tsx b/src/components/views/messages/MJitsiWidgetEvent.tsx index 6031ede8fa..626efe1f36 100644 --- a/src/components/views/messages/MJitsiWidgetEvent.tsx +++ b/src/components/views/messages/MJitsiWidgetEvent.tsx @@ -21,11 +21,13 @@ import WidgetStore from "../../../stores/WidgetStore"; import EventTileBubble from "./EventTileBubble"; import { MatrixClientPeg } from "../../../MatrixClientPeg"; import { Container, WidgetLayoutStore } from "../../../stores/widgets/WidgetLayoutStore"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { mxEvent: MatrixEvent; } +@replaceableComponent("views.messages.MJitsiWidgetEvent") export default class MJitsiWidgetEvent extends React.PureComponent { constructor(props) { super(props); diff --git a/src/components/views/messages/MKeyVerificationConclusion.js b/src/components/views/messages/MKeyVerificationConclusion.js index 880299d29d..75d20131c0 100644 --- a/src/components/views/messages/MKeyVerificationConclusion.js +++ b/src/components/views/messages/MKeyVerificationConclusion.js @@ -22,7 +22,9 @@ import { _t } from '../../../languageHandler'; import {getNameForEventRoom, userLabelForEventRoom} from '../../../utils/KeyVerificationStateObserver'; import EventTileBubble from "./EventTileBubble"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.messages.MKeyVerificationConclusion") export default class MKeyVerificationConclusion extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/messages/MKeyVerificationRequest.js b/src/components/views/messages/MKeyVerificationRequest.js index d9594091c5..988606a766 100644 --- a/src/components/views/messages/MKeyVerificationRequest.js +++ b/src/components/views/messages/MKeyVerificationRequest.js @@ -25,7 +25,9 @@ import dis from "../../../dispatcher/dispatcher"; import {RightPanelPhases} from "../../../stores/RightPanelStorePhases"; import {Action} from "../../../dispatcher/actions"; import EventTileBubble from "./EventTileBubble"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.messages.MKeyVerificationRequest") export default class MKeyVerificationRequest extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/messages/MStickerBody.js b/src/components/views/messages/MStickerBody.js index 9839080661..54eb7649b4 100644 --- a/src/components/views/messages/MStickerBody.js +++ b/src/components/views/messages/MStickerBody.js @@ -17,7 +17,9 @@ limitations under the License. import React from 'react'; import MImageBody from './MImageBody'; import * as sdk from '../../../index'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.messages.MStickerBody") export default class MStickerBody extends MImageBody { // Mostly empty to prevent default behaviour of MImageBody onClick(ev) { diff --git a/src/components/views/messages/MVideoBody.tsx b/src/components/views/messages/MVideoBody.tsx index ce4a4eda76..89985dee7d 100644 --- a/src/components/views/messages/MVideoBody.tsx +++ b/src/components/views/messages/MVideoBody.tsx @@ -22,6 +22,7 @@ import { decryptFile } from '../../../utils/DecryptFile'; import { _t } from '../../../languageHandler'; import SettingsStore from "../../../settings/SettingsStore"; import InlineSpinner from '../elements/InlineSpinner'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { /* the MatrixEvent to show */ @@ -38,6 +39,7 @@ interface IState { fetchingData: boolean, } +@replaceableComponent("views.messages.MVideoBody") export default class MVideoBody extends React.PureComponent { private videoRef = React.createRef(); diff --git a/src/components/views/messages/MessageActionBar.js b/src/components/views/messages/MessageActionBar.js index c94f296eac..c33debe3f5 100644 --- a/src/components/views/messages/MessageActionBar.js +++ b/src/components/views/messages/MessageActionBar.js @@ -28,6 +28,7 @@ import { isContentActionable, canEditContent } from '../../../utils/EventUtils'; import RoomContext from "../../../contexts/RoomContext"; import Toolbar from "../../../accessibility/Toolbar"; import {RovingAccessibleTooltipButton, useRovingTabIndex} from "../../../accessibility/RovingTabIndex"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const OptionsButton = ({mxEvent, getTile, getReplyThread, permalinkCreator, onFocusChange}) => { const [menuDisplayed, button, openMenu, closeMenu] = useContextMenu(); @@ -101,6 +102,7 @@ const ReactButton = ({mxEvent, reactions, onFocusChange}) => { ; }; +@replaceableComponent("views.messages.MessageActionBar") export default class MessageActionBar extends React.PureComponent { static propTypes = { mxEvent: PropTypes.object.isRequired, diff --git a/src/components/views/messages/MessageEvent.js b/src/components/views/messages/MessageEvent.js index f93813fe79..866e0f521d 100644 --- a/src/components/views/messages/MessageEvent.js +++ b/src/components/views/messages/MessageEvent.js @@ -21,7 +21,9 @@ import SettingsStore from "../../../settings/SettingsStore"; import {Mjolnir} from "../../../mjolnir/Mjolnir"; import RedactedBody from "./RedactedBody"; import UnknownBody from "./UnknownBody"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.messages.MessageEvent") export default class MessageEvent extends React.Component { static propTypes = { /* the MatrixEvent to show */ diff --git a/src/components/views/messages/MessageTimestamp.js b/src/components/views/messages/MessageTimestamp.js index 199a6f47ce..c9bdb8937e 100644 --- a/src/components/views/messages/MessageTimestamp.js +++ b/src/components/views/messages/MessageTimestamp.js @@ -18,7 +18,9 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import {formatFullDate, formatTime} from '../../../DateUtils'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.messages.MessageTimestamp") export default class MessageTimestamp extends React.Component { static propTypes = { ts: PropTypes.number.isRequired, diff --git a/src/components/views/messages/MjolnirBody.js b/src/components/views/messages/MjolnirBody.js index baaee91657..4368fd936c 100644 --- a/src/components/views/messages/MjolnirBody.js +++ b/src/components/views/messages/MjolnirBody.js @@ -17,7 +17,9 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import {_t} from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.messages.MjolnirBody") export default class MjolnirBody extends React.Component { static propTypes = { mxEvent: PropTypes.object.isRequired, diff --git a/src/components/views/messages/ReactionsRow.js b/src/components/views/messages/ReactionsRow.js index 3451cdbb2d..d5c8ea2ac9 100644 --- a/src/components/views/messages/ReactionsRow.js +++ b/src/components/views/messages/ReactionsRow.js @@ -21,10 +21,12 @@ import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; import { isContentActionable } from '../../../utils/EventUtils'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; // The maximum number of reactions to initially show on a message. const MAX_ITEMS_WHEN_LIMITED = 8; +@replaceableComponent("views.messages.ReactionsRow") export default class ReactionsRow extends React.PureComponent { static propTypes = { // The event we're displaying reactions for diff --git a/src/components/views/messages/ReactionsRowButton.js b/src/components/views/messages/ReactionsRowButton.js index bb8d9a3b6e..06421c02a2 100644 --- a/src/components/views/messages/ReactionsRowButton.js +++ b/src/components/views/messages/ReactionsRowButton.js @@ -23,7 +23,9 @@ import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; import { formatCommaSeparatedList } from '../../../utils/FormattingUtils'; import dis from "../../../dispatcher/dispatcher"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.messages.ReactionsRowButton") export default class ReactionsRowButton extends React.PureComponent { static propTypes = { // The event we're displaying reactions for diff --git a/src/components/views/messages/ReactionsRowButtonTooltip.js b/src/components/views/messages/ReactionsRowButtonTooltip.js index 2b90175722..5ecdfe311d 100644 --- a/src/components/views/messages/ReactionsRowButtonTooltip.js +++ b/src/components/views/messages/ReactionsRowButtonTooltip.js @@ -22,7 +22,9 @@ import * as sdk from '../../../index'; import { unicodeToShortcode } from '../../../HtmlUtils'; import { _t } from '../../../languageHandler'; import { formatCommaSeparatedList } from '../../../utils/FormattingUtils'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.messages.ReactionsRowButtonTooltip") export default class ReactionsRowButtonTooltip extends React.PureComponent { static propTypes = { // The event we're displaying reactions for diff --git a/src/components/views/messages/RoomAvatarEvent.js b/src/components/views/messages/RoomAvatarEvent.js index f526d080cc..ba860216f0 100644 --- a/src/components/views/messages/RoomAvatarEvent.js +++ b/src/components/views/messages/RoomAvatarEvent.js @@ -23,7 +23,9 @@ import { _t } from '../../../languageHandler'; import * as sdk from '../../../index'; import Modal from '../../../Modal'; import AccessibleButton from '../elements/AccessibleButton'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.messages.RoomAvatarEvent") export default class RoomAvatarEvent extends React.Component { static propTypes = { /* the MatrixEvent to show */ diff --git a/src/components/views/messages/RoomCreate.js b/src/components/views/messages/RoomCreate.js index 479592aa42..3e02884c02 100644 --- a/src/components/views/messages/RoomCreate.js +++ b/src/components/views/messages/RoomCreate.js @@ -23,7 +23,9 @@ import { RoomPermalinkCreator } from '../../../utils/permalinks/Permalinks'; import { _t } from '../../../languageHandler'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; import EventTileBubble from "./EventTileBubble"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.messages.RoomCreate") export default class RoomCreate extends React.Component { static propTypes = { /* the MatrixEvent to show */ diff --git a/src/components/views/messages/SenderProfile.js b/src/components/views/messages/SenderProfile.js index d2db05252c..bd10526799 100644 --- a/src/components/views/messages/SenderProfile.js +++ b/src/components/views/messages/SenderProfile.js @@ -20,7 +20,9 @@ import Flair from '../elements/Flair.js'; import FlairStore from '../../../stores/FlairStore'; import {getUserNameColorClass} from '../../../utils/FormattingUtils'; import MatrixClientContext from "../../../contexts/MatrixClientContext"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.messages.SenderProfile") export default class SenderProfile extends React.Component { static propTypes = { mxEvent: PropTypes.object.isRequired, // event whose sender we're showing diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index 04db7bd725..b0eb6f2f35 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -35,7 +35,9 @@ import {isPermalinkHost} from "../../../utils/permalinks/Permalinks"; import {toRightOf} from "../../structures/ContextMenu"; import {copyPlaintext} from "../../../utils/strings"; import AccessibleTooltipButton from "../elements/AccessibleTooltipButton"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.messages.TextualBody") export default class TextualBody extends React.Component { static propTypes = { /* the MatrixEvent to show */ diff --git a/src/components/views/messages/TextualEvent.js b/src/components/views/messages/TextualEvent.js index 99e94147f7..a020cc6c52 100644 --- a/src/components/views/messages/TextualEvent.js +++ b/src/components/views/messages/TextualEvent.js @@ -18,7 +18,9 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import * as TextForEvent from "../../../TextForEvent"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.messages.TextualEvent") export default class TextualEvent extends React.Component { static propTypes = { /* the MatrixEvent to show */ diff --git a/src/components/views/messages/TileErrorBoundary.js b/src/components/views/messages/TileErrorBoundary.js index 9b67e32548..0e9a7b6128 100644 --- a/src/components/views/messages/TileErrorBoundary.js +++ b/src/components/views/messages/TileErrorBoundary.js @@ -20,7 +20,9 @@ import { _t } from '../../../languageHandler'; import * as sdk from '../../../index'; import Modal from '../../../Modal'; import SdkConfig from "../../../SdkConfig"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.messages.TileErrorBoundary") export default class TileErrorBoundary extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/messages/ViewSourceEvent.js b/src/components/views/messages/ViewSourceEvent.js index 9064fc3b68..adc7a248cd 100644 --- a/src/components/views/messages/ViewSourceEvent.js +++ b/src/components/views/messages/ViewSourceEvent.js @@ -17,7 +17,9 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.messages.ViewSourceEvent") export default class ViewSourceEvent extends React.PureComponent { static propTypes = { /* the MatrixEvent to show */ From c5935dbc6169f44c32becb8163aff99c42bbae0f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 8 Mar 2021 20:12:00 -0700 Subject: [PATCH 63/91] Batch of views getting replaceableComponent decorators --- src/components/views/right_panel/GroupHeaderButtons.tsx | 2 ++ src/components/views/right_panel/HeaderButton.tsx | 2 ++ src/components/views/right_panel/HeaderButtons.tsx | 2 ++ src/components/views/right_panel/RoomHeaderButtons.tsx | 2 ++ src/components/views/right_panel/VerificationPanel.tsx | 2 ++ src/components/views/room_settings/AliasSettings.js | 2 ++ src/components/views/room_settings/RelatedGroupSettings.js | 2 ++ src/components/views/room_settings/RoomProfileSettings.js | 2 ++ src/components/views/room_settings/UrlPreviewSettings.js | 3 ++- src/components/views/rooms/AppsDrawer.js | 2 ++ src/components/views/rooms/Autocomplete.tsx | 2 ++ src/components/views/rooms/AuxPanel.tsx | 2 ++ src/components/views/rooms/BasicMessageComposer.tsx | 2 ++ src/components/views/rooms/EditMessageComposer.js | 2 ++ src/components/views/rooms/EntityTile.js | 2 ++ src/components/views/rooms/EventTile.js | 2 ++ src/components/views/rooms/ForwardMessage.js | 3 ++- src/components/views/rooms/LinkPreviewWidget.js | 2 ++ src/components/views/rooms/MemberList.js | 2 ++ src/components/views/rooms/MemberTile.js | 2 ++ src/components/views/rooms/MessageComposer.js | 2 ++ src/components/views/rooms/MessageComposerFormatBar.js | 2 ++ src/components/views/rooms/NotificationBadge.tsx | 2 ++ src/components/views/rooms/PinnedEventTile.js | 2 ++ src/components/views/rooms/PinnedEventsPanel.js | 2 ++ src/components/views/rooms/PresenceLabel.js | 3 ++- src/components/views/rooms/ReadReceiptMarker.js | 2 ++ src/components/views/rooms/ReplyPreview.js | 2 ++ src/components/views/rooms/RoomBreadcrumbs.tsx | 2 ++ src/components/views/rooms/RoomDetailList.js | 2 ++ src/components/views/rooms/RoomDetailRow.js | 2 ++ src/components/views/rooms/RoomHeader.js | 2 ++ src/components/views/rooms/RoomList.tsx | 2 ++ src/components/views/rooms/RoomPreviewBar.js | 2 ++ src/components/views/rooms/RoomSublist.tsx | 2 ++ src/components/views/rooms/RoomTile.tsx | 2 ++ src/components/views/rooms/RoomUpgradeWarningBar.js | 2 ++ src/components/views/rooms/SearchBar.js | 2 ++ src/components/views/rooms/SearchResultTile.js | 2 ++ src/components/views/rooms/SendMessageComposer.js | 2 ++ src/components/views/rooms/SimpleRoomHeader.js | 2 ++ src/components/views/rooms/Stickerpicker.js | 2 ++ src/components/views/rooms/TemporaryTile.tsx | 2 ++ src/components/views/rooms/ThirdPartyMemberInfo.js | 2 ++ src/components/views/rooms/TopUnreadMessagesBar.js | 2 ++ src/components/views/rooms/WhoIsTypingTile.js | 2 ++ 46 files changed, 92 insertions(+), 3 deletions(-) diff --git a/src/components/views/right_panel/GroupHeaderButtons.tsx b/src/components/views/right_panel/GroupHeaderButtons.tsx index dd4a82e645..f006975b08 100644 --- a/src/components/views/right_panel/GroupHeaderButtons.tsx +++ b/src/components/views/right_panel/GroupHeaderButtons.tsx @@ -26,6 +26,7 @@ import {RightPanelPhases} from "../../../stores/RightPanelStorePhases"; import {Action} from "../../../dispatcher/actions"; import {ActionPayload} from "../../../dispatcher/payloads"; import {ViewUserPayload} from "../../../dispatcher/payloads/ViewUserPayload"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const GROUP_PHASES = [ RightPanelPhases.GroupMemberInfo, @@ -38,6 +39,7 @@ const ROOM_PHASES = [ interface IProps {} +@replaceableComponent("views.right_panel.GroupHeaderButtons") export default class GroupHeaderButtons extends HeaderButtons { constructor(props: IProps) { super(props, HeaderKind.Group); diff --git a/src/components/views/right_panel/HeaderButton.tsx b/src/components/views/right_panel/HeaderButton.tsx index 7f682e2d89..2bc360e380 100644 --- a/src/components/views/right_panel/HeaderButton.tsx +++ b/src/components/views/right_panel/HeaderButton.tsx @@ -22,6 +22,7 @@ import React from 'react'; import classNames from 'classnames'; import Analytics from '../../../Analytics'; import AccessibleTooltipButton from "../elements/AccessibleTooltipButton"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { // Whether this button is highlighted @@ -41,6 +42,7 @@ interface IProps { // TODO: replace this, the composer buttons and the right panel buttons with a unified // representation +@replaceableComponent("views.right_panel.HeaderButton") export default class HeaderButton extends React.Component { constructor(props: IProps) { super(props); diff --git a/src/components/views/right_panel/HeaderButtons.tsx b/src/components/views/right_panel/HeaderButtons.tsx index 543c7c067f..2144292679 100644 --- a/src/components/views/right_panel/HeaderButtons.tsx +++ b/src/components/views/right_panel/HeaderButtons.tsx @@ -28,6 +28,7 @@ import { SetRightPanelPhaseRefireParams, } from '../../../dispatcher/payloads/SetRightPanelPhasePayload'; import {EventSubscription} from "fbemitter"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; export enum HeaderKind { Room = "room", @@ -41,6 +42,7 @@ interface IState { interface IProps {} +@replaceableComponent("views.right_panel.HeaderButtons") export default abstract class HeaderButtons extends React.Component { private storeToken: EventSubscription; private dispatcherRef: string; diff --git a/src/components/views/right_panel/RoomHeaderButtons.tsx b/src/components/views/right_panel/RoomHeaderButtons.tsx index c2364546fd..0571622e64 100644 --- a/src/components/views/right_panel/RoomHeaderButtons.tsx +++ b/src/components/views/right_panel/RoomHeaderButtons.tsx @@ -26,6 +26,7 @@ import {RightPanelPhases} from "../../../stores/RightPanelStorePhases"; import {Action} from "../../../dispatcher/actions"; import {ActionPayload} from "../../../dispatcher/payloads"; import RightPanelStore from "../../../stores/RightPanelStore"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const ROOM_INFO_PHASES = [ RightPanelPhases.RoomSummary, @@ -37,6 +38,7 @@ const ROOM_INFO_PHASES = [ RightPanelPhases.Room3pidMemberInfo, ]; +@replaceableComponent("views.right_panel.RoomHeaderButtons") export default class RoomHeaderButtons extends HeaderButtons { constructor(props) { super(props, HeaderKind.Room); diff --git a/src/components/views/right_panel/VerificationPanel.tsx b/src/components/views/right_panel/VerificationPanel.tsx index f584a63209..ac01c953b9 100644 --- a/src/components/views/right_panel/VerificationPanel.tsx +++ b/src/components/views/right_panel/VerificationPanel.tsx @@ -36,6 +36,7 @@ import { PHASE_CANCELLED, } from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest"; import Spinner from "../elements/Spinner"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; // XXX: Should be defined in matrix-js-sdk enum VerificationPhase { @@ -65,6 +66,7 @@ interface IState { reciprocateQREvent?: ReciprocateQRCode; } +@replaceableComponent("views.right_panel.VerificationPanel") export default class VerificationPanel extends React.PureComponent { private hasVerifier: boolean; diff --git a/src/components/views/room_settings/AliasSettings.js b/src/components/views/room_settings/AliasSettings.js index eb9276b729..ee8232ebd7 100644 --- a/src/components/views/room_settings/AliasSettings.js +++ b/src/components/views/room_settings/AliasSettings.js @@ -26,6 +26,7 @@ import ErrorDialog from "../dialogs/ErrorDialog"; import AccessibleButton from "../elements/AccessibleButton"; import Modal from "../../../Modal"; import RoomPublishSetting from "./RoomPublishSetting"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; class EditableAliasesList extends EditableItemList { constructor(props) { @@ -74,6 +75,7 @@ class EditableAliasesList extends EditableItemList { } } +@replaceableComponent("views.room_settings.AliasSettings") export default class AliasSettings extends React.Component { static propTypes = { roomId: PropTypes.string.isRequired, diff --git a/src/components/views/room_settings/RelatedGroupSettings.js b/src/components/views/room_settings/RelatedGroupSettings.js index af3f58f9db..f82e238722 100644 --- a/src/components/views/room_settings/RelatedGroupSettings.js +++ b/src/components/views/room_settings/RelatedGroupSettings.js @@ -22,9 +22,11 @@ import { _t } from '../../../languageHandler'; import Modal from '../../../Modal'; import ErrorDialog from "../dialogs/ErrorDialog"; import MatrixClientContext from "../../../contexts/MatrixClientContext"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const GROUP_ID_REGEX = /\+\S+:\S+/; +@replaceableComponent("views.room_settings.RelatedGroupSettings") export default class RelatedGroupSettings extends React.Component { static propTypes = { roomId: PropTypes.string.isRequired, diff --git a/src/components/views/room_settings/RoomProfileSettings.js b/src/components/views/room_settings/RoomProfileSettings.js index 65acc802dc..563368384b 100644 --- a/src/components/views/room_settings/RoomProfileSettings.js +++ b/src/components/views/room_settings/RoomProfileSettings.js @@ -20,8 +20,10 @@ import {_t} from "../../../languageHandler"; import {MatrixClientPeg} from "../../../MatrixClientPeg"; import Field from "../elements/Field"; import * as sdk from "../../../index"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; // TODO: Merge with ProfileSettings? +@replaceableComponent("views.room_settings.RoomProfileSettings") export default class RoomProfileSettings extends React.Component { static propTypes = { roomId: PropTypes.string.isRequired, diff --git a/src/components/views/room_settings/UrlPreviewSettings.js b/src/components/views/room_settings/UrlPreviewSettings.js index 114e9b2894..7b04e296e5 100644 --- a/src/components/views/room_settings/UrlPreviewSettings.js +++ b/src/components/views/room_settings/UrlPreviewSettings.js @@ -26,8 +26,9 @@ import dis from "../../../dispatcher/dispatcher"; import {MatrixClientPeg} from "../../../MatrixClientPeg"; import {Action} from "../../../dispatcher/actions"; import {SettingLevel} from "../../../settings/SettingLevel"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; - +@replaceableComponent("views.room_settings.UrlPreviewSettings") export default class UrlPreviewSettings extends React.Component { static propTypes = { room: PropTypes.object, diff --git a/src/components/views/rooms/AppsDrawer.js b/src/components/views/rooms/AppsDrawer.js index aa7120bbe6..3ef8d71682 100644 --- a/src/components/views/rooms/AppsDrawer.js +++ b/src/components/views/rooms/AppsDrawer.js @@ -35,7 +35,9 @@ import PercentageDistributor from "../../../resizer/distributors/percentage"; import {Container, WidgetLayoutStore} from "../../../stores/widgets/WidgetLayoutStore"; import {clamp, percentageOf, percentageWithin} from "../../../utils/numbers"; import {useStateCallback} from "../../../hooks/useStateCallback"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.rooms.AppsDrawer") export default class AppsDrawer extends React.Component { static propTypes = { userId: PropTypes.string.isRequired, diff --git a/src/components/views/rooms/Autocomplete.tsx b/src/components/views/rooms/Autocomplete.tsx index 15af75084a..a4dcba11a3 100644 --- a/src/components/views/rooms/Autocomplete.tsx +++ b/src/components/views/rooms/Autocomplete.tsx @@ -23,6 +23,7 @@ import {Room} from 'matrix-js-sdk/src/models/room'; import SettingsStore from "../../../settings/SettingsStore"; import Autocompleter from '../../../autocomplete/Autocompleter'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const COMPOSER_SELECTED = 0; @@ -49,6 +50,7 @@ interface IState { forceComplete: boolean; } +@replaceableComponent("views.rooms.Autocomplete") export default class Autocomplete extends React.PureComponent { autocompleter: Autocompleter; queryRequested: string; diff --git a/src/components/views/rooms/AuxPanel.tsx b/src/components/views/rooms/AuxPanel.tsx index d193b98ec1..3d431f7c67 100644 --- a/src/components/views/rooms/AuxPanel.tsx +++ b/src/components/views/rooms/AuxPanel.tsx @@ -27,6 +27,7 @@ import {UIFeature} from "../../../settings/UIFeature"; import { ResizeNotifier } from "../../../utils/ResizeNotifier"; import CallViewForRoom from '../voip/CallViewForRoom'; import {objectHasDiff} from "../../../utils/objects"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { // js-sdk room object @@ -58,6 +59,7 @@ interface IState { counters: Counter[], } +@replaceableComponent("views.rooms.AuxPanel") export default class AuxPanel extends React.Component { static defaultProps = { showApps: true, diff --git a/src/components/views/rooms/BasicMessageComposer.tsx b/src/components/views/rooms/BasicMessageComposer.tsx index 017ce77166..829809ad49 100644 --- a/src/components/views/rooms/BasicMessageComposer.tsx +++ b/src/components/views/rooms/BasicMessageComposer.tsx @@ -46,6 +46,7 @@ import {IDiff} from "../../../editor/diff"; import AutocompleteWrapperModel from "../../../editor/autocomplete"; import DocumentPosition from "../../../editor/position"; import {ICompletion} from "../../../autocomplete/Autocompleter"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; // matches emoticons which follow the start of a line or whitespace const REGEX_EMOTICON_WHITESPACE = new RegExp('(?:^|\\s)(' + EMOTICON_REGEX.source + ')\\s$'); @@ -105,6 +106,7 @@ interface IState { completionIndex?: number; } +@replaceableComponent("views.rooms.BasixMessageEditor") export default class BasicMessageEditor extends React.Component { private editorRef = createRef(); private autocompleteRef = createRef(); diff --git a/src/components/views/rooms/EditMessageComposer.js b/src/components/views/rooms/EditMessageComposer.js index c59b3555b9..6ecb2bd549 100644 --- a/src/components/views/rooms/EditMessageComposer.js +++ b/src/components/views/rooms/EditMessageComposer.js @@ -34,6 +34,7 @@ import MatrixClientContext from "../../../contexts/MatrixClientContext"; import {Action} from "../../../dispatcher/actions"; import SettingsStore from "../../../settings/SettingsStore"; import CountlyAnalytics from "../../../CountlyAnalytics"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; function _isReply(mxEvent) { const relatesTo = mxEvent.getContent()["m.relates_to"]; @@ -102,6 +103,7 @@ function createEditContent(model, editedEvent) { }, contentBody); } +@replaceableComponent("views.rooms.EditMessageComposer") export default class EditMessageComposer extends React.Component { static propTypes = { // the message event being edited diff --git a/src/components/views/rooms/EntityTile.js b/src/components/views/rooms/EntityTile.js index 9017e4aa3e..75b03739b9 100644 --- a/src/components/views/rooms/EntityTile.js +++ b/src/components/views/rooms/EntityTile.js @@ -23,6 +23,7 @@ import AccessibleButton from '../elements/AccessibleButton'; import { _t } from '../../../languageHandler'; import classNames from "classnames"; import E2EIcon from './E2EIcon'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const PRESENCE_CLASS = { "offline": "mx_EntityTile_offline", @@ -50,6 +51,7 @@ function presenceClassForMember(presenceState, lastActiveAgo, showPresence) { } } +@replaceableComponent("views.rooms.EntityTile") class EntityTile extends React.Component { static propTypes = { name: PropTypes.string, diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index a705e92d9c..1366d9b603 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -39,6 +39,7 @@ import {WidgetType} from "../../../widgets/WidgetType"; import RoomAvatar from "../avatars/RoomAvatar"; import {WIDGET_LAYOUT_EVENT_TYPE} from "../../../stores/widgets/WidgetLayoutStore"; import {objectHasDiff} from "../../../utils/objects"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const eventTileTypes = { 'm.room.message': 'messages.MessageEvent', @@ -146,6 +147,7 @@ const MAX_READ_AVATARS = 5; // | '--------------------------------------' | // '----------------------------------------------------------' +@replaceableComponent("views.rooms.EventTile") export default class EventTile extends React.Component { static propTypes = { /* the MatrixEvent to show */ diff --git a/src/components/views/rooms/ForwardMessage.js b/src/components/views/rooms/ForwardMessage.js index b85dd2c8df..222895ef04 100644 --- a/src/components/views/rooms/ForwardMessage.js +++ b/src/components/views/rooms/ForwardMessage.js @@ -19,8 +19,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import { _t } from '../../../languageHandler'; import {Key} from '../../../Keyboard'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; - +@replaceableComponent("views.rooms.FowardMessage") export default class ForwardMessage extends React.Component { static propTypes = { onCancelClick: PropTypes.func.isRequired, diff --git a/src/components/views/rooms/LinkPreviewWidget.js b/src/components/views/rooms/LinkPreviewWidget.js index 2a053bf467..39c9f0bcf7 100644 --- a/src/components/views/rooms/LinkPreviewWidget.js +++ b/src/components/views/rooms/LinkPreviewWidget.js @@ -25,7 +25,9 @@ import * as sdk from "../../../index"; import Modal from "../../../Modal"; import * as ImageUtils from "../../../ImageUtils"; import { _t } from "../../../languageHandler"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.rooms.LinkPreviewWidget") export default class LinkPreviewWidget extends React.Component { static propTypes = { link: PropTypes.string.isRequired, // the URL being previewed diff --git a/src/components/views/rooms/MemberList.js b/src/components/views/rooms/MemberList.js index d4d618c821..593132a283 100644 --- a/src/components/views/rooms/MemberList.js +++ b/src/components/views/rooms/MemberList.js @@ -29,6 +29,7 @@ import BaseCard from "../right_panel/BaseCard"; import {RightPanelPhases} from "../../../stores/RightPanelStorePhases"; import RoomAvatar from "../avatars/RoomAvatar"; import RoomName from "../elements/RoomName"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const INITIAL_LOAD_NUM_MEMBERS = 30; const INITIAL_LOAD_NUM_INVITED = 5; @@ -38,6 +39,7 @@ const SHOW_MORE_INCREMENT = 100; // matches all ASCII punctuation: !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ const SORT_REGEX = /[\x21-\x2F\x3A-\x40\x5B-\x60\x7B-\x7E]+/g; +@replaceableComponent("views.rooms.MemberList") export default class MemberList extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/rooms/MemberTile.js b/src/components/views/rooms/MemberTile.js index a43b42b6d3..f8df7ed78f 100644 --- a/src/components/views/rooms/MemberTile.js +++ b/src/components/views/rooms/MemberTile.js @@ -23,7 +23,9 @@ import dis from "../../../dispatcher/dispatcher"; import { _t } from '../../../languageHandler'; import { MatrixClientPeg } from "../../../MatrixClientPeg"; import {Action} from "../../../dispatcher/actions"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.rooms.MemberTile") export default class MemberTile extends React.Component { static propTypes = { member: PropTypes.any.isRequired, // RoomMember diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index c03178cdf7..ccf097c4fd 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -32,6 +32,7 @@ import {UIFeature} from "../../../settings/UIFeature"; import WidgetStore from "../../../stores/WidgetStore"; import {UPDATE_EVENT} from "../../../stores/AsyncStore"; import ActiveWidgetStore from "../../../stores/ActiveWidgetStore"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; function ComposerAvatar(props) { const MemberStatusMessageAvatar = sdk.getComponent('avatars.MemberStatusMessageAvatar'); @@ -168,6 +169,7 @@ class UploadButton extends React.Component { } } +@replaceableComponent("views.rooms.MessageComposer") export default class MessageComposer extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/rooms/MessageComposerFormatBar.js b/src/components/views/rooms/MessageComposerFormatBar.js index 71aef1e833..d2539b1ef4 100644 --- a/src/components/views/rooms/MessageComposerFormatBar.js +++ b/src/components/views/rooms/MessageComposerFormatBar.js @@ -19,7 +19,9 @@ import PropTypes from 'prop-types'; import { _t } from '../../../languageHandler'; import classNames from 'classnames'; import AccessibleTooltipButton from "../elements/AccessibleTooltipButton"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.rooms.MessageComposerFormatBar") export default class MessageComposerFormatBar extends React.PureComponent { static propTypes = { onAction: PropTypes.func.isRequired, diff --git a/src/components/views/rooms/NotificationBadge.tsx b/src/components/views/rooms/NotificationBadge.tsx index 8b996d3238..36a52e260d 100644 --- a/src/components/views/rooms/NotificationBadge.tsx +++ b/src/components/views/rooms/NotificationBadge.tsx @@ -21,6 +21,7 @@ import SettingsStore from "../../../settings/SettingsStore"; import AccessibleButton from "../elements/AccessibleButton"; import { XOR } from "../../../@types/common"; import { NOTIFICATION_STATE_UPDATE, NotificationState } from "../../../stores/notifications/NotificationState"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { notification: NotificationState; @@ -48,6 +49,7 @@ interface IState { showCounts: boolean; // whether or not to show counts. Independent of props.forceCount } +@replaceableComponent("views.rooms.NotificationBadge") export default class NotificationBadge extends React.PureComponent, IState> { private countWatcherRef: string; diff --git a/src/components/views/rooms/PinnedEventTile.js b/src/components/views/rooms/PinnedEventTile.js index 9fad0c2391..2259cad7fb 100644 --- a/src/components/views/rooms/PinnedEventTile.js +++ b/src/components/views/rooms/PinnedEventTile.js @@ -23,7 +23,9 @@ import MessageEvent from "../messages/MessageEvent"; import MemberAvatar from "../avatars/MemberAvatar"; import { _t } from '../../../languageHandler'; import {formatFullDate} from '../../../DateUtils'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.rooms.PinnedEventTile") export default class PinnedEventTile extends React.Component { static propTypes = { mxRoom: PropTypes.object.isRequired, diff --git a/src/components/views/rooms/PinnedEventsPanel.js b/src/components/views/rooms/PinnedEventsPanel.js index 3ea0299976..285829bf63 100644 --- a/src/components/views/rooms/PinnedEventsPanel.js +++ b/src/components/views/rooms/PinnedEventsPanel.js @@ -22,7 +22,9 @@ import AccessibleButton from "../elements/AccessibleButton"; import PinnedEventTile from "./PinnedEventTile"; import { _t } from '../../../languageHandler'; import PinningUtils from "../../../utils/PinningUtils"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.rooms.PinnedEventsPanel") export default class PinnedEventsPanel extends React.Component { static propTypes = { // The Room from the js-sdk we're going to show pinned events for diff --git a/src/components/views/rooms/PresenceLabel.js b/src/components/views/rooms/PresenceLabel.js index ff1460ca21..ca21afe63d 100644 --- a/src/components/views/rooms/PresenceLabel.js +++ b/src/components/views/rooms/PresenceLabel.js @@ -18,8 +18,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import { _t } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; - +@replaceableComponent("views.rooms.PresenceLabel") export default class PresenceLabel extends React.Component { static propTypes = { // number of milliseconds ago this user was last active. diff --git a/src/components/views/rooms/ReadReceiptMarker.js b/src/components/views/rooms/ReadReceiptMarker.js index ba2b3064fd..ade84cbef3 100644 --- a/src/components/views/rooms/ReadReceiptMarker.js +++ b/src/components/views/rooms/ReadReceiptMarker.js @@ -23,6 +23,7 @@ import {formatDate} from '../../../DateUtils'; import Velociraptor from "../../../Velociraptor"; import * as sdk from "../../../index"; import {toPx} from "../../../utils/units"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; let bounce = false; try { @@ -32,6 +33,7 @@ try { } catch (e) { } +@replaceableComponent("views.rooms.ReadReceiptMarker") export default class ReadReceiptMarker extends React.PureComponent { static propTypes = { // the RoomMember to show the RR for diff --git a/src/components/views/rooms/ReplyPreview.js b/src/components/views/rooms/ReplyPreview.js index c7872d95ed..0d99be4f53 100644 --- a/src/components/views/rooms/ReplyPreview.js +++ b/src/components/views/rooms/ReplyPreview.js @@ -23,6 +23,7 @@ import SettingsStore from "../../../settings/SettingsStore"; import PropTypes from "prop-types"; import {RoomPermalinkCreator} from "../../../utils/permalinks/Permalinks"; import {UIFeature} from "../../../settings/UIFeature"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; function cancelQuoting() { dis.dispatch({ @@ -31,6 +32,7 @@ function cancelQuoting() { }); } +@replaceableComponent("views.rooms.ReplyPreview") export default class ReplyPreview extends React.Component { static propTypes = { permalinkCreator: PropTypes.instanceOf(RoomPermalinkCreator).isRequired, diff --git a/src/components/views/rooms/RoomBreadcrumbs.tsx b/src/components/views/rooms/RoomBreadcrumbs.tsx index ff60ab7779..ea0ff233da 100644 --- a/src/components/views/rooms/RoomBreadcrumbs.tsx +++ b/src/components/views/rooms/RoomBreadcrumbs.tsx @@ -27,6 +27,7 @@ import RoomListStore from "../../../stores/room-list/RoomListStore"; import { DefaultTagID } from "../../../stores/room-list/models"; import { RovingAccessibleTooltipButton } from "../../../accessibility/RovingTabIndex"; import Toolbar from "../../../accessibility/Toolbar"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { } @@ -42,6 +43,7 @@ interface IState { skipFirst: boolean; } +@replaceableComponent("views.rooms.RoomBreadcrumbs") export default class RoomBreadcrumbs extends React.PureComponent { private isMounted = true; diff --git a/src/components/views/rooms/RoomDetailList.js b/src/components/views/rooms/RoomDetailList.js index d8205aeb21..be22cda199 100644 --- a/src/components/views/rooms/RoomDetailList.js +++ b/src/components/views/rooms/RoomDetailList.js @@ -22,7 +22,9 @@ import PropTypes from 'prop-types'; import classNames from 'classnames'; import {roomShape} from './RoomDetailRow'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.rooms.RoomDetailList") export default class RoomDetailList extends React.Component { static propTypes = { rooms: PropTypes.arrayOf(roomShape), diff --git a/src/components/views/rooms/RoomDetailRow.js b/src/components/views/rooms/RoomDetailRow.js index 667f821922..e7c259cd98 100644 --- a/src/components/views/rooms/RoomDetailRow.js +++ b/src/components/views/rooms/RoomDetailRow.js @@ -21,6 +21,7 @@ import { linkifyElement } from '../../../HtmlUtils'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; import PropTypes from 'prop-types'; import {getHttpUriForMxc} from "matrix-js-sdk/src/content-repo"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; export function getDisplayAliasForRoom(room) { return room.canonicalAlias || (room.aliases ? room.aliases[0] : ""); @@ -39,6 +40,7 @@ export const roomShape = PropTypes.shape({ guestCanJoin: PropTypes.bool, }); +@replaceableComponent("views.rooms.RoomDetailRow") export default class RoomDetailRow extends React.Component { static propTypes = { room: roomShape, diff --git a/src/components/views/rooms/RoomHeader.js b/src/components/views/rooms/RoomHeader.js index 6736600bc8..f856f7f6ef 100644 --- a/src/components/views/rooms/RoomHeader.js +++ b/src/components/views/rooms/RoomHeader.js @@ -32,7 +32,9 @@ import AccessibleTooltipButton from "../elements/AccessibleTooltipButton"; import RoomTopic from "../elements/RoomTopic"; import RoomName from "../elements/RoomName"; import {PlaceCallType} from "../../../CallHandler"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.rooms.RoomHeader") export default class RoomHeader extends React.Component { static propTypes = { room: PropTypes.object, diff --git a/src/components/views/rooms/RoomList.tsx b/src/components/views/rooms/RoomList.tsx index f7da6571da..ff6e3793bf 100644 --- a/src/components/views/rooms/RoomList.tsx +++ b/src/components/views/rooms/RoomList.tsx @@ -50,6 +50,7 @@ import CallHandler from "../../../CallHandler"; import SpaceStore from "../../../stores/SpaceStore"; import { showAddExistingRooms, showCreateNewRoom } from "../../../utils/space"; import { EventType } from "matrix-js-sdk/src/@types/event"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { onKeyDown: (ev: React.KeyboardEvent) => void; @@ -256,6 +257,7 @@ function customTagAesthetics(tagId: TagID): ITagAesthetics { }; } +@replaceableComponent("views.rooms.RoomList") export default class RoomList extends React.PureComponent { private dispatcherRef; private customTagStoreRef; diff --git a/src/components/views/rooms/RoomPreviewBar.js b/src/components/views/rooms/RoomPreviewBar.js index dc68068157..36038da61c 100644 --- a/src/components/views/rooms/RoomPreviewBar.js +++ b/src/components/views/rooms/RoomPreviewBar.js @@ -27,6 +27,7 @@ import SdkConfig from "../../../SdkConfig"; import IdentityAuthClient from '../../../IdentityAuthClient'; import {CommunityPrototypeStore} from "../../../stores/CommunityPrototypeStore"; import {UPDATE_EVENT} from "../../../stores/AsyncStore"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const MessageCase = Object.freeze({ NotLoggedIn: "NotLoggedIn", @@ -45,6 +46,7 @@ const MessageCase = Object.freeze({ OtherError: "OtherError", }); +@replaceableComponent("views.rooms.RoomPreviewBar") export default class RoomPreviewBar extends React.Component { static propTypes = { onJoinClick: PropTypes.func, diff --git a/src/components/views/rooms/RoomSublist.tsx b/src/components/views/rooms/RoomSublist.tsx index a2574bf60c..cb98ba85e4 100644 --- a/src/components/views/rooms/RoomSublist.tsx +++ b/src/components/views/rooms/RoomSublist.tsx @@ -51,6 +51,7 @@ import { objectExcluding, objectHasDiff } from "../../../utils/objects"; import TemporaryTile from "./TemporaryTile"; import { ListNotificationState } from "../../../stores/notifications/ListNotificationState"; import IconizedContextMenu from "../context_menus/IconizedContextMenu"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const SHOW_N_BUTTON_HEIGHT = 28; // As defined by CSS const RESIZE_HANDLE_HEIGHT = 4; // As defined by CSS @@ -98,6 +99,7 @@ interface IState { filteredExtraTiles?: TemporaryTile[]; } +@replaceableComponent("views.rooms.RoomSublist") export default class RoomSublist extends React.Component { private headerButton = createRef(); private sublistRef = createRef(); diff --git a/src/components/views/rooms/RoomTile.tsx b/src/components/views/rooms/RoomTile.tsx index 835447dc18..07de70fe45 100644 --- a/src/components/views/rooms/RoomTile.tsx +++ b/src/components/views/rooms/RoomTile.tsx @@ -51,6 +51,7 @@ import IconizedContextMenu, { IconizedContextMenuRadio, } from "../context_menus/IconizedContextMenu"; import { CommunityPrototypeStore, IRoomProfile } from "../../../stores/CommunityPrototypeStore"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { room: Room; @@ -78,6 +79,7 @@ const contextMenuBelow = (elementRect: PartialDOMRect) => { return {left, top, chevronFace}; }; +@replaceableComponent("views.rooms.RoomTile") export default class RoomTile extends React.PureComponent { private dispatcherRef: string; private roomTileRef = createRef(); diff --git a/src/components/views/rooms/RoomUpgradeWarningBar.js b/src/components/views/rooms/RoomUpgradeWarningBar.js index 877cfb39d7..a2d4f92d35 100644 --- a/src/components/views/rooms/RoomUpgradeWarningBar.js +++ b/src/components/views/rooms/RoomUpgradeWarningBar.js @@ -21,7 +21,9 @@ import Modal from '../../../Modal'; import { _t } from '../../../languageHandler'; import {MatrixClientPeg} from "../../../MatrixClientPeg"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.rooms.RoomUpgradeWarningBar") export default class RoomUpgradeWarningBar extends React.Component { static propTypes = { room: PropTypes.object.isRequired, diff --git a/src/components/views/rooms/SearchBar.js b/src/components/views/rooms/SearchBar.js index ac637673e4..029516c932 100644 --- a/src/components/views/rooms/SearchBar.js +++ b/src/components/views/rooms/SearchBar.js @@ -21,7 +21,9 @@ import classNames from "classnames"; import { _t } from '../../../languageHandler'; import {Key} from "../../../Keyboard"; import DesktopBuildsNotice, {WarningKind} from "../elements/DesktopBuildsNotice"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.rooms.SearchBar") export default class SearchBar extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/rooms/SearchResultTile.js b/src/components/views/rooms/SearchResultTile.js index 29def9e368..dcfd633e76 100644 --- a/src/components/views/rooms/SearchResultTile.js +++ b/src/components/views/rooms/SearchResultTile.js @@ -21,7 +21,9 @@ import * as sdk from '../../../index'; import {haveTileForEvent} from "./EventTile"; import SettingsStore from "../../../settings/SettingsStore"; import {UIFeature} from "../../../settings/UIFeature"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.rooms.SearchResultTile") export default class SearchResultTile extends React.Component { static propTypes = { // a matrix-js-sdk SearchResult containing the details of this result diff --git a/src/components/views/rooms/SendMessageComposer.js b/src/components/views/rooms/SendMessageComposer.js index 673df949f7..ba3076c07d 100644 --- a/src/components/views/rooms/SendMessageComposer.js +++ b/src/components/views/rooms/SendMessageComposer.js @@ -48,6 +48,7 @@ import SettingsStore from "../../../settings/SettingsStore"; import CountlyAnalytics from "../../../CountlyAnalytics"; import {MatrixClientPeg} from "../../../MatrixClientPeg"; import EMOJI_REGEX from 'emojibase-regex'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; function addReplyToMessageContent(content, repliedToEvent, permalinkCreator) { const replyContent = ReplyThread.makeReplyMixIn(repliedToEvent); @@ -111,6 +112,7 @@ export function isQuickReaction(model) { return false; } +@replaceableComponent("views.rooms.SendMessageComposer") export default class SendMessageComposer extends React.Component { static propTypes = { room: PropTypes.object.isRequired, diff --git a/src/components/views/rooms/SimpleRoomHeader.js b/src/components/views/rooms/SimpleRoomHeader.js index 1c78253eff..b2a66f6670 100644 --- a/src/components/views/rooms/SimpleRoomHeader.js +++ b/src/components/views/rooms/SimpleRoomHeader.js @@ -19,6 +19,7 @@ import PropTypes from 'prop-types'; import AccessibleButton from '../elements/AccessibleButton'; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; // cancel button which is shared between room header and simple room header export function CancelButton(props) { @@ -36,6 +37,7 @@ export function CancelButton(props) { * A stripped-down room header used for things like the user settings * and room directory. */ +@replaceableComponent("views.rooms.SimpleRoomHeader") export default class SimpleRoomHeader extends React.Component { static propTypes = { title: PropTypes.string, diff --git a/src/components/views/rooms/Stickerpicker.js b/src/components/views/rooms/Stickerpicker.js index 5446d15671..44d31d7146 100644 --- a/src/components/views/rooms/Stickerpicker.js +++ b/src/components/views/rooms/Stickerpicker.js @@ -30,6 +30,7 @@ import {WidgetType} from "../../../widgets/WidgetType"; import AccessibleTooltipButton from "../elements/AccessibleTooltipButton"; import {Action} from "../../../dispatcher/actions"; import {WidgetMessagingStore} from "../../../stores/widgets/WidgetMessagingStore"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; // This should be below the dialog level (4000), but above the rest of the UI (1000-2000). // We sit in a context menu, so this should be given to the context menu. @@ -38,6 +39,7 @@ const STICKERPICKER_Z_INDEX = 3500; // Key to store the widget's AppTile under in PersistedElement const PERSISTED_ELEMENT_KEY = "stickerPicker"; +@replaceableComponent("views.rooms.Stickerpicker") export default class Stickerpicker extends React.Component { static currentWidget; diff --git a/src/components/views/rooms/TemporaryTile.tsx b/src/components/views/rooms/TemporaryTile.tsx index eec3105880..a9765faa5d 100644 --- a/src/components/views/rooms/TemporaryTile.tsx +++ b/src/components/views/rooms/TemporaryTile.tsx @@ -22,6 +22,7 @@ import { } from "../../../accessibility/RovingTabIndex"; import NotificationBadge from "./NotificationBadge"; import { NotificationState } from "../../../stores/notifications/NotificationState"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { isMinimized: boolean; @@ -37,6 +38,7 @@ interface IState { } // TODO: Remove with community invites in the room list: https://github.com/vector-im/element-web/issues/14456 +@replaceableComponent("views.rooms.TemporaryTile") export default class TemporaryTile extends React.Component { constructor(props: IProps) { super(props); diff --git a/src/components/views/rooms/ThirdPartyMemberInfo.js b/src/components/views/rooms/ThirdPartyMemberInfo.js index 73510c2b4f..5e2d82a1b2 100644 --- a/src/components/views/rooms/ThirdPartyMemberInfo.js +++ b/src/components/views/rooms/ThirdPartyMemberInfo.js @@ -25,7 +25,9 @@ import Modal from "../../../Modal"; import {isValid3pidInvite} from "../../../RoomInvite"; import RoomAvatar from "../avatars/RoomAvatar"; import RoomName from "../elements/RoomName"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.rooms.ThirdPartyMemberInfo") export default class ThirdPartyMemberInfo extends React.Component { static propTypes = { event: PropTypes.instanceOf(MatrixEvent).isRequired, diff --git a/src/components/views/rooms/TopUnreadMessagesBar.js b/src/components/views/rooms/TopUnreadMessagesBar.js index 9ac3c49ef4..cba99ac913 100644 --- a/src/components/views/rooms/TopUnreadMessagesBar.js +++ b/src/components/views/rooms/TopUnreadMessagesBar.js @@ -20,7 +20,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import { _t } from '../../../languageHandler'; import AccessibleButton from '../elements/AccessibleButton'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.rooms.TopUnreadMessagesBar") export default class TopUnreadMessagesBar extends React.Component { static propTypes = { onScrollUpClick: PropTypes.func, diff --git a/src/components/views/rooms/WhoIsTypingTile.js b/src/components/views/rooms/WhoIsTypingTile.js index 905cbe6d09..a25b43fc3a 100644 --- a/src/components/views/rooms/WhoIsTypingTile.js +++ b/src/components/views/rooms/WhoIsTypingTile.js @@ -21,7 +21,9 @@ import * as WhoIsTyping from '../../../WhoIsTyping'; import Timer from '../../../utils/Timer'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; import MemberAvatar from '../avatars/MemberAvatar'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.rooms.WhoIsTypingTile") export default class WhoIsTypingTile extends React.Component { static propTypes = { // the room this statusbar is representing. From 41576954fd3dfbdff9604a76760e10db44c8f5b4 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 8 Mar 2021 20:20:07 -0700 Subject: [PATCH 64/91] Batch of views getting replaceableComponent decorators --- src/components/views/settings/BridgeTile.tsx | 2 ++ src/components/views/settings/ChangeAvatar.js | 2 ++ src/components/views/settings/ChangeDisplayName.js | 2 ++ src/components/views/settings/ChangePassword.js | 2 ++ src/components/views/settings/CrossSigningPanel.js | 2 ++ src/components/views/settings/DevicesPanel.js | 2 ++ src/components/views/settings/DevicesPanelEntry.js | 2 ++ src/components/views/settings/EventIndexPanel.js | 2 ++ src/components/views/settings/IntegrationManager.js | 2 ++ src/components/views/settings/Notifications.js | 2 ++ src/components/views/settings/ProfileSettings.js | 2 ++ src/components/views/settings/SecureBackupPanel.js | 2 ++ src/components/views/settings/SetIdServer.js | 2 ++ src/components/views/settings/SetIntegrationManager.js | 2 ++ src/components/views/settings/SpellCheckSettings.tsx | 2 ++ src/components/views/settings/account/EmailAddresses.js | 2 ++ src/components/views/settings/account/PhoneNumbers.js | 2 ++ src/components/views/settings/discovery/EmailAddresses.js | 2 ++ src/components/views/settings/discovery/PhoneNumbers.js | 2 ++ .../views/settings/tabs/room/AdvancedRoomSettingsTab.js | 2 ++ src/components/views/settings/tabs/room/BridgeSettingsTab.tsx | 2 ++ .../views/settings/tabs/room/GeneralRoomSettingsTab.js | 2 ++ .../views/settings/tabs/room/NotificationSettingsTab.js | 2 ++ .../views/settings/tabs/room/RolesRoomSettingsTab.js | 2 ++ .../views/settings/tabs/room/SecurityRoomSettingsTab.js | 2 ++ .../views/settings/tabs/user/AppearanceUserSettingsTab.tsx | 3 ++- .../views/settings/tabs/user/FlairUserSettingsTab.js | 2 ++ .../views/settings/tabs/user/GeneralUserSettingsTab.js | 2 ++ src/components/views/settings/tabs/user/HelpUserSettingsTab.js | 2 ++ src/components/views/settings/tabs/user/LabsUserSettingsTab.js | 2 ++ .../views/settings/tabs/user/MjolnirUserSettingsTab.js | 2 ++ .../views/settings/tabs/user/NotificationUserSettingsTab.js | 2 ++ .../views/settings/tabs/user/PreferencesUserSettingsTab.js | 2 ++ .../views/settings/tabs/user/SecurityUserSettingsTab.js | 2 ++ .../views/settings/tabs/user/VoiceUserSettingsTab.js | 2 ++ src/components/views/terms/InlineTermsAgreement.js | 2 ++ src/components/views/toasts/NonUrgentEchoFailureToast.tsx | 2 ++ src/components/views/toasts/VerificationRequestToast.tsx | 2 ++ src/components/views/verification/VerificationCancelled.js | 2 ++ src/components/views/verification/VerificationComplete.js | 2 ++ src/components/views/verification/VerificationShowSas.js | 2 ++ src/components/views/voip/CallContainer.tsx | 2 ++ src/components/views/voip/CallPreview.tsx | 2 ++ src/components/views/voip/CallView.tsx | 2 ++ src/components/views/voip/CallViewForRoom.tsx | 2 ++ src/components/views/voip/DialPad.tsx | 2 ++ src/components/views/voip/DialPadModal.tsx | 2 ++ src/components/views/voip/IncomingCallBox.tsx | 2 ++ src/components/views/voip/VideoFeed.tsx | 2 ++ 49 files changed, 98 insertions(+), 1 deletion(-) diff --git a/src/components/views/settings/BridgeTile.tsx b/src/components/views/settings/BridgeTile.tsx index 58499ebd25..b33219ad4a 100644 --- a/src/components/views/settings/BridgeTile.tsx +++ b/src/components/views/settings/BridgeTile.tsx @@ -26,6 +26,7 @@ import SettingsStore from "../../../settings/SettingsStore"; import {MatrixEvent} from "matrix-js-sdk/src/models/event"; import { Room } from "matrix-js-sdk/src/models/room"; import { isUrlPermitted } from '../../../HtmlUtils'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { ev: MatrixEvent; @@ -64,6 +65,7 @@ interface IBridgeStateEvent { }; } +@replaceableComponent("views.settings.BridgeTile") export default class BridgeTile extends React.PureComponent { static propTypes = { ev: PropTypes.object.isRequired, diff --git a/src/components/views/settings/ChangeAvatar.js b/src/components/views/settings/ChangeAvatar.js index 7ab2936584..8067046ffd 100644 --- a/src/components/views/settings/ChangeAvatar.js +++ b/src/components/views/settings/ChangeAvatar.js @@ -20,7 +20,9 @@ import {MatrixClientPeg} from "../../../MatrixClientPeg"; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; import Spinner from '../elements/Spinner'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.settings.ChangeAvatar") export default class ChangeAvatar extends React.Component { static propTypes = { initialAvatarUrl: PropTypes.string, diff --git a/src/components/views/settings/ChangeDisplayName.js b/src/components/views/settings/ChangeDisplayName.js index 538e52d0ca..cae4a22be9 100644 --- a/src/components/views/settings/ChangeDisplayName.js +++ b/src/components/views/settings/ChangeDisplayName.js @@ -20,7 +20,9 @@ import React from 'react'; import * as sdk from '../../../index'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; import { _t } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.settings.ChangeDisplayName") export default class ChangeDisplayName extends React.Component { _getDisplayName = async () => { const cli = MatrixClientPeg.get(); diff --git a/src/components/views/settings/ChangePassword.js b/src/components/views/settings/ChangePassword.js index 22b758b1ca..aa635ef974 100644 --- a/src/components/views/settings/ChangePassword.js +++ b/src/components/views/settings/ChangePassword.js @@ -27,6 +27,7 @@ import * as sdk from "../../../index"; import Modal from "../../../Modal"; import PassphraseField from "../auth/PassphraseField"; import CountlyAnalytics from "../../../CountlyAnalytics"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const FIELD_OLD_PASSWORD = 'field_old_password'; const FIELD_NEW_PASSWORD = 'field_new_password'; @@ -34,6 +35,7 @@ const FIELD_NEW_PASSWORD_CONFIRM = 'field_new_password_confirm'; const PASSWORD_MIN_SCORE = 3; // safely unguessable: moderate protection from offline slow-hash scenario. +@replaceableComponent("views.settings.ChangePassword") export default class ChangePassword extends React.Component { static propTypes = { onFinished: PropTypes.func, diff --git a/src/components/views/settings/CrossSigningPanel.js b/src/components/views/settings/CrossSigningPanel.js index 1c548bd9d8..e5f57d1af2 100644 --- a/src/components/views/settings/CrossSigningPanel.js +++ b/src/components/views/settings/CrossSigningPanel.js @@ -23,7 +23,9 @@ import Modal from '../../../Modal'; import Spinner from '../elements/Spinner'; import InteractiveAuthDialog from '../dialogs/InteractiveAuthDialog'; import ConfirmDestroyCrossSigningDialog from '../dialogs/security/ConfirmDestroyCrossSigningDialog'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.settings.CrossSigningPanel") export default class CrossSigningPanel extends React.PureComponent { constructor(props) { super(props); diff --git a/src/components/views/settings/DevicesPanel.js b/src/components/views/settings/DevicesPanel.js index dc3ce9e03d..e7d300b0f8 100644 --- a/src/components/views/settings/DevicesPanel.js +++ b/src/components/views/settings/DevicesPanel.js @@ -24,7 +24,9 @@ import {MatrixClientPeg} from '../../../MatrixClientPeg'; import { _t } from '../../../languageHandler'; import Modal from '../../../Modal'; import {SSOAuthEntry} from "../auth/InteractiveAuthEntryComponents"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.settings.DevicesPanel") export default class DevicesPanel extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/settings/DevicesPanelEntry.js b/src/components/views/settings/DevicesPanelEntry.js index 567b144a92..93d4c78476 100644 --- a/src/components/views/settings/DevicesPanelEntry.js +++ b/src/components/views/settings/DevicesPanelEntry.js @@ -22,7 +22,9 @@ import { _t } from '../../../languageHandler'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; import {formatDate} from '../../../DateUtils'; import StyledCheckbox from '../elements/StyledCheckbox'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.settings.DevicesPanelEntry") export default class DevicesPanelEntry extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/settings/EventIndexPanel.js b/src/components/views/settings/EventIndexPanel.js index ec6ccacc9a..d78b99fc5d 100644 --- a/src/components/views/settings/EventIndexPanel.js +++ b/src/components/views/settings/EventIndexPanel.js @@ -25,7 +25,9 @@ import AccessibleButton from "../elements/AccessibleButton"; import {formatBytes, formatCountLong} from "../../../utils/FormattingUtils"; import EventIndexPeg from "../../../indexing/EventIndexPeg"; import {SettingLevel} from "../../../settings/SettingLevel"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.settings.EventIndexPanel") export default class EventIndexPanel extends React.Component { constructor() { super(); diff --git a/src/components/views/settings/IntegrationManager.js b/src/components/views/settings/IntegrationManager.js index da11832cf5..b058625139 100644 --- a/src/components/views/settings/IntegrationManager.js +++ b/src/components/views/settings/IntegrationManager.js @@ -21,7 +21,9 @@ import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; import dis from '../../../dispatcher/dispatcher'; import {Key} from "../../../Keyboard"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.settings.IntegrationManager") export default class IntegrationManager extends React.Component { static propTypes = { // false to display an error saying that we couldn't connect to the integration manager diff --git a/src/components/views/settings/Notifications.js b/src/components/views/settings/Notifications.js index 1337991dc3..25fe434994 100644 --- a/src/components/views/settings/Notifications.js +++ b/src/components/views/settings/Notifications.js @@ -32,6 +32,7 @@ import LabelledToggleSwitch from "../elements/LabelledToggleSwitch"; import AccessibleButton from "../elements/AccessibleButton"; import {SettingLevel} from "../../../settings/SettingLevel"; import {UIFeature} from "../../../settings/UIFeature"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; // TODO: this "view" component still has far too much application logic in it, // which should be factored out to other files. @@ -65,6 +66,7 @@ function portLegacyActions(actions) { } } +@replaceableComponent("views.settings.Notifications") export default class Notifications extends React.Component { static phases = { LOADING: "LOADING", // The component is loading or sending data to the hs diff --git a/src/components/views/settings/ProfileSettings.js b/src/components/views/settings/ProfileSettings.js index 89d7cf6c2b..30dcdc3c47 100644 --- a/src/components/views/settings/ProfileSettings.js +++ b/src/components/views/settings/ProfileSettings.js @@ -23,7 +23,9 @@ import * as sdk from "../../../index"; import {OwnProfileStore} from "../../../stores/OwnProfileStore"; import Modal from "../../../Modal"; import ErrorDialog from "../dialogs/ErrorDialog"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.settings.ProfileSettings") export default class ProfileSettings extends React.Component { constructor() { super(); diff --git a/src/components/views/settings/SecureBackupPanel.js b/src/components/views/settings/SecureBackupPanel.js index 080d83b2cf..310114c8af 100644 --- a/src/components/views/settings/SecureBackupPanel.js +++ b/src/components/views/settings/SecureBackupPanel.js @@ -26,7 +26,9 @@ import AccessibleButton from '../elements/AccessibleButton'; import QuestionDialog from '../dialogs/QuestionDialog'; import RestoreKeyBackupDialog from '../dialogs/security/RestoreKeyBackupDialog'; import { accessSecretStorage } from '../../../SecurityManager'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.settings.SecureBackupPanel") export default class SecureBackupPanel extends React.PureComponent { constructor(props) { super(props); diff --git a/src/components/views/settings/SetIdServer.js b/src/components/views/settings/SetIdServer.js index e05fe4f1c3..fa2a36476d 100644 --- a/src/components/views/settings/SetIdServer.js +++ b/src/components/views/settings/SetIdServer.js @@ -27,6 +27,7 @@ import IdentityAuthClient from "../../../IdentityAuthClient"; import {abbreviateUrl, unabbreviateUrl} from "../../../utils/UrlUtils"; import { getDefaultIdentityServerUrl, doesIdentityServerHaveTerms } from '../../../utils/IdentityServerUtils'; import {timeout} from "../../../utils/promise"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; // We'll wait up to this long when checking for 3PID bindings on the IS. const REACHABILITY_TIMEOUT = 10000; // ms @@ -58,6 +59,7 @@ async function checkIdentityServerUrl(u) { } } +@replaceableComponent("views.settings.SetIdServer") export default class SetIdServer extends React.Component { static propTypes = { // Whether or not the ID server is missing terms. This affects the text diff --git a/src/components/views/settings/SetIntegrationManager.js b/src/components/views/settings/SetIntegrationManager.js index e6fb3f6e1c..29cc5d7131 100644 --- a/src/components/views/settings/SetIntegrationManager.js +++ b/src/components/views/settings/SetIntegrationManager.js @@ -20,7 +20,9 @@ import {IntegrationManagers} from "../../../integrations/IntegrationManagers"; import * as sdk from '../../../index'; import SettingsStore from "../../../settings/SettingsStore"; import {SettingLevel} from "../../../settings/SettingLevel"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.settings.SetIntegrationManager") export default class SetIntegrationManager extends React.Component { constructor() { super(); diff --git a/src/components/views/settings/SpellCheckSettings.tsx b/src/components/views/settings/SpellCheckSettings.tsx index d08f263b5f..e5455c8c68 100644 --- a/src/components/views/settings/SpellCheckSettings.tsx +++ b/src/components/views/settings/SpellCheckSettings.tsx @@ -18,6 +18,7 @@ import React from 'react'; import SpellCheckLanguagesDropdown from "../../../components/views/elements/SpellCheckLanguagesDropdown"; import AccessibleButton from "../../../components/views/elements/AccessibleButton"; import {_t} from "../../../languageHandler"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface ExistingSpellCheckLanguageIProps { language: string, @@ -53,6 +54,7 @@ export class ExistingSpellCheckLanguage extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/settings/account/EmailAddresses.js b/src/components/views/settings/account/EmailAddresses.js index a8de7693a9..1ebd374173 100644 --- a/src/components/views/settings/account/EmailAddresses.js +++ b/src/components/views/settings/account/EmailAddresses.js @@ -25,6 +25,7 @@ import * as Email from "../../../../email"; import AddThreepid from "../../../../AddThreepid"; import * as sdk from '../../../../index'; import Modal from '../../../../Modal'; +import {replaceableComponent} from "../../../../utils/replaceableComponent"; /* TODO: Improve the UX for everything in here. @@ -112,6 +113,7 @@ export class ExistingEmailAddress extends React.Component { } } +@replaceableComponent("views.settings.account.EmailAddresses") export default class EmailAddresses extends React.Component { static propTypes = { emails: PropTypes.array.isRequired, diff --git a/src/components/views/settings/account/PhoneNumbers.js b/src/components/views/settings/account/PhoneNumbers.js index df54b5ca1f..5725fdb909 100644 --- a/src/components/views/settings/account/PhoneNumbers.js +++ b/src/components/views/settings/account/PhoneNumbers.js @@ -25,6 +25,7 @@ import AddThreepid from "../../../../AddThreepid"; import CountryDropdown from "../../auth/CountryDropdown"; import * as sdk from '../../../../index'; import Modal from '../../../../Modal'; +import {replaceableComponent} from "../../../../utils/replaceableComponent"; /* TODO: Improve the UX for everything in here. @@ -107,6 +108,7 @@ export class ExistingPhoneNumber extends React.Component { } } +@replaceableComponent("views.settings.account.PhoneNumbers") export default class PhoneNumbers extends React.Component { static propTypes = { msisdns: PropTypes.array.isRequired, diff --git a/src/components/views/settings/discovery/EmailAddresses.js b/src/components/views/settings/discovery/EmailAddresses.js index f9a1ba1818..0493597537 100644 --- a/src/components/views/settings/discovery/EmailAddresses.js +++ b/src/components/views/settings/discovery/EmailAddresses.js @@ -23,6 +23,7 @@ import {MatrixClientPeg} from "../../../../MatrixClientPeg"; import * as sdk from '../../../../index'; import Modal from '../../../../Modal'; import AddThreepid from '../../../../AddThreepid'; +import {replaceableComponent} from "../../../../utils/replaceableComponent"; /* TODO: Improve the UX for everything in here. @@ -233,6 +234,7 @@ export class EmailAddress extends React.Component { } } +@replaceableComponent("views.settings.discovery.EmailAddresses") export default class EmailAddresses extends React.Component { static propTypes = { emails: PropTypes.array.isRequired, diff --git a/src/components/views/settings/discovery/PhoneNumbers.js b/src/components/views/settings/discovery/PhoneNumbers.js index 03f459ee15..5cbcdfe47e 100644 --- a/src/components/views/settings/discovery/PhoneNumbers.js +++ b/src/components/views/settings/discovery/PhoneNumbers.js @@ -23,6 +23,7 @@ import {MatrixClientPeg} from "../../../../MatrixClientPeg"; import * as sdk from '../../../../index'; import Modal from '../../../../Modal'; import AddThreepid from '../../../../AddThreepid'; +import {replaceableComponent} from "../../../../utils/replaceableComponent"; /* TODO: Improve the UX for everything in here. @@ -246,6 +247,7 @@ export class PhoneNumber extends React.Component { } } +@replaceableComponent("views.settings.discovery.PhoneNumbers") export default class PhoneNumbers extends React.Component { static propTypes = { msisdns: PropTypes.array.isRequired, diff --git a/src/components/views/settings/tabs/room/AdvancedRoomSettingsTab.js b/src/components/views/settings/tabs/room/AdvancedRoomSettingsTab.js index 2fa61a0ee6..28aad65129 100644 --- a/src/components/views/settings/tabs/room/AdvancedRoomSettingsTab.js +++ b/src/components/views/settings/tabs/room/AdvancedRoomSettingsTab.js @@ -22,7 +22,9 @@ import * as sdk from "../../../../.."; import AccessibleButton from "../../../elements/AccessibleButton"; import Modal from "../../../../../Modal"; import dis from "../../../../../dispatcher/dispatcher"; +import {replaceableComponent} from "../../../../../utils/replaceableComponent"; +@replaceableComponent("views.settings.tabs.room.AdvancedRoomSettingsTab") export default class AdvancedRoomSettingsTab extends React.Component { static propTypes = { roomId: PropTypes.string.isRequired, diff --git a/src/components/views/settings/tabs/room/BridgeSettingsTab.tsx b/src/components/views/settings/tabs/room/BridgeSettingsTab.tsx index 3c74bd4c1a..8d886a191e 100644 --- a/src/components/views/settings/tabs/room/BridgeSettingsTab.tsx +++ b/src/components/views/settings/tabs/room/BridgeSettingsTab.tsx @@ -21,6 +21,7 @@ import {MatrixEvent} from "matrix-js-sdk/src/models/event"; import {_t} from "../../../../../languageHandler"; import {MatrixClientPeg} from "../../../../../MatrixClientPeg"; import BridgeTile from "../../BridgeTile"; +import {replaceableComponent} from "../../../../../utils/replaceableComponent"; const BRIDGE_EVENT_TYPES = [ "uk.half-shot.bridge", @@ -33,6 +34,7 @@ interface IProps { roomId: string; } +@replaceableComponent("views.settings.tabs.room.BridgeSettingsTab") export default class BridgeSettingsTab extends React.Component { private renderBridgeCard(event: MatrixEvent, room: Room) { const content = event.getContent(); diff --git a/src/components/views/settings/tabs/room/GeneralRoomSettingsTab.js b/src/components/views/settings/tabs/room/GeneralRoomSettingsTab.js index 9b8004d9d6..cd4a043622 100644 --- a/src/components/views/settings/tabs/room/GeneralRoomSettingsTab.js +++ b/src/components/views/settings/tabs/room/GeneralRoomSettingsTab.js @@ -24,7 +24,9 @@ import dis from "../../../../../dispatcher/dispatcher"; import MatrixClientContext from "../../../../../contexts/MatrixClientContext"; import SettingsStore from "../../../../../settings/SettingsStore"; import {UIFeature} from "../../../../../settings/UIFeature"; +import {replaceableComponent} from "../../../../../utils/replaceableComponent"; +@replaceableComponent("views.settings.tabs.room.GeneralRoomSettingsTab") export default class GeneralRoomSettingsTab extends React.Component { static propTypes = { roomId: PropTypes.string.isRequired, diff --git a/src/components/views/settings/tabs/room/NotificationSettingsTab.js b/src/components/views/settings/tabs/room/NotificationSettingsTab.js index dd88b5018f..baefb5ae20 100644 --- a/src/components/views/settings/tabs/room/NotificationSettingsTab.js +++ b/src/components/views/settings/tabs/room/NotificationSettingsTab.js @@ -22,7 +22,9 @@ import AccessibleButton from "../../../elements/AccessibleButton"; import Notifier from "../../../../../Notifier"; import SettingsStore from '../../../../../settings/SettingsStore'; import {SettingLevel} from "../../../../../settings/SettingLevel"; +import {replaceableComponent} from "../../../../../utils/replaceableComponent"; +@replaceableComponent("views.settings.tabs.room.NotificationsSettingsTab") export default class NotificationsSettingsTab extends React.Component { static propTypes = { roomId: PropTypes.string.isRequired, diff --git a/src/components/views/settings/tabs/room/RolesRoomSettingsTab.js b/src/components/views/settings/tabs/room/RolesRoomSettingsTab.js index 49d683c42a..09498e0d4a 100644 --- a/src/components/views/settings/tabs/room/RolesRoomSettingsTab.js +++ b/src/components/views/settings/tabs/room/RolesRoomSettingsTab.js @@ -21,6 +21,7 @@ import {MatrixClientPeg} from "../../../../../MatrixClientPeg"; import * as sdk from "../../../../.."; import AccessibleButton from "../../../elements/AccessibleButton"; import Modal from "../../../../../Modal"; +import {replaceableComponent} from "../../../../../utils/replaceableComponent"; const plEventsToLabels = { // These will be translated for us later. @@ -103,6 +104,7 @@ export class BannedUser extends React.Component { } } +@replaceableComponent("views.settings.tabs.room.RolesRoomSettingsTab") export default class RolesRoomSettingsTab extends React.Component { static propTypes = { roomId: PropTypes.string.isRequired, diff --git a/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.js b/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.js index f72e78fa3f..ce883c6d23 100644 --- a/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.js +++ b/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.js @@ -26,7 +26,9 @@ import StyledRadioGroup from '../../../elements/StyledRadioGroup'; import {SettingLevel} from "../../../../../settings/SettingLevel"; import SettingsStore from "../../../../../settings/SettingsStore"; import {UIFeature} from "../../../../../settings/UIFeature"; +import {replaceableComponent} from "../../../../../utils/replaceableComponent"; +@replaceableComponent("views.settings.tabs.room.SecurityRoomSettingsTab") export default class SecurityRoomSettingsTab extends React.Component { static propTypes = { roomId: PropTypes.string.isRequired, diff --git a/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx b/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx index 80a20d8afa..d6e01d194c 100644 --- a/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx +++ b/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx @@ -36,6 +36,7 @@ import StyledRadioGroup from "../../../elements/StyledRadioGroup"; import { SettingLevel } from "../../../../../settings/SettingLevel"; import {UIFeature} from "../../../../../settings/UIFeature"; import {Layout} from "../../../../../settings/Layout"; +import {replaceableComponent} from "../../../../../utils/replaceableComponent"; interface IProps { } @@ -64,7 +65,7 @@ interface IState extends IThemeState { layout: Layout; } - +@replaceableComponent("views.settings.tabs.user.AppearanceUserSettingsTab") export default class AppearanceUserSettingsTab extends React.Component { private readonly MESSAGE_PREVIEW_TEXT = _t("Hey you. You're the best!"); diff --git a/src/components/views/settings/tabs/user/FlairUserSettingsTab.js b/src/components/views/settings/tabs/user/FlairUserSettingsTab.js index 26e0033233..28e80f3030 100644 --- a/src/components/views/settings/tabs/user/FlairUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/FlairUserSettingsTab.js @@ -17,7 +17,9 @@ limitations under the License. import React from 'react'; import {_t} from "../../../../../languageHandler"; import GroupUserSettings from "../../../groups/GroupUserSettings"; +import {replaceableComponent} from "../../../../../utils/replaceableComponent"; +@replaceableComponent("views.settings.tabs.user.FlairUserSettingsTab") export default class FlairUserSettingsTab extends React.Component { render() { return ( diff --git a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js index b17ab18c39..314acf5d65 100644 --- a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js @@ -39,7 +39,9 @@ import { getThreepidsWithBindStatus } from '../../../../../boundThreepids'; import Spinner from "../../../elements/Spinner"; import {SettingLevel} from "../../../../../settings/SettingLevel"; import {UIFeature} from "../../../../../settings/UIFeature"; +import {replaceableComponent} from "../../../../../utils/replaceableComponent"; +@replaceableComponent("views.settings.tabs.user.GeneralUserSettingsTab") export default class GeneralUserSettingsTab extends React.Component { static propTypes = { closeSettingsFn: PropTypes.func.isRequired, diff --git a/src/components/views/settings/tabs/user/HelpUserSettingsTab.js b/src/components/views/settings/tabs/user/HelpUserSettingsTab.js index 85ba22a353..e16ee686f5 100644 --- a/src/components/views/settings/tabs/user/HelpUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/HelpUserSettingsTab.js @@ -27,7 +27,9 @@ import * as sdk from "../../../../../"; import PlatformPeg from "../../../../../PlatformPeg"; import * as KeyboardShortcuts from "../../../../../accessibility/KeyboardShortcuts"; import UpdateCheckButton from "../../UpdateCheckButton"; +import {replaceableComponent} from "../../../../../utils/replaceableComponent"; +@replaceableComponent("views.settings.tabs.user.HelpUserSettingsTab") export default class HelpUserSettingsTab extends React.Component { static propTypes = { closeSettingsFn: PropTypes.func.isRequired, diff --git a/src/components/views/settings/tabs/user/LabsUserSettingsTab.js b/src/components/views/settings/tabs/user/LabsUserSettingsTab.js index 91bc9abcad..f515f1862b 100644 --- a/src/components/views/settings/tabs/user/LabsUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/LabsUserSettingsTab.js @@ -21,6 +21,7 @@ import SettingsStore from "../../../../../settings/SettingsStore"; import LabelledToggleSwitch from "../../../elements/LabelledToggleSwitch"; import * as sdk from "../../../../../index"; import {SettingLevel} from "../../../../../settings/SettingLevel"; +import {replaceableComponent} from "../../../../../utils/replaceableComponent"; export class LabsSettingToggle extends React.Component { static propTypes = { @@ -40,6 +41,7 @@ export class LabsSettingToggle extends React.Component { } } +@replaceableComponent("views.settings.tabs.user.LabsUserSettingsTab") export default class LabsUserSettingsTab extends React.Component { constructor() { super(); diff --git a/src/components/views/settings/tabs/user/MjolnirUserSettingsTab.js b/src/components/views/settings/tabs/user/MjolnirUserSettingsTab.js index 510d6076a0..91f6728a7a 100644 --- a/src/components/views/settings/tabs/user/MjolnirUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/MjolnirUserSettingsTab.js @@ -23,7 +23,9 @@ import {BanList, RULE_SERVER, RULE_USER} from "../../../../../mjolnir/BanList"; import Modal from "../../../../../Modal"; import {MatrixClientPeg} from "../../../../../MatrixClientPeg"; import * as sdk from "../../../../../index"; +import {replaceableComponent} from "../../../../../utils/replaceableComponent"; +@replaceableComponent("views.settings.tabs.user.MjolnirUserSettingsTab") export default class MjolnirUserSettingsTab extends React.Component { constructor() { super(); diff --git a/src/components/views/settings/tabs/user/NotificationUserSettingsTab.js b/src/components/views/settings/tabs/user/NotificationUserSettingsTab.js index 2e649cb7f8..8a71d1bf15 100644 --- a/src/components/views/settings/tabs/user/NotificationUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/NotificationUserSettingsTab.js @@ -17,7 +17,9 @@ limitations under the License. import React from 'react'; import {_t} from "../../../../../languageHandler"; import * as sdk from "../../../../../index"; +import {replaceableComponent} from "../../../../../utils/replaceableComponent"; +@replaceableComponent("views.settings.tabs.user.NotificationUserSettingsTab") export default class NotificationUserSettingsTab extends React.Component { constructor() { super(); diff --git a/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.js b/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.js index ae9cad4cfa..238f875e22 100644 --- a/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.js @@ -23,7 +23,9 @@ import Field from "../../../elements/Field"; import * as sdk from "../../../../.."; import PlatformPeg from "../../../../../PlatformPeg"; import {SettingLevel} from "../../../../../settings/SettingLevel"; +import {replaceableComponent} from "../../../../../utils/replaceableComponent"; +@replaceableComponent("views.settings.tabs.user.PreferencesUserSettingsTab") export default class PreferencesUserSettingsTab extends React.Component { static ROOM_LIST_SETTINGS = [ 'breadcrumbs', diff --git a/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js b/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js index a0d9016ce2..8a70811399 100644 --- a/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js @@ -34,6 +34,7 @@ import SettingsStore from "../../../../../settings/SettingsStore"; import {UIFeature} from "../../../../../settings/UIFeature"; import {isE2eAdvancedPanelPossible} from "../../E2eAdvancedPanel"; import CountlyAnalytics from "../../../../../CountlyAnalytics"; +import {replaceableComponent} from "../../../../../utils/replaceableComponent"; export class IgnoredUser extends React.Component { static propTypes = { @@ -59,6 +60,7 @@ export class IgnoredUser extends React.Component { } } +@replaceableComponent("views.settings.tabs.user.SecurityUserSettingsTab") export default class SecurityUserSettingsTab extends React.Component { static propTypes = { closeSettingsFn: PropTypes.func.isRequired, diff --git a/src/components/views/settings/tabs/user/VoiceUserSettingsTab.js b/src/components/views/settings/tabs/user/VoiceUserSettingsTab.js index a78cc10b92..bc6fe796b8 100644 --- a/src/components/views/settings/tabs/user/VoiceUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/VoiceUserSettingsTab.js @@ -25,7 +25,9 @@ import {MatrixClientPeg} from "../../../../../MatrixClientPeg"; import * as sdk from "../../../../../index"; import Modal from "../../../../../Modal"; import {SettingLevel} from "../../../../../settings/SettingLevel"; +import {replaceableComponent} from "../../../../../utils/replaceableComponent"; +@replaceableComponent("views.settings.tabs.user.VoiceUserSettingsTab") export default class VoiceUserSettingsTab extends React.Component { constructor() { super(); diff --git a/src/components/views/terms/InlineTermsAgreement.js b/src/components/views/terms/InlineTermsAgreement.js index 5f6e276976..473a97642c 100644 --- a/src/components/views/terms/InlineTermsAgreement.js +++ b/src/components/views/terms/InlineTermsAgreement.js @@ -20,7 +20,9 @@ import {_t, pickBestLanguage} from "../../../languageHandler"; import * as sdk from "../../.."; import {objectClone} from "../../../utils/objects"; import StyledCheckbox from "../elements/StyledCheckbox"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.terms.InlineTermsAgreement") export default class InlineTermsAgreement extends React.Component { static propTypes = { policiesAndServicePairs: PropTypes.array.isRequired, // array of service/policy pairs diff --git a/src/components/views/toasts/NonUrgentEchoFailureToast.tsx b/src/components/views/toasts/NonUrgentEchoFailureToast.tsx index 76d0328e8b..abf5b10692 100644 --- a/src/components/views/toasts/NonUrgentEchoFailureToast.tsx +++ b/src/components/views/toasts/NonUrgentEchoFailureToast.tsx @@ -19,7 +19,9 @@ import { _t } from "../../../languageHandler"; import AccessibleButton from "../elements/AccessibleButton"; import Modal from "../../../Modal"; import ServerOfflineDialog from "../dialogs/ServerOfflineDialog"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.toasts.NonUrgentEchoFailureToast") export default class NonUrgentEchoFailureToast extends React.PureComponent { private openDialog = () => { Modal.createTrackedDialog('Local Echo Server Error', '', ServerOfflineDialog, {}); diff --git a/src/components/views/toasts/VerificationRequestToast.tsx b/src/components/views/toasts/VerificationRequestToast.tsx index 8c8a74b2be..010c8fd12f 100644 --- a/src/components/views/toasts/VerificationRequestToast.tsx +++ b/src/components/views/toasts/VerificationRequestToast.tsx @@ -29,6 +29,7 @@ import GenericToast from "./GenericToast"; import {VerificationRequest} from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest"; import {DeviceInfo} from "matrix-js-sdk/src/crypto/deviceinfo"; import {Action} from "../../../dispatcher/actions"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { toastKey: string; @@ -40,6 +41,7 @@ interface IState { device?: DeviceInfo; } +@replaceableComponent("views.toasts.VerificationRequestToast") export default class VerificationRequestToast extends React.PureComponent { private intervalHandle: NodeJS.Timeout; diff --git a/src/components/views/verification/VerificationCancelled.js b/src/components/views/verification/VerificationCancelled.js index fc2a287359..0bbaea1804 100644 --- a/src/components/views/verification/VerificationCancelled.js +++ b/src/components/views/verification/VerificationCancelled.js @@ -18,7 +18,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.verification.VerificationCancelled") export default class VerificationCancelled extends React.Component { static propTypes = { onDone: PropTypes.func.isRequired, diff --git a/src/components/views/verification/VerificationComplete.js b/src/components/views/verification/VerificationComplete.js index 2214711b1f..cf2a72591c 100644 --- a/src/components/views/verification/VerificationComplete.js +++ b/src/components/views/verification/VerificationComplete.js @@ -18,7 +18,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.verification.VerificationComplete") export default class VerificationComplete extends React.Component { static propTypes = { onDone: PropTypes.func.isRequired, diff --git a/src/components/views/verification/VerificationShowSas.js b/src/components/views/verification/VerificationShowSas.js index 09374b91af..36f99b2140 100644 --- a/src/components/views/verification/VerificationShowSas.js +++ b/src/components/views/verification/VerificationShowSas.js @@ -21,11 +21,13 @@ import {PendingActionSpinner} from "../right_panel/EncryptionInfo"; import AccessibleButton from "../elements/AccessibleButton"; import DialogButtons from "../elements/DialogButtons"; import { fixupColorFonts } from '../../../utils/FontManager'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; function capFirst(s) { return s.charAt(0).toUpperCase() + s.slice(1); } +@replaceableComponent("views.verification.VerificationShowSas") export default class VerificationShowSas extends React.Component { static propTypes = { pending: PropTypes.bool, diff --git a/src/components/views/voip/CallContainer.tsx b/src/components/views/voip/CallContainer.tsx index 51925cb147..9d0047fc54 100644 --- a/src/components/views/voip/CallContainer.tsx +++ b/src/components/views/voip/CallContainer.tsx @@ -17,6 +17,7 @@ limitations under the License. import React from 'react'; import IncomingCallBox from './IncomingCallBox'; import CallPreview from './CallPreview'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { @@ -26,6 +27,7 @@ interface IState { } +@replaceableComponent("views.voip.CallContainer") export default class CallContainer extends React.PureComponent { public render() { return
diff --git a/src/components/views/voip/CallPreview.tsx b/src/components/views/voip/CallPreview.tsx index c08e52181b..29de068b0c 100644 --- a/src/components/views/voip/CallPreview.tsx +++ b/src/components/views/voip/CallPreview.tsx @@ -26,6 +26,7 @@ import PersistentApp from "../elements/PersistentApp"; import SettingsStore from "../../../settings/SettingsStore"; import { CallEvent, CallState, MatrixCall } from 'matrix-js-sdk/src/webrtc/call'; import { MatrixClientPeg } from '../../../MatrixClientPeg'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const SHOW_CALL_IN_STATES = [ CallState.Connected, @@ -85,6 +86,7 @@ function getPrimarySecondaryCalls(calls: MatrixCall[]): [MatrixCall, MatrixCall[ * CallPreview shows a small version of CallView hovering over the UI in 'picture-in-picture' * (PiP mode). It displays the call(s) which is *not* in the room the user is currently viewing. */ +@replaceableComponent("views.voip.CallPreview") export default class CallPreview extends React.Component { private roomStoreToken: any; private dispatcherRef: string; diff --git a/src/components/views/voip/CallView.tsx b/src/components/views/voip/CallView.tsx index 7cac682794..9bdc8fb11d 100644 --- a/src/components/views/voip/CallView.tsx +++ b/src/components/views/voip/CallView.tsx @@ -31,6 +31,7 @@ import {alwaysAboveLeftOf, alwaysAboveRightOf, ChevronFace, ContextMenuButton} f import CallContextMenu from '../context_menus/CallContextMenu'; import { avatarUrlForMember } from '../../../Avatar'; import DialpadContextMenu from '../context_menus/DialpadContextMenu'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { // The call for us to display @@ -100,6 +101,7 @@ const BOTTOM_PADDING = 10; const BOTTOM_MARGIN_TOP_BOTTOM = 10; // top margin plus bottom margin const CONTEXT_MENU_VPADDING = 8; // How far the context menu sits above the button (px) +@replaceableComponent("views.voip.CallView") export default class CallView extends React.Component { private dispatcherRef: string; private contentRef = createRef(); diff --git a/src/components/views/voip/CallViewForRoom.tsx b/src/components/views/voip/CallViewForRoom.tsx index 4cb4e66fbe..97960d1e0b 100644 --- a/src/components/views/voip/CallViewForRoom.tsx +++ b/src/components/views/voip/CallViewForRoom.tsx @@ -19,6 +19,7 @@ import React from 'react'; import CallHandler from '../../../CallHandler'; import CallView from './CallView'; import dis from '../../../dispatcher/dispatcher'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { // What room we should display the call for @@ -40,6 +41,7 @@ interface IState { * Wrapper for CallView that always display the call in a given room, * or nothing if there is no call in that room. */ +@replaceableComponent("views.voip.CallViewForRoom") export default class CallViewForRoom extends React.Component { private dispatcherRef: string; diff --git a/src/components/views/voip/DialPad.tsx b/src/components/views/voip/DialPad.tsx index da88f49adf..3598f511f5 100644 --- a/src/components/views/voip/DialPad.tsx +++ b/src/components/views/voip/DialPad.tsx @@ -16,6 +16,7 @@ limitations under the License. import * as React from "react"; import AccessibleButton from "../elements/AccessibleButton"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const BUTTONS = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '*', '0', '#']; @@ -59,6 +60,7 @@ interface IProps { onDialPress?: (string) => void; } +@replaceableComponent("views.voip.Dialpad") export default class Dialpad extends React.PureComponent { render() { const buttonNodes = []; diff --git a/src/components/views/voip/DialPadModal.tsx b/src/components/views/voip/DialPadModal.tsx index 9f031a48a3..c085809d5a 100644 --- a/src/components/views/voip/DialPadModal.tsx +++ b/src/components/views/voip/DialPadModal.tsx @@ -25,6 +25,7 @@ import dis from '../../../dispatcher/dispatcher'; import Modal from "../../../Modal"; import ErrorDialog from "../../views/dialogs/ErrorDialog"; import CallHandler from "../../../CallHandler"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { onFinished: (boolean) => void; @@ -34,6 +35,7 @@ interface IState { value: string; } +@replaceableComponent("views.voip.DialpadModal") export default class DialpadModal extends React.PureComponent { constructor(props) { super(props); diff --git a/src/components/views/voip/IncomingCallBox.tsx b/src/components/views/voip/IncomingCallBox.tsx index a495093d85..0ca2a196c2 100644 --- a/src/components/views/voip/IncomingCallBox.tsx +++ b/src/components/views/voip/IncomingCallBox.tsx @@ -25,6 +25,7 @@ import CallHandler from '../../../CallHandler'; import RoomAvatar from '../avatars/RoomAvatar'; import FormButton from '../elements/FormButton'; import { CallState } from 'matrix-js-sdk/src/webrtc/call'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { } @@ -33,6 +34,7 @@ interface IState { incomingCall: any; } +@replaceableComponent("views.voip.IncomingCallBox") export default class IncomingCallBox extends React.Component { private dispatcherRef: string; diff --git a/src/components/views/voip/VideoFeed.tsx b/src/components/views/voip/VideoFeed.tsx index 5210f28eb1..23dbe4d46b 100644 --- a/src/components/views/voip/VideoFeed.tsx +++ b/src/components/views/voip/VideoFeed.tsx @@ -18,6 +18,7 @@ import classnames from 'classnames'; import { MatrixCall } from 'matrix-js-sdk/src/webrtc/call'; import React, {createRef} from 'react'; import SettingsStore from "../../../settings/SettingsStore"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; export enum VideoFeedType { Local, @@ -37,6 +38,7 @@ interface IProps { onResize?: (e: Event) => void, } +@replaceableComponent("views.voip.VideoFeed") export default class VideoFeed extends React.Component { private vid = createRef(); From 591ccabab91e0ab5d30cc23acaca56c01c57858a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 8 Mar 2021 20:26:08 -0700 Subject: [PATCH 65/91] Remove a bunch of useless 'use strict' definitions --- src/components/structures/EmbeddedPage.js | 2 -- src/components/views/auth/AuthBody.js | 2 -- src/components/views/auth/AuthHeaderLogo.js | 2 -- src/components/views/auth/CompleteSecurityBody.js | 2 -- src/components/views/elements/Flair.js | 2 -- src/components/views/messages/MAudioBody.js | 2 -- src/notifications/VectorPushRulesDefinitions.js | 2 -- src/notifications/index.js | 2 -- src/utils/MegolmExportEncryption.js | 2 -- test/test-utils.js | 2 -- test/utils/MegolmExportEncryption-test.js | 2 -- 11 files changed, 22 deletions(-) diff --git a/src/components/structures/EmbeddedPage.js b/src/components/structures/EmbeddedPage.js index cbfeff7582..c37ab3df48 100644 --- a/src/components/structures/EmbeddedPage.js +++ b/src/components/structures/EmbeddedPage.js @@ -16,8 +16,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -'use strict'; - import React from 'react'; import PropTypes from 'prop-types'; import request from 'browser-request'; diff --git a/src/components/views/auth/AuthBody.js b/src/components/views/auth/AuthBody.js index 9a078efb52..7881486a5f 100644 --- a/src/components/views/auth/AuthBody.js +++ b/src/components/views/auth/AuthBody.js @@ -14,8 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -'use strict'; - import React from 'react'; export default class AuthBody extends React.PureComponent { diff --git a/src/components/views/auth/AuthHeaderLogo.js b/src/components/views/auth/AuthHeaderLogo.js index 9edf149a83..2f27885322 100644 --- a/src/components/views/auth/AuthHeaderLogo.js +++ b/src/components/views/auth/AuthHeaderLogo.js @@ -14,8 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -'use strict'; - import React from 'react'; export default class AuthHeaderLogo extends React.PureComponent { diff --git a/src/components/views/auth/CompleteSecurityBody.js b/src/components/views/auth/CompleteSecurityBody.js index d757de9fe0..734af3192c 100644 --- a/src/components/views/auth/CompleteSecurityBody.js +++ b/src/components/views/auth/CompleteSecurityBody.js @@ -14,8 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -'use strict'; - import React from 'react'; export default class CompleteSecurityBody extends React.PureComponent { diff --git a/src/components/views/elements/Flair.js b/src/components/views/elements/Flair.js index 0f06904b68..645444b300 100644 --- a/src/components/views/elements/Flair.js +++ b/src/components/views/elements/Flair.js @@ -14,8 +14,6 @@ limitations under the License. */ -'use strict'; - import React from 'react'; import PropTypes from 'prop-types'; import FlairStore from '../../../stores/FlairStore'; diff --git a/src/components/views/messages/MAudioBody.js b/src/components/views/messages/MAudioBody.js index 587dee4513..ac42b485d7 100644 --- a/src/components/views/messages/MAudioBody.js +++ b/src/components/views/messages/MAudioBody.js @@ -14,8 +14,6 @@ limitations under the License. */ -'use strict'; - import React from 'react'; import MFileBody from './MFileBody'; diff --git a/src/notifications/VectorPushRulesDefinitions.js b/src/notifications/VectorPushRulesDefinitions.js index 98d197a004..c049a81c15 100644 --- a/src/notifications/VectorPushRulesDefinitions.js +++ b/src/notifications/VectorPushRulesDefinitions.js @@ -15,8 +15,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -'use strict'; - import { _td } from '../languageHandler'; import {StandardActions} from "./StandardActions"; import {PushRuleVectorState} from "./PushRuleVectorState"; diff --git a/src/notifications/index.js b/src/notifications/index.js index 7c400ad8b3..96c176303b 100644 --- a/src/notifications/index.js +++ b/src/notifications/index.js @@ -15,8 +15,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -'use strict'; - export * from "./NotificationUtils"; export * from "./PushRuleVectorState"; export * from "./VectorPushRulesDefinitions"; diff --git a/src/utils/MegolmExportEncryption.js b/src/utils/MegolmExportEncryption.js index cde20a0eb2..be7472901a 100644 --- a/src/utils/MegolmExportEncryption.js +++ b/src/utils/MegolmExportEncryption.js @@ -15,8 +15,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; - // polyfill textencoder if necessary import * as TextEncodingUtf8 from 'text-encoding-utf-8'; let TextEncoder = window.TextEncoder; diff --git a/test/test-utils.js b/test/test-utils.js index 839e1d6cd8..b6e0468d86 100644 --- a/test/test-utils.js +++ b/test/test-utils.js @@ -1,5 +1,3 @@ -"use strict"; - import React from 'react'; import {MatrixClientPeg as peg} from '../src/MatrixClientPeg'; import dis from '../src/dispatcher/dispatcher'; diff --git a/test/utils/MegolmExportEncryption-test.js b/test/utils/MegolmExportEncryption-test.js index 1fd305b0a6..e0ed5ba26a 100644 --- a/test/utils/MegolmExportEncryption-test.js +++ b/test/utils/MegolmExportEncryption-test.js @@ -14,8 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; - import {TextEncoder} from "util"; import nodeCrypto from "crypto"; import { Crypto } from "@peculiar/webcrypto"; From 81e1f36c4b3a0b5a260da20f9b84e91083d4f302 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 8 Mar 2021 17:48:08 +0000 Subject: [PATCH 66/91] Tidy up TemporaryTile now that it isn't temporary --- .../views/avatars/_DecoratedRoomAvatar.scss | 3 +-- .../{TemporaryTile.tsx => ExtraTile.tsx} | 7 +++-- src/components/views/rooms/RoomList.tsx | 14 +++++----- src/components/views/rooms/RoomSublist.tsx | 26 +++++++++---------- 4 files changed, 23 insertions(+), 27 deletions(-) rename src/components/views/rooms/{TemporaryTile.tsx => ExtraTile.tsx} (92%) diff --git a/res/css/views/avatars/_DecoratedRoomAvatar.scss b/res/css/views/avatars/_DecoratedRoomAvatar.scss index e0afd9de66..2631cbfb40 100644 --- a/res/css/views/avatars/_DecoratedRoomAvatar.scss +++ b/res/css/views/avatars/_DecoratedRoomAvatar.scss @@ -14,8 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// XXX: We shouldn't be using TemporaryTile anywhere - delete it. -.mx_DecoratedRoomAvatar, .mx_TemporaryTile { +.mx_DecoratedRoomAvatar, .mx_ExtraTile { position: relative; &.mx_DecoratedRoomAvatar_cutout .mx_BaseAvatar { diff --git a/src/components/views/rooms/TemporaryTile.tsx b/src/components/views/rooms/ExtraTile.tsx similarity index 92% rename from src/components/views/rooms/TemporaryTile.tsx rename to src/components/views/rooms/ExtraTile.tsx index 31d2acbc61..20d12955d5 100644 --- a/src/components/views/rooms/TemporaryTile.tsx +++ b/src/components/views/rooms/ExtraTile.tsx @@ -1,5 +1,5 @@ /* -Copyright 2020 The Matrix.org Foundation C.I.C. +Copyright 2020, 2021 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -36,8 +36,7 @@ interface IState { hover: boolean; } -// TODO: Remove with community invites in the room list: https://github.com/vector-im/element-web/issues/14456 -export default class TemporaryTile extends React.Component { +export default class ExtraTile extends React.Component { constructor(props: IProps) { super(props); @@ -57,8 +56,8 @@ export default class TemporaryTile extends React.Component { public render(): React.ReactElement { // XXX: We copy classes because it's easier const classes = classNames({ + 'mx_ExtraTile': true, 'mx_RoomTile': true, - 'mx_TemporaryTile': true, 'mx_RoomTile_selected': this.props.isSelected, 'mx_RoomTile_minimized': this.props.isMinimized, }); diff --git a/src/components/views/rooms/RoomList.tsx b/src/components/views/rooms/RoomList.tsx index beb85e50ce..7b44647be6 100644 --- a/src/components/views/rooms/RoomList.tsx +++ b/src/components/views/rooms/RoomList.tsx @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import * as React from "react"; +import React, { ReactComponentElement } from "react"; import { Dispatcher } from "flux"; import { Room } from "matrix-js-sdk/src/models/room"; import * as fbEmitter from "fbemitter"; @@ -34,7 +34,7 @@ import RoomSublist from "./RoomSublist"; import { ActionPayload } from "../../../dispatcher/payloads"; import { MatrixClientPeg } from "../../../MatrixClientPeg"; import GroupAvatar from "../avatars/GroupAvatar"; -import TemporaryTile from "./TemporaryTile"; +import ExtraTile from "./ExtraTile"; import { StaticNotificationState } from "../../../stores/notifications/StaticNotificationState"; import { NotificationColor } from "../../../stores/notifications/NotificationColor"; import { Action } from "../../../dispatcher/actions"; @@ -422,7 +422,7 @@ export default class RoomList extends React.PureComponent { dis.dispatch({ action: Action.ViewRoomDirectory, initialText }); }; - private renderSuggestedRooms(): JSX.Element[] { + private renderSuggestedRooms(): ReactComponentElement[] { return this.state.suggestedRooms.map(room => { const name = room.name || room.canonical_alias || room.aliases.pop() || _t("Empty room"); const avatar = ( @@ -443,7 +443,7 @@ export default class RoomList extends React.PureComponent { }); }; return ( - { }); } - private renderCommunityInvites(): TemporaryTile[] { + private renderCommunityInvites(): ReactComponentElement[] { // TODO: Put community invites in a more sensible place (not in the room list) // See https://github.com/vector-im/element-web/issues/14456 return MatrixClientPeg.get().getGroups().filter(g => { @@ -476,7 +476,7 @@ export default class RoomList extends React.PureComponent { }); }; return ( - { isMinimized={this.props.isMinimized} onResize={this.props.onResize} showSkeleton={showSkeleton} - extraBadTilesThatShouldntExist={extraTiles} + extraTiles={extraTiles} />); } diff --git a/src/components/views/rooms/RoomSublist.tsx b/src/components/views/rooms/RoomSublist.tsx index a2574bf60c..1a9ff182bc 100644 --- a/src/components/views/rooms/RoomSublist.tsx +++ b/src/components/views/rooms/RoomSublist.tsx @@ -17,7 +17,7 @@ limitations under the License. */ import * as React from "react"; -import {createRef} from "react"; +import { createRef, ReactComponentElement } from "react"; import { Room } from "matrix-js-sdk/src/models/room"; import classNames from 'classnames'; import { RovingAccessibleButton, RovingTabIndexWrapper } from "../../../accessibility/RovingTabIndex"; @@ -48,7 +48,7 @@ import { RoomNotificationStateStore } from "../../../stores/notifications/RoomNo import RoomListLayoutStore from "../../../stores/room-list/RoomListLayoutStore"; import { arrayFastClone, arrayHasOrderChange } from "../../../utils/arrays"; import { objectExcluding, objectHasDiff } from "../../../utils/objects"; -import TemporaryTile from "./TemporaryTile"; +import ExtraTile from "./ExtraTile"; import { ListNotificationState } from "../../../stores/notifications/ListNotificationState"; import IconizedContextMenu from "../context_menus/IconizedContextMenu"; @@ -73,9 +73,7 @@ interface IProps { onResize: () => void; showSkeleton?: boolean; - // TODO: Don't use this. It's for community invites, and community invites shouldn't be here. - // You should feel bad if you use this. - extraBadTilesThatShouldntExist?: TemporaryTile[]; + extraTiles?: ReactComponentElement[]; // TODO: Account for https://github.com/vector-im/element-web/issues/14179 } @@ -95,7 +93,7 @@ interface IState { isExpanded: boolean; // used for the for expand of the sublist when the room list is being filtered height: number; rooms: Room[]; - filteredExtraTiles?: TemporaryTile[]; + filteredExtraTiles?: ReactComponentElement[]; } export default class RoomSublist extends React.Component { @@ -153,12 +151,12 @@ export default class RoomSublist extends React.Component { return padding; } - private get extraTiles(): TemporaryTile[] | null { + private get extraTiles(): ReactComponentElement[] | null { if (this.state.filteredExtraTiles) { return this.state.filteredExtraTiles; } - if (this.props.extraBadTilesThatShouldntExist) { - return this.props.extraBadTilesThatShouldntExist; + if (this.props.extraTiles) { + return this.props.extraTiles; } return null; } @@ -177,7 +175,7 @@ export default class RoomSublist extends React.Component { } public componentDidUpdate(prevProps: Readonly, prevState: Readonly) { - const prevExtraTiles = prevState.filteredExtraTiles || prevProps.extraBadTilesThatShouldntExist; + const prevExtraTiles = prevState.filteredExtraTiles || prevProps.extraTiles; // as the rooms can come in one by one we need to reevaluate // the amount of available rooms to cap the amount of requested visible rooms by the layout if (RoomSublist.calcNumTiles(prevState.rooms, prevExtraTiles) !== this.numTiles) { @@ -200,8 +198,8 @@ export default class RoomSublist extends React.Component { // If we're supposed to handle extra tiles, take the performance hit and re-render all the // time so we don't have to consider them as part of the visible room optimization. - const prevExtraTiles = this.props.extraBadTilesThatShouldntExist || []; - const nextExtraTiles = (nextState.filteredExtraTiles || nextProps.extraBadTilesThatShouldntExist) || []; + const prevExtraTiles = this.props.extraTiles || []; + const nextExtraTiles = (nextState.filteredExtraTiles || nextProps.extraTiles) || []; if (prevExtraTiles.length > 0 || nextExtraTiles.length > 0) { return true; } @@ -249,10 +247,10 @@ export default class RoomSublist extends React.Component { private onListsUpdated = () => { const stateUpdates: IState & any = {}; // &any is to avoid a cast on the initializer - if (this.props.extraBadTilesThatShouldntExist) { + if (this.props.extraTiles) { const nameCondition = RoomListStore.instance.getFirstNameFilterCondition(); if (nameCondition) { - stateUpdates.filteredExtraTiles = this.props.extraBadTilesThatShouldntExist + stateUpdates.filteredExtraTiles = this.props.extraTiles .filter(t => nameCondition.matches(t.props.displayName || "")); } else if (this.state.filteredExtraTiles) { stateUpdates.filteredExtraTiles = null; From 41c87c757028ad00da4b4850374843d1661da00a Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 9 Mar 2021 13:35:42 +0000 Subject: [PATCH 67/91] remove obsolete comment --- src/stores/SetupEncryptionStore.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/stores/SetupEncryptionStore.js b/src/stores/SetupEncryptionStore.js index 28ab76edc0..3839f27a77 100644 --- a/src/stores/SetupEncryptionStore.js +++ b/src/stores/SetupEncryptionStore.js @@ -97,7 +97,6 @@ export class SetupEncryptionStore extends EventEmitter { if (!this.hasDevicesToVerifyAgainst && !this.keyInfo) { // skip before we can even render anything. - // XXX: this causes a dialog box flash this.phase = PHASE_FINISHED; } else { this.phase = PHASE_INTRO; From dd0b0834e68e7f96c683604d23c06b94f0575f6c Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 9 Mar 2021 13:40:48 +0000 Subject: [PATCH 68/91] Fix React warning --- src/components/views/dialogs/InfoDialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/dialogs/InfoDialog.js b/src/components/views/dialogs/InfoDialog.js index 6dc9fc01b0..8207d334d3 100644 --- a/src/components/views/dialogs/InfoDialog.js +++ b/src/components/views/dialogs/InfoDialog.js @@ -27,7 +27,7 @@ export default class InfoDialog extends React.Component { className: PropTypes.string, title: PropTypes.string, description: PropTypes.node, - button: PropTypes.oneOfType(PropTypes.string, PropTypes.bool), + button: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), onFinished: PropTypes.func, hasCloseButton: PropTypes.bool, onKeyDown: PropTypes.func, From cf2c79069983a525d878e3fc634ead908091a709 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 9 Mar 2021 13:41:06 +0000 Subject: [PATCH 69/91] Pass OOB data for suggested rooms --- src/components/views/rooms/RoomList.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/views/rooms/RoomList.tsx b/src/components/views/rooms/RoomList.tsx index 7b44647be6..1573945a17 100644 --- a/src/components/views/rooms/RoomList.tsx +++ b/src/components/views/rooms/RoomList.tsx @@ -440,6 +440,10 @@ export default class RoomList extends React.PureComponent { defaultDispatcher.dispatch({ action: "view_room", room_id: room.room_id, + oobData: { + avatarUrl: room.avatar_url, + name, + }, }); }; return ( From 1cfeb3692716a8ea17a91fc14f1ef7cf756f0454 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 9 Mar 2021 13:41:37 +0000 Subject: [PATCH 70/91] Update suggested room on join --- src/stores/SpaceStore.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/stores/SpaceStore.tsx b/src/stores/SpaceStore.tsx index 1ada5d6361..d1abc68f4e 100644 --- a/src/stores/SpaceStore.tsx +++ b/src/stores/SpaceStore.tsx @@ -355,6 +355,12 @@ export class SpaceStoreClass extends AsyncStoreWithClient { // this.onRoomUpdate(room); this.onRoomsUpdate(); } + + const numSuggestedRooms = this._suggestedRooms.length; + this._suggestedRooms = this._suggestedRooms.filter(r => r.room_id !== room.roomId); + if (numSuggestedRooms !== this._suggestedRooms.length) { + this.emit(SUGGESTED_ROOMS, this._suggestedRooms); + } }; private onRoomState = (ev: MatrixEvent) => { From e6370a970bc755f5c89ccd5ffc39ea0162800453 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 9 Mar 2021 14:03:58 +0000 Subject: [PATCH 71/91] Tweak call handler stuff to not explode the room list on unsupported servers --- src/VoipUserMapper.ts | 8 +++++--- src/stores/room-list/RoomListStore.ts | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/VoipUserMapper.ts b/src/VoipUserMapper.ts index d919615349..4f5613b4a8 100644 --- a/src/VoipUserMapper.ts +++ b/src/VoipUserMapper.ts @@ -37,7 +37,7 @@ export default class VoipUserMapper { return results[0].userid; } - public async getOrCreateVirtualRoomForRoom(roomId: string):Promise { + public async getOrCreateVirtualRoomForRoom(roomId: string): Promise { const userId = DMRoomMap.shared().getUserIdForRoomId(roomId); if (!userId) return null; @@ -52,7 +52,7 @@ export default class VoipUserMapper { return virtualRoomId; } - public nativeRoomForVirtualRoom(roomId: string):string { + public nativeRoomForVirtualRoom(roomId: string): string { const virtualRoom = MatrixClientPeg.get().getRoom(roomId); if (!virtualRoom) return null; const virtualRoomEvent = virtualRoom.getAccountData(VIRTUAL_ROOM_EVENT_TYPE); @@ -60,7 +60,7 @@ export default class VoipUserMapper { return virtualRoomEvent.getContent()['native_room'] || null; } - public isVirtualRoom(room: Room):boolean { + public isVirtualRoom(room: Room): boolean { if (this.nativeRoomForVirtualRoom(room.roomId)) return true; if (this.virtualRoomIdCache.has(room.roomId)) return true; @@ -79,6 +79,8 @@ export default class VoipUserMapper { } public async onNewInvitedRoom(invitedRoom: Room) { + if (!CallHandler.sharedInstance().getSupportsVirtualRooms()) return; + const inviterId = invitedRoom.getDMInviter(); console.log(`Checking virtual-ness of room ID ${invitedRoom.roomId}, invited by ${inviterId}`); const result = await CallHandler.sharedInstance().sipNativeLookup(inviterId); diff --git a/src/stores/room-list/RoomListStore.ts b/src/stores/room-list/RoomListStore.ts index 60a960261c..5775e685fd 100644 --- a/src/stores/room-list/RoomListStore.ts +++ b/src/stores/room-list/RoomListStore.ts @@ -409,7 +409,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient { } private async handleRoomUpdate(room: Room, cause: RoomUpdateCause): Promise { - if (cause === RoomUpdateCause.NewRoom) { + if (cause === RoomUpdateCause.NewRoom && room.getMyMembership() === "invite") { // Let the visibility provider know that there is a new invited room. It would be nice // if this could just be an event that things listen for but the point of this is that // we delay doing anything about this room until the VoipUserMapper had had a chance From 3ac4cb49fc7d2dfaac3c7c775c45f7fe6402d25f Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 9 Mar 2021 14:16:29 +0000 Subject: [PATCH 72/91] Tweak styling of manage rooms in space ux --- res/css/structures/_SpaceRoomDirectory.scss | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/res/css/structures/_SpaceRoomDirectory.scss b/res/css/structures/_SpaceRoomDirectory.scss index 5cb91820cf..c96398594f 100644 --- a/res/css/structures/_SpaceRoomDirectory.scss +++ b/res/css/structures/_SpaceRoomDirectory.scss @@ -203,8 +203,9 @@ limitations under the License. .mx_SpaceRoomDirectory_actions { width: 180px; text-align: right; - height: min-content; - margin: auto 0 auto 28px; + margin-left: 28px; + display: inline-flex; + align-items: center; .mx_AccessibleButton { vertical-align: middle; @@ -223,9 +224,5 @@ limitations under the License. line-height: $font-15px; color: $secondary-fg-color; } - - .mx_Checkbox { - display: inline-block; - } } } From 71b8959d3c12fca4d5cf88db5d2de215b22bb34a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 9 Mar 2021 09:36:17 -0700 Subject: [PATCH 73/91] Apply suggestions from code review Co-authored-by: J. Ryan Stinnett --- src/components/views/rooms/BasicMessageComposer.tsx | 2 +- src/components/views/rooms/ForwardMessage.js | 2 +- src/components/views/voip/DialPad.tsx | 2 +- src/components/views/voip/DialPadModal.tsx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/views/rooms/BasicMessageComposer.tsx b/src/components/views/rooms/BasicMessageComposer.tsx index 829809ad49..5ab2b82a32 100644 --- a/src/components/views/rooms/BasicMessageComposer.tsx +++ b/src/components/views/rooms/BasicMessageComposer.tsx @@ -106,7 +106,7 @@ interface IState { completionIndex?: number; } -@replaceableComponent("views.rooms.BasixMessageEditor") +@replaceableComponent("views.rooms.BasicMessageEditor") export default class BasicMessageEditor extends React.Component { private editorRef = createRef(); private autocompleteRef = createRef(); diff --git a/src/components/views/rooms/ForwardMessage.js b/src/components/views/rooms/ForwardMessage.js index 222895ef04..dd894c0dcf 100644 --- a/src/components/views/rooms/ForwardMessage.js +++ b/src/components/views/rooms/ForwardMessage.js @@ -21,7 +21,7 @@ import { _t } from '../../../languageHandler'; import {Key} from '../../../Keyboard'; import {replaceableComponent} from "../../../utils/replaceableComponent"; -@replaceableComponent("views.rooms.FowardMessage") +@replaceableComponent("views.rooms.ForwardMessage") export default class ForwardMessage extends React.Component { static propTypes = { onCancelClick: PropTypes.func.isRequired, diff --git a/src/components/views/voip/DialPad.tsx b/src/components/views/voip/DialPad.tsx index 3598f511f5..68092fb0be 100644 --- a/src/components/views/voip/DialPad.tsx +++ b/src/components/views/voip/DialPad.tsx @@ -60,7 +60,7 @@ interface IProps { onDialPress?: (string) => void; } -@replaceableComponent("views.voip.Dialpad") +@replaceableComponent("views.voip.DialPad") export default class Dialpad extends React.PureComponent { render() { const buttonNodes = []; diff --git a/src/components/views/voip/DialPadModal.tsx b/src/components/views/voip/DialPadModal.tsx index c085809d5a..cdd5bc6641 100644 --- a/src/components/views/voip/DialPadModal.tsx +++ b/src/components/views/voip/DialPadModal.tsx @@ -35,7 +35,7 @@ interface IState { value: string; } -@replaceableComponent("views.voip.DialpadModal") +@replaceableComponent("views.voip.DialPadModal") export default class DialpadModal extends React.PureComponent { constructor(props) { super(props); From 375ffafda647a47f9390b272f93b84ca2d8571a0 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 9 Mar 2021 10:13:16 -0700 Subject: [PATCH 74/91] Fix tests failing to load skin We should find a better way to do this, but this works well enough. --- test/accessibility/RovingTabIndex-test.js | 1 + .../components/views/messages/MKeyVerificationConclusion-test.js | 1 + test/components/views/rooms/SendMessageComposer-test.js | 1 + test/createRoom-test.js | 1 + test/editor/deserialize-test.js | 1 + 5 files changed, 5 insertions(+) diff --git a/test/accessibility/RovingTabIndex-test.js b/test/accessibility/RovingTabIndex-test.js index 8be4a2976c..5aa93f99f3 100644 --- a/test/accessibility/RovingTabIndex-test.js +++ b/test/accessibility/RovingTabIndex-test.js @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +import '../skinned-sdk'; // Must be first for skinning to work import React from "react"; import Adapter from "enzyme-adapter-react-16"; import { configure, mount } from "enzyme"; diff --git a/test/components/views/messages/MKeyVerificationConclusion-test.js b/test/components/views/messages/MKeyVerificationConclusion-test.js index 689151fe3f..45e122295b 100644 --- a/test/components/views/messages/MKeyVerificationConclusion-test.js +++ b/test/components/views/messages/MKeyVerificationConclusion-test.js @@ -1,3 +1,4 @@ +import '../../../skinned-sdk'; // Must be first for skinning to work import React from 'react'; import TestRenderer from 'react-test-renderer'; import { EventEmitter } from 'events'; diff --git a/test/components/views/rooms/SendMessageComposer-test.js b/test/components/views/rooms/SendMessageComposer-test.js index 6eeac7ceea..64a90eee81 100644 --- a/test/components/views/rooms/SendMessageComposer-test.js +++ b/test/components/views/rooms/SendMessageComposer-test.js @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +import '../../../skinned-sdk'; // Must be first for skinning to work import Adapter from "enzyme-adapter-react-16"; import { configure, mount } from "enzyme"; import React from "react"; diff --git a/test/createRoom-test.js b/test/createRoom-test.js index f7e8617c3f..ed8f9779f7 100644 --- a/test/createRoom-test.js +++ b/test/createRoom-test.js @@ -1,3 +1,4 @@ +import './skinned-sdk'; // Must be first for skinning to work import {_waitForMember, canEncryptToAllUsers} from '../src/createRoom'; import {EventEmitter} from 'events'; diff --git a/test/editor/deserialize-test.js b/test/editor/deserialize-test.js index 112ac7d02b..07b75aaae5 100644 --- a/test/editor/deserialize-test.js +++ b/test/editor/deserialize-test.js @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +import '../skinned-sdk'; // Must be first for skinning to work import {parseEvent} from "../../src/editor/deserialize"; import {createPartCreator} from "./mock"; From ac1ce24b74c631346a653a17e79ff20ddbc9e754 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 9 Mar 2021 20:52:30 -0700 Subject: [PATCH 75/91] Fix sent markers disappearing for edits/reactions Fixes https://github.com/vector-im/element-web/issues/16651 --- src/components/structures/MessagePanel.js | 24 +++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index 9deda54bee..b0705b5878 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -534,10 +534,17 @@ export default class MessagePanel extends React.Component { const nextEvent = i < this.props.events.length - 1 ? this.props.events[i + 1] : null; + + // The next event with tile is used to to determine the 'last successful' flag + // when rendering the tile. The shouldShowEvent function is pretty quick at what + // it does, so this should have no significant cost even when a room is used for + // not-chat purposes. + const nextTile = this.props.events.slice(i + 1).find(e => this._shouldShowEvent(e)); + // make sure we unpack the array returned by _getTilesForEvent, // otherwise react will auto-generate keys and we will end up // replacing all of the DOM elements every time we paginate. - ret.push(...this._getTilesForEvent(prevEvent, mxEv, last, nextEvent)); + ret.push(...this._getTilesForEvent(prevEvent, mxEv, last, nextEvent, nextTile)); prevEvent = mxEv; } @@ -553,7 +560,7 @@ export default class MessagePanel extends React.Component { return ret; } - _getTilesForEvent(prevEvent, mxEv, last, nextEvent) { + _getTilesForEvent(prevEvent, mxEv, last, nextEvent, nextEventWithTile) { const TileErrorBoundary = sdk.getComponent('messages.TileErrorBoundary'); const EventTile = sdk.getComponent('rooms.EventTile'); const DateSeparator = sdk.getComponent('messages.DateSeparator'); @@ -598,12 +605,21 @@ export default class MessagePanel extends React.Component { let isLastSuccessful = false; const isSentState = s => !s || s === 'sent'; const isSent = isSentState(mxEv.getAssociatedStatus()); - if (!nextEvent && isSent) { + const hasNextEvent = nextEvent && this._shouldShowEvent(nextEvent); + if (!hasNextEvent && isSent) { isLastSuccessful = true; - } else if (nextEvent && isSent && !isSentState(nextEvent.getAssociatedStatus())) { + } else if (hasNextEvent && isSent && !isSentState(nextEvent.getAssociatedStatus())) { isLastSuccessful = true; } + // This is a bit nuanced, but if our next event is hidden but a future event is not + // hidden then we're not the last successful. + if (nextEventWithTile) { // avoid length limit by wrapping in an if + if (isSentState(nextEventWithTile.getAssociatedStatus()) && nextEventWithTile !== nextEvent) { + isLastSuccessful = false; + } + } + // We only want to consider "last successful" if the event is sent by us, otherwise of course // it's successful: we received it. isLastSuccessful = isLastSuccessful && mxEv.getSender() === MatrixClientPeg.get().getUserId(); From f25db38b2b304b60c1c8b2c2d93eeaca9fb90742 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 9 Mar 2021 21:13:23 -0700 Subject: [PATCH 76/91] Add tooltips to sent/sending receipts Fixes https://github.com/vector-im/element-web/issues/16649 --- src/components/views/rooms/EventTile.js | 62 ++++++++++++++++++++++--- src/i18n/strings/en_EN.json | 3 ++ 2 files changed, 59 insertions(+), 6 deletions(-) diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index a705e92d9c..ecc7eb7131 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -39,6 +39,7 @@ import {WidgetType} from "../../../widgets/WidgetType"; import RoomAvatar from "../avatars/RoomAvatar"; import {WIDGET_LAYOUT_EVENT_TYPE} from "../../../stores/widgets/WidgetLayoutStore"; import {objectHasDiff} from "../../../utils/objects"; +import Tooltip from "../elements/Tooltip"; const eventTileTypes = { 'm.room.message': 'messages.MessageEvent', @@ -567,11 +568,8 @@ export default class EventTile extends React.Component { }; getReadAvatars() { - if (this._shouldShowSentReceipt) { - return ; - } - if (this._shouldShowSendingReceipt) { - return ; + if (this._shouldShowSentReceipt || this._shouldShowSendingReceipt) { + return ; } // return early if there are no read receipts @@ -1180,7 +1178,6 @@ class E2ePadlock extends React.Component { render() { let tooltip = null; if (this.state.hover) { - const Tooltip = sdk.getComponent("elements.Tooltip"); tooltip = ; } @@ -1195,3 +1192,56 @@ class E2ePadlock extends React.Component { ); } } + +interface ISentReceiptProps { + messageState: string; // TODO: Types for message sending state +} + +interface ISentReceiptState { + hover: boolean; +} + +class SentReceipt extends React.PureComponent { + constructor() { + super(); + + this.state = { + hover: false, + }; + } + + onHoverStart = () => { + this.setState({hover: true}); + }; + + onHoverEnd = () => { + this.setState({hover: false}); + }; + + render() { + const isSent = !this.props.messageState || this.props.messageState === 'sent'; + const receiptClasses = classNames({ + 'mx_EventTile_receiptSent': isSent, + 'mx_EventTile_receiptSending': !isSent, + }); + + let tooltip = null; + if (this.state.hover) { + let label = _t("Sending your message..."); + if (this.props.messageState === 'encrypting') { + label = _t("Encrypting your message..."); + } else if (isSent) { + label = _t("Your message was sent"); + } + // The yOffset is somewhat arbitrary - it just brings the tooltip down to be more associated + // with the read receipt. + tooltip = ; + } + + return + + {tooltip} + + ; + } +} diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 833a8c7838..9ed75bde37 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1440,6 +1440,9 @@ "Unencrypted": "Unencrypted", "Encrypted by a deleted session": "Encrypted by a deleted session", "The authenticity of this encrypted message can't be guaranteed on this device.": "The authenticity of this encrypted message can't be guaranteed on this device.", + "Sending your message...": "Sending your message...", + "Encrypting your message...": "Encrypting your message...", + "Your message was sent": "Your message was sent", "Please select the destination room for this message": "Please select the destination room for this message", "Scroll to most recent messages": "Scroll to most recent messages", "Close preview": "Close preview", From 78568d6a015c764ae1a5eaed70b35b0ab14d40e8 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 10 Mar 2021 01:40:43 -0700 Subject: [PATCH 77/91] Document behaviour of showReadReceipts=false for sent receipts --- src/components/structures/MessagePanel.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index 9deda54bee..353fd80528 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -498,6 +498,9 @@ export default class MessagePanel extends React.Component { let prevEvent = null; // the last event we showed + // Note: the EventTile might still render a "sent/sending receipt" independent of + // this information. When not providing read receipt information, the tile is likely + // to assume that sent receipts are to be shown more often. this._readReceiptsByEvent = {}; if (this.props.showReadReceipts) { this._readReceiptsByEvent = this._getReadReceiptsByShownEvent(); From 0583ea6a253074f300f7e17c213762f974b8a47b Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Wed, 10 Mar 2021 12:11:48 +0000 Subject: [PATCH 78/91] Ignore to-device decryption in the room list store This avoids meaningless warnings about "unknown" rooms. --- src/stores/room-list/RoomListStore.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/stores/room-list/RoomListStore.ts b/src/stores/room-list/RoomListStore.ts index 5775e685fd..3f415f946d 100644 --- a/src/stores/room-list/RoomListStore.ts +++ b/src/stores/room-list/RoomListStore.ts @@ -302,6 +302,9 @@ export class RoomListStoreClass extends AsyncStoreWithClient { } else if (payload.action === 'MatrixActions.Event.decrypted') { const eventPayload = (payload); // TODO: Type out the dispatcher types const roomId = eventPayload.event.getRoomId(); + if (!roomId) { + return; + } const room = this.matrixClient.getRoom(roomId); if (!room) { console.warn(`Event ${eventPayload.event.getId()} was decrypted in an unknown room ${roomId}`); From 32f737e1ba6e442974067c058dd192785e526d00 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Wed, 10 Mar 2021 13:45:37 +0000 Subject: [PATCH 79/91] Tweak sent marker code style --- src/components/structures/MessagePanel.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index b0705b5878..f8bf554cb3 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -614,10 +614,12 @@ export default class MessagePanel extends React.Component { // This is a bit nuanced, but if our next event is hidden but a future event is not // hidden then we're not the last successful. - if (nextEventWithTile) { // avoid length limit by wrapping in an if - if (isSentState(nextEventWithTile.getAssociatedStatus()) && nextEventWithTile !== nextEvent) { - isLastSuccessful = false; - } + if ( + nextEventWithTile && + nextEventWithTile !== nextEvent && + isSentState(nextEventWithTile.getAssociatedStatus()) + ) { + isLastSuccessful = false; } // We only want to consider "last successful" if the event is sent by us, otherwise of course From fc180cd6d4efc02c2193efbbc23c628fdf3e1d05 Mon Sep 17 00:00:00 2001 From: "@a2sc:matrix.org" Date: Mon, 8 Mar 2021 23:12:51 +0000 Subject: [PATCH 80/91] Translated using Weblate (German) Currently translated at 99.6% (2769 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 7304d35fcd..f0f371ebe5 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -3076,5 +3076,6 @@ "Settable at global": "Global festlegbar", "Setting definition:": "Definition der Einstellung:", "Value in this room": "Wert in diesem Raum", - "Settings Explorer": "Einstellungs-Explorer" + "Settings Explorer": "Einstellungs-Explorer", + "Values at explicit levels": "Werte für explizite Levels" } From 73327c9bc68b166e6af1973c786aa067524f2421 Mon Sep 17 00:00:00 2001 From: libexus Date: Mon, 8 Mar 2021 23:12:26 +0000 Subject: [PATCH 81/91] Translated using Weblate (German) Currently translated at 99.6% (2769 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index f0f371ebe5..65e08ae4c3 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -3073,9 +3073,10 @@ "Show chat effects (animations when receiving e.g. confetti)": "Animierte Chateffekte zeigen, wenn z.B. Konfetti-Emojis erhalten werden", "Save setting values": "Einstellungswerte speichern", "Caution:": "Vorsicht:", - "Settable at global": "Global festlegbar", + "Settable at global": "Global einstellbar", "Setting definition:": "Definition der Einstellung:", "Value in this room": "Wert in diesem Raum", "Settings Explorer": "Einstellungs-Explorer", - "Values at explicit levels": "Werte für explizite Levels" + "Values at explicit levels": "Werte für explizite Levels", + "Settable at room": "Für den Raum einstellbar" } From 2125438aac407222b88d4578bf2ce187c6301999 Mon Sep 17 00:00:00 2001 From: Tirifto Date: Wed, 10 Mar 2021 09:27:48 +0000 Subject: [PATCH 82/91] Translated using Weblate (Esperanto) Currently translated at 99.1% (2755 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/eo/ --- src/i18n/strings/eo.json | 41 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index 3f99a68187..390fb74099 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -3006,5 +3006,44 @@ "Your homeserver was unreachable and was not able to log you in. Please try again. If this continues, please contact your homeserver administrator.": "Via hejmservilo estis neatingebla kaj ne povis vin salutigi. Bonvolu reprovi. Se tio daŭros, bonvolu kontakti la administranton de via hejmservilo.", "Try again": "Reprovu", "We asked the browser to remember which homeserver you use to let you sign in, but unfortunately your browser has forgotten it. Go to the sign in page and try again.": "Ni petis la foliumilon memori, kiun hejmservilon vi uzas por saluti, sed domaĝe, via foliumilo forgesis. Iru al la saluta paĝo kaj reprovu.", - "We couldn't log you in": "Ni ne povis salutigi vin" + "We couldn't log you in": "Ni ne povis salutigi vin", + "%(creator)s created this DM.": "%(creator)s kreis ĉi tiun rektan ĉambron.", + "Invalid URL": "Nevalida URL", + "Unable to validate homeserver": "Ne povas validigi hejmservilon", + "Just a heads up, if you don't add an email and forget your password, you could permanently lose access to your account.": "Averte, se vi ne aldonos retpoŝtadreson kaj poste forgesos vian pasvorton, vi eble por ĉiam perdos aliron al via konto.", + "Continuing without email": "Daŭrigante sen retpoŝtadreso", + "We recommend you change your password and Security Key in Settings immediately": "Ni rekomendas, ke vi tuj ŝanĝu viajn pasvorton kaj Sekurecan ŝlosilon per la Agordoj", + "Transfer": "Transigi", + "Invite someone using their name, email address, username (like ) or share this room.": "Invitu iun per ĝia nomo, retpoŝtadreso, uzantonomo (ekz. ), aŭ konigu ĉi tiun ĉambron.", + "Start a conversation with someone using their name, email address or username (like ).": "Komencu interparolon kun iu per ĝia nomo, retpoŝtadreso, aŭ uzantonomo (ekz. ).", + "Failed to transfer call": "Malsukcesis transigi vokon", + "A call can only be transferred to a single user.": "Voko povas transiĝi nur al unu uzanto.", + "Learn more in our , and .": "Eksciu plion per niaj , kaj .", + "Failed to connect to your homeserver. Please close this dialog and try again.": "Malsukcesis konektiĝi al via hejmservilo. Bonvolu fermi ĉi tiun interagujon kaj reprovi.", + "Edit Values": "Redakti valorojn", + "Value in this room:": "Valoro en ĉi tiu ĉambro:", + "Value:": "Valoro:", + "Settable at room": "Agordebla ĉambre", + "Settable at global": "Agordebla ĉiee", + "Level": "Nivelo", + "Setting definition:": "Difino de agordo:", + "This UI does NOT check the types of the values. Use at your own risk.": "Ĉi tiu fasado ne kontrolas la tipojn de valoroj. Uzu je via risko.", + "Caution:": "Atentu:", + "Setting:": "Agordo:", + "Value in this room": "Valoro en ĉi tiu ĉambro", + "Value": "Valoro", + "Setting ID": "Identigilo de agordo", + "Failed to save settings": "Malsukcesis konservi agordojn", + "Settings Explorer": "Esplorilo de agordoj", + "Set my room layout for everyone": "Agordi al ĉiuj mian aranĝon de ĉambro", + "Open dial pad": "Malfermi ciferplaton", + "Back up your encryption keys with your account data in case you lose access to your sessions. Your keys will be secured with a unique Security Key.": "Savkopiu viajn čifrajn šlosilojn kune kun la datumoj de via konto, okaze ke vi perdos aliron al viaj salutaĵoj. Viaj ŝlosiloj sekuriĝos per unika Sekureca ŝlosilo.", + "Dial pad": "Ciferplato", + "Show chat effects (animations when receiving e.g. confetti)": "Montri grafikaĵojn en babilujo (ekz. movbildojn, ricevante konfetojn)", + "Use Ctrl + Enter to send a message": "Sendu mesaĝon per stirklavo (Ctrl) + eniga klavo", + "Use Command + Enter to send a message": "Sendu mesaĝon per komanda klavo + eniga klavo", + "Use Ctrl + F to search": "Serĉu per stirklavo (Ctrl) + F", + "Use Command + F to search": "Serĉu per komanda klavo + F", + "%(senderDisplayName)s changed the server ACLs for this room.": "%(senderDisplayName)s ŝanĝis la servilblokajn listojn por ĉi tiu ĉambro.", + "%(senderDisplayName)s set the server ACLs for this room.": "%(senderDisplayName)s agordis la servilblokajn listojn por ĉi tiu ĉambro." } From 7c497cc96e2e6d566008e15e44ccc50d5319b210 Mon Sep 17 00:00:00 2001 From: jelv Date: Wed, 10 Mar 2021 15:13:56 +0000 Subject: [PATCH 83/91] Translated using Weblate (Dutch) Currently translated at 100.0% (2780 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/nl/ --- src/i18n/strings/nl.json | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index db3255c051..18c7c3b0bf 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -145,7 +145,7 @@ "Displays action": "Toont actie", "Emoji": "Emoji", "%(senderName)s ended the call.": "%(senderName)s heeft opgehangen.", - "Enter passphrase": "Voer wachtwoord in", + "Enter passphrase": "Wachtwoord invoeren", "Error decrypting attachment": "Fout bij het ontsleutelen van de bijlage", "Error: Problem communicating with the given homeserver.": "Fout: probleem bij communicatie met de gegeven thuisserver.", "Existing Call": "Bestaande oproep", @@ -335,11 +335,11 @@ "Passphrases must match": "Wachtwoorden moeten overeenkomen", "Passphrase must not be empty": "Wachtwoord mag niet leeg zijn", "Export room keys": "Gesprekssleutels wegschrijven", - "Confirm passphrase": "Bevestig wachtwoord", + "Confirm passphrase": "Wachtwoord bevestigen", "Import room keys": "Gesprekssleutels inlezen", "File to import": "In te lezen bestand", "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Hiermee kunt u de sleutels van uw ontvangen berichten in versleutelde gesprekken naar een lokaal bestand wegschrijven. Als u dat bestand dan in een andere Matrix-cliënt inleest kan die ook die berichten ontcijferen.", - "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Wie het weggeschreven bestand kan lezen, kan daarmee ook alle versleutelde berichten die u kunt zien ontcijferen - ga er dus zorgvuldig mee om! Daartoe kunt u hieronder een wachtwoord invoeren, dat dan gebruikt zal worden om het bestand te versleutelen. Het is dan enkel mogelijk de gegevens in te lezen met hetzelfde wachtwoord.", + "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Het opgeslagen bestand geeft toegang tot het lezen en schrijven van uw versleutelde berichten - ga er dus zorgvuldig mee om! Bescherm uzelf door hieronder een wachtwoord in te voeren, dat dan gebruikt zal worden om het bestand te versleutelen. Het is dan alleen mogelijk de gegevens te lezen met hetzelfde wachtwoord.", "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Hiermee kunt u vanuit een andere Matrix-cliënt weggeschreven versleutelingssleutels inlezen, zodat u alle berichten die de andere cliënt kon ontcijferen ook hier kunt lezen.", "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Het weggeschreven bestand is beveiligd met een wachtwoord. Voer dat wachtwoord hier in om het bestand te ontsleutelen.", "You must join the room to see its files": "Slechts na toetreding tot het gesprek zult u de bestanden kunnen zien", @@ -792,7 +792,7 @@ "Enable widget screenshots on supported widgets": "Widget-schermafbeeldingen inschakelen op ondersteunde widgets", "Muted Users": "Gedempte gebruikers", "Popout widget": "Widget in nieuw venster openen", - "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Kan de gebeurtenis waarop gereageerd was niet laden. Wellicht bestaat die niet, of heeft u geen toestemming die te bekijken.", + "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Kan de gebeurtenis waarop gereageerd was niet laden. Wellicht bestaat die niet, of u heeft geen toestemming die te bekijken.", "This will make your account permanently unusable. You will not be able to log in, and no one will be able to re-register the same user ID. This will cause your account to leave all rooms it is participating in, and it will remove your account details from your identity server. This action is irreversible.": "Dit zal uw account voorgoed onbruikbaar maken. U zult niet meer kunnen inloggen, en niemand anders zal zich met dezelfde gebruikers-ID kunnen registreren. Hierdoor zal uw account alle gesprekken waaraan u deelneemt verlaten, en worden de accountgegevens verwijderd van de identiteitsserver. Deze stap is onomkeerbaar.", "Deactivating your account does not by default cause us to forget messages you have sent. If you would like us to forget your messages, please tick the box below.": "Het sluiten van uw account maakt op zich niet dat wij de door u verstuurde berichten vergeten. Als u wilt dat wij uw berichten vergeten, vink dan het vakje hieronder aan.", "Message visibility in Matrix is similar to email. Our forgetting your messages means that messages you have sent will not be shared with any new or unregistered users, but registered users who already have access to these messages will still have access to their copy.": "De zichtbaarheid van berichten in Matrix is zoals bij e-mails. Het vergeten van uw berichten betekent dat berichten die u heeft verstuurd niet meer gedeeld worden met nieuwe of ongeregistreerde gebruikers, maar geregistreerde gebruikers die al toegang hebben tot deze berichten zullen alsnog toegang hebben tot hun eigen kopie ervan.", @@ -1641,7 +1641,7 @@ "Your user agent": "Jouw gebruikersagent", "If you cancel now, you won't complete verifying the other user.": "Als u nu annuleert zult u de andere gebruiker niet verifiëren.", "If you cancel now, you won't complete verifying your other session.": "Als u nu annuleert zult u uw andere sessie niet verifiëren.", - "Cancel entering passphrase?": "Wachtwoordinvoer annuleren?", + "Cancel entering passphrase?": "Wachtwoord annuleren?", "Show typing notifications": "Typmeldingen weergeven", "Verify this session by completing one of the following:": "Verifieer deze sessie door een van het volgende te doen:", "Scan this unique code": "Scan deze unieke code", @@ -1981,8 +1981,8 @@ "Confirm adding phone number": "Bevestig toevoegen van het telefoonnummer", "Click the button below to confirm adding this phone number.": "Klik op de knop hieronder om het toevoegen van dit telefoonnummer te bevestigen.", "If you cancel now, you won't complete your operation.": "Als u de operatie afbreekt kunt u haar niet voltooien.", - "Review where you’re logged in": "Kijk na waar u ingelogd bent", - "New login. Was this you?": "Nieuwe login - was u dat?", + "Review where you’re logged in": "Controleer waar u ingelogd bent", + "New login. Was this you?": "Nieuwe login gevonden. Was u dat?", "%(name)s is requesting verification": "%(name)s verzoekt om verificatie", "Sends a message as html, without interpreting it as markdown": "Stuurt een bericht als HTML, zonder markdown toe te passen", "Failed to set topic": "Kon onderwerp niet instellen", @@ -2330,8 +2330,8 @@ "Start a conversation with someone using their name, email address or username (like ).": "Start een gesprek met iemand door hun naam, emailadres of gebruikersnaam (zoals ) te typen.", "Messages here are end-to-end encrypted. Verify %(displayName)s in their profile - tap on their avatar.": "Berichten hier zijn eind-tot-eind versleuteld. Verifieer %(displayName)s op hun profiel - klik op hun avatar.", "%(creator)s created this DM.": "%(creator)s maakte deze DM.", - "Switch to dark mode": "Wissel naar donkere modus", - "Switch to light mode": "Wissel naar lichte modus", + "Switch to dark mode": "Naar donkere modus wisselen", + "Switch to light mode": "Naar lichte modus wisselen", "Appearance": "Weergave", "All settings": "Alle instellingen", "Error removing address": "Fout bij verwijderen van adres", @@ -2696,7 +2696,7 @@ "Calls": "Oproepen", "Navigation": "Navigatie", "Currently indexing: %(currentRoom)s": "Momenteel indexeren: %(currentRoom)s", - "Enter your recovery passphrase a second time to confirm it.": "Voer uw herstel wachtwoord een tweede keer in om te bevestigen.", + "Enter your recovery passphrase a second time to confirm it.": "Voer uw Herstelwachtwoord een tweede keer in om te bevestigen.", "This session has detected that your Security Phrase and key for Secure Messages have been removed.": "Deze sessie heeft ontdekt dat uw veiligheidszin en sleutel voor versleutelde berichten zijn verwijderd.", "A new Security Phrase and key for Secure Messages have been detected.": "Er is een nieuwe veiligheidszin en sleutel voor versleutelde berichten gedetecteerd.", "Save your Security Key": "Uw veiligheidssleutel opslaan", @@ -2708,7 +2708,7 @@ "Secret storage:": "Sleutelopslag:", "Unable to query secret storage status": "Kan status sleutelopslag niet opvragen", "Store your Security Key somewhere safe, like a password manager or a safe, as it’s used to safeguard your encrypted data.": "Bewaar uw veiligheidssleutel op een veilige plaats, zoals in een wachtwoordmanager of een kluis, aangezien deze wordt gebruikt om uw versleutelde gegevens te beveiligen.", - "Confirm your recovery passphrase": "Bevestig uw herstel wachtwoord", + "Confirm your recovery passphrase": "Bevestig uw Herstelwachtwoord", "Use a different passphrase?": "Gebruik een ander wachtwoord?", "Enter a security phrase only you know, as it’s used to safeguard your data. To be secure, you shouldn’t re-use your account password.": "Voer een veiligheidszin in die alleen u kent, aangezien deze wordt gebruikt om uw gegevens te versleutelen. Om veilig te zijn, moet u het wachtwoord van uw account niet opnieuw gebruiken.", "Safeguard against losing access to encrypted messages & data by backing up encryption keys on your server.": "Bescherm uw server tegen toegangsverlies tot versleutelde berichten en gegevens door een back-up te maken van de versleutelingssleutels.", @@ -2797,7 +2797,7 @@ "Not a valid Security Key": "Geen geldige veiligheidssleutel", "This looks like a valid Security Key!": "Dit lijkt op een geldige veiligheidssleutel!", "Enter Security Key": "Veiligheidssleutel invoeren", - "If you've forgotten your Security Phrase you can use your Security Key or set up new recovery options": "Als u uw veiligheidszin bent vergeten, kunt u uw veiligheidssleutel gebruiken of nieuwe herstelopties instellen", + "If you've forgotten your Security Phrase you can use your Security Key or set up new recovery options": "Als u uw Herstelwachtwoord bent vergeten, kunt u uw Herstelsleutel gebruiken of nieuwe herstelopties instellen", "Access your secure message history and set up secure messaging by entering your Security Phrase.": "Ga naar uw veilige berichtengeschiedenis en stel veilige berichten in door uw veiligheidszin in te voeren.", "Enter Security Phrase": "Voer veiligheidszin in", "Successfully restored %(sessionCount)s keys": "Succesvol %(sessionCount)s sleutels hersteld", From e2cdc93be4a200f7d8c7bf759ad4f8413870d814 Mon Sep 17 00:00:00 2001 From: MamasLT Date: Tue, 9 Mar 2021 13:39:41 +0000 Subject: [PATCH 84/91] Translated using Weblate (Lithuanian) Currently translated at 68.5% (1907 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/lt/ --- src/i18n/strings/lt.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/lt.json b/src/i18n/strings/lt.json index 80b70e67e4..1973247e66 100644 --- a/src/i18n/strings/lt.json +++ b/src/i18n/strings/lt.json @@ -2089,5 +2089,7 @@ "If your other sessions do not have the key for this message you will not be able to decrypt them.": "Jei jūsų kiti seansai neturi šios žinutės rakto, jūs negalėsite jos iššifruoti.", "Missing session data": "Trūksta seanso duomenų", "Successfully restored %(sessionCount)s keys": "Sėkmingai atkurti %(sessionCount)s raktai", - "Warning: Your personal data (including encryption keys) is still stored in this session. Clear it if you're finished using this session, or want to sign in to another account.": "Įspėjimas: Jūsų asmeniniai duomenys (įskaitant šifravimo raktus) vis dar yra saugomi šiame seanse. Išvalykite juos, jei baigėte naudoti šį seansą, arba norite prisijungti prie kitos paskyros." + "Warning: Your personal data (including encryption keys) is still stored in this session. Clear it if you're finished using this session, or want to sign in to another account.": "Įspėjimas: Jūsų asmeniniai duomenys (įskaitant šifravimo raktus) vis dar yra saugomi šiame seanse. Išvalykite juos, jei baigėte naudoti šį seansą, arba norite prisijungti prie kitos paskyros.", + "Reason (optional)": "Priežastis (nebūtina)", + "Reason: %(reason)s": "Priežastis: %(reason)s" } From 0fe1e2dc182eb833a832fd242cd28b235bcb7072 Mon Sep 17 00:00:00 2001 From: tateisu Date: Wed, 10 Mar 2021 13:37:09 +0000 Subject: [PATCH 85/91] Translated using Weblate (Japanese) Currently translated at 79.1% (2199 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/ja/ --- src/i18n/strings/ja.json | 839 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 820 insertions(+), 19 deletions(-) diff --git a/src/i18n/strings/ja.json b/src/i18n/strings/ja.json index ea7d51ae05..0035bdd5df 100644 --- a/src/i18n/strings/ja.json +++ b/src/i18n/strings/ja.json @@ -341,7 +341,7 @@ "Unable to connect to Homeserver. Retrying...": "ホームサーバーに接続できません。 再試行中...", "Your browser does not support the required cryptography extensions": "お使いのブラウザは、必要な暗号化拡張機能をサポートしていません", "Not a valid %(brand)s keyfile": "有効な%(brand)sキーファイルではありません", - "Authentication check failed: incorrect password?": "認証に失敗しました: パスワードの間違っている可能性があります。", + "Authentication check failed: incorrect password?": "認証に失敗しました: 間違ったパスワード?", "Sorry, your homeserver is too old to participate in this room.": "申し訳ありませんが、あなたのホームサーバーはこの部屋に参加するには古すぎます。", "Please contact your homeserver administrator.": "ホームサーバー管理者に連絡してください。", "Failed to join room": "部屋に参加できませんでした", @@ -554,7 +554,7 @@ "Only visible to community members": "コミュニティメンバーにのみ表示されます", "Filter community rooms": "コミュニティルームを絞り込む", "Something went wrong when trying to get your communities.": "コミュニティに参加しようとすると何かがうまくいかなかった。", - "Display your community flair in rooms configured to show it.": "表示するよう設定した部屋であなたのコミュニティ バッジを表示", + "Display your community flair in rooms configured to show it.": "表示するよう設定した部屋であなたのコミュニティ バッジを表示します。", "Show developer tools": "開発者ツールを表示", "You're not currently a member of any communities.": "あなたは現在、どのコミュニティのメンバーでもありません。", "Unknown Address": "不明な住所", @@ -875,7 +875,7 @@ "Open Devtools": "開発ツールを開く", "Flair": "バッジ", "Fill screen": "フィルスクリーン", - "Unignore": "無視しない", + "Unignore": "無視をやめる", "Unable to load! Check your network connectivity and try again.": "ロードできません! ネットワーク通信を確認の上もう一度お試しください。", "Failed to invite users to the room:": "部屋にユーザーを招待できませんでした:", "You do not have permission to invite people to this room.": "この部屋にユーザーを招待する権限がありません。", @@ -1064,7 +1064,7 @@ "%(senderDisplayName)s enabled flair for %(groups)s in this room.": "%(senderDisplayName)s がこの部屋に %(groups)s のバッジを追加しました。", "%(senderDisplayName)s disabled flair for %(groups)s in this room.": "%(senderDisplayName)s がこの部屋から %(groups)s のバッジを削除しました。", "%(senderDisplayName)s enabled flair for %(newGroups)s and disabled flair for %(oldGroups)s in this room.": "%(senderDisplayName)s が %(newGroups)s のバッジを追加し、 %(oldGroups)s のバッジを削除しました。", - "Are you sure? You will lose your encrypted messages if your keys are not backed up properly.": "キーが正常にバックアップされていない場合、暗号化されたメッセージにアクセスできなくなります。本当によろしいですか?", + "Are you sure? You will lose your encrypted messages if your keys are not backed up properly.": "本当によろしいですか? もしキーが正常にバックアップされていない場合、暗号化されたメッセージにアクセスできなくなります。", "not stored": "保存されていません", "All keys backed up": "すべてのキーがバックアップされました", "Backup version: ": "バックアップのバージョン: ", @@ -1072,7 +1072,7 @@ "Backup key stored: ": "バックアップキーの保存: ", "Back up your keys before signing out to avoid losing them.": "暗号化キーを失くさないために、サインアウトする前にキーをバックアップしてください。", "Start using Key Backup": "キーのバックアップをはじめる", - "Error updating flair": "バッジの更新でエラーが発生しました。", + "Error updating flair": "バッジの更新でエラーが発生しました", "There was an error updating the flair for this room. The server may not allow it or a temporary error occurred.": "この部屋のバッジの更新でエラーが発生しました。サーバーが許可していないか、一時的なエラーが発生しました。", "Edited at %(date)s. Click to view edits.": "%(date)sに編集。クリックして編集を表示。", "edited": "編集済み", @@ -1103,7 +1103,7 @@ "Session ID:": "セッション ID:", "Session key:": "セッション鍵:", "Cross-signing": "クロス署名", - "A session's public name is visible to people you communicate with": "各セッションの公開名は、あなたの連絡先のユーザーが閲覧できます。", + "A session's public name is visible to people you communicate with": "各セッションの公開名は、あなたの連絡先のユーザーが閲覧できます", "Session name": "セッション名", "Session key": "セッション鍵", "Never send encrypted messages to unverified sessions from this session": "このセッションでは、未検証のセッションに対して暗号化されたメッセージを送信しない", @@ -1161,7 +1161,7 @@ "Confirm": "確認", "Enable audible notifications for this session": "このセッションでは音声通知を有効にする", "Enable encryption?": "暗号化を有効にしますか?", - "Once enabled, encryption for a room cannot be disabled. Messages sent in an encrypted room cannot be seen by the server, only by the participants of the room. Enabling encryption may prevent many bots and bridges from working correctly. Learn more about encryption.": "一度有効にした部屋の暗号化は無効にすることはできません。暗号化された部屋で送信されたメッセージは、サーバーからは見ることができず、その部屋の参加者だけが見ることができます。暗号化を有効にすると、多くのボットやブリッジが正常に動作しなくなる場合があります。暗号化についての詳細はこちらをご覧ください。", + "Once enabled, encryption for a room cannot be disabled. Messages sent in an encrypted room cannot be seen by the server, only by the participants of the room. Enabling encryption may prevent many bots and bridges from working correctly. Learn more about encryption.": "一度有効にした部屋の暗号化は無効にすることはできません。暗号化された部屋で送信されたメッセージは、サーバーからは見ることができず、その部屋の参加者だけが見ることができます。暗号化を有効にすると、多くのボットやブリッジが正常に動作しなくなる場合があります。暗号化についての詳細はこちらをご覧ください。", "Enter username": "ユーザー名を入力", "Email (optional)": "メールアドレス (任意)", "Phone (optional)": "電話番号 (任意)", @@ -1208,7 +1208,7 @@ "Suggestions": "提案", "Start a conversation with someone using their name, username (like ) or email address.": "相手の名前、( のような)ユーザー名、メールアドレスを使って会話を開始できます。", "Go": "続行", - "Session already verified!": "このセッションは検証済みです。", + "Session already verified!": "このセッションは検証済みです!", "WARNING: Session already verified, but keys do NOT MATCH!": "警告: このセッションは検証済みです、しかし鍵が一致していません!", "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and session %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "警告: 鍵の検証に失敗しました!提供された鍵「%(fingerprint)s」は、%(userId)s およびセッション %(deviceId)s の署名鍵「%(fprint)s」と一致しません。これはつまり、あなたの会話が傍受・盗聴されようとしている恐れがあるということです!", "Show typing notifications": "入力中通知を表示する", @@ -1234,11 +1234,11 @@ " to store messages from ": " を使用中であり ", "rooms.": "件の部屋のメッセージが含まれています。", "Manage": "管理", - "Add an email address to configure email notifications": "メールアドレスを追加すると電子メール通知の設定も行えます。", + "Add an email address to configure email notifications": "メールアドレスを追加すると電子メール通知の設定も行えます", "Custom theme URL": "カスタムテーマ URL", "Add theme": "テーマの追加", "Account management": "アカウントの管理", - "Deactivating your account is a permanent action - be careful!": "アカウントの無効化は取り消せません。ご注意ください。", + "Deactivating your account is a permanent action - be careful!": "アカウントの無効化は取り消せません。注意してください!", "Deactivate account": "アカウントの無効化", "Room list": "部屋一覧", "Timeline": "タイムライン", @@ -1283,7 +1283,7 @@ "Backup has a signature from unknown session with ID %(deviceId)s": "バックアップには、ID %(deviceId)s の未知のセッションによる署名があります", "Backup has a valid signature from this session": "バックアップには、このセッションによる有効な署名があります", "Backup has an invalid signature from this session": "バックアップには、このセッションによる無効な署名があります", - "Backup has a valid signature from verified session ": "バックアップには、検証済みのセッション による有効な署名があります", + "Backup has a valid signature from verified session ": "バックアップには検証されたセッションの による有効な署名があります", "Backup has a valid signature from unverified session ": "バックアップには、未検証のセッション による有効な署名があります", "Backup has an invalid signature from verified session ": "バックアップには、検証済みのセッション による無効な署名があります", "Backup has an invalid signature from unverified session ": "バックアップには、未検証のセッション による無効な署名があります", @@ -1313,7 +1313,7 @@ "Autocomplete delay (ms)": "自動補完の遅延 (ms)", "Missing media permissions, click the button below to request.": "メディア権限が不足しています、リクエストするには下のボタンを押してください。", "Request media permissions": "メディア権限をリクエスト", - "Joining room …": "部屋に参加中...", + "Joining room …": "部屋に参加中…", "Join the discussion": "話し合いに参加", "%(roomName)s can't be previewed. Do you want to join it?": "%(roomName)s はプレビューできません。部屋に参加しますか?", "Set addresses for this room so users can find this room through your homeserver (%(localDomain)s)": "他のユーザーがあなたのホームサーバー (%(localDomain)s) を通じてこの部屋を見つけられるよう、アドレスを設定しましょう", @@ -1436,9 +1436,9 @@ "Report bugs & give feedback": "バグ報告とフィードバック", "Everyone in this room is verified": "この部屋内の全員を検証済み", "Verify all users in a room to ensure it's secure.": "この部屋内のすべてのユーザーが安全であることを確認しました。", - "You've successfully verified %(displayName)s!": "%(displayName)s は正常に検証されました。", - "You've successfully verified %(deviceName)s (%(deviceId)s)!": "%(deviceName)s (%(deviceId)s) は正常に検証されました。", - "You've successfully verified your device!": "このデバイスは正常に検証されました。", + "You've successfully verified %(displayName)s!": "%(displayName)s は正常に検証されました!", + "You've successfully verified %(deviceName)s (%(deviceId)s)!": "%(deviceName)s (%(deviceId)s) は正常に検証されました!", + "You've successfully verified your device!": "このデバイスは正常に検証されました!", "You've successfully verified this user.": "このユーザーは正常に検証されました。", "Reject & Ignore user": "拒否した上でこのユーザーを無視する", " invited you": " があなたを招待しています", @@ -1452,7 +1452,7 @@ "Got it": "了解", "Got It": "了解", "Accepting…": "了承中…", - "Waiting for %(displayName)s to verify…": "%(displayName)s が検証するのを待っています…", + "Waiting for %(displayName)s to verify…": "%(displayName)s による検証を待っています…", "Waiting for %(displayName)s to accept…": "%(displayName)s が了承するのを待っています…", "Room avatar": "部屋のアバター", "Start Verification": "検証を開始", @@ -1484,7 +1484,7 @@ "e.g. my-room": "例: my-room", "Room address": "ルームアドレス", "New published address (e.g. #alias:server)": "新しい公開アドレス (例: #alias:server)", - "No other published addresses yet, add one below": "現在、公開アドレスがありません。以下から追加可能です。", + "No other published addresses yet, add one below": "現在、公開アドレスがありません。以下から追加可能です", "Securely cache encrypted messages locally for them to appear in search results, using %(size)s to store messages from %(rooms)s rooms.|one": "検索結果を表示させるために、暗号化されたメッセージをローカルに安全にキャッシュしています。現在、%(rooms)s 件の部屋のメッセージの保存に %(size)s を使用中です。", "Securely cache encrypted messages locally for them to appear in search results, using %(size)s to store messages from %(rooms)s rooms.|other": "検索結果を表示させるために、暗号化されたメッセージをローカルに安全にキャッシュしています。現在、%(rooms)s 件の部屋のメッセージの保存に %(size)s を使用中です。", "Mentions & Keywords": "メンションとキーワード", @@ -1531,9 +1531,810 @@ "Key share requests are sent to your other sessions automatically. If you rejected or dismissed the key share request on your other sessions, click here to request the keys for this session again.": "鍵共有リクエストは自動的にあなたの他のセッションに送信されます。他のセッションで鍵共有リクエストを拒否または却下した場合は、ここをクリックしてこのセッションの鍵を再度リクエストしてください。", "Your key share request has been sent - please check your other sessions for key share requests.": "鍵共有リクエストが送信されました。あなたの他のセッションで鍵共有リクエストをご確認ください。", "Re-request encryption keys from your other sessions.": "あなたの他のセッションに暗号鍵を再リクエストする。", - "Block anyone not part of %(serverName)s from ever joining this room.": "%(serverName)s 以外からの参加をブロック", + "Block anyone not part of %(serverName)s from ever joining this room.": "%(serverName)s 以外からの参加をブロックします。", "Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone.": "プライベートな部屋は招待者のみが参加できます。公開された部屋は誰でも検索・参加できます。", "To report a Matrix-related security issue, please read the Matrix.org Security Disclosure Policy.": "Matrix 関連のセキュリティ問題を報告するには、Matrix.org の Security Disclosure Policy をご覧ください。", "Confirm adding email": "メールアドレスの追加を確認する", - "Confirm adding this email address by using Single Sign On to prove your identity.": "シングルサインオンを使用して本人確認を行い、メールアドレスの追加を承認してください。" + "Confirm adding this email address by using Single Sign On to prove your identity.": "シングルサインオンを使用して本人確認を行い、メールアドレスの追加を承認してください。", + "There was an error creating that address. It may not be allowed by the server or a temporary failure occurred.": "そのアドレスの作成中にエラーが発生しました。 サーバーで許可されていないか、一時的な障害が発生した可能性があります。", + "Error creating address": "アドレスの作成中にエラーが発生しました", + "There was an error updating the room's alternative addresses. It may not be allowed by the server or a temporary failure occurred.": "部屋の代替アドレスの更新中にエラーが発生しました。 サーバーで許可されていないか、一時的な障害が発生した可能性があります。", + "There was an error updating the room's main address. It may not be allowed by the server or a temporary failure occurred.": "部屋のメインアドレスの更新中にエラーが発生しました。 サーバーで許可されていないか、一時的な障害が発生した可能性があります。", + "Error updating main address": "メインアドレスの更新中にエラーが発生しました", + "Mark all as read": "すべて既読としてマーク", + "Invited by %(sender)s": "%(sender)s からの招待", + "Revoke invite": "招待を取り消す", + "Could not revoke the invite. The server may be experiencing a temporary problem or you do not have sufficient permissions to revoke the invite.": "招待を取り消すことができませんでした。 サーバーで一時的な問題が発生しているか、招待を取り消すための十分な権限がない可能性があります。", + "Failed to revoke invite": "招待を取り消せませんでした", + "Hint: Begin your message with // to start it with a slash.": "ヒント: 通常メッセージをスラッシュで開始したい場合は // から始めます。", + "You can use /help to list available commands. Did you mean to send this as a message?": "/helpを使って利用可能なコマンドを一覧できます。メッセージとして送るつもりでしたか?", + "This room is running room version , which this homeserver has marked as unstable.": "この部屋はホームサーバが不安定と判断した部屋バージョンで動作しています。", + "Upgrading this room will shut down the current instance of the room and create an upgraded room with the same name.": "この部屋をアップグレードすると、部屋の現在のインスタンスがシャットダウンされて、同じ名前でアップグレードされた部屋が作成されます。", + "This room has already been upgraded.": "この部屋はすでにアップグレードされています。", + "Unread messages.": "未読メッセージ。", + "%(count)s unread messages.|one": "未読メッセージ1件。", + "%(count)s unread messages.|other": "未読メッセージ%(count)s件。", + "%(count)s unread messages including mentions.|one": "未読のメンション1件。", + "%(count)s unread messages including mentions.|other": "メンションを含む未読メッセージ%(count)s件。", + "Jump to first invite.": "最初の招待にジャンプします。", + "Jump to first unread room.": "未読のある最初の部屋にジャンプします。", + "A-Z": "A-Z", + "Activity": "活発さ", + "Show previews of messages": "メッセージのプレビューを表示する", + "Show rooms with unread messages first": "未読メッセージのある部屋を最初に表示する", + "%(errcode)s was returned while trying to access the room. If you think you're seeing this message in error, please submit a bug report.": "部屋にアクセスしようとした際に エラー(%(errcode)s)が発生しました。このメッセージが誤って表示されていると思われる場合はバグレポートを送信してください。", + "Try again later, or ask a room admin to check if you have access.": "後でもう一度試すか、あなたがアクセスできるかどうか部屋の管理者に問い合わせてください。", + "This room doesn't exist. Are you sure you're at the right place?": "この部屋は存在しません。表示内容が正しくない可能性があります?", + "You're previewing %(roomName)s. Want to join it?": "部屋 %(roomName)s のプレビューです。参加したいですか?", + "Share this email in Settings to receive invites directly in %(brand)s.": "このメールアドレスを設定から共有すると、%(brand)s から招待を受け取れます。", + "Use an identity server in Settings to receive invites directly in %(brand)s.": "設定から identity サーバーを使うと、%(brand)s から直接招待を受け取れます。", + "This invite to %(roomName)s was sent to %(email)s": "部屋 %(roomName)s への正体はメールアドレス %(email)s へ送られました", + "Link this email with your account in Settings to receive invites directly in %(brand)s.": "このメールアドレスを設定からあなたのアカウントにリンクすると %(brand)s から直接招待を受け取ることができます。", + "This invite to %(roomName)s was sent to %(email)s which is not associated with your account": "部屋 %(roomName)s への招待はアカウントに関連付けられていないメールアドレス %(email)s に送られました", + "You can still join it because this is a public room.": "公開された部屋なので参加が可能です。", + "Try to join anyway": "とにかく参加してみる", + "You can only join it with a working invite.": "有効な招待がある場合にのみ参加できます。", + "An error (%(errcode)s) was returned while trying to validate your invite. You could try to pass this information on to a room admin.": "招待を検証しようとした際にエラー(%(errcode)s)が発生しました。この情報を部屋の管理者に伝えてみてはどうでしょうか。", + "Something went wrong with your invite to %(roomName)s": "%(roomName)s への招待に問題が発生しました", + "You were banned from %(roomName)s by %(memberName)s": "%(memberName)s により %(roomName)s からあなたは禁止されました", + "Re-join": "再参加", + "Reason: %(reason)s": "理由: %(reason)s", + "You were kicked from %(roomName)s by %(memberName)s": "%(memberName)s により %(roomName)s からあなたは蹴り出されました", + "Loading room preview": "部屋プレビューのロード中", + "Sign Up": "サインアップ", + "Join the conversation with an account": "アカウントで会話に参加する", + "Rejecting invite …": "招待を拒否する…", + "%(count)s results|one": "%(count)s 件の結果", + "%(count)s results|other": "%(count)s 件の結果", + "Use the + to make a new room or explore existing ones below": "+を使って新しい部屋を作成するか、以下の既存の部屋を探索します", + "Explore all public rooms": "すべての公開ルームを探索する", + "Start a new chat": "新しいチャットを開始します", + "Can't see what you’re looking for?": "探しているものが見つかりませんか?", + "Custom Tag": "カスタムタグ", + "Explore public rooms": "公開ルームを探索する", + "Discovery options will appear once you have added a phone number above.": "上記の電話番号を追加すると Discovery オプションが表示されます。", + "Verification code": "確認コード", + "Please enter verification code sent via text.": "テキストで送信された確認コードを入力してください。", + "Unable to verify phone number.": "電話番号を検証できません。", + "Unable to share phone number": "電話番号を共有できません", + "Unable to revoke sharing for phone number": "電話番号の共有を取り消せません", + "Discovery options will appear once you have added an email above.": "上記のメールを追加すると Discovery オプションが表示されます。", + "Share": "共有", + "Revoke": "取り消す", + "Complete": "完了", + "Verify the link in your inbox": "受信したメールの検証リンクを開いてください", + "Click the link in the email you received to verify and then click continue again.": "受信したメール中のリンクを開いて検証して、その後に「続ける」を押します。", + "Your email address hasn't been verified yet": "あなたのメールアドレスはまだ検証されていません", + "Unable to share email address": "メールアドレスを共有できません", + "Unable to revoke sharing for email address": "メールアドレスの共有を取り消せません", + "To link to this room, please add an address.": "この部屋にリンクするにはアドレスを追加してください。", + "Send %(eventType)s events": "%(eventType)s イベントを送信します", + "Remove messages sent by others": "他の人から送信されたメッセージを削除する", + "An error occurred changing the user's power level. Ensure you have sufficient permissions and try again.": "ユーザーのパワーレベルの変更中にエラーが発生しました。 十分な権限があることを確認して、再試行してください。", + "Uploaded sound": "アップロードされたサウンド", + "Bridges": "ブリッジ", + "This room isn’t bridging messages to any platforms. Learn more.": "この部屋はどのプラットフォームともメッセージをブリッジしていません。詳細", + "This room is bridging messages to the following platforms. Learn more.": "この部屋は以下のプラットフォームにメッセージをブリッジしています。 詳細", + "View older messages in %(roomName)s.": "%(roomName)s の古いメッセージを表示します。", + "this room": "この部屋", + "Upgrade this room to the recommended room version": "この部屋を推奨部屋バージョンにアップグレードします", + "Warning: Upgrading a room will not automatically migrate room members to the new version of the room. We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.": "警告: ルームをアップグレードしても、ルームメンバーが新しいバージョンのルームに自動的に移行されることはありません。 古いバージョンのルームの新しいルームへのリンクを投稿します。ルームメンバーは、このリンクをクリックして新しいルームに参加する必要があります。", + "Your server admin has disabled end-to-end encryption by default in private rooms & Direct Messages.": "サーバー管理者は、プライベートな部屋とダイレクトメッセージでデフォルトでエンドツーエンド暗号化を無効にしています。", + "Accept all %(invitedRooms)s invites": "%(invitedRooms)s の招待を全て受け入れる", + "Read Marker off-screen lifetime (ms)": "既読マーカーを動かすまでの時間(画面オフ時)(ミリ秒)", + "Read Marker lifetime (ms)": "既読マーカーを動かすまでの時間(ミリ秒)", + "Subscribe": "購読", + "Room ID or address of ban list": "禁止リストの部屋IDまたはアドレス", + "If this isn't what you want, please use a different tool to ignore users.": "これが希望どおりでない場合は、別のツールを使用してユーザーを無視してください。", + "Subscribing to a ban list will cause you to join it!": "禁止リストを購読するとあなたはその効果が得られます!", + "Subscribed lists": "購読リスト", + "eg: @bot:* or example.org": "例: @bot:* や example.org など", + "Server or user ID to ignore": "無視するサーバー/ユーザー ID", + "Your personal ban list holds all the users/servers you personally don't want to see messages from. After ignoring your first user/server, a new room will show up in your room list named 'My Ban List' - stay in this room to keep the ban list in effect.": "あなたの個人的な禁止リストはあなたがメッセージを見たくないすべてのユーザー/サーバーを保持します。 最初のユーザー/サーバーを無視すると、「マイ禁止リスト」という名前の新しい部屋が部屋リストに表示されます。この部屋から出ると禁止リストは効果を失います。", + "Personal ban list": "個人的な禁止リスト", + "Ignoring people is done through ban lists which contain rules for who to ban. Subscribing to a ban list means the users/servers blocked by that list will be hidden from you.": "人を無視することは、誰を禁止するかについての規則を含む禁止リストを通して行われます。 禁止リストに登録すると、そのリストによってブロックされたユーザー/サーバーが非表示になります。", + "Add users and servers you want to ignore here. Use asterisks to have %(brand)s match any characters. For example, @bot:* would ignore all users that have the name 'bot' on any server.": "無視するユーザー/サーバーをここに追加します。 アスタリスクを使用して %(brand)s を任意の文字と一致させます。たとえば、 @bot:* は任意のサーバーで「bot」という名前のすべてのユーザーを無視します。", + "⚠ These settings are meant for advanced users.": "⚠これらの設定は、上級ユーザーを対象としています。", + "You are currently subscribed to:": "購読されています:", + "View rules": "ルールを表示", + "Unsubscribe": "購読の解除", + "You are not subscribed to any lists": "あなたはどのリストにも加入していません", + "You are currently ignoring:": "あなたは無視しています:", + "You have not ignored anyone.": "あなたは誰も無視していません。", + "User rules": "ユーザールール", + "Server rules": "サーバールール", + "Ban list rules - %(roomName)s": "禁止ルールのリスト - %(roomName)s", + "None": "なし", + "Please try again or view your console for hints.": "もう一度試すか、コンソールでヒントを確認してください。", + "Error unsubscribing from list": "リスト購読解除のエラー", + "Error removing ignored user/server": "ユーザー/サーバーの無視を除去する際のエラー", + "Please verify the room ID or address and try again.": "部屋のIDやアドレスを確認して、もう一度お試しください。", + "Error subscribing to list": "リスト購読のエラー", + "Something went wrong. Please try again or view your console for hints.": "何かがうまくいかなかった。 もう一度試すか、コンソールでヒントを確認してください。", + "Error adding ignored user/server": "ユーザー/サーバーの無視を追加する際のエラー", + "Ignored/Blocked": "無視/ブロック", + "Customise your experience with experimental labs features. Learn more.": "試験機能を使って利用経験を調整します。 もっと見る。", + "Chat with %(brand)s Bot": "%(brand)s ボットとチャットする", + "For help with using %(brand)s, click here or start a chat with our bot using the button below.": "%(brand)s の使用についてサポートが必要な場合は、 こちら をクリックするか、下のボタンを使用してボットとチャットを開始してください。", + "Discovery": "見つける", + "Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.": "identity サーバー (%(serverName)s) の利用規約に同意して、メールアドレスや電話番号でユーザを見つけたり見つけられたり招待したりできるようにします。", + "Your password was successfully changed. You will not receive push notifications on other sessions until you log back in to them": "パスワードは正常に変更されました。 他のセッションに再度ログインするまで、他のセッションでプッシュ通知を受信しません", + "Set the name of a font installed on your system & %(brand)s will attempt to use it.": "システムにインストールされているフォントの名前を設定すると、 %(brand)s がそれを使おうとします。", + "Theme added!": "テーマが追加されました!", + "Error downloading theme information.": "テーマ情報のダウンロード中にエラーが発生しました。", + "Invalid theme schema.": "テーマスキーマが無効です。", + "Use between %(min)s pt and %(max)s pt": "%(min)s ~ %(max)s (pt)の間の数字を指定します", + "Custom font size can only be between %(min)s pt and %(max)s pt": "カスタムフォントサイズの指定(単位: point)は %(min)s ~ %(max)s の間にできます", + "Size must be a number": "サイズには数値を指定してください", + "Disconnecting from your identity server will mean you won't be discoverable by other users and you won't be able to invite others by email or phone.": "identity サーバーから切断すると、連絡先を使ってユーザを見つけたり見つけられたり招待したりできなくなります。", + "You are not currently using an identity server. To discover and be discoverable by existing contacts you know, add one below.": "現在 identity サーバーを使用していません。連絡先を使ってユーザを見つけたり見つけられたりするには identity サーバーを以下に追加します。", + "Identity Server": "identity サーバー", + "If you don't want to use to discover and be discoverable by existing contacts you know, enter another identity server below.": "連絡先の検出に ではなく他の identity サーバーを使いたい場合は以下に指定してください。", + "You are currently using to discover and be discoverable by existing contacts you know. You can change your identity server below.": "現在 を使用して、連絡先を検出可能にしています。以下で identity サーバーを変更できます。", + "Identity Server (%(server)s)": "identity サーバー (%(server)s)", + "We recommend that you remove your email addresses and phone numbers from the identity server before disconnecting.": "切断する前に、identity サーバーからメールアドレスと電話番号を削除することをお勧めします。", + "You are still sharing your personal data on the identity server .": "まだ identity サーバー 個人データを共有しています。", + "Disconnect anyway": "とにかく切断します", + "wait and try again later": "しばらく待って、後でもう一度試す", + "contact the administrators of identity server ": "identity サーバー の管理者に連絡する", + "check your browser plugins for anything that might block the identity server (such as Privacy Badger)": "identity サーバーをブロックする可能性のあるもの(Privacy Badgerなど)がないか、ブラウザプラグインを確認してください", + "You should:": "するべきこと:", + "You should remove your personal data from identity server before disconnecting. Unfortunately, identity server is currently offline or cannot be reached.": "切断する前に identity サーバー から個人データを削除する必要があります。 しかし残念ながら identity サーバー は現在オフライン状態か、またはアクセスできません。", + "Disconnect": "切断する", + "Disconnect from the identity server ?": "identity サーバー から切断しますか?", + "Disconnect identity server": "identity サーバーを切断します", + "The identity server you have chosen does not have any terms of service.": "選択した identity サーバーには利用規約がありません。", + "Terms of service not accepted or the identity server is invalid.": "利用規約に同意していないか、identity サーバーが無効です。", + "Disconnect from the identity server and connect to instead?": "identity サーバー から切断して に接続しますか?", + "Change identity server": "identity サーバーを変更する", + "Checking server": "サーバーをチェックしています", + "Could not connect to Identity Server": "identity サーバーに接続できませんでした", + "Not a valid Identity Server (status code %(code)s)": "有効な identity サーバーではありません (ステータスコード %(code)s)", + "Identity Server URL must be HTTPS": "identityサーバーのURLは HTTPS スキーマである必要があります", + "not ready": "準備ができていない", + "ready": "準備ができました", + "unexpected type": "unexpected type", + "well formed": "well formed", + "Your keys are not being backed up from this session.": "キーはこのセッションからバックアップされていません。", + "Backing up %(sessionsRemaining)s keys...": "%(sessionsRemaining)s キーをバックアップしています…", + "Unable to load key backup status": "キーのバックアップ状態を読み込めません", + "The operation could not be completed": "操作を完了できませんでした", + "Failed to save your profile": "プロファイルの保存に失敗しました", + "You might have configured them in a client other than %(brand)s. You cannot tune them in %(brand)s but they still apply.": "%(brand)s 以外のクライアントでそれらを構成した可能性があります。%(brand)sで変更することはできませんが適用されます。", + "There are advanced notifications which are not shown here.": "ここに表示されていない追加の通知があります。", + "Clear notifications": "通知をクリアする", + "The integration manager is offline or it cannot reach your homeserver.": "integration マネージャーがオフライン状態か、またはあなたのホームサーバに到達できません。", + "%(brand)s can't securely cache encrypted messages locally while running in a web browser. Use %(brand)s Desktop for encrypted messages to appear in search results.": "Webブラウザー上で動作する %(brand)s Web は暗号化メッセージの安全なキャッシュをローカルに保存できません。%(brand)s Desktop アプリを使うと暗号化メッセージを検索結果に表示することができます。", + "%(brand)s is missing some components required for securely caching encrypted messages locally. If you'd like to experiment with this feature, build a custom %(brand)s Desktop with search components added.": "暗号化されたメッセージの安全なキャッシュをローカルに保存するためのいくつかのコンポーネントが %(brand)s にはありません。 この機能を試してみたい場合は、検索コンポーネントが追加された %(brand)s デスクトップのカスタム版をビルドしてください。", + "Securely cache encrypted messages locally for them to appear in search results.": "暗号化メッセージの安全なキャッシュをローカルに保存して、検索結果に表示できるようにします。", + "Delete sessions|one": "セッションを削除する", + "Delete sessions|other": "セッションを削除する", + "Click the button below to confirm deleting these sessions.|one": "下のボタンをクリックしてこのセッションの削除を確認してください。", + "Click the button below to confirm deleting these sessions.|other": "下のボタンをクリックしてこれらのセッションの削除を確認してください。", + "Confirm deleting these sessions": "これらのセッションの削除を確認してください", + "Confirm deleting these sessions by using Single Sign On to prove your identity.|one": "あなたのidentityを確認するためシングルサインオンを使いこのセッションを削除することを確認します。", + "Confirm deleting these sessions by using Single Sign On to prove your identity.|other": "あなたのidentityを調べるためにシングルサインオンを使いこれらのセッションを削除することを確認します。", + "not found in storage": "ストレージには見つかりません", + "Set up": "設定する", + "Cross-signing is not set up.": "クロス署名が設定されていません。", + "Passwords don't match": "パスワードが一致しません", + "Changing password will currently reset any end-to-end encryption keys on all sessions, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "パスワードを変更すると全てのセッションでエンドツーエンド暗号化キーがリセットされて暗号化されたチャット履歴が読み取れなくなります。将来的にはこれは改善される見込みですが、現時点では、パスワード変更の前に部屋のキーをエクスポートして後で再インポートすることを検討してください。", + "Channel: ": "Channel: ", + "Workspace: ": "Workspace: ", + "This bridge is managed by .": "このブリッジはにより管理されています。", + "This bridge was provisioned by .": "このブリッジはにより提供されました。", + "Decline (%(counter)s)": "Decline (%(counter)s)", + "From %(deviceName)s (%(deviceId)s)": "From %(deviceName)s (%(deviceId)s)", + "Your server isn't responding to some requests.": "あなたのサーバは数回のリクエストに応答しません。", + "Pin": "ピン", + "Folder": "フォルダー", + "Headphones": "ヘッドホン", + "Anchor": "錨", + "Bell": "鐘", + "Trumpet": "トランペット", + "Guitar": "ギター", + "Ball": "ボール", + "Trophy": "トロフィー", + "Rocket": "ロケット", + "Aeroplane": "飛行機", + "Bicycle": "自転車", + "Train": "列車", + "Flag": "旗", + "Telephone": "電話", + "Hammer": "ハンマー", + "Key": "鍵", + "Lock": "錠前", + "Scissors": "鋏", + "Paperclip": "紙ばさみ", + "Pencil": "鉛筆", + "Book": "本", + "Light bulb": "電球", + "Gift": "ギフト", + "Clock": "時計", + "Hourglass": "砂時計", + "Umbrella": "傘", + "Thumbs up": "サムズアップ", + "Santa": "サンタ", + "Spanner": "スパナ", + "Glasses": "眼鏡", + "Hat": "帽子", + "Robot": "ロボット", + "Smiley": "笑顔", + "Heart": "ハート", + "Cake": "ケーキ", + "Pizza": "ピザ", + "Corn": "トウモロコシ", + "Strawberry": "苺", + "Apple": "林檎", + "Banana": "バナナ", + "Fire": "炎", + "Cloud": "雲", + "Moon": "月", + "Globe": "金魚鉢", + "Mushroom": "茸", + "Cactus": "サボテン", + "Tree": "木", + "Flower": "花", + "Butterfly": "蝶", + "Octopus": "蛸", + "Fish": "魚", + "Turtle": "亀", + "Penguin": "ペンギン", + "Rooster": "鶏", + "Panda": "パンダ", + "Rabbit": "兎", + "Elephant": "象", + "Pig": "豚", + "Unicorn": "一角獣", + "Horse": "馬", + "Lion": "ライオン", + "Cat": "猫", + "Dog": "犬", + "To be secure, do this in person or use a trusted way to communicate.": "安全を確保するため、1人でこれを行うか、または信頼できる方法で連携してください。", + "They don't match": "それらは一致しません", + "They match": "それらは一致します", + "Cancelling…": "取り消し中…", + "Waiting for your other session to verify…": "他のセッションによる検証を待っています…", + "Waiting for your other session, %(deviceName)s (%(deviceId)s), to verify…": "他のセッション %(deviceName)s (%(deviceId)s) による検証を待っています…", + "Unable to find a supported verification method.": "どの検証方法にも対応していません。", + "Verify this user by confirming the following number appears on their screen.": "このユーザを検証するため、両方の画面に同じ番号が表示されていることを確認してください。", + "The user must be unbanned before they can be invited.": "招待する前にユーザの禁止を解除する必要があります。", + "Unrecognised address": "認識されないアドレス", + "Error leaving room": "部屋を出る際のエラー", + "Unexpected server error trying to leave the room": "部屋を出る際に予期しないサーバーエラー", + "The message you are trying to send is too large.": "送信しようとしているメッセージが大きすぎます。", + "Unexpected error resolving identity server configuration": "identity サーバー構成の解釈中に予期しないエラーが発生しました", + "Unexpected error resolving homeserver configuration": "ホームサーバー構成の解釈中に予期しないエラーが発生しました", + "You can log in, but some features will be unavailable until the identity server is back online. If you keep seeing this warning, check your configuration or contact a server admin.": "あなたはログインできますが、identity サーバーがオンラインに戻るまで一部の機能を使用できません。 この警告が引き続き表示される場合は、構成を確認するか、サーバー管理者に連絡してください。", + "You can reset your password, but some features will be unavailable until the identity server is back online. If you keep seeing this warning, check your configuration or contact a server admin.": "あなたはパスワードをリセットできますが、identity サーバーがオンラインに復帰するまで一部の機能を使用できません。 この警告が引き続き表示される場合は、構成を確認するか、サーバー管理者に連絡してください。", + "You can register, but some features will be unavailable until the identity server is back online. If you keep seeing this warning, check your configuration or contact a server admin.": "あなたは登録できますが、identity サーバーがオンラインに復帰するまで一部の機能は使用できません。 この警告が引き続き表示される場合は、構成を確認するか、サーバー管理者に連絡してください。", + "Ask your %(brand)s admin to check your config for incorrect or duplicate entries.": "設定が間違っているか重複しているか確認するよう、%(brand)s の管理者に問い合わせてください。", + "Ensure you have a stable internet connection, or get in touch with the server admin": "安定したインターネット接続があることを確認するか、サーバー管理者に連絡してください", + "See %(msgtype)s messages posted to your active room": "アクティブな部屋に送られた %(msgtype)s メッセージを見る", + "See %(msgtype)s messages posted to this room": "部屋に送られた %(msgtype)s メッセージを見る", + "Send %(msgtype)s messages as you in your active room": "あなたとしてアクティブな部屋に %(msgtype)s メッセージを送る", + "Send %(msgtype)s messages as you in this room": "あなたとして部屋に %(msgtype)s メッセージを送る", + "See general files posted to your active room": "アクティブな部屋に送られたファイルを見る", + "See general files posted to this room": "部屋に送られたファイルを見る", + "Send general files as you in your active room": "あなたとしてアクティブな部屋にファイルを送る", + "Send general files as you in this room": "あなたとしてファイルを部屋に送る", + "See videos posted to this room": "部屋に送られた動画を見る", + "See videos posted to your active room": "アクティブな部屋に送られた動画を見る", + "Send videos as you in your active room": "あなたとしてアクティブな部屋に画像を送る", + "Send videos as you in this room": "あなたとして部屋に動画を送る", + "See images posted to your active room": "アクティブな部屋に送られた画像を見る", + "See images posted to this room": "部屋に送られた画像を見る", + "Send images as you in your active room": "あなたとしてアクティブな部屋に画像を送る", + "Send images as you in this room": "あなたとして部屋に画像を送る", + "See emotes posted to your active room": "アクティブな部屋に送られたエモートを見る", + "See emotes posted to this room": "部屋に送られたエモートを見る", + "Send emotes as you in your active room": "あなたとしてアクティブな部屋にエモートを送る", + "Send emotes as you in this room": "あなたとして部屋にエモートを送る", + "See text messages posted to your active room": "アクティブな部屋に送られたテキストメッセージを見る", + "See text messages posted to this room": "部屋に送られたテキストメッセージを見る", + "Send text messages as you in your active room": "あなたとしてアクティブな部屋にメッセージを送る", + "Send text messages as you in this room": "あなたとしてテキストメッセージを部屋に送る", + "See messages posted to your active room": "アクティブな部屋に送られたメッセージを見る", + "See messages posted to this room": "部屋に送られたメッセージを見る", + "Send messages as you in your active room": "あなたとしてメッセージをアクティブな部屋に送る", + "Send messages as you in this room": "あなたとしてメッセージを部屋に送る", + "The %(capability)s capability": "%(capability)s 機能", + "See %(eventType)s events posted to your active room": "アクティブな部屋に送られたイベント %(eventType)s を見る", + "Send %(eventType)s events as you in your active room": "あなたとしてイベント %(eventType)s をアクティブな部屋に送る", + "See %(eventType)s events posted to this room": "この部屋に送られたイベント %(eventType)s を見る", + "Send %(eventType)s events as you in this room": "あなたとしてイベント %(eventType)s をこの部屋に送る", + "with state key %(stateKey)s": "ステートキー %(stateKey)s と共に", + "with an empty state key": "空のステートキーと共に", + "See when anyone posts a sticker to your active room": "アクティブな部屋にステッカーが送られた時刻を見る", + "Send stickers to your active room as you": "あなたとしてアクティブな部屋にステッカーを送る", + "See when a sticker is posted in this room": "部屋にステッカーが投稿された時刻を見る", + "Send stickers to this room as you": "あなたとして部屋にステッカーを送る", + "See when the avatar changes in your active room": "アクティブな部屋でアバターが変わった時刻を見る", + "Change the avatar of your active room": "アクティブな部屋のアバター画像を変える", + "See when the avatar changes in this room": "部屋のアバター画像が変わった時刻を見る", + "Change the avatar of this room": "部屋のアバター画像を変える", + "See when the name changes in your active room": "アクティブな部屋で名前が変わった時刻を見る", + "Change the name of your active room": "アクティブな部屋の名前を変える", + "See when the name changes in this room": "部屋の名前が変わった時刻を見る", + "Change the name of this room": "部屋の名前を変える", + "See when the topic changes in your active room": "アクティブな部屋でトピックが変わった時刻を見る", + "Change the topic of your active room": "アクティブな部屋のトピックを変える", + "See when the topic changes in this room": "部屋のトピックが変わった時刻を見る", + "Change the topic of this room": "部屋のトピックを変える", + "Change which room, message, or user you're viewing": "表示する部屋/メッセージ/ユーザを変える", + "Change which room you're viewing": "表示する部屋を変える", + "Send stickers into your active room": "アクティブな部屋にステッカーを送る", + "Send stickers into this room": "この部屋にステッカーを送る", + "Remain on your screen while running": "実行中は画面に留める", + "Remain on your screen when viewing another room, when running": "他の部屋を表示してる間も実行中は画面に留める", + "Ask this user to verify their session, or manually verify it below.": "このユーザーに彼らのセッションを検証するよう問い合わせるか、以下のように手動で検証してください。", + "Verify your other session using one of the options below.": "以下のどれか一つを使って他のセッションを検証します。", + "%(senderName)s updated a ban rule that was matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)sは禁止ルール %(oldGlob)s を %(newGlob)s (理由 %(reason)s)に変更しました", + "%(senderName)s changed a rule that was banning servers matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s はサーバ禁止ルール %(oldGlob)s を %(newGlob)s (理由 %(reason)s) に変更しました", + "%(senderName)s changed a rule that was banning rooms matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s は部屋の禁止ルール %(oldGlob)s を %(newGlob)s (理由 %(reason)s) に変更しました", + "%(senderName)s changed a rule that was banning users matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s はユーザ禁止ルール %(oldGlob)s を %(newGlob)s (理由 %(reason)s) に変更しました", + "%(senderName)s created a ban rule matching %(glob)s for %(reason)s": "%(senderName)s は禁止ルール %(glob)s (理由 %(reason)s)を作成しました", + "%(senderName)s created a rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s はサーバ禁止ルール %(glob)s (理由 %(reason)s)を作成しました", + "%(senderName)s created a rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s は部屋の禁止ルール %(glob)s (理由 %(reason)s)を作成しました", + "%(senderName)s created a rule banning users matching %(glob)s for %(reason)s": "%(senderName)s はユーザ禁止ルール %(glob)s (理由 %(reason)s)を作成しました", + "%(senderName)s updated a ban rule matching %(glob)s for %(reason)s": "%(senderName)s は禁止ルール %(glob)s (理由 %(reason)s)を更新しました", + "%(senderName)s updated the rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s はサーバ禁止ルール %(glob)s (理由 %(reason)s)を更新しました", + "%(senderName)s updated the rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s は部屋の禁止ルール %(glob)s (理由 %(reason)s)を更新しました", + "%(senderName)s updated the rule banning users matching %(glob)s for %(reason)s": "%(senderName)s はユーザ禁止ルール %(glob)s (理由 %(reason)s)を更新しました", + "%(senderName)s updated an invalid ban rule": "%(senderName)s はinvalidな禁止ルールを更新しました", + "%(senderName)s removed a ban rule matching %(glob)s": "%(senderName)s は 禁止ルール %(glob)s を削除しました", + "%(senderName)s removed the rule banning servers matching %(glob)s": "%(senderName)s はサーバ禁止ルール %(glob)s を削除しました", + "%(senderName)s removed the rule banning rooms matching %(glob)s": "%(senderName)s は部屋の禁止ルール %(glob)s を削除しました", + "%(senderName)s removed the rule banning users matching %(glob)s": "%(senderName)s はユーザー禁止ルール %(glob)s を削除しました", + "%(senderName)s has updated the widget layout": "%(senderName)s はウィジェットのレイアウトを更新しました", + "%(senderName)s revoked the invitation for %(targetDisplayName)s to join the room.": "%(senderName)s は部屋 %(targetDisplayName)s への招待を取り消しました。", + "%(senderName)s declined the call.": "%(senderName)s は通話を拒否しました。", + "(an error occurred)": "(エラーが発生しました)", + "(their device couldn't start the camera / microphone)": "(彼らのデバイスはカメラ/マイクを使用できませんでした)", + "(connection failed)": "(接続に失敗しました)", + "%(senderName)s changed the addresses for this room.": "%(senderName)s がこの部屋のアドレスを変更しました。", + "%(senderName)s changed the main and alternative addresses for this room.": "%(senderName)s がこの部屋のメインアドレスと代替アドレスを変更しました。", + "%(senderName)s changed the alternative addresses for this room.": "%(senderName)s がこの部屋の代替アドレスを変更しました。", + "%(senderName)s removed the alternative addresses %(addresses)s for this room.|one": "%(senderName)s がこの部屋の代替アドレス %(addresses)s を削除しました。", + "%(senderName)s removed the alternative addresses %(addresses)s for this room.|other": "%(senderName)s がこの部屋の代替アドレス %(addresses)s を削除しました。", + "%(senderName)s added the alternative addresses %(addresses)s for this room.|one": "%(senderName)s がこの部屋の代替アドレス %(addresses)s を追加しました。", + "%(senderName)s added the alternative addresses %(addresses)s for this room.|other": "%(senderName)s がこの部屋の代替アドレス %(addresses)s を追加しました。", + "🎉 All servers are banned from participating! This room can no longer be used.": "🎉すべてのサーバーは参加を禁止されています! この部屋は使用できなくなりました。", + "%(senderDisplayName)s changed the server ACLs for this room.": "%(senderDisplayName)s がこの部屋のサーバーACLを変更しました。", + "%(senderDisplayName)s set the server ACLs for this room.": "%(senderDisplayName)s がこの部屋のサーバーACLを設定しました。", + "Converts the DM to a room": "DMを部屋に変換します", + "Converts the room to a DM": "部屋をDMに変換します", + "Takes the call in the current room off hold": "現在の部屋の通話を保留から外します", + "Places the call in the current room on hold": "保留中の現在の部屋に通話を発信します", + "Sends a message to the given user": "指定されたユーザーにメッセージを送ります", + "Opens chat with the given user": "指定されたユーザーとのチャットを開きます", + "Send a bug report with logs": "ログ付きのバグ報告を送る", + "Displays information about a user": "ユーザーの情報を表示します", + "The signing key you provided matches the signing key you received from %(userId)s's session %(deviceId)s. Session marked as verified.": "指定された署名キーは %(userId)s のセッション %(deviceId)s から受け取ったキーと一致します。セッションは検証済みです。", + "Unknown (user, session) pair:": "ユーザーとセッションのペアが不明です:", + "Verifies a user, session, and pubkey tuple": "ユーザー、セッション、およびpubkeyタプルを検証します", + "Please supply a widget URL or embed code": "ウィジェットのURLまたは埋め込みコードを入力してください", + "Could not find user in room": "部屋にユーザーが見つかりません", + "Command failed": "コマンドが失敗しました", + "Unrecognised room address:": "部屋のアドレスを認識できません:", + "Joins room with given address": "指定されたアドレスの部屋に参加します", + "Use an identity server to invite by email. Click continue to use the default identity server (%(defaultIdentityServerName)s) or manage in Settings.": "メールでの招待に identity サーバーを使います。デフォルトの identity サーバー (%(defaultIdentityServerName)s) を使う場合は「続ける」を押してください。または設定画面を開いて変更してください。", + "Failed to set topic": "トピックの設定に失敗しました", + "Double check that your server supports the room version chosen and try again.": "選択した部屋のバージョンをあなたのサーバーがサポートしているか何度も確認してから、もう一度試してください。", + "Sends a message as html, without interpreting it as markdown": "メッセージを(Markdownではなく)HTMLとして送信します", + "Prepends ( ͡° ͜ʖ ͡°) to a plain-text message": "プレーンテキストメッセージの前に ( ͡° ͜ʖ ͡°) を付けます", + "Prepends ┬──┬ ノ( ゜-゜ノ) to a plain-text message": "プレーンテキストメッセージの前に ┬──┬ ノ( ゜-゜ノ) を付けます", + "Prepends (╯°□°)╯︵ ┻━┻ to a plain-text message": "プレーンテキストメッセージの前に (╯°□°)╯︵ ┻━┻ を付けます", + "Effects": "効果", + "Setting up keys": "キーのセットアップ", + "Are you sure you want to cancel entering passphrase?": "パスフレーズの入力をキャンセルしてもよいですか?", + "Cancel entering passphrase?": "パスフレーズの入力をキャンセルしますか?", + "Custom (%(level)s)": "カスタム(%(level)s)", + "Use your account or create a new one to continue.": "作成ずみのアカウントを使うか、新しいアカウントを作成して続けます。", + "Sign In or Create Account": "サインインまたはアカウントの作成", + "Zimbabwe": "ジンバブエ", + "Zambia": "ザンビア", + "Yemen": "イエメン", + "Western Sahara": "西サハラ", + "Wallis & Futuna": "ウォリス・フツナ", + "Vietnam": "ベトナム", + "Venezuela": "ベネズエラ", + "Vatican City": "バチカン市", + "Vanuatu": "バヌアツ", + "Uzbekistan": "ウズベキスタン", + "Uruguay": "ウルグアイ", + "United Arab Emirates": "アラブ首長国連邦", + "Ukraine": "ウクライナ", + "Uganda": "ウガンダ", + "U.S. Virgin Islands": "アメリカ領バージン諸島", + "Tuvalu": "ツバル", + "Turks & Caicos Islands": "タークス・カイコス諸島", + "Turkmenistan": "トルクメニスタン", + "Turkey": "トルコ", + "Tunisia": "チュニジア", + "Trinidad & Tobago": "トリニダード・トバゴ", + "Tonga": "トンガ", + "Tokelau": "トケラウ", + "Togo": "トーゴ", + "Timor-Leste": "東ティモール", + "Thailand": "タイ", + "Tanzania": "タンザニア", + "Tajikistan": "タジキスタン", + "Taiwan": "台湾", + "São Tomé & Príncipe": "サントメ・プリンシペ", + "Syria": "シリア", + "Switzerland": "スイス", + "Sweden": "スウェーデン", + "Swaziland": "スワジランド", + "Svalbard & Jan Mayen": "スバールバル&ヤンマイエン", + "Suriname": "スリナム", + "Sudan": "スーダン", + "St. Vincent & Grenadines": "セントビンセント&グレナディーン諸島", + "St. Pierre & Miquelon": "サンピエール島ミクロン島", + "St. Martin": "セントマーチン", + "St. Lucia": "セントルシア", + "St. Kitts & Nevis": "セントクリストファー・ネイビス", + "St. Helena": "セントヘレナ", + "St. Barthélemy": "サン・バルテルミー島", + "Sri Lanka": "スリランカ", + "Spain": "スペイン", + "South Sudan": "南スーダン", + "South Korea": "韓国", + "South Georgia & South Sandwich Islands": "南ジョージア&南サンドイッチ諸島", + "Explore community rooms": "コミュニティルームを探索する", + "Open dial pad": "ダイヤルパッドを開く", + "Start a Conversation": "会話を始める", + "Show Widgets": "ウィジェットを表示する", + "Hide Widgets": "ウィジェットを隠す", + "No recently visited rooms": "最近訪れた部屋はありません", + "Recently visited rooms": "最近訪れた部屋", + "Room %(name)s": "部屋 %(name)s", + "Code block": "コードブロック", + "Strikethrough": "取り消し線", + "The authenticity of this encrypted message can't be guaranteed on this device.": "この暗号化メッセージの信頼性はこのデバイスでは保証できません。", + "Mod": "Mod", + "Edit message": "メッセージの編集", + "Someone is using an unknown session": "誰かが不明なセッションを使用しています", + "You have verified this user. This user has verified all of their sessions.": "このユーザーを検証しました。このユーザは全てのセッションを検証しました。", + "You have not verified this user.": "あなたはこのユーザーを検証していません。", + "This user has not verified all of their sessions.": "このユーザーはすべてのセッションを確認していません。", + "Phone Number": "電話番号", + "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains.": "+%(msisdn)s にテキストメッセージを送りました。メッセージに含まれた確認コードを入力してください。", + "Remove %(phone)s?": "%(phone)s を除去しますか?", + "We've sent you an email to verify your address. Please follow the instructions there and then click the button below.": "アドレスを確認するためメールを送りました。そこにある手順に従い、その後に下のボタンを押してください。", + "Remove %(email)s?": "%(email)s を除去しますか?", + "South Africa": "南アフリカ", + "Somalia": "ソマリア", + "Solomon Islands": "ソロモン諸島", + "Slovenia": "スロベニア", + "Slovakia": "スロバキア", + "Sint Maarten": "シントマールテン", + "Singapore": "シンガポール", + "Sierra Leone": "シエラレオネ", + "Seychelles": "セイシェル", + "Serbia": "セルビア", + "Senegal": "セネガル", + "Saudi Arabia": "サウジアラビア", + "San Marino": "サンマリノ", + "Samoa": "サモア", + "Réunion": "レユニオン", + "Rwanda": "ルワンダ", + "Russia": "ロシア", + "Romania": "ルーマニア", + "Qatar": "カタール", + "Puerto Rico": "プエルトリコ", + "Portugal": "ポルトガル", + "Poland": "ポーランド", + "Pitcairn Islands": "ピトケアン諸島", + "Philippines": "フィリピン", + "Peru": "ペルー", + "Paraguay": "パラグアイ", + "Papua New Guinea": "パプアニューギニア", + "Panama": "パナマ", + "Palestine": "パレスチナ", + "Palau": "パラオ", + "Pakistan": "パキスタン", + "Oman": "オマーン", + "Norway": "ノルウェー", + "Northern Mariana Islands": "北マリアナ諸島", + "North Korea": "北朝鮮", + "Norfolk Island": "ノーフォーク島", + "Niue": "ニウエ", + "Nigeria": "ナイジェリア", + "Niger": "ニジェール", + "Nicaragua": "ニカラグア", + "New Zealand": "ニュージーランド", + "New Caledonia": "ニューカレドニア", + "Netherlands": "オランダ", + "Nepal": "ネパール", + "Nauru": "ナウル", + "Namibia": "ナミビア", + "Myanmar": "ミャンマー", + "Mozambique": "モザンビーク", + "Morocco": "モロッコ", + "Montserrat": "モントセラト", + "Montenegro": "モンテネグロ", + "Mongolia": "モンゴル", + "Monaco": "モナコ", + "Moldova": "モルドバ", + "Micronesia": "ミクロネシア", + "Mexico": "メキシコ", + "Mayotte": "マヨット", + "Mauritius": "モーリシャス", + "Mauritania": "モーリタニア", + "Martinique": "マルティニーク", + "Marshall Islands": "マーシャル諸島", + "Malta": "マルタ", + "Mali": "マリ", + "Maldives": "モルディブ", + "Malaysia": "マレーシア", + "Malawi": "マラウイ", + "Madagascar": "マダガスカル", + "Macedonia": "マケドニア", + "Macau": "マカオ", + "Luxembourg": "ルクセンブルク", + "Lithuania": "リトアニア", + "Liechtenstein": "リヒテンシュタイン", + "Libya": "リビア", + "Liberia": "リベリア", + "Lesotho": "レソト", + "Lebanon": "レバノン", + "Latvia": "ラトビア", + "Laos": "ラオス", + "Kyrgyzstan": "キルギスタン", + "Kuwait": "クウェート", + "Kosovo": "コソボ", + "Kiribati": "キリバス", + "Kenya": "ケニア", + "Kazakhstan": "カザフスタン", + "Jordan": "ヨルダン", + "Jersey": "ジャージー", + "Japan": "日本", + "Jamaica": "ジャマイカ", + "Italy": "イタリア", + "Israel": "イスラエル", + "Isle of Man": "マン島", + "Ireland": "アイルランド", + "Iraq": "イラク", + "Iran": "イラン", + "Indonesia": "インドネシア", + "India": "インド", + "Iceland": "アイスランド", + "Hungary": "ハンガリー", + "Hong Kong": "香港", + "Honduras": "ホンジュラス", + "Heard & McDonald Islands": "ハード島とマクドナルド諸島", + "Haiti": "ハイチ", + "Guyana": "ガイアナ", + "Guinea-Bissau": "ギニアビサウ", + "Guinea": "ギニア", + "Guernsey": "ガーンジー", + "Guatemala": "グアテマラ", + "Guam": "グアム", + "Guadeloupe": "グアドループ", + "Grenada": "グレナダ", + "Greenland": "グリーンランド", + "Greece": "ギリシャ", + "Gibraltar": "ジブラルタル", + "Ghana": "ガーナ", + "Germany": "ドイツ", + "Georgia": "ジョージア", + "Gambia": "ガンビア", + "Gabon": "ガボン", + "French Southern Territories": "フランス領南方領土", + "French Polynesia": "フランス領ポリネシア", + "French Guiana": "フランス領ギアナ", + "France": "フランス", + "Finland": "フィンランド", + "Fiji": "フィジー", + "Faroe Islands": "フェロー諸島", + "Falkland Islands": "フォークランド諸島", + "Ethiopia": "エチオピア", + "Estonia": "エストニア", + "Eritrea": "エリトリア", + "Equatorial Guinea": "赤道ギニア", + "El Salvador": "エルサルバドル", + "Egypt": "エジプト", + "Ecuador": "エクアドル", + "Dominican Republic": "ドミニカ共和国", + "Dominica": "ドミニカ", + "Djibouti": "ジブチ", + "Denmark": "デンマーク", + "Côte d’Ivoire": "コートジボワール", + "Czech Republic": "チェコ共和国", + "Cyprus": "キプロス", + "Curaçao": "キュラソー", + "Cuba": "キューバ", + "Croatia": "クロアチア", + "Costa Rica": "コスタリカ", + "Cook Islands": "クック諸島", + "Congo - Kinshasa": "コンゴ-キンシャサ", + "Congo - Brazzaville": "コンゴ-ブラザビル", + "Comoros": "コモロ", + "Colombia": "コロンビア", + "Cocos (Keeling) Islands": "ココス(キーリング)諸島", + "Christmas Island": "クリスマス島", + "China": "中国", + "Chile": "チリ", + "Chad": "チャド", + "Central African Republic": "中央アフリカ共和国", + "Cayman Islands": "ケイマン諸島", + "Caribbean Netherlands": "カリブ海オランダ", + "Cape Verde": "カーボベルデ", + "Canada": "カナダ", + "Cameroon": "カメルーン", + "Cambodia": "カンボジア", + "Burundi": "ブルンジ", + "Burkina Faso": "ブルキナファソ", + "Bulgaria": "ブルガリア", + "Brunei": "ブルネイ", + "British Virgin Islands": "イギリス領ヴァージン諸島", + "British Indian Ocean Territory": "イギリス領インド洋地域", + "Brazil": "ブラジル", + "Bouvet Island": "ブーベ島", + "Botswana": "ボツワナ", + "Bosnia": "ボスニア", + "Bolivia": "ボリビア", + "Bhutan": "ブータン", + "Bermuda": "バミューダ", + "Benin": "ベナン", + "Belize": "ベリーズ", + "Belgium": "ベルギー", + "Belarus": "ベラルーシ", + "Barbados": "バルバドス", + "Bangladesh": "バングラデシュ", + "Bahrain": "バーレーン", + "Bahamas": "バハマ", + "Azerbaijan": "アゼルバイジャン", + "Austria": "オーストリア", + "Australia": "オーストラリア", + "Aruba": "アルバ", + "Armenia": "アルメニア", + "Argentina": "アルゼンチン", + "Antigua & Barbuda": "アンティグア&バーブーダ", + "Antarctica": "南極大陸", + "Anguilla": "アンギラ", + "Angola": "アンゴラ", + "Andorra": "アンドラ", + "American Samoa": "アメリカ領サモア", + "Algeria": "アルジェリア", + "Albania": "アルバニア", + "Åland Islands": "オーランド諸島", + "Afghanistan": "アフガニスタン", + "United States": "アメリカ", + "United Kingdom": "イギリス", + "%(name)s is requesting verification": "%(name)s は検証を要望しています", + "Your homeserver rejected your log in attempt. This could be due to things just taking too long. Please try again. If this continues, please contact your homeserver administrator.": "ホームサーバーがログインの試行を拒否しました。時間がかかりすぎたことが原因かもしれません。もう一度やり直してください。これが続く場合はホームサーバー管理者に連絡してください。", + "Your homeserver was unreachable and was not able to log you in. Please try again. If this continues, please contact your homeserver administrator.": "ホームサーバーにアクセスできませんでした。もう一度やり直してください。これが続く場合はホームサーバー管理者に連絡してください。", + "Try again": "もう一度試す", + "We asked the browser to remember which homeserver you use to let you sign in, but unfortunately your browser has forgotten it. Go to the sign in page and try again.": "残念ながらブラウザはサインインするホームサーバーを忘れてしまいました。 サインインページに移動して再試行してください。", + "We couldn't log you in": "ログインできませんでした", + "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "このアクションはデフォルトのidentity サーバー にアクセスしてメールアドレスまたは電話番号を検証する必要がありますが、サーバには利用規約がありません。", + "Room name or address": "部屋の名前またはアドレス", + "At this time it is not possible to reply with a file. Would you like to upload this file without replying?": "現時点ではファイルで返信することはできません。 返信せずにこのファイルをアップロードしますか?", + "This will end the conference for everyone. Continue?": "これは全員の会議を終了させます。続けますか?", + "End conference": "会議を終了する", + "You've reached the maximum number of simultaneous calls.": "同時通話数の上限に達しました。", + "Too Many Calls": "通話が多すぎます", + "No other application is using the webcam": "他のアプリがWebカメラを使用中ではないこと", + "Permission is granted to use the webcam": "Webカメラを使う権限が与えられていること", + "A microphone and webcam are plugged in and set up correctly": "マイクとWebカメラが接続されていて、正しく設定されていること", + "Verify this user by confirming the following emoji appear on their screen.": "このユーザを検証するため、両方の画面に絵文字が同じ順序で表示されていることを確認してください。", + "Verify this session by confirming the following number appears on its screen.": "このセッションを検証するため、同じ番号が両方の画面に表示されていることを確認してください。", + "Confirm the emoji below are displayed on both sessions, in the same order:": "以下の絵文字が両方のセッションで同じ順序で表示されていることをしてください:", + "Start": "開始", + "Compare a unique set of emoji if you don't have a camera on either device": "両方の端末でQRコードをキャプチャできない場合、絵文字の比較を選んでください", + "Compare unique emoji": "絵文字の並びを比較する", + "or": "または", + "Scan this unique code": "ユニークなコードをスキャン", + "Verify this session by completing one of the following:": "以下のどれか一つの方法で、このセッションを検証します。", + "Secure messages with this user are end-to-end encrypted and not able to be read by third parties.": "ユーザ間でエンドツーエンド暗号化されたメッセージです。第三者が解読することはできません。", + "Verified!": "検証されました!", + "The other party cancelled the verification.": "相手方が確認をキャンセルしました。", + "Incoming call": "着信", + "Incoming video call": "ビデオ通話の着信", + "Incoming voice call": "音声通話の着信", + "Unknown caller": "不明な発信者", + "Dial pad": "ダイヤルパッド", + "There was an error looking up the phone number": "電話番号を見つける際にエラーがありました", + "Unable to look up phone number": "電話番号が見つかりません", + "%(name)s on hold": "%(name)s が保留中", + "Return to call": "電話に戻る", + "Fill Screen": "全画面", + "Voice Call": "音声電話", + "Video Call": "ビデオ通話", + "%(peerName)s held the call": "%(peerName)s が電話をかけました", + "You held the call Resume": "再開の電話をかけました", + "You held the call Switch": "スイッチに電話をかけました", + "sends snowfall": "降雪を送る", + "Sends the given message with snowfall": "メッセージを降雪と共に送る", + "sends fireworks": "花火を送る", + "Sends the given message with fireworks": "メッセージを花火と共に送る", + "sends confetti": "紙吹雪を送る", + "Sends the given message with confetti": "メッセージを紙吹雪と共に送信します", + "This is your list of users/servers you have blocked - don't leave the room!": "あなたがブロックしたユーザー/サーバーのリストです。部屋から出ないでください!", + "My Ban List": "私の禁止リスト", + "Downloading logs": "ログのダウンロード", + "Uploading logs": "ログのアップロード", + "Show chat effects (animations when receiving e.g. confetti)": "チャット効果を表示する(紙吹雪などを受け取ったときのアニメーション)", + "IRC display name width": "IRC表示名の幅", + "How fast should messages be downloaded.": "メッセージをダウンロードする速度。", + "Enable message search in encrypted rooms": "暗号化された部屋でもメッセージ検索を有効にする", + "Show hidden events in timeline": "省略されたイベントをタイムラインに表示する", + "Use Command + Enter to send a message": "メッセージ送信に Command + Enter を使う", + "Use Command + F to search": "検索に Command + F を使う", + "Show line numbers in code blocks": "コードブロックに行番号を表示する", + "Expand code blocks by default": "デフォルトでコードブロックを展開表示する", + "Show stickers button": "ステッカーボタンを表示する", + "Show info about bridges in room settings": "部屋の設定にブリッジの情報を表示する", + "Enable advanced debugging for the room list": "ルーム一覧の高度なデバッグを有効にする", + "Offline encrypted messaging using dehydrated devices": "dehydrated デバイスを使用したオフライン暗号化メッセージング", + "Show message previews for reactions in all rooms": "すべての部屋でリアクションのメッセージプレビューを表示する", + "Show message previews for reactions in DMs": "DM中のリアクションにメッセージプレビューを表示する", + "Support adding custom themes": "カスタムテーマの追加に対応する", + "Try out new ways to ignore people (experimental)": "人々を無視する新しい方法を試す (実験的)", + "Multiple integration managers": "複数の integration マネージャー", + "Group & filter rooms by custom tags (refresh to apply changes)": "カスタムタグを使って部屋をグループまたはフィルタします(ページのリロードが必要)", + "New spinner design": "新しいスピナーのデザイン", + "Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Communities v2 prototypes. 互換性のあるホームサーバーが必要です。 非常に実験的。注意して使用してください。", + "Render LaTeX maths in messages": "メッセージ中の LaTeX 数式を描画する", + "Change notification settings": "通知設定を変更する", + "%(senderName)s: %(stickerName)s": "%(senderName)s: %(stickerName)s", + "%(senderName)s: %(reaction)s": "%(senderName)s: %(reaction)s", + "%(senderName)s: %(message)s": "%(senderName)s: %(message)s", + "* %(senderName)s %(emote)s": "* %(senderName)s %(emote)s", + "%(senderName)s is calling": "%(senderName)s が呼び出し中", + "Waiting for answer": "応答を待っています", + "%(senderName)s started a call": "%(senderName)s が通話を開始しました", + "You started a call": "あなたは通話を開始しました", + "Call ended": "通話が終了しました", + "%(senderName)s ended the call": "%(senderName)s が通話を終了しました", + "You ended the call": "あなたは通話を終了しました", + "Call in progress": "通話中", + "%(senderName)s joined the call": "%(senderName)s が通話に参加しました", + "You joined the call": "通話に参加しました", + "The person who invited you already left the room, or their server is offline.": "あなたを招待した人はすでに部屋を出たか、彼らのサーバーがオフライン状態です。", + "The person who invited you already left the room.": "あなたを招待した人はすでに部屋を出ました。", + "There was an error joining the room": "部屋に参加する際にエラーがありました", + "Guest": "ゲスト", + "Verify the new login accessing your account: %(name)s": "あなたのアカウントへの新しいログインを確認します: %(name)s", + "New login. Was this you?": "新しいログインがありました。これはあなたですか?", + "Safeguard against losing access to encrypted messages & data": "暗号化されたメッセージとデータへのアクセスを失うことから保護します", + "Ok": "OK", + "Contact your server admin.": "サーバ管理者に問い合わせてください。", + "Your homeserver has exceeded one of its resource limits.": "ホームサーバーはリソースの上限に達しました。", + "Your homeserver has exceeded its user limit.": "あなたのホームサーバーはユーザー数の上限に達しました。", + "Use app": "アプリを使う", + "Element Web is experimental on mobile. For a better experience and the latest features, use our free native app.": "Element Webはモバイル端末ではまだ試験的です。より良い体験と最新の機能を得るには、無料のネイティブアプリを使用してください。", + "Use app for a better experience": "より良い体験のためにアプリを使用する", + "Enable": "有効", + "Enable desktop notifications": "デスクトップ通知を有効にする", + "Don't miss a reply": "返信をお見逃しなく", + "Verify all your sessions to ensure your account & messages are safe": "すべてのセッションを確認して、アカウントとメッセージが安全であることを確認します", + "Review where you’re logged in": "どこからログインしたか確認する", + "No": "いいえ", + "Yes": "はい", + "Send anonymous usage data which helps us improve %(brand)s. This will use a cookie.": "%(brand)s の向上に役立つ 匿名の使用状況データ を送信します。 これは cookie を使用します。", + "Help us improve %(brand)s": "%(brand)s の改善にご協力ください", + "Short keyboard patterns are easy to guess": "短いキーボードパターンは簡単に推測されます", + "Straight rows of keys are easy to guess": "キーの配置順序を辿ると簡単に推測されます", + "Common names and surnames are easy to guess": "名前と名字は簡単に推測されます", + "Names and surnames by themselves are easy to guess": "名前や名字は簡単に推測されます", + "Call failed because webcam or microphone could not be accessed. Check that:": "Webカメラやマイクを利用できず通話に失敗しました。確認してください:", + "Unable to access webcam / microphone": "Webカメラとマイクを利用できません", + "Call failed because microphone could not be accessed. Check that a microphone is plugged in and set up correctly.": "マイクを利用できなかったので通話に失敗しました。マイクが接続されて正しく設定されているか確認してください。", + "Unable to access microphone": "マイクを利用できません", + "Alternatively, you can try to use the public server at turn.matrix.org, but this will not be as reliable, and it will share your IP address with that server. You can also manage this in Settings.": "または公開サーバー turn.matrix.org を使用することもできますが、信頼性は低く、また公開サーバにIPアドレスが漏洩します。これはアプリ設定でも変更できます。", + "Please ask the administrator of your homeserver (%(homeserverDomain)s) to configure a TURN server in order for calls to work reliably.": "通話が機能するよう、ホームサーバー(%(homeserverDomain)s)の管理者にTURNサーバーの設定を尋ねてください。", + "The call was answered on another device.": "通話は他の端末で応答されました。", + "Answered Elsewhere": "他端末で応答しました", + "The call could not be established": "通話を確立できませんでした", + "The other party declined the call.": "相手方は通話を拒否しました。", + "Call Declined": "通話は拒否されました", + "Whether you're using %(brand)s as an installed Progressive Web App": "インストールされた Progressive Web App として %(brand)s を使用しているか", + "Whether you're using %(brand)s on a device where touch is the primary input mechanism": "主な入力方法がタッチであるデバイスで %(brand)s を使っているか", + "Click the button below to confirm adding this phone number.": "下のボタンをクリックして電話番号の追加を確認します。", + "Confirm adding phone number": "電話番号の追加を確認する", + "Confirm adding this phone number by using Single Sign On to prove your identity.": "シングルサインオンを使用して本人確認を行い、電話番号の追加を承認してください。", + "Click the button below to confirm adding this email address.": "下のボタンを押してこのメールアドレスを確認します。" } From bfa47ba447c3fc5800b6e78349d57d3a9c305003 Mon Sep 17 00:00:00 2001 From: Thibault Martin Date: Tue, 9 Mar 2021 12:24:53 +0000 Subject: [PATCH 86/91] Translated using Weblate (French) Currently translated at 100.0% (2780 of 2780 strings) Translation: Element Web/matrix-react-sdk Translate-URL: https://translate.element.io/projects/element-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 898 +++++++++++++++++++-------------------- 1 file changed, 449 insertions(+), 449 deletions(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index e170ec1414..dc6a70bc24 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -7,10 +7,10 @@ "Error": "Erreur", "Existing Call": "Appel en cours", "Export E2E room keys": "Exporter les clés de chiffrement de salon", - "Failed to ban user": "Échec du bannissement de l'utilisateur", - "Failed to change password. Is your password correct?": "Échec du changement de mot de passe. Votre mot de passe est-il correct ?", + "Failed to ban user": "Échec du bannissement de l’utilisateur", + "Failed to change password. Is your password correct?": "Échec du changement de mot de passe. Votre mot de passe est-il correct ?", "Failed to change power level": "Échec du changement de rang", - "Failed to forget room %(errCode)s": "Échec de l'oubli du salon %(errCode)s", + "Failed to forget room %(errCode)s": "Échec de l’oubli du salon %(errCode)s", "Remove": "Supprimer", "Favourite": "Favoris", "Notifications": "Notifications", @@ -20,13 +20,13 @@ "Admin": "Administrateur", "Advanced": "Avancé", "%(items)s and %(lastItem)s": "%(items)s et %(lastItem)s", - "and %(count)s others...|other": "et %(count)s autres...", - "and %(count)s others...|one": "et un autre...", + "and %(count)s others...|other": "et %(count)s autres…", + "and %(count)s others...|one": "et un autre…", "A new password must be entered.": "Un nouveau mot de passe doit être saisi.", "Anyone who knows the room's link, apart from guests": "Tous ceux qui connaissent le lien du salon, à part les visiteurs", "Anyone who knows the room's link, including guests": "Tous ceux qui connaissent le lien du salon, y compris les visiteurs", - "Are you sure?": "Êtes-vous sûr(e) ?", - "Are you sure you want to reject the invitation?": "Voulez-vous vraiment rejeter l'invitation ?", + "Are you sure?": "Êtes-vous sûr ?", + "Are you sure you want to reject the invitation?": "Voulez-vous vraiment rejeter l’invitation ?", "Attachment": "Pièce jointe", "Autoplay GIFs and videos": "Jouer automatiquement les GIFs et les vidéos", "%(senderName)s banned %(targetName)s.": "%(senderName)s a banni %(targetName)s.", @@ -34,13 +34,13 @@ "Banned users": "Utilisateurs bannis", "Bans user with given id": "Bannit l’utilisateur à partir de son identifiant", "Call Timeout": "L’appel a dépassé le délai d'attente maximal", - "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Impossible de se connecter au serveur d'accueil en HTTP si l'URL dans la barre de votre explorateur est en HTTPS. Utilisez HTTPS ou activez le support des scripts non-vérifiés.", + "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Impossible de se connecter au serveur d'accueil en HTTP si l’URL dans la barre de votre explorateur est en HTTPS. Utilisez HTTPS ou activez la prise en charge des scripts non-vérifiés.", "Change Password": "Changer le mot de passe", "%(senderName)s changed their profile picture.": "%(senderName)s a changé son image de profil.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s a changé le rang de %(powerLevelDiffText)s.", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s a changé le nom du salon en %(roomName)s.", "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s a changé le sujet du salon en « %(topic)s ».", - "Changes your display nickname": "Change votre nom affiché", + "Changes your display nickname": "Change votre nom d’affichage", "Click here to fix": "Cliquer ici pour réparer", "Click to mute audio": "Cliquer pour couper le son", "Click to mute video": "Cliquer ici pour couper la vidéo", @@ -59,24 +59,24 @@ "Decrypt %(text)s": "Déchiffrer %(text)s", "Deops user with given id": "Retire le rang d’opérateur d’un utilisateur à partir de son identifiant", "Failed to join room": "Échec de l’inscription au salon", - "Failed to kick": "Échec de l'expulsion", + "Failed to kick": "Échec de l’expulsion", "Failed to leave room": "Échec du départ du salon", - "Failed to load timeline position": "Échec du chargement de la position dans l'historique", - "Failed to mute user": "Échec de la mise en sourdine de l'utilisateur", - "Failed to reject invite": "Échec du rejet de l'invitation", - "Failed to reject invitation": "Échec du rejet de l'invitation", + "Failed to load timeline position": "Échec du chargement de la position dans le fil de discussion", + "Failed to mute user": "Échec de la mise en sourdine de l’utilisateur", + "Failed to reject invite": "Échec du rejet de l’invitation", + "Failed to reject invitation": "Échec du rejet de l’invitation", "Failed to send email": "Échec de l’envoi de l’e-mail", "Failed to send request.": "Échec de l’envoi de la requête.", - "Failed to set display name": "Échec de l'enregistrement du nom affiché", + "Failed to set display name": "Échec de l’enregistrement du nom d’affichage", "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s a accepté l’invitation de %(displayName)s.", - "Access Token:": "Jeton d’accès :", - "Always show message timestamps": "Toujours afficher l'heure des messages", + "Access Token:": "Jeton d’accès :", + "Always show message timestamps": "Toujours afficher l’heure des messages", "Authentication": "Authentification", "%(senderName)s answered the call.": "%(senderName)s a répondu à l’appel.", "An error has occurred.": "Une erreur est survenue.", "Email": "E-mail", "Failed to unban": "Échec de la révocation du bannissement", - "Failed to verify email address: make sure you clicked the link in the email": "La vérification de l’adresse e-mail a échoué : vérifiez que vous avez bien cliqué sur le lien dans l’e-mail", + "Failed to verify email address: make sure you clicked the link in the email": "La vérification de l’adresse e-mail a échoué : vérifiez que vous avez bien cliqué sur le lien dans l’e-mail", "Failure to create room": "Échec de création du salon", "Favourites": "Favoris", "Fill screen": "Plein écran", @@ -86,8 +86,8 @@ "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s de %(fromPowerLevel)s à %(toPowerLevel)s", "Hangup": "Raccrocher", "Historical": "Historique", - "Homeserver is": "Le serveur d'accueil est", - "Identity Server is": "Le serveur d'identité est", + "Homeserver is": "Le serveur d’accueil est", + "Identity Server is": "Le serveur d’identité est", "I have verified my email address": "J’ai vérifié mon adresse e-mail", "Import E2E room keys": "Importer les clés de chiffrement de bout en bout", "Incorrect verification code": "Code de vérification incorrect", @@ -121,7 +121,7 @@ "New passwords must match each other.": "Les nouveaux mots de passe doivent être identiques.", "not specified": "non spécifié", "(not supported by this browser)": "(non pris en charge par ce navigateur)", - "": "", + "": "", "No more results": "Fin des résultats", "No results": "Pas de résultat", "unknown error code": "code d’erreur inconnu", @@ -135,41 +135,41 @@ "Default": "Par défaut", "Email address": "Adresse e-mail", "Error decrypting attachment": "Erreur lors du déchiffrement de la pièce jointe", - "Guests cannot join this room even if explicitly invited.": "Les visiteurs ne peuvent pas rejoindre ce salon, même s'ils ont été explicitement invités.", + "Guests cannot join this room even if explicitly invited.": "Les visiteurs ne peuvent pas rejoindre ce salon, même s’ils ont été explicitement invités.", "Invalid file%(extra)s": "Fichier %(extra)s non valide", "Mute": "Mettre en sourdine", "No users have specific privileges in this room": "Aucun utilisateur n’a de privilège spécifique dans ce salon", - "olm version:": "version de olm :", - "Please check your email and click on the link it contains. Once this is done, click continue.": "Veuillez vérifier vos e-mails et cliquer sur le lien que vous avez reçu. Puis cliquez sur continuer.", + "olm version:": "version de olm :", + "Please check your email and click on the link it contains. Once this is done, click continue.": "Veuillez consulter vos e-mails et cliquer sur le lien que vous avez reçu. Puis cliquez sur continuer.", "Power level must be positive integer.": "Le rang doit être un entier positif.", "Privileged Users": "Utilisateurs privilégiés", "Profile": "Profil", "Reason": "Raison", "%(targetName)s rejected the invitation.": "%(targetName)s a rejeté l’invitation.", - "Reject invitation": "Rejeter l'invitation", - "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s a supprimé son nom affiché (%(oldDisplayName)s).", + "Reject invitation": "Rejeter l’invitation", + "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s a supprimé son nom d’affichage (%(oldDisplayName)s).", "%(senderName)s removed their profile picture.": "%(senderName)s a supprimé son image de profil.", "%(senderName)s requested a VoIP conference.": "%(senderName)s a demandé une téléconférence audio.", "Return to login screen": "Retourner à l’écran de connexion", "%(brand)s does not have permission to send you notifications - please check your browser settings": "%(brand)s n’a pas l’autorisation de vous envoyer des notifications - merci de vérifier les paramètres de votre navigateur", "%(brand)s was not given permission to send notifications - please try again": "%(brand)s n’a pas reçu l’autorisation de vous envoyer des notifications - veuillez réessayer", - "%(brand)s version:": "Version de %(brand)s :", + "%(brand)s version:": "Version de %(brand)s :", "Room %(roomId)s not visible": "Le salon %(roomId)s n’est pas visible", "Room Colour": "Couleur du salon", "Rooms": "Salons", "Search": "Rechercher", "Search failed": "Échec de la recherche", "Searches DuckDuckGo for results": "Recherche des résultats dans DuckDuckGo", - "Send Reset Email": "Envoyer l'e-mail de réinitialisation", + "Send Reset Email": "Envoyer l’e-mail de réinitialisation", "%(senderDisplayName)s sent an image.": "%(senderDisplayName)s a envoyé une image.", "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s a invité %(targetDisplayName)s à rejoindre le salon.", "Server error": "Erreur du serveur", "Server may be unavailable, overloaded, or search timed out :(": "Le serveur semble être inaccessible, surchargé ou la recherche a expiré :(", "Server may be unavailable, overloaded, or you hit a bug.": "Le serveur semble être indisponible, surchargé ou vous êtes tombé sur un bug.", - "Server unavailable, overloaded, or something else went wrong.": "Le serveur semble être inaccessible, surchargé ou quelque chose s'est mal passé.", + "Server unavailable, overloaded, or something else went wrong.": "Le serveur semble être inaccessible, surchargé ou quelque chose s’est mal passé.", "Session ID": "Identifiant de session", "%(senderName)s set a profile picture.": "%(senderName)s a défini une image de profil.", - "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s a défini son nom affiché comme %(displayName)s.", + "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s a défini son nom d’affichage comme %(displayName)s.", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Afficher l’heure au format am/pm (par ex. 2:30pm)", "Signed Out": "Déconnecté", "Sign in": "Se connecter", @@ -182,15 +182,15 @@ "This email address was not found": "Cette adresse e-mail n’a pas été trouvée", "The email address linked to your account must be entered.": "L’adresse e-mail liée à votre compte doit être renseignée.", "The remote side failed to pick up": "Le correspondant n’a pas décroché", - "This room has no local addresses": "Ce salon n'a pas d'adresse locale", + "This room has no local addresses": "Ce salon n’a pas d’adresse locale", "This room is not recognised.": "Ce salon n’est pas reconnu.", "This doesn't appear to be a valid email address": "Cette adresse e-mail ne semble pas valide", "This phone number is already in use": "Ce numéro de téléphone est déjà utilisé", "This room is not accessible by remote Matrix servers": "Ce salon n’est pas accessible par les serveurs Matrix distants", "To use it, just wait for autocomplete results to load and tab through them.": "Pour l’utiliser, attendez simplement que les résultats de l’auto-complétion s’affichent et défilez avec la touche Tab.", - "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Un instant donné de la chronologie n’a pu être chargé car vous n’avez pas la permission de le visualiser.", - "Tried to load a specific point in this room's timeline, but was unable to find it.": "Un instant donné de la chronologie n’a pu être chargé car il n’a pas pu être trouvé.", - "Unable to add email address": "Impossible d'ajouter l'adresse e-mail", + "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Un instant donné du fil de discussion n’a pu être chargé car vous n’avez pas la permission de le visualiser.", + "Tried to load a specific point in this room's timeline, but was unable to find it.": "Un instant donné du fil de discussion n’a pu être chargé car il n’a pas pu être trouvé.", + "Unable to add email address": "Impossible d'ajouter l’adresse e-mail", "Unable to remove contact information": "Impossible de supprimer les informations du contact", "Unable to verify email address.": "Impossible de vérifier l’adresse e-mail.", "Unban": "Révoquer le bannissement", @@ -198,31 +198,31 @@ "Unable to capture screen": "Impossible de faire une capture d’écran", "Unable to enable Notifications": "Impossible d’activer les notifications", "Unmute": "Activer le son", - "Upload avatar": "Télécharger une photo de profil", + "Upload avatar": "Envoyer un avatar", "Upload Failed": "Échec de l’envoi", "Upload file": "Envoyer un fichier", "Usage": "Utilisation", "Users": "Utilisateurs", "Verification Pending": "Vérification en attente", "Video call": "Appel vidéo", - "Voice call": "Appel vocal", + "Voice call": "Appel audio", "VoIP conference finished.": "Téléconférence VoIP terminée.", "VoIP conference started.": "Téléconférence VoIP démarrée.", "VoIP is unsupported": "Voix sur IP non prise en charge", - "Warning!": "Attention !", - "Who can access this room?": "Qui peut accéder au salon ?", - "Who can read history?": "Qui peut lire l'historique ?", - "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s a annulé l’invitation de %(targetName)s.", + "Warning!": "Attention !", + "Who can access this room?": "Qui peut accéder au salon ?", + "Who can read history?": "Qui peut lire l’historique ?", + "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s a révoqué l’invitation de %(targetName)s.", "You are already in a call.": "Vous avez déjà un appel en cours.", "You cannot place a call with yourself.": "Vous ne pouvez pas passer d’appel avec vous-même.", - "You cannot place VoIP calls in this browser.": "Vous ne pouvez pas passer d’appel en Voix sur IP dans ce navigateur.", + "You cannot place VoIP calls in this browser.": "Vous ne pouvez pas passer d’appel en VoIP dans ce navigateur.", "You do not have permission to post to this room": "Vous n’avez pas la permission de poster dans ce salon", "You have no visible notifications": "Vous n'avez pas de notification visible", "You need to be able to invite users to do that.": "Vous devez avoir l’autorisation d’inviter des utilisateurs pour faire ceci.", "You need to be logged in.": "Vous devez être identifié.", "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Votre adresse e-mail ne semble pas être associée à un identifiant Matrix sur ce serveur d’accueil.", - "You seem to be in a call, are you sure you want to quit?": "Vous semblez avoir un appel en cours, voulez-vous vraiment partir ?", - "You seem to be uploading files, are you sure you want to quit?": "Vous semblez être en train d'envoyer des fichiers, voulez-vous vraiment partir ?", + "You seem to be in a call, are you sure you want to quit?": "Vous semblez avoir un appel en cours, voulez-vous vraiment partir ?", + "You seem to be uploading files, are you sure you want to quit?": "Vous semblez être en train d’envoyer des fichiers, voulez-vous vraiment partir ?", "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Vous ne pourrez pas annuler cette modification car vous promouvez l’utilisateur au même rang que le vôtre.", "Sun": "Dim", "Mon": "Lun", @@ -252,7 +252,7 @@ "An error occurred: %(error_string)s": "Une erreur est survenue : %(error_string)s", "There are no visible files in this room": "Il n'y a pas de fichier visible dans ce salon", "Room": "Salon", - "Connectivity to the server has been lost.": "La connectivité au serveur a été perdue.", + "Connectivity to the server has been lost.": "La connexion au serveur a été perdue.", "Sent messages will be stored until your connection has returned.": "Les messages envoyés seront stockés jusqu’à ce que votre connexion revienne.", "Cancel": "Annuler", "Active call": "Appel en cours", @@ -260,7 +260,7 @@ "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s a supprimé le nom du salon.", "Analytics": "Collecte de données", "%(brand)s collects anonymous analytics to allow us to improve the application.": "%(brand)s collecte des données anonymes qui nous permettent d’améliorer l’application.", - "Passphrases must match": "Les phrases de passe doivent être identiques", + "Passphrases must match": "Les phrases secrètes doivent être identiques", "Passphrase must not be empty": "Le mot de passe ne peut pas être vide", "Export room keys": "Exporter les clés de salon", "Enter passphrase": "Saisir le mot de passe", @@ -276,7 +276,7 @@ "Failed to invite": "Échec de l’invitation", "Failed to invite the following users to the %(roomName)s room:": "Échec de l’invitation des utilisateurs suivants dans le salon %(roomName)s :", "Confirm Removal": "Confirmer la suppression", - "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Voulez-vous vraiment supprimer cet événement ? Notez que si vous supprimez le changement du nom ou du sujet d’un salon, il est possible que ce changement soit annulé.", + "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Voulez-vous vraiment supprimer cet événement ? Notez que si vous supprimez le changement du nom ou du sujet d’un salon, il est possible que ce changement soit annulé.", "Unknown error": "Erreur inconnue", "Incorrect password": "Mot de passe incorrect", "Unable to restore session": "Impossible de restaurer la session", @@ -288,7 +288,7 @@ "Dismiss": "Ignorer", "Please check your email to continue registration.": "Merci de vérifier votre e-mail afin de continuer votre inscription.", "Token incorrect": "Jeton incorrect", - "Please enter the code it contains:": "Merci de saisir le code qu'il contient :", + "Please enter the code it contains:": "Merci de saisir le code qu’il contient :", "powered by Matrix": "propulsé par Matrix", "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Si vous ne renseignez pas d’adresse e-mail, vous ne pourrez pas réinitialiser votre mot de passe. En êtes vous sûr(e) ?", "Error decrypting audio": "Erreur lors du déchiffrement de l’audio", @@ -296,7 +296,7 @@ "Error decrypting video": "Erreur lors du déchiffrement de la vidéo", "Add an Integration": "Ajouter une intégration", "URL Previews": "Aperçus des liens", - "Drop file here to upload": "Déposer le fichier ici pour l'envoyer", + "Drop file here to upload": "Glisser le fichier ici pour l’envoyer", " (unsupported)": " (pas pris en charge)", "Ongoing conference call%(supportedText)s.": "Téléconférence en cours%(supportedText)s.", "Online": "En ligne", @@ -305,7 +305,7 @@ "Idle": "Inactif", "Jump to first unread message.": "Aller au premier message non lu.", "Options": "Options", - "You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "Vous êtes sur le point d’accéder à un site tiers afin de pouvoir vous identifier pour utiliser %(integrationsUrl)s. Voulez-vous continuer ?", + "You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "Vous êtes sur le point d’accéder à un site tiers afin de pouvoir vous identifier pour utiliser %(integrationsUrl)s. Voulez-vous continuer ?", "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s a changé l’avatar du salon en ", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s a supprimé l'avatar du salon.", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s a changé l’avatar de %(roomName)s", @@ -315,17 +315,17 @@ "Results from DuckDuckGo": "Résultats de DuckDuckGo", "Verified key": "Clé vérifiée", "No Microphones detected": "Aucun micro détecté", - "No Webcams detected": "Aucune webcam détectée", + "No Webcams detected": "Aucune caméra détectée", "No media permissions": "Pas de permission pour les médias", - "You may need to manually permit %(brand)s to access your microphone/webcam": "Il est possible que vous deviez manuellement autoriser %(brand)s à accéder à votre micro/webcam", + "You may need to manually permit %(brand)s to access your microphone/webcam": "Il est possible que vous deviez manuellement autoriser %(brand)s à accéder à votre micro/caméra", "Default Device": "Appareil par défaut", "Microphone": "Micro", "Camera": "Caméra", "Add a topic": "Ajouter un sujet", - "Anyone": "N'importe qui", - "Are you sure you want to leave the room '%(roomName)s'?": "Voulez-vous vraiment quitter le salon \"%(roomName)s\" ?", + "Anyone": "N’importe qui", + "Are you sure you want to leave the room '%(roomName)s'?": "Voulez-vous vraiment quitter le salon « %(roomName)s » ?", "Custom level": "Rang personnalisé", - "Register": "S'inscrire", + "Register": "S’inscrire", "Save": "Enregistrer", "You have disabled URL previews by default.": "Vous avez désactivé les aperçus d’URL par défaut.", "You have enabled URL previews by default.": "Vous avez activé les aperçus d’URL par défaut.", @@ -339,11 +339,11 @@ "You must register to use this functionality": "Vous devez vous inscrire pour utiliser cette fonctionnalité", "Create new room": "Créer un nouveau salon", "Room directory": "Répertoire des salons", - "Start chat": "Commencer une discussion", + "Start chat": "Commencer un conversation privée", "New Password": "Nouveau mot de passe", "Username available": "Nom d'utilisateur disponible", "Username not available": "Nom d'utilisateur indisponible", - "Something went wrong!": "Quelque chose s’est mal passé !", + "Something went wrong!": "Quelque chose s’est mal déroulé !", "This will be your account name on the homeserver, or you can pick a different server.": "Cela sera le nom de votre compte sur le serveur d'accueil , ou vous pouvez sélectionner un autre serveur.", "If you already have a Matrix account you can log in instead.": "Si vous avez déjà un compte Matrix vous pouvez vous connecter à la place.", "Accept": "Accepter", @@ -352,18 +352,18 @@ "Close": "Fermer", "Custom": "Personnaliser", "Decline": "Refuser", - "Drop File Here": "Déposer le fichier Ici", - "Failed to upload profile picture!": "Échec de l'envoi de l'image de profil !", + "Drop File Here": "Glisser le fichier ici", + "Failed to upload profile picture!": "Échec de l’envoi de l’image de profil !", "Incoming call from %(name)s": "Appel entrant de %(name)s", "Incoming video call from %(name)s": "Appel vidéo entrant de %(name)s", "Incoming voice call from %(name)s": "Appel vocal entrant de %(name)s", - "No display name": "Pas de nom affiché", + "No display name": "Pas de nom d’affichage", "Private Chat": "Discussion privée", "Public Chat": "Discussion publique", - "%(roomName)s does not exist.": "%(roomName)s n'existe pas.", - "%(roomName)s is not accessible at this time.": "%(roomName)s n'est pas accessible pour le moment.", + "%(roomName)s does not exist.": "%(roomName)s n’existe pas.", + "%(roomName)s is not accessible at this time.": "%(roomName)s n’est pas joignable pour le moment.", "Seen by %(userName)s at %(dateTime)s": "Vu par %(userName)s à %(dateTime)s", - "Start authentication": "Commencer une authentification", + "Start authentication": "Commencer l’authentification", "This room": "Ce salon", "unknown caller": "appelant inconnu", "Unnamed Room": "Salon anonyme", @@ -371,17 +371,17 @@ "(~%(count)s results)|one": "(~%(count)s résultat)", "(~%(count)s results)|other": "(~%(count)s résultats)", "Home": "Accueil", - "Upload new:": "Envoyer un nouveau :", + "Upload new:": "Envoyer un nouveau :", "Join as voice or video.": "Rejoindre en audio ou en vidéo.", "Last seen": "Vu pour la dernière fois", "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (rang %(powerLevelNumber)s)", "(could not connect media)": "(impossible de se connecter au média)", "(no answer)": "(pas de réponse)", "(unknown failure: %(reason)s)": "(erreur inconnue : %(reason)s)", - "Your browser does not support the required cryptography extensions": "Votre navigateur ne supporte pas les extensions cryptographiques nécessaires", + "Your browser does not support the required cryptography extensions": "Votre navigateur ne prend pas en charge les extensions cryptographiques nécessaires", "Not a valid %(brand)s keyfile": "Fichier de clé %(brand)s non valide", - "Authentication check failed: incorrect password?": "Erreur d’authentification : mot de passe incorrect ?", - "Do you want to set an email address?": "Souhaitez-vous configurer une adresse e-mail ?", + "Authentication check failed: incorrect password?": "Erreur d’authentification : mot de passe incorrect ?", + "Do you want to set an email address?": "Souhaitez-vous configurer une adresse e-mail ?", "This will allow you to reset your password and receive notifications.": "Ceci vous permettra de réinitialiser votre mot de passe et de recevoir des notifications.", "Skip": "Passer", "Check for update": "Rechercher une mise à jour", @@ -397,13 +397,13 @@ "You do not have permission to do that in this room.": "Vous n’avez pas l’autorisation d’effectuer cette action dans ce salon.", "Example": "Exemple", "Create": "Créer", - "Featured Rooms:": "Salons mis en avant :", - "Featured Users:": "Utilisateurs mis en avant :", + "Featured Rooms:": "Salons mis en avant :", + "Featured Users:": "Utilisateurs mis en avant :", "Automatically replace plain text Emoji": "Remplacer automatiquement le texte par des émojis", - "Failed to upload image": "Impossible d'envoyer l'image", + "Failed to upload image": "Impossible d’envoyer l’image", "%(widgetName)s widget added by %(senderName)s": "Widget %(widgetName)s ajouté par %(senderName)s", "%(widgetName)s widget removed by %(senderName)s": "Widget %(widgetName)s supprimé par %(senderName)s", - "Publish this room to the public in %(domain)s's room directory?": "Publier ce salon dans le répertoire de salons public de %(domain)s ?", + "Publish this room to the public in %(domain)s's room directory?": "Publier ce salon dans le répertoire de salons public de %(domain)s ?", "Cannot add any more widgets": "Impossible d'ajouter plus de widgets", "The maximum permitted number of widgets have already been added to this room.": "Le nombre maximum de widgets autorisés a déjà été atteint pour ce salon.", "AM": "AM", @@ -432,26 +432,26 @@ "Unignore": "Ne plus ignorer", "Ignore": "Ignorer", "Invite": "Inviter", - "Admin Tools": "Outils d'administration", + "Admin Tools": "Outils d’administration", "Unpin Message": "Dépingler le message", "Jump to message": "Aller au message", "No pinned messages.": "Aucun message épinglé.", - "Loading...": "Chargement...", + "Loading...": "Chargement…", "Pinned Messages": "Messages épinglés", "Unknown": "Inconnu", "Unnamed room": "Salon sans nom", "No rooms to show": "Aucun salon à afficher", "Banned by %(displayName)s": "Banni par %(displayName)s", "%(senderName)s changed the pinned messages for the room.": "%(senderName)s a changé les messages épinglés du salon.", - "Jump to read receipt": "Aller à l'accusé de lecture", + "Jump to read receipt": "Aller à l’accusé de lecture", "World readable": "Lisible publiquement", "Guests can join": "Accessible aux visiteurs", "Invalid community ID": "Identifiant de communauté non valide", - "'%(groupId)s' is not a valid community ID": "\"%(groupId)s\" n'est pas un identifiant de communauté valide", + "'%(groupId)s' is not a valid community ID": "« %(groupId)s » n’est pas un identifiant de communauté valide", "%(senderName)s sent an image": "%(senderName)s a envoyé une image", "%(senderName)s sent a video": "%(senderName)s a envoyé une vidéo", "%(senderName)s uploaded a file": "%(senderName)s a transféré un fichier", - "Disinvite this user?": "Désinviter l'utilisateur ?", + "Disinvite this user?": "Désinviter l’utilisateur ?", "Kick this user?": "Expulser cet utilisateur ?", "Unban this user?": "Révoquer le bannissement de cet utilisateur ?", "Ban this user?": "Bannir cet utilisateur ?", @@ -464,13 +464,13 @@ "Remove from community": "Supprimer de la communauté", "Disinvite this user from community?": "Désinviter cet utilisateur de la communauté ?", "Remove this user from community?": "Supprimer cet utilisateur de la communauté ?", - "Failed to withdraw invitation": "Échec de l'annulation de l'invitation", - "Failed to remove user from community": "Échec de la suppression de l'utilisateur de la communauté", + "Failed to withdraw invitation": "Échec de l’annulation de l’invitation", + "Failed to remove user from community": "Échec de la suppression de l’utilisateur de la communauté", "Filter community members": "Filtrer les membres de la communauté", "Filter community rooms": "Filtrer les salons de la communauté", "Failed to remove room from community": "Échec de la suppression du salon de la communauté", - "Failed to remove '%(roomName)s' from %(groupId)s": "Échec de la suppression de \"%(roomName)s\" de %(groupId)s", - "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Voulez-vous vraiment supprimer \"%(roomName)s\" de %(groupId)s ?", + "Failed to remove '%(roomName)s' from %(groupId)s": "Échec de la suppression de « %(roomName)s » de %(groupId)s", + "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Voulez-vous vraiment supprimer « %(roomName)s » de %(groupId)s ?", "Removing a room from the community will also remove it from the community page.": "Supprimer un salon de la communauté le supprimera aussi de la page de la communauté.", "Delete Widget": "Supprimer le widget", "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Supprimer un widget le supprime pour tous les utilisateurs du salon. Voulez-vous vraiment supprimer ce widget ?", @@ -525,13 +525,13 @@ "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)s a changé d'avatar", "%(items)s and %(count)s others|other": "%(items)s et %(count)s autres", "%(items)s and %(count)s others|one": "%(items)s et un autre", - "And %(count)s more...|other": "Et %(count)s autres...", + "And %(count)s more...|other": "Et %(count)s autres…", "Matrix ID": "Identifiant Matrix", "Matrix Room ID": "Identifiant de salon Matrix", "email address": "adresse e-mail", - "Try using one of the following valid address types: %(validTypesList)s.": "Essayez d'utiliser un des types d'adresse valide suivants : %(validTypesList)s.", - "You have entered an invalid address.": "L'adresse saisie n'est pas valide.", - "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "Les identifiants de communauté ne peuvent contenir que les caractères a-z, 0-9 ou '=_-./'", + "Try using one of the following valid address types: %(validTypesList)s.": "Essayez d’utiliser un des types d’adresse valide suivants : %(validTypesList)s.", + "You have entered an invalid address.": "L’adresse saisie n’est pas valide.", + "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "Les identifiants de communauté ne peuvent contenir que les caractères a-z, 0-9 ou « =_-./ »", "Something went wrong whilst creating your community": "Une erreur est survenue lors de la création de votre communauté", "Create Community": "Créer une communauté", "Community Name": "Nom de la communauté", @@ -540,41 +540,41 @@ "Add rooms to the community summary": "Ajouter des salons au sommaire de la communauté", "Which rooms would you like to add to this summary?": "Quels salons souhaitez-vous ajouter à ce sommaire ?", "Add to summary": "Ajouter au sommaire", - "Failed to add the following rooms to the summary of %(groupId)s:": "Échec de l'ajout des salons suivants au sommaire de %(groupId)s :", + "Failed to add the following rooms to the summary of %(groupId)s:": "Échec de l’ajout des salons suivants au sommaire de %(groupId)s :", "Add a Room": "Ajouter un salon", "Failed to remove the room from the summary of %(groupId)s": "Échec de la suppression du salon du sommaire de %(groupId)s", - "The room '%(roomName)s' could not be removed from the summary.": "Le salon \"%(roomName)s\" n'a pas pu être supprimé du sommaire.", + "The room '%(roomName)s' could not be removed from the summary.": "Le salon « %(roomName)s » n’a pas pu être supprimé du sommaire.", "Add users to the community summary": "Ajouter des utilisateurs au sommaire de la communauté", "Who would you like to add to this summary?": "Qui souhaitez-vous ajouter à ce sommaire ?", - "Failed to add the following users to the summary of %(groupId)s:": "Échec de l'ajout des utilisateurs suivants au sommaire de %(groupId)s :", + "Failed to add the following users to the summary of %(groupId)s:": "Échec de l’ajout des utilisateurs suivants au sommaire de %(groupId)s :", "Add a User": "Ajouter un utilisateur", - "Failed to remove a user from the summary of %(groupId)s": "Échec de la suppression d'un utilisateur du sommaire de %(groupId)s", - "The user '%(displayName)s' could not be removed from the summary.": "L'utilisateur \"%(displayName)s\" n'a pas pu être supprimé du sommaire.", + "Failed to remove a user from the summary of %(groupId)s": "Échec de la suppression d’un utilisateur du sommaire de %(groupId)s", + "The user '%(displayName)s' could not be removed from the summary.": "L'utilisateur « %(displayName)s » n'a pas pu être supprimé du sommaire.", "Failed to update community": "Échec de la mise à jour de la communauté", - "Unable to accept invite": "Impossible d'accepter l'invitation", - "Unable to reject invite": "Impossible de décliner l'invitation", + "Unable to accept invite": "Impossible d’accepter l’invitation", + "Unable to reject invite": "Impossible de décliner l’invitation", "Leave Community": "Quitter la communauté", "Leave %(groupName)s?": "Quitter %(groupName)s ?", "Leave": "Quitter", "Community Settings": "Paramètres de la communauté", "Add rooms to this community": "Ajouter des salons à cette communauté", "%(inviter)s has invited you to join this community": "%(inviter)s vous a invité à rejoindre cette communauté", - "You are an administrator of this community": "Vous êtes un(e) administrateur(trice) de cette communauté", + "You are an administrator of this community": "Vous êtes un administrateur de cette communauté", "You are a member of this community": "Vous êtes un membre de cette communauté", "Long Description (HTML)": "Description longue (HTML)", "Description": "Description", "Community %(groupId)s not found": "Communauté %(groupId)s non trouvée", "Failed to load %(groupId)s": "Échec du chargement de %(groupId)s", "Your Communities": "Vos communautés", - "You're not currently a member of any communities.": "Vous n'êtes actuellement membre d'aucune communauté.", - "Error whilst fetching joined communities": "Erreur lors de l'obtention des communautés rejointes", + "You're not currently a member of any communities.": "Vous n’êtes actuellement membre d’aucune communauté.", + "Error whilst fetching joined communities": "Erreur lors de la récupération des communautés dont vous faites partie", "Create a new community": "Créer une nouvelle communauté", - "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Créez une communauté pour grouper des utilisateurs et des salons ! Construisez une page d'accueil personnalisée pour distinguer votre espace dans l'univers Matrix.", + "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Créez une communauté pour grouper des utilisateurs et des salons ! Construisez une page d’accueil personnalisée pour distinguer votre espace dans l’univers Matrix.", "Mirror local video feed": "Inverser horizontalement la vidéo locale (effet miroir)", "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "Un e-mail a été envoyé à %(emailAddress)s. Après avoir suivi le lien présent dans celui-ci, cliquez ci-dessous.", "Ignores a user, hiding their messages from you": "Ignore un utilisateur, en masquant ses messages", "Stops ignoring a user, showing their messages going forward": "Arrête d’ignorer un utilisateur, en affichant ses messages à partir de maintenant", - "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "La visibilité de \"%(roomName)s\" dans %(groupId)s n'a pas pu être mise à jour.", + "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "La visibilité de « %(roomName)s » dans %(groupId)s n’a pas pu être mise à jour.", "Visibility in Room List": "Visibilité dans la liste des salons", "Visible to everyone": "Visible pour tout le monde", "Only visible to community members": "Visible uniquement par les membres de la communauté", @@ -583,13 +583,13 @@ "Room Notification": "Notification du salon", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Ces salons sont affichés aux membres de la communauté sur la page de la communauté. Les membres de la communauté peuvent rejoindre ces salons en cliquant dessus.", "

HTML for your community's page

\n

\n Use the long description to introduce new members to the community, or distribute\n some important links\n

\n

\n You can even use 'img' tags\n

\n": "

HTML pour votre page de communauté

\n

\n Utilisez la description longue pour présenter la communauté aux nouveaux membres\n ou pour diffuser des liens importants\n

\n

\n Vous pouvez même utiliser des balises \"img\"\n

\n", - "Your community hasn't got a Long Description, a HTML page to show to community members.
Click here to open settings and give it one!": "Votre communauté n'a pas de description longue, une page HTML à montrer aux membres de la communauté.
Cliquez ici pour ouvrir les réglages et créez-la !", + "Your community hasn't got a Long Description, a HTML page to show to community members.
Click here to open settings and give it one!": "Votre communauté n’a pas de description longue, une page HTML à montrer aux membres de la communauté.
Cliquez ici pour ouvrir les réglages et créez-la !", "Show these rooms to non-members on the community page and room list?": "Afficher ces salons aux non-membres sur la page de communauté et la liste des salons ?", "Please note you are logging into the %(hs)s server, not matrix.org.": "Veuillez noter que vous vous connectez au serveur %(hs)s, pas à matrix.org.", "Restricted": "Restreint", - "Enable inline URL previews by default": "Activer l'aperçu des URL par défaut", - "Enable URL previews for this room (only affects you)": "Activer l'aperçu des URL pour ce salon (n'affecte que vous)", - "Enable URL previews by default for participants in this room": "Activer l'aperçu des URL par défaut pour les participants de ce salon", + "Enable inline URL previews by default": "Activer l’aperçu des URL par défaut", + "Enable URL previews for this room (only affects you)": "Activer l’aperçu des URL pour ce salon (n’affecte que vous)", + "Enable URL previews by default for participants in this room": "Activer l’aperçu des URL par défaut pour les participants de ce salon", "URL previews are enabled by default for participants in this room.": "Les aperçus d'URL sont activés par défaut pour les participants de ce salon.", "URL previews are disabled by default for participants in this room.": "Les aperçus d'URL sont désactivés par défaut pour les participants de ce salon.", "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Il n'y a personne d'autre ici ! Souhaitez-vous inviter d'autres personnes ou ne plus être notifié à propos du salon vide ?", @@ -601,22 +601,22 @@ "Idle for %(duration)s": "Inactif depuis %(duration)s", "Offline for %(duration)s": "Hors ligne depuis %(duration)s", "Unknown for %(duration)s": "Inconnu depuis %(duration)s", - "Something went wrong when trying to get your communities.": "Une erreur est survenue lors de l'obtention de vos communautés.", - "This homeserver doesn't offer any login flows which are supported by this client.": "Ce serveur d'accueil n'offre aucune méthode d'identification compatible avec ce client.", + "Something went wrong when trying to get your communities.": "Une erreur est survenue lors de la récupération de vos communautés.", + "This homeserver doesn't offer any login flows which are supported by this client.": "Ce serveur d’accueil n’offre aucune méthode d’identification compatible avec ce client.", "Flair": "Badge", - "Showing flair for these communities:": "Ce salon affichera les badges pour ces communautés :", - "This room is not showing flair for any communities": "Ce salon n'affiche de badge pour aucune communauté", + "Showing flair for these communities:": "Ce salon affichera les badges pour ces communautés :", + "This room is not showing flair for any communities": "Ce salon n’affiche de badge pour aucune communauté", "Display your community flair in rooms configured to show it.": "Sélectionnez les badges dans les paramètres de chaque salon pour les afficher.", "expand": "développer", "collapse": "réduire", "Call Failed": "L’appel a échoué", "Send": "Envoyer", "Old cryptography data detected": "Anciennes données de chiffrement détectées", - "Data from an older version of %(brand)s has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Nous avons détecté des données d'une ancienne version de %(brand)s. Le chiffrement de bout en bout n'aura pas fonctionné correctement sur l'ancienne version. Les messages chiffrés échangés récemment dans l'ancienne version ne sont peut-être pas déchiffrables dans cette version. Les échanges de message avec cette version peuvent aussi échouer. Si vous rencontrez des problèmes, déconnectez-vous puis reconnectez-vous. Pour conserver l'historique des messages, exportez puis réimportez vos clés de chiffrement.", + "Data from an older version of %(brand)s has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Nous avons détecté des données d’une ancienne version de %(brand)s. Le chiffrement de bout en bout n’aura pas fonctionné correctement sur l’ancienne version. Les messages chiffrés échangés récemment dans l’ancienne version ne sont peut-être pas déchiffrables dans cette version. Les échanges de message avec cette version peuvent aussi échouer. Si vous rencontrez des problèmes, déconnectez-vous puis reconnectez-vous. Pour conserver l’historique des messages, exportez puis réimportez vos clés de chiffrement.", "Warning": "Attention", - "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Vous ne pourrez pas annuler cette modification car vous vous destituez. Si vous êtes le dernier utilisateur privilégié de ce salon, il sera impossible de récupérer les privilèges.", - "%(count)s of your messages have not been sent.|one": "Votre message n'a pas été envoyé.", - "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "Tout renvoyer ou tout annuler maintenant. Vous pouvez aussi choisir des messages individuels à renvoyer ou annuler.", + "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Vous ne pourrez pas annuler cette modification car vous vous rétrogradez. Si vous êtes le dernier utilisateur privilégié de ce salon, il sera impossible de récupérer les privilèges.", + "%(count)s of your messages have not been sent.|one": "Votre message n’a pas été envoyé.", + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "Tout renvoyer ou tout annuler maintenant. Vous pouvez aussi choisir de ne renvoyer ou annuler que certains messages.", "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Renvoyer le message ou annuler le message maintenant.", "Send an encrypted reply…": "Envoyer une réponse chiffrée…", "Send an encrypted message…": "Envoyer un message chiffré…", @@ -633,31 +633,31 @@ "Whether or not you're using the Richtext mode of the Rich Text Editor": "Si vous utilisez le mode « texte enrichi » de l’éditeur de texte enrichi", "Your homeserver's URL": "L’URL de votre serveur d’accueil", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s %(day)s %(monthName)s %(fullYear)s", - "This room is not public. You will not be able to rejoin without an invite.": "Ce salon n'est pas public. Vous ne pourrez pas y revenir sans invitation.", + "This room is not public. You will not be able to rejoin without an invite.": "Ce salon n’est pas public. Vous ne pourrez pas y revenir sans invitation.", "Community IDs cannot be empty.": "Les identifiants de communauté ne peuvent pas être vides.", "In reply to ": "En réponse à ", - "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s a changé son nom affiché en %(displayName)s.", - "Failed to set direct chat tag": "Échec de l'ajout de l'étiquette discussion directe", - "Failed to remove tag %(tagName)s from room": "Échec de la suppression de l'étiquette %(tagName)s du salon", - "Failed to add tag %(tagName)s to room": "Échec de l'ajout de l'étiquette %(tagName)s au salon", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s a changé son nom d’affichage en %(displayName)s.", + "Failed to set direct chat tag": "Échec de l’ajout de l’étiquette discussion directe", + "Failed to remove tag %(tagName)s from room": "Échec de la suppression de l’étiquette %(tagName)s du salon", + "Failed to add tag %(tagName)s to room": "Échec de l’ajout de l’étiquette %(tagName)s au salon", "Clear filter": "Supprimer les filtres", "Did you know: you can use communities to filter your %(brand)s experience!": "Le saviez-vous : vous pouvez utiliser les communautés pour filtrer votre expérience %(brand)s !", - "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Pour activer un filtre, faites glisser un avatar de communauté sur le panneau des filtres tout à gauche de l'écran. Vous pouvez cliquer sur un avatar dans ce panneau quand vous le souhaitez afin de ne voir que les salons et les personnes associés à cette communauté.", + "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Pour activer un filtre, faites glisser un avatar de communauté sur le panneau des filtres tout à gauche de l’écran. Vous pouvez cliquer sur un avatar dans ce panneau quand vous le souhaitez afin de ne voir que les salons et les personnes associés à cette communauté.", "Key request sent.": "Demande de clé envoyée.", "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Vu par %(displayName)s (%(userName)s) à %(dateTime)s", "Code": "Code", - "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Si vous avez signalé un bug via GitHub, les journaux de débogage peuvent nous aider à identifier le problème. Les journaux de débogage contiennent des données d'utilisation de l'application dont votre nom d'utilisateur, les identifiants ou alias des salons ou groupes que vous avez visité et les noms d'utilisateur des autres participants. Ils ne contiennent pas les messages.", + "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Si vous avez signalé un bug via GitHub, les journaux de débogage peuvent nous aider à identifier le problème. Les journaux de débogage contiennent des données d’utilisation de l’application dont votre nom d’utilisateur, les identifiants ou alias des salons ou groupes que vous avez visité et les noms d’utilisateur des autres participants. Ils ne contiennent pas les messages.", "Submit debug logs": "Envoyer les journaux de débogage", "Opens the Developer Tools dialog": "Ouvre la fenêtre des outils de développeur", "Unable to join community": "Impossible de rejoindre la communauté", "Unable to leave community": "Impossible de quitter la communauté", - "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Les changements effectués au nom et à l'avatar de votre communauté peuvent prendre jusqu'à 30 minutes avant d'être vus par d'autres utilisateurs.", + "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Les changements effectués au nom et à l’avatar de votre communauté peuvent prendre jusqu'à 30 minutes avant d’être visibles par d’autres utilisateurs.", "Join this community": "Rejoindre cette communauté", "Leave this community": "Quitter cette communauté", - "Stickerpack": "Pack de stickers", - "You don't currently have any stickerpacks enabled": "Vous n'avez activé aucun pack de stickers pour l'instant", - "Hide Stickers": "Masquer les stickers", - "Show Stickers": "Afficher les stickers", + "Stickerpack": "Jeu d’autocollants", + "You don't currently have any stickerpacks enabled": "Vous n'avez activé aucun jeu d’autocollants pour l’instant", + "Hide Stickers": "Masquer les autocollants", + "Show Stickers": "Afficher les autocollants", "Who can join this community?": "Qui peut rejoindre cette communauté ?", "Everyone": "Tout le monde", "Fetching third party location failed": "Échec de la récupération de la localisation tierce", @@ -666,7 +666,7 @@ "Uploading report": "Envoi du rapport", "Sunday": "Dimanche", "Notification targets": "Appareils recevant les notifications", - "Today": "Aujourd'hui", + "Today": "Aujourd’hui", "Files": "Fichiers", "You are not receiving desktop notifications": "Vous ne recevez pas les notifications sur votre bureau", "Friday": "Vendredi", @@ -675,25 +675,25 @@ "On": "Activé", "Changelog": "Journal des modifications", "Waiting for response from server": "En attente d’une réponse du serveur", - "Send Custom Event": "Envoyer l'événement personnalisé", + "Send Custom Event": "Envoyer l’événement personnalisé", "Advanced notification settings": "Paramètres de notification avancés", "Forget": "Oublier", "You cannot delete this image. (%(code)s)": "Vous ne pouvez pas supprimer cette image. (%(code)s)", - "Cancel Sending": "Annuler l'envoi", + "Cancel Sending": "Annuler l’envoi", "This Room": "Ce salon", "Noisy": "Sonore", "Room not found": "Salon non trouvé", - "Messages containing my display name": "Messages contenant mon nom affiché", + "Messages containing my display name": "Messages contenant mon nom d’affichage", "Messages in one-to-one chats": "Messages dans les discussions directes", "Unavailable": "Indisponible", "View Decrypted Source": "Voir la source déchiffrée", - "Failed to update keywords": "Échec dans la mise à jour des mots-clés", + "Failed to update keywords": "Échec de la mise à jour des mots-clés", "remove %(name)s from the directory.": "supprimer %(name)s du répertoire.", - "Notifications on the following keywords follow rules which can’t be displayed here:": "Les notifications pour les mots-clés suivant répondent à des critères qui ne peuvent pas être affichés ici :", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Les notifications pour les mots-clés suivant répondent à des critères qui ne peuvent pas être affichés ici :", "Please set a password!": "Veuillez définir un mot de passe !", "You have successfully set a password!": "Vous avez défini un mot de passe avec succès !", "An error occurred whilst saving your email notification preferences.": "Une erreur est survenue lors de la sauvegarde de vos préférences de notification par e-mail.", - "Explore Room State": "Parcourir l'état du salon", + "Explore Room State": "Parcourir l’état du salon", "Source URL": "URL de la source", "Messages sent by bot": "Messages envoyés par des robots", "Filter results": "Filtrer les résultats", @@ -707,10 +707,10 @@ "Messages containing keywords": "Messages contenant des mots-clés", "Error saving email notification preferences": "Erreur lors de la sauvegarde des préférences de notification par e-mail", "Tuesday": "Mardi", - "Enter keywords separated by a comma:": "Entrez les mots-clés séparés par une virgule :", + "Enter keywords separated by a comma:": "Entrez les mots-clés séparés par une virgule :", "Search…": "Rechercher…", "You have successfully set a password and an email address!": "Vous avez défini un mot de passe et une adresse e-mail avec succès !", - "Remove %(name)s from the directory?": "Supprimer %(name)s du répertoire ?", + "Remove %(name)s from the directory?": "Supprimer %(name)s du répertoire ?", "%(brand)s uses many advanced browser features, some of which are not available or experimental in your current browser.": "%(brand)s utilise de nombreuses fonctionnalités avancées du navigateur, certaines ne sont pas disponibles ou expérimentales dans votre navigateur actuel.", "Developer Tools": "Outils de développement", "Remember, you can always set an email address in user settings if you change your mind.": "Souvenez-vous que vous pourrez toujours définir une adresse e-mail dans les paramètres de l'utilisateur si vous changez d’avis.", @@ -727,7 +727,7 @@ "Enable them now": "Les activer maintenant", "Toolbox": "Boîte à outils", "Collecting logs": "Récupération des journaux", - "You must specify an event type!": "Vous devez spécifier un type d'événement !", + "You must specify an event type!": "Vous devez indiquer un type d’événement !", "(HTTP status %(httpStatus)s)": "(état HTTP %(httpStatus)s)", "Invite to this room": "Inviter dans ce salon", "Wednesday": "Mercredi", @@ -736,15 +736,15 @@ "Send logs": "Envoyer les journaux", "All messages": "Tous les messages", "Call invitation": "Appel entrant", - "Downloading update...": "Mise à jour en cours de téléchargement...", - "State Key": "Clé d'état", - "Failed to send custom event.": "Échec de l'envoi de l'événement personnalisé.", + "Downloading update...": "Mise à jour en cours de téléchargement…", + "State Key": "Clé d’état", + "Failed to send custom event.": "Échec de l’envoi de l’événement personnalisé.", "What's new?": "Nouveautés", "Notify me for anything else": "Me notifier pour tout le reste", "View Source": "Voir la source", - "Can't update user notification settings": "Impossible de mettre à jour les paramètres de notification de l'utilisateur", + "Can't update user notification settings": "Impossible de mettre à jour les paramètres de notification de l’utilisateur", "Notify for all other messages/rooms": "Me notifier pour tous les autres messages/salons", - "Unable to look up room ID from server": "Impossible de récupérer l'ID du salon sur le serveur", + "Unable to look up room ID from server": "Impossible de récupérer l’identifiant du salon sur le serveur", "Couldn't find a matching Matrix room": "Impossible de trouver un salon Matrix correspondant", "All Rooms": "Tous les salons", "Thursday": "Jeudi", @@ -752,7 +752,7 @@ "Back": "Retour", "Reply": "Répondre", "Show message in desktop notification": "Afficher le message dans les notifications de bureau", - "Unhide Preview": "Dévoiler l'aperçu", + "Unhide Preview": "Dévoiler l’aperçu", "Unable to join network": "Impossible de rejoindre le réseau", "Sorry, your browser is not able to run %(brand)s.": "Désolé, %(brand)s n'est pas supporté par votre navigateur.", "Uploaded on %(date)s by %(user)s": "Téléchargé le %(date)s par %(user)s", @@ -767,21 +767,21 @@ "Mentions only": "Seulement les mentions", "You can now return to your account after signing out, and sign in on other devices.": "Vous pouvez maintenant revenir sur votre compte après vous être déconnecté, et vous identifier sur d'autres appareils.", "Enable email notifications": "Activer les notifications par e-mail", - "Event Type": "Type d'événement", + "Event Type": "Type d’événement", "Download this file": "Télécharger ce fichier", "Pin Message": "Épingler le message", "Failed to change settings": "Échec de la mise à jour des paramètres", "View Community": "Voir la communauté", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Depuis votre navigateur actuel, le visuel et le ressenti de l'application pourraient être complètement erronés, et certaines fonctionnalités pourraient ne pas être supportées. Vous pouvez continuer malgré tout, mais vous n'aurez aucune aide si vous rencontrez des problèmes !", "Event sent!": "Événement envoyé !", - "Event Content": "Contenu de l'événement", - "Thank you!": "Merci !", + "Event Content": "Contenu de l’événement", + "Thank you!": "Merci !", "When I'm invited to a room": "Quand je suis invité dans un salon", - "Checking for an update...": "Recherche de mise à jour...", + "Checking for an update...": "Recherche de mise à jour…", "Logs sent": "Journaux envoyés", - "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Les journaux de débogage contiennent des données d'usage de l'application qui incluent votre nom d'utilisateur, les identifiants ou alias des salons ou groupes auxquels vous avez rendu visite ainsi que les noms des autres utilisateurs. Ils ne contiennent aucun message.", - "Failed to send logs: ": "Échec lors de l'envoi des journaux : ", - "Preparing to send logs": "Préparation d'envoi des journaux", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Les journaux de débogage contiennent des données d'usage de l’application qui incluent votre nom d’utilisateur, les identifiants ou alias des salons ou groupes auxquels vous avez rendu visite ainsi que les noms des autres utilisateurs. Ils ne contiennent aucun message.", + "Failed to send logs: ": "Échec lors de l’envoi des journaux : ", + "Preparing to send logs": "Préparation de l’envoi des journaux", "Missing roomId.": "Identifiant de salon manquant.", "Popout widget": "Détacher le widget", "Every page you use in the app": "Toutes les pages que vous utilisez dans l’application", @@ -792,46 +792,46 @@ "Clear Storage and Sign Out": "Effacer le stockage et se déconnecter", "Refresh": "Rafraîchir", "We encountered an error trying to restore your previous session.": "Une erreur est survenue lors de la restauration de la dernière session.", - "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Effacer le stockage de votre navigateur peut résoudre le problème, mais cela vous déconnectera et tous les historiques de conversation encryptés seront illisibles.", - "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Impossible de charger l'événement auquel il a été répondu, soit il n'existe pas, soit vous n'avez pas l'autorisation de le voir.", + "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Effacer le stockage de votre navigateur peut résoudre le problème. Ceci vous déconnectera et tous les historiques de conversations chiffrées seront illisibles.", + "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Impossible de charger l’événement auquel il a été répondu, soit il n’existe pas, soit vous n'avez pas l’autorisation de le voir.", "Collapse Reply Thread": "Masquer le fil de réponse", - "Enable widget screenshots on supported widgets": "Activer les captures d'écran des widgets pris en charge", - "Send analytics data": "Envoyer les données analytiques", + "Enable widget screenshots on supported widgets": "Activer les captures d’écran pour les widgets pris en charge", + "Send analytics data": "Envoyer les données de télémétrie", "Muted Users": "Utilisateurs ignorés", "Terms and Conditions": "Conditions générales", - "To continue using the %(homeserverDomain)s homeserver you must review and agree to our terms and conditions.": "Pour continuer à utiliser le serveur d'accueil %(homeserverDomain)s, vous devez lire et accepter nos conditions générales.", + "To continue using the %(homeserverDomain)s homeserver you must review and agree to our terms and conditions.": "Pour continuer à utiliser le serveur d’accueil %(homeserverDomain)s, vous devez lire et accepter nos conditions générales.", "Review terms and conditions": "Voir les conditions générales", "To continue, please enter your password:": "Pour continuer, veuillez renseigner votre mot de passe :", - "This will make your account permanently unusable. You will not be able to log in, and no one will be able to re-register the same user ID. This will cause your account to leave all rooms it is participating in, and it will remove your account details from your identity server. This action is irreversible.": "Votre compte sera inutilisable de façon permanente. Vous ne pourrez plus vous reconnecter et personne ne pourra se réenregistrer avec le même identifiant d'utilisateur. Votre compte quittera tous les salons auxquels il participe et tous ses détails seront supprimés du serveur d'identité. Cette action est irréversible.", + "This will make your account permanently unusable. You will not be able to log in, and no one will be able to re-register the same user ID. This will cause your account to leave all rooms it is participating in, and it will remove your account details from your identity server. This action is irreversible.": "Votre compte sera inutilisable de façon permanente. Vous ne pourrez plus vous reconnecter et personne ne pourra se réenregistrer avec le même identifiant d'utilisateur. Votre compte quittera tous les salons auxquels il participe et tous ses détails seront supprimés du serveur d’identité. Cette action est irréversible.", "Deactivating your account does not by default cause us to forget messages you have sent. If you would like us to forget your messages, please tick the box below.": "La désactivation du compte ne nous fait pas oublier les messages que vous avez envoyés par défaut. Si vous souhaitez que nous les oubliions, cochez la case ci-dessous.", "e.g. %(exampleValue)s": "par ex. %(exampleValue)s", "Message visibility in Matrix is similar to email. Our forgetting your messages means that messages you have sent will not be shared with any new or unregistered users, but registered users who already have access to these messages will still have access to their copy.": "La visibilité des messages dans Matrix est la même que celle des e-mails. Quand nous oublions vos messages, cela signifie que les messages que vous avez envoyés ne seront partagés avec aucun nouvel utilisateur ou avec les utilisateurs non enregistrés, mais les utilisateurs enregistrés qui ont déjà eu accès à ces messages en conserveront leur propre copie.", - "Please forget all messages I have sent when my account is deactivated (Warning: this will cause future users to see an incomplete view of conversations)": "Veuillez oublier tous les messages que j'ai envoyé quand mon compte sera désactivé (Avertissement : les futurs utilisateurs verront des conversations incomplètes)", - "Can't leave Server Notices room": "Impossible de quitter le salon des Annonces du serveur", - "This room is used for important messages from the Homeserver, so you cannot leave it.": "Ce salon est utilisé pour les messages importants du serveur d'accueil, donc vous ne pouvez pas en partir.", + "Please forget all messages I have sent when my account is deactivated (Warning: this will cause future users to see an incomplete view of conversations)": "Veuillez oublier tous les messages que j’ai envoyé quand mon compte sera désactivé (Avertissement : les futurs utilisateurs verront des conversations incomplètes)", + "Can't leave Server Notices room": "Impossible de quitter le salon des annonces au serveur", + "This room is used for important messages from the Homeserver, so you cannot leave it.": "Ce salon est utilisé pour les messages importants du serveur d’accueil, vous ne pouvez donc pas en partir.", "No Audio Outputs detected": "Aucune sortie audio détectée", "Audio Output": "Sortie audio", - "Share Link to User": "Partager le lien vers l'utilisateur", + "Share Link to User": "Partager le lien vers l’utilisateur", "Share room": "Partager le salon", "Share Room": "Partager le salon", "Link to most recent message": "Lien vers le message le plus récent", - "Share User": "Partager l'utilisateur", + "Share User": "Partager l’utilisateur", "Share Community": "Partager la communauté", "Share Room Message": "Partager le message du salon", "Link to selected message": "Lien vers le message sélectionné", "COPY": "COPIER", "Share Message": "Partager le message", - "In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.": "Dans les salons chiffrés, comme celui-ci, l'aperçu des liens est désactivé par défaut pour s'assurer que le serveur d'accueil (où sont générés les aperçus) ne puisse pas collecter d'informations sur les liens qui apparaissent dans ce salon.", - "When someone puts a URL in their message, a URL preview can be shown to give more information about that link such as the title, description, and an image from the website.": "Quand quelqu'un met un lien dans son message, un aperçu du lien peut être affiché afin de fournir plus d'informations sur ce lien comme le titre, la description et une image du site.", + "In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.": "Dans les salons chiffrés, comme celui-ci, l’aperçu des liens est désactivé par défaut pour s’assurer que le serveur d’accueil (où sont générés les aperçus) ne puisse pas collecter d’informations sur les liens qui apparaissent dans ce salon.", + "When someone puts a URL in their message, a URL preview can be shown to give more information about that link such as the title, description, and an image from the website.": "Quand quelqu’un met un lien dans son message, un aperçu du lien peut être affiché afin de fournir plus d’informations sur ce lien comme le titre, la description et une image du site.", "The email field must not be blank.": "Le champ de l'adresse e-mail ne doit pas être vide.", "The phone number field must not be blank.": "Le champ du numéro de téléphone ne doit pas être vide.", "The password field must not be blank.": "Le champ du mot de passe ne doit pas être vide.", "Call in Progress": "Appel en cours", "A call is already in progress!": "Un appel est déjà en cours !", - "You can't send any messages until you review and agree to our terms and conditions.": "Vous ne pouvez voir aucun message tant que vous ne lisez et n'acceptez pas nos conditions générales.", + "You can't send any messages until you review and agree to our terms and conditions.": "Vous ne pouvez voir aucun message tant que vous ne lisez et n’acceptez pas nos conditions générales.", "Demote yourself?": "Vous rétrograder ?", "Demote": "Rétrograder", - "This event could not be displayed": "Cet événement n'a pas pu être affiché", + "This event could not be displayed": "Cet événement n’a pas pu être affiché", "Permission Required": "Autorisation requise", "You do not have permission to start a conference call in this room": "Vous n’avez pas l’autorisation de lancer un appel en téléconférence dans ce salon", "A call is currently being placed!": "Un appel est en cours !", @@ -839,51 +839,51 @@ "An error ocurred whilst trying to remove the widget from the room": "Une erreur est survenue lors de la suppression du widget du salon", "System Alerts": "Alertes système", "Only room administrators will see this warning": "Seuls les administrateurs du salon verront cet avertissement", - "Please contact your service administrator to continue using the service.": "Veuillez contacter l'administrateur de votre service pour continuer à l'utiliser.", - "This homeserver has hit its Monthly Active User limit.": "Ce serveur d'accueil a atteint sa limite mensuelle d'utilisateurs actifs.", - "This homeserver has exceeded one of its resource limits.": "Ce serveur d'accueil a dépassé une de ses limites de ressources.", + "Please contact your service administrator to continue using the service.": "Veuillez contacter l’administrateur de votre service pour continuer à l’utiliser.", + "This homeserver has hit its Monthly Active User limit.": "Ce serveur d’accueil a atteint sa limite mensuelle d'utilisateurs actifs.", + "This homeserver has exceeded one of its resource limits.": "Ce serveur d’accueil a dépassé une de ses limites de ressources.", "Upgrade Room Version": "Mettre à niveau la version du salon", "Create a new room with the same name, description and avatar": "Créer un salon avec le même nom, la même description et le même avatar", - "Update any local room aliases to point to the new room": "Mettre à jour tous les alias du salon locaux pour qu'ils dirigent vers le nouveau salon", - "Stop users from speaking in the old version of the room, and post a message advising users to move to the new room": "Empêcher les utilisateurs de discuter dans l'ancienne version du salon et envoyer un message conseillant aux nouveaux utilisateurs d'aller dans le nouveau salon", - "Put a link back to the old room at the start of the new room so people can see old messages": "Fournir un lien vers l'ancien salon au début du nouveau salon pour que l'on puisse voir les vieux messages", - "Your message wasn't sent because this homeserver has hit its Monthly Active User Limit. Please contact your service administrator to continue using the service.": "Votre message n'a pas été envoyé car le serveur d'accueil a atteint sa limite mensuelle d'utilisateurs. Veuillez contacter l'administrateur de votre service pour continuer à l'utiliser.", - "Your message wasn't sent because this homeserver has exceeded a resource limit. Please contact your service administrator to continue using the service.": "Votre message n'a pas été envoyé car ce serveur d'accueil a dépassé une de ses limites de ressources. Veuillez contacter l'administrateur de votre service pour continuer à l'utiliser.", - "Please contact your service administrator to continue using this service.": "Veuillez contacter l'administrateur de votre service pour continuer à l'utiliser.", - "Sorry, your homeserver is too old to participate in this room.": "Désolé, votre serveur d'accueil est trop vieux pour participer à ce salon.", - "Please contact your homeserver administrator.": "Veuillez contacter l'administrateur de votre serveur d'accueil.", + "Update any local room aliases to point to the new room": "Mettre à jour tous les alias du salon locaux pour qu’ils dirigent vers le nouveau salon", + "Stop users from speaking in the old version of the room, and post a message advising users to move to the new room": "Empêcher les utilisateurs de discuter dans l’ancienne version du salon et envoyer un message conseillant aux nouveaux utilisateurs d’aller dans le nouveau salon", + "Put a link back to the old room at the start of the new room so people can see old messages": "Fournir un lien vers l’ancien salon au début du nouveau salon pour qu’il soit possible de consulter les anciens messages", + "Your message wasn't sent because this homeserver has hit its Monthly Active User Limit. Please contact your service administrator to continue using the service.": "Votre message n’a pas été envoyé car le serveur d’accueil a atteint sa limite mensuelle d’utilisateurs. Veuillez contacter l’administrateur de votre service pour continuer à l’utiliser.", + "Your message wasn't sent because this homeserver has exceeded a resource limit. Please contact your service administrator to continue using the service.": "Votre message n’a pas été envoyé car ce serveur d’accueil a dépassé une de ses limites de ressources. Veuillez contacter l’administrateur de votre service pour continuer à l’utiliser.", + "Please contact your service administrator to continue using this service.": "Veuillez contacter l’administrateur de votre service pour continuer à l’utiliser.", + "Sorry, your homeserver is too old to participate in this room.": "Désolé, votre serveur d’accueil est trop vieux pour participer à ce salon.", + "Please contact your homeserver administrator.": "Veuillez contacter l’administrateur de votre serveur d’accueil.", "Legal": "Légal", - "This room has been replaced and is no longer active.": "Ce salon a été remplacé et n'est plus actif.", + "This room has been replaced and is no longer active.": "Ce salon a été remplacé et n’est plus actif.", "The conversation continues here.": "La discussion continue ici.", - "This room is a continuation of another conversation.": "Ce salon est la suite d'une autre discussion.", - "Click here to see older messages.": "Cliquer ici pour voir les vieux messages.", + "This room is a continuation of another conversation.": "Ce salon est la suite d’une autre discussion.", + "Click here to see older messages.": "Cliquer ici pour voir les anciens messages.", "Failed to upgrade room": "Échec de la mise à niveau du salon", - "The room upgrade could not be completed": "La mise à niveau du salon n'a pas pu être effectuée", + "The room upgrade could not be completed": "La mise à niveau du salon n’a pas pu être effectuée", "Upgrade this room to version %(version)s": "Mettre à niveau ce salon vers la version %(version)s", "Forces the current outbound group session in an encrypted room to be discarded": "Force la session de groupe sortante actuelle dans un salon chiffré à être rejetée", - "Unable to connect to Homeserver. Retrying...": "Impossible de se connecter au serveur d'accueil. Reconnexion...", + "Unable to connect to Homeserver. Retrying...": "Impossible de se connecter au serveur d’accueil. Reconnexion…", "%(senderName)s set the main address for this room to %(address)s.": "%(senderName)s a défini l’adresse principale pour ce salon comme %(address)s.", "%(senderName)s removed the main address for this room.": "%(senderName)s a supprimé l’adresse principale de ce salon.", - "%(brand)s now uses 3-5x less memory, by only loading information about other users when needed. Please wait whilst we resynchronise with the server!": "%(brand)s utilise maintenant 3 à 5 fois moins de mémoire, en ne chargeant les informations des autres utilisateurs que quand elles sont nécessaires. Veuillez patienter pendant que l'on se resynchronise avec le serveur !", + "%(brand)s now uses 3-5x less memory, by only loading information about other users when needed. Please wait whilst we resynchronise with the server!": "%(brand)s utilise maintenant 3 à 5 fois moins de mémoire, en ne chargeant les informations des autres utilisateurs que quand elles sont nécessaires. Veuillez patienter pendant que l’on se resynchronise avec le serveur !", "Updating %(brand)s": "Mise à jour de %(brand)s", "Before submitting logs, you must create a GitHub issue to describe your problem.": "Avant de soumettre vos journaux, vous devez créer une « issue » sur GitHub pour décrire votre problème.", - "You've previously used %(brand)s on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, %(brand)s needs to resync your account.": "Vous avez utilisé auparavant %(brand)s sur %(host)s avec le chargement différé activé. Dans cette version le chargement différé est désactivé. Comme le cache local n'est pas compatible entre ces deux réglages, %(brand)s doit resynchroniser votre compte.", - "If the other version of %(brand)s is still open in another tab, please close it as using %(brand)s on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "Si l'autre version de %(brand)s est encore ouverte dans un autre onglet, merci de le fermer car l'utilisation de %(brand)s sur le même hôte avec le chargement différé activé et désactivé à la fois causera des problèmes.", + "You've previously used %(brand)s on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, %(brand)s needs to resync your account.": "Vous avez utilisé auparavant %(brand)s sur %(host)s avec le chargement différé activé. Dans cette version le chargement différé est désactivé. Comme le cache local n’est pas compatible entre ces deux réglages, %(brand)s doit resynchroniser votre compte.", + "If the other version of %(brand)s is still open in another tab, please close it as using %(brand)s on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "Si l’autre version de %(brand)s est encore ouverte dans un autre onglet, merci de le fermer car l’utilisation de %(brand)s sur le même hôte avec le chargement différé activé et désactivé à la fois causera des problèmes.", "Incompatible local cache": "Cache local incompatible", "Clear cache and resync": "Vider le cache et resynchroniser", - "Please review and accept the policies of this homeserver:": "Veuillez lire et accepter les politiques de ce serveur d'accueil :", + "Please review and accept the policies of this homeserver:": "Veuillez lire et accepter les politiques de ce serveur d’accueil :", "Add some now": "En ajouter maintenant", - "You are an administrator of this community. You will not be able to rejoin without an invite from another administrator.": "Vous êtes administrateur de cette communauté. Vous ne pourrez pas revenir sans une invitation d'un autre administrateur.", + "You are an administrator of this community. You will not be able to rejoin without an invite from another administrator.": "Vous êtes administrateur de cette communauté. Vous ne pourrez pas revenir sans une invitation d’un autre administrateur.", "Open Devtools": "Ouvrir les outils développeur", "Show developer tools": "Afficher les outils de développeur", - "Please review and accept all of the homeserver's policies": "Veuillez lire et accepter toutes les politiques du serveur d'accueil", - "To avoid losing your chat history, you must export your room keys before logging out. You will need to go back to the newer version of %(brand)s to do this": "Pour éviter de perdre l'historique de vos discussions, vous devez exporter vos clés avant de vous déconnecter. Vous devez revenir à une version plus récente de %(brand)s pour pouvoir le faire", + "Please review and accept all of the homeserver's policies": "Veuillez lire et accepter toutes les politiques du serveur d’accueil", + "To avoid losing your chat history, you must export your room keys before logging out. You will need to go back to the newer version of %(brand)s to do this": "Pour éviter de perdre l’historique de vos discussions, vous devez exporter vos clés avant de vous déconnecter. Vous devez revenir à une version plus récente de %(brand)s pour pouvoir le faire", "Incompatible Database": "Base de données incompatible", "Continue With Encryption Disabled": "Continuer avec le chiffrement désactivé", - "Sign in with single sign-on": "Se connecter avec l'authentification unique", + "Sign in with single sign-on": "Se connecter avec l’authentification unique", "Unable to load! Check your network connectivity and try again.": "Chargement impossible ! Vérifiez votre connexion au réseau et réessayez.", "Delete Backup": "Supprimer la sauvegarde", - "Unable to load key backup status": "Impossible de charger l'état de sauvegarde des clés", + "Unable to load key backup status": "Impossible de charger l’état de sauvegarde des clés", "Backup version: ": "Version de la sauvegarde : ", "Algorithm: ": "Algorithme : ", "Next": "Suivant", @@ -897,28 +897,28 @@ "Set up Secure Message Recovery": "Configurer la récupération de messages sécurisée", "Unable to create key backup": "Impossible de créer la sauvegarde des clés", "Retry": "Réessayer", - "Unable to load backup status": "Impossible de charger l'état de la sauvegarde", + "Unable to load backup status": "Impossible de récupérer l’état de la sauvegarde", "Unable to restore backup": "Impossible de restaurer la sauvegarde", - "No backup found!": "Aucune sauvegarde n'a été trouvée !", + "No backup found!": "Aucune sauvegarde n’a été trouvée !", "Failed to decrypt %(failedCount)s sessions!": "Le déchiffrement de %(failedCount)s sessions a échoué !", "Access your secure message history and set up secure messaging by entering your recovery passphrase.": "Accédez à l'historique sécurisé de vos messages et configurez la messagerie sécurisée en renseignant votre phrase de récupération.", "If you've forgotten your recovery passphrase you can use your recovery key or set up new recovery options": "Si vous avez oublié votre phrase de récupération vous pouvez utiliser votre clé de récupération ou configurer de nouvelles options de récupération", "This looks like a valid recovery key!": "Cela ressemble à une clé de récupération valide !", "Not a valid recovery key": "Ce n'est pas une clé de récupération valide", "Access your secure message history and set up secure messaging by entering your recovery key.": "Accédez à l'historique sécurisé de vos messages et configurez la messagerie sécurisée en renseignant votre clé de récupération.", - "Failed to perform homeserver discovery": "Échec lors de la découverte du serveur d'accueil", - "Invalid homeserver discovery response": "Réponse de découverte du serveur d'accueil non valide", + "Failed to perform homeserver discovery": "Échec lors de la découverte du serveur d’accueil", + "Invalid homeserver discovery response": "Réponse de découverte du serveur d’accueil non valide", "Use a few words, avoid common phrases": "Utilisez quelques mots, évitez les phrases courantes", - "No need for symbols, digits, or uppercase letters": "Il n'y a pas besoin de symboles, de chiffres ou de majuscules", + "No need for symbols, digits, or uppercase letters": "Il n'y a pas besoin de symbole, de chiffre ou de majuscule", "Avoid repeated words and characters": "Évitez de répéter des mots et des caractères", "Avoid sequences": "Évitez les séquences", "Avoid recent years": "Évitez les années récentes", "Avoid years that are associated with you": "Évitez les années qui ont un rapport avec vous", "Avoid dates and years that are associated with you": "Évitez les dates et les années qui ont un rapport avec vous", - "Capitalization doesn't help very much": "Les majuscules n'aident pas vraiment", - "All-uppercase is almost as easy to guess as all-lowercase": "Uniquement des majuscules, c'est presque aussi facile à deviner qu'uniquement des minuscules", + "Capitalization doesn't help very much": "Les majuscules n’aident pas vraiment", + "All-uppercase is almost as easy to guess as all-lowercase": "Uniquement des majuscules, c’est presque aussi facile à deviner qu’uniquement des minuscules", "Reversed words aren't much harder to guess": "Les mots inversés ne sont pas beaucoup plus difficiles à deviner", - "Predictable substitutions like '@' instead of 'a' don't help very much": "Les substitutions prévisibles comme « @ » à la place de « a » n'aident pas vraiment", + "Predictable substitutions like '@' instead of 'a' don't help very much": "Les substitutions prévisibles comme « @ » à la place de « a » ne sont pas très utiles", "Add another word or two. Uncommon words are better.": "Ajoutez un ou deux mots. Les mots rares sont à privilégier.", "Repeats like \"aaa\" are easy to guess": "Les répétitions comme « aaa » sont faciles à deviner", "Repeats like \"abcabcabc\" are only slightly harder to guess than \"abc\"": "Les répétitions comme « abcabcabc » ne sont pas beaucoup plus difficiles à deviner que « abc »", @@ -927,7 +927,7 @@ "Dates are often easy to guess": "Les dates sont généralement faciles à deviner", "This is a top-10 common password": "Cela fait partie des 10 mots de passe les plus répandus", "This is a top-100 common password": "Cela fait partie des 100 mots de passe les plus répandus", - "This is a very common password": "C'est un mot de passe très répandu", + "This is a very common password": "C’est un mot de passe très répandu", "This is similar to a commonly used password": "Cela ressemble à un mot de passe répandu", "A word by itself is easy to guess": "Un mot seul est facile à deviner", "Names and surnames by themselves are easy to guess": "Les noms et prénoms seuls sont faciles à deviner", @@ -936,8 +936,8 @@ "Failed to load group members": "Échec du chargement des membres du groupe", "Failed to invite users to the room:": "Échec de l’invitation d'utilisateurs dans le salon :", "There was an error joining the room": "Une erreur est survenue en rejoignant le salon", - "You do not have permission to invite people to this room.": "Vous n'avez pas la permission d'envoyer des invitations dans ce salon.", - "User %(user_id)s does not exist": "L'utilisateur %(user_id)s n'existe pas", + "You do not have permission to invite people to this room.": "Vous n’avez pas la permission d’envoyer des invitations dans ce salon.", + "User %(user_id)s does not exist": "L’utilisateur %(user_id)s n’existe pas", "Unknown server error": "Erreur de serveur inconnue", "Show a reminder to enable Secure Message Recovery in encrypted rooms": "Afficher un rappel pour activer la récupération de messages sécurisée dans les salons chiffrés", "Don't ask again": "Ne plus me demander", @@ -952,23 +952,23 @@ "Invalid identity server discovery response": "Réponse non valide lors de la découverte du serveur d'identité", "General failure": "Erreur générale", "New Recovery Method": "Nouvelle méthode de récupération", - "If you didn't set the new recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.": "Si vous n'avez pas activé de nouvelle méthode de récupération, un attaquant essaye peut-être d'accéder à votre compte. Changez immédiatement le mot de passe de votre compte et configurez une nouvelle méthode de récupération dans les paramètres.", + "If you didn't set the new recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.": "Si vous n’avez pas activé de nouvelle méthode de récupération, un attaquant essaye peut-être d’accéder à votre compte. Changez immédiatement le mot de passe de votre compte et configurez une nouvelle méthode de récupération dans les paramètres.", "Set up Secure Messages": "Configurer les messages sécurisés", "Go to Settings": "Aller aux paramètres", "Straight rows of keys are easy to guess": "Les suites de touches sont faciles à deviner", "Short keyboard patterns are easy to guess": "Les répétitions de motif court sur un clavier sont faciles à deviner", - "Custom user status messages": "Messages de statut de l'utilisateur personnalisés", - "Unable to load commit detail: %(msg)s": "Impossible de charger les détails de l'envoi : %(msg)s", + "Custom user status messages": "Messages de statut de l’utilisateur personnalisés", + "Unable to load commit detail: %(msg)s": "Impossible de charger les détails de l’envoi : %(msg)s", "Set a new status...": "Configurer un nouveau statut…", "Clear status": "Effacer le statut", "Unrecognised address": "Adresse non reconnue", - "User %(user_id)s may or may not exist": "L'utilisateur %(user_id)s pourrait exister", + "User %(user_id)s may or may not exist": "L’utilisateur %(user_id)s pourrait exister", "The following users may not exist": "Les utilisateurs suivants pourraient ne pas exister", - "Prompt before sending invites to potentially invalid matrix IDs": "Demander avant d'envoyer des invitations à des identifiants matrix potentiellement non valides", + "Prompt before sending invites to potentially invalid matrix IDs": "Demander avant d’envoyer des invitations à des identifiants matrix potentiellement non valides", "Unable to find profiles for the Matrix IDs listed below - would you like to invite them anyway?": "Impossible de trouver les profils pour les identifiants Matrix listés ci-dessous. Voulez-vous quand même les inviter ?", "Invite anyway and never warn me again": "Inviter quand même et ne plus me prévenir", "Invite anyway": "Inviter quand même", - "Whether or not you're logged in (we don't record your username)": "Si vous êtes connecté ou pas (votre nom d'utilisateur n’est pas enregistré)", + "Whether or not you're logged in (we don't record your username)": "Si vous êtes connecté ou pas (votre nom d’utilisateur n’est pas enregistré)", "Upgrades a room to a new version": "Met à niveau un salon vers une nouvelle version", "Sets the room name": "Définit le nom du salon", "%(senderDisplayName)s upgraded this room.": "%(senderDisplayName)s a mis à niveau ce salon.", @@ -979,15 +979,15 @@ "Enable Emoji suggestions while typing": "Activer la suggestion d’émojis lors de la saisie", "Render simple counters in room header": "Afficher des compteurs simples dans l’en-tête des salons", "Show a placeholder for removed messages": "Afficher les messages supprimés", - "Show join/leave messages (invites/kicks/bans unaffected)": "Afficher les messages d'arrivée et de départ (les invitations/expulsions/bannissements ne sont pas concernés)", - "Show avatar changes": "Afficher les changements d'avatar", - "Show display name changes": "Afficher les changements de nom affiché", - "Show avatars in user and room mentions": "Afficher les avatars dans les mentions d'utilisateur et de salon", + "Show join/leave messages (invites/kicks/bans unaffected)": "Afficher les messages d’arrivée et de départ (les invitations/expulsions/bannissements ne sont pas concernés)", + "Show avatar changes": "Afficher les changements d’avatar", + "Show display name changes": "Afficher les changements de nom d’affichage", + "Show avatars in user and room mentions": "Afficher les avatars dans les mentions d’utilisateur et de salon", "Enable big emoji in chat": "Activer les gros émojis dans les discussions", "Send typing notifications": "Envoyer des notifications de saisie", "Enable Community Filter Panel": "Activer le panneau de filtrage de communauté", - "Messages containing my username": "Messages contenant mon nom d'utilisateur", - "The other party cancelled the verification.": "L'autre personne a annulé la vérification.", + "Messages containing my username": "Messages contenant mon nom d’utilisateur", + "The other party cancelled the verification.": "L’autre personne a annulé la vérification.", "Verified!": "Vérifié !", "You've successfully verified this user.": "Vous avez vérifié cet utilisateur avec succès.", "Secure messages with this user are end-to-end encrypted and not able to be read by third parties.": "Les messages sécurisés avec cet utilisateur sont chiffrés de bout en bout et ne peuvent être lus par d’autres personnes.", @@ -995,16 +995,16 @@ "Verify this user by confirming the following number appears on their screen.": "Vérifier cet utilisateur en confirmant que le nombre suivant apparaît sur leur écran.", "Yes": "Oui", "No": "Non", - "We've sent you an email to verify your address. Please follow the instructions there and then click the button below.": "Nous vous avons envoyé un e-mail pour vérifier votre adresse. Veuillez suivre les instructions qu'il contient puis cliquer sur le bouton ci-dessous.", + "We've sent you an email to verify your address. Please follow the instructions there and then click the button below.": "Nous vous avons envoyé un e-mail pour vérifier votre adresse. Veuillez suivre les instructions qu’il contient puis cliquer sur le bouton ci-dessous.", "Email Address": "Adresse e-mail", - "Backing up %(sessionsRemaining)s keys...": "Sauvegarde de %(sessionsRemaining)s clés...", + "Backing up %(sessionsRemaining)s keys...": "Sauvegarde de %(sessionsRemaining)s clés…", "All keys backed up": "Toutes les clés ont été sauvegardées", "Add an email address to configure email notifications": "Ajouter une adresse e-mail pour configurer les notifications par e-mail", "Unable to verify phone number.": "Impossible de vérifier le numéro de téléphone.", "Verification code": "Code de vérification", "Phone Number": "Numéro de téléphone", "Profile picture": "Image de profil", - "Display Name": "Nom affiché", + "Display Name": "Nom d’affichage", "Room information": "Information du salon", "Internal room ID:": "Identifiant interne du salon :", "Room version": "Version du salon", @@ -1018,37 +1018,37 @@ "Language and region": "Langue et région", "Theme": "Thème", "Account management": "Gestion du compte", - "Deactivating your account is a permanent action - be careful!": "La désactivation du compte est une action permanente. Soyez prudent !", - "For help with using %(brand)s, click here.": "Pour obtenir de l'aide sur l'utilisation de %(brand)s, cliquez ici.", - "For help with using %(brand)s, click here or start a chat with our bot using the button below.": "Pour obtenir de l'aide sur l'utilisation de %(brand)s, cliquez ici ou commencez une discussion avec notre bot en utilisant le bouton ci-dessous.", - "Help & About": "Aide & À propos", - "Bug reporting": "Signalement d'anomalies", + "Deactivating your account is a permanent action - be careful!": "La désactivation du compte est une action définitive. Soyez prudents !", + "For help with using %(brand)s, click here.": "Pour obtenir de l’aide sur l’utilisation de %(brand)s, cliquez ici.", + "For help with using %(brand)s, click here or start a chat with our bot using the button below.": "Pour obtenir de l’aide sur l’utilisation de %(brand)s, cliquez ici ou commencez une discussion avec notre bot en utilisant le bouton ci-dessous.", + "Help & About": "Aide et À propos", + "Bug reporting": "Signalement d’anomalies", "FAQ": "FAQ", "Versions": "Versions", "Preferences": "Préférences", "Composer": "Compositeur", "Room list": "Liste de salons", - "Timeline": "Historique", - "Autocomplete delay (ms)": "Délai pour l'autocomplétion (ms)", + "Timeline": "Fil de discussion", + "Autocomplete delay (ms)": "Retard pour l’autocomplétion (ms)", "Chat with %(brand)s Bot": "Discuter avec le bot %(brand)s", - "Roles & Permissions": "Rôles & Permissions", - "Changes to who can read history will only apply to future messages in this room. The visibility of existing history will be unchanged.": "Les modifications concernant l'accès à l'historique ne s'appliqueront qu'aux futurs messages de ce salon. La visibilité de l'historique existant ne sera pas modifiée.", - "Security & Privacy": "Sécurité & Vie privée", + "Roles & Permissions": "Rôles et permissions", + "Changes to who can read history will only apply to future messages in this room. The visibility of existing history will be unchanged.": "Les modifications concernant l'accès à l’historique ne s'appliqueront qu’aux futurs messages de ce salon. La visibilité de l’historique existant ne sera pas modifiée.", + "Security & Privacy": "Sécurité et vie privée", "Encryption": "Chiffrement", - "Once enabled, encryption cannot be disabled.": "Le chiffrement ne peut pas être désactivé une fois qu'il a été activé.", + "Once enabled, encryption cannot be disabled.": "Le chiffrement ne peut pas être désactivé une fois qu’il a été activé.", "Encrypted": "Chiffré", "Ignored users": "Utilisateurs ignorés", "Bulk options": "Options de groupe", "Key backup": "Sauvegarde de clés", "Missing media permissions, click the button below to request.": "Permissions multimédia manquantes, cliquez sur le bouton ci-dessous pour la demander.", "Request media permissions": "Demander les permissions multimédia", - "Voice & Video": "Voix & Vidéo", - "Main address": "Adresse princpale", + "Voice & Video": "Audio et vidéo", + "Main address": "Adresse principale", "Room avatar": "Avatar du salon", "Room Name": "Nom du salon", "Room Topic": "Sujet du salon", "Join": "Rejoindre", - "Verify this user to mark them as trusted. Trusting users gives you extra peace of mind when using end-to-end encrypted messages.": "Vérifier cet utilisateur pour le marquer comme fiable. Faire confiance aux utilisateurs vous permet d’être serein quand vous utilisez des messages chiffrés de bout en bout.", + "Verify this user to mark them as trusted. Trusting users gives you extra peace of mind when using end-to-end encrypted messages.": "Vérifier cet utilisateur pour le marquer comme fiable. Faire confiance aux utilisateurs vous permet d’être tranquille lorsque vous utilisez des messages chiffrés de bout en bout.", "Waiting for partner to confirm...": "Nous attendons que le partenaire confirme…", "Incoming Verification Request": "Demande de vérification entrante", "Go back": "Revenir en arrière", @@ -1060,7 +1060,7 @@ "Enter the location of your Modular homeserver. It may use your own domain name or be a subdomain of modular.im.": "Saisissez l'emplacement de votre serveur d'accueil Modular. Il peut utiliser votre nom de domaine personnel ou être un sous-domaine de modular.im.", "Server Name": "Nom du serveur", "The username field must not be blank.": "Le champ du nom d'utilisateur ne doit pas être vide.", - "Username": "Nom d'utilisateur", + "Username": "Nom d’utilisateur", "Not sure of your password? Set a new one": "Vous n'êtes pas sûr(e) de votre mot de passe ? Changez-le", "Create your account": "Créer votre compte", "Email (optional)": "E-mail (facultatif)", @@ -1070,20 +1070,20 @@ "Homeserver URL": "URL du serveur d'accueil", "Identity Server URL": "URL du serveur d'identité", "Free": "Gratuit", - "Join millions for free on the largest public server": "Rejoignez des millions d'utilisateurs gratuitement sur le plus grand serveur public", + "Join millions for free on the largest public server": "Rejoignez des millions d’utilisateurs gratuitement sur le plus grand serveur public", "Premium": "Premium", "Premium hosting for organisations Learn more": "Hébergement premium pour les organisations En savoir plus", "Other": "Autre", "Find other public servers or use a custom server": "Trouvez d'autres serveurs publics ou utilisez un serveur personnalisé", "Guest": "Visiteur", - "Sign in instead": "Se connecter", + "Sign in instead": "Se connecter plutôt", "Set a new password": "Définir un nouveau mot de passe", "Create account": "Créer un compte", "Keep going...": "Continuer…", "Starting backup...": "Début de la sauvegarde…", "A new recovery passphrase and key for Secure Messages have been detected.": "Un nouveau mot de passe et une nouvelle clé de récupération pour les messages sécurisés ont été détectés.", "Recovery Method Removed": "Méthode de récupération supprimée", - "If you didn't remove the recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.": "Si vous n'avez pas supprimé la méthode de récupération, un attaquant peut être en train d'essayer d'accéder à votre compte. Modifiez le mot de passe de votre compte et configurez une nouvelle méthode de récupération dans les réglages.", + "If you didn't remove the recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.": "Si vous n’avez pas supprimé la méthode de récupération, un attaquant peut être en train d’essayer d’accéder à votre compte. Modifiez le mot de passe de votre compte et configurez une nouvelle méthode de récupération dans les réglages.", "The file '%(fileName)s' exceeds this homeserver's size limit for uploads": "Le fichier « %(fileName)s » dépasse la taille limite autorisée par ce serveur pour les envois", "Gets or sets the room topic": "Récupère ou définit le sujet du salon", "This room has no topic.": "Ce salon n'a pas de sujet.", @@ -1158,16 +1158,16 @@ "Headphones": "Écouteurs", "Folder": "Dossier", "Pin": "Épingle", - "This homeserver would like to make sure you are not a robot.": "Ce serveur d'accueil veut s'assurer que vous n'êtes pas un robot.", + "This homeserver would like to make sure you are not a robot.": "Ce serveur d’accueil veut s’assurer que vous n’êtes pas un robot.", "Change": "Changer", "Couldn't load page": "Impossible de charger la page", - "This homeserver does not support communities": "Ce serveur d'accueil ne prend pas en charge les communautés", + "This homeserver does not support communities": "Ce serveur d’accueil ne prend pas en charge les communautés", "A verification email will be sent to your inbox to confirm setting your new password.": "Un e-mail de vérification sera envoyé à votre adresse pour confirmer la modification de votre mot de passe.", "Your password has been reset.": "Votre mot de passe a été réinitialisé.", - "This homeserver does not support login using email address.": "Ce serveur d'accueil ne prend pas en charge la connexion avec une adresse e-mail.", - "Registration has been disabled on this homeserver.": "L'inscription a été désactivée sur ce serveur d'accueil.", - "Unable to query for supported registration methods.": "Impossible de demander les méthodes d'inscription prises en charge.", - "Are you sure? You will lose your encrypted messages if your keys are not backed up properly.": "En êtes-vous sûr(e) ? Vous perdrez vos messages chiffrés si vos clés ne sont pas sauvegardées correctement.", + "This homeserver does not support login using email address.": "Ce serveur d’accueil ne prend pas en charge la connexion avec une adresse e-mail.", + "Registration has been disabled on this homeserver.": "L’inscription a été désactivée sur ce serveur d’accueil.", + "Unable to query for supported registration methods.": "Impossible de demander les méthodes d’inscription prises en charge.", + "Are you sure? You will lose your encrypted messages if your keys are not backed up properly.": "En êtes-vous sûr ? Vous perdrez vos messages chiffrés si vos clés ne sont pas sauvegardées correctement.", "Encrypted messages are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.": "Les messages chiffrés sont sécurisés avec un chiffrement de bout en bout. Seuls vous et le(s) destinataire(s) ont les clés pour lire ces messages.", "Restore from Backup": "Restaurer depuis la sauvegarde", "Back up your keys before signing out to avoid losing them.": "Sauvegardez vos clés avant de vous déconnecter pour éviter de les perdre.", @@ -1189,7 +1189,7 @@ "Allow Peer-to-Peer for 1:1 calls": "Autoriser les connexions pair-à-pair pour les appels individuels", "Credits": "Crédits", "If you run into any bugs or have feedback you'd like to share, please let us know on GitHub.": "Si vous avez rencontré des problèmes ou si vous souhaitez partager votre avis, dites-le nous sur GitHub.", - "Changes your display nickname in the current room only": "Change votre nom affiché seulement dans le salon actuel", + "Changes your display nickname in the current room only": "Change votre nom d’affichage seulement dans le salon actuel", "%(senderDisplayName)s enabled flair for %(groups)s in this room.": "%(senderDisplayName)s a activé le badge pour %(groups)s dans ce salon.", "%(senderDisplayName)s disabled flair for %(groups)s in this room.": "%(senderDisplayName)s a désactivé le badge pour %(groups)s dans ce salon.", "%(senderDisplayName)s enabled flair for %(newGroups)s and disabled flair for %(oldGroups)s in this room.": "%(senderDisplayName)s a activé le badge pour %(newGroups)s et désactivé le badge pour %(oldGroups)s dans ce salon.", @@ -1242,7 +1242,7 @@ "This room is running room version , which this homeserver has marked as unstable.": "Ce salon utilise la version , que ce serveur d’accueil a marqué comme instable.", "Upgrading this room will shut down the current instance of the room and create an upgraded room with the same name.": "La mise à niveau du salon désactivera cette instance du salon et créera un salon mis à niveau avec le même nom.", "Failed to revoke invite": "Échec de la révocation de l’invitation", - "Could not revoke the invite. The server may be experiencing a temporary problem or you do not have sufficient permissions to revoke the invite.": "Impossible de révoquer l’invitation. Le serveur subi peut-être un problème temporaire ou vous n’avez pas la permission de révoquer l’invitation.", + "Could not revoke the invite. The server may be experiencing a temporary problem or you do not have sufficient permissions to revoke the invite.": "Impossible de révoquer l’invitation. Le serveur subit peut-être un problème temporaire ou vous n’avez pas la permission de révoquer l’invitation.", "Revoke invite": "Révoquer l’invitation", "Invited by %(sender)s": "Invité par %(sender)s", "Maximize apps": "Maximiser les applications", @@ -1295,11 +1295,11 @@ "Join the conversation with an account": "Rejoindre la conversation avec un compte", "Sign Up": "S’inscrire", "Sign In": "Se connecter", - "You were kicked from %(roomName)s by %(memberName)s": "Vous avez été expulsé(e) de %(roomName)s par %(memberName)s", + "You were kicked from %(roomName)s by %(memberName)s": "Vous avez été expulsé de %(roomName)s par %(memberName)s", "Reason: %(reason)s": "Motif : %(reason)s", "Forget this room": "Oublier ce salon", "Re-join": "Revenir", - "You were banned from %(roomName)s by %(memberName)s": "Vous avez été banni(e) de %(roomName)s par %(memberName)s", + "You were banned from %(roomName)s by %(memberName)s": "Vous avez été banni de %(roomName)s par %(memberName)s", "Something went wrong with your invite to %(roomName)s": "Une erreur est survenue avec votre invitation à %(roomName)s", "You can only join it with a working invite.": "Vous ne pouvez le rejoindre qu’avec une invitation fonctionnelle.", "You can still join it because this is a public room.": "Vous pouvez quand même le rejoindre car c’est un salon public.", @@ -1307,7 +1307,7 @@ "Try to join anyway": "Essayer de le rejoindre quand même", "Do you want to chat with %(user)s?": "Voulez-vous discuter avec %(user)s ?", "Do you want to join %(roomName)s?": "Voulez-vous rejoindre %(roomName)s ?", - " invited you": " vous a invité(e)", + " invited you": " vous a invité", "You're previewing %(roomName)s. Want to join it?": "Ceci est un aperçu de %(roomName)s. Voulez-vous rejoindre le salon ?", "%(roomName)s can't be previewed. Do you want to join it?": "Vous ne pouvez pas avoir d’aperçu de %(roomName)s. Voulez-vous rejoindre le salon ?", "This room doesn't exist. Are you sure you're at the right place?": "Ce salon n’existe pas. Êtes-vous vraiment au bon endroit ?", @@ -1315,7 +1315,7 @@ "%(errcode)s was returned while trying to access the room. If you think you're seeing this message in error, please submit a bug report.": "%(errcode)s a été retourné en essayant d’accéder au salon. Si vous pensez que vous ne devriez pas voir ce message, veuillez soumettre un rapport d’anomalie.", "This room has already been upgraded.": "Ce salon a déjà été mis à niveau.", "reacted with %(shortName)s": "ont réagi avec %(shortName)s", - "edited": "édité", + "edited": "modifié", "Rotate Left": "Tourner à gauche", "Rotate Right": "Tourner à droite", "View Servers in Room": "Voir les serveurs dans le salon", @@ -1336,10 +1336,10 @@ "Homeserver URL does not appear to be a valid Matrix homeserver": "L’URL du serveur d’accueil ne semble pas être un serveur d’accueil Matrix valide", "Invalid base_url for m.identity_server": "base_url pour m.identity_server non valide", "Identity server URL does not appear to be a valid identity server": "L’URL du serveur d’identité ne semble pas être un serveur d’identité valide", - "Show hidden events in timeline": "Afficher les évènements cachés dans l’historique", + "Show hidden events in timeline": "Afficher les évènements cachés dans le fil de discussion", "Your profile": "Votre profil", "Add room": "Ajouter un salon", - "Edit message": "Éditer le message", + "Edit message": "Modifier le message", "No homeserver URL provided": "Aucune URL de serveur d’accueil fournie", "Unexpected error resolving homeserver configuration": "Une erreur inattendue est survenue pendant la résolution de la configuration du serveur d’accueil", "Unable to validate homeserver/identity server": "Impossible de valider le serveur d’accueil/d’identité", @@ -1369,8 +1369,8 @@ "Upload all": "Tout envoyer", "Your new account (%(newAccountId)s) is registered, but you're already logged into a different account (%(loggedInUserId)s).": "Votre nouveau compte (%(newAccountId)s) est créé, mais vous êtes déjà connecté avec un autre compte (%(loggedInUserId)s).", "Continue with previous account": "Continuer avec le compte précédent", - "Edited at %(date)s. Click to view edits.": "Édité à %(date)s. Cliquer pour voir les éditions.", - "Message edits": "Éditions du message", + "Edited at %(date)s. Click to view edits.": "Modifié le %(date)s. Cliquer pour voir les modifications.", + "Message edits": "Modifications du message", "Upgrading this room requires closing down the current instance of the room and creating a new room in its place. To give room members the best possible experience, we will:": "La mise à niveau de ce salon nécessite de fermer l’instance actuelle du salon et de créer un nouveau salon à la place. Pour fournir la meilleure expérience possible aux utilisateurs, nous allons :", "Loading room preview": "Chargement de l’aperçu du salon", "Show all": "Tout afficher", @@ -1379,12 +1379,12 @@ "%(severalUsers)smade no changes %(count)s times|one": "%(severalUsers)s n’ont fait aucun changement", "%(oneUser)smade no changes %(count)s times|other": "%(oneUser)s n’a fait aucun changement %(count)s fois", "%(oneUser)smade no changes %(count)s times|one": "%(oneUser)s n’a fait aucun changement", - "Resend edit": "Renvoyer l’édition", + "Resend edit": "Renvoyer la modification", "Resend %(unsentCount)s reaction(s)": "Renvoyer %(unsentCount)s réaction(s)", "Resend removal": "Renvoyer la suppression", "Your homeserver doesn't seem to support this feature.": "Il semble que votre serveur d’accueil ne prenne pas en charge cette fonctionnalité.", "Changes your avatar in all rooms": "Change votre avatar dans tous les salons", - "You're signed out": "Vous êtes déconnecté(e)", + "You're signed out": "Vous êtes déconnecté", "Clear all data": "Supprimer toutes les données", "Removing…": "Suppression…", "Failed to re-authenticate due to a homeserver problem": "Échec de la ré-authentification à cause d’un problème du serveur d’accueil", @@ -1397,8 +1397,8 @@ "Please tell us what went wrong or, better, create a GitHub issue that describes the problem.": "Dites-nous ce qui s’est mal passé ou, encore mieux, créez un rapport d’erreur sur GitHub qui décrit le problème.", "Identity Server": "Serveur d’identité", "Find others by phone or email": "Trouver d’autres personnes par téléphone ou e-mail", - "Be found by phone or email": "Être trouvé(e) par téléphone ou e-mail", - "Use bots, bridges, widgets and sticker packs": "Utiliser des robots, des passerelles, des widgets ou des packs de stickers", + "Be found by phone or email": "Être trouvé par téléphone ou e-mail", + "Use bots, bridges, widgets and sticker packs": "Utiliser des robots, des passerelles, des widgets ou des jeux d’autocollants", "Terms of Service": "Conditions de service", "Service": "Service", "Summary": "Résumé", @@ -1418,14 +1418,14 @@ "Unable to share phone number": "Impossible de partager le numéro de téléphone", "Please enter verification code sent via text.": "Veuillez saisir le code de vérification envoyé par SMS.", "Discovery options will appear once you have added a phone number above.": "Les options de découverte apparaîtront quand vous aurez ajouté un numéro de téléphone ci-dessus.", - "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains.": "Un message textuel a été envoyé à +%(msisdn)s. Saisissez le code de vérification qu’il contient.", + "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains.": "Un SMS a été envoyé à +%(msisdn)s. Saisissez le code de vérification qu’il contient.", "Command Help": "Aide aux commandes", "No identity server is configured: add one in server settings to reset your password.": "Aucun serveur d’identité n’est configuré : ajoutez-en un dans les paramètres du serveur pour réinitialiser votre mot de passe.", "Identity Server URL must be HTTPS": "L’URL du serveur d’identité doit être en HTTPS", "Not a valid Identity Server (status code %(code)s)": "Serveur d’identité non valide (code de statut %(code)s)", "Could not connect to Identity Server": "Impossible de se connecter au serveur d’identité", "Checking server": "Vérification du serveur", - "Disconnect from the identity server ?": "Se déconnecter du serveur d’identité ?", + "Disconnect from the identity server ?": "Se déconnecter du serveur d’identité  ?", "Disconnect": "Se déconnecter", "Identity Server (%(server)s)": "Serveur d’identité (%(server)s)", "You are currently using to discover and be discoverable by existing contacts you know. You can change your identity server below.": "Vous utilisez actuellement pour découvrir et être découvert par des contacts existants que vous connaissez. Vous pouvez changer votre serveur d’identité ci-dessous.", @@ -1487,9 +1487,9 @@ "We recommend that you remove your email addresses and phone numbers from the identity server before disconnecting.": "Nous recommandons que vous supprimiez vos adresses e-mail et vos numéros de téléphone du serveur d’identité avant de vous déconnecter.", "Disconnect anyway": "Se déconnecter quand même", "Error changing power level requirement": "Erreur de changement du critère de rang", - "An error occurred changing the room's power level requirements. Ensure you have sufficient permissions and try again.": "Une erreur est survenue lors de la modification des critères de rang du salon. Vérifiez que vous avez les bonnes permissions et réessayez.", + "An error occurred changing the room's power level requirements. Ensure you have sufficient permissions and try again.": "Une erreur est survenue lors de la modification des critères de rang du salon. Vérifiez que vous avez les permissions nécessaires et réessayez.", "No recent messages by %(user)s found": "Aucun message récent de %(user)s n’a été trouvé", - "Try scrolling up in the timeline to see if there are any earlier ones.": "Essayez de faire défiler l’historique vers le haut pour voir s’il y en a de plus anciens.", + "Try scrolling up in the timeline to see if there are any earlier ones.": "Essayez de faire défiler le fil de discussion vers le haut pour voir s’il y en a de plus anciens.", "Remove recent messages by %(user)s": "Supprimer les messages récents de %(user)s", "You are about to remove %(count)s messages by %(user)s. This cannot be undone. Do you wish to continue?|other": "Vous êtes sur le point de supprimer %(count)s messages de %(user)s. Ça ne peut pas être annulé. Voulez-vous continuer ?", "For a large amount of messages, this might take some time. Please don't refresh your client in the meantime.": "Pour un grand nombre de messages, cela peut prendre du temps. N’actualisez pas votre client pendant ce temps.", @@ -1557,11 +1557,11 @@ "DuckDuckGo Results": "Résultats de DuckDuckGo", "Quick Reactions": "Réactions rapides", "Frequently Used": "Utilisé fréquemment", - "Smileys & People": "Émoticônes & personnes", - "Animals & Nature": "Animaux & nature", - "Food & Drink": "Nourriture & boisson", + "Smileys & People": "Visages et personnes", + "Animals & Nature": "Animaux et nature", + "Food & Drink": "Nourriture et boisson", "Activities": "Activités", - "Travel & Places": "Voyage & lieux", + "Travel & Places": "Voyages et lieux", "Objects": "Objets", "Symbols": "Symboles", "Flags": "Drapeaux", @@ -1608,10 +1608,10 @@ "User rules": "Règles d’utilisateur", "You have not ignored anyone.": "Vous n’avez ignoré personne.", "You are currently ignoring:": "Vous ignorez actuellement :", - "You are not subscribed to any lists": "Vous n’êtes inscrit(e) à aucune liste", + "You are not subscribed to any lists": "Vous n’êtes inscrit à aucune liste", "Unsubscribe": "Se désinscrire", "View rules": "Voir les règles", - "You are currently subscribed to:": "Vous êtes actuellement inscrit(e) à :", + "You are currently subscribed to:": "Vous êtes actuellement inscrit à :", "⚠ These settings are meant for advanced users.": "⚠ Ces paramètres sont prévus pour les utilisateurs avancés.", "Ignoring people is done through ban lists which contain rules for who to ban. Subscribing to a ban list means the users/servers blocked by that list will be hidden from you.": "Ignorer les gens est possible grâce à des listes de bannissement qui contiennent des règles sur les personnes à bannir. L’inscription à une liste de bannissement signifie que les utilisateurs/serveurs bloqués par cette liste seront cachés pour vous.", "Personal ban list": "Liste de bannissement personnelle", @@ -1646,8 +1646,8 @@ "Connecting to integration manager...": "Connexion au gestionnaire d’intégrations…", "Cannot connect to integration manager": "Impossible de se connecter au gestionnaire d’intégrations", "The integration manager is offline or it cannot reach your homeserver.": "Le gestionnaire d’intégrations est hors ligne ou il ne peut pas joindre votre serveur d’accueil.", - "Use an Integration Manager (%(serverName)s) to manage bots, widgets, and sticker packs.": "Utilisez un gestionnaire d’intégrations (%(serverName)s) pour gérer les bots, les widgets et les packs de stickers.", - "Use an Integration Manager to manage bots, widgets, and sticker packs.": "Utilisez un gestionnaire d’intégrations pour gérer les bots, les widgets et les packs de stickers.", + "Use an Integration Manager (%(serverName)s) to manage bots, widgets, and sticker packs.": "Utilisez un gestionnaire d’intégrations (%(serverName)s) pour gérer les robots, les widgets et les jeux d’autocollants.", + "Use an Integration Manager to manage bots, widgets, and sticker packs.": "Utilisez un gestionnaire d’intégrations pour gérer les robots, les widgets et les jeux d’autocollants.", "Integration Managers receive configuration data, and can modify widgets, send room invites, and set power levels on your behalf.": "Les gestionnaires d’intégrations reçoivent les données de configuration et peuvent modifier les widgets, envoyer des invitations aux salons et définir les rangs à votre place.", "Failed to connect to integration manager": "Échec de la connexion au gestionnaire d’intégrations", "Widgets do not use message encryption.": "Les widgets n’utilisent pas le chiffrement des messages.", @@ -1664,8 +1664,8 @@ "Manage integrations": "Gérer les intégrations", "Verification Request": "Demande de vérification", "Match system theme": "S’adapter au thème du système", - "%(senderName)s placed a voice call.": "%(senderName)s a passé un appel vocal.", - "%(senderName)s placed a voice call. (not supported by this browser)": "%(senderName)s a passé un appel vocal. (non pris en charge par ce navigateur)", + "%(senderName)s placed a voice call.": "%(senderName)s a passé un appel audio.", + "%(senderName)s placed a voice call. (not supported by this browser)": "%(senderName)s a passé un appel audio. (non pris en charge par ce navigateur)", "%(senderName)s placed a video call.": "%(senderName)s a passé un appel vidéo.", "%(senderName)s placed a video call. (not supported by this browser)": "%(senderName)s a passé un appel vidéo. (non pris en charge par ce navigateur)", "Clear notifications": "Vider les notifications", @@ -1731,7 +1731,7 @@ "Close preview": "Fermer l’aperçu", "Language Dropdown": "Sélection de la langue", "Country Dropdown": "Sélection du pays", - "The message you are trying to send is too large.": "Le message que vous essayez d’envoyer est trop gros.", + "The message you are trying to send is too large.": "Le message que vous essayez d’envoyer est trop grand.", "Help": "Aide", "Show more": "En voir plus", "Recent Conversations": "Conversations récentes", @@ -1759,9 +1759,9 @@ "about a day from now": "dans un jour environ", "%(num)s days from now": "dans %(num)s jours", "Failed to invite the following users to chat: %(csvUsers)s": "Échec de l’invitation des utilisateurs suivants à discuter : %(csvUsers)s", - "We couldn't create your DM. Please check the users you want to invite and try again.": "Impossible de créer votre message direct. Vérifiez les utilisateurs que vous souhaitez inviter et réessayez.", + "We couldn't create your DM. Please check the users you want to invite and try again.": "Impossible de créer votre conversation privée. Vérifiez quels utilisateurs que vous souhaitez inviter et réessayez.", "Something went wrong trying to invite the users.": "Une erreur est survenue en essayant d’inviter les utilisateurs.", - "We couldn't invite those users. Please check the users you want to invite and try again.": "Impossible d’inviter ces utilisateurs. Vérifiez les utilisateurs que vous souhaitez inviter et réessayez.", + "We couldn't invite those users. Please check the users you want to invite and try again.": "Impossible d’inviter ces utilisateurs. Vérifiez quels utilisateurs que vous souhaitez inviter et réessayez.", "Recently Direct Messaged": "Messages directs récents", "Start": "Commencer", "Session verified": "Session vérifiée", @@ -1805,7 +1805,7 @@ "%(brand)s is securely caching encrypted messages locally for them to appear in search results:": "%(brand)s met en cache les messages chiffrés localement et de manière sécurisée pour qu’ils apparaissent dans les résultats de recherche :", "Space used:": "Espace utilisé :", "Indexed messages:": "Messages indexés :", - "Waiting for %(displayName)s to verify…": "Nous attendons que %(displayName)s vérifie…", + "Waiting for %(displayName)s to verify…": "En attente de la vérification de %(displayName)s…", "They match": "Ils correspondent", "They don't match": "Ils ne correspondent pas", "This bridge was provisioned by .": "Cette passerelle a été fournie par .", @@ -1815,7 +1815,7 @@ "This room is bridging messages to the following platforms. Learn more.": "Ce salon transmet les messages vers les plateformes suivantes. En savoir plus.", "This room isn’t bridging messages to any platforms. Learn more.": "Ce salon ne transmet les messages à aucune plateforme. En savoir plus.", "Bridges": "Passerelles", - "Waiting for %(displayName)s to accept…": "Nous attendons que %(displayName)s accepte…", + "Waiting for %(displayName)s to accept…": "En attente d’acceptation par %(displayName)s…", "Your messages are secured and only you and the recipient have the unique keys to unlock them.": "Vos messages sont sécurisés et seuls vous et le destinataire avez les clés uniques pour les déchiffrer.", "Your messages are not secure": "Vos messages ne sont pas sécurisés", "One of the following may be compromised:": "Un des éléments suivants est peut-être compromis :", @@ -1843,8 +1843,8 @@ "Never send encrypted messages to unverified sessions from this session": "Ne jamais envoyer de messages chiffrés aux sessions non vérifiées depuis cette session", "Never send encrypted messages to unverified sessions in this room from this session": "Ne jamais envoyer des messages chiffrés aux sessions non vérifiées dans ce salon depuis cette session", "To be secure, do this in person or use a trusted way to communicate.": "Pour être sûr, faites cela en personne ou utilisez un moyen de communication fiable.", - "Changing password will currently reset any end-to-end encryption keys on all sessions, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Changer votre mot de passe réinitialisera toutes les clés de chiffrement sur toutes les sessions, ce qui rendra l’historique de vos messages illisible, sauf si vous exportez d’abord vos clés de chiffrement et si vous les réimportez ensuite. Dans l’avenir, ce processus sera amélioré.", - "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "Votre compte à une identité de signature croisée dans le coffre secret, mais cette session ne lui fait pas encore confiance.", + "Changing password will currently reset any end-to-end encryption keys on all sessions, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Changer votre mot de passe réinitialisera toutes les clés de chiffrement sur toutes les sessions, ce qui rendra l’historique de vos messages illisible, sauf si vous exportez d’abord vos clés de chiffrement et si vous les réimportez ensuite. À l’avenir, ce processus sera amélioré.", + "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "Votre compte a une identité de signature croisée dans le coffre secret, mais cette session ne lui fait pas encore confiance.", "in memory": "en mémoire", "Your homeserver does not support session management.": "Votre serveur d’accueil ne prend pas en charge la gestion de session.", "Unable to load session list": "Impossible de charger la liste de sessions", @@ -1872,7 +1872,7 @@ "A session's public name is visible to people you communicate with": "Le nom public d’une session est visible par les personnes avec lesquelles vous communiquez", "This user has not verified all of their sessions.": "Cet utilisateur n’a pas vérifié toutes ses sessions.", "You have verified this user. This user has verified all of their sessions.": "Vous avez vérifié cet utilisateur. Cet utilisateur a vérifié toutes ses sessions.", - "Someone is using an unknown session": "Quelqu'un utilise une session inconnue", + "Someone is using an unknown session": "Quelqu’un utilise une session inconnue", "Mod": "Modo", "Your key share request has been sent - please check your other sessions for key share requests.": "Votre demande de partage de clé a été envoyée − vérifiez les demandes de partage de clé sur vos autres sessions.", "Key share requests are sent to your other sessions automatically. If you rejected or dismissed the key share request on your other sessions, click here to request the keys for this session again.": "Les demandes de partage de clé sont envoyées à vos autres sessions automatiquement. Si vous avez rejeté ou ignoré la demande de partage de clé sur vos autres sessions, cliquez ici pour redemander les clés pour cette session.", @@ -1894,7 +1894,7 @@ "Session name": "Nom de la session", "Session key": "Clé de la session", "Verifying this user will mark their session as trusted, and also mark your session as trusted to them.": "Vérifier cet utilisateur marquera sa session comme fiable, et marquera aussi votre session comme fiable pour lui.", - "Verify this device to mark it as trusted. Trusting this device gives you and other users extra peace of mind when using end-to-end encrypted messages.": "Vérifier cet appareil le marquera comme fiable. Faire confiance à cette appareil vous permettra à vous et aux autres utilisateurs d’être sereins lors de l’utilisation de messages chiffrés.", + "Verify this device to mark it as trusted. Trusting this device gives you and other users extra peace of mind when using end-to-end encrypted messages.": "Vérifier cet appareil le marquera comme fiable. Faire confiance à cette appareil vous permettra à vous et aux autres utilisateurs d’être tranquilles lors de l’utilisation de messages chiffrés.", "Verifying this device will mark it as trusted, and users who have verified with you will trust this device.": "Vérifier cet appareil le marquera comme fiable, et les utilisateurs qui ont vérifié avec vous feront confiance à cet appareil.", "This will allow you to return to your account after signing out, and sign in on other sessions.": "Cela vous permettra de revenir sur votre compte après vous être déconnecté, et de vous connecter sur d’autres sessions.", "Without completing security on this session, it won’t have access to encrypted messages.": "Sans compléter la sécurité sur cette session, elle n’aura pas accès aux messages chiffrés.", @@ -1954,10 +1954,10 @@ "Accepting…": "Acceptation…", "Accepting …": "Acceptation…", "Declining …": "Refus…", - "Your account is not secure": "Votre compte n'est pas sécurisé", + "Your account is not secure": "Votre compte n’est pas sûr", "Your password": "Votre mot de passe", - "This session, or the other session": "Cette session, ou l'autre session", - "The internet connection either session is using": "La connection internet de l'une des sessions", + "This session, or the other session": "Cette session, ou l’autre session", + "The internet connection either session is using": "La connexion internet de l’une des sessions", "We recommend you change your password and recovery key in Settings immediately": "Nous vous recommandons de changer votre mot de passe et la clé de récupération dans Paramètres dès que possible", "Sign In or Create Account": "Se connecter ou créer un compte", "Use your account or create a new one to continue.": "Utilisez votre compte ou créez en un pour continuer.", @@ -1981,7 +1981,7 @@ "%(senderName)s changed the addresses for this room.": "%(senderName)s a changé les adresses de ce salon.", "Support adding custom themes": "Autoriser l’ajout de thèmes personnalisés", "Invalid theme schema.": "Schéma du thème invalide.", - "Error downloading theme information.": "Une erreur s'est produite en téléchargeant les informations du thème.", + "Error downloading theme information.": "Une erreur s’est produite en téléchargeant les informations du thème.", "Theme added!": "Thème ajouté !", "Custom theme URL": "URL personnalisée pour le thème", "Add theme": "Ajouter le thème", @@ -1989,7 +1989,7 @@ "Local address": "Adresse locale", "Published Addresses": "Adresses publiées", "Published addresses can be used by anyone on any server to join your room. To publish an address, it needs to be set as a local address first.": "Les adresses publiées peuvent être utilisées par n’importe qui sur n’importe quel serveur pour rejoindre votre salon. Pour publier une adresse, elle doit d’abord être définie comme adresse locale.", - "Other published addresses:": "Autres adresses publiques :", + "Other published addresses:": "Autres adresses publiées :", "No other published addresses yet, add one below": "Aucune autre adresse n’est publiée, ajoutez-en une ci-dessous", "New published address (e.g. #alias:server)": "Nouvelles adresses publiées (par ex. #alias:serveur)", "Local Addresses": "Adresses locales", @@ -2032,9 +2032,9 @@ "Toggle Italics": "(Dés)activer l’italique", "Toggle Quote": "(Dés)activer la citation", "New line": "Nouvelle ligne", - "Navigate recent messages to edit": "Parcourir les messages récents pour éditer", + "Navigate recent messages to edit": "Parcourir les messages récents pour modifier", "Jump to start/end of the composer": "Sauter au début/à la fin du compositeur", - "Toggle microphone mute": "(Dés)activer la sourdine du micro", + "Toggle microphone mute": "Activer/désactiver le micro", "Toggle video on/off": "Dés(activer) la vidéo", "Jump to room search": "Sauter à la recherche de salon", "Navigate up/down in the room list": "Parcourir avec haut/bas dans la liste des salons", @@ -2042,7 +2042,7 @@ "Collapse room list section": "Réduire la section de la liste des salons", "Expand room list section": "Développer la section de la liste des salons", "Clear room list filter field": "Effacer le champ de filtrage de la liste des salons", - "Scroll up/down in the timeline": "Défiler vers le haut/le bas dans l’historique", + "Scroll up/down in the timeline": "Défiler vers le haut/le bas dans le fil de discussion", "Toggle the top left menu": "Afficher/masquer le menu en haut à gauche", "Close dialog or context menu": "Fermer le dialogue ou le menu contextuel", "Activate selected button": "Activer le bouton sélectionné", @@ -2061,8 +2061,8 @@ "Confirm this user's session by comparing the following with their User Settings:": "Confirmez la session de cet utilisateur en comparant ceci avec ses paramètres utilisateur :", "If they don't match, the security of your communication may be compromised.": "S’ils ne correspondent pas, la sécurité de vos communications est peut-être compromise.", "Navigate composer history": "Explorer l’historique du compositeur", - "Previous/next unread room or DM": "Salon ou message direct non lu précédent/suivant", - "Previous/next room or DM": "Salon ou message direct précédent/suivant", + "Previous/next unread room or DM": "Salon ou conversation privée non lu précédent/suivant", + "Previous/next room or DM": "Salon ou conversation privée précédent/suivant", "Toggle right panel": "Afficher/masquer le panneau de droite", "Manually verify all remote sessions": "Vérifier manuellement toutes les sessions à distance", "Self signing private key:": "Clé privée d’auto-signature :", @@ -2094,7 +2094,7 @@ "Delete sessions": "Supprimer les sessions", "Confirm the emoji below are displayed on both sessions, in the same order:": "Confirmez que les émojis ci-dessous s’affichent dans les deux sessions et dans le même ordre :", "Verify this session by confirming the following number appears on its screen.": "Vérifiez cette session en confirmant que le nombre suivant s’affiche sur son écran.", - "Waiting for your other session, %(deviceName)s (%(deviceId)s), to verify…": "Dans l’attente que votre autre session, %(deviceName)s (%(deviceId)s), vérifie…", + "Waiting for your other session, %(deviceName)s (%(deviceId)s), to verify…": "En attente de la vérification depuis votre autre session, %(deviceName)s (%(deviceId)s)…", "From %(deviceName)s (%(deviceId)s)": "Depuis %(deviceName)s (%(deviceId)s)", "Waiting for you to accept on your other session…": "Dans l’attente que vous acceptiez dans votre autre session…", "Almost there! Is your other session showing the same shield?": "On y est presque ! Est-ce que votre autre session affiche le même bouclier ?", @@ -2128,7 +2128,7 @@ "Delete sessions|other": "Supprimer les sessions", "Delete sessions|one": "Supprimer la session", "Enable end-to-end encryption": "Activer le chiffrement de bout en bout", - "You can’t disable this later. Bridges & most bots won’t work yet.": "Vous ne pourrez pas le désactiver plus tard. Les passerelles et la plupart des bots ne fonctionneront pas pour le moment.", + "You can’t disable this later. Bridges & most bots won’t work yet.": "Vous ne pourrez pas le désactiver plus tard. Les passerelles et la plupart des robots ne fonctionneront pas pour le moment.", "Failed to set topic": "Échec du changement de sujet", "Command failed": "La commande a échoué", "Could not find user in room": "Impossible de trouver l’utilisateur dans le salon", @@ -2151,7 +2151,7 @@ "Secure your backup with a recovery passphrase": "Protégez votre sauvegarde avec une phrase secrète de récupération", "Can't load this message": "Impossible de charger ce message", "Submit logs": "Envoyer les journaux", - "Reminder: Your browser is unsupported, so your experience may be unpredictable.": "Rappel : Votre navigateur n’est pas pris en charge donc votre expérience pourrait être imprévisible.", + "Reminder: Your browser is unsupported, so your experience may be unpredictable.": "Rappel : Votre navigateur n’est pas pris en charge donc votre expérience pourrait être aléatoire.", "Unable to upload": "Envoi impossible", "Currently indexing: %(currentRoom)s": "En train d’indexer : %(currentRoom)s", "Please supply a widget URL or embed code": "Veuillez fournir l’URL ou le code d’intégration du widget", @@ -2164,15 +2164,15 @@ "Where you’re logged in": "Où vous vous êtes connecté", "Manage the names of and sign out of your sessions below or verify them in your User Profile.": "Gérez les noms et déconnectez-vous de vos sessions ci-dessous ou vérifiez-les dans votre profil utilisateur.", "Review where you’re logged in": "Vérifier où vous vous êtes connecté", - "New login. Was this you?": "Nouvelle connexion. Était-ce vous ?", - "Verify all your sessions to ensure your account & messages are safe": "Vérifiez toutes vos sessions pour vous assurer que votre compte et messages sont sécurisés", + "New login. Was this you?": "Nouvelle connexion. Était-ce vous ?", + "Verify all your sessions to ensure your account & messages are safe": "Vérifiez toutes vos sessions pour vous assurer que votre compte et messages ne sont pas compromis", "Verify the new login accessing your account: %(name)s": "Vérifiez la nouvelle connexion accédant à votre compte : %(name)s", "Restoring keys from backup": "Restauration des clés depuis la sauvegarde", "Fetching keys from server...": "Récupération des clés depuis le serveur…", "%(completed)s of %(total)s keys restored": "%(completed)s clés sur %(total)s restaurées", "Keys restored": "Clés restaurées", "Successfully restored %(sessionCount)s keys": "%(sessionCount)s clés ont été restaurées avec succès", - "You signed in to a new session without verifying it:": "Vous vous êtes connecté·e à une nouvelle session sans la vérifier :", + "You signed in to a new session without verifying it:": "Vous vous êtes connecté à une nouvelle session sans la vérifier :", "Verify your other session using one of the options below.": "Vérifiez votre autre session en utilisant une des options ci-dessous.", "Invite someone using their name, username (like ), email address or share this room.": "Invitez quelqu’un en utilisant leur nom, leur nom d’utilisateur (comme ), leur adresse e-mail ou partagez ce salon.", "Message deleted": "Message supprimé", @@ -2188,9 +2188,9 @@ "Click the button below to confirm setting up encryption.": "Cliquez sur le bouton ci-dessous pour confirmer la configuration du chiffrement.", "QR Code": "Code QR", "Dismiss read marker and jump to bottom": "Ignorer le signet de lecture et aller en bas", - "Jump to oldest unread message": "Aller au plus vieux message non lu", + "Jump to oldest unread message": "Aller au plus ancien message non lu", "Upload a file": "Envoyer un fichier", - "IRC display name width": "Largeur du nom affiché IRC", + "IRC display name width": "Largeur du nom d’affichage IRC", "Create room": "Créer un salon", "Font scaling": "Mise à l’échelle de la police", "Font size": "Taille de la police", @@ -2239,7 +2239,7 @@ "Switch to light mode": "Passer au mode clair", "Switch to dark mode": "Passer au mode sombre", "Switch theme": "Changer le thème", - "Security & privacy": "Sécurité & vie privée", + "Security & privacy": "Sécurité et vie privée", "All settings": "Tous les paramètres", "Feedback": "Commentaire", "No recently visited rooms": "Aucun salon visité récemment", @@ -2278,8 +2278,8 @@ "You left the call": "Vous avez quitté l’appel", "%(senderName)s left the call": "%(senderName)s a quitté l’appel", "Call ended": "Appel terminé", - "You started a call": "Vous avez démarré un appel", - "%(senderName)s started a call": "%(senderName)s a démarré un appel", + "You started a call": "Vous avez commencé un appel", + "%(senderName)s started a call": "%(senderName)s a commencé un appel", "Waiting for answer": "En attente d’une réponse", "%(senderName)s is calling": "%(senderName)s appelle", "You created the room": "Vous avez créé le salon", @@ -2337,10 +2337,10 @@ "Use your Security Key to continue.": "Utilisez votre clé de sécurité pour continuer.", "Safeguard against losing access to encrypted messages & data by backing up encryption keys on your server.": "Protection afin d’éviter de perdre l’accès aux messages et données chiffrés en sauvegardant les clés de chiffrement sur votre serveur.", "Generate a Security Key": "Générer une clé de sécurité", - "We’ll generate a Security Key for you to store somewhere safe, like a password manager or a safe.": "Nous génèrerons une clé de sécurité que vous devrez stocker dans un endroit sûr, comme un gestionnaire de mots de passe ou un coffre.", + "We’ll generate a Security Key for you to store somewhere safe, like a password manager or a safe.": "Nous générerons une clé de sécurité que vous devrez stocker dans un endroit sûr, comme un gestionnaire de mots de passe ou un coffre.", "Enter a Security Phrase": "Saisir une phrase de sécurité", - "Use a secret phrase only you know, and optionally save a Security Key to use for backup.": "Utilisez une phrase secrète que vous êtes seul·e à connaître et enregistrez éventuellement une clé de sécurité à utiliser pour la sauvegarde.", - "Enter a security phrase only you know, as it’s used to safeguard your data. To be secure, you shouldn’t re-use your account password.": "Saisissez une phrase de sécurité que vous seul·e connaissez, car elle est utilisée pour protéger vos données. Pour plus de sécurité, vous ne devriez pas réutiliser le mot de passe de votre compte.", + "Use a secret phrase only you know, and optionally save a Security Key to use for backup.": "Utilisez une phrase secrète que vous êtes seul à connaître et enregistrez éventuellement une clé de sécurité à utiliser pour la sauvegarde.", + "Enter a security phrase only you know, as it’s used to safeguard your data. To be secure, you shouldn’t re-use your account password.": "Saisissez une phrase de sécurité que vous seul connaissez, car elle est utilisée pour protéger vos données. Pour plus de sécurité, vous ne devriez pas réutiliser le mot de passe de votre compte.", "Store your Security Key somewhere safe, like a password manager or a safe, as it’s used to safeguard your encrypted data.": "Stockez votre clé de sécurité dans un endroit sûr, comme un gestionnaire de mots de passe ou un coffre, car elle est utilisée pour protéger vos données chiffrées.", "If you cancel now, you may lose encrypted messages & data if you lose access to your logins.": "Si vous annulez maintenant, vous pourriez perdre vos messages et données chiffrés si vous perdez l’accès à vos identifiants.", "You can also set up Secure Backup & manage your keys in Settings.": "Vous pouvez aussi configurer la sauvegarde sécurisée et gérer vos clés depuis les paramètres.", @@ -2353,7 +2353,7 @@ "Riot is now Element!": "Riot est maintenant Element !", "Learn More": "Plus d'infos", "Enable experimental, compact IRC style layout": "Disposition expérimentale compacte style IRC", - "Incoming voice call": "Appel vocal entrant", + "Incoming voice call": "Appel audio entrant", "Incoming video call": "Appel vidéo entrant", "Incoming call": "Appel entrant", "Make this room low priority": "Définir ce salon en priorité basse", @@ -2367,13 +2367,13 @@ "Favourited": "Favori", "Forget Room": "Oublier le salon", "This room is public": "Ce salon est public", - "Edited at %(date)s": "Édité le %(date)s", - "Click to view edits": "Cliquez pour éditer", + "Edited at %(date)s": "Modifié le %(date)s", + "Click to view edits": "Cliquez pour voir les modifications", "Go to Element": "Aller à Element", "We’re excited to announce Riot is now Element!": "Nous sommes heureux d'annoncer que Riot est désormais Element !", "Learn more at element.io/previously-riot": "Plus d'infos sur element.io/previously-riot", "Search rooms": "Chercher des salons", - "User menu": "Menu d'utilisateur", + "User menu": "Menu d’utilisateur", "%(brand)s Web": "%(brand)s Web", "%(brand)s Desktop": "%(brand)s Desktop", "%(brand)s iOS": "%(brand)s iOS", @@ -2385,20 +2385,20 @@ "The person who invited you already left the room, or their server is offline.": "La personne vous ayant invité a déjà quitté le salon, ou son serveur est hors-ligne.", "* %(senderName)s %(emote)s": "* %(senderName)s %(emote)s", "Change notification settings": "Modifier les paramètres de notification", - "Show message previews for reactions in DMs": "Afficher la prévisualisation des messages pour les réactions dans les messages privés", + "Show message previews for reactions in DMs": "Afficher l’aperçu des messages pour les réactions dans les conversations privées", "Show message previews for reactions in all rooms": "Afficher la prévisualisation des messages pour les réactions dans tous les salons", "Enable advanced debugging for the room list": "Activer le débogage avancé pour la liste de salons", - "Uploading logs": "Téléversement des journaux", + "Uploading logs": "Envoi des journaux", "Downloading logs": "Téléchargement des journaux", "Your server isn't responding to some requests.": "Votre serveur ne répond pas à certaines requêtes.", "Cross-signing and secret storage are ready for use.": "La signature croisée et le coffre secret sont prêt à l'emploi.", "Cross-signing is ready for use, but secret storage is currently not being used to backup your keys.": "La signature croisée est prête à l'emploi, mais le coffre secret n'est pas actuellement utilisé pour sauvegarder vos clés.", - "Master private key:": "Clé privée maîtresse :", + "Master private key:": "Clé privée maîtresse :", "%(brand)s can't securely cache encrypted messages locally while running in a web browser. Use %(brand)s Desktop for encrypted messages to appear in search results.": "%(brand)s ne peut actuellement mettre en cache vos messages chiffrés localement de manière sécurisée via le navigateur Web. Utilisez %(brand)s Desktop pour que les messages chiffrés apparaissent dans vos résultats de recherche.", "There are advanced notifications which are not shown here.": "Des notifications avancées ne sont pas affichées ici.", "ready": "prêt", - "The operation could not be completed": "L'opération n'a pas pu être terminée", - "Failed to save your profile": "Erreur lors de l'enregistrement du profile", + "The operation could not be completed": "L’opération n’a pas pu être terminée", + "Failed to save your profile": "Erreur lors de l’enregistrement du profil", "Unknown App": "Application inconnue", "%(senderName)s declined the call.": "%(senderName)s a refusé l’appel.", "(an error occurred)": "(une erreur est survenue)", @@ -2408,39 +2408,39 @@ "Prepends ( ͡° ͜ʖ ͡°) to a plain-text message": "Ajoute ( ͡° ͜ʖ ͡°) en préfixe du message", "This will end the conference for everyone. Continue?": "Ceci arrêtera la téléconférence pour tout le monde. Continuer ?", "End conference": "Finir la téléconférence", - "The call was answered on another device.": "L’appel a été répondu sur un autre appareil.", + "The call was answered on another device.": "L’appel a été décroché sur un autre appareil.", "Answered Elsewhere": "Répondu autre-part", "The call could not be established": "L’appel n’a pas pu être établi", "The other party declined the call.": "Le correspondant a décliné l’appel.", "Call Declined": "Appel rejeté", "Ignored attempt to disable encryption": "Essai de désactiver le chiffrement ignoré", - "Add users and servers you want to ignore here. Use asterisks to have %(brand)s match any characters. For example, @bot:* would ignore all users that have the name 'bot' on any server.": "Ajoutez les utilisateurs et les serveurs que vous voulez ignorer ici. Utilisez des astérisques pour que %(brand)s comprenne tous les caractères. Par exemple, @bot:* va ignorer tous les utilisateurs ayant le nom 'bot' sur n'importe quel serveur.", + "Add users and servers you want to ignore here. Use asterisks to have %(brand)s match any characters. For example, @bot:* would ignore all users that have the name 'bot' on any server.": "Ajoutez les utilisateurs et les serveurs que vous voulez ignorer ici. Utilisez des astérisques pour que %(brand)s comprenne tous les caractères. Par exemple, @bot:* va ignorer tous les utilisateurs ayant le nom « bot » sur n’importe quel serveur.", "not ready": "pas prêt", - "Secret storage:": "Coffre secret :", - "Backup key cached:": "Clé de sauvegarde mise en cache :", - "Backup key stored:": "Clé de sauvegarde enregistrée :", + "Secret storage:": "Coffre secret :", + "Backup key cached:": "Clé de sauvegarde mise en cache :", + "Backup key stored:": "Clé de sauvegarde enregistrée :", "Back up your encryption keys with your account data in case you lose access to your sessions. Your keys will be secured with a unique Recovery Key.": "Sauvegarder vos clés de chiffrement avec les données de votre compte dans le cas où vous perdez l'accès à vos sessions. Vos clés seront sécurisées grâce à une unique clé de récupération.", - "Backup version:": "Version de la sauvegarde :", - "You might have configured them in a client other than %(brand)s. You cannot tune them in %(brand)s but they still apply.": "Vous les avez peut-être configurés dans un autre client que %(brand)s. Vous ne pouvez pas les configurer dans %(brand)s mais ils s'appliquent quand même.", + "Backup version:": "Version de la sauvegarde :", + "You might have configured them in a client other than %(brand)s. You cannot tune them in %(brand)s but they still apply.": "Vous les avez peut-être configurés dans un autre client que %(brand)s. Vous ne pouvez pas les configurer dans %(brand)s mais ils s’appliquent quand même.", "not found in storage": "non trouvé dans le coffre", - "Cross-signing is not set up.": "La signature croisée n'est pas configurée.", + "Cross-signing is not set up.": "La signature croisée n’est pas configurée.", "Cross-signing is ready for use.": "La signature croisée est prête à être utilisée.", "Offline encrypted messaging using dehydrated devices": "Messagerie hors-ligne chiffrée utilisant des appareils déshydratés", - "Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Prototype de communautés v2. Requiert un serveur d'accueil compatible. Très expérimental - à utiliser avec précaution.", - "Safeguard against losing access to encrypted messages & data": "Sécurité contre la perte d'accès aux messages & données chiffrées", + "Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Prototype de communautés v2. Requiert un serveur d’accueil compatible. Très expérimental - à utiliser avec précaution.", + "Safeguard against losing access to encrypted messages & data": "Sécurité contre la perte d’accès aux messages et données chiffrées", "(their device couldn't start the camera / microphone)": "(leur appareil ne peut pas démarrer la caméra/le microphone)", "🎉 All servers are banned from participating! This room can no longer be used.": "🎉 Tous les serveurs ont été bannis ! Ce salon ne peut plus être utilisé.", "What's the name of your community or team?": "Quel est le nom de votre communauté ou équipe ?", "You can change this later if needed.": "Vous pouvez modifier ceci après si besoin.", - "Use this when referencing your community to others. The community ID cannot be changed.": "Utilisez ceci lorsque vous faites référence à votre communauté aux autres. L'identifiant de la communauté ne peut pas être modifié.", + "Use this when referencing your community to others. The community ID cannot be changed.": "Utilisez ceci lorsque vous faites référence à votre communauté aux autres. L’identifiant de la communauté ne peut pas être modifié.", "There was an error creating your community. The name may be taken or the server is unable to process your request.": "Une erreur est survenue lors de la création de votre communauté. Le nom est peut-être pris ou le serveur ne peut pas exécuter votre requête.", "This version of %(brand)s does not support searching encrypted messages": "Cette version de %(brand)s ne prend pas en charge la recherche dans les messages chiffrés", - "This version of %(brand)s does not support viewing some encrypted files": "Cette version de %(brand)s ne prend pas en charge l'affichage de certains fichiers chiffrés", + "This version of %(brand)s does not support viewing some encrypted files": "Cette version de %(brand)s ne prend pas en charge l’affichage de certains fichiers chiffrés", "Use the Desktop app to search encrypted messages": "Utilisez une Application de bureau pour rechercher dans tous les messages chiffrés", "Use the Desktop app to see all encrypted files": "Utilisez une Application de bureau pour voir tous les fichiers chiffrés", "Join the conference at the top of this room": "Rejoignez la téléconférence en haut de ce salon", - "Join the conference from the room information card on the right": "Rejoignez la téléconférence à partir de la carte d'informations sur la droite", - "Set the name of a font installed on your system & %(brand)s will attempt to use it.": "Définissez le nom d'une police de caractères installée sur votre système et %(brand)s essaiera de l'utiliser.", + "Join the conference from the room information card on the right": "Rejoignez la téléconférence à partir de la carte d’informations sur la droite", + "Set the name of a font installed on your system & %(brand)s will attempt to use it.": "Définissez le nom d’une police de caractères installée sur votre système et %(brand)s essaiera de l’utiliser.", "Create a room in %(communityName)s": "Créer un salon dans %(communityName)s", "An image will help people identify your community.": "Une image aidera les personnes à identifier votre communauté.", "Add image (optional)": "Ajouter une image (facultatif)", @@ -2463,32 +2463,32 @@ "%(count)s people|one": "%(count)s personne", "About": "À propos", "Not encrypted": "Non-chiffré", - "Add widgets, bridges & bots": "Ajouter des widgets, ponts et bots", - "Edit widgets, bridges & bots": "Modifier les widgets, ponts et bots", + "Add widgets, bridges & bots": "Ajouter des widgets, passerelles et robots", + "Edit widgets, bridges & bots": "Modifier les widgets, passerelles et robots", "Widgets": "Widgets", - "Unpin a widget to view it in this panel": "Dépingler un widget pour l'afficher dans ce panneau", + "Unpin a widget to view it in this panel": "Dépingler un widget pour l’afficher dans ce panneau", "Unpin": "Dépingler", - "You can only pin up to %(count)s widgets|other": "Vous ne pouvez épingler que jusqu'à %(count)s widgets", + "You can only pin up to %(count)s widgets|other": "Vous ne pouvez épingler que jusqu’à %(count)s widgets", "Room Info": "Informations sur le salon", "%(count)s results|one": "%(count)s résultat", "%(count)s results|other": "%(count)s résultats", - "Explore all public rooms": "Explorer tous les salons publiques", - "Can't see what you’re looking for?": "Vous ne voyez pas ce que vous cherchez ?", + "Explore all public rooms": "Explorer tous les salons publics", + "Can't see what you’re looking for?": "Vous ne trouvez pas ce que vous cherchez ?", "Custom Tag": "Étiquette personnalisée", - "Explore public rooms": "Explorer les salons publiques", + "Explore public rooms": "Explorer les salons publics", "Explore community rooms": "Explorer les salons de la communauté", "Show Widgets": "Afficher les widgets", "Hide Widgets": "Masquer les widgets", - "Remove messages sent by others": "Supprimer les messages envoyés par d'autres", + "Remove messages sent by others": "Supprimer les messages envoyés par d’autres", "Privacy": "Vie privée", "Secure Backup": "Sauvegarde sécurisée", "Algorithm:": "Algorithme :", "Set up Secure Backup": "Configurer la sauvegarde sécurisée", "%(brand)s Android": "%(brand)s Android", - "Community and user menu": "Menu de la communauté et de l'utilisateur", - "User settings": "Paramètres de l'utilisateur", + "Community and user menu": "Menu de la communauté et de l’utilisateur", + "User settings": "Paramètres de l’utilisateur", "Community settings": "Paramètres de la communauté", - "Failed to find the general chat for this community": "Impossible de trouver le chat général de cette communauté", + "Failed to find the general chat for this community": "Impossible de trouver la discussion générale de cette communauté", "Starting microphone...": "Allumage du microphone …", "Starting camera...": "Allumage de la caméra ...", "Call connecting...": "Connexion à l'appel …", @@ -2496,10 +2496,10 @@ "Explore rooms in %(communityName)s": "Explorer les salons dans %(communityName)s", "You have no visible notifications in this room.": "Vous n'avez pas de notification visible dans ce salon.", "You’re all caught up": "Vous êtes à jour", - "You do not have permission to create rooms in this community.": "Vous n'avez pas la permission de créer des salons dans cette communauté.", + "You do not have permission to create rooms in this community.": "Vous n’avez pas la permission de créer des salons dans cette communauté.", "Cannot create rooms in this community": "Impossible de créer des salons dans cette communauté", "Create community": "Créer une communauté", - "Attach files from chat or just drag and drop them anywhere in a room.": "Envoyez des fichiers depuis le chat ou juste glissez et déposez-les n'importe où dans le salon.", + "Attach files from chat or just drag and drop them anywhere in a room.": "Envoyez des fichiers depuis la discussion ou glissez et déposez-les n’importe où dans le salon.", "No files visible in this room": "Aucun fichier visible dans ce salon", "Enter the location of your Element Matrix Services homeserver. It may use your own domain name or be a subdomain of element.io.": "Entrez l'emplacement de votre serveur d'accueil Element Matrix Services. Cela peut utiliser votre propre nom de domaine ou être un sous-domaine de element.io.", "You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use %(brand)s with an existing Matrix account on a different homeserver.": "Vous pouvez utiliser l'option de serveur personnalisé pour vous connecter à d'autres serveurs Matrix en spécifiant une URL de serveur d'accueil différente. Cela vous permet d'utiliser %(brand)s avec un compte Matrix existant sur un serveur d'accueil différent.", @@ -2509,61 +2509,61 @@ "Revoke permissions": "Révoquer les permissions", "Take a picture": "Prendre une photo", "Unable to set up keys": "Impossible de configurer les clés", - "Recent changes that have not yet been received": "Changements récents qui n'ont pas encore été reçus", - "The server is not configured to indicate what the problem is (CORS).": "Le n'est n'est pas configuré pour indiquer quel est le problème (CORS).", + "Recent changes that have not yet been received": "Changements récents qui n’ont pas encore été reçus", + "The server is not configured to indicate what the problem is (CORS).": "Le serveur n’est pas configuré pour indiquer quel est le problème (CORS).", "A connection error occurred while trying to contact the server.": "Une erreur de connexion est survenue en essayant de contacter le serveur.", - "Your area is experiencing difficulties connecting to the internet.": "Votre emplacement connaît des difficultés à se connecter à Internet.", + "Your area is experiencing difficulties connecting to the internet.": "Votre secteur connaît des difficultés à se connecter à Internet.", "The server has denied your request.": "Le serveur a refusé votre requête.", "The server is offline.": "Le serveur est éteint.", "A browser extension is preventing the request.": "Une extension du navigateur bloque la requête.", "Your firewall or anti-virus is blocking the request.": "Votre pare-feu ou votre antivirus bloque la requête.", "The server (%(serverName)s) took too long to respond.": "Le serveur (%(serverName)s) met trop de temps à répondre.", - "Your server isn't responding to some of your requests. Below are some of the most likely reasons.": "Votre serveur ne répond pas à certaines requêtes. Vous trouverez ci-dessus quelles sont la plupart des raisons.", + "Your server isn't responding to some of your requests. Below are some of the most likely reasons.": "Votre serveur ne répond pas à certaines requêtes. Vous trouverez ci-dessus quelles en sont les raisons probables.", "Server isn't responding": "Le serveur ne répond pas", "You're all caught up.": "Vous êtes à jour.", "Data on this screen is shared with %(widgetDomain)s": "Les données sur cet écran sont partagées avec %(widgetDomain)s", "Modal Widget": "Fenêtre de widget", - "Invite someone using their name, username (like ) or share this room.": "Invitez quelqu'un à partir de son nom, pseudo (comme ) ou partagez ce salon.", - "This won't invite them to %(communityName)s. To invite someone to %(communityName)s, click here": "Cela ne va pas l'inviter à %(communityName)s. Pour inviter quelqu'un à %(communityName)s, cliquez ici", - "Start a conversation with someone using their name or username (like ).": "Démarrer une conversation avec quelqu'un en utilisant son nom ou son pseudo (comme ).", + "Invite someone using their name, username (like ) or share this room.": "Invitez quelqu’un à partir de son nom, pseudo (comme ) ou partagez ce salon.", + "This won't invite them to %(communityName)s. To invite someone to %(communityName)s, click here": "Cela ne va pas l’inviter à %(communityName)s. Pour inviter quelqu’un à %(communityName)s, cliquez ici", + "Start a conversation with someone using their name or username (like ).": "Commencer une conversation privée avec quelqu’un en utilisant son nom ou son pseudo (comme ).", "May include members not in %(communityName)s": "Peut inclure des membres qui ne sont pas dans %(communityName)s", "Send feedback": "Envoyer un commentaire", - "PRO TIP: If you start a bug, please submit debug logs to help us track down the problem.": "CONSEIL : si vous reportez un bug, merci d'envoyer les logs de débogage pour nous aider à identifier le problème.", - "Please view existing bugs on Github first. No match? Start a new one.": "Merci de regarder d'abord les bugs déjà répertoriés sur Github. Pas de résultat ? Reportez un nouveau bug.", - "Report a bug": "Reporter un bug", + "PRO TIP: If you start a bug, please submit debug logs to help us track down the problem.": "CONSEIL : si vous rapportez un bug, merci d’envoyer les journaux de débogage pour nous aider à identifier le problème.", + "Please view existing bugs on Github first. No match? Start a new one.": "Merci de regarder d’abord les bugs déjà répertoriés sur Github. Pas de résultat ? Rapportez un nouveau bug.", + "Report a bug": "Rapporter un bug", "There are two ways you can provide feedback and help us improve %(brand)s.": "Il y a deux manières pour que vous puissiez faire vos retour et nous aider à améliorer %(brand)s.", "Comment": "Commentaire", "Add comment": "Ajouter un commentaire", - "Please go into as much detail as you like, so we can track down the problem.": "Merci d'ajouter le plus de détails possible, pour que nous puissions mieux identifier le problème.", + "Please go into as much detail as you like, so we can track down the problem.": "Merci d’ajouter le plus de détails possible, pour que nous puissions mieux identifier le problème.", "Tell us below how you feel about %(brand)s so far.": "Dites-nous ci-dessous quel est votre ressenti à propos de %(brand)s jusque là.", "Rate %(brand)s": "Noter %(brand)s", "Feedback sent": "Commentaire envoyé", "Update community": "Modifier la communauté", "There was an error updating your community. The server is unable to process your request.": "Une erreur est survenue lors de la mise à jour de votre communauté. Le serveur est incapable de traiter votre requête.", - "Block anyone not part of %(serverName)s from ever joining this room.": "Bloque n'importe qui qui n'est pas membre de %(serverName)s de rejoindre ce salon.", - "You might disable this if the room will be used for collaborating with external teams who have their own homeserver. This cannot be changed later.": "Vous devriez le déactiver si le salon est utilisé pour collaborer avec des équipes externes qui ont leur propre serveur d'accueil. Ce ne peut pas être changé plus tard.", - "You might enable this if the room will only be used for collaborating with internal teams on your homeserver. This cannot be changed later.": "Vous devriez l'activer si le salon n'est utilisé que pour collaborer avec des équipes internes sur votre serveur d'accueil. Ce ne peut pas être changé plus tard.", - "Your server requires encryption to be enabled in private rooms.": "Votre serveur requiert d'activer le chiffrement dans les salons privés.", - "Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone in this community.": "Les salons privés ne peuvent être trouvés et rejoints seulement par invitation. Les salons publics peut être trouvés et rejoints par n'importe qui dans cette communauté.", - "Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone.": "Les salons privés ne peuvent être trouvés et rejoints seulement par invitation. Les salons publics peut être trouvés et rejoints par n'importe qui.", - "Start a new chat": "Commencer une nouvelle discussion", + "Block anyone not part of %(serverName)s from ever joining this room.": "Empêche n’importe qui n’étant pas membre de %(serverName)s de rejoindre ce salon.", + "You might disable this if the room will be used for collaborating with external teams who have their own homeserver. This cannot be changed later.": "Vous devriez le déactiver si le salon est utilisé pour collaborer avec des équipes externes qui ont leur propre serveur d’accueil. Ceci ne peut pas être changé plus tard.", + "You might enable this if the room will only be used for collaborating with internal teams on your homeserver. This cannot be changed later.": "Vous devriez l’activer si le salon n’est utilisé que pour collaborer avec des équipes internes sur votre serveur d’accueil. Ceci ne peut pas être changé plus tard.", + "Your server requires encryption to be enabled in private rooms.": "Votre serveur impose d’activer le chiffrement dans les salons privés.", + "Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone in this community.": "Les salons privés ne peuvent être trouvés et rejoints seulement par invitation. Les salons publics peut être trouvés et rejoints par n’importe qui dans cette communauté.", + "Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone.": "Les salons privés ne peuvent être trouvés et rejoints seulement par invitation. Les salons publics peut être trouvés et rejoints par n’importe qui.", + "Start a new chat": "Commencer une nouvelle conversation privée", "Add a photo so people know it's you.": "Ajoutez une photo pour que les gens sachent qu’il s’agit de vous.", "%(ssoButtons)s Or %(usernamePassword)s": "%(ssoButtons)s ou %(usernamePassword)s", "Decide where your account is hosted": "Décidez où votre compte est hébergé", - "Go to Home View": "Revenir à la page d'accueil", + "Go to Home View": "Revenir à la page d’accueil", "Use Ctrl + Enter to send a message": "Utilisez Ctrl + Entrée pour envoyer un message", - "%(senderName)s ended the call": "%(senderName)s a terminé l'appel", - "You ended the call": "Vous avez terminé l'appel", - "%(creator)s created this DM.": "%(creator)s a envoyé ce DM.", - "Now, let's help you get started": "Maintenant, commençons à vous initier", + "%(senderName)s ended the call": "%(senderName)s a terminé l’appel", + "You ended the call": "Vous avez terminé l’appel", + "%(creator)s created this DM.": "%(creator)s a créé cette conversation privée.", + "Now, let's help you get started": "Maintenant, initions vous", "Welcome %(name)s": "Bienvenue %(name)s", "Filter rooms and people": "Filtrer des salons et personnes", - "Got an account? Sign in": "Vous avez un compte ? Connectez-vous", - "New here? Create an account": "Nouveau ici ? Créez un compte", - "There was a problem communicating with the homeserver, please try again later.": "Il y a eu un problème lors de la communication avec le serveur d'accueil, veuillez réessayer ultérieurement.", - "New? Create account": "Nouveau ? Créez un compte", - "That username already exists, please try another.": "Ce nom d'utilisateur existe déjà, essayez-en un autre.", - "Already have an account? Sign in here": "Vous avez déjà un compte ? Connectez-vous ici", + "Got an account? Sign in": "Vous avez un compte ? Connectez-vous", + "New here? Create an account": "Nouveau ici ? Créez un compte", + "There was a problem communicating with the homeserver, please try again later.": "Il y a eu un problème lors de la communication avec le serveur d’accueil, veuillez réessayer ultérieurement.", + "New? Create account": "Nouveau ? Créez un compte", + "That username already exists, please try another.": "Ce nom d’utilisateur existe déjà, essayez-en un autre.", + "Already have an account? Sign in here": "Vous avez déjà un compte ? Connectez-vous ici", "Algeria": "Algérie", "Albania": "Albanie", "Åland Islands": "Îles Åland", @@ -2572,7 +2572,7 @@ "United Kingdom": "Royaume-Uni", "You've reached the maximum number of simultaneous calls.": "Vous avez atteint le nombre maximum d’appels en simultané.", "No other application is using the webcam": "Aucune autre application n’est en train d’utiliser la caméra", - "A microphone and webcam are plugged in and set up correctly": "Un microphone et une caméra sont branchées et bien configurés", + "A microphone and webcam are plugged in and set up correctly": "Un microphone et une caméra sont branchés et bien configurés", "Unable to access webcam / microphone": "Impossible d’accéder à la caméra ou au microphone", "Call failed because microphone could not be accessed. Check that a microphone is plugged in and set up correctly.": "La fonction a échoué faute de pouvoir accéder au microphone. Vérifiez qu’un microphone est branché et bien configuré.", "Unable to access microphone": "Impossible d’accéder au microphone", @@ -2594,12 +2594,12 @@ "Angola": "République d’Angola", "Andorra": "Andorre", "American Samoa": "Samoa américaines", - "Invite someone using their name, email address, username (like ) or share this room.": "Invitez quelqu'un via leur nom, e-mail ou nom d'utilisateur (p. ex. ) ou partagez ce salon.", - "Start a conversation with someone using their name, email address or username (like ).": "Commencer une conversation avec quelqu'un via leur nom, e-mail ou nom d'utilisateur (comme par exemple ).", + "Invite someone using their name, email address, username (like ) or share this room.": "Invitez quelqu’un via son nom, e-mail ou pseudo (p. ex. ) ou partagez ce salon.", + "Start a conversation with someone using their name, email address or username (like ).": "Commencer une conversation privée avec quelqu’un via son nom, e-mail ou pseudo (comme par exemple ).", "Too Many Calls": "Trop d’appels", "Permission is granted to use the webcam": "L’autorisation d’accéder à la caméra a été accordée", "Call failed because webcam or microphone could not be accessed. Check that:": "La fonction a échoué faute de pouvoir accéder à la caméra ou au microphone. Vérifiez que :", - "Send stickers to this room as you": "Envoyer des stickers dans ce salon en tant que vous-même", + "Send stickers to this room as you": "Envoyer des autocollants dans ce salon sous votre nom", "Zambia": "Zambie", "Yemen": "Yémen", "Western Sahara": "Sahara occidental", @@ -2827,13 +2827,13 @@ "Bermuda": "Bermudes", "with state key %(stateKey)s": "avec la ou les clés d’état %(stateKey)s", "with an empty state key": "avec une clé d’état vide", - "See when anyone posts a sticker to your active room": "Voir quand n’importe qui envoie un sticker dans le salon actuel", - "See when a sticker is posted in this room": "Voir quand un sticker est envoyé dans ce salon", + "See when anyone posts a sticker to your active room": "Voir quand n’importe qui envoie un autocollant dans le salon actuel", + "See when a sticker is posted in this room": "Voir quand un autocollant est envoyé dans ce salon", "See when the avatar changes in your active room": "Voir quand l’avatar change dans le salon actuel", "Change the avatar of your active room": "Changer l’avatar du salon actuel", "See when the avatar changes in this room": "Voir quand l’avatar change dans ce salon", "Change the avatar of this room": "Changer l’avatar de ce salon", - "Send stickers into your active room": "Envoyer des stickers dans le salon actuel", + "Send stickers into your active room": "Envoyer des autocollants dans le salon actuel", "See when the topic changes in this room": "Voir quand le sujet change dans ce salon", "See when the topic changes in your active room": "Voir quand le sujet change dans le salon actuel", "Change the name of your active room": "Changer le nom du salon actuel", @@ -2841,10 +2841,10 @@ "Change the name of this room": "Changer le nom de ce salon", "Change the topic of your active room": "Changer le sujet dans le salon actuel", "Change the topic of this room": "Changer le sujet de ce salon", - "Send stickers into this room": "Envoyer des stickers dans ce salon", + "Send stickers into this room": "Envoyer des autocollants dans ce salon", "Remain on your screen when viewing another room, when running": "Reste sur votre écran quand vous regardez un autre salon lors de l’appel", - "Takes the call in the current room off hold": "Reprend l’appel en cours dans ce salon", - "Places the call in the current room on hold": "Met l’appel en pause dans ce salon", + "Takes the call in the current room off hold": "Reprend l’appel en attente dans ce salon", + "Places the call in the current room on hold": "Met l’appel dans ce salon en attente", "Prepends (╯°□°)╯︵ ┻━┻ to a plain-text message": "Ajoute (╯°□°)╯︵ ┻━┻ en préfixe du message", "Prepends ┬──┬ ノ( ゜-゜ノ) to a plain-text message": "Ajoute ┬──┬ ノ( ゜-゜ノ) en préfixe du message", "Effects": "Effets", @@ -2857,102 +2857,102 @@ "Send emotes as you in this room": "Envoyer des réactions sous votre nom dans ce salon", "See videos posted to your active room": "Voir les vidéos publiées dans votre salon actif", "See videos posted to this room": "Voir les vidéos publiées dans ce salon", - "Send videos as you in your active room": "Envoie des vidéos en tant que vous-même dans votre salon actuel", - "Send videos as you in this room": "Envoie des vidéos en tant que vous dans ce salon", + "Send videos as you in your active room": "Envoie des vidéos sous votre nom dans votre salon actuel", + "Send videos as you in this room": "Envoie des vidéos sous votre nom dans ce salon", "See images posted to this room": "Voir les images publiées dans ce salon", "See images posted to your active room": "Voir les images publiées dans votre salon actif", "See messages posted to your active room": "Voir les messages publiés dans votre salon actif", "See messages posted to this room": "Voir les messages publiés dans ce salon", - "Send messages as you in your active room": "Envoie des messages en tant que vous-même dans votre salon actif", - "Send messages as you in this room": "Envoie des messages en tant que vous-même dans ce salon", + "Send messages as you in your active room": "Envoie des messages sous votre nom dans votre salon actif", + "Send messages as you in this room": "Envoie des messages sous votre nom dans ce salon", "The %(capability)s capability": "La capacité %(capability)s", "See %(eventType)s events posted to your active room": "Voir les événements %(eventType)s publiés dans votre salon actuel", - "Send %(eventType)s events as you in your active room": "Envoie des événements %(eventType)s en tant que vous-même dans votre salon actuel", + "Send %(eventType)s events as you in your active room": "Envoie des événements %(eventType)s sous votre nom dans votre salon actuel", "See %(eventType)s events posted to this room": "Voir les événements %(eventType)s publiés dans ce salon", - "Send %(eventType)s events as you in this room": "Envoie des événements %(eventType)s en tant que vous-même dans ce salon", - "Send stickers to your active room as you": "Envoie des stickers en tant que vous-même dans le salon actuel", + "Send %(eventType)s events as you in this room": "Envoie des événements %(eventType)s sous votre nom dans ce salon", + "Send stickers to your active room as you": "Envoie des autocollants sous votre nom dans le salon actuel", "Continue with %(ssoButtons)s": "Continuer avec %(ssoButtons)s", - "About homeservers": "À propos des serveurs d'accueils", + "About homeservers": "À propos des serveurs d’accueil", "Learn more": "En savoir plus", - "Use your preferred Matrix homeserver if you have one, or host your own.": "Utilisez votre serveur d'accueil Matrix préféré si vous en avez un, ou hébergez le vôtre.", - "Other homeserver": "Autre serveur d'accueil", - "We call the places where you can host your account ‘homeservers’.": "Nous appelons ‘serveur d'accueils’ les lieux où vous pouvez héberger votre compte.", - "Sign into your homeserver": "Connectez-vous sur votre serveur d'accueil", - "Matrix.org is the biggest public homeserver in the world, so it’s a good place for many.": "Matrix.org est le plus grand serveur d'accueil dans le monde, donc c'est un bon lieu pour beaucoup.", - "Specify a homeserver": "Spécifiez un serveur d'accueil", + "Use your preferred Matrix homeserver if you have one, or host your own.": "Utilisez votre serveur d’accueil Matrix préféré si vous en avez un, ou hébergez le vôtre.", + "Other homeserver": "Autre serveur d’accueil", + "We call the places where you can host your account ‘homeservers’.": "Nous appelons « serveur d’accueil » les lieux où vous pouvez héberger votre compte.", + "Sign into your homeserver": "Connectez-vous sur votre serveur d’accueil", + "Matrix.org is the biggest public homeserver in the world, so it’s a good place for many.": "Matrix.org est le plus grand serveur d’accueil du monde, ce qui en fait un endroit agréable pour le plus grand nombre.", + "Specify a homeserver": "Spécifiez un serveur d’accueil", "Invalid URL": "URL invalide", - "Unable to validate homeserver": "Impossible de valider le serveur d'accueil", - "Just a heads up, if you don't add an email and forget your password, you could permanently lose access to your account.": "Juste une remarque, si vous n'ajoutez pas un email et que vous oubliez votre mot de passe, vous pourriez perdre définitivement l'accés à votre compte.", - "Continuing without email": "Continuer sans email", + "Unable to validate homeserver": "Impossible de valider le serveur d’accueil", + "Just a heads up, if you don't add an email and forget your password, you could permanently lose access to your account.": "Juste une remarque, si vous n'ajoutez pas d’e-mail et que vous oubliez votre mot de passe, vous pourriez perdre définitivement l’accès à votre compte.", + "Continuing without email": "Continuer sans e-mail", "Transfer": "Transférer", - "Failed to transfer call": "N'a pas réussi à transférer l'appel", - "A call can only be transferred to a single user.": "Un appel peut seulement être transféré à un seul utilisateur.", - "Invite by email": "Inviter par email", - "Active Widgets": "Gadgets actifs", + "Failed to transfer call": "Échec du transfert de l’appel", + "A call can only be transferred to a single user.": "Un appel ne peut être transféré qu’à un seul utilisateur.", + "Invite by email": "Inviter par e-mail", + "Active Widgets": "Widgets actifs", "Reason (optional)": "Raison (optionnelle)", "Continue with %(provider)s": "Continuer avec %(provider)s", - "Homeserver": "Serveur d'accueil", - "You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use Element with an existing Matrix account on a different homeserver.": "Vous pouvez utiliser les options de serveur personnalisés pour vous connecter à d'autres serveurs Matrix en spécifiant une URL de serveur d'accueil différente. Celà vous permet d'utiliser Element avec un compte Matrix existant sur un serveur d'accueil différent.", + "Homeserver": "Serveur d’accueil", + "You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use Element with an existing Matrix account on a different homeserver.": "Vous pouvez utiliser les options de serveur personnalisés pour vous connecter à d’autres serveurs Matrix en spécifiant une URL de serveur d’accueil différente. Cela vous permet d’utiliser Element avec un compte Matrix existant sur un serveur d’accueil différent.", "Server Options": "Options serveur", "Messages in this room are end-to-end encrypted. When people join, you can verify them in their profile, just tap on their avatar.": "Les messages ici sont chiffrés de bout en bout. Quand les gens joignent, vous pouvez les vérifier dans leur profil, tapez simplement sur leur avatar.", "Messages here are end-to-end encrypted. Verify %(displayName)s in their profile - tap on their avatar.": "Les messages ici sont chiffrés de bout en bout. Vérifiez %(displayName)s dans leur profil - tapez sur leur avatar.", "Role": "Rôle", - "Use the + to make a new room or explore existing ones below": "Utilisez le + pour créer un nouveau salon ou explorer les existantes ci-dessous", - "This is the start of .": "C'est le début de .", + "Use the + to make a new room or explore existing ones below": "Utilisez le + pour créer un nouveau salon ou explorer ceux existant ci-dessous", + "This is the start of .": "C’est le début de .", "Add a photo, so people can easily spot your room.": "Ajoutez une photo afin que les gens repèrent facilement votre salon.", "%(displayName)s created this room.": "%(displayName)s a créé ce salon.", "You created this room.": "Vous avez créé ce salon.", "Add a topic to help people know what it is about.": "Ajoutez un sujet pour aider les gens à savoir de quoi il est question.", - "Topic: %(topic)s ": "Sujet : %(topic)s ", - "Topic: %(topic)s (edit)": "Sujet : %(topic)s (éditer)", - "This is the beginning of your direct message history with .": "C'est le début de votre historique de messages direct avec .", - "Only the two of you are in this conversation, unless either of you invites anyone to join.": "Seulement vous deux êtes dans cette conversation, à moins que l'un de vous invite quelqu'un à joindre.", + "Topic: %(topic)s ": "Sujet : %(topic)s ", + "Topic: %(topic)s (edit)": "Sujet : %(topic)s (modifier)", + "This is the beginning of your direct message history with .": "C’est le début de votre historique de messages privés avec .", + "Only the two of you are in this conversation, unless either of you invites anyone to join.": "Vous n’êtes que tous les deux dans cette conversation, à moins que l’un de vous invite quelqu’un.", "%(name)s on hold": "%(name)s est en attente", - "Return to call": "Revenir à l'appel", - "Fill Screen": "Remplir l'écran", - "Voice Call": "Appel vocal", + "Return to call": "Revenir à l’appel", + "Fill Screen": "Remplir l’écran", + "Voice Call": "Appel audio", "Video Call": "Appel vidéo", - "%(peerName)s held the call": "%(peerName)s a mis l'appel en pause", - "You held the call Resume": "Vous avez mis l'appel en attente Reprendre", - "You held the call Switch": "Vous avez mis l'appel en attente Basculer", + "%(peerName)s held the call": "%(peerName)s a mis l’appel en attente", + "You held the call Resume": "Vous avez mis l’appel en attente Reprendre", + "You held the call Switch": "Vous avez mis l’appel en attente Basculer", "sends snowfall": "envoie une chute de neige", "Sends the given message with snowfall": "Envoie le message donné avec une chute de neige", - "sends fireworks": "envoie des feux d'artifices", + "sends fireworks": "envoie des feux d’artifices", "Sends the given message with fireworks": "Envoie le message donné avec des feux d'artifices", "sends confetti": "envoie des confettis", "Sends the given message with confetti": "Envoie le message avec des confettis", "Show chat effects": "Montrer les effets cosmétiques du chat", "Use Command + Enter to send a message": "Utilisez Ctrl + Entrée pour envoyer un message", - "Render LaTeX maths in messages": "Formate et affiche les maths format LaTeX dans les messages", + "Render LaTeX maths in messages": "Affiche les formules mathématiques au format LaTeX dans les messages", "New version of %(brand)s is available": "Nouvelle version de %(brand)s disponible", "Update %(brand)s": "Mettre à jour %(brand)s", "Enable desktop notifications": "Activer les notifications sur le bureau", "Don't miss a reply": "Ne ratez pas une réponse", "See %(msgtype)s messages posted to your active room": "Voir les messages de type %(msgtype)s publiés dans le salon actuel", "See %(msgtype)s messages posted to this room": "Voir les messages de type %(msgtype)s publiés dans ce salon", - "Send %(msgtype)s messages as you in this room": "Envoie des messages de type%(msgtype)s en tant que vous-même dans ce salon", - "Send %(msgtype)s messages as you in your active room": "Envoie des messages de type %(msgtype)s en tant que vous-même dans votre salon actif", + "Send %(msgtype)s messages as you in this room": "Envoie des messages de type%(msgtype)s sous votre nom dans ce salon", + "Send %(msgtype)s messages as you in your active room": "Envoie des messages de type %(msgtype)s sous votre nom dans votre salon actif", "See general files posted to your active room": "Voir les fichiers postés dans votre salon actuel", "See general files posted to this room": "Voir les fichiers postés dans ce salon", - "Send general files as you in your active room": "Envoyer des fichiers en tant que vous-même dans votre salon actif", - "Send general files as you in this room": "Envoyer des fichiers en tant que vous-même dans ce salon", + "Send general files as you in your active room": "Envoyer des fichiers sous votre nom dans votre salon actif", + "Send general files as you in this room": "Envoyer des fichiers sous votre nom dans ce salon", "Search (must be enabled)": "Recherche (si activée)", - "This session has detected that your Security Phrase and key for Secure Messages have been removed.": "Cette session a détecté que votre phrase de passe et clé de sécurité pour les messages sécurisés ont été supprimées.", - "A new Security Phrase and key for Secure Messages have been detected.": "Une nouvelle phrase de passe et clé pour les messages sécurisés ont été détectées.", - "Make a copy of your Security Key": "Faire une copie de votre Clé de Sécurité", - "Confirm your Security Phrase": "Confirmez votre phrase de passe", - "Secure your backup with a Security Phrase": "Protégez votre sauvegarde avec une Clé de Sécurité", - "Your Security Key is in your Downloads folder.": "Votre Clé de Sécurité est dans le répertoire Téléchargements.", - "Your Security Key has been copied to your clipboard, paste it to:": "Votre Clé de Sécurité a été copiée dans votre presse-papier, copiez la pour :", - "Your Security Key": "Votre Clé de Sécurité", - "Your Security Key is a safety net - you can use it to restore access to your encrypted messages if you forget your Security Phrase.": "Votre Clé de Sécurité est un filet de sécurité. Vous pouvez l’utiliser pour retrouver l’accès à vos messages chiffrés si vous oubliez votre phrase de passe.", - "Repeat your Security Phrase...": "Répétez votre phrase de passe…", - "Please enter your Security Phrase a second time to confirm.": "Merci de saisir votre phrase de passe une seconde fois pour confirmer.", - "Set up with a Security Key": "Configurer avec une Clé de Sécurité", - "Great! This Security Phrase looks strong enough.": "Super ! Cette phrase de passe a l’air assez solide.", - "We'll store an encrypted copy of your keys on our server. Secure your backup with a Security Phrase.": "Nous avons stocké une copie chiffrée de vos clés sur notre serveur. Sécurisez vos sauvegardes avec une phrase de passe.", - "Use Security Key": "Utiliser la Clé de Sécurité", - "Use Security Key or Phrase": "Utilisez votre Clé de Sécurité ou phrase de passe", + "This session has detected that your Security Phrase and key for Secure Messages have been removed.": "Cette session a détecté que votre phrase secrète et clé de sécurité pour les messages sécurisés ont été supprimées.", + "A new Security Phrase and key for Secure Messages have been detected.": "Une nouvelle phrase secrète et clé de sécurité pour les messages sécurisés ont été détectées.", + "Make a copy of your Security Key": "Faire une copie de votre clé de sécurité", + "Confirm your Security Phrase": "Confirmez votre phrase secrète", + "Secure your backup with a Security Phrase": "Protégez votre sauvegarde avec une clé de sécurité", + "Your Security Key is in your Downloads folder.": "Votre clé de sécurité est dans le répertoire Téléchargements.", + "Your Security Key has been copied to your clipboard, paste it to:": "Votre clé de Sécurité a été copiée dans votre presse-papier, copiez la pour :", + "Your Security Key": "Votre clé de sécurité", + "Your Security Key is a safety net - you can use it to restore access to your encrypted messages if you forget your Security Phrase.": "Votre clé de sécurité est un filet de sécurité. Vous pouvez l’utiliser pour retrouver l’accès à vos messages chiffrés si vous oubliez votre phrase secrète.", + "Repeat your Security Phrase...": "Répétez votre phrase secrète…", + "Please enter your Security Phrase a second time to confirm.": "Merci de saisir votre phrase secrète une seconde fois pour confirmer.", + "Set up with a Security Key": "Configurer avec une clé de sécurité", + "Great! This Security Phrase looks strong enough.": "Super ! Cette phrase secrète a l’air assez solide.", + "We'll store an encrypted copy of your keys on our server. Secure your backup with a Security Phrase.": "Nous allons stocker une copie chiffrée de vos clés sur notre serveur. Protégez vos sauvegardes avec une phrase secrète.", + "Use Security Key": "Utiliser la clé de sécurité", + "Use Security Key or Phrase": "Utilisez votre clé de sécurité ou phrase secrète", "You have no visible notifications.": "Vous n’avez aucune notification visible.", "Upgrade to pro": "Mettre à jour vers pro", "Great, that'll help people know it's you": "Super, ceci aidera des personnes à confirmer qu’il s’agit bien de vous", @@ -2969,19 +2969,19 @@ "A confirmation email has been sent to %(emailAddress)s": "Un e-mail de confirmation a été envoyé à %(emailAddress)s", "Hold": "Mettre en pause", "Resume": "Reprendre", - "If you've forgotten your Security Key you can ": "Si vous avez oublié votre Clé de Sécurité, vous pouvez ", - "Access your secure message history and set up secure messaging by entering your Security Key.": "Accédez à votre historique de messages chiffrés et mettez en place la messagerie sécurisée en entrant votre Clé de Sécurité.", - "Not a valid Security Key": "Clé de Sécurité invalide", - "This looks like a valid Security Key!": "Ça ressemble à une Clé de Sécurité !", + "If you've forgotten your Security Key you can ": "Si vous avez oublié votre clé de sécurité, vous pouvez ", + "Access your secure message history and set up secure messaging by entering your Security Key.": "Accédez à votre historique de messages chiffrés et mettez en place la messagerie sécurisée en entrant votre clé de sécurité.", + "Not a valid Security Key": "Clé de sécurité invalide", + "This looks like a valid Security Key!": "Ça ressemble à une clé de sécurité !", "Enter Security Key": "Saisir la clé de sécurité", - "If you've forgotten your Security Phrase you can use your Security Key or set up new recovery options": "Si vous avez oublié votre phrase de passe vous pouvez utiliser votre Clé de Sécurité ou définir de nouvelles options de récupération", - "Access your secure message history and set up secure messaging by entering your Security Phrase.": "Accédez à votre historique de messages chiffrés et mettez en place la messagerie sécurisée en entrant votre phrase de passe.", - "Enter Security Phrase": "Saisir la phrase de passe", - "Backup could not be decrypted with this Security Phrase: please verify that you entered the correct Security Phrase.": "La sauvegarde n’a pas pu être déchiffrée avec cette phrase de passe : merci de vérifier que vous avez saisi la bonne phrase de passe.", - "Incorrect Security Phrase": "Phrase de passe incorrecte", - "Backup could not be decrypted with this Security Key: please verify that you entered the correct Security Key.": "La sauvegarde n’a pas pu être déchiffrée avec cette Clé de Sécurité : merci de vérifier que vous avez saisi la bonne Clé de Sécurité.", - "Security Key mismatch": "Pas de correspondance entre les Clés de Sécurité", - "Unable to access secret storage. Please verify that you entered the correct Security Phrase.": "Impossible d’accéder à l’espace de stockage sécurisé. Merci de vérifier que vous avez saisi la bonne phrase de passe.", + "If you've forgotten your Security Phrase you can use your Security Key or set up new recovery options": "Si vous avez oublié votre phrase secrète vous pouvez utiliser votre clé de sécurité ou définir de nouvelles options de récupération", + "Access your secure message history and set up secure messaging by entering your Security Phrase.": "Accédez à votre historique de messages chiffrés et mettez en place la messagerie sécurisée en entrant votre phrase secrète.", + "Enter Security Phrase": "Saisir la phrase de secrète", + "Backup could not be decrypted with this Security Phrase: please verify that you entered the correct Security Phrase.": "La sauvegarde n’a pas pu être déchiffrée avec cette phrase secrète : merci de vérifier que vous avez saisi la bonne phrase secrète.", + "Incorrect Security Phrase": "Phrase secrète incorrecte", + "Backup could not be decrypted with this Security Key: please verify that you entered the correct Security Key.": "La sauvegarde n’a pas pu être déchiffrée avec cette clé de sécurité : merci de vérifier que vous avez saisi la bonne clé de sécurité.", + "Security Key mismatch": "Pas de correspondance entre les clés de sécurité", + "Unable to access secret storage. Please verify that you entered the correct Security Phrase.": "Impossible d’accéder à l’espace de stockage sécurisé. Merci de vérifier que vous avez saisi la bonne phrase secrète.", "Invalid Security Key": "Clé de Sécurité invalide", "Wrong Security Key": "Mauvaise Clé de Sécurité", "Remember this": "Mémoriser ceci", @@ -2995,14 +2995,14 @@ "Minimize dialog": "Réduire la modale", "Maximize dialog": "Maximiser la modale", "%(hostSignupBrand)s Setup": "Configuration de %(hostSignupBrand)s", - "You should know": "Vous devriez connaître", + "You should know": "Vous devriez prendre connaissance de", "Privacy Policy": "Politique de confidentialité", "Cookie Policy": "Politique de gestion des cookies", "Learn more in our , and .": "Consultez nos , et .", - "Continuing temporarily allows the %(hostSignupBrand)s setup process to access your account to fetch verified email addresses. This data is not stored.": "Continuer permettra temporairement au processus de configuration de %(hostSignupBrand)s d’accéder à votre compte pour récupérer les adresses email vérifiées. Les données ne sont pas stockées.", + "Continuing temporarily allows the %(hostSignupBrand)s setup process to access your account to fetch verified email addresses. This data is not stored.": "Continuer permettra temporairement au processus de configuration de %(hostSignupBrand)s d’accéder à votre compte pour récupérer les adresses e-mail vérifiées. Les données ne sont pas stockées.", "Failed to connect to your homeserver. Please close this dialog and try again.": "Impossible de vous connecter à votre serveur d’accueil. Merci de fermer cette modale et de réessayer.", "Abort": "Annuler", - "Are you sure you wish to abort creation of the host? The process cannot be continued.": "Êtes-vous sûr de vouloir annuler la création de cet hôte ? Le process ne pourra pas être repris.", + "Are you sure you wish to abort creation of the host? The process cannot be continued.": "Êtes-vous sûr de vouloir annuler la création de cet hôte ? Le processus ne pourra pas être repris.", "Confirm abort of host creation": "Confirmer l’annulation de la création de cet hôte", "There was an error finding this widget.": "Erreur lors de la récupération de ce widget.", "Windows": "Windows", @@ -3010,9 +3010,9 @@ "Share your screen": "Partager votre écran", "Set my room layout for everyone": "Définir ma disposition de salon pour tout le monde", "Open dial pad": "Ouvrir le pavé de numérotation", - "Start a Conversation": "Démarrer une conversation", + "Start a Conversation": "Commencer une conversation", "Recently visited rooms": "Salons visités récemment", - "Back up your encryption keys with your account data in case you lose access to your sessions. Your keys will be secured with a unique Security Key.": "Sauvegardez vos clés de chiffrement et les données de votre compte au casoù vous perdiez l’accès à vos sessions. Vos clés seront sécurisés avec une Clé de Sécurité unique.", + "Back up your encryption keys with your account data in case you lose access to your sessions. Your keys will be secured with a unique Security Key.": "Sauvegardez vos clés de chiffrement et les données de votre compte au cas où vous perdiez l’accès à vos sessions. Vos clés seront sécurisés avec une Clé de Sécurité unique.", "Securely cache encrypted messages locally for them to appear in search results, using %(size)s to store messages from %(rooms)s rooms.|one": "Mettre en cache localement et de manière sécurisée les messages chiffrés pour qu’ils apparaissent dans les résultats de recherche, en utilisant %(size)s pour stocker les messages de %(rooms)s salons.", "Securely cache encrypted messages locally for them to appear in search results, using %(size)s to store messages from %(rooms)s rooms.|other": "Mettre en cache localement et de manière sécurisée les messages chiffrés pour qu’ils apparaissent dans les résultats de recherche, en utilisant %(size)s pour stocker les messages de %(rooms)s salons.", "Channel: ": "Canal : ", @@ -3020,25 +3020,25 @@ "Dial pad": "Pavé de numérotation", "There was an error looking up the phone number": "Erreur lors de la recherche de votre numéro de téléphone", "Unable to look up phone number": "Impossible de trouver votre numéro de téléphone", - "Use Ctrl + F to search": "Utilisez Control + F pour rechercher", + "Use Ctrl + F to search": "Utilisez Ctrl + F pour rechercher", "Use Command + F to search": "Utilisez Commande + F pour rechercher", "Show line numbers in code blocks": "Afficher les numéros de ligne dans les blocs de code", - "Expand code blocks by default": "Dérouler les blocs de code par défaut", - "Show stickers button": "Afficher le bouton stickers", + "Expand code blocks by default": "Développer les blocs de code par défaut", + "Show stickers button": "Afficher le bouton autocollants", "Use app": "Utiliser l’application", "Element Web is experimental on mobile. For a better experience and the latest features, use our free native app.": "Element Web est expérimental sur téléphone. Pour une meilleure expérience et bénéficier des dernières fonctionnalités, utilisez notre application native gratuite.", "Use app for a better experience": "Utilisez une application pour une meilleure expérience", "See text messages posted to your active room": "Voir les messages textuels dans le salon actif", "See text messages posted to this room": "Voir les messages textuels envoyés dans ce salon", - "Send text messages as you in your active room": "Envoyez des messages textuels en tant que vous-même dans le salon actif", - "Send text messages as you in this room": "Envoyez des messages textuels en tant que vous-même dans ce salon", + "Send text messages as you in your active room": "Envoyez des messages textuels sous votre nom dans le salon actif", + "Send text messages as you in this room": "Envoyez des messages textuels sous votre nom dans ce salon", "See when the name changes in your active room": "Suivre les changements de nom dans le salon actif", "Change which room, message, or user you're viewing": "Changer le salon, message, ou la personne que vous visualisez", "Change which room you're viewing": "Changer le salon que vous visualisez", "Remain on your screen while running": "Reste sur votre écran pendant l’exécution", "%(senderName)s has updated the widget layout": "%(senderName)s a mis à jour la disposition du widget", - "Converts the DM to a room": "Transforme le message privé en salon", - "Converts the room to a DM": "Transforme le salon en message privé", + "Converts the DM to a room": "Transforme la conversation privée en salon", + "Converts the room to a DM": "Transforme le salon en conversation privée", "Your homeserver rejected your log in attempt. This could be due to things just taking too long. Please try again. If this continues, please contact your homeserver administrator.": "Votre serveur d’accueil a rejeté la demande de connexion. Ceci pourrait être dû à une connexion qui prend trop de temps. Si cela persiste, merci de contacter l’administrateur de votre serveur d’accueil.", "Your homeserver was unreachable and was not able to log you in. Please try again. If this continues, please contact your homeserver administrator.": "Votre serveur d’accueil n’est pas accessible, nous n’avons pas pu vous connecter. Merci de réessayer. Si cela persiste, merci de contacter l’administrateur de votre serveur d’accueil.", "Try again": "Réessayez", From 88a2bdb119d721ccdfbb19a9590f09545f858069 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 10 Mar 2021 16:47:27 -0700 Subject: [PATCH 87/91] Change read receipt drift to be non-fractional I suspect this is what is causing issues in Firefox for read receipts not falling down. --- src/components/views/rooms/ReadReceiptMarker.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/ReadReceiptMarker.js b/src/components/views/rooms/ReadReceiptMarker.js index ba2b3064fd..0000d767df 100644 --- a/src/components/views/rooms/ReadReceiptMarker.js +++ b/src/components/views/rooms/ReadReceiptMarker.js @@ -156,14 +156,14 @@ export default class ReadReceiptMarker extends React.PureComponent { // then shift to the rightmost column, // and then it will drop down to its resting position // - // XXX: We use a fractional left value to trick velocity-animate into actually animating. + // XXX: We use a small left value to trick velocity-animate into actually animating. // This is a very annoying bug where if it thinks there's no change to `left` then it'll // skip applying it, thus making our read receipt at +14px instead of +0px like it // should be. This does cause a tiny amount of drift for read receipts, however with a // value so small it's not perceived by a user. // Note: Any smaller values (or trying to interchange units) might cause read receipts to // fail to fall down or cause gaps. - startStyles.push({ top: startTopOffset+'px', left: '0.001px' }); + startStyles.push({ top: startTopOffset+'px', left: '1px' }); enterTransitionOpts.push({ duration: bounce ? Math.min(Math.log(Math.abs(startTopOffset)) * 200, 3000) : 300, easing: bounce ? 'easeOutBounce' : 'easeOutCubic', From 4ca838d4c76e8e44fd197face06be179c59388ce Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 11 Mar 2021 11:04:39 +0000 Subject: [PATCH 88/91] Properly gate SpaceRoomView behind labs --- src/components/structures/RoomView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 1961779d0e..f3dff6b217 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -1874,7 +1874,7 @@ export default class RoomView extends React.Component { ); } - if (this.state.room?.isSpaceRoom()) { + if (SettingsStore.getValue("feature_spaces") && this.state.room?.isSpaceRoom()) { return Date: Thu, 11 Mar 2021 11:49:43 +0000 Subject: [PATCH 89/91] Rebuild space previews with new designs --- res/css/structures/_SpaceRoomView.scss | 121 ++++++++++++++++-- res/css/views/elements/_FormButton.scss | 6 + src/components/structures/SpaceRoomView.tsx | 132 ++++++++++++++------ src/i18n/strings/en_EN.json | 10 +- 4 files changed, 214 insertions(+), 55 deletions(-) diff --git a/res/css/structures/_SpaceRoomView.scss b/res/css/structures/_SpaceRoomView.scss index 38310d39a9..60abe36c29 100644 --- a/res/css/structures/_SpaceRoomView.scss +++ b/res/css/structures/_SpaceRoomView.scss @@ -20,6 +20,8 @@ $SpaceRoomViewInnerWidth: 428px; .mx_MainSplit > div:first-child { padding: 80px 60px; flex-grow: 1; + max-height: 100%; + overflow-y: auto; h1 { margin: 0; @@ -69,9 +71,116 @@ $SpaceRoomViewInnerWidth: 428px; } } - .mx_SpaceRoomView_landing { - overflow-y: auto; + .mx_SpaceRoomView_preview { + padding: 32px 24px !important; // override default padding from above + margin: auto; + max-width: 480px; + box-sizing: border-box; + box-shadow: 2px 15px 30px $dialog-shadow-color; + border: 1px solid $input-border-color; + border-radius: 8px; + .mx_SpaceRoomView_preview_inviter { + display: flex; + align-items: center; + margin-bottom: 20px; + font-size: $font-15px; + + > div { + margin-left: 8px; + + .mx_SpaceRoomView_preview_inviter_name { + line-height: $font-18px; + } + + .mx_SpaceRoomView_preview_inviter_mxid { + line-height: $font-24px; + color: $secondary-fg-color; + } + } + } + + > .mx_BaseAvatar_image, + > .mx_BaseAvatar > .mx_BaseAvatar_image { + border-radius: 12px; + } + + h1.mx_SpaceRoomView_preview_name { + margin: 20px 0 !important; // override default margin from above + } + + .mx_SpaceRoomView_preview_info { + color: $tertiary-fg-color; + font-size: $font-15px; + line-height: $font-24px; + margin: 20px 0; + + .mx_SpaceRoomView_preview_info_public, + .mx_SpaceRoomView_preview_info_private { + padding-left: 20px; + position: relative; + + &::before { + position: absolute; + content: ""; + width: 20px; + height: 20px; + top: 0; + left: -2px; + mask-position: center; + mask-repeat: no-repeat; + background-color: $tertiary-fg-color; + } + } + + .mx_SpaceRoomView_preview_info_public::before { + mask-size: 12px; + mask-image: url("$(res)/img/globe.svg"); + } + + .mx_SpaceRoomView_preview_info_private::before { + mask-size: 14px; + mask-image: url("$(res)/img/element-icons/lock.svg"); + } + + .mx_AccessibleButton_kind_link { + color: inherit; + position: relative; + padding-left: 16px; + + &::before { + content: "·"; // visual separator + position: absolute; + left: 6px; + } + } + } + + .mx_SpaceRoomView_preview_topic { + font-size: $font-14px; + line-height: $font-22px; + color: $secondary-fg-color; + margin: 20px 0; + max-height: 160px; + overflow-y: auto; + } + + .mx_SpaceRoomView_preview_joinButtons { + margin-top: 20px; + + .mx_AccessibleButton { + width: 200px; + box-sizing: border-box; + padding: 14px 0; + + & + .mx_AccessibleButton { + margin-left: 20px; + } + } + } + } + + .mx_SpaceRoomView_landing { > .mx_BaseAvatar_image, > .mx_BaseAvatar > .mx_BaseAvatar_image { border-radius: 12px; @@ -128,14 +237,6 @@ $SpaceRoomViewInnerWidth: 428px; font-size: $font-15px; } - .mx_SpaceRoomView_landing_joinButtons { - margin-top: 24px; - - .mx_FormButton { - padding: 8px 22px; - } - } - .mx_SpaceRoomView_landing_adminButtons { margin-top: 32px; diff --git a/res/css/views/elements/_FormButton.scss b/res/css/views/elements/_FormButton.scss index 7ec01f17e6..eda201ff03 100644 --- a/res/css/views/elements/_FormButton.scss +++ b/res/css/views/elements/_FormButton.scss @@ -33,4 +33,10 @@ limitations under the License. color: $notice-primary-color; background-color: $notice-primary-bg-color; } + + &.mx_AccessibleButton_kind_secondary { + color: $secondary-fg-color; + border: 1px solid $secondary-fg-color; + background-color: unset; + } } diff --git a/src/components/structures/SpaceRoomView.tsx b/src/components/structures/SpaceRoomView.tsx index 9bacdd975d..0b0f2a2ac9 100644 --- a/src/components/structures/SpaceRoomView.tsx +++ b/src/components/structures/SpaceRoomView.tsx @@ -94,26 +94,95 @@ const useMyRoomMembership = (room: Room) => { return membership; }; -const SpaceLanding = ({ space, onJoinButtonClicked, onRejectButtonClicked }) => { +const SpacePreview = ({ space, onJoinButtonClicked, onRejectButtonClicked }) => { const cli = useContext(MatrixClientContext); const myMembership = useMyRoomMembership(space); - const joinRule = space.getJoinRule(); - const userId = cli.getUserId(); + let inviterSection; let joinButtons; if (myMembership === "invite") { - joinButtons =
- - - {_t("Decline")} - -
; - } else if (myMembership !== "join" && joinRule === "public") { - joinButtons =
- -
; + const inviteSender = space.getMember(cli.getUserId())?.events.member?.getSender(); + const inviter = inviteSender && space.getMember(inviteSender); + + if (inviteSender) { + inviterSection =
+ +
+
+ { _t(" invites you", {}, { + inviter: () => { inviter.name || inviteSender }, + }) } +
+ { inviter ?
+ { inviteSender } +
: null } +
+
; + } + + joinButtons = <> + + + ; + } else { + joinButtons = } + let visibilitySection; + if (space.getJoinRule() === "public") { + visibilitySection = + { _t("Public space") } + ; + } else { + visibilitySection = + { _t("Private space") } + ; + } + + return
+ { inviterSection } + +

+ +

+
+ { visibilitySection } + + {(count) => count > 0 ? ( + { + defaultDispatcher.dispatch({ + action: Action.SetRightPanelPhase, + phase: RightPanelPhases.RoomMemberList, + refireParams: { space }, + }); + }} + > + { _t("%(count)s members", { count }) } + + ) : null} + +
+ + {(topic, ref) => +
+ { topic } +
+ } +
+
+ { joinButtons } +
+
; +}; + +const SpaceLanding = ({ space }) => { + const cli = useContext(MatrixClientContext); + const myMembership = useMyRoomMembership(space); + const userId = cli.getUserId(); + let inviteButton; if (myMembership === "join" && space.canInvite(userId)) { inviteButton = ( @@ -227,26 +296,7 @@ const SpaceLanding = ({ space, onJoinButtonClicked, onRejectButtonClicked }) => ) : null}
}; - if (myMembership === "invite") { - const inviteSender = space.getMember(userId)?.events.member?.getSender(); - const inviter = inviteSender && space.getMember(inviteSender); - - if (inviteSender) { - return _t(" invited you to ", {}, { - name: tags.name, - inviter: () => inviter - ? - - { inviter.name } - - : - { inviteSender } - , - }) as JSX.Element; - } else { - return _t("You have been invited to ", {}, tags) as JSX.Element; - } - } else if (shouldShowSpaceSettings(cli, space)) { + if (shouldShowSpaceSettings(cli, space)) { if (space.getJoinRule() === "public") { return _t("Your public space ", {}, tags) as JSX.Element; } else { @@ -260,7 +310,6 @@ const SpaceLanding = ({ space, onJoinButtonClicked, onRejectButtonClicked }) =>
- { joinButtons }
{ inviteButton } { addRoomButtons } @@ -548,12 +597,15 @@ export default class SpaceRoomView extends React.PureComponent { private renderBody() { switch (this.state.phase) { case Phase.Landing: - return ; - + if (this.props.space.getMyMembership() === "join") { + return ; + } else { + return ; + } case Phase.PublicCreateRooms: return invites you": " invites you", + "Public space": "Public space", + "Private space": "Private space", + "%(count)s members|other": "%(count)s members", + "%(count)s members|one": "%(count)s member", "Add existing rooms & spaces": "Add existing rooms & spaces", "Default Rooms": "Default Rooms", "Your server does not support showing space hierarchies.": "Your server does not support showing space hierarchies.", - "%(count)s members|other": "%(count)s members", - "%(count)s members|one": "%(count)s member", - " invited you to ": " invited you to ", - "You have been invited to ": "You have been invited to ", "Your public space ": "Your public space ", "Your private space ": "Your private space ", "Welcome to ": "Welcome to ", From c2e05c647e499e60fbda85f5942db7bb7b689403 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 11 Mar 2021 11:56:53 +0000 Subject: [PATCH 90/91] Remove unused common CSS classes --- res/css/_common.scss | 48 -------------------------------------------- 1 file changed, 48 deletions(-) diff --git a/res/css/_common.scss b/res/css/_common.scss index 8ae1cc6641..36a81e6651 100644 --- a/res/css/_common.scss +++ b/res/css/_common.scss @@ -489,54 +489,6 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus { margin-top: 69px; } -.mx_Beta { - color: red; - margin-right: 10px; - position: relative; - top: -3px; - background-color: white; - padding: 0 4px; - border-radius: 3px; - border: 1px solid darkred; - cursor: help; - transition-duration: 200ms; - font-size: smaller; - filter: opacity(0.5); -} - -.mx_Beta:hover { - color: white; - border: 1px solid gray; - background-color: darkred; -} - -.mx_TintableSvgButton { - position: relative; - display: flex; - flex-direction: row; - justify-content: center; - align-content: center; -} - -.mx_TintableSvgButton object { - margin: 0; - padding: 0; - width: 100%; - height: 100%; - max-width: 100%; - max-height: 100%; -} - -.mx_TintableSvgButton span { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - opacity: 0; - cursor: pointer; -} - // username colors // used by SenderProfile & RoomPreviewBar .mx_Username_color1 { From b2d4639ec9a5a768415d37f9aff0a255cc55c0ae Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 11 Mar 2021 13:40:11 +0000 Subject: [PATCH 91/91] Use fsync in reskindex to ensure file is written to disk This should (hopefully) resolve occasional errors where the rename step would fail because the temporary file did not exist. In addition, this also exits with an error code if something goes wrong so we notice it early, rather than having to scroll through pages of logs at release time. --- scripts/reskindex.js | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/scripts/reskindex.js b/scripts/reskindex.js index 12310b77c1..5eaec4d1d5 100755 --- a/scripts/reskindex.js +++ b/scripts/reskindex.js @@ -1,5 +1,6 @@ #!/usr/bin/env node const fs = require('fs'); +const { promises: fsp } = fs; const path = require('path'); const glob = require('glob'); const util = require('util'); @@ -25,6 +26,8 @@ async function reskindex() { const header = args.h || args.header; const strm = fs.createWriteStream(componentIndexTmp); + // Wait for the open event to ensure the file descriptor is set + await new Promise(resolve => strm.once("open", resolve)); if (header) { strm.write(fs.readFileSync(header)); @@ -53,14 +56,9 @@ async function reskindex() { strm.write("export {components};\n"); // Ensure the file has been fully written to disk before proceeding + await util.promisify(fs.fsync)(strm.fd); await util.promisify(strm.end); - fs.rename(componentIndexTmp, componentIndex, function(err) { - if (err) { - console.error("Error moving new index into place: " + err); - } else { - console.log('Reskindex: completed'); - } - }); + await fsp.rename(componentIndexTmp, componentIndex); } // Expects both arrays of file names to be sorted @@ -77,9 +75,17 @@ function filesHaveChanged(files, prevFiles) { return false; } +// Wrapper since await at the top level is not well supported yet +function run() { + (async function() { + await reskindex(); + console.log("Reskindex completed"); + })(); +} + // -w indicates watch mode where any FS events will trigger reskindex if (!args.w) { - reskindex(); + run(); return; } @@ -87,5 +93,5 @@ let watchDebouncer = null; chokidar.watch(path.join(componentsDir, componentJsGlob)).on('all', (event, path) => { if (path === componentIndex) return; if (watchDebouncer) clearTimeout(watchDebouncer); - watchDebouncer = setTimeout(reskindex, 1000); + watchDebouncer = setTimeout(run, 1000); });