From 17262ad80d4a7596c698f6c13caa2842903e36bc Mon Sep 17 00:00:00 2001 From: Pablo Saavedra Date: Mon, 8 May 2017 12:18:31 +0200 Subject: [PATCH 001/123] Added TextInputWithCheckbox dialog --- src/component-index.js | 2 + src/components/structures/MatrixChat.js | 15 ++- .../dialogs/TextInputWithCheckboxDialog.js | 108 ++++++++++++++++++ 3 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 src/components/views/dialogs/TextInputWithCheckboxDialog.js diff --git a/src/component-index.js b/src/component-index.js index d6873c6dfd..ed538a6fcb 100644 --- a/src/component-index.js +++ b/src/component-index.js @@ -99,6 +99,8 @@ import views$dialogs$SetDisplayNameDialog from './components/views/dialogs/SetDi views$dialogs$SetDisplayNameDialog && (module.exports.components['views.dialogs.SetDisplayNameDialog'] = views$dialogs$SetDisplayNameDialog); import views$dialogs$TextInputDialog from './components/views/dialogs/TextInputDialog'; views$dialogs$TextInputDialog && (module.exports.components['views.dialogs.TextInputDialog'] = views$dialogs$TextInputDialog); +import views$dialogs$TextInputWithCheckboxDialog from './components/views/dialogs/TextInputWithCheckboxDialog'; +views$dialogs$TextInputWithCheckboxDialog && (module.exports.components['views.dialogs.TextInputWithCheckboxDialog'] = views$dialogs$TextInputWithCheckboxDialog); import views$dialogs$UnknownDeviceDialog from './components/views/dialogs/UnknownDeviceDialog'; views$dialogs$UnknownDeviceDialog && (module.exports.components['views.dialogs.UnknownDeviceDialog'] = views$dialogs$UnknownDeviceDialog); import views$elements$AccessibleButton from './components/views/elements/AccessibleButton'; diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index b449ff3094..d87ca203ce 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -191,6 +191,10 @@ module.exports = React.createClass({ return this.props.config.default_is_url || "https://vector.im"; }, + getDefaultFederate() { + return this.props.config.default_federate && true; + }, + componentWillMount: function() { SdkConfig.put(this.props.config); @@ -501,15 +505,20 @@ module.exports = React.createClass({ //this._setPage(PageTypes.CreateRoom); //this.notifyNewScreen('new'); - var TextInputDialog = sdk.getComponent("dialogs.TextInputDialog"); - Modal.createDialog(TextInputDialog, { + var TextInputWithCheckboxDialog = sdk.getComponent("dialogs.TextInputWithCheckboxDialog"); + Modal.createDialog(TextInputWithCheckboxDialog, { title: "Create Room", description: "Room name (optional)", button: "Create Room", - onFinished: (should_create, name) => { + check: this.getDefaultFederate(), + checkLabel: "Federate room in domain " + MatrixClientPeg.get().getDomain(), + onFinished: (should_create, name, isFederate) => { if (should_create) { const createOpts = {}; if (name) createOpts.name = name; + if (isFederate) { + createOpts.creation_content = {"m.federate": isFederate} + } createRoom({createOpts}).done(); } } diff --git a/src/components/views/dialogs/TextInputWithCheckboxDialog.js b/src/components/views/dialogs/TextInputWithCheckboxDialog.js new file mode 100644 index 0000000000..916de16af5 --- /dev/null +++ b/src/components/views/dialogs/TextInputWithCheckboxDialog.js @@ -0,0 +1,108 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import React from 'react'; +import sdk from '../../../index'; + +export default React.createClass({ + displayName: 'TextInputWithCheckboxDialog', + propTypes: { + title: React.PropTypes.string, + description: React.PropTypes.oneOfType([ + React.PropTypes.element, + React.PropTypes.string, + ]), + value: React.PropTypes.string, + button: React.PropTypes.string, + focus: React.PropTypes.bool, + checkLabel: React.PropTypes.string, + check: React.PropTypes.bool, + onFinished: React.PropTypes.func.isRequired, + }, + + getDefaultProps: function() { + return { + title: "", + value: "", + description: "", + button: "OK", + focus: true, + checkLabel: "", + check: true, + }; + }, + + getInitialState: function() { + return { + isChecked: this.props.check, + }; + }, + + componentDidMount: function() { + if (this.props.focus) { + // Set the cursor at the end of the text input + this.refs.textinput.value = this.props.value; + } + }, + + onOk: function() { + this.props.onFinished(true, this.refs.textinput.value, this.state.isChecked); + }, + + onCancel: function() { + this.props.onFinished(false); + }, + + _onToggle: function(keyName, checkedValue, uncheckedValue, ev) { + console.log("Checkbox toggle: %s %s", keyName, ev.target.checked); + var state = {}; + state[keyName] = ev.target.checked ? checkedValue : uncheckedValue; + this.setState(state); + }, + + render: function() { + const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); + return ( + +
+
+ +
+
+ +
+ +
+
+ + +
+
+ ); + }, +}); From 4b4b7302331b195e199e44bd2abddbf1a2c68b29 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 2 Aug 2017 13:41:26 +0100 Subject: [PATCH 002/123] fix and i18n the impl Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/MatrixChat.js | 24 ++++++++------ .../dialogs/TextInputWithCheckboxDialog.js | 33 +++++++------------ src/i18n/strings/en_EN.json | 2 ++ 3 files changed, 27 insertions(+), 32 deletions(-) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 50ee9963a6..22119585d9 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -214,10 +214,6 @@ module.exports = React.createClass({ return this.props.config.default_is_url || "https://vector.im"; }, - getDefaultFederate() { - return this.props.config.default_federate && true; - }, - componentWillMount: function() { SdkConfig.put(this.props.config); @@ -790,19 +786,27 @@ module.exports = React.createClass({ dis.dispatch({action: 'view_set_mxid'}); return; } + // Dialog shows inverse of m.federate (noFederate) strict false check to skip undefined check (default = true) + const defaultNoFederate = this.props.config.default_federate === false; const TextInputWithCheckboxDialog = sdk.getComponent("dialogs.TextInputWithCheckboxDialog"); Modal.createDialog(TextInputWithCheckboxDialog, { title: _t('Create Room'), description: _t('Room name (optional)'), button: _t('Create Room'), - // TODO i18n below. - check: this.getDefaultFederate(), - checkLabel: 'Federate room in domain ' + MatrixClientPeg.get().getDomain(), - onFinished: (shouldCreate, name, federate) => { + check: defaultNoFederate, + checkLabel: + {_t('Block users on other matrix homeservers from joining this room')} +
+ ({_t('This setting cannot be changed later!')}) +
, + onFinished: (shouldCreate, name, noFederate) => { if (shouldCreate) { - const createOpts = {}; + const createOpts = { + creation_content: { + "m.federate": !noFederate, + }, + }; if (name) createOpts.name = name; - if (federate) createOpts.creation_content = {"m.federate": federate}; createRoom({createOpts}).done(); } }, diff --git a/src/components/views/dialogs/TextInputWithCheckboxDialog.js b/src/components/views/dialogs/TextInputWithCheckboxDialog.js index 916de16af5..613fab4cdb 100644 --- a/src/components/views/dialogs/TextInputWithCheckboxDialog.js +++ b/src/components/views/dialogs/TextInputWithCheckboxDialog.js @@ -16,6 +16,7 @@ limitations under the License. import React from 'react'; import sdk from '../../../index'; +import { _t } from '../../../languageHandler'; export default React.createClass({ displayName: 'TextInputWithCheckboxDialog', @@ -28,7 +29,10 @@ export default React.createClass({ value: React.PropTypes.string, button: React.PropTypes.string, focus: React.PropTypes.bool, - checkLabel: React.PropTypes.string, + checkLabel: React.PropTypes.oneOfType([ + React.PropTypes.element, + React.PropTypes.string, + ]), check: React.PropTypes.bool, onFinished: React.PropTypes.func.isRequired, }, @@ -38,16 +42,9 @@ export default React.createClass({ title: "", value: "", description: "", - button: "OK", focus: true, checkLabel: "", - check: true, - }; - }, - - getInitialState: function() { - return { - isChecked: this.props.check, + check: false, }; }, @@ -59,20 +56,13 @@ export default React.createClass({ }, onOk: function() { - this.props.onFinished(true, this.refs.textinput.value, this.state.isChecked); + this.props.onFinished(true, this.refs.textinput.value, this.refs.checkbox.value); }, onCancel: function() { this.props.onFinished(false); }, - _onToggle: function(keyName, checkedValue, uncheckedValue, ev) { - console.log("Checkbox toggle: %s %s", keyName, ev.target.checked); - var state = {}; - state[keyName] = ev.target.checked ? checkedValue : uncheckedValue; - this.setState(state); - }, - render: function() { const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); return ( @@ -87,16 +77,15 @@ export default React.createClass({
+
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 87eb189ad0..f7fb221072 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -146,6 +146,7 @@ "Microphone": "Microphone", "Camera": "Camera", "Advanced": "Advanced", + "Advanced options": "Advanced options", "Algorithm": "Algorithm", "Hide removed messages": "Hide removed messages", "Always show message timestamps": "Always show message timestamps", From ffda53269515aa78e9a776024bfcc287961609b7 Mon Sep 17 00:00:00 2001 From: Silke Date: Sat, 16 Sep 2017 07:54:58 +0000 Subject: [PATCH 006/123] Translated using Weblate (Dutch) Currently translated at 100.0% (855 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/nl/ --- src/i18n/strings/nl.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index 3620c31816..fff3aaa4a5 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -855,5 +855,9 @@ "%(widgetName)s widget added by %(senderName)s": "%(widgetName)s-widget toegevoegd door %(senderName)s", "%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s-widget verwijderd door %(senderName)s", "Robot check is currently unavailable on desktop - please use a web browser": "Robot-check is momenteel niet beschikbaar op de desktop - gebruik in plaats daarvan een webbrowser", - "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s-widget aangepast door %(senderName)s" + "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s-widget aangepast door %(senderName)s", + "%(weekDayName)s, %(monthName)s %(day)s": "%(weekDayName)s %(day)s %(monthName)s", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s %(day)s %(monthName)s %(fullYear)s", + "Copied!": "Gekopieerd!", + "Failed to copy": "Kopiëren mislukt" } From 93f404081b7e994777b0d31d50d78258c817c02c Mon Sep 17 00:00:00 2001 From: Jan Kudrik Date: Sun, 17 Sep 2017 16:48:24 +0000 Subject: [PATCH 007/123] Translated using Weblate (Czech) Currently translated at 44.4% (380 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/cs/ --- src/i18n/strings/cs.json | 172 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 165 insertions(+), 7 deletions(-) diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index 7951779e75..5e4846794a 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -13,7 +13,7 @@ "Rooms": "Místnosti", "Scroll to unread messages": "Přejít k nepřečteným zprávám", "Search": "Hledání", - "Send a message (unencrypted)": "Poslat zprávu (nezašifrovaně)", + "Send a message (unencrypted)": "Poslat zprávu (nešifrovanou)", "Settings": "Nastavení", "Start Chat": "Začít chat", "This room": "Tato místnost", @@ -51,12 +51,12 @@ "Error": "Chyba", "Failed to join the room": "Vstup do místnosti se nezdařil", "Favourite": "V oblíbených", - "Mute": "Ztišit", + "Mute": "Ztlumit", "Continue": "Pokračovat", "Failed to change password. Is your password correct?": "Nepodařilo se změnit heslo. Je vaše heslo správné?", "Welcome page": "Uvítací stránka", "Operation failed": "Chyba operace", - "Please Register": "Prosím zaregistrujte se", + "Please Register": "Zaregistrujte se prosím", "Remove": "Odebrat", "unknown error code": "neznámý kód chyby", "Sunday": "Neděle", @@ -129,8 +129,8 @@ "Changes your display nickname": "Změní vaši zobrazovanou přezdívku", "Changes colour scheme of current room": "Změní barevné schéma aktuální místnosti", "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "V současnosti změna hesla resetuje všechny šifrovací klíče na všech zařízeních, což vám znepřístupní historii zašifrovaných chatů, pokud si nejprve nevyexportujete klíče svých místností a pak je do nich znova nevložíte. Toto bude v budoucnu lépe ošetřeno.", - "Clear Cache and Reload": "Vymazat vyrovnávací paměť a načíst znovu", - "Clear Cache": "Vymazat vyrovnávací paměť", + "Clear Cache and Reload": "Vymazat mezipaměť a načíst znovu", + "Clear Cache": "Vymazat mezipaměť", "Click here to join the discussion!": "Kliknutím zde se přidáte k diskuzi!", "Command error": "Chyba příkazu", "Commands": "Příkazy", @@ -219,6 +219,164 @@ "Failed to upload profile picture!": "Nahrání profilového obrázku se nezdařilo", "Failure to create room": "Vytvoření místnosti se nezdařilo", "Forget room": "Zapomenout místnost", - "Forgot your password?": "Zapomněl/a jste své heslo?", - "For security, this session has been signed out. Please sign in again.": "Z bezpečnostních důvodů bylo toto přihlášení ukončeno. Přihlašte se prosím znovu." + "Forgot your password?": "Zapomněli jste své heslo?", + "For security, this session has been signed out. Please sign in again.": "Z bezpečnostních důvodů bylo toto přihlášení ukončeno. Přihlašte se prosím znovu.", + "all room members, from the point they are invited": "všichni členové místnosti od chvíle jejich pozvání", + "all room members, from the point they joined": "všichni členové místnosti od chvíle jejich vstupu", + "%(names)s and one other are typing": "%(names)s a jeden další píší", + "%(names)s and %(lastPerson)s are typing": "%(names)s a %(lastPerson)s píší", + "and %(count)s others...|other": "a %(count)s další...", + "%(names)s and %(count)s others are typing": "%(names)s a %(count)s další píší", + "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s widget upravil/a %(senderName)s", + "%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s widget odstranil/a %(senderName)s", + "%(widgetName)s widget added by %(senderName)s": "%(widgetName)s widget přidal/a %(senderName)s", + "Automatically replace plain text Emoji": "Automaticky nahrazovat textové emodži", + "Failed to upload image": "Obrázek se nepodařilo nahrát", + "Failed to update group": "Aktualizace skupiny se nepodařila", + "Edit Group": "Upravit skupinu", + "Join an existing group": "Přidat se do existující skupiny", + "To join an existing group you'll have to know its group identifier; this will look something like +example:matrix.org.": "Pro přidání se do existující skupiny je nutno znát její identifikátor. Vypadá nějak takto: +skupina:matrix.org.", + "You are a member of these groups:": "Jste členem těchto skupin:", + "Room creation failed": "Místnost se nepodařilo vytvořit", + "%(senderName)s answered the call.": "%(senderName)s přijal/a hovor.", + "Click to mute audio": "Kliknutím ztlumíte zvuk", + "Failed to verify email address: make sure you clicked the link in the email": "E-mailovou adresu se nepodařilo ověřit. Přesvědčte se, že jste kliknul/a na zaslaný odkaz", + "Found a bug?": "Našli jste chybu?", + "Guest access is disabled on this Home Server.": "Na tomto domovském serveru je hostům vstup odepřen.", + "Guests can't set avatars. Please register.": "Hosté si nemohou nastavovat avatar. Zaregistrujte se prosím.", + "Guest users can't create new rooms. Please register to create room and start a chat.": "Hosté nemohou vytvářet nové místnosti. Abyste mohli místnosti vytvářet a chatovat v nich, nejprve se prosím zaregistrujte.", + "Guest users can't upload files. Please register to upload.": "Hosté nemohou nahrávat soubory. Abyste je mohli nahrávat, nejprve se prosím zaregistrujte.", + "Guests cannot join this room even if explicitly invited.": "Hosté nemohou vstoupit do této místnosti, i když jsou přímo pozváni.", + "had": "měl/a", + "Hide read receipts": "Skrýt potvrzení o přečtení", + "Homeserver is": "Domovský server je", + "Identity Server is": "Server identity je", + "I have verified my email address": "Ověřil/a jsem svoji e-mailovou adresu", + "Import": "Importovat", + "Import E2E room keys": "Importovat E2E klíče místností", + "Incoming call from %(name)s": "Příchozí hovor od %(name)s", + "Incoming video call from %(name)s": "Příchozí videohovor od %(name)s", + "Incoming voice call from %(name)s": "Příchozí hlasový hovor od %(name)s", + "Incorrect username and/or password.": "Nesprávné uživatelské jméno nebo heslo.", + "Incorrect verification code": "Nesprávný ověřovací kód", + "Interface Language": "Jazyk rozhraní", + "Invalid alias format": "Neplaný formát aliasu", + "Invalid address format": "Neplatný formát adresy", + "Invalid Email Address": "Neplatná e-mailová adresa", + "%(senderName)s invited %(targetName)s.": "%(senderName)s pozval/a %(targetName)s.", + "Invite new room members": "Pozvat do místnosti nové členy", + "Invites": "Pozvánky", + "Invites user with given id to current room": "Pozve do aktuální místnosti uživatele s daným id", + "'%(alias)s' is not a valid format for an address": "'%(alias)s' není platný formát adresy", + "'%(alias)s' is not a valid format for an alias": "'%(alias)s' není platný formát aliasu", + "Join Room": "Vstoupit do místnosti", + "%(targetName)s joined the room.": "%(targetName)s vstoupil/a do místnosti.", + "%(senderName)s kicked %(targetName)s.": "%(senderName)s vykopnul/a %(targetName)s.", + "Kick": "Vykopnout", + "Kicks user with given id": "Vykopne uživatele s daným id", + "Last seen": "Naposledy viděn/a", + "Leave room": "Odejít z místnosti", + "Level:": "Úroveň:", + "Local addresses for this room:": "Místní adresy této místnosti:", + "Logged in as:": "Přihlášen/a jako:", + "Login as guest": "Přihlášen/a jako host", + "matrix-react-sdk version:": "Verze matrix-react-sdk:", + "Members only": "Pouze pro členy", + "Mobile phone number": "Číslo mobilního telefonu", + "Mobile phone number (optional)": "Číslo mobilního telefonu (nepovinné)", + "Moderator": "Moderátor", + "my Matrix ID": "moje Matrix ID", + "Name": "Jméno", + "New address (e.g. #foo:%(localDomain)s)": "Nová adresa (např. #neco:%(localDomain)s)", + "New password": "Nové heslo", + "New passwords don't match": "Nová hesla se neshodují", + "New passwords must match each other.": "Nová hesla se musí shodovat.", + "not set": "nenastaveno", + "not specified": "neurčeno", + "(not supported by this browser)": "(nepodporováno tímto prohlížečem)", + "": "", + "AM": "dop.", + "PM": "odp.", + "NOT verified": "Neověřeno", + "No display name": "Žádné zobrazované jméno", + "No more results": "Žádné další výsledky", + "No results": "Žádné výsledky", + "olm version:": "verze olm:", + "Once encryption is enabled for a room it cannot be turned off again (for now)": "Jakmile je jednou šifrování v místnosti zapnuto, nelze už vypnout (prozatím)", + "Only people who have been invited": "Pouze lidé, kteří byli pozváni", + "Otherwise, click here to send a bug report.": "V opačném případě klikněte zde a pošlete hlášení o chybě.", + "Password": "Heslo", + "Password:": "Heslo:", + "Passwords can't be empty": "Hesla nemohou být prázdná", + "Permissions": "Oprávnění", + "Phone": "Telefon", + "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s změnil/a úroveň moci o %(powerLevelDiffText)s.", + "Define the power level of a user": "Stanovte úroveň moci uživatele", + "Failed to change power level": "Nepodařilo se změnit úroveň moci", + "Power level must be positive integer.": "Úroveň moci musí být kladné celé číslo.", + "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (moc %(powerLevelNumber)s)", + "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Tuto změnu nepůjde vrátit zpět, protože tomuto uživateli nastavujete stejnou úroveň moci, jakou máte vy.", + "And %(count)s more...": "A %(count)s další...", + "Alias (optional)": "Alias (nepovinný)", + "Room name (optional)": "Název místnosti (nepovinný)", + "Report it": "Nahlásit to", + "restore": "obnovit", + "Results from DuckDuckGo": "Výsledky z DuckDuckGo", + "Return to app": "Vrátit k aplikaci", + "Return to login screen": "Vrátit k přihlašovací obrazovce", + "Riot does not have permission to send you notifications - please check your browser settings": "Riot není oprávněn posílat vám upozornění – zkontrolujte prosím nastavení svého prohlížeče", + "Riot was not given permission to send notifications - please try again": "Riot nebyl oprávněn k posílání upozornění – zkuste to prosím znovu", + "riot-web version:": "verze riot-web:", + "Room %(roomId)s not visible": "Místnost %(roomId)s není viditelná", + "Room Colour": "Barva místnosti", + "Room contains unknown devices": "V místnosti jsou neznámá zařízení", + "%(roomName)s does not exist.": "%(roomName)s neexistuje.", + "%(roomName)s is not accessible at this time.": "Místnost %(roomName)s není v tuto chvíli dostupná.", + "Save": "Uložit", + "Scroll to bottom of page": "Přejít na konec stránky", + "Send an encrypted message": "Poslat šifrovanou zprávu", + "Send anyway": "Přesto poslat", + "Sender device information": "Informace o odesilatelově zařízení", + "Send Reset Email": "Poslat resetovací e-mail", + "sent an image": "poslat obrázek", + "%(senderDisplayName)s sent an image.": "%(senderDisplayName)s poslal/a obrázek.", + "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s poslal/a %(targetDisplayName)s pozvánku ke vstupu do místnosti.", + "sent a video": "poslat video", + "Server error": "Chyba serveru", + "Server may be unavailable or overloaded": "Server může být nedostupný nebo přetížený", + "Server may be unavailable, overloaded, or search timed out :(": "Server může být nedostupný, přetížený nebo vyhledávání vypršelo :(", + "Server may be unavailable, overloaded, or the file too big": "Server může být nedostupný, přetížený nebo soubor je příliš velký", + "Server may be unavailable, overloaded, or you hit a bug.": "Server může být nedostupný, přetížený nebo jste narazili na chybu.", + "Server unavailable, overloaded, or something else went wrong.": "Server je nedostupný, přetížený nebo se pokazilo něco jiného.", + "Session ID": "ID sezení", + "%(senderName)s set a profile picture.": "%(senderName)s si nastavil/a profilový obrázek.", + "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s si změnil/a zobrazované jméno na %(displayName)s.", + "Set": "Nastavit", + "Sets the room topic": "Nastavuje téma místnosti", + "Show Apps": "Zobrazit aplikace", + "Show panel": "Zobrazit panel", + "Show timestamps in 12 hour format (e.g. 2:30pm)": "Zobrazovat časové značky v 12hodinovém formátu (např. 2:30 odp.)", + "Sign in": "Přihlásit", + "Sign out": "Odhlásit", + "Some of your messages have not been sent.": "Některé z vašich zpráv nebyly odeslány.", + "Someone": "Někdo", + "Start a chat": "Začít chat", + "Start authentication": "Začít ověření", + "Submit": "Odeslat", + "Success": "Úspěch", + "tag as %(tagName)s": "oštítkovat jako %(tagName)s", + "The main address for this room is": "Hlavní adresa této místnosti je", + "The phone number entered looks invalid": "Zadané telefonní číslo se zdá být neplatné", + "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Zadaný podepisovací klíč se shoduje s klíčem obdrženým od uživatele %(userId)s ze zařízení %(deviceId)s. Zařízení je označeno jako ověřené.", + "This email address is already in use": "Tato e-mailová adresa je již používaná", + "This email address was not found": "Tato e-mailová adresa nebyla nalezena", + "%(actionVerb)s this person?": "%(actionVerb)s tuto osobu?", + "The file '%(fileName)s' exceeds this home server's size limit for uploads": "Soubor '%(fileName)s' překračuje maximální velikost povolenou na tomto domovském serveru", + "The file '%(fileName)s' failed to upload": "Soubor '%(fileName)s' se nepodařilo nahrát", + "This Home Server does not support login using email address.": "Tento domovský server nepodporuje přihlašování e-mailovou adresou.", + "There was a problem logging in.": "Při přihlašování se vyskytl problém.", + "This room has no local addresses": "Tato místnost nemá žádné místní adresy", + "This room is not recognised.": "Tato místnost nebyla rozpoznána.", + "These are experimental features that may break in unexpected ways": "Tyto funkce jsou experimentální a mohou se pokazit nečekanými způsoby", + "The visibility of existing history will be unchanged": "Viditelnost existující historie nebude změněna" } From 3903f5a41368d2e87aa50734a9c7f60f1c204a33 Mon Sep 17 00:00:00 2001 From: ErCiccione Date: Sun, 17 Sep 2017 15:45:49 +0000 Subject: [PATCH 008/123] Translated using Weblate (Italian) Currently translated at 7.3% (63 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/it/ --- src/i18n/strings/it.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/it.json b/src/i18n/strings/it.json index 67df5bc332..954fa1bd69 100644 --- a/src/i18n/strings/it.json +++ b/src/i18n/strings/it.json @@ -59,5 +59,7 @@ "all room members": "Tutti i membri della stanza", "all room members, from the point they are invited": "Tutti i membri della stanza, dal punto in cui sono stati/e invitati/e", "all room members, from the point they joined": "tutti i membri della stanza, dal punto in cui si sono uniti", - "and": "e" + "and": "e", + "Add a widget": "Aggiungi un widget", + "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Un messaggio di testo è stato inviato a +%(msisdn)s. Inserisci il codice di verifica che contiene" } From 1639e643285ec85d083111b92bda3aa66ebb5dc8 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Mon, 18 Sep 2017 01:10:23 +0000 Subject: [PATCH 009/123] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (855 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hant/ --- src/i18n/strings/zh_Hant.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 6196608d48..9fbbb95059 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -861,5 +861,7 @@ "Robot check is currently unavailable on desktop - please use a web browser": "機器人檢查目前在桌面端不可用 ── 請使用網路瀏覽器", "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s 小工具已被 %(senderName)s 修改", "%(weekDayName)s, %(monthName)s %(day)s": "%(monthName)s%(day)s %(weekDayName)s", - "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(fullYear)s %(monthName)s %(day)s %(weekDayName)s" + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(fullYear)s %(monthName)s %(day)s %(weekDayName)s", + "Copied!": "已複製!", + "Failed to copy": "複製失敗" } From add9f6949790cacb354d8f58ef9ad37138af1614 Mon Sep 17 00:00:00 2001 From: Stefan Parviainen Date: Mon, 18 Sep 2017 07:29:33 +0000 Subject: [PATCH 010/123] Translated using Weblate (Finnish) Currently translated at 59.7% (511 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fi/ --- src/i18n/strings/fi.json | 164 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 163 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fi.json b/src/i18n/strings/fi.json index 149464d009..5456a4d22f 100644 --- a/src/i18n/strings/fi.json +++ b/src/i18n/strings/fi.json @@ -349,5 +349,167 @@ "Unrecognised room alias:": "Tuntematon huonealias:", "Unverified": "Varmentamaton", "Uploading %(filename)s and %(count)s others|zero": "Ladataan %(filename)s", - "Uploading %(filename)s and %(count)s others|one": "Ladataan %(filename)s ja %(count)s muuta" + "Uploading %(filename)s and %(count)s others|one": "Ladataan %(filename)s ja %(count)s muuta", + "Blacklisted": "Estetyt", + "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s muuti huoneen nimeksi %(roomName)s.’,,False,.%(senderDisplayName)s changed the room name to %(roomName)s.,,\n,%(senderDisplayName)s removed the room name.'", + "Drop here to tag %(section)s": "Pudota tähän tägätäksesi %(section)s", + "Enable automatic language detection for syntax highlighting": "Ota automaattinen kielentunnistus käyttöön koodin väritystä varten", + "Encrypted messages will not be visible on clients that do not yet implement encryption": "Salatut viestit eivät näy ohjelmissa joissa salaus ei ole vielä implementoitu", + "%(senderName)s ended the call.": "%(senderName)s lopetti puhelun.’,,False,.%(senderName)s ended the call.,,\n,End-to-end encryption information,Päästä päähän-salauksen tiedot,,False,.End-to-end encryption information,,\n,End-to-end encryption is in beta and may not be reliable,Päästä päähän salaus on vielä testausvaiheessa ja saattaa toimia epävarmasti,,False,.End-to-end encryption is in beta and may not be reliable,,\n,Enter Code,Syötä koodi,,False,.Enter Code,,\n,Enter passphrase,Syötä salasana,,False,.Enter passphrase,,\n,Error,Virhe,,False,.Error,,\n,Error decrypting attachment,Liitteen salauksen purku epäonnistui,,False,.Error decrypting attachment,,\n,Error: Problem communicating with the given homeserver.,Virhe: Ongelma yhteydenpidossa kotipalvelimeen,,False,.Error: Problem communicating with the given homeserver.,,\n,Event information,Tapahtumatiedot,,False,.Event information,,\n,Existing Call,Käynnissä oleva puhelu,,False,.Existing Call,,\n,Export,Vie,,False,.Export,,\n,Export E2E room keys,Vie huoneen päästä päähän-salauksen (E2E) avaimet ,,False,.Export E2E room keys,,\n,Failed to ban user,Porttikiellon antaminen epäonnistui,,False,.Failed to ban user,,\n,Failed to change password. Is your password correct?,Salasanan muuttaminen epäonnistui. Onko salasanasi oikein?,,False,.Failed to change password. Is your password correct?,,\n,Failed to change power level,,,False,.Failed to change power level,,\n,Failed to delete device,Laitten poistamine epäonnistui,,False,.Failed to delete device,,\n,Failed to fetch avatar URL,Avatar URL:n haku epäonnistui,,False,.Failed to fetch avatar URL,,\n,Failed to forget room %(errCode)s,Huoneen unohtaminen epäonnistui %(errCode)s,,False,.Failed to forget room %(errCode)s,,\n,Failed to join room,Huoneeseen liittyminen epäonnistui,,False,.Failed to join room,,\n,Failed to join the room,Huoneeseen liittyminen epäonnistui,,False,.Failed to join the room,,\n,Failed to kick,Huoneesta poistaminen epäonnistui,,False,.Failed to kick,,\n,Failed to leave room,Huoneesta poistuminen epäonnistui,,False,.Failed to leave room,,\n,Failed to load timeline position,Aikajanapaikan lataaminen epäonnistui,,False,.Failed to load timeline position,,\n,Failed to lookup current room,Nykyisen huoneen löytäminen epäonnistui,,False,.Failed to lookup current room,,\n,Failed to mute user,Käyttäjän mykistäminen epäonnistui,,False,.Failed to mute user,,\n,Failed to register as guest:,Vieraana rekisteröityminen epäonnistui,,False,.Failed to register as guest:,,\n,Failed to reject invite,Kutsun hylkääminen epäonnistui,,False,.Failed to reject invite,,\n,Failed to reject invitation,Kutsun hylkääminen epäonnistui,,False,.Failed to reject invitation,,\n,Failed to save settings,Asetusten tallentaminen epäonnistui,,False,.Failed to save settings,,\n,Failed to send email,Sähköpostin lähettäminen epäonnistui,,False,.Failed to send email,,\n,Failed to send request.,Pyynnön lähettäminen epäonnistui,,False,.Failed to send request.,,\n,Failed to set avatar.,,,False,.Failed to set avatar.,,\n,Failed to set display name,Näyttönimen asettaminen epäonnistui,,False,.Failed to set display name,,\n,Failed to set up conference call,Konferenssipuhelun alustus epäonnistui,,False,.Failed to set up conference call,,\n,Failed to toggle moderator status,Moderaattoriasetuksen muuttaminen epäonnistui,,False,.Failed to toggle moderator status,,\n,Failed to unban,Porttikiellon poistaminen epäonnistui,,False,.Failed to unban,,\n,Failed to upload file,Tiedoston lataaminen epäonnistui,,False,.Failed to upload file,,\n,Failed to upload profile picture!,Profiilikuvan lataaminen epäonnistui,,False,.Failed to upload profile picture!,,\n,Failed to verify email address: make sure you clicked the link in the email,Varmenna sähköpostiosoitteesi: varmista että klikkasit sähköpostissa olevaa linkkiä,,False,.Failed to verify email address: make sure you clicked the link in the email,,\n,Failure to create room,Huoneen luominen epäonnistui,,False,.Failure to create room,,\n,Favourite,Suosikki,,False,.Favourite,,\n,favourite,suosikki,,False,.favourite,,\n,Favourites,Suosikit,,False,.Favourites,,\n,Fill screen,Täytä näyttö,,False,.Fill screen,,\n,Filter room members,Suodata huoneen jäsenet,,False,.Filter room members,,\n,Forget room,Unohda huone,,False,.Forget room,,\n,Forgot your password?,Unohditko salasanasi?,,False,.Forgot your password?,,\n,\"For security, this session has been signed out. Please sign in again.\",Turvallisuussyistä tämä istunto on vanhentunut. Ole hyvä ja kirjaudu uudestaan.,,False,\".For security, this session has been signed out. Please sign in again.\",,\n,\"For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.\",Turvallusuussyistä uloskirjautuminen poistaa kaikki päästä päähän-salausavaimet tästä selaimesta. Jos haluat purkaa keskustelujen salaukset tulevaisuudessa pitää sinun viedä purkuavaimet ja pitää ne turvallisesti tallessa.,,False,\".For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.\",,\n,Found a bug?,Löysitkö virheen?,,False,.Found a bug?,,\n,%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s'", + "Guest access is disabled on this Home Server.": "Vierailijat on estetty tällä kotipalvelimella.", + "Guest users can't create new rooms. Please register to create room and start a chat.": "Vierailijat eivät voi luoda huoneita. Ole hyvä ja rekisteröidy luodaksesi huoneen ja aloittaaksesi keskustelun", + "Guest users can't upload files. Please register to upload.": "Vierailijat eivät voi ladata tiedostoja. Ole hyvä ja rekisteröidy voidaksesi ladata tiedostoja.", + "Guests can't use labs features. Please register.": "\"Vierailijat eivät voi käyttää kokeellisia toimintoja. Ole hyvä ja rekisteröidy", + "Guests cannot join this room even if explicitly invited.": "Vierailijat eivät voi liittyä tähän huoneeseen vaikka heidät on explisiittisesti kutsuttu", + "Hangup": "Lopeta", + "Hide join/leave messages (invites/kicks/bans unaffected)": "Piilota liittymis-/poistumisviestit (ei koske kutsuja/poistamisia/porttikieltoja)", + "Historical": "Vanhat", + "Home": "Etusivu", + "Invalid file%(extra)s": "Virheellinen tiedosto%(extra)s", + "%(senderName)s invited %(targetName)s.": "%(senderName)s kutsui käyttäjän %(targetName)s.’,,False,.%(senderName)s invited %(targetName)s.,,\n,Invite new room members,Kutsu lisää jäseniä huoneeseen,,False,.Invite new room members,,\n,Invited,Kutsuttu,,False,.Invited,,\n,Invites,Kutsuu,,False,.Invites,,\n,Invites user with given id to current room,Kutsuu annetun käyttäjätunnisteen mukaisen käyttäjän huoneeseen,,False,.Invites user with given id to current room,,\n,%(alias)s' is not a valid format for an address", + "%(displayName)s is typing": "%(displayName)s kirjoittaa’,,False,.%(displayName)s is typing,,\n,Sign in with,Kirjaudu käyttäen,,False,.Sign in with,,\n,Join as voice or video.,Liitty käyttäen ääntä tai videota,,False,.Join as voice or video.,,\n,Join Room,Liity huoneeseen,,False,.Join Room,,\n,joined and left,liittyi ja poistui,,False,.joined and left,,\n,joined,liittyi,,False,.joined,,\n,%(targetName)s joined the room.'", + "%(senderName)s made future room history visible to": "%(senderName)s teki tulevista viesteistä näkyviä’,,False,.%(senderName)s made future room history visible to,,\n,Manage Integrations,Hallinoi integraatioita,,False,.Manage Integrations,,\n,Markdown is disabled,Markdown on pois päältä,,False,.Markdown is disabled,,\n,Markdown is enabled,Mardown on päällä,,False,.Markdown is enabled,,\n,matrix-react-sdk version:,Matrix-react-sdk versio:,,False,.matrix-react-sdk version:,,\n,Matrix Apps,Matrix ohjelmat,,False,.Matrix Apps,,\n,Members only,Vain jäsenet,,False,.Members only,,\n,Message not sent due to unknown devices being present,Viestiä ei lähetetty koska paikalla on tuntemattomia laitteita,,False,.Message not sent due to unknown devices being present,,\n,Missing room_id in request,room_id puuttuu kyselystä,,False,.Missing room_id in request,,\n,Missing user_id in request,user_id puuttuu kyselystä,,False,.Missing user_id in request,,\n,Mobile phone number,Matkapuhelinnumero,,False,.Mobile phone number,,\n,Mobile phone number (optional),Matkapuhelinnumero (valinnainen),,False,.Mobile phone number (optional),,\n,Moderator,Moderaattori,,False,.Moderator,,\n,Must be viewing a room,Pakko olla huoneessa,,False,.Must be viewing a room,,\n,Mute,Vaimenna,,False,.Mute,,\n,my Matrix ID,minun Matrix tunniste,,False,.my Matrix ID,,\n,Name,Nimi,,False,.Name,,\n,Never send encrypted messages to unverified devices from this device,Älä koskaa lähetä salattuja viestejä varmentamattomiin laitteisiin tältä laitteelta,,False,.Never send encrypted messages to unverified devices from this device,,\n,Never send encrypted messages to unverified devices in this room,Älä koskaa lähetä salattuja viestejä varmentamattomiin laitteisiin tässä huoneessa,,False,.Never send encrypted messages to unverified devices in this room,,\n,Never send encrypted messages to unverified devices in this room from this device,Älä koskaa lähetä salattuja viestejä varmentamattomiin laitteisiin tässä huoneessa tältä laitteelta,,False,.Never send encrypted messages to unverified devices in this room from this device,,\n,New address (e.g. #foo:%(localDomain)s),Uusi osoite (esim. #foo:%(localDomain)s),,False,.New address (e.g. #foo:%(localDomain)s),,\n,New Composer & Autocomplete,,,False,.New Composer & Autocomplete,,\n,New password,Uusi salasana,,False,.New password,,\n,New passwords dont match", + "none": "Ei mikään", + "No devices with registered encryption keys": "Ei laitteita joilla rekisteröityjä salausavaimia", + "No users have specific privileges in this room": "Kellään käyttäjällä ei ole erityisiä oikeuksia", + "%(senderName)s placed a %(callType)s call.": "%(senderName)s soitti %(callType)spuhelun’,,False,.%(senderName)s placed a %(callType)s call.,,\n,\"Please check your email and click on the link it contains. Once this is done, click continue.\",Ole hyvä ja tarkista sähköpostisi ja seuraa sen sisältämää linkkiä. Voit jatkaa tämän jälkeen.,,False,\".Please check your email and click on the link it contains. Once this is done, click continue.\",,\n,Please Register,Ole hyvä ja rekisteröidy,,False,.Please Register,,\n,Power level must be positive integer.,,,False,.Power level must be positive integer.,,\n,Press,,,False,.Press,,\n,Press to start a chat with someone,Paina ,,False,.Press to start a chat with someone,,\n,Privacy warning,Yksityisyysvaroitus,,False,.Privacy warning,,\n,Private Chat,Yksityinen keskustelu,,False,.Private Chat,,\n,Privileged Users,,,False,.Privileged Users,,\n,Profile,Profiili,,False,.Profile,,\n,Public Chat,Julkinen keskustelu,,False,.Public Chat,,\n,Reason,Syy,,False,.Reason,,\n,Reason: %(reasonText)s,Syy: %(reasonText)s,,False,.Reason: %(reasonText)s,,\n,Revoke Moderator,Poista moderaattorioikeudet,,False,.Revoke Moderator,,\n,Revoke widget access,,,False,.Revoke widget access,,\n,Refer a friend to Riot:,Suosittele Riot ystävälle:,,False,.Refer a friend to Riot:,,\n,Register,Rekisteröi,,False,.Register,,\n,rejected,hylätty,,False,.rejected,,\n,%(targetName)s rejected the invitation.'", + "Remove %(threePid)s?": "Poista %(threePid)s?", + "%(senderName)s requested a VoIP conference.": "%(senderName)s pyysi VoIP konferenssia.’,,False,.%(senderName)s requested a VoIP conference.,,\n,Report it,Ilmoita siitä,,False,.Report it,,\n,\"Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.\",,,False,\".Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.\",,\n,restore,palauta,,False,.restore,,\n,Results from DuckDuckGo,DuckDuckGo:n tulokset,,False,.Results from DuckDuckGo,,\n,Return to app,Palaa ohjelmaan,,False,.Return to app,,\n,Return to login screen,Palaa kirjautumissivulle,,False,.Return to login screen,,\n,Riot does not have permission to send you notifications - please check your browser settings,Riotilla ei ole oikeuksia lähettää sinulle ilmoituksia. Ole hyvä ja tarkista selaimen asetukset,,False,.Riot does not have permission to send you notifications - please check your browser settings,,\n,Riot was not given permission to send notifications - please try again,Riotilla ei saannut oikeuksia lähettää ilmoituksia. Ole hyvä ja yritä uudelleen,,False,.Riot was not given permission to send notifications - please try again,,\n,riot-web version:,Riot-web versio:,,False,.riot-web version:,,\n,Room %(roomId)s not visible,Huone %(roomId)s ei ole näkyvissä,,False,.Room %(roomId)s not visible,,\n,Room Colour,Huoneen väri,,False,.Room Colour,,\n,Room contains unknown devices,Huone sisältää tuntemattomia laitteita,,False,.Room contains unknown devices,,\n,Room name (optional),Huoneen nimi (valinnainen),,False,.Room name (optional),,\n,%(roomName)s does not exist.'", + "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s asetti näyttönimekseen %(displayName)s.’,,False,.%(senderName)s set their display name to %(displayName)s.,,\n,Set,Aseta,,False,.Set,,\n,Settings,Asetukset,,False,.Settings,,\n,Sets the room topic,Asettaa huoneen aiheen,,False,.Sets the room topic,,\n,Show Apps,,,False,.Show Apps,,\n,Show panel,Näytä paneeli,,False,.Show panel,,\n,Show Text Formatting Toolbar,Näytä tekstinmuotoilupalkki,,False,.Show Text Formatting Toolbar,,\n,Show timestamps in 12 hour format (e.g. 2:30pm),Näytä aikaleimat 12h muodossa (esim. 2:30pm),,False,.Show timestamps in 12 hour format (e.g. 2:30pm),,\n,Signed Out,Uloskirjautunut,,False,.Signed Out,,\n,Sign in,Kirjaudu sisään,,False,.Sign in,,\n,Sign out,Kirjaudu ulos,,False,.Sign out,,\n,since the point in time of selecting this option,tämän asetuksen valitsemisesta,,False,.since the point in time of selecting this option,,\n,since they joined,liittymisestä lähtien,,False,.since they joined,,\n,since they were invited,kutsusta lähtien,,False,.since they were invited,,\n,Some of your messages have not been sent.,Jotkut viesteistäsi ei ole lähetetty,,False,.Some of your messages have not been sent.,,\n,Someone,Joku,,False,.Someone,,\n,\"Sorry, this homeserver is using a login which is not recognised \",Valitettavasti tämä kotipalvelin käyttää sisäänkirjautumista jota ei tunnistettu,,False,\".Sorry, this homeserver is using a login which is not recognised \",,\n,Start a chat,Aloita keskustelu,,False,.Start a chat,,\n,Start authentication,Aloita tunnistus,,False,.Start authentication,,\n,Start Chat,Aloita keskustelu,,False,.Start Chat,,\n,Submit,Lähetä,,False,.Submit,,\n,Success,Onnistuminen,,False,.Success,,\n,tag as %(tagName)s,lisää tägi %(tagName)s,,False,.tag as %(tagName)s,,\n,tag direct chat,tägää suora viestittely,,False,.tag direct chat,,\n,Tagged as: ,Tägit:,,False,.Tagged as: ,,\n,The default role for new room members is,Huoneen uusien jäsenten oletusrooli on,,False,.The default role for new room members is,,\n,The main address for this room is,Tämän huoneen pääosoite on,,False,.The main address for this room is,,\n,The maximum permitted number of widgets have already been added to this room.,,,False,.The maximum permitted number of widgets have already been added to this room.,,\n,The phone number entered looks invalid,Syötetty puhelinnumero näyttää virheelliseltä,,False,.The phone number entered looks invalid,,\n,The signing key you provided matches the signing key you received from %(userId)ss device %(deviceId)s. Device marked as verified.", + "This action cannot be performed by a guest user. Please register to be able to do this.": "Vierailija ei voi suorittaa tätä toimintoa. Ole hyvä ja rekisteröidy suorittaaksesi toiminnon.", + "The file '%(fileName)s' exceeds this home server's size limit for uploads": "Tiedosto ‘%(fileName)s’ ylittää tämän kotipalvelimen maksimitiedostokoon", + "The file '%(fileName)s' failed to upload": "Tiedoston ‘%(fileName)s’ lataaminen epäonnistui", + "This Home Server does not support login using email address.": "Kotipalvelin ei tue kirjatumista sähköpostiosoitteen avulla.", + "This invitation was sent to an email address which is not associated with this account:": "Kutsu lähetettiin sähköpostiosoitteeseen jota ei ole liitetty tähän tiliin:", + "This room is not recognised.": "Huonetta ei tunnistettu", + "These are experimental features that may break in unexpected ways": "Nämä ovat kokeellisia ominaisuuksia jotka saattavat toimia ennakoimattomilla tavoilla", + "This doesn't appear to be a valid email address": "Olemassa olevan historian näkyvyys ei muutu", + "This is a preview of this room. Room interactions have been disabled": "Tämä on huoneen ennakokatselu. Vuorovaikutus ei ole mahdollista", + "This phone number is already in use": "Puhelinnumero on jo käytössä", + "times": "kertaa", + "To link to a room it must have an address.": "Linkittääksesi tähän huoneseen sillä on oltava osoite.", + "Turn Markdown off": "Ota Markdown pois käytöstä", + "Turn Markdown on": "Ota Markdown käyttöön", + "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s otti päästä päähän-salauksen käyttöön (algoritmi %(algorithm)s).’,,False,.%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).,,\n,Unable to add email address,Sähköpostiosoitteen lisääminen epäonnistui,,False,.Unable to add email address,,\n,Unable to create widget.,,,False,.Unable to create widget.,,\n,Unable to remove contact information,Yhteystietojen poistaminen epäonnistui,,False,.Unable to remove contact information,,\n,Unable to restore previous session,Edellisen istunnon palauttaminen epäonnistui,,False,.Unable to restore previous session,,\n,Unable to verify email address.,Sähköpostin varmentaminen epäonnistui.,,False,.Unable to verify email address.,,\n,Unban,Poista porttikielto,,False,.Unban,,\n,Unbans user with given id,Poistaa porttikiellon annetun ID:n omaavalta käyttäjältä,,False,.Unbans user with given id,,\n,%(senderName)s unbanned %(targetName)s.'", + "Username invalid: %(errMessage)s": "Virheellinen käyttäjänimi: %(errMessage)s", + "Users": "Käyttäjät", + "User": "Käyttäjä", + "Verification": "Varmennus", + "verified": "varmennettu", + "Verified": "Varmennettu", + "Verified key": "Varmennusavain", + "Video call": "Videopuhelu", + "Voice call": "Äänipuhelu", + "VoIP conference finished.": "VoIP konferenssi loppui.", + "VoIP conference started.": "VoIP konferenssi alkoi", + "VoIP is unsupported": "VoIP ei ole tuettu", + "(no answer)": "(ei vastausta)", + "(unknown failure: %(reason)s)": "(tuntematon virhe: %(reason)s)", + "(warning: cannot be disabled again!)": "(varoitus: ei voida ottaa pois käytöstä enää!)", + "Warning!": "Varoitus!", + "Who can access this room?": "Keillä on pääsy tähän huoneeseen?", + "Who can read history?": "Kuka pystyy lukemaan historian?", + "Who would you like to add to this room?": "Kenet sinä haluaisit lisätä tähän huoneeseen?", + "Who would you like to communicate with?": "Kenen kanssa haluaisit kommunikoida?", + "Would you like to accept or decline this invitation?": "Haluatko hyväksyä vai hylätä kutsun?", + "You already have existing direct chats with this user:": "Sinulla on jo keskusteluja käynnissä tämän käyttäjän kanssa:", + "You are already in a call.": "Sinulla on jo puhelu käynnissä.", + "You are not in this room.": "Sinä et ole tässä huoneessa.", + "You do not have permission to do that in this room.": "Sinulla ei ole oikeutta tehdä tuota tässä huoneessa.", + "You are trying to access %(roomName)s.": "Yrität liittyä huoneeseen %(roomName)s", + "You cannot place a call with yourself.": "Et voi soittaa itsellesi.", + "You cannot place VoIP calls in this browser.": "Et voi soittaa VoIP puheluita tällä selaimella.", + "You do not have permission to post to this room": "Sinulla ei ole oikeutta kirjoittaa tässä huoneessa", + "You have been banned from %(roomName)s by %(userName)s.": "Käyttäjä %(userName)s on antanut sinulle porttikiellon huoneeseen %(roomName)s", + "You have been invited to join this room by %(inviterName)s": "Käyttäjä %(userName)s on kutsunut sinut tähän huoneeseen", + "You have been kicked from %(roomName)s by %(userName)s.": "Käyttäjä %(userName)s on poistanut sinut huoneesta %(roomName)s.", + "You have disabled URL previews by default.": "Olet oletusarvoisesti ottanut URL esikatselut pois käytöstä.", + "You have enabled URL previews by default.": "Olet oletusarvoisesti ottanut URL esikatselut käyttöön.", + "You have entered an invalid contact. Try using their Matrix ID or email address.": "Olet syöttänyt virheellisen kontaktin. Yritä käyttää heidän Matrixtunnistetta tai sähköpostiosoitetta.", + "You have no visible notifications": "Sinulla ei ole näkyviä ilmoituksia.", + "You must register to use this functionality": "Sinun pitää rekisteröityä käyttääksesi tätä toiminnallisuutta", + "You need to be able to invite users to do that.": "Sinun pitää pystyä kutsua käyttäjiä voidaksesi tehdä tuon.", + "You need to be logged in.": "Sinun pitää olla kirjautunut.", + "You need to enter a user name.": "Sinun pitää syöttää käyttäjänimi.", + "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Sinun sähköpostiosoitteesi ei vaikuta olevan liitetty mihinkään Matrixtunnisteeseen tällä kotipalvelimella.", + "Your password has been reset": "Salasanasi on palautettu", + "You should not yet trust it to secure data": "Sinun ei vielä kannata luottaa siihen turvataksesi dataa.", + "Your home server does not support device management.": "Kotipalvelimesi ei tue laitteiden hallintaa.", + "Sun": "Su", + "Mon": "Ma", + "Tue": "Ti", + "Wed": "Ke", + "Thu": "To", + "Fri": "Pe", + "Sat": "La", + "Set a display name:": "Aseta näyttönimi:", + "Set a Display Name": "Aseta näyttönimi:", + "This server does not support authentication with a phone number.": "Tämä palvelin ei tue autentikointia puhelinnumeron avulla.", + "Missing password.": "Salasana puuttuu.", + "Passwords don't match.": "Salasanat eivät täsmää.", + "Password too short (min %(MIN_PASSWORD_LENGTH)s).": "Salasana on liian lyhyt (minimi %(MIN_PASSWORD_LENGTH)s).", + "This doesn't look like a valid email address.": "Tämä ei näytä oikealta sähköpostiosoitteelta.", + "This doesn't look like a valid phone number.": "Tämä ei näytä oikealta puhelinnumerolta.", + "An unknown error occurred.": "Tuntematon virhe.", + "I already have an account": "Minulla on jo tili", + "An error occurred: %(error_string)s": "Virhe: %(error_string)s", + "Topic": "Aihe", + "Make this room private": "Tee tästä huoneesta yksityinen", + "Share message history with new users": "Jaa viestihistoria uusille käyttäjille", + "Encrypt room": "Salaa huone", + "There are no visible files in this room": "Tässä huoneessa ei tiedostoja näkyvissä", + "Room": "Huone", + "Copied!": "Kopioitu!", + "Failed to copy": "Kopiointi epäonnistui", + "Connectivity to the server has been lost.": "Yhteys palvelimeen menetettiin.", + "Sent messages will be stored until your connection has returned.": "Lähetetyt viestit tallennetaan kunnes yhteys on taas muodostettu.", + "Auto-complete": "Automaattitäydennys", + "Resend all or cancel all now. You can also select individual messages to resend or cancel.": "Uudelleenlähetä kaikki tai hylkää kaikki nyt. Voit myös valita yksittäisiä viestejä uudelleenlähetettäväksi tai hylättäväksi.", + "(~%(count)s results)|one": "(~%(count)s tulos)", + "(~%(count)s results)|other": "(~%(count)s tulosta)", + "or": "tai", + "Active call": "Aktiivinen puhelu", + "bold": "lihavoitu", + "italic": "kursiivi", + "strike": "ylivedetty", + "underline": "alleviivattu", + "code": "koodi", + "quote": "sitaatti", + "bullet": "lista", + "numbullet": "numeroitu lista", + "%(severalUsers)sjoined %(repeats)s times": "%(severalUsers)sliittyivät %(repeats)s kertaa’,,False,.%(severalUsers)sjoined %(repeats)s times,,\n,%(oneUser)sjoined %(repeats)s times'", + "%(oneUser)srejected their invitation %(repeats)s times": "%(oneUser)shylkäsi kutsunsa %(repeats)s kertaa’,,False,.%(oneUser)srejected their invitation %(repeats)s times,,\n,%(severalUsers)srejected their invitations'", + "Please select the destination room for this message": "Ole hyvä ja valitse vastaanottava huone tälle viestille", + "New Password": "Uusi salasana", + "Start automatically after system login": "Käynnistä automaattisesti käyttöjärjestelmään kirjautumisen jälkeen", + "Desktop specific": "Työpöytäkäytön asetukset", + "Analytics": "Analytiikka", + "Opt out of analytics": "Ota analytiikka pois käytöstä", + "Options": "Valinnat", + "Riot collects anonymous analytics to allow us to improve the application.": "Riot kerää anonyymisti tilastoja jotta voimme parantaa ohjelmistoa", + "Passphrases must match": "Salasanojen on täsmättävä", + "Passphrase must not be empty": "Salasana ei saa olla tyhjä", + "Export room keys": "Vie huoneen avaimet", + "Confirm passphrase": "Varmista salasana", + "Import room keys": "Tuo huoneen avaimet", + "File to import": "Tiedosto", + "You must join the room to see its files": "Sinun pitää liittyä huoneeseen voidaksesi nähdä sen sisältämät tiedostot", + "Reject all %(invitedRooms)s invites": "Hylkää kaikki %(invitedRooms)s kutsut", + "Start new chat": "Aloita uusi keskustelu", + "Guest users can't invite users. Please register.": "Vierailijat eivät voi lähettää kutsuja. Ole hyvä ja rekisteröidy.", + "Failed to invite": "Kutsu epäonnistui", + "Failed to invite user": "Käyttäjän kutsuminen epäonnistui", + "Failed to invite the following users to the %(roomName)s room:": "Seuraavian käyttäjien kutsuminen huoneeseen %(roomName)s epäonnistui:", + "Confirm Removal": "Varmista poistaminen", + "Unknown error": "Tuntematon virhe", + "Incorrect password": "Virheellinen salasana", + "This action is irreversible.": "Tätä toimintoa ei voi perua.", + "Device name": "Laitenimi", + "Device Name": "Laitenimi", + "Device key": "Laiteavain", + "In future this verification process will be more sophisticated.": "Tulevaisuudessa tämä varmennusprosessi tulee olemaan hienostuneempi.", + "Verify device": "Varmenna laite", + "I verify that the keys match": "Totean että avaimet vastaavat toisiaan.", + "Unable to restore session": "Istunnon palautus epäonnistui", + "Continue anyway": "Jatka kuitenkin" } From ff503fce3b0ecb4bcd691084dd91c2381b565318 Mon Sep 17 00:00:00 2001 From: Stefan Parviainen Date: Mon, 18 Sep 2017 09:53:17 +0000 Subject: [PATCH 011/123] Translated using Weblate (Finnish) Currently translated at 59.7% (511 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fi/ --- src/i18n/strings/fi.json | 70 ++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/i18n/strings/fi.json b/src/i18n/strings/fi.json index 5456a4d22f..204d02a106 100644 --- a/src/i18n/strings/fi.json +++ b/src/i18n/strings/fi.json @@ -113,8 +113,8 @@ "Click to unmute audio": "Paina poistaaksesi äänimykistyksen", "Command error": "Komentovirhe", "Commands": "Komennot", - "Conference call failed.": "Konferenssipuhelu epäonnistui", - "Conference calling is in development and may not be reliable.": "Konferenssipuhelut ovat vielä kehityksen alla ja saattavat toimia epäluotettavasti", + "Conference call failed.": "Konferenssipuhelu epäonnistui.", + "Conference calling is in development and may not be reliable.": "Konferenssipuhelut ovat vielä kehityksen alla ja saattavat toimia epäluotettavasti.", "Conference calls are not supported in encrypted rooms": "Konferenssipuhelut eivät ole mahdollisia salatuissa huoneissa", "Conference calls are not supported in this client": "Tämä asiakasohjelma ei tue konferenssipuheluja", "Confirm password": "Varmista salasana", @@ -138,7 +138,7 @@ "Device already verified!": "Laite on jo varmennettu!", "Device ID": "Laitetunniste", "Device ID:": "Laitetunniste:", - "device id: ": "laitetunniste:", + "device id: ": "laitetunniste: ", "Device key:": "Laiteavain:", "Devices": "Laitteet", "Direct chats": "Suorat viestittelyt", @@ -170,7 +170,7 @@ "Error decrypting attachment": "Liitteen salauksen purku epäonnistui", "Event information": "Tapahtumatiedot", "Export": "Vie", - "Export E2E room keys": "Vie huoneen päästä päähän-salauksen (E2E) avaimet ", + "Export E2E room keys": "Vie huoneen päästä päähän-salauksen (E2E) avaimet", "Failed to ban user": "Porttikiellon antaminen epäonnistui", "Failed to delete device": "Laitten poistamine epäonnistui", "Failed to fetch avatar URL": "Avatar URL:n haku epäonnistui", @@ -179,12 +179,12 @@ "Failed to leave room": "Huoneesta poistuminen epäonnistui", "Failed to load timeline position": "Aikajanapaikan lataaminen epäonnistui", "Failed to mute user": "Käyttäjän mykistäminen epäonnistui", - "Failed to register as guest:": "Vieraana rekisteröityminen epäonnistui", + "Failed to register as guest:": "Vieraana rekisteröityminen epäonnistui:", "Failed to reject invite": "Kutsun hylkääminen epäonnistui", "Failed to reject invitation": "Kutsun hylkääminen epäonnistui", "Failed to save settings": "Asetusten tallentaminen epäonnistui", "Failed to send email": "Sähköpostin lähettäminen epäonnistui", - "Failed to send request.": "Pyynnön lähettäminen epäonnistui", + "Failed to send request.": "Pyynnön lähettäminen epäonnistui.", "Failed to set display name": "Näyttönimen asettaminen epäonnistui", "Failed to set up conference call": "Konferenssipuhelun alustus epäonnistui", "Failed to toggle moderator status": "Moderaattoriasetuksen muuttaminen epäonnistui", @@ -214,7 +214,7 @@ "Incoming call from %(name)s": "Saapuva puhelu käyttäjältä %(name)s", "Incoming video call from %(name)s": "Saapuva videopuhelu käyttäjältä %(name)s", "Incoming voice call from %(name)s": "Saapuva äänipuhelu käyttäjältä %(name)s", - "Incorrect username and/or password.": "Virheellinen käyttäjänimi ja/tai salasana", + "Incorrect username and/or password.": "Virheellinen käyttäjänimi ja/tai salasana.", "Incorrect verification code": "Virheellinen varmennuskoodi", "Integrations Error": "Integraatiovirhe", "Interface Language": "Käyttöliittymän kieli", @@ -230,7 +230,7 @@ "joined and left": "liittyi ja poistui", "joined": "liittyi", "Joins room with given alias": "Liittyy huoneeseen jolla on annettu alias", - "Jump to first unread message.": "Hyppää ensimmäiseen lukemattomaan viestiin", + "Jump to first unread message.": "Hyppää ensimmäiseen lukemattomaan viestiin.", "Kick": "Poista huoneesta", "Kicks user with given id": "Poistaa käyttäjätunnisteen mukaisen käyttäjän huoneesta", "Labs": "Laboratorio", @@ -258,7 +258,7 @@ "Name": "Nimi", "New password": "Uusi salasana", "New passwords don't match": "Uudet salasanat eivät täsmää", - "New passwords must match each other.": "Uusien salasanojen on vastattava toisiaan", + "New passwords must match each other.": "Uusien salasanojen on vastattava toisiaan.", "not set": "ei asetettu", "not specified": "ei määritetty", "(not supported by this browser)": "(ei tuettu tässä selaimessa)", @@ -320,7 +320,7 @@ "Sign out": "Kirjaudu ulos", "since they joined": "liittymisestä lähtien", "since they were invited": "kutsusta lähtien", - "Some of your messages have not been sent.": "Jotkut viesteistäsi ei ole lähetetty", + "Some of your messages have not been sent.": "Jotkut viesteistäsi ei ole lähetetty.", "Someone": "Joku", "Start a chat": "Aloita keskustelu", "Start Chat": "Aloita keskustelu", @@ -341,7 +341,7 @@ "unknown caller": "tuntematon soittaja", "unknown device": "tuntematon laite", "Unknown room %(roomId)s": "Tuntematon huone %(roomId)s", - "Unknown (user, device) pair:": "Tuntematon (käyttäjä,laite) -pari.", + "Unknown (user, device) pair:": "Tuntematon (käyttäjä,laite) -pari:", "unknown": "tuntematon", "Unmute": "Poista mykistys", "Unnamed Room": "Nimeämätön huone", @@ -351,37 +351,37 @@ "Uploading %(filename)s and %(count)s others|zero": "Ladataan %(filename)s", "Uploading %(filename)s and %(count)s others|one": "Ladataan %(filename)s ja %(count)s muuta", "Blacklisted": "Estetyt", - "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s muuti huoneen nimeksi %(roomName)s.’,,False,.%(senderDisplayName)s changed the room name to %(roomName)s.,,\n,%(senderDisplayName)s removed the room name.'", + "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s muuti huoneen nimeksi %(roomName)s.", "Drop here to tag %(section)s": "Pudota tähän tägätäksesi %(section)s", "Enable automatic language detection for syntax highlighting": "Ota automaattinen kielentunnistus käyttöön koodin väritystä varten", "Encrypted messages will not be visible on clients that do not yet implement encryption": "Salatut viestit eivät näy ohjelmissa joissa salaus ei ole vielä implementoitu", - "%(senderName)s ended the call.": "%(senderName)s lopetti puhelun.’,,False,.%(senderName)s ended the call.,,\n,End-to-end encryption information,Päästä päähän-salauksen tiedot,,False,.End-to-end encryption information,,\n,End-to-end encryption is in beta and may not be reliable,Päästä päähän salaus on vielä testausvaiheessa ja saattaa toimia epävarmasti,,False,.End-to-end encryption is in beta and may not be reliable,,\n,Enter Code,Syötä koodi,,False,.Enter Code,,\n,Enter passphrase,Syötä salasana,,False,.Enter passphrase,,\n,Error,Virhe,,False,.Error,,\n,Error decrypting attachment,Liitteen salauksen purku epäonnistui,,False,.Error decrypting attachment,,\n,Error: Problem communicating with the given homeserver.,Virhe: Ongelma yhteydenpidossa kotipalvelimeen,,False,.Error: Problem communicating with the given homeserver.,,\n,Event information,Tapahtumatiedot,,False,.Event information,,\n,Existing Call,Käynnissä oleva puhelu,,False,.Existing Call,,\n,Export,Vie,,False,.Export,,\n,Export E2E room keys,Vie huoneen päästä päähän-salauksen (E2E) avaimet ,,False,.Export E2E room keys,,\n,Failed to ban user,Porttikiellon antaminen epäonnistui,,False,.Failed to ban user,,\n,Failed to change password. Is your password correct?,Salasanan muuttaminen epäonnistui. Onko salasanasi oikein?,,False,.Failed to change password. Is your password correct?,,\n,Failed to change power level,,,False,.Failed to change power level,,\n,Failed to delete device,Laitten poistamine epäonnistui,,False,.Failed to delete device,,\n,Failed to fetch avatar URL,Avatar URL:n haku epäonnistui,,False,.Failed to fetch avatar URL,,\n,Failed to forget room %(errCode)s,Huoneen unohtaminen epäonnistui %(errCode)s,,False,.Failed to forget room %(errCode)s,,\n,Failed to join room,Huoneeseen liittyminen epäonnistui,,False,.Failed to join room,,\n,Failed to join the room,Huoneeseen liittyminen epäonnistui,,False,.Failed to join the room,,\n,Failed to kick,Huoneesta poistaminen epäonnistui,,False,.Failed to kick,,\n,Failed to leave room,Huoneesta poistuminen epäonnistui,,False,.Failed to leave room,,\n,Failed to load timeline position,Aikajanapaikan lataaminen epäonnistui,,False,.Failed to load timeline position,,\n,Failed to lookup current room,Nykyisen huoneen löytäminen epäonnistui,,False,.Failed to lookup current room,,\n,Failed to mute user,Käyttäjän mykistäminen epäonnistui,,False,.Failed to mute user,,\n,Failed to register as guest:,Vieraana rekisteröityminen epäonnistui,,False,.Failed to register as guest:,,\n,Failed to reject invite,Kutsun hylkääminen epäonnistui,,False,.Failed to reject invite,,\n,Failed to reject invitation,Kutsun hylkääminen epäonnistui,,False,.Failed to reject invitation,,\n,Failed to save settings,Asetusten tallentaminen epäonnistui,,False,.Failed to save settings,,\n,Failed to send email,Sähköpostin lähettäminen epäonnistui,,False,.Failed to send email,,\n,Failed to send request.,Pyynnön lähettäminen epäonnistui,,False,.Failed to send request.,,\n,Failed to set avatar.,,,False,.Failed to set avatar.,,\n,Failed to set display name,Näyttönimen asettaminen epäonnistui,,False,.Failed to set display name,,\n,Failed to set up conference call,Konferenssipuhelun alustus epäonnistui,,False,.Failed to set up conference call,,\n,Failed to toggle moderator status,Moderaattoriasetuksen muuttaminen epäonnistui,,False,.Failed to toggle moderator status,,\n,Failed to unban,Porttikiellon poistaminen epäonnistui,,False,.Failed to unban,,\n,Failed to upload file,Tiedoston lataaminen epäonnistui,,False,.Failed to upload file,,\n,Failed to upload profile picture!,Profiilikuvan lataaminen epäonnistui,,False,.Failed to upload profile picture!,,\n,Failed to verify email address: make sure you clicked the link in the email,Varmenna sähköpostiosoitteesi: varmista että klikkasit sähköpostissa olevaa linkkiä,,False,.Failed to verify email address: make sure you clicked the link in the email,,\n,Failure to create room,Huoneen luominen epäonnistui,,False,.Failure to create room,,\n,Favourite,Suosikki,,False,.Favourite,,\n,favourite,suosikki,,False,.favourite,,\n,Favourites,Suosikit,,False,.Favourites,,\n,Fill screen,Täytä näyttö,,False,.Fill screen,,\n,Filter room members,Suodata huoneen jäsenet,,False,.Filter room members,,\n,Forget room,Unohda huone,,False,.Forget room,,\n,Forgot your password?,Unohditko salasanasi?,,False,.Forgot your password?,,\n,\"For security, this session has been signed out. Please sign in again.\",Turvallisuussyistä tämä istunto on vanhentunut. Ole hyvä ja kirjaudu uudestaan.,,False,\".For security, this session has been signed out. Please sign in again.\",,\n,\"For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.\",Turvallusuussyistä uloskirjautuminen poistaa kaikki päästä päähän-salausavaimet tästä selaimesta. Jos haluat purkaa keskustelujen salaukset tulevaisuudessa pitää sinun viedä purkuavaimet ja pitää ne turvallisesti tallessa.,,False,\".For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.\",,\n,Found a bug?,Löysitkö virheen?,,False,.Found a bug?,,\n,%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s'", + "%(senderName)s ended the call.": "%(senderName)s lopetti puhelun.", "Guest access is disabled on this Home Server.": "Vierailijat on estetty tällä kotipalvelimella.", - "Guest users can't create new rooms. Please register to create room and start a chat.": "Vierailijat eivät voi luoda huoneita. Ole hyvä ja rekisteröidy luodaksesi huoneen ja aloittaaksesi keskustelun", + "Guest users can't create new rooms. Please register to create room and start a chat.": "Vierailijat eivät voi luoda huoneita. Ole hyvä ja rekisteröidy luodaksesi huoneen ja aloittaaksesi keskustelun.", "Guest users can't upload files. Please register to upload.": "Vierailijat eivät voi ladata tiedostoja. Ole hyvä ja rekisteröidy voidaksesi ladata tiedostoja.", - "Guests can't use labs features. Please register.": "\"Vierailijat eivät voi käyttää kokeellisia toimintoja. Ole hyvä ja rekisteröidy", - "Guests cannot join this room even if explicitly invited.": "Vierailijat eivät voi liittyä tähän huoneeseen vaikka heidät on explisiittisesti kutsuttu", + "Guests can't use labs features. Please register.": "Vierailijat eivät voi käyttää kokeellisia toimintoja. Ole hyvä ja rekisteröidy.", + "Guests cannot join this room even if explicitly invited.": "Vierailijat eivät voi liittyä tähän huoneeseen vaikka heidät on eksplisiittisesti kutsuttu.", "Hangup": "Lopeta", "Hide join/leave messages (invites/kicks/bans unaffected)": "Piilota liittymis-/poistumisviestit (ei koske kutsuja/poistamisia/porttikieltoja)", "Historical": "Vanhat", "Home": "Etusivu", "Invalid file%(extra)s": "Virheellinen tiedosto%(extra)s", - "%(senderName)s invited %(targetName)s.": "%(senderName)s kutsui käyttäjän %(targetName)s.’,,False,.%(senderName)s invited %(targetName)s.,,\n,Invite new room members,Kutsu lisää jäseniä huoneeseen,,False,.Invite new room members,,\n,Invited,Kutsuttu,,False,.Invited,,\n,Invites,Kutsuu,,False,.Invites,,\n,Invites user with given id to current room,Kutsuu annetun käyttäjätunnisteen mukaisen käyttäjän huoneeseen,,False,.Invites user with given id to current room,,\n,%(alias)s' is not a valid format for an address", - "%(displayName)s is typing": "%(displayName)s kirjoittaa’,,False,.%(displayName)s is typing,,\n,Sign in with,Kirjaudu käyttäen,,False,.Sign in with,,\n,Join as voice or video.,Liitty käyttäen ääntä tai videota,,False,.Join as voice or video.,,\n,Join Room,Liity huoneeseen,,False,.Join Room,,\n,joined and left,liittyi ja poistui,,False,.joined and left,,\n,joined,liittyi,,False,.joined,,\n,%(targetName)s joined the room.'", - "%(senderName)s made future room history visible to": "%(senderName)s teki tulevista viesteistä näkyviä’,,False,.%(senderName)s made future room history visible to,,\n,Manage Integrations,Hallinoi integraatioita,,False,.Manage Integrations,,\n,Markdown is disabled,Markdown on pois päältä,,False,.Markdown is disabled,,\n,Markdown is enabled,Mardown on päällä,,False,.Markdown is enabled,,\n,matrix-react-sdk version:,Matrix-react-sdk versio:,,False,.matrix-react-sdk version:,,\n,Matrix Apps,Matrix ohjelmat,,False,.Matrix Apps,,\n,Members only,Vain jäsenet,,False,.Members only,,\n,Message not sent due to unknown devices being present,Viestiä ei lähetetty koska paikalla on tuntemattomia laitteita,,False,.Message not sent due to unknown devices being present,,\n,Missing room_id in request,room_id puuttuu kyselystä,,False,.Missing room_id in request,,\n,Missing user_id in request,user_id puuttuu kyselystä,,False,.Missing user_id in request,,\n,Mobile phone number,Matkapuhelinnumero,,False,.Mobile phone number,,\n,Mobile phone number (optional),Matkapuhelinnumero (valinnainen),,False,.Mobile phone number (optional),,\n,Moderator,Moderaattori,,False,.Moderator,,\n,Must be viewing a room,Pakko olla huoneessa,,False,.Must be viewing a room,,\n,Mute,Vaimenna,,False,.Mute,,\n,my Matrix ID,minun Matrix tunniste,,False,.my Matrix ID,,\n,Name,Nimi,,False,.Name,,\n,Never send encrypted messages to unverified devices from this device,Älä koskaa lähetä salattuja viestejä varmentamattomiin laitteisiin tältä laitteelta,,False,.Never send encrypted messages to unverified devices from this device,,\n,Never send encrypted messages to unverified devices in this room,Älä koskaa lähetä salattuja viestejä varmentamattomiin laitteisiin tässä huoneessa,,False,.Never send encrypted messages to unverified devices in this room,,\n,Never send encrypted messages to unverified devices in this room from this device,Älä koskaa lähetä salattuja viestejä varmentamattomiin laitteisiin tässä huoneessa tältä laitteelta,,False,.Never send encrypted messages to unverified devices in this room from this device,,\n,New address (e.g. #foo:%(localDomain)s),Uusi osoite (esim. #foo:%(localDomain)s),,False,.New address (e.g. #foo:%(localDomain)s),,\n,New Composer & Autocomplete,,,False,.New Composer & Autocomplete,,\n,New password,Uusi salasana,,False,.New password,,\n,New passwords dont match", + "%(senderName)s invited %(targetName)s.": "%(senderName)s kutsui käyttäjän %(targetName)s.", + "%(displayName)s is typing": "%(displayName)s kirjoittaa", + "%(senderName)s made future room history visible to": "%(senderName)s teki tulevista viesteistä näkyviä", "none": "Ei mikään", "No devices with registered encryption keys": "Ei laitteita joilla rekisteröityjä salausavaimia", "No users have specific privileges in this room": "Kellään käyttäjällä ei ole erityisiä oikeuksia", - "%(senderName)s placed a %(callType)s call.": "%(senderName)s soitti %(callType)spuhelun’,,False,.%(senderName)s placed a %(callType)s call.,,\n,\"Please check your email and click on the link it contains. Once this is done, click continue.\",Ole hyvä ja tarkista sähköpostisi ja seuraa sen sisältämää linkkiä. Voit jatkaa tämän jälkeen.,,False,\".Please check your email and click on the link it contains. Once this is done, click continue.\",,\n,Please Register,Ole hyvä ja rekisteröidy,,False,.Please Register,,\n,Power level must be positive integer.,,,False,.Power level must be positive integer.,,\n,Press,,,False,.Press,,\n,Press to start a chat with someone,Paina ,,False,.Press to start a chat with someone,,\n,Privacy warning,Yksityisyysvaroitus,,False,.Privacy warning,,\n,Private Chat,Yksityinen keskustelu,,False,.Private Chat,,\n,Privileged Users,,,False,.Privileged Users,,\n,Profile,Profiili,,False,.Profile,,\n,Public Chat,Julkinen keskustelu,,False,.Public Chat,,\n,Reason,Syy,,False,.Reason,,\n,Reason: %(reasonText)s,Syy: %(reasonText)s,,False,.Reason: %(reasonText)s,,\n,Revoke Moderator,Poista moderaattorioikeudet,,False,.Revoke Moderator,,\n,Revoke widget access,,,False,.Revoke widget access,,\n,Refer a friend to Riot:,Suosittele Riot ystävälle:,,False,.Refer a friend to Riot:,,\n,Register,Rekisteröi,,False,.Register,,\n,rejected,hylätty,,False,.rejected,,\n,%(targetName)s rejected the invitation.'", + "%(senderName)s placed a %(callType)s call.": "%(senderName)s soitti %(callType)spuhelun.", "Remove %(threePid)s?": "Poista %(threePid)s?", - "%(senderName)s requested a VoIP conference.": "%(senderName)s pyysi VoIP konferenssia.’,,False,.%(senderName)s requested a VoIP conference.,,\n,Report it,Ilmoita siitä,,False,.Report it,,\n,\"Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.\",,,False,\".Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.\",,\n,restore,palauta,,False,.restore,,\n,Results from DuckDuckGo,DuckDuckGo:n tulokset,,False,.Results from DuckDuckGo,,\n,Return to app,Palaa ohjelmaan,,False,.Return to app,,\n,Return to login screen,Palaa kirjautumissivulle,,False,.Return to login screen,,\n,Riot does not have permission to send you notifications - please check your browser settings,Riotilla ei ole oikeuksia lähettää sinulle ilmoituksia. Ole hyvä ja tarkista selaimen asetukset,,False,.Riot does not have permission to send you notifications - please check your browser settings,,\n,Riot was not given permission to send notifications - please try again,Riotilla ei saannut oikeuksia lähettää ilmoituksia. Ole hyvä ja yritä uudelleen,,False,.Riot was not given permission to send notifications - please try again,,\n,riot-web version:,Riot-web versio:,,False,.riot-web version:,,\n,Room %(roomId)s not visible,Huone %(roomId)s ei ole näkyvissä,,False,.Room %(roomId)s not visible,,\n,Room Colour,Huoneen väri,,False,.Room Colour,,\n,Room contains unknown devices,Huone sisältää tuntemattomia laitteita,,False,.Room contains unknown devices,,\n,Room name (optional),Huoneen nimi (valinnainen),,False,.Room name (optional),,\n,%(roomName)s does not exist.'", - "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s asetti näyttönimekseen %(displayName)s.’,,False,.%(senderName)s set their display name to %(displayName)s.,,\n,Set,Aseta,,False,.Set,,\n,Settings,Asetukset,,False,.Settings,,\n,Sets the room topic,Asettaa huoneen aiheen,,False,.Sets the room topic,,\n,Show Apps,,,False,.Show Apps,,\n,Show panel,Näytä paneeli,,False,.Show panel,,\n,Show Text Formatting Toolbar,Näytä tekstinmuotoilupalkki,,False,.Show Text Formatting Toolbar,,\n,Show timestamps in 12 hour format (e.g. 2:30pm),Näytä aikaleimat 12h muodossa (esim. 2:30pm),,False,.Show timestamps in 12 hour format (e.g. 2:30pm),,\n,Signed Out,Uloskirjautunut,,False,.Signed Out,,\n,Sign in,Kirjaudu sisään,,False,.Sign in,,\n,Sign out,Kirjaudu ulos,,False,.Sign out,,\n,since the point in time of selecting this option,tämän asetuksen valitsemisesta,,False,.since the point in time of selecting this option,,\n,since they joined,liittymisestä lähtien,,False,.since they joined,,\n,since they were invited,kutsusta lähtien,,False,.since they were invited,,\n,Some of your messages have not been sent.,Jotkut viesteistäsi ei ole lähetetty,,False,.Some of your messages have not been sent.,,\n,Someone,Joku,,False,.Someone,,\n,\"Sorry, this homeserver is using a login which is not recognised \",Valitettavasti tämä kotipalvelin käyttää sisäänkirjautumista jota ei tunnistettu,,False,\".Sorry, this homeserver is using a login which is not recognised \",,\n,Start a chat,Aloita keskustelu,,False,.Start a chat,,\n,Start authentication,Aloita tunnistus,,False,.Start authentication,,\n,Start Chat,Aloita keskustelu,,False,.Start Chat,,\n,Submit,Lähetä,,False,.Submit,,\n,Success,Onnistuminen,,False,.Success,,\n,tag as %(tagName)s,lisää tägi %(tagName)s,,False,.tag as %(tagName)s,,\n,tag direct chat,tägää suora viestittely,,False,.tag direct chat,,\n,Tagged as: ,Tägit:,,False,.Tagged as: ,,\n,The default role for new room members is,Huoneen uusien jäsenten oletusrooli on,,False,.The default role for new room members is,,\n,The main address for this room is,Tämän huoneen pääosoite on,,False,.The main address for this room is,,\n,The maximum permitted number of widgets have already been added to this room.,,,False,.The maximum permitted number of widgets have already been added to this room.,,\n,The phone number entered looks invalid,Syötetty puhelinnumero näyttää virheelliseltä,,False,.The phone number entered looks invalid,,\n,The signing key you provided matches the signing key you received from %(userId)ss device %(deviceId)s. Device marked as verified.", + "%(senderName)s requested a VoIP conference.": "%(senderName)s pyysi VoIP konferenssia.", + "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s asetti näyttönimekseen %(displayName)s.", "This action cannot be performed by a guest user. Please register to be able to do this.": "Vierailija ei voi suorittaa tätä toimintoa. Ole hyvä ja rekisteröidy suorittaaksesi toiminnon.", "The file '%(fileName)s' exceeds this home server's size limit for uploads": "Tiedosto ‘%(fileName)s’ ylittää tämän kotipalvelimen maksimitiedostokoon", "The file '%(fileName)s' failed to upload": "Tiedoston ‘%(fileName)s’ lataaminen epäonnistui", "This Home Server does not support login using email address.": "Kotipalvelin ei tue kirjatumista sähköpostiosoitteen avulla.", "This invitation was sent to an email address which is not associated with this account:": "Kutsu lähetettiin sähköpostiosoitteeseen jota ei ole liitetty tähän tiliin:", - "This room is not recognised.": "Huonetta ei tunnistettu", + "This room is not recognised.": "Huonetta ei tunnistettu.", "These are experimental features that may break in unexpected ways": "Nämä ovat kokeellisia ominaisuuksia jotka saattavat toimia ennakoimattomilla tavoilla", "This doesn't appear to be a valid email address": "Olemassa olevan historian näkyvyys ei muutu", "This is a preview of this room. Room interactions have been disabled": "Tämä on huoneen ennakokatselu. Vuorovaikutus ei ole mahdollista", @@ -390,7 +390,7 @@ "To link to a room it must have an address.": "Linkittääksesi tähän huoneseen sillä on oltava osoite.", "Turn Markdown off": "Ota Markdown pois käytöstä", "Turn Markdown on": "Ota Markdown käyttöön", - "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s otti päästä päähän-salauksen käyttöön (algoritmi %(algorithm)s).’,,False,.%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).,,\n,Unable to add email address,Sähköpostiosoitteen lisääminen epäonnistui,,False,.Unable to add email address,,\n,Unable to create widget.,,,False,.Unable to create widget.,,\n,Unable to remove contact information,Yhteystietojen poistaminen epäonnistui,,False,.Unable to remove contact information,,\n,Unable to restore previous session,Edellisen istunnon palauttaminen epäonnistui,,False,.Unable to restore previous session,,\n,Unable to verify email address.,Sähköpostin varmentaminen epäonnistui.,,False,.Unable to verify email address.,,\n,Unban,Poista porttikielto,,False,.Unban,,\n,Unbans user with given id,Poistaa porttikiellon annetun ID:n omaavalta käyttäjältä,,False,.Unbans user with given id,,\n,%(senderName)s unbanned %(targetName)s.'", + "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s otti päästä päähän-salauksen käyttöön (algoritmi %(algorithm)s).", "Username invalid: %(errMessage)s": "Virheellinen käyttäjänimi: %(errMessage)s", "Users": "Käyttäjät", "User": "Käyttäjä", @@ -401,7 +401,7 @@ "Video call": "Videopuhelu", "Voice call": "Äänipuhelu", "VoIP conference finished.": "VoIP konferenssi loppui.", - "VoIP conference started.": "VoIP konferenssi alkoi", + "VoIP conference started.": "VoIP konferenssi alkoi.", "VoIP is unsupported": "VoIP ei ole tuettu", "(no answer)": "(ei vastausta)", "(unknown failure: %(reason)s)": "(tuntematon virhe: %(reason)s)", @@ -416,24 +416,24 @@ "You are already in a call.": "Sinulla on jo puhelu käynnissä.", "You are not in this room.": "Sinä et ole tässä huoneessa.", "You do not have permission to do that in this room.": "Sinulla ei ole oikeutta tehdä tuota tässä huoneessa.", - "You are trying to access %(roomName)s.": "Yrität liittyä huoneeseen %(roomName)s", + "You are trying to access %(roomName)s.": "Yrität liittyä huoneeseen %(roomName)s.", "You cannot place a call with yourself.": "Et voi soittaa itsellesi.", "You cannot place VoIP calls in this browser.": "Et voi soittaa VoIP puheluita tällä selaimella.", "You do not have permission to post to this room": "Sinulla ei ole oikeutta kirjoittaa tässä huoneessa", - "You have been banned from %(roomName)s by %(userName)s.": "Käyttäjä %(userName)s on antanut sinulle porttikiellon huoneeseen %(roomName)s", - "You have been invited to join this room by %(inviterName)s": "Käyttäjä %(userName)s on kutsunut sinut tähän huoneeseen", + "You have been banned from %(roomName)s by %(userName)s.": "Käyttäjä %(userName)s on antanut sinulle porttikiellon huoneeseen %(roomName)s.", + "You have been invited to join this room by %(inviterName)s": "Käyttäjä %(inviterName)s on kutsunut sinut tähän huoneeseen", "You have been kicked from %(roomName)s by %(userName)s.": "Käyttäjä %(userName)s on poistanut sinut huoneesta %(roomName)s.", "You have disabled URL previews by default.": "Olet oletusarvoisesti ottanut URL esikatselut pois käytöstä.", "You have enabled URL previews by default.": "Olet oletusarvoisesti ottanut URL esikatselut käyttöön.", "You have entered an invalid contact. Try using their Matrix ID or email address.": "Olet syöttänyt virheellisen kontaktin. Yritä käyttää heidän Matrixtunnistetta tai sähköpostiosoitetta.", - "You have no visible notifications": "Sinulla ei ole näkyviä ilmoituksia.", + "You have no visible notifications": "Sinulla ei ole näkyviä ilmoituksia", "You must register to use this functionality": "Sinun pitää rekisteröityä käyttääksesi tätä toiminnallisuutta", "You need to be able to invite users to do that.": "Sinun pitää pystyä kutsua käyttäjiä voidaksesi tehdä tuon.", "You need to be logged in.": "Sinun pitää olla kirjautunut.", "You need to enter a user name.": "Sinun pitää syöttää käyttäjänimi.", "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Sinun sähköpostiosoitteesi ei vaikuta olevan liitetty mihinkään Matrixtunnisteeseen tällä kotipalvelimella.", "Your password has been reset": "Salasanasi on palautettu", - "You should not yet trust it to secure data": "Sinun ei vielä kannata luottaa siihen turvataksesi dataa.", + "You should not yet trust it to secure data": "Sinun ei vielä kannata luottaa siihen turvataksesi dataa", "Your home server does not support device management.": "Kotipalvelimesi ei tue laitteiden hallintaa.", "Sun": "Su", "Mon": "Ma", @@ -443,7 +443,7 @@ "Fri": "Pe", "Sat": "La", "Set a display name:": "Aseta näyttönimi:", - "Set a Display Name": "Aseta näyttönimi:", + "Set a Display Name": "Aseta näyttönimi", "This server does not support authentication with a phone number.": "Tämä palvelin ei tue autentikointia puhelinnumeron avulla.", "Missing password.": "Salasana puuttuu.", "Passwords don't match.": "Salasanat eivät täsmää.", @@ -477,8 +477,8 @@ "quote": "sitaatti", "bullet": "lista", "numbullet": "numeroitu lista", - "%(severalUsers)sjoined %(repeats)s times": "%(severalUsers)sliittyivät %(repeats)s kertaa’,,False,.%(severalUsers)sjoined %(repeats)s times,,\n,%(oneUser)sjoined %(repeats)s times'", - "%(oneUser)srejected their invitation %(repeats)s times": "%(oneUser)shylkäsi kutsunsa %(repeats)s kertaa’,,False,.%(oneUser)srejected their invitation %(repeats)s times,,\n,%(severalUsers)srejected their invitations'", + "%(severalUsers)sjoined %(repeats)s times": "%(severalUsers)sliittyivät %(repeats)s kertaa", + "%(oneUser)srejected their invitation %(repeats)s times": "%(oneUser)shylkäsi kutsunsa %(repeats)s kertaa", "Please select the destination room for this message": "Ole hyvä ja valitse vastaanottava huone tälle viestille", "New Password": "Uusi salasana", "Start automatically after system login": "Käynnistä automaattisesti käyttöjärjestelmään kirjautumisen jälkeen", @@ -486,7 +486,7 @@ "Analytics": "Analytiikka", "Opt out of analytics": "Ota analytiikka pois käytöstä", "Options": "Valinnat", - "Riot collects anonymous analytics to allow us to improve the application.": "Riot kerää anonyymisti tilastoja jotta voimme parantaa ohjelmistoa", + "Riot collects anonymous analytics to allow us to improve the application.": "Riot kerää anonyymisti tilastoja jotta voimme parantaa ohjelmistoa.", "Passphrases must match": "Salasanojen on täsmättävä", "Passphrase must not be empty": "Salasana ei saa olla tyhjä", "Export room keys": "Vie huoneen avaimet", @@ -509,7 +509,7 @@ "Device key": "Laiteavain", "In future this verification process will be more sophisticated.": "Tulevaisuudessa tämä varmennusprosessi tulee olemaan hienostuneempi.", "Verify device": "Varmenna laite", - "I verify that the keys match": "Totean että avaimet vastaavat toisiaan.", + "I verify that the keys match": "Totean että avaimet vastaavat toisiaan", "Unable to restore session": "Istunnon palautus epäonnistui", "Continue anyway": "Jatka kuitenkin" } From 35cdea44bdfe73479f7b1a66959e6d78ab3e7ed7 Mon Sep 17 00:00:00 2001 From: Max Sandholm Date: Mon, 18 Sep 2017 08:01:03 +0000 Subject: [PATCH 012/123] Translated using Weblate (Swedish) Currently translated at 52.6% (450 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sv/ --- src/i18n/strings/sv.json | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sv.json b/src/i18n/strings/sv.json index 298c0c4d86..c684f4c5ab 100644 --- a/src/i18n/strings/sv.json +++ b/src/i18n/strings/sv.json @@ -430,5 +430,28 @@ "Enable automatic language detection for syntax highlighting": "Aktivera automatisk språkdetektering för syntaxmarkering", "Hide Apps": "Dölj Appar", "Hide avatar and display name changes": "Dölj avatar och visningsnamns ändringar", - "Integrations Error": "Integrationsfel" + "Integrations Error": "Integrationsfel", + "Publish this room to the public in %(domain)s's room directory?": "Publicera rummet i den offentliga rumskatalogen på %(domain)s?", + "Matrix Apps": "Matrix-appar", + "AM": "a.m.", + "PM": "p.m.", + "NOTE: Apps are not end-to-end encrypted": "OBS: Apparna är inte end-to-end-krypterade", + "Revoke widget access": "Upphäv widget-åtkomst", + "Show Apps": "Visa appar", + "Submit": "Lämna", + "tag as %(tagName)s": "tagga som %(tagName)s", + "tag direct chat": "tagga som direkt-chatt", + "Tagged as: ": "Taggad som: ", + "The default role for new room members is": "Standardrollen för nya medlemmar är", + "The main address for this room is": "Huvudadressen för det här rummet är", + "The maximum permitted number of widgets have already been added to this room.": "Den största tillåtna mängden widgetar har redan tillsats till rummet.", + "The phone number entered looks invalid": "Telefonnumret ser felaktigt ut", + "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Signeringsnyckeln du angav matchar signeringsnyckeln som mottogs från enheten %(deviceId)s som tillhör %(userId)s. Enheten är markerad som verifierad.", + "This action cannot be performed by a guest user. Please register to be able to do this.": "Den här handlingen kan inte utföras av en gästanvändare. Registrera dig för att kunna göra det här.", + "This email address is already in use": "Den här epostadressen är redan i bruk", + "This email address was not found": "Den här epostadressen fanns inte", + "%(actionVerb)s this person?": "%(actionVerb)s den här personen?", + "The email address linked to your account must be entered.": "Epostadressen som är kopplad till ditt konto måste anges.", + "The file '%(fileName)s' exceeds this home server's size limit for uploads": "Filen '%(fileName)s' överskrider serverns största tillåtna filstorlek", + "The file '%(fileName)s' failed to upload": "Filen '%(fileName)s' kunde inte laddas upp" } From 0c8a31d9e9cbaf3817b345aa4e2a476f42bf92c9 Mon Sep 17 00:00:00 2001 From: Stefan Parviainen Date: Mon, 18 Sep 2017 18:27:44 +0000 Subject: [PATCH 013/123] Translated using Weblate (Finnish) Currently translated at 73.2% (626 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fi/ --- src/i18n/strings/fi.json | 117 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fi.json b/src/i18n/strings/fi.json index 204d02a106..3da1fef551 100644 --- a/src/i18n/strings/fi.json +++ b/src/i18n/strings/fi.json @@ -511,5 +511,120 @@ "Verify device": "Varmenna laite", "I verify that the keys match": "Totean että avaimet vastaavat toisiaan", "Unable to restore session": "Istunnon palautus epäonnistui", - "Continue anyway": "Jatka kuitenkin" + "Continue anyway": "Jatka kuitenkin", + "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s poisti huoneen nimen.", + "Changes to who can read history will only apply to future messages in this room": "Muutokset koskien ketkä voivat lukea historian koskevat vain uusia viestejä", + "Click here to join the discussion!": "Paina tästä liittyäksesi keskusteluun", + "%(count)s new messages|one": "%(count)s uusi viesti", + "%(count)s new messages|other": "%(count)s uutta viestiä", + "Curve25519 identity key": "Curve25519 tunnistusavain", + "Decrypt %(text)s": "Pura %(text)s", + "Devices will not yet be able to decrypt history from before they joined the room": "Laitteet eivät vielä pysty purkamaan viestejä ajalta ennen kun ne liittyivät huoneseen", + "Disable inline URL previews by default": "Ota oletusarvoisesti pois käytöstä URL esikatselut", + "Displays action": "Näyttää toiminnan", + "Don't send typing notifications": "Älä lähetä kirjoitusilmoituksia", + "End-to-end encryption is in beta and may not be reliable": "Päästä päähän salaus on vielä testausvaiheessa ja saattaa toimia epävarmasti", + "Error: Problem communicating with the given homeserver.": "Virhe: Ongelma yhteydenpidossa kotipalvelimeen", + "Existing Call": "Käynnissä oleva puhelu", + "Failed to lookup current room": "Nykyisen huoneen löytäminen epäonnistui", + "Join as voice or video.": "Liitty käyttäen ääntä tai videota", + "%(targetName)s joined the room.": "%(targetName)s liittyi huoneeseen.", + "%(senderName)s kicked %(targetName)s.": "%(senderName)s poisti käyttäjän %(targetName)s huoneesta.", + "%(targetName)s left the room.": "%(targetName)s poistui huoneesta.", + "Publish this room to the public in %(domain)s's room directory?": "Julkaise tämä huone domainin %(domain)s huoneluettelossa?", + "Missing room_id in request": "room_id puuttuu kyselystä", + "Missing user_id in request": "user_id puuttuu kyselystä", + "Must be viewing a room": "Pakko olla huoneessa", + "Never send encrypted messages to unverified devices from this device": "Älä koskaa lähetä salattuja viestejä varmentamattomiin laitteisiin tältä laitteelta", + "Never send encrypted messages to unverified devices in this room": "Älä koskaa lähetä salattuja viestejä varmentamattomiin laitteisiin tässä huoneessa", + "Never send encrypted messages to unverified devices in this room from this device": "Älä koskaa lähetä salattuja viestejä varmentamattomiin laitteisiin tässä huoneessa tältä laitteelta", + "New address (e.g. #foo:%(localDomain)s)": "Uusi osoite (esim. #foo:%(localDomain)s)", + "Press to start a chat with someone": "Paina ", + "Revoke Moderator": "Poista moderaattorioikeudet", + "Refer a friend to Riot:": "Suosittele Riot ystävälle:", + "%(targetName)s rejected the invitation.": "%(targetName)s hylkäsi kutsun.", + "Remote addresses for this room:": "Tämän huoneen etäosoitteet:", + "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s poisti näyttönimensä (%(oldDisplayName)s).", + "Report it": "Ilmoita siitä", + "restore": "palauta", + "Return to app": "Palaa ohjelmaan", + "Riot does not have permission to send you notifications - please check your browser settings": "Riotilla ei ole oikeuksia lähettää sinulle ilmoituksia. Ole hyvä ja tarkista selaimen asetukset", + "Riot was not given permission to send notifications - please try again": "Riotilla ei saannut oikeuksia lähettää ilmoituksia. Ole hyvä ja yritä uudelleen", + "Room %(roomId)s not visible": "Huone %(roomId)s ei ole näkyvissä", + "%(roomName)s does not exist.": "%(roomName)s ei ole olemassa.", + "%(roomName)s is not accessible at this time.": "%(roomName)s ei ole saatavilla tällä hetkellä.", + "Seen by %(userName)s at %(dateTime)s": "Käyttäjän %(userName)s näkemä %(dateTime)s", + "Send Reset Email": "Lähetä salasanan palautusviesti", + "%(senderDisplayName)s sent an image.": "%(senderDisplayName)s lähetti kuvan.", + "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s lähetti kutsun käyttäjälle %(targetDisplayName)s liittyäkseen huoneeseen.", + "Server may be unavailable or overloaded": "Palvelin saattaa olla saavuttamattomissa tai ylikuormitettu", + "Show Text Formatting Toolbar": "Näytä tekstinmuotoilupalkki", + "Show timestamps in 12 hour format (e.g. 2:30pm)": "Näytä aikaleimat 12h muodossa (esim. 2:30pm)", + "Signed Out": "Uloskirjautunut", + "since the point in time of selecting this option": "tämän asetuksen valitsemisesta", + "Start authentication": "Aloita tunnistus", + "Success": "Onnistuminen", + "tag as %(tagName)s": "lisää tägi %(tagName)s", + "tag direct chat": "tägää suora viestittely", + "Tagged as: ": "Tägit:", + "The default role for new room members is": "Huoneen uusien jäsenten oletusrooli on", + "The main address for this room is": "Tämän huoneen pääosoite on", + "The phone number entered looks invalid": "Syötetty puhelinnumero näyttää virheelliseltä", + "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Syöttämäsi allekirjoitusavain vastaa käyttäjältä %(userId)s saamaasi allekirjoitusavainta. Laite on merkitty varmennetuksi.'", + "Unable to add email address": "Sähköpostiosoitteen lisääminen epäonnistui", + "Unable to remove contact information": "Yhteystietojen poistaminen epäonnistui", + "Unable to restore previous session": "Edellisen istunnon palauttaminen epäonnistui", + "Unable to verify email address.": "Sähköpostin varmentaminen epäonnistui.", + "Unbans user with given id": "Poistaa porttikiellon annetun ID:n omaavalta käyttäjältä", + "%(senderName)s unbanned %(targetName)s.": "%(senderName)s poisti porttikiellon käyttäjältä %(targetName)s.", + "Unable to capture screen": "Ruudun kaappaus epäonnistui", + "Unable to enable Notifications": "Ilmoitusten käyttöönotto epäonnistui", + "Unable to load device list": "Laitelistan lataaminen epäonnistui", + "Uploading %(filename)s and %(count)s others|other": "Ladataan %(filename)s ja %(count)s muuta", + "uploaded a file": "lattaa tiedosto", + "Upload Failed": "Lataus epäonnistui", + "Upload Files": "Lataa tiedostoja", + "Upload file": "Lataa tiedosto", + "Upload new:": "Lataa uusi:", + "Usage": "Käyttö", + "Use compact timeline layout": "Käytä kompaktia aikajanaa", + "Use with caution": "Käytä varoen", + "User ID": "Käyttäjätunniste", + "User Interface": "Käyttöliittymä", + "%(user)s is a": "%(user)s on", + "User name": "Käyttäjänimi", + "%(oneUser)sjoined %(repeats)s times": "%(oneUser)sliittyi %(repeat)s kertaa", + "%(severalUsers)sjoined": "%(severalUsers)sliittyivät", + "%(oneUser)sjoined": "%(oneUser)sliittyi", + "%(severalUsers)sleft %(repeats)s times": "%(severalUsers)spoistuivat %(repeat)s kertaa", + "%(oneUser)sleft %(repeats)s times": "%(oneUser)spoistui %(repeat)s kertaa", + "%(severalUsers)sleft": "%(severalUsers)sspoistuivat", + "%(oneUser)sleft": "%(oneUser)spoistui", + "%(severalUsers)sjoined and left %(repeats)s times": "%(severalUsers)sliittyivät ja poistuivat %(repeats)s kertaa", + "%(oneUser)sjoined and left %(repeats)s times": "%(oneUser)sliittyi ja poistui %(repeat)s kertaa", + "%(severalUsers)sjoined and left": "%(severalUsers)sliittyivät ja poistuivat", + "%(oneUser)sjoined and left": "%(oneUser)sliittyi ja poistui", + "%(severalUsers)sleft and rejoined %(repeats)s times": "%(oneUser)spoistui ja liittyi uudelleen %(repeats)s kertaa", + "%(oneUser)sleft and rejoined %(repeats)s times": "%(severalUsers)spoistuivat ja liittyivät uudelleen %(repeats)s kertaa", + "%(severalUsers)sleft and rejoined": "%(severalUsers)spoistuivat ja liittyivät uudelleen", + "%(oneUser)sleft and rejoined": "%(oneUser)spoistui ja liittyi uudelleen", + "%(severalUsers)srejected their invitations %(repeats)s times": "%(severalUsers)shylkäsivät kutsunsa %(repeats)s kertaa'", + "%(severalUsers)srejected their invitations": "%(severalUsers)hylkäsivät kutsunsa", + "%(oneUser)srejected their invitation": "%(oneUser)shylkäsi kutsunsa", + "%(severalUsers)shad their invitations withdrawn %(repeats)s times": "%(severalUsers)skutsut vedettiin takaisin %(repeats)s kertaa", + "%(oneUser)shad their invitation withdrawn %(repeats)s times": "%(oneUser)skutsu vedettiin takaisin %(repeats)s kertaa", + "%(severalUsers)shad their invitations withdrawn": "%(severalUsers)skutsut vedettiin takaisin", + "%(oneUser)shad their invitation withdrawn": "%(oneUser)skutsu vedettiin takaisin", + "were invited %(repeats)s times": "kutsuttiin %(repeats)s kertaa", + "was invited %(repeats)s times": "kutsuttiin %(repeats)s kertaa", + "were invited": "kutsuttiin", + "was invited": "kutsuttiin", + "were kicked %(repeats)s times": "poistettiin huoneesta %(repeats)s kertaa", + "was kicked %(repeats)s times": "poistettiin huoneesta %(repeats)s kertaa", + "were kicked": "poistettiin huoneesta", + "was kicked": "poistettiin huoneesta", + "%(severalUsers)schanged their name %(repeats)s times": "%(severalUsers)smuuttivat nimensä %(repeats)s kertaa", + "%(oneUser)schanged their name %(repeats)s times": "%(oneUser)smuutti nimensä %(repeats)s kertaa", + "%(severalUsers)schanged their name": "%(severalUsers)smuuttivat nimensä", + "%(oneUser)schanged their name": "%(oneUser)smuutti nimensä" } From 3e7e7987ba4d60ab8f950364427f819048d2544e Mon Sep 17 00:00:00 2001 From: Stefan Parviainen Date: Tue, 19 Sep 2017 07:31:51 +0000 Subject: [PATCH 014/123] Translated using Weblate (Finnish) Currently translated at 88.1% (754 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fi/ --- src/i18n/strings/fi.json | 152 +++++++++++++++++++++++++++++++++++---- 1 file changed, 140 insertions(+), 12 deletions(-) diff --git a/src/i18n/strings/fi.json b/src/i18n/strings/fi.json index 3da1fef551..072a634b08 100644 --- a/src/i18n/strings/fi.json +++ b/src/i18n/strings/fi.json @@ -524,10 +524,10 @@ "Displays action": "Näyttää toiminnan", "Don't send typing notifications": "Älä lähetä kirjoitusilmoituksia", "End-to-end encryption is in beta and may not be reliable": "Päästä päähän salaus on vielä testausvaiheessa ja saattaa toimia epävarmasti", - "Error: Problem communicating with the given homeserver.": "Virhe: Ongelma yhteydenpidossa kotipalvelimeen", + "Error: Problem communicating with the given homeserver.": "Virhe: Ongelma yhteydenpidossa kotipalvelimeen.", "Existing Call": "Käynnissä oleva puhelu", "Failed to lookup current room": "Nykyisen huoneen löytäminen epäonnistui", - "Join as voice or video.": "Liitty käyttäen ääntä tai videota", + "Join as voice or video.": "Liity käyttäen ääntä tai videota.", "%(targetName)s joined the room.": "%(targetName)s liittyi huoneeseen.", "%(senderName)s kicked %(targetName)s.": "%(senderName)s poisti käyttäjän %(targetName)s huoneesta.", "%(targetName)s left the room.": "%(targetName)s poistui huoneesta.", @@ -566,11 +566,11 @@ "Success": "Onnistuminen", "tag as %(tagName)s": "lisää tägi %(tagName)s", "tag direct chat": "tägää suora viestittely", - "Tagged as: ": "Tägit:", + "Tagged as: ": "Tägit: ", "The default role for new room members is": "Huoneen uusien jäsenten oletusrooli on", "The main address for this room is": "Tämän huoneen pääosoite on", "The phone number entered looks invalid": "Syötetty puhelinnumero näyttää virheelliseltä", - "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Syöttämäsi allekirjoitusavain vastaa käyttäjältä %(userId)s saamaasi allekirjoitusavainta. Laite on merkitty varmennetuksi.'", + "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Syöttämäsi allekirjoitusavain vastaa käyttäjän %(userId)s laitteelta %(deviceId)s saamaasi allekirjoitusavainta. Laite on merkitty varmennetuksi.", "Unable to add email address": "Sähköpostiosoitteen lisääminen epäonnistui", "Unable to remove contact information": "Yhteystietojen poistaminen epäonnistui", "Unable to restore previous session": "Edellisen istunnon palauttaminen epäonnistui", @@ -593,23 +593,23 @@ "User Interface": "Käyttöliittymä", "%(user)s is a": "%(user)s on", "User name": "Käyttäjänimi", - "%(oneUser)sjoined %(repeats)s times": "%(oneUser)sliittyi %(repeat)s kertaa", + "%(oneUser)sjoined %(repeats)s times": "%(oneUser)sliittyi %(repeats)s kertaa", "%(severalUsers)sjoined": "%(severalUsers)sliittyivät", "%(oneUser)sjoined": "%(oneUser)sliittyi", - "%(severalUsers)sleft %(repeats)s times": "%(severalUsers)spoistuivat %(repeat)s kertaa", - "%(oneUser)sleft %(repeats)s times": "%(oneUser)spoistui %(repeat)s kertaa", + "%(severalUsers)sleft %(repeats)s times": "%(severalUsers)spoistuivat %(repeats)s kertaa", + "%(oneUser)sleft %(repeats)s times": "%(oneUser)spoistui %(repeats)s kertaa", "%(severalUsers)sleft": "%(severalUsers)sspoistuivat", "%(oneUser)sleft": "%(oneUser)spoistui", "%(severalUsers)sjoined and left %(repeats)s times": "%(severalUsers)sliittyivät ja poistuivat %(repeats)s kertaa", - "%(oneUser)sjoined and left %(repeats)s times": "%(oneUser)sliittyi ja poistui %(repeat)s kertaa", + "%(oneUser)sjoined and left %(repeats)s times": "%(oneUser)sliittyi ja poistui %(repeats)s kertaa", "%(severalUsers)sjoined and left": "%(severalUsers)sliittyivät ja poistuivat", "%(oneUser)sjoined and left": "%(oneUser)sliittyi ja poistui", - "%(severalUsers)sleft and rejoined %(repeats)s times": "%(oneUser)spoistui ja liittyi uudelleen %(repeats)s kertaa", - "%(oneUser)sleft and rejoined %(repeats)s times": "%(severalUsers)spoistuivat ja liittyivät uudelleen %(repeats)s kertaa", + "%(severalUsers)sleft and rejoined %(repeats)s times": "%(severalUsers)spoistuivat ja liittyivät uudelleen %(repeats)s kertaa", + "%(oneUser)sleft and rejoined %(repeats)s times": "%(oneUser)spoistui ja liittyi uudelleen %(repeats)s kertaa", "%(severalUsers)sleft and rejoined": "%(severalUsers)spoistuivat ja liittyivät uudelleen", "%(oneUser)sleft and rejoined": "%(oneUser)spoistui ja liittyi uudelleen", "%(severalUsers)srejected their invitations %(repeats)s times": "%(severalUsers)shylkäsivät kutsunsa %(repeats)s kertaa'", - "%(severalUsers)srejected their invitations": "%(severalUsers)hylkäsivät kutsunsa", + "%(severalUsers)srejected their invitations": "%(severalUsers)shylkäsivät kutsunsa", "%(oneUser)srejected their invitation": "%(oneUser)shylkäsi kutsunsa", "%(severalUsers)shad their invitations withdrawn %(repeats)s times": "%(severalUsers)skutsut vedettiin takaisin %(repeats)s kertaa", "%(oneUser)shad their invitation withdrawn %(repeats)s times": "%(oneUser)skutsu vedettiin takaisin %(repeats)s kertaa", @@ -626,5 +626,133 @@ "%(severalUsers)schanged their name %(repeats)s times": "%(severalUsers)smuuttivat nimensä %(repeats)s kertaa", "%(oneUser)schanged their name %(repeats)s times": "%(oneUser)smuutti nimensä %(repeats)s kertaa", "%(severalUsers)schanged their name": "%(severalUsers)smuuttivat nimensä", - "%(oneUser)schanged their name": "%(oneUser)smuutti nimensä" + "%(oneUser)schanged their name": "%(oneUser)smuutti nimensä", + "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s asetti aiheeksi \"%(topic)s\".", + "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Salasanan muuttaminen uudelleenalustaa myös päästä päähän-salausavaimet kaikilla laitteilla, jolloin vanhojen viestien lukeminen ei ole enään mahdollista, ellet ensin vie huoneavaimet ja tuo ne takaisin jälkeenpäin. Tämä tulee muuttumaan tulevaisuudessa.", + "Define the power level of a user": "Määritä käyttäjän oikeustaso", + "Failed to change power level": "Oikeustason muuttaminen epäonnistui", + "'%(alias)s' is not a valid format for an address": "'%(alias)s' ei ole oikean muotoinen osoitteelle", + "'%(alias)s' is not a valid format for an alias": "'%(alias)s' ei ole oikean muotoinen aliakselle", + "Once you've followed the link it contains, click below": "Klikkaa alla kun olet seuruannut sen sisältämää linkkiä", + "Otherwise, click here to send a bug report.": "Paina muutoin tästä lähettääksesi virheraportin.", + "Please check your email and click on the link it contains. Once this is done, click continue.": "Ole hyvä ja tarkista sähköpostisi ja seuraa sen sisältämää linkkiä. Kun olet valmis, paina jatka.", + "Power level must be positive integer.": "Oikeustason pitää olla positiivinen kokonaisluku.", + "Press": "Paina", + "Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Salasanan uudelleenalustus uudelleenalustaa myös päästä päähän-salausavaimet kaikilla laitteilla, jolloin vanhojen viestien lukeminen ei ole enään mahdollista, ellet ensin vie huoneavaimet ja tuo ne takaisin jälkeenpäin. Tämä tulee muuttumaan tulevaisuudessa.", + "Server may be unavailable, overloaded, or search timed out :(": "Palvelin saattaa olla saavuttamattomissa, ylikuormitettu tai haku kesti liian kauan :(", + "Server may be unavailable, overloaded, or the file too big": "Palvelin saattaa olla saavuttamattomissa, ylikuormitettu, tai tiedosto on liian suuri", + "Server may be unavailable, overloaded, or you hit a bug.": "Palvelin saattaa olla saavuttamattomissa, ylikuormitettu tai olet törmännyt virheeseen.", + "Server unavailable, overloaded, or something else went wrong.": "Palvelin on saavuttamattomissa, ylikuormitettu tai jokin muu meni vikaan.", + "Sorry, this homeserver is using a login which is not recognised ": "Valitettavasti tämä palvelin käyttää kirjautumista joka ei ole tuettu ", + "The email address linked to your account must be entered.": "Sinun pitää syöttää tiliisi liitetty sähköpostiosoite.", + "The visibility of existing history will be unchanged": "Olemassaolevan viestihistorian näkyvyys ei muutu", + "To get started, please pick a username!": "Valitse käyttäjänimi aloittaaksesi!", + "To use it, just wait for autocomplete results to load and tab through them.": "Käyttääksesi sitä odota vain automaattitäydennyksiä ja selaa niiden läpi.", + "To reset your password, enter the email address linked to your account": "Syötä tiliisi liitetty sähköpostiosoite uudelleenalustaaksesi salasanasi", + "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Aikajanan tietty hetki yritettiin ladata, mutta sinulla ei ole oikeutta nähdä kyseistä viestiä.", + "Tried to load a specific point in this room's timeline, but was unable to find it.": "Aikajanan tietty hetki yritettiin ladata, mutta se ei löytynyt.", + "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Ei ole mahdollista varmistaa että sähköposti johon tämä kutsu lähetettiin vastaa sinun tiliisi liittettyä osoitetta.", + "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (oikeustaso %(powerLevelNumber)s)", + "Verification Pending": "Varmennus on vireillä", + "(could not connect media)": "(mediaa ei voitu yhdistää)", + "WARNING: Device already verified, but keys do NOT MATCH!": "VAROITUS: Laite on jo varmennettu mutta avaimet eivät vastaa toisiaan!", + "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "VAROITUS: AVAIMEN VARMENNUS EPÄONNISTUI! Käyttäjän %(userId)s ja laitteen %(deviceId)s allekirjoitusavain on \"%(fprint)s\" joka ei vastaa annettua avainta \"%(fingerprint)s\". Tämä saattaa tarkoittaa että viestintäsi siepataan!", + "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s veti takaisin käyttäjän %(targetName)s kutsun.", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Et ole vielä missään huoneessa! Paina luodaksesi huoneen tai selatakseski hakemistoa", + "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Sinut on kirjattu ulos kaikista laitteista etkä enää saa Push-ilmoituksia. Jotta saisit jälleen ilmoituksia pitää sinun jälleen kirjautua sisään jokaisella laitteella", + "You may wish to login with a different account, or add this email to this account.": "Haluat ehkä kirjautua toiseen tiliin tai lisätä tämä sähköpostiosoite tähän tiliin.", + "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Salasanan muuttaminen onnistui. Et saa enää push-ilmoituksia muilla laitteilla kunnes olet uudelleen kirjautunut sisään niillä", + "You seem to be in a call, are you sure you want to quit?": "Sinulla näyttää olevan puhelu kesken. Haluatko varmasti lopettaa?", + "You seem to be uploading files, are you sure you want to quit?": "Näytät lataavan tiedostoja. Oletko varma että haluat lopettaa?", + "Jan": "tammikuu", + "Feb": "helmikuu", + "Mar": "maaliskuu", + "Apr": "huhtikuu", + "May": "toukokuu", + "Jun": "kesäkuu", + "Jul": "heinäkuu", + "Aug": "elokuu", + "Sep": "syyskuu", + "Oct": "lokakuu", + "Nov": "marraskuu", + "Dec": "jolukuu", + "User names may only contain letters, numbers, dots, hyphens and underscores.": "Käyttäjänimet voivat sisältää vain kirjaimia, numeroita, pisteitä, viivoja ja alaviivoja.", + "To continue, please enter your password.": "Ole hyvä ja syötä salasanasi jatkaaksesi.", + "Verifies a user, device, and pubkey tuple": "Varmentaa käyttäjän, laitteen ja julkisen avaimen kolmikon", + "\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" sisältä laitteita joita et ole nähnyt aikaisemmin.", + "Unknown devices": "Tuntemattomia laitteita", + "Unknown Address": "Tuntematon osoite", + "Unverify": "Kumoa varmennus", + "Verify...": "Varmenna...", + "ex. @bob:example.com": "esim. @bob:example.com", + "Add User": "Lisää käyttäjä", + "This Home Server would like to make sure you are not a robot": "Tämä kotipalvelin haluaa varmistaa että et ole robotti", + "A text message has been sent to": "Tekstiviesti on lähetetty numeroon", + "Please enter the code it contains:": "Ole hyvä ja syötä sen sisältämä koodi:", + "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Jos et syötä sähköpostiosoitetta et voi uudelleenalustaa salasanasi myöhemmin. Oletko varma?", + "Default server": "Oletuspalvelin", + "Home server URL": "Kotipalvelimen URL", + "Identity server URL": "Identiteettipalvelimen URL", + "What does this mean?": "Mitä tämä tarkoittaa?", + "Error decrypting audio": "Äänen salauksen purku epäonnistui", + "Error decrypting image": "Kuvan salauksen purku epäonnistui", + "Image '%(Body)s' cannot be displayed.": "Kuva '%(Body)s' ei voida näyttää.", + "This image cannot be displayed.": "Tätä kuvaa ei voida näyttää.", + "Error decrypting video": "Videon salauksen purku epäonnistui", + "Add an Integration": "Lisää integraatio", + "Removed or unknown message type": "Poistettu tai tuntematon viestityyppi", + "URL Previews": "URL esikatselut", + "Drop file here to upload": "Pudota tiedosto tähän ladataksesi sen palvelimelle", + " (unsupported)": " (ei tuettu)", + "Updates": "Päivitykset", + "Check for update": "Tarkista päivitykset", + "Start chatting": "Aloita keskustelu", + "Start Chatting": "Aloita keskustelu", + "Click on the button below to start chatting!": "Paina nappia alla aloittaaksesi keskustelu!", + "Username available": "Käyttäjänimi saatavissa", + "Username not available": "Käyttäjänimi ei ole saatavissa", + "Something went wrong!": "Jokin meni vikaan!", + "This will be your account name on the homeserver, or you can pick a different server.": "Tämä on tilisi -kotipalvelimella, tai voit valita toisen palvelimen.", + "If you already have a Matrix account you can log in instead.": "Jos sinulla on jo Matrix-tili voit kirjautua.", + "Your browser does not support the required cryptography extensions": "Selaimesi ei tue vaadittuja kryptografisia laajennuksia", + "Not a valid Riot keyfile": "Virheellinen Riot avaintiedosto", + "Authentication check failed: incorrect password?": "Autentikointi epäonnistui: virheellinen salasana?", + "Do you want to set an email address?": "Haluatko asettaa sähköpostiosoitteen?", + "This will allow you to reset your password and receive notifications.": "Tämä sallii sinun uudelleenalustaa salasanasi ja vastaanottaa ilmoituksia.", + "To return to your account in future you need to set a password": "Päästäksesi uudestaan tiliisi myöhemmin sinun täytyy asettaa salasana", + "Skip": "Hyppää yli", + "Start verification": "Aloita varmennus", + "Share without verifying": "Jaa ilman varmennusta", + "Ignore request": "Jätä pyyntö huomioimatta", + "You added a new device '%(displayName)s', which is requesting encryption keys.": "Lisäsit laitteen '%(displayName)s' joka pyytää salausavaimia.", + "Your unverified device '%(displayName)s' is requesting encryption keys.": "Sinun varmentamaton laitteesi '%(displayName)s' pyytää salausavaimia.", + "Encryption key request": "Salausavainpyyntö", + "This Home server does not support groups": "Kotipalvelin ei tue ryhmiä", + "Loading device info...": "Ladataan laitetiedot...", + "Groups": "Ryhmät", + "Create a new group": "Luo uusi ryhmä", + "Create Group": "Luo ryhmä", + "Group Name": "Ryhmän nimi", + "Example": "Esimerkki", + "Create": "Luo", + "Group ID": "Ryhmän tunniste", + "+example:%(domain)s": "+esimerkki:%(domain)s", + "Group IDs must be of the form +localpart:%(domain)s": "Ryhmätunnisteiden pitää olla muotoa +paikallinen:%(domain)s", + "Room creation failed": "Huoneen luonti epäonnistui", + "You are a member of these groups:": "Olet seuraavien ryhmien jäsen:", + "Join an existing group": "Liity olemassaolevaan ryhmään", + "Edit Group": "Muokkaa ryhmää", + "Failed to upload image": "Kuvan lataaminen epäonnistui", + "Failed to update group": "Ryhmän päivitys epäonnistui", + "Robot check is currently unavailable on desktop - please use a web browser": "Robottitarkistus ei tällä hetkellä toimi työpöytäversiossa. Ole hyvä ja käytä nettiselainta", + "Add a widget": "Lisää sovelma", + "Cannot add any more widgets": "Lisää sovelmia ei voida enää lisätä", + "Delete widget": "Poista sovelma", + "Do you want to load widget from URL:": "Haluatko ladata sovelman URL-osoitteesta:", + "The maximum permitted number of widgets have already been added to this room.": "Maksimimäärä sovelmia on jo lisätty tähän huoneeseen.", + "Unable to create widget.": "Sovelman luominen epäonnistui.", + "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Et voi kumota tätä toimintoa koska olet antamassa käyttäjälle saman oikeustason kuin sinullakin on.", + "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.": "Tämä prosessi mahdollistaa salatuissa huoneissa vastaanottamasi viestien salausavainten vieminen tiedostoon. Voit sitten myöhemmin tuoda ne toiseen Matrix-asiakasohjelmaan niin että myös se ohjema voi purkaa viestit.", + "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.": "Tämän tiedoston avulla kuka tahansa pystyy purkamaan kaikki salatut viestit jotka sinä voit nähdä, joten sinun täytyy säilyttää se turvallisesti. Helpottaaksesi tätä sinun pitäisi syötää salasana alla jonka avulla tiedosto salataan. Käyttäen samaa salasanaa voit myöhemmin tuoda tiedot ohjelmaan.", + "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.": "Tämä prosessi mahdollistaa aiemmin tallennettujen salausavainten tuominen toiseen Matrix-asiakasohjelmaan. Tämän jälkeen voit purkaa kaikki salatut viestit jotka toinen asiakasohjelma pystyisi purkamaan." } From 6352e5cca655f73f9cb8812cf2178bb31d326101 Mon Sep 17 00:00:00 2001 From: carlos-am Date: Tue, 19 Sep 2017 13:54:03 +0000 Subject: [PATCH 015/123] Translated using Weblate (Portuguese) Currently translated at 91.6% (784 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/pt/ --- src/i18n/strings/pt.json | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/pt.json b/src/i18n/strings/pt.json index 75b690cb26..fe74fedf13 100644 --- a/src/i18n/strings/pt.json +++ b/src/i18n/strings/pt.json @@ -842,5 +842,18 @@ "Start chat": "Iniciar conversa", "You already have existing direct chats with this user:": "Você já tem conversas pessoais com esta pessoa:", "Accept": "Aceitar", - "%(roomName)s is not accessible at this time.": "%(roomName)s não está acessível neste momento." + "%(roomName)s is not accessible at this time.": "%(roomName)s não está acessível neste momento.", + "Add a widget": "Adicionar widget", + "Allow": "Permitir", + "Cannot add any more widgets": "Não é possível adicionar mais widgets", + "Changes colour scheme of current room": "Altera o esquema de cores da sala atual", + "Delete widget": "Apagar widget", + "Define the power level of a user": "Definir o nível de privilégios de um utilizador", + "Do you want to load widget from URL:": "Deseja carregar o widget a partir do URL:", + "Edit": "Editar", + "Enable automatic language detection for syntax highlighting": "Ativar deteção automática da linguagem para o destaque da sintaxe", + "Hide Apps": "Ocultar apps", + "Hide join/leave messages (invites/kicks/bans unaffected)": "Ocultar mensagens de entrada/saída (não afeta convites/expulsões/proibições)", + "Hide avatar and display name changes": "Ocultar mudanças de avatar e de nome público", + "Integrations Error": "Erro de integrações" } From 4d127db358665dfa32cb43936881b3125ea6b3bd Mon Sep 17 00:00:00 2001 From: carlos-am Date: Tue, 19 Sep 2017 14:01:37 +0000 Subject: [PATCH 016/123] Translated using Weblate (Portuguese) Currently translated at 92.7% (793 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/pt/ --- src/i18n/strings/pt.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/pt.json b/src/i18n/strings/pt.json index fe74fedf13..68886c2e85 100644 --- a/src/i18n/strings/pt.json +++ b/src/i18n/strings/pt.json @@ -855,5 +855,14 @@ "Hide Apps": "Ocultar apps", "Hide join/leave messages (invites/kicks/bans unaffected)": "Ocultar mensagens de entrada/saída (não afeta convites/expulsões/proibições)", "Hide avatar and display name changes": "Ocultar mudanças de avatar e de nome público", - "Integrations Error": "Erro de integrações" + "Integrations Error": "Erro de integrações", + "Publish this room to the public in %(domain)s's room directory?": "Publicar esta sala ao público no diretório de salas de %(domain)s's?", + "Matrix Apps": "Apps Matrix", + "AM": "AM", + "PM": "PM", + "NOTE: Apps are not end-to-end encrypted": "NOTA: As apps não são cifradas ponta-a-ponta", + "Press to start a chat with someone": "Clique para iniciar uma conversa com alguém", + "Revoke widget access": "Revogar o acesso do wiget", + "Sets the room topic": "Define o assunto da sala", + "Show Apps": "Mostrar apps" } From d221b20721f078ac6a64a8198796de05541403e1 Mon Sep 17 00:00:00 2001 From: carlos-am Date: Tue, 19 Sep 2017 14:59:57 +0000 Subject: [PATCH 017/123] Translated using Weblate (Portuguese) Currently translated at 99.1% (848 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/pt/ --- src/i18n/strings/pt.json | 58 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/pt.json b/src/i18n/strings/pt.json index 68886c2e85..6f8572a0c7 100644 --- a/src/i18n/strings/pt.json +++ b/src/i18n/strings/pt.json @@ -539,7 +539,7 @@ "quote": "citação", "bullet": "marcador de lista", "numbullet": "marcador de numeração", - "%(severalUsers)sjoined %(repeats)s times": "%(severalUsers)singressaram %(repeats)s vezes", + "%(severalUsers)sjoined %(repeats)s times": "%(severalUsers)s entraram %(repeats)s vezes", "%(oneUser)sjoined %(repeats)s times": "%(oneUser)singressou %(repeats)s vezes", "%(severalUsers)sjoined": "%(severalUsers)singressaram", "%(oneUser)sjoined": "%(oneUser)singressou", @@ -864,5 +864,59 @@ "Press to start a chat with someone": "Clique para iniciar uma conversa com alguém", "Revoke widget access": "Revogar o acesso do wiget", "Sets the room topic": "Define o assunto da sala", - "Show Apps": "Mostrar apps" + "Show Apps": "Mostrar apps", + "The maximum permitted number of widgets have already been added to this room.": "O número máximo de widgets permitido já foi adicionado a esta sala.", + "To get started, please pick a username!": "Para começar, escolha um nome de utilizador!", + "Unable to create widget.": "Não foi possível criar o widget.", + "Unbans user with given id": "Retira ban ao utilizador através do seu id", + "(could not connect media)": "(não foi possível conectar-se ao media)", + "(no answer)": "(sem resposta)", + "(unknown failure: %(reason)s)": "(falha desconhecida: %(reason)s)", + "You are not in this room.": "Não se encontra nesta sala.", + "You do not have permission to do that in this room.": "Não tem permissão para fazer isso nesta sala.", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Ainda não se encontra em nenhuma sala! Clique em para criar uma sala ou em para navegar o diretório de salas", + "%(weekDayName)s, %(monthName)s %(day)s": "%(weekDayName)s, %(day)s de %(monthName)s", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(day)s de %(monthName)s de %(fullYear)s", + "Copied!": "Copiado!", + "Failed to copy": "Falha ao copiar", + "Verifies a user, device, and pubkey tuple": "Verifica um utilizador, o dispositivo e o tuplo da chave pública", + "Updates": "Atualizações", + "Check for update": "Procurar atualizações", + "Your browser does not support the required cryptography extensions": "O seu browser não suporta as extensões de criptografia necessárias", + "Not a valid Riot keyfile": "Não é um ficheiro de chaves Riot válido", + "Authentication check failed: incorrect password?": "Erro de autenticação: palavra-passe incorreta?", + "Disable Peer-to-Peer for 1:1 calls": "Desativar ponto-a-ponto para chamadas 1:1", + "Do you want to set an email address?": "Deseja definir um endereço de e-mail?", + "This will allow you to reset your password and receive notifications.": "Isto irá permitir-lhe redefinir a sua palavra-passe e receber notificações.", + "To return to your account in future you need to set a password": "Para voltar à sua conta no futuro necessita de definir uma palavra-passe", + "Skip": "Saltar", + "Start verification": "Iniciar verificação", + "Share without verifying": "Partilhar sem verificar", + "Ignore request": "Ignorar pedido", + "You added a new device '%(displayName)s', which is requesting encryption keys.": "Adicionou um novo dispositivo '%(displayName)s', que está a pedir chaves de encriptação.", + "Your unverified device '%(displayName)s' is requesting encryption keys.": "O seu dispositivo não verificado '%(displayName)s' está a pedir chaves de encriptação.", + "Encryption key request": "Pedido de chave de encriptação", + "Autocomplete Delay (ms):": "Atraso de preenchimento automático (ms):", + "This Home server does not support groups": "Este servidor (home server) não suporta grupos", + "Loading device info...": "A carregar as informações do dispositivo...", + "Groups": "Grupos", + "Create a new group": "Criar um novo grupo", + "Create Group": "Criar grupo", + "Group Name": "Nome do grupo", + "Example": "Exemplo", + "Create": "Criar", + "Group ID": "ID do grupo", + "+example:%(domain)s": "+exemplo:%(domain)s", + "Group IDs must be of the form +localpart:%(domain)s": "IDs de grupo têm que ser no formato +localpart:%(domain)s", + "It is currently only possible to create groups on your own home server: use a group ID ending with %(domain)s": "Atualmente apenas é possível criar grupos no seu próprio servidor (home server): utilize um ID de grupo que termine com %(domain)s", + "Room creation failed": "Criação de sala falhou", + "You are a member of these groups:": "É um membro destes grupos:", + "Create a group to represent your community! Define a set of rooms and your own custom homepage to mark out your space in the Matrix universe.": "Crie um grupo para representar a sua comunidade! Defina um conjunto de salas e a sua própria página inicial personalizada para marcar o seu espaço no universo Matrix.", + "Join an existing group": "Juntar-se a um grupo existente", + "To join an existing group you'll have to know its group identifier; this will look something like +example:matrix.org.": "Para juntar-se a um grupo existente necessita de saber a identificação do grupo; isto será algo como +exemplo:matrix.org.", + "Featured Rooms:": "Salas em destaque:", + "Error whilst fetching joined groups": "Erro ao obter os seus grupos", + "Featured Users:": "Utilizadores em destaque:", + "Edit Group": "Editar grupo", + "Automatically replace plain text Emoji": "Substituir Emoji em texto automaticamente" } From 077d4aafe225ebe689ab0c9f58bb813bf20a0d40 Mon Sep 17 00:00:00 2001 From: carlos-am Date: Tue, 19 Sep 2017 15:04:12 +0000 Subject: [PATCH 018/123] Translated using Weblate (Portuguese) Currently translated at 100.0% (855 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/pt/ --- src/i18n/strings/pt.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/pt.json b/src/i18n/strings/pt.json index 6f8572a0c7..a20474a62d 100644 --- a/src/i18n/strings/pt.json +++ b/src/i18n/strings/pt.json @@ -918,5 +918,12 @@ "Error whilst fetching joined groups": "Erro ao obter os seus grupos", "Featured Users:": "Utilizadores em destaque:", "Edit Group": "Editar grupo", - "Automatically replace plain text Emoji": "Substituir Emoji em texto automaticamente" + "Automatically replace plain text Emoji": "Substituir Emoji em texto automaticamente", + "Failed to upload image": "Falha ao carregar imagem", + "Failed to update group": "Falha ao atualizar grupo", + "Hide avatars in user and room mentions": "Ocultar avatares nas menções de utilizadores e salas", + "%(widgetName)s widget added by %(senderName)s": "Widget %(widgetName)s adicionado por %(senderName)s", + "%(widgetName)s widget removed by %(senderName)s": "Widget %(widgetName)s removido por %(senderName)s", + "%(widgetName)s widget modified by %(senderName)s": "Widget %(widgetName)s modificado por %(senderName)s", + "Robot check is currently unavailable on desktop - please use a web browser": "A verificação através de robot está atualmente indisponível na versão desktop - utilize um navegador web" } From b676d1818e775b1a2142fa3b576da2c302cc6d62 Mon Sep 17 00:00:00 2001 From: carlos-am Date: Tue, 19 Sep 2017 15:26:15 +0000 Subject: [PATCH 019/123] Translated using Weblate (Portuguese) Currently translated at 100.0% (855 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/pt/ --- src/i18n/strings/pt.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/pt.json b/src/i18n/strings/pt.json index a20474a62d..c650a024a8 100644 --- a/src/i18n/strings/pt.json +++ b/src/i18n/strings/pt.json @@ -81,7 +81,7 @@ "Error": "Erro", "Event information": "Informação do evento", "Export E2E room keys": "Exportar chaves ponta-a-ponta da sala", - "Failed to change password. Is your password correct?": "Não foi possível modificar a senha. A senha informada está correta?", + "Failed to change password. Is your password correct?": "Falha ao alterar a palavra-passe. A sua palavra-passe está correta?", "Failed to forget room": "Não foi possível esquecer a sala", "Failed to leave room": "Falha ao tentar deixar a sala", "Failed to reject invitation": "Falha ao tentar rejeitar convite", From 29be5878dd875716285fc9eb0ea965a334a7ea88 Mon Sep 17 00:00:00 2001 From: Carlos Date: Tue, 19 Sep 2017 15:47:04 +0000 Subject: [PATCH 020/123] Translated using Weblate (Portuguese) Currently translated at 100.0% (855 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/pt/ --- src/i18n/strings/pt.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/pt.json b/src/i18n/strings/pt.json index c650a024a8..7edd67b0a9 100644 --- a/src/i18n/strings/pt.json +++ b/src/i18n/strings/pt.json @@ -165,7 +165,7 @@ "Privacy warning": "Alerta sobre privacidade", "Privileged Users": "Usuárias/os privilegiadas/os", "Profile": "Perfil", - "Refer a friend to Riot:": "Indicar um amigo para participar", + "Refer a friend to Riot:": "Recomendar Riot a um amigo:", "rejected": "recusou", "rejected the invitation.": "rejeitou o convite.", "Reject invitation": "Rejeitar convite", From 94a30c0889cab92fd5cb11e9d0bed42249f4cad0 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Tue, 19 Sep 2017 18:49:08 +0000 Subject: [PATCH 021/123] Translated using Weblate (Hungarian) Currently translated at 100.0% (855 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 3dcef42c58..36cbe4cb2b 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -853,5 +853,9 @@ "%(widgetName)s widget added by %(senderName)s": "%(widgetName)s kisalkalmazást %(senderName)s hozzáadta", "%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s kisalkalmazást %(senderName)s eltávolította", "Robot check is currently unavailable on desktop - please use a web browser": "Robot ellenőrzés az asztali verzióban nem érhető el - használd a web böngészőt", - "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s kisalkalmazást %(senderName)s módosította" + "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s kisalkalmazást %(senderName)s módosította", + "%(weekDayName)s, %(monthName)s %(day)s": "%(weekDayName)s, %(monthName)s %(day)s", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(fullYear)s %(monthName)s %(day)s", + "Copied!": "Lemásolva!", + "Failed to copy": "Sikertelen másolás" } From 5f73fa5a770024061ebab6e06a1e685bab755e8a Mon Sep 17 00:00:00 2001 From: Walter Date: Thu, 21 Sep 2017 12:29:38 +0000 Subject: [PATCH 022/123] Translated using Weblate (Russian) Currently translated at 100.0% (855 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-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 914fd49798..34d3e287a4 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -366,7 +366,7 @@ "Command error": "Ошибка команды", "Confirm password": "Подтвердите пароль", "Current password": "Текущий пароль", - "Email": "Электронная почта", + "Email": "Эл. почта", "Failed to kick": "Не удалось выгнать", "Failed to load timeline position": "Не удалось загрузить метку из хронологии", "Failed to mute user": "Не удалось заглушить пользователя", From 2bc2d30a0e181f9297725a4566b6781b70bfde63 Mon Sep 17 00:00:00 2001 From: Andrey Date: Thu, 21 Sep 2017 13:21:28 +0000 Subject: [PATCH 023/123] Translated using Weblate (Russian) Currently translated at 100.0% (855 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-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 34d3e287a4..914fd49798 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -366,7 +366,7 @@ "Command error": "Ошибка команды", "Confirm password": "Подтвердите пароль", "Current password": "Текущий пароль", - "Email": "Эл. почта", + "Email": "Электронная почта", "Failed to kick": "Не удалось выгнать", "Failed to load timeline position": "Не удалось загрузить метку из хронологии", "Failed to mute user": "Не удалось заглушить пользователя", From 4802b2abc141970765028cda307378b97681adc6 Mon Sep 17 00:00:00 2001 From: Walter Date: Fri, 22 Sep 2017 06:27:01 +0000 Subject: [PATCH 024/123] Translated using Weblate (Russian) Currently translated at 100.0% (855 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-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 914fd49798..b65eebe929 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -96,7 +96,7 @@ "Homeserver is": "Домашний сервер это", "Identity Server is": "Сервер идентификации это", "I have verified my email address": "Я подтвердил свой адрес электронной почты", - "Import E2E room keys": "Импортировать ключи сквозного шифрования комнаты", + "Import E2E room keys": "Импорт ключей сквозного шифрования комнаты", "Invalid Email Address": "Недопустимый адрес электронной почты", "invited": "invited", "Invite new room members": "Пригласить новых участников в комнату", From f37efcb3c4c8e482010e067683f8f663f9c343b1 Mon Sep 17 00:00:00 2001 From: Bamstam Date: Fri, 22 Sep 2017 07:56:54 +0000 Subject: [PATCH 025/123] Translated using Weblate (German) Currently translated at 100.0% (855 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 48dd7602df..9dadc7d632 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -595,7 +595,7 @@ "Report it": "Melden", "riot-web version:": "Version von riot-web:", "Scroll to bottom of page": "Zum Ende der Seite springen", - "Show timestamps in 12 hour format (e.g. 2:30pm)": "Zeitstempel im 12-Stunden-Format anzeigen (z. B. 2:30pm)", + "Show timestamps in 12 hour format (e.g. 2:30pm)": "Zeitstempel im 12-Stunden-Format anzeigen (z. B. 2:30 p. m.)", "to tag as %(tagName)s": "um als \"%(tagName)s\" zu markieren", "Email address": "E-Mail-Adresse", "Error decrypting attachment": "Fehler beim Entschlüsseln des Anhangs", @@ -877,8 +877,8 @@ "Edit": "Bearbeiten", "Enable automatic language detection for syntax highlighting": "Automatische Spracherkennung für die Syntax-Hervorhebung aktivieren", "Hide Apps": "Apps verbergen", - "Hide join/leave messages (invites/kicks/bans unaffected)": "Verberge Beitritt-/Verlassen-Meldungen (außer Einladungen/Kicks/Bans)", - "Hide avatar and display name changes": "Verberge Avatar- und Anzeigenamen-Änderungen", + "Hide join/leave messages (invites/kicks/bans unaffected)": "Betreten-/Verlassen-Benachrichtigungen verbergen (gilt nicht für Einladungen/Kicks/Bans)", + "Hide avatar and display name changes": "Profilbild- und Anzeigenamen-Änderungen verbergen", "Matrix Apps": "Matrix-Apps", "Revoke widget access": "Ziehe Widget-Zugriff zurück", "Sets the room topic": "Setzt das Raum-Thema", @@ -889,7 +889,7 @@ "You are not in this room.": "Du bist nicht in diesem Raum.", "You do not have permission to do that in this room.": "Du hast keine Berechtigung, dies in diesem Raum zu tun.", "Verifies a user, device, and pubkey tuple": "Verifiziert ein Tupel aus Nutzer, Gerät und öffentlichem Schlüssel", - "Autocomplete Delay (ms):": "Verzögerung zur Autovervollständigung (ms):", + "Autocomplete Delay (ms):": "Verzögerung bei Autovervollständigung (ms):", "This Home server does not support groups": "Dieser Heimserver unterstützt keine Gruppen", "Loading device info...": "Lädt Geräte-Info...", "Groups": "Gruppen", @@ -914,7 +914,7 @@ "Automatically replace plain text Emoji": "Klartext-Emoji automatisch ersetzen", "Failed to upload image": "Bild-Hochladen fehlgeschlagen", "Failed to update group": "Aktualisieren der Gruppe fehlgeschlagen", - "Hide avatars in user and room mentions": "Verberge Profilbilder in Benutzer- und Raum-Erwähnungen", + "Hide avatars in user and room mentions": "Profilbilder in Benutzer- und Raum-Erwähnungen verbergen", "AM": "a. m.", "PM": "p. m.", "The maximum permitted number of widgets have already been added to this room.": "Die maximal erlaubte Anzahl an hinzufügbaren Widgets für diesen Raum wurde erreicht.", From e7d68395251335e4a93ddc05aa39e3d4277eaebd Mon Sep 17 00:00:00 2001 From: Andrey Date: Fri, 22 Sep 2017 07:53:45 +0000 Subject: [PATCH 026/123] Translated using Weblate (Russian) Currently translated at 100.0% (855 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-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 b65eebe929..48a070f066 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -96,7 +96,7 @@ "Homeserver is": "Домашний сервер это", "Identity Server is": "Сервер идентификации это", "I have verified my email address": "Я подтвердил свой адрес электронной почты", - "Import E2E room keys": "Импорт ключей сквозного шифрования комнаты", + "Import E2E room keys": "Импорт ключей сквозного шифрования", "Invalid Email Address": "Недопустимый адрес электронной почты", "invited": "invited", "Invite new room members": "Пригласить новых участников в комнату", From 40688b1a2b5a609f86eae2a4ea888ae96382f96a Mon Sep 17 00:00:00 2001 From: Walter Date: Fri, 22 Sep 2017 14:01:08 +0000 Subject: [PATCH 027/123] Translated using Weblate (Ukrainian) Currently translated at 12.0% (103 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/uk/ --- src/i18n/strings/uk.json | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/uk.json b/src/i18n/strings/uk.json index ed11668ddd..8f9c18356a 100644 --- a/src/i18n/strings/uk.json +++ b/src/i18n/strings/uk.json @@ -78,5 +78,28 @@ "%(names)s and one other are typing": "%(names)s та інші пишуть", "%(names)s and %(count)s others are typing": "%(names)s та %(count)s інших пишуть", "An email has been sent to": "Лист було надіслано", - "A new password must be entered.": "Має бути введений новий пароль." + "A new password must be entered.": "Має бути введений новий пароль.", + "Add a widget": "Добавити віджет", + "Allow": "Принюти", + "%(senderName)s answered the call.": "%(senderName)s відповіла на дзвінок.", + "anyone": "Будь-який", + "An error has occurred.": "Трапилась помилка.", + "Anyone": "Кожний", + "Anyone who knows the room's link, apart from guests": "Кожний, хто знає посилання на кімнату, окрім гостей", + "Anyone who knows the room's link, including guests": "Кожний, хто знає посилання на кімнату, включно гостей", + "Are you sure?": "Ви впевнені?", + "Are you sure you want to leave the room '%(roomName)s'?": "Ви впевнені, що хочете покинути '%(roomName)s'?", + "Are you sure you want to reject the invitation?": "Ви впевнені, що ви хочете відхилити запрошення?", + "Are you sure you want to upload the following files?": "Ви впевнені, що ви хочете відправити наступний файл?", + "Attachment": "Прикріплення", + "Autoplay GIFs and videos": "Автовідтворення GIF і відео", + "%(senderName)s banned %(targetName)s.": "%(senderName)s заблокував(ла) %(targetName)s.", + "Ban": "Заблокувати", + "Banned users": "Заблоковані користувачі", + "Bans user with given id": "Блокує користувача з заданим ID", + "Blacklisted": "В чорному списку", + "Bug Report": "Звіт про помилку", + "Bulk Options": "Групові параметри", + "Call Timeout": "Час очікування виклика", + "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.": "Не вдається підключитись до домашнього серверу - перевірте підключення, переконайтесь, що ваш SSL-сертифікат домашнього сервера є довіреним і що розширення браузера не блокує запити." } From d4929b558edec1a473ae2c4e431bd74cd1f2e7fd Mon Sep 17 00:00:00 2001 From: Stefan Parviainen Date: Fri, 22 Sep 2017 21:43:27 +0200 Subject: [PATCH 028/123] Add dummy translation function to mark translatable strings Signed-off-by: Stefan Parviainen --- src/autocomplete/CommandProvider.js | 34 ++++++++--------- src/components/structures/UserSettings.js | 38 +++++++++---------- src/components/views/elements/AppTile.js | 6 +-- .../views/rooms/MessageComposerInput.js | 18 ++++----- src/languageHandler.js | 6 +++ 5 files changed, 54 insertions(+), 48 deletions(-) diff --git a/src/autocomplete/CommandProvider.js b/src/autocomplete/CommandProvider.js index 011ad0a7dc..42347d3955 100644 --- a/src/autocomplete/CommandProvider.js +++ b/src/autocomplete/CommandProvider.js @@ -16,7 +16,7 @@ limitations under the License. */ import React from 'react'; -import { _t } from '../languageHandler'; +import { _t, _td } from '../languageHandler'; import AutocompleteProvider from './AutocompleteProvider'; import FuzzyMatcher from './FuzzyMatcher'; import {TextualCompletion} from './Components'; @@ -27,82 +27,82 @@ const COMMANDS = [ { command: '/me', args: '', - description: 'Displays action', + description: _td('Displays action'), }, { command: '/ban', args: ' [reason]', - description: 'Bans user with given id', + description: _td('Bans user with given id'), }, { command: '/unban', args: '', - description: 'Unbans user with given id', + description: _td('Unbans user with given id'), }, { command: '/op', args: ' []', - description: 'Define the power level of a user', + description: _td('Define the power level of a user'), }, { command: '/deop', args: '', - description: 'Deops user with given id', + description: _td('Deops user with given id'), }, { command: '/invite', args: '', - description: 'Invites user with given id to current room', + description: _td('Invites user with given id to current room'), }, { command: '/join', args: '', - description: 'Joins room with given alias', + description: _td('Joins room with given alias'), }, { command: '/part', args: '[]', - description: 'Leave room', + description: _td('Leave room'), }, { command: '/topic', args: '', - description: 'Sets the room topic', + description: _td('Sets the room topic'), }, { command: '/kick', args: ' [reason]', - description: 'Kicks user with given id', + description: _td('Kicks user with given id'), }, { command: '/nick', args: '', - description: 'Changes your display nickname', + description: _td('Changes your display nickname'), }, { command: '/ddg', args: '', - description: 'Searches DuckDuckGo for results', + description: _td('Searches DuckDuckGo for results'), }, { command: '/tint', args: ' []', - description: 'Changes colour scheme of current room', + description: _td('Changes colour scheme of current room'), }, { command: '/verify', args: ' ', - description: 'Verifies a user, device, and pubkey tuple', + description: _td('Verifies a user, device, and pubkey tuple'), }, { command: '/ignore', args: '', - description: 'Ignores a user, hiding their messages from you', + description: _td('Ignores a user, hiding their messages from you'), }, { command: '/unignore', args: '', - description: 'Stops ignoring a user, showing their messages going forward', + description: _td('Stops ignoring a user, showing their messages going forward'), }, // Omitting `/markdown` as it only seems to apply to OldComposer ]; diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index d2f27b63e1..572ee79a69 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -32,7 +32,7 @@ const AddThreepid = require('../../AddThreepid'); const SdkConfig = require('../../SdkConfig'); import Analytics from '../../Analytics'; import AccessibleButton from '../views/elements/AccessibleButton'; -import { _t } from '../../languageHandler'; +import { _t, _td } from '../../languageHandler'; import * as languageHandler from '../../languageHandler'; import * as FormattingUtils from '../../utils/FormattingUtils'; @@ -63,55 +63,55 @@ const gHVersionLabel = function(repo, token='') { const SETTINGS_LABELS = [ { id: 'autoplayGifsAndVideos', - label: 'Autoplay GIFs and videos', + label: _td('Autoplay GIFs and videos'), }, { id: 'hideReadReceipts', - label: 'Hide read receipts', + label: _td('Hide read receipts'), }, { id: 'dontSendTypingNotifications', - label: "Don't send typing notifications", + label: _td("Don't send typing notifications"), }, { id: 'alwaysShowTimestamps', - label: 'Always show message timestamps', + label: _td('Always show message timestamps'), }, { id: 'showTwelveHourTimestamps', - label: 'Show timestamps in 12 hour format (e.g. 2:30pm)', + label: _td('Show timestamps in 12 hour format (e.g. 2:30pm)'), }, { id: 'hideJoinLeaves', - label: 'Hide join/leave messages (invites/kicks/bans unaffected)', + label: _td('Hide join/leave messages (invites/kicks/bans unaffected)'), }, { id: 'hideAvatarDisplaynameChanges', - label: 'Hide avatar and display name changes', + label: _td('Hide avatar and display name changes'), }, { id: 'useCompactLayout', - label: 'Use compact timeline layout', + label: _td('Use compact timeline layout'), }, { id: 'hideRedactions', - label: 'Hide removed messages', + label: _td('Hide removed messages'), }, { id: 'enableSyntaxHighlightLanguageDetection', - label: 'Enable automatic language detection for syntax highlighting', + label: _td('Enable automatic language detection for syntax highlighting'), }, { id: 'MessageComposerInput.autoReplaceEmoji', - label: 'Automatically replace plain text Emoji', + label: _td('Automatically replace plain text Emoji'), }, { id: 'MessageComposerInput.dontSuggestEmoji', - label: 'Disable Emoji suggestions while typing', + label: _td('Disable Emoji suggestions while typing'), }, { id: 'Pill.shouldHidePillAvatar', - label: 'Hide avatars in user and room mentions', + label: _td('Hide avatars in user and room mentions'), }, /* { @@ -124,7 +124,7 @@ const SETTINGS_LABELS = [ const ANALYTICS_SETTINGS_LABELS = [ { id: 'analyticsOptOut', - label: 'Opt out of analytics', + label: _td('Opt out of analytics'), fn: function(checked) { Analytics[checked ? 'disable' : 'enable'](); }, @@ -134,7 +134,7 @@ const ANALYTICS_SETTINGS_LABELS = [ const WEBRTC_SETTINGS_LABELS = [ { id: 'webRtcForceTURN', - label: 'Disable Peer-to-Peer for 1:1 calls', + label: _td('Disable Peer-to-Peer for 1:1 calls'), }, ]; @@ -143,7 +143,7 @@ const WEBRTC_SETTINGS_LABELS = [ const CRYPTO_SETTINGS_LABELS = [ { id: 'blacklistUnverifiedDevices', - label: 'Never send encrypted messages to unverified devices from this device', + label: _td('Never send encrypted messages to unverified devices from this device'), fn: function(checked) { MatrixClientPeg.get().setGlobalBlacklistUnverifiedDevices(checked); }, @@ -166,12 +166,12 @@ const CRYPTO_SETTINGS_LABELS = [ const THEMES = [ { id: 'theme', - label: 'Light theme', + label: _td('Light theme'), value: 'light', }, { id: 'theme', - label: 'Dark theme', + label: _td('Dark theme'), value: 'dark', }, ]; diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 7436f84f69..1d7e4bd217 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -22,7 +22,7 @@ import MatrixClientPeg from '../../../MatrixClientPeg'; import ScalarAuthClient from '../../../ScalarAuthClient'; import SdkConfig from '../../../SdkConfig'; import Modal from '../../../Modal'; -import { _t } from '../../../languageHandler'; +import { _t, _td } from '../../../languageHandler'; import sdk from '../../../index'; import AppPermission from './AppPermission'; import AppWarning from './AppWarning'; @@ -170,9 +170,9 @@ export default React.createClass({ // These strings are translated at the point that they are inserted in to the DOM, in the render method _deleteWidgetLabel() { if (this._canUserModify()) { - return 'Delete widget'; + return _td('Delete widget'); } - return 'Revoke widget access'; + return _td('Revoke widget access'); }, /* TODO -- Store permission in account data so that it is persisted across multiple devices */ diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 37602a94ca..39666c94a4 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -30,7 +30,7 @@ import SlashCommands from '../../../SlashCommands'; import KeyCode from '../../../KeyCode'; import Modal from '../../../Modal'; import sdk from '../../../index'; -import { _t } from '../../../languageHandler'; +import { _t, _td } from '../../../languageHandler'; import Analytics from '../../../Analytics'; import dis from '../../../dispatcher'; @@ -1032,10 +1032,10 @@ export default class MessageComposerInput extends React.Component { buttons. */ getSelectionInfo(editorState: EditorState) { const styleName = { - BOLD: 'bold', - ITALIC: 'italic', - STRIKETHROUGH: 'strike', - UNDERLINE: 'underline', + BOLD: _td('bold'), + ITALIC: _td('italic'), + STRIKETHROUGH: _td('strike'), + UNDERLINE: _td('underline'), }; const originalStyle = editorState.getCurrentInlineStyle().toArray(); @@ -1044,10 +1044,10 @@ export default class MessageComposerInput extends React.Component { .filter((styleName) => !!styleName); const blockName = { - 'code-block': 'code', - 'blockquote': 'quote', - 'unordered-list-item': 'bullet', - 'ordered-list-item': 'numbullet', + 'code-block': _td('code'), + 'blockquote': _td('quote'), + 'unordered-list-item': _td('bullet'), + 'ordered-list-item': _td('numbullet'), }; const originalBlockType = editorState.getCurrentContent() .getBlockForKey(editorState.getSelection().getStartKey()) diff --git a/src/languageHandler.js b/src/languageHandler.js index 4455d58b04..12242a2e15 100644 --- a/src/languageHandler.js +++ b/src/languageHandler.js @@ -29,6 +29,12 @@ counterpart.setSeparator('|'); // Fall back to English counterpart.setFallbackLocale('en'); +// Function which only purpose is to mark that a string is translatable +// Does not actually do anything. It's helpful for automatic extraction of translatable strings +export function _td(s) { + return s; +} + // The translation function. This is just a simple wrapper to counterpart, // but exists mostly because we must use the same counterpart instance // between modules (ie. here (react-sdk) and the app (riot-web), and if we From cc441f42f9594f3e59b58ece05ccfaa2b99e4422 Mon Sep 17 00:00:00 2001 From: Stefan Parviainen Date: Sat, 23 Sep 2017 09:02:51 +0200 Subject: [PATCH 029/123] Some more translatable strings Signed-off-by: Stefan Parviainen --- src/components/views/dialogs/KeyShareDialog.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/views/dialogs/KeyShareDialog.js b/src/components/views/dialogs/KeyShareDialog.js index aed8e6a5af..c44e856382 100644 --- a/src/components/views/dialogs/KeyShareDialog.js +++ b/src/components/views/dialogs/KeyShareDialog.js @@ -18,7 +18,7 @@ import Modal from '../../../Modal'; import React from 'react'; import sdk from '../../../index'; -import { _t } from '../../../languageHandler'; +import { _t, _td } from '../../../languageHandler'; /** * Dialog which asks the user whether they want to share their keys with @@ -116,11 +116,11 @@ export default React.createClass({ let text; if (this.state.wasNewDevice) { - text = "You added a new device '%(displayName)s', which is" - + " requesting encryption keys."; + text = _td("You added a new device '%(displayName)s', which is" + + " requesting encryption keys."); } else { - text = "Your unverified device '%(displayName)s' is requesting" - + " encryption keys."; + text = _td("Your unverified device '%(displayName)s' is requesting" + + " encryption keys."); } text = _t(text, {displayName: displayName}); From 198dc7ea5cd02c86ae63ba3ffce08213e9596bca Mon Sep 17 00:00:00 2001 From: Jan Kudrik Date: Sat, 23 Sep 2017 15:39:09 +0000 Subject: [PATCH 030/123] Translated using Weblate (Czech) Currently translated at 47.6% (407 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/cs/ --- src/i18n/strings/cs.json | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index 5e4846794a..31a52593b0 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -378,5 +378,32 @@ "This room has no local addresses": "Tato místnost nemá žádné místní adresy", "This room is not recognised.": "Tato místnost nebyla rozpoznána.", "These are experimental features that may break in unexpected ways": "Tyto funkce jsou experimentální a mohou se pokazit nečekanými způsoby", - "The visibility of existing history will be unchanged": "Viditelnost existující historie nebude změněna" + "The visibility of existing history will be unchanged": "Viditelnost existující historie nebude změněna", + "VoIP is unsupported": "VoIP není podporován", + "Warning!": "Pozor!", + "Who can access this room?": "Kdo má přístup k této místnosti?", + "Who can read history?": "Kdo může číst historii?", + "Who would you like to add to this room?": "Koho byste chtěli přidat do této místnosti?", + "Who would you like to communicate with?": "S kým byste chtěli komunikovat?", + "Would you like to accept or decline this invitation?": "Chtěli byste tuto pozvánku přijmout nebo odmítnout?", + "You are not in this room.": "Nejste v této místnosti.", + "You do not have permission to do that in this room.": "V této místnosti nemáte na toto právo.", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Ještě nejste v žádné místnosti! Zmáčkněte pro vytvoření místnosti nebo pro prohlížení adresáře", + "You are trying to access %(roomName)s.": "Snažíte se přistoupit k %(roomName)s.", + "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 have been banned from %(roomName)s by %(userName)s.": "%(userName)s vás vykázal/a z místnosti %(roomName)s.", + "You have been kicked from %(roomName)s by %(userName)s.": "%(userName)s vás vykopnul/a z místnosti %(roomName)s.", + "You have entered an invalid contact. Try using their Matrix ID or email address.": "Zadali jste neplatný kontakt. Zkuste jejich Matrix ID nebo e-mailovou adresu.", + "you must be a": "musíte být", + "You need to enter a user name.": "Musíte zadat uživatelské jméno.", + "Your password has been reset": "Vaše heslo bylo resetováno", + "Your home server does not support device management.": "Váš domovský server nepodporuje správu zařízení.", + "Online": "Online", + "Offline": "Offline", + "Updates": "Aktualizace", + "Check for update": "Zkontrolovat aktualizace", + "Start chatting": "Začít chatovat", + "Start Chatting": "Začít chatovat" } From 14bce1119c15feefee5813c8f4cd50ded7f76526 Mon Sep 17 00:00:00 2001 From: Stefan Parviainen Date: Sat, 23 Sep 2017 21:36:10 +0200 Subject: [PATCH 031/123] Make theme names translatable Signed-off-by: Stefan Parviainen --- src/components/structures/UserSettings.js | 2 +- src/i18n/strings/en_EN.json | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 572ee79a69..5e7658f056 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -793,7 +793,7 @@ module.exports = React.createClass({ onChange={ onChange } /> ; }, diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index a0945d7f50..8b53f17d8c 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -879,5 +879,7 @@ "Failed to remove the room from the summary of %(groupId)s": "Failed to remove the room from the summary of %(groupId)s", "The room '%(roomName)' could not be removed from the summary.": "The room '%(roomName)' could not be removed from the summary.", "Failed to remove a user from the summary of %(groupId)s": "Failed to remove a user from the summary of %(groupId)s", - "The user '%(displayName)s' could not be removed from the summary.": "The user '%(displayName)s' could not be removed from the summary." + "The user '%(displayName)s' could not be removed from the summary.": "The user '%(displayName)s' could not be removed from the summary.", + "Light theme": "Light theme", + "Dark theme": "Dark theme" } From dbae5a66e3a3b1b83bd08304c408a3939b11ed59 Mon Sep 17 00:00:00 2001 From: Stefan Parviainen Date: Sun, 24 Sep 2017 09:43:52 +0200 Subject: [PATCH 032/123] Use translation in img alt text Signed-off-by: Stefan Parviainen --- src/components/views/room_settings/AliasSettings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/room_settings/AliasSettings.js b/src/components/views/room_settings/AliasSettings.js index f37bd4271a..ea3bad390f 100644 --- a/src/components/views/room_settings/AliasSettings.js +++ b/src/components/views/room_settings/AliasSettings.js @@ -299,7 +299,7 @@ module.exports = React.createClass({ blurToCancel={ false } onValueChanged={ self.onAliasAdded } />
- Add
: "" From 2b5b7080572940fed75960b76ede1725e7cb6b35 Mon Sep 17 00:00:00 2001 From: Stefan Parviainen Date: Sun, 24 Sep 2017 10:14:04 +0200 Subject: [PATCH 033/123] Translate unknown presence label Signed-off-by: Stefan Parviainen --- src/components/views/rooms/PresenceLabel.js | 2 +- src/i18n/strings/en_EN.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/PresenceLabel.js b/src/components/views/rooms/PresenceLabel.js index 47a723f5cd..87b218e2e2 100644 --- a/src/components/views/rooms/PresenceLabel.js +++ b/src/components/views/rooms/PresenceLabel.js @@ -70,7 +70,7 @@ module.exports = React.createClass({ if (presence === "online") return _t("Online"); if (presence === "unavailable") return _t("Idle"); // XXX: is this actually right? if (presence === "offline") return _t("Offline"); - return "Unknown"; + return _t("Unknown"); }, render: function() { diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 8b53f17d8c..f3e4b93e9c 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -881,5 +881,6 @@ "Failed to remove a user from the summary of %(groupId)s": "Failed to remove a user from the summary of %(groupId)s", "The user '%(displayName)s' could not be removed from the summary.": "The user '%(displayName)s' could not be removed from the summary.", "Light theme": "Light theme", - "Dark theme": "Dark theme" + "Dark theme": "Dark theme", + "Unknown": "Unknown" } From b9584cd421eeb37a0b69c28161a180e10bdbb6ab Mon Sep 17 00:00:00 2001 From: Bruno Bigras Date: Sat, 23 Sep 2017 19:10:38 +0000 Subject: [PATCH 034/123] Translated using Weblate (French) Currently translated at 98.8% (845 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-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 80e76a17ac..5459672f9e 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -600,7 +600,7 @@ "Unknown Address": "Adresse inconnue", "Unblacklist": "Réhabiliter", "Blacklist": "Blacklister", - "Unverify": "Non-vérifié", + "Unverify": "Révoquer", "Verify...": "Vérifier...", "ex. @bob:example.com": "ex. @bob:exemple.com", "Add User": "Ajouter l'utilisateur", From 38f884f28506f5b65d74e87e2e527d45981fb05f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Sun, 24 Sep 2017 23:36:51 +0000 Subject: [PATCH 035/123] Translated using Weblate (French) Currently translated at 99.8% (854 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 691 ++++++++++++++++++++------------------- 1 file changed, 350 insertions(+), 341 deletions(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 5459672f9e..bf83f394d5 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -1,41 +1,41 @@ { "anyone": "n'importe qui", "Direct Chat": "Discussion directe", - "Direct chats": "Conversations directes", - "Disable inline URL previews by default": "Désactiver l’aperçu des URLs", + "Direct chats": "Discussions directes", + "Disable inline URL previews by default": "Désactiver l’aperçu des liens", "Disinvite": "Désinviter", - "Display name": "Nom d'affichage", + "Display name": "Nom affiché", "Displays action": "Affiche l'action", "Don't send typing notifications": "Ne pas envoyer les notifications de saisie", "Download %(text)s": "Télécharger %(text)s", "Drop here %(toAction)s": "Déposer ici %(toAction)s", - "Drop here to tag %(section)s": "Déposer ici pour marquer comme %(section)s", + "Drop here to tag %(section)s": "Déposer ici pour étiqueter comme %(section)s", "Ed25519 fingerprint": "Empreinte Ed25519", "Email Address": "Adresse e-mail", "Email, name or matrix ID": "E-mail, nom ou identifiant Matrix", - "Emoji": "Emoticône", + "Emoji": "Émoticône", "Enable encryption": "Activer le chiffrement", "Encrypted messages will not be visible on clients that do not yet implement encryption": "Les messages chiffrés ne seront pas visibles dans les clients qui n’implémentent pas encore le chiffrement", "Encrypted room": "Salon chiffré", "%(senderName)s ended the call.": "%(senderName)s a terminé l’appel.", - "End-to-end encryption information": "Information sur le chiffrement de bout-en-bout", - "End-to-end encryption is in beta and may not be reliable": "Le chiffrement de bout-en-bout est en bêta et risque de ne pas être fiable", - "Enter Code": "Entrer le code", + "End-to-end encryption information": "Informations sur le chiffrement de bout en bout", + "End-to-end encryption is in beta and may not be reliable": "Le chiffrement de bout en bout est en bêta et risque de ne pas être fiable", + "Enter Code": "Saisir le code", "Error": "Erreur", - "Event information": "Information de l'événement", + "Event information": "Informations de l'événement", "Existing Call": "Appel en cours", - "Export E2E room keys": "Exporter les clés de chiffrement du salon", - "Failed to ban user": "Échec lors du bannissement de l'utilisateur", + "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 change power level": "Échec du changement de niveau d'autorité", + "Failed to change power level": "Échec du changement de rang", "Failed to delete device": "Échec de la suppression de l'appareil", - "Failed to forget room %(errCode)s": "Échec lors de l'oubli du salon %(errCode)s", + "Failed to forget room %(errCode)s": "Échec de l'oubli du salon %(errCode)s", "Please Register": "Veuillez vous inscrire", "Remove": "Supprimer", "was banned": "a été banni(e)", "was invited": "a été invité(e)", - "was kicked": "a été expulsé(e)", - "was unbanned": "a été amnistié(e)", + "was kicked": "a été exclu(e)", + "was unbanned": "a vu son bannissement révoqué", "Monday": "Lundi", "Tuesday": "Mardi", "Wednesday": "Mercredi", @@ -51,56 +51,56 @@ "Notifications": "Notifications", "Settings": "Paramètres", "Failed to join the room": "Échec de l'adhésion au salon", - "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Un message texte a été envoyé à +%(msisdn)s. Merci d'entrer 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. Merci de saisir le code de vérification qu'il contient", "accept": "Accepter", "%(targetName)s accepted an invitation.": "%(targetName)s a accepté une invitation.", "Account": "Compte", "Add email address": "Ajouter une adresse e-mail", - "Add phone number": "Ajouter un numéro", - "Admin": "Admin", + "Add phone number": "Ajouter un numéro de téléphone", + "Admin": "Administrateur", "Advanced": "Avancé", "Algorithm": "Algorithme", "all room members": "tous les membres du salon", "all room members, from the point they are invited": "tous les membres du salon, depuis le moment où ils ont été invités", - "all room members, from the point they joined": "tous les membres du salon, depuis le moment où ils ont rejoint", + "all room members, from the point they joined": "tous les membres du salon, depuis le moment où ils l'ont rejoint", "an address": "une adresse", "and": "et", "%(items)s and %(remaining)s others": "%(items)s et %(remaining)s autres", "%(items)s and one other": "%(items)s et un autre", "%(items)s and %(lastItem)s": "%(items)s et %(lastItem)s", - "%(names)s and %(lastPerson)s are typing": "%(names)s et %(lastPerson)s sont en train d'écrire", - "%(names)s and one other are typing": "%(names)s et un autre sont en train d'écrire", - "%(names)s and %(count)s others are typing": "%(names)s et %(count)s d'autres sont en train d'écrire", + "%(names)s and %(lastPerson)s are typing": "%(names)s et %(lastPerson)s écrivent", + "%(names)s and one other are typing": "%(names)s et un autre écrivent", + "%(names)s and %(count)s others are typing": "%(names)s et %(count)s autres écrivent", "and %(count)s others...|other": "et %(count)s autres...", "and %(count)s others...|one": "et un autre...", "An email has been sent to": "Un e-mail a été envoyé à", - "A new password must be entered.": "Un nouveau mot de passe doit être entré.", + "A new password must be entered.": "Un nouveau mot de passe doit être saisi.", "Anyone who knows the room's link, apart from guests": "Tout ceux qui connaissent le lien du salon, à part les visiteurs", "Anyone who knows the room's link, including guests": "Tout ceux qui connaissent le lien du salon, y compris les visiteurs", - "Are you sure?": "Êtes-vous sûr ?", - "Are you sure you want to reject the invitation?": "Êtes-vous sûr de vouloir rejeter l'invitation ?", - "Are you sure you want to upload the following files?": "Êtes-vous sûr de vouloir télécharger les fichiers suivants ?", + "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 you want to upload the following files?": "Voulez-vous vraiment envoyer les fichiers suivants ?", "Attachment": "Pièce jointe", - "Autoplay GIFs and videos": "Jouer automatiquement les GIFs et vidéos", + "Autoplay GIFs and videos": "Jouer automatiquement les GIFs et les vidéos", "%(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 avec un identifiant donné", + "Bans user with given id": "Bannit l'utilisateur à partir de son identifiant", "Blacklisted": "Sur liste noire", "Bug Report": "Rapport d'erreur", "Call Timeout": "Délai d’appel expiré", "Can't connect to homeserver - please check your connectivity and ensure your homeserver's SSL certificate is trusted.": "Connexion au Home Server impossible - merci de vérifier votre connectivité et que le certificat SSL de votre Home Server est de confiance.", - "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 homeserver 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 load user settings": "Impossible de charger les paramètres utilisateur", + "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 load user settings": "Impossible de charger les paramètres de l'utilisateur", "Change Password": "Changer le mot de passe", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s a changé son nom d’affichage de %(oldDisplayName)s en %(displayName)s.", - "%(senderName)s changed their profile picture.": "%(senderName)s a changé sa photo de profil.", - "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s a changé le niveau de pouvoir de %(powerLevelDiffText)s.", + "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s a changé son nom affiché de %(oldDisplayName)s en %(displayName)s.", + "%(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 to who can read history will only apply to future messages in this room": "Les changements de visibilité de l’historique de ce salon ne s’appliquent qu’aux messages futurs", - "Changes your display nickname": "Change votre nom d'affichage", - "Claimed Ed25519 fingerprint key": "Clé empreinte Ed25519 revendiquée", + "Changes to who can read history will only apply to future messages in this room": "Les changements de visibilité de l’historique de ce salon ne s’appliquent qu’aux futurs messages", + "Changes your display nickname": "Change votre nom affiché", + "Claimed Ed25519 fingerprint key": "Clé de l'empreinte Ed25519 revendiquée", "Clear Cache and Reload": "Vider le cache et rafraîchir", "Clear Cache": "Vider le cache", "Click here": "Cliquer ici", @@ -112,10 +112,10 @@ "Click to unmute audio": "Cliquer pour rétablir le son", "Command error": "Erreur de commande", "Commands": "Commandes", - "Conference call failed.": "Échec de la conférence.", - "Conference calling is in development and may not be reliable.": "Les appels en conférence sont encore en développement et sont potentiellement peu fiables.", - "Conference calls are not supported in encrypted rooms": "Les appels en conférence ne sont pas supportés dans les salons chiffrés", - "Conference calls are not supported in this client": "Les appels en conférence ne sont pas supportés avec ce client", + "Conference call failed.": "Échec de la téléconférence.", + "Conference calling is in development and may not be reliable.": "Les appels en téléconférence sont encore en développement et sont potentiellement peu fiables.", + "Conference calls are not supported in encrypted rooms": "Les appels en téléconférence ne sont pas supportés dans les salons chiffrés", + "Conference calls are not supported in this client": "Les appels en téléconférence ne sont pas supportés par ce client", "Confirm password": "Confirmer le mot de passe", "Confirm your new password": "Confirmer votre nouveau mot de passe", "Continue": "Continuer", @@ -133,25 +133,25 @@ "Decryption error": "Erreur de déchiffrement", "Delete": "Supprimer", "demote": "rétrograder", - "Deops user with given id": "Retire les privilèges d’opérateur d’un utilisateur avec un ID donné", + "Deops user with given id": "Retire le rang d’opérateur d’un utilisateur à partir de son identifiant", "Device ID": "Identifiant de l'appareil", "Devices": "Appareils", - "Devices will not yet be able to decrypt history from before they joined the room": "Les appareils ne seront pas capables de déchiffrer l’historique précédant leur adhésion au salon", + "Devices will not yet be able to decrypt history from before they joined the room": "Les appareils ne pourront pas encore déchiffrer l'historique de messages d'avant leur arrivée sur le salon", "ml": "Malayalam", "Failed to join room": "Échec lors de l’adhésion au salon", - "Failed to kick": "Échec lors de l'expulsion", - "Failed to leave room": "Échec du départ", - "Failed to load timeline position": "Erreur lors du chargement de la position dans la chronologie", - "Failed to lookup current room": "Échec lors de la recherche du salon actuel", - "Failed to mute user": "Échec lors de l'interruption de l'utilisateur", - "Failed to reject invite": "Échec lors du rejet de l'invitation", - "Failed to reject invitation": "Échec lors du rejet de l'invitation", - "Failed to save settings": "Échec lors de la sauvegarde des paramètres", - "Failed to send email": "Échec lors de l’envoi de l’e-mail", - "Failed to send request.": "Erreur lors de l'envoi de la requête.", - "Failed to set display name": "Échec lors de l'enregistrement du nom d'affichage", - "Failed to set up conference call": "Échec lors de l’établissement de l’appel", - "Failed to toggle moderator status": "Échec lors de l’activation du statut de modérateur", + "Failed to kick": "Échec de l'exclusion", + "Failed to leave room": "Échec du départ du salon", + "Failed to load timeline position": "Échec du chargement de la position dans la chronologie", + "Failed to lookup current room": "Échec de la recherche du salon actuel", + "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 save settings": "Échec de la sauvegarde des paramètres", + "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 up conference call": "Échec de l’établissement de la téléconférence", + "Failed to toggle moderator status": "Échec de l’activation du statut de modérateur", "%(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", @@ -159,8 +159,8 @@ "%(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 l'amnistie", - "Failed to upload file": "Échec du téléchargement", + "Failed to unban": "Échec de la révocation du bannissement", + "Failed to upload file": "Échec de l'envoi du fichier", "Failed to verify email address: make sure you clicked the link in the email": "Échec de la vérification de l’adresse e-mail : 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", "favourite": "favoris", @@ -168,62 +168,62 @@ "Fill screen": "Plein écran", "Filter room members": "Filtrer les membres du salon", "Forget room": "Oublier le salon", - "Forgot your password?": "Mot de passe perdu ?", - "For security, this session has been signed out. Please sign in again.": "Par sécurité, la session a expiré. Merci de vous authentifier à nouveau.", - "Found a bug?": "Trouvé un problème ?", + "Forgot your password?": "Mot de passe oublié ?", + "For security, this session has been signed out. Please sign in again.": "Par mesure de sécurité, la session a expiré. Merci de vous authentifier à nouveau.", + "Found a bug?": "Vous avez trouvé un problème ?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s de %(fromPowerLevel)s à %(toPowerLevel)s", - "Guest users can't create new rooms. Please register to create room and start a chat.": "Les visiteurs ne peuvent créer de nouveaux salons. Merci de vous inscrire pour commencer une discussion.", - "Guest users can't upload files. Please register to upload.": "Les visiteurs ne peuvent pas télécharger de fichier. Veuillez vous inscrire pour télécharger.", + "Guest users can't create new rooms. Please register to create room and start a chat.": "Les visiteurs ne peuvent pas créer de nouveau salon. Veuillez vous inscrire pour créer un salon et commencer une discussion.", + "Guest users can't upload files. Please register to upload.": "Les visiteurs ne peuvent pas envoyer de fichier. Veuillez vous inscrire pour envoyer des fichiers.", "had": "avait", "Hangup": "Raccrocher", "Hide read receipts": "Cacher les accusés de lecture", "Hide Text Formatting Toolbar": "Cacher la barre de formatage de texte", "Historical": "Historique", - "Homeserver is": "Le homeserver 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", + "Import E2E room keys": "Importer les clés de chiffrement de bout en bout", "Incorrect verification code": "Code de vérification incorrect", "Interface Language": "Langue de l'interface", - "Invalid alias format": "Format de l'alias invalide", - "Invalid address format": "Format d'adresse invalide", - "Invalid Email Address": "Adresse e-mail invalide", + "Invalid alias format": "Format d'alias non valide", + "Invalid address format": "Format d'adresse non valide", + "Invalid Email Address": "Adresse e-mail non valide", "%(senderName)s invited %(targetName)s.": "%(senderName)s a invité %(targetName)s.", "Invite new room members": "Inviter de nouveaux membres", "Invited": "Invités", "Invites": "Invitations", - "Invites user with given id to current room": "Inviter l’utilisateur avec un ID donné dans le salon actuel", + "Invites user with given id to current room": "Invite un utilisateur dans le salon actuel à partir de son identifiant", "is a": "est un", "'%(alias)s' is not a valid format for an address": "'%(alias)s' n'est pas un format valide pour une adresse", "'%(alias)s' is not a valid format for an alias": "'%(alias)s' n'est pas un format valide pour un alias", - "%(displayName)s is typing": "%(displayName)s est en train d'écrire", - "Sign in with": "Je veux m'identifier avec", + "%(displayName)s is typing": "%(displayName)s écrit", + "Sign in with": "Se connecter avec", "Join Room": "Rejoindre le salon", - "joined and left": "a rejoint et quitté", + "joined and left": "a rejoint et est parti", "joined": "a rejoint", "%(targetName)s joined the room.": "%(targetName)s a rejoint le salon.", - "Joins room with given alias": "Rejoint le salon avec l'alias défini", - "%(senderName)s kicked %(targetName)s.": "%(senderName)s a expulsé %(targetName)s.", - "Kick": "Expulser", - "Kicks user with given id": "Expulse l'utilisateur avec l'ID donné", + "Joins room with given alias": "Rejoint le salon avec l'alias renseigné", + "%(senderName)s kicked %(targetName)s.": "%(senderName)s a exclu %(targetName)s.", + "Kick": "Exclure", + "Kicks user with given id": "Exclut l'utilisateur à partir de son identifiant", "Labs": "Laboratoire", "Leave room": "Quitter le salon", - "left and rejoined": "a quitté et rejoint", - "left": "a quitté", + "left and rejoined": "est parti et revenu", + "left": "est parti", "%(targetName)s left the room.": "%(targetName)s a quitté le salon.", "Level": "Niveau", - "Local addresses for this room:": "Adresse locale pour ce salon :", + "Local addresses for this room:": "Adresses locales pour ce salon :", "Logged in as:": "Identifié en tant que :", - "Login as guest": "S'identifier en tant que visiteur", + "Login as guest": "Se connecter en tant que visiteur", "Logout": "Se déconnecter", - "Low priority": "Priorité basse", - "%(senderName)s made future room history visible to": "%(senderName)s a rendu l'historique visible à", + "Low priority": "Priorité faible", + "%(senderName)s made future room history visible to": "%(senderName)s a rendu l'historique futur visible à", "Manage Integrations": "Gestion des intégrations", - "Markdown is disabled": "Le formatage \"Markdown\" est désactivé", - "Markdown is enabled": "Le formatage “Markdown” est activé", - "matrix-react-sdk version:": "Version du matrix-react-sdk :", + "Markdown is disabled": "Le formatage Markdown est désactivé", + "Markdown is enabled": "Le formatage Markdown est activé", + "matrix-react-sdk version:": "Version de matrix-react-sdk :", "Members only": "Membres uniquement", - "Message not sent due to unknown devices being present": "Message non-envoyé à cause de la présence d’appareils non-vérifiés", + "Message not sent due to unknown devices being present": "Message non envoyé à cause de la présence d’appareils inconnus", "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", "Mobile phone number": "Numéro de téléphone mobile", @@ -231,11 +231,11 @@ "Must be viewing a room": "Doit être en train de visualiser un salon", "my Matrix ID": "mon identifiant Matrix", "Name": "Nom", - "Never send encrypted messages to unverified devices from this device": "Ne jamais envoyer de message chiffré aux appareils non-vérifiés depuis cet appareil", - "Never send encrypted messages to unverified devices in this room": "Ne jamais envoyer de message chiffré aux appareils non-vérifiés dans ce salon", - "Never send encrypted messages to unverified devices in this room from this device": "Ne jamais envoyer de message chiffré aux appareils non-vérifiés dans ce salon depuis cet appareil", + "Never send encrypted messages to unverified devices from this device": "Ne jamais envoyer de message chiffré aux appareils non vérifiés depuis cet appareil", + "Never send encrypted messages to unverified devices in this room": "Ne jamais envoyer de message chiffré aux appareils non vérifiés dans ce salon", + "Never send encrypted messages to unverified devices in this room from this device": "Ne jamais envoyer de message chiffré aux appareils non vérifiés dans ce salon depuis cet appareil", "New address (e.g. #foo:%(localDomain)s)": "Nouvelle adresse (par ex. #foo:%(localDomain)s)", - "New Composer & Autocomplete": "Nouveau compositeur et autocomplétion", + "New Composer & Autocomplete": "Nouveau compositeur et auto-complétion", "New password": "Nouveau mot de passe", "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.", @@ -247,8 +247,8 @@ "NOT verified": "NON vérifié", "No devices with registered encryption keys": "Pas d’appareil avec des clés de chiffrement enregistrées", "No more results": "Fin des résultats", - "No results": "Pas de résultats", - "unknown error code": "Code erreur inconnu", + "No results": "Pas de résultat", + "unknown error code": "Code d'erreur inconnu", "OK": "OK", "Once encryption is enabled for a room it cannot be turned off again (for now)": "Une fois le chiffrement activé dans un salon il ne peut pas être désactivé (pour le moment)", "Only people who have been invited": "Seul les personnes ayant été invitées", @@ -260,26 +260,26 @@ "Phone": "Numéro de téléphone", "Operation failed": "L'opération a échoué", "Bulk Options": "Options de masse", - "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Changer le mot de passe réinitialise actuellement les clés de chiffrement sur tous les appareils, rendant l’historique chiffré illisible, à moins d’exporter les clés du salon en avance de phase puis de les ré-importer. Ceci sera amélioré prochainement.", + "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Pour le moment, changer le mot de passe réinitialise les clés de chiffrement sur tous les appareils, rendant l’historique des discussions chiffrées illisible, à moins d’exporter d'abord les clés de salon puis de les ré-importer. Ceci sera amélioré prochainement.", "Default": "Par défaut", "Email address": "Adresse e-mail", "Error decrypting attachment": "Erreur lors du déchiffrement de la pièce jointe", - "Failed to set avatar.": "Erreur lors de la définition de la photo de profil.", - "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Par sécurité une déconnexion supprimera toutes les clés de chiffrement de ce navigateur. Si vous voulez être capable de déchiffrer l’historique de votre conversation lors de sessions futures de Riot, merci d’exporter les clés pour le salon.", - "Guests can't set avatars. Please register.": "Les visiteurs ne peuvent définir de photo de profil. Merci de vous inscrire.", - "Guests can't use labs features. Please register.": "Les visiteurs ne peuvent utiliser les fonctionalités du laboratoire. Merci de vous inscrire.", - "Guests cannot join this room even if explicitly invited.": "Les visiteurs ne peuvent rejoindre ce salon, même si explicitement invités.", - "Invalid file%(extra)s": "Fichier %(extra)s invalide", - "Mute": "Couper le son", + "Failed to set avatar.": "Échec de la définition de l'avatar.", + "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Par mesure de sécurité une déconnexion supprimera toutes les clés de chiffrement de ce navigateur. Si vous voulez être capable de déchiffrer l’historique de votre conversation lors des prochaines sessions de Riot, veuillez exporter les clés de salon pour les garder en lieu sûr.", + "Guests can't set avatars. Please register.": "Les visiteurs ne peuvent pas définir d'avatar. Veuillez vous inscrire.", + "Guests can't use labs features. Please register.": "Les visiteurs ne peuvent pas utiliser les fonctionnalités du laboratoire. Veuillez vous inscrire.", + "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 :", "Once you've followed the link it contains, click below": "Une fois que vous aurez suivi le lien qu’il contient, cliquez ci-dessous", - "%(senderName)s placed a %(callType)s call.": "%(senderName)s a placé un appel %(callType)s.", + "%(senderName)s placed a %(callType)s call.": "%(senderName)s a passé un appel %(callType)s.", "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.", - "Press": "Cliquer", + "Power level must be positive integer.": "Le rang doit être un entier positif.", + "Press": "Appuyer", "Privacy warning": "Alerte de confidentialité", - "Privileged Users": "Utilisateur privilégié", + "Privileged Users": "Utilisateurs privilégiés", "Profile": "Profil", "Reason": "Raison", "Revoke Moderator": "Révoquer le modérateur", @@ -288,26 +288,26 @@ "%(targetName)s rejected the invitation.": "%(targetName)s a rejeté l’invitation.", "Reject invitation": "Rejeter l'invitation", "Remove Contact Information?": "Supprimer les informations du contact ?", - "%(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é sa photo de profil.", + "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s a supprimé son nom affiché (%(oldDisplayName)s).", + "%(senderName)s removed their profile picture.": "%(senderName)s a supprimé son image de profil.", "Remove %(threePid)s?": "Supprimer %(threePid)s ?", - "%(senderName)s requested a VoIP conference.": "%(senderName)s a demandé une conférence audio.", + "%(senderName)s requested a VoIP conference.": "%(senderName)s a demandé une téléconférence audio.", "Report it": "Le signaler", - "Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Réinitialiser le mot de passe va réinitialiser les clés de chiffrement sur tous les appareils, rendant l’historique chiffré illisible, à moins que vous ayez exporté les clés du salon en avance de phase puis que vous les ré-importiez. Cela sera amélioré prochainement.", + "Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Pour le moment, réinitialiser le mot de passe va réinitialiser les clés de chiffrement sur tous les appareils, rendant l’historique des salons chiffrés illisible, à moins que vous exportiez d'abord les clés de salon puis que vous les ré-importiez après. Cela sera amélioré prochainement.", "restore": "restaurer", "Return to app": "Retourner à l’application", - "Return to login screen": "Retourner à l’écran d’identification", + "Return to login screen": "Retourner à l’écran de connexion", "Riot does not have permission to send you notifications - please check your browser settings": "Riot n’a pas la permission de vous envoyer des notifications - merci de vérifier les paramètres de votre navigateur", - "Riot was not given permission to send notifications - please try again": "Riot n’a pas reçu la permission de vous envoyer des notifications - merci d’essayer à nouveau", + "Riot was not given permission to send notifications - please try again": "Riot n’a pas reçu la permission de vous envoyer des notifications - veuillez réessayer", "riot-web version:": "Version de riot-web :", "Room %(roomId)s not visible": "Le salon %(roomId)s n'est pas visible", "Room Colour": "Couleur du salon", "Room name (optional)": "Nom du salon (facultatif)", "Rooms": "Salons", "Scroll to bottom of page": "Aller en bas de la page", - "Scroll to unread messages": "Aller aux messages non-lus", + "Scroll to unread messages": "Aller aux messages non lus", "Search": "Rechercher", - "Search failed": "Erreur lors de la recherche", + "Search failed": "Échec de la recherche", "Searches DuckDuckGo for results": "Recherche des résultats dans DuckDuckGo", "Send a message (unencrypted)": "Envoyer un message (non chiffré)", "Send an encrypted message": "Envoyer un message chiffré", @@ -322,93 +322,93 @@ "Server may be unavailable or overloaded": "Le serveur semble être inaccessible ou surchargé", "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 the file too big": "Le serveur semble être inaccessible, surchargé ou le fichier est trop volumineux", - "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 avez rencontré un problème.", "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 photo de profil.", - "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s a défini son nom d’affichage comme %(displayName)s.", + "%(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.", "Show panel": "Dévoiler le panneau", "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": "S'identifier", + "Sign in": "Se connecter", "Sign out": "Se déconnecter", "since the point in time of selecting this option": "depuis le moment où cette option a été sélectionnée", "since they joined": "depuis qu’ils ont rejoint le salon", "since they were invited": "depuis qu’ils ont été invités", "Some of your messages have not been sent.": "Certains de vos messages n’ont pas été envoyés.", "Someone": "Quelqu'un", - "Sorry, this homeserver is using a login which is not recognised ": "Désolé, ce homeserver utilise un identifiant qui n’est pas reconnu ", - "Start a chat": "Démarrer une discussion", - "Start Chat": "Démarrer une discussion", + "Sorry, this homeserver is using a login which is not recognised ": "Désolé, ce serveur d'accueil utilise un identifiant qui n’est pas reconnu ", + "Start a chat": "Commencer une discussion", + "Start Chat": "Commencer une discussion", "Submit": "Soumettre", "Success": "Succès", - "tag as %(tagName)s": "marquer comme %(tagName)s", - "tag direct chat": "marquer comme discussion directe", + "tag as %(tagName)s": "étiqueter comme %(tagName)s", + "tag direct chat": "étiqueter comme discussion directe", "The default role for new room members is": "Le rôle par défaut des nouveaux membres est", "The main address for this room is": "L'adresse principale pour ce salon est", - "This action cannot be performed by a guest user. Please register to be able to do this.": "Cette action ne peut être effectuée par un visiteur. Merci de vous inscrire afin de pouvoir effectuer cette action.", + "This action cannot be performed by a guest user. Please register to be able to do this.": "Cette action ne peut pas être effectuée par un visiteur. Veuillez vous inscrire afin de pouvoir effectuer cette action.", "This email address is already in use": "Cette adresse e-mail est déjà utilisée", "This email address was not found": "Cette adresse e-mail n’a pas été trouvée", "%(actionVerb)s this person?": "%(actionVerb)s cette personne ?", - "The email address linked to your account must be entered.": "L’adresse e-mail liée à votre compte doit être entrée.", - "The file '%(fileName)s' exceeds this home server's size limit for uploads": "Le fichier '%(fileName)s' dépasse la taille limite autorisée pour les téléchargements sur ce homeserver", - "The file '%(fileName)s' failed to upload": "Le fichier '%(fileName)s' n’a pas pu être téléchargé", + "The email address linked to your account must be entered.": "L’adresse e-mail liée à votre compte doit être renseignée.", + "The file '%(fileName)s' exceeds this home server's size limit for uploads": "Le fichier '%(fileName)s' dépasse la taille limite autorisée pour les envois sur ce serveur d'accueil", + "The file '%(fileName)s' failed to upload": "Le fichier '%(fileName)s' n’a pas pu être envoyé", "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'a pas été reconnu.", - "These are experimental features that may break in unexpected ways": "Ces fonctionnalités sont expérimentales et risquent de mal fonctionner", - "The visibility of existing history will be unchanged": "La visibilité de l’historique existant sera inchangée", - "This doesn't appear to be a valid email address": "Cette adresse n’a pas l’air d’être valide", + "This room is not recognised.": "Ce salon n'est pas reconnu.", + "These are experimental features that may break in unexpected ways": "Ce sont des fonctionnalités expérimentales qui peuvent créer des problèmes inattendus", + "The visibility of existing history will be unchanged": "La visibilité de l’historique existant restera inchangée", + "This doesn't appear to be a valid email address": "Cette adresse e-mail ne semble pas valide", "this invitation?": "cette invitation ?", "This is a preview of this room. Room interactions have been disabled": "Ceci est un aperçu du salon. Les interactions avec le salon ont été désactivées", - "This phone number is already in use": "Ce numéro de téléphone est déja utilisé", + "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", "This room's internal ID is": "L'identifiant interne de ce salon est", "times": "fois", "To ban users": "Pour bannir des utilisateurs", "to browse the directory": "pour parcourir le répertoire", "To configure the room": "Pour configurer le salon", - "to demote": "pour réduire la priorité", - "to favourite": "pour marquer comme favori", + "to demote": "pour rétrograder", + "to favourite": "pour ajouter aux favoris", "To invite users into the room": "Pour inviter des utilisateurs dans le salon", "to join the discussion": "pour rejoindre la discussion", - "To kick users": "Pour expulser des utilisateurs", + "To kick users": "Pour exclure des utilisateurs", "To link to a room it must have": "Pour avoir un lien vers un salon, il doit avoir", "to make a room or": "pour créer un salon ou", "To remove other users' messages": "Pour supprimer les messages des autres utilisateurs", - "To reset your password, enter the email address linked to your account": "Pour réinitialiser votre mot de passe, merci d’entrer l’adresse e-mail liée à votre compte", + "To reset your password, enter the email address linked to your account": "Pour réinitialiser votre mot de passe, veuillez saisir l’adresse e-mail liée à votre compte", "to restore": "pour restaurer", - "To send events of type": "Pour envoyer des évènements du type", + "To send events of type": "Pour envoyer des événements du type", "To send messages": "Pour envoyer des messages", - "to start a chat with someone": "pour démarrer une discussion avec quelqu’un", - "to tag as %(tagName)s": "pour marquer comme %(tagName)s", - "to tag direct chat": "pour marquer comme conversation directe", - "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é.", - "Turn Markdown off": "Désactiver le formatage ’Markdown’", - "Turn Markdown on": "Activer le formatage ’Markdown’", - "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s a activé le chiffrement de bout-en-bout (algorithme %(algorithm)s).", + "to start a chat with someone": "pour commencer une discussion avec quelqu’un", + "to tag as %(tagName)s": "pour étiqueter comme %(tagName)s", + "to tag direct chat": "pour étiqueter comme discussion directe", + "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 faites-les défiler 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.": "L'instant donné de la chronologie n’a pu être chargé car vous n’avez pas la permission de visualiser le message concerné.", + "Tried to load a specific point in this room's timeline, but was unable to find it.": "L'instant donné de la chronologie n’a pu être chargé car il n’a pas pu être trouvé.", + "Turn Markdown off": "Désactiver le formatage Markdown", + "Turn Markdown on": "Activer le formatage Markdown", + "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s a activé le chiffrement de bout en bout (algorithme %(algorithm)s).", "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 restore previous session": "Impossible de rétablir la session précédente", "Unable to verify email address.": "Impossible de vérifier l’adresse e-mail.", - "Unban": "Amnistier (annuler le bannissement)", - "%(senderName)s unbanned %(targetName)s.": "%(senderName)s a amnistié %(targetName)s.", + "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 capturer l'écran", "Unable to enable Notifications": "Impossible d'activer les notifications", - "Unable to load device list": "Impossible de charger la liste d'appareils", + "Unable to load device list": "Impossible de charger la liste des appareils", "Unencrypted room": "Salon non chiffré", "unencrypted": "non chiffré", "unknown device": "appareil inconnu", "Unknown room %(roomId)s": "Salon inconnu %(roomId)s", "unknown": "inconnu", - "Unmute": "Activer le son", - "uploaded a file": "téléchargé un fichier", - "Upload avatar": "Télécharger une photo de profil", - "Upload Failed": "Erreur lors du téléchargement", - "Upload Files": "Télécharger les fichiers", - "Upload file": "Télécharger un fichier", + "Unmute": "Désactiver la sourdine", + "uploaded a file": "a envoyé un fichier", + "Upload avatar": "Envoyer un avatar", + "Upload Failed": "Échec de l'envoi", + "Upload Files": "Envoyer les fichiers", + "Upload file": "Envoyer un fichier", "Usage": "Utilisation", "Use with caution": "Utiliser avec prudence", "User ID": "Identifiant d'utilisateur", @@ -416,15 +416,15 @@ "User name": "Nom d'utilisateur", "Users": "Utilisateurs", "User": "Utilisateur", - "Verification Pending": "Vérification en cours", + "Verification Pending": "Vérification en attente", "Verification": "Vérification", "verified": "vérifié", "Video call": "Appel vidéo", "Voice call": "Appel vocal", - "VoIP conference finished.": "Conférence audio terminée.", - "VoIP conference started.": "Conférence audio démarrée.", - "VoIP is unsupported": "Appels voix non supportés", - "(warning: cannot be disabled again!)": "(attention : ne peut être désactivé !)", + "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 supportée", + "(warning: cannot be disabled again!)": "(attention : ne peut pas être désactivé !)", "Warning!": "Attention !", "Who can access this room?": "Qui peut accéder au salon ?", "Who can read history?": "Qui peut lire l'historique ?", @@ -432,27 +432,27 @@ "Who would you like to communicate with?": "Avec qui voulez-vous communiquer ?", "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s a révoqué l’invitation de %(targetName)s.", "Would you like to": "Voulez-vous", - "You are already in a call.": "Vous êtes déjà dans un appel.", + "You are already in a call.": "Vous avez déjà un appel en cours.", "You're not in any rooms yet! Press": "Vous n’êtes dans aucun salon ! Cliquez", "You are trying to access %(roomName)s.": "Vous essayez d'accéder à %(roomName)s.", "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 vocal dans ce navigateur.", + "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 been invited to join this room by %(inviterName)s": "Vous avez été invité à joindre ce salon par %(inviterName)s", - "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Vous avez été déconnecté de tous vos appareils et ne recevrez plus de notifications. Pour réactiver les notifications, identifiez vous à nouveau sur tous les appareils", - "You have no visible notifications": "Vous n'avez pas de notifications visibles", - "you must be a": "vous devez être un", + "You have been invited to join this room by %(inviterName)s": "Vous avez été invité(e) à rejoindre ce salon par %(inviterName)s", + "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Vous avez été déconnecté de tous vos appareils et ne recevrez plus de notifications. Pour réactiver les notifications, reconnectez-vous sur tous les appareils", + "You have no visible notifications": "Vous n'avez pas de notification visible", + "you must be a": "vous devez être un(e)", "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 logged in.": "Vous devez être identifié.", "You need to enter a user name.": "Vous devez entrer un nom d’utilisateur.", "You need to log back in to generate end-to-end encryption keys for this device and submit the public key to your homeserver. This is a once off; sorry for the inconvenience.": "Vous devez vous connecter à nouveau pour générer les clés de chiffrement pour cet appareil, et soumettre la clé publique à votre homeserver. Cette action ne se reproduira pas ; veuillez nous excuser pour la gêne occasionnée.", - "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Votre adresse e-mail ne semble pas associée à un identifiant Matrix sur ce homeserver.", + "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 password has been reset": "Votre mot de passe a été réinitialisé", - "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Votre mot de passe a été mis à jour avec succès. Vous ne recevrez plus de notification sur vos appareils jusqu’à ce que vous vous identifiez à nouveau", - "You seem to be in a call, are you sure you want to quit?": "Vous semblez avoir un appel en cours, êtes-vous sûr(e) de vouloir quitter ?", - "You seem to be uploading files, are you sure you want to quit?": "Vous semblez être en train de télécharger des fichiers, êtes-vous sûr(e) de vouloir quitter ?", + "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Votre mot de passe a été mis à jour avec succès. Vous ne recevrez plus de notification sur vos autres appareils jusqu’à ce que vous vous identifiez à nouveau", + "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 should not yet trust it to secure data": "Vous ne pouvez pas encore lui faire confiance pour sécuriser vos données", - "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 ce changement car vous promouvez l’utilisateur au même niveau d'autorité que le vôtre.", + "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", "Tue": "Mar", @@ -461,29 +461,29 @@ "Fri": "Ven", "Sat": "Sam", "Jan": "Jan", - "Feb": "Fev", + "Feb": "Fév", "Mar": "Mar", "Apr": "Avr", "May": "Mai", - "Jun": "Jun", - "Jul": "Jul", - "Aug": "Aou", + "Jun": "Juin", + "Jul": "Juil", + "Aug": "Aoû", "Sep": "Sep", "Oct": "Oct", "Nov": "Nov", - "Dec": "Dec", + "Dec": "Déc", "%(weekDayName)s, %(monthName)s %(day)s %(time)s": "%(weekDayName)s %(day)s %(monthName)s %(time)s", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s": "%(weekDayName)s %(day)s %(monthName)s %(fullYear)s %(time)s", "%(weekDayName)s %(time)s": "%(weekDayName)s %(time)s", - "Set a display name:": "Définir un nom d’affichage :", - "Upload an avatar:": "Télécharger une photo de profil :", - "This server does not support authentication with a phone number.": "Ce serveur ne supporte pas l’identification avec un numéro de téléphone.", + "Set a display name:": "Définir le nom affiché :", + "Upload an avatar:": "Envoyer un avatar :", + "This server does not support authentication with a phone number.": "Ce serveur ne prend pas en charge l’authentification avec un numéro de téléphone.", "Missing password.": "Mot de passe manquant.", "Passwords don't match.": "Les mots de passe ne correspondent pas.", "Password too short (min %(MIN_PASSWORD_LENGTH)s).": "Mot de passe trop court (min %(MIN_PASSWORD_LENGTH)s).", - "This doesn't look like a valid email address.": "Cela ne semble pas être une adresse e-mail valide.", - "This doesn't look like a valid phone number.": "Cela ne semble pas être un numéro de téléphone valide.", - "User names may only contain letters, numbers, dots, hyphens and underscores.": "Les noms d’utilisateurs ne peuvent contenir que des lettres, chiffres, points et tirets hauts ou bas.", + "This doesn't look like a valid email address.": "Cette adresse e-mail ne semble pas valide.", + "This doesn't look like a valid phone number.": "Ce numéro de téléphone ne semble pas valide.", + "User names may only contain letters, numbers, dots, hyphens and underscores.": "Les noms d’utilisateurs ne peuvent contenir que des lettres, des chiffres, des points, des traits d'union et des tirets bas.", "An unknown error occurred.": "Une erreur inconnue est survenue.", "I already have an account": "J’ai déjà un compte", "An error occurred: %(error_string)s": "Une erreur est survenue : %(error_string)s", @@ -494,8 +494,8 @@ "Encrypt room": "Chiffrer le salon", "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.", - "Sent messages will be stored until your connection has returned.": "Les messages envoyés seront stockés jusqu’à ce que votre connection revienne.", + "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.", "Auto-complete": "Auto-complétion", "Resend all": "Tout renvoyer", "(~%(searchCount)s results)": "(~%(searchCount)s résultats)", @@ -505,7 +505,7 @@ "Active call": "Appel en cours", "code": "code", "quote": "citer", - "bullet": "puce", + "bullet": "liste à puces", "numbullet": "liste numérotée", "%(severalUsers)sjoined %(repeats)s times": "%(severalUsers)sont rejoint le salon %(repeats)s fois", "%(oneUser)sjoined %(repeats)s times": "%(oneUser)sa rejoint le salon %(repeats)s fois", @@ -514,161 +514,161 @@ "%(severalUsers)sleft %(repeats)s times": "%(severalUsers)sont quitté le salon %(repeats)s fois", "%(oneUser)sleft %(repeats)s times": "%(oneUser)sa quitté le salon %(repeats)s fois", "%(severalUsers)sleft": "%(severalUsers)sont quitté le salon", - "%(oneUser)sleft": "%(oneUser)sont quitté le salon", + "%(oneUser)sleft": "%(oneUser)sa quitté le salon", "%(severalUsers)sjoined and left %(repeats)s times": "%(severalUsers)sont rejoint et quitté le salon %(repeats)s fois", "%(oneUser)sjoined and left %(repeats)s times": "%(oneUser)sa rejoint et quitté le salon%(repeats)s fois", "%(severalUsers)sjoined and left": "%(severalUsers)sont rejoint et quitté le salon", "%(oneUser)sjoined and left": "%(oneUser)sa rejoint et quitté le salon", - "%(severalUsers)sleft and rejoined %(repeats)s times": "%(severalUsers)sont quitté et à nouveau joint le salon %(repeats)s fois", - "%(oneUser)sleft and rejoined %(repeats)s times": "%(oneUser)sa quitté et à nouveau joint le salon %(repeats)s fois", - "%(severalUsers)sleft and rejoined": "%(severalUsers)sont quitté et à nouveau joint le salon", - "%(oneUser)sleft and rejoined": "%(oneUser)sa quitté et à nouveau joint le salon", - "%(severalUsers)srejected their invitations %(repeats)s times": "%(severalUsers)sont rejeté leurs invitations %(repeats)s fois", + "%(severalUsers)sleft and rejoined %(repeats)s times": "%(severalUsers)sont quitté et sont revenus dans le salon %(repeats)s fois", + "%(oneUser)sleft and rejoined %(repeats)s times": "%(oneUser)sa quitté et est revenu dans le salon %(repeats)s fois", + "%(severalUsers)sleft and rejoined": "%(severalUsers)sont quitté et sont revenus dans le salon", + "%(oneUser)sleft and rejoined": "%(oneUser)sa quitté et est revenu dans le salon", + "%(severalUsers)srejected their invitations %(repeats)s times": "%(severalUsers)sont rejeté leur invitation %(repeats)s fois", "%(oneUser)srejected their invitation %(repeats)s times": "%(oneUser)sa rejeté son invitation %(repeats)s fois", "%(severalUsers)srejected their invitations": "%(severalUsers)sont rejeté leur invitation", "%(oneUser)srejected their invitation": "%(oneUser)sa rejeté son invitation", - "%(severalUsers)shad their invitations withdrawn %(repeats)s times": "%(severalUsers)sont vu leur invitation rétractée %(repeats)s fois", - "%(oneUser)shad their invitation withdrawn %(repeats)s times": "%(oneUser)sa vu son invitation rétractée %(repeats)s fois", - "%(severalUsers)shad their invitations withdrawn": "%(severalUsers)sont vu leur invitation rétractée", - "%(oneUser)shad their invitation withdrawn": "%(oneUser)sa vu son invitation rétractée", + "%(severalUsers)shad their invitations withdrawn %(repeats)s times": "%(severalUsers)sont vu leur invitation révoquée %(repeats)s fois", + "%(oneUser)shad their invitation withdrawn %(repeats)s times": "%(oneUser)sa vu son invitation révoquée %(repeats)s fois", + "%(severalUsers)shad their invitations withdrawn": "%(severalUsers)sont vu leur invitation révoquée", + "%(oneUser)shad their invitation withdrawn": "%(oneUser)sa vu son invitation révoquée", "were invited %(repeats)s times": "ont été invité(e)s %(repeats)s fois", "was invited %(repeats)s times": "a été invité(e) %(repeats)s fois", "were invited": "ont été invité(e)s", "were banned %(repeats)s times": "ont été banni(e)s %(repeats)s fois", - "was banned %(repeats)s times": "été banni(e) %(repeats)s fois", + "was banned %(repeats)s times": "a été banni(e) %(repeats)s fois", "were banned": "ont été banni(e)s", - "were unbanned %(repeats)s times": "ont été amnistié(e)s %(repeats)s fois", - "was unbanned %(repeats)s times": "a été amnistié(e) %(repeats)s fois", - "were unbanned": "ont été amnistié(e)s", - "were kicked %(repeats)s times": "ont été expulsé(e)s %(repeats)s fois", - "was kicked %(repeats)s times": "a été expulsé(e) %(repeats)s fois", - "were kicked": "ont été expulsé(e)s", + "were unbanned %(repeats)s times": "ont vu leur bannissement révoqué %(repeats)s fois", + "was unbanned %(repeats)s times": "a vu son bannissement révoqué %(repeats)s fois", + "were unbanned": "ont vu leur bannissement révoqué", + "were kicked %(repeats)s times": "ont été exclu(e)s %(repeats)s fois", + "was kicked %(repeats)s times": "a été exclu(e) %(repeats)s fois", + "were kicked": "ont été exclu(e)s", "%(severalUsers)schanged their name %(repeats)s times": "%(severalUsers)sont changé leur nom %(repeats)s fois", "%(oneUser)schanged their name %(repeats)s times": "%(oneUser)sa changé son nom %(repeats)s fois", "%(severalUsers)schanged their name": "%(severalUsers)sont changé leur nom", "%(oneUser)schanged their name": "%(oneUser)sa changé son nom", - "%(severalUsers)schanged their avatar %(repeats)s times": "%(severalUsers)sont changé leur photo de profil %(repeats)s fois", - "%(oneUser)schanged their avatar %(repeats)s times": "%(oneUser)sa changé sa photo de profil %(repeats)s fois", - "%(severalUsers)schanged their avatar": "%(severalUsers)sont changé leur photo de profil", - "%(oneUser)schanged their avatar": "%(oneUser)sa changé sa photo de profil", - "Please select the destination room for this message": "Merci de sélectionner un salon de destination pour ce message", + "%(severalUsers)schanged their avatar %(repeats)s times": "%(severalUsers)sont changé leur avatar %(repeats)s fois", + "%(oneUser)schanged their avatar %(repeats)s times": "%(oneUser)sa changé son avatar %(repeats)s fois", + "%(severalUsers)schanged their avatar": "%(severalUsers)sont changé leur avatar", + "%(oneUser)schanged their avatar": "%(oneUser)sa changé son avatar", + "Please select the destination room for this message": "Merci de sélectionner le salon de destination pour ce message", "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s a supprimé le nom du salon.", - "Analytics": "Outils d'analyse", - "Opt out of analytics": "Refuser de participer", - "Riot collects anonymous analytics to allow us to improve the application.": "Riot recueille des données anonymes qui nous permettent d’analyser et améliorer l’application.", - "Passphrases must match": "Les phrases secrètes doivent être identiques", - "Passphrase must not be empty": "La phrase secrète ne doit pas être vide", - "Export room keys": "Exporter les clés du salon", - "Enter passphrase": "Entrer la phrase secrète", - "Confirm passphrase": "Confirmer la phrase secrète", - "Import room keys": "Importer les clés du salon", + "Analytics": "Collecte de données", + "Opt out of analytics": "Ne pas envoyer ses données", + "Riot collects anonymous analytics to allow us to improve the application.": "Riot collecte des données anonymes qui nous permettent d’améliorer l’application.", + "Passphrases must match": "Les phrases de passe doivent être identiques", + "Passphrase must not be empty": "La phrase de passe ne peut pas être vide", + "Export room keys": "Exporter les clés de salon", + "Enter passphrase": "Saisir la phrase de passe", + "Confirm passphrase": "Confirmer la phrase de passe", + "Import room keys": "Importer les clés de salon", "File to import": "Fichier à importer", "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.": "Ce processus vous permet d’exporter dans un fichier local les clés pour les messages que vous avez reçus dans des salons chiffrés. Il sera ensuite possible d’importer ce fichier dans un autre client Matrix, afin de permettre à ce client de pouvoir déchiffrer ces messages.", - "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.": "Le fichier exporté permettra à tout ceux qui peuvent le lire de déchiffrer tous les messages chiffrés auxquels vous avez accès, vous devez donc être vigilant et le stocker dans un endroit sûr. Afin de protéger ce fichier, entrez ci-dessous une phrase secrète qui sera utilisée pour chiffrer les données exportées. Seule l’utilisation de la même phrase secrète permettra de déchiffrer et importer les données.", - "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.": "Ce processus vous permet d’importer les clés de chiffrement que vous avez précédemment exportées depuis un autre client Matrix. Vous serez alors capable de déchiffrer n’importe quel messages que l’autre client peut déchiffer.", - "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Le fichier exporté est protégé par une phrase secrète. Vous devez entrer cette phrase secrète ici pour déchiffrer le fichier.", - "You must join the room to see its files": "Vous devez joindre le salon pour voir ses fichiers", + "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.": "Le fichier exporté permettra à tout ceux qui peuvent le lire de déchiffrer tous les messages chiffrés auxquels vous avez accès, vous devez donc être vigilant et le stocker dans un endroit sûr. Afin de protéger ce fichier, saisissez ci-dessous une phrase secrète qui sera utilisée pour chiffrer les données exportées. Seule l’utilisation de la même phrase secrète permettra de déchiffrer et importer les données.", + "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.": "Ce processus vous permet d’importer les clés de chiffrement que vous avez précédemment exportées depuis un autre client Matrix. Vous serez alors capable de déchiffrer n’importe quel message que l’autre client pouvait déchiffrer.", + "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Le fichier exporté est protégé par une phrase de passe. Vous devez saisir cette phrase de passe ici pour déchiffrer le fichier.", + "You must join the room to see its files": "Vous devez rejoindre le salon pour voir ses fichiers", "Reject all %(invitedRooms)s invites": "Rejeter la totalité des %(invitedRooms)s invitations", - "Start new chat": "Démarrer une nouvelle discussion", - "Guest users can't invite users. Please register.": "Les visiteurs ne peuvent inviter d’autres utilisateurs. Merci de vous inscrire.", - "Failed to invite": "Echec de l'invitation", - "Failed to invite user": "Echec lors de l'invitation de l'utilisateur", - "Failed to invite the following users to the %(roomName)s room:": "Echec lors de l’invitation des utilisateurs suivants dans le salon %(roomName)s :", + "Start new chat": "Commencer une nouvelle discussion", + "Guest users can't invite users. Please register.": "Les visiteurs ne peuvent inviter d’autres utilisateurs. Veuillez vous inscrire.", + "Failed to invite": "Échec de l'invitation", + "Failed to invite user": "Échec de l'invitation de l'utilisateur", + "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.": "Êtes vous sûr de vouloir supprimer cet événement ? Notez que si vous supprimez le changement de nom d’un salon ou la mise à jour du sujet d’un salon, il est possible que le 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", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Ceci rendra votre compte inutilisable de manière permanente. Vous ne pourrez pas enregistrer à nouveau le même identifiant utilisateur.", + "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Ceci rendra votre compte inutilisable de manière permanente. Vous ne pourrez pas vous réinscrire avec le même identifiant utilisateur.", "This action is irreversible.": "Cette action est irréversible.", - "To continue, please enter your password.": "Pour continuer, merci d'entrer votre mot de passe.", + "To continue, please enter your password.": "Pour continuer, veuillez saisir votre mot de passe.", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Pour vérifier que vous pouvez faire confiance à cet appareil, merci de contacter son propriétaire par un autre moyen (par ex. en personne ou par téléphone) et demandez lui si la clé qu’il/elle voit dans ses Paramètres Utilisateur pour cet appareil correspond à la clé ci-dessous :", "Device name": "Nom de l'appareil", "Device key": "Clé de l'appareil", - "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Si les clés correspondent, cliquer sur le bouton ’Vérifier’ ci-dessous. Si non, alors quelqu’un d’autre est en train d’intercepter cet appareil et vous devriez certainement cliquer sur le bouton ’Blacklister' (Ajouter à la liste noire) à la place.", - "In future this verification process will be more sophisticated.": "À l’avenir ce processus de vérification sera simplifié et plus sophistiqué.", + "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Si les clés correspondent, cliquer sur le bouton \"Vérifier\" ci-dessous. Sinon quelqu’un d’autre est en train d’intercepter cet appareil et vous devriez certainement cliquer sur le bouton \"Ajouter à la liste noire\" à la place.", + "In future this verification process will be more sophisticated.": "À l’avenir ce processus de vérification sera plus sophistiqué.", "Verify device": "Vérifier cet appareil", "I verify that the keys match": "J’ai vérifié que les clés correspondaient", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Nous avons rencontré une erreur en essayant de rétablir votre session précédente. Si vous continuez, vous devrez vous identifier à nouveau et l’historique chiffré de vos conversations sera illisible.", + "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Nous avons rencontré une erreur en essayant de rétablir votre session précédente. Si vous continuez, vous devrez vous identifier à nouveau et l’historique de vos discussions chiffrées sera illisible.", "Unable to restore session": "Impossible de restaurer la session", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Si vous avez utilisé une version plus récente de Riot précédemment, votre session risque d’être incompatible avec cette version. Fermez cette fenêtre et retournez à la version plus récente.", "Continue anyway": "Continuer quand même", - "Your display name is how you'll appear to others when you speak in rooms. What would you like it to be?": "Votre nom d’affichage est la manière dont vous allez apparaître pour les autres quand vous parlerez dans les salons. Que voulez-vous qu’il soit ?", - "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Vous êtes en train d’ajouter à la liste noire des appareils non-vérifiés ; pour envoyer des messages à ces appareils vous devez les vérifier.", - "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Nous vous recommandons d’effectuer le processus de vérification pour tous les appareils afin de confirmer qu’ils appartiennent à leurs propriétaires légitimes, mais vous pouvez renvoyer le(s) message(s) sans vérifier si vous préférez.", + "Your display name is how you'll appear to others when you speak in rooms. What would you like it to be?": "Votre nom affiché est ce qui apparaîtra pour les autres quand vous parlerez dans les salons. Que voulez-vous qu’il soit ?", + "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Vous êtes en train d’ajouter à la liste noire des appareils non vérifiés ; pour envoyer des messages à ces appareils vous devez les vérifier.", + "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Nous vous recommandons d’effectuer le processus de vérification pour tous les appareils afin de confirmer qu’ils appartiennent à leurs propriétaires légitimes, mais vous pouvez renvoyer le message sans vérifier si vous préférez.", "\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" contient des appareils que vous n'avez encore jamais vus.", "Unknown devices": "Appareils inconnus", "Unknown Address": "Adresse inconnue", - "Unblacklist": "Réhabiliter", - "Blacklist": "Blacklister", - "Unverify": "Révoquer", + "Unblacklist": "Supprimer de la liste noire", + "Blacklist": "Ajouter à la liste noire", + "Unverify": "Révoquer la vérification", "Verify...": "Vérifier...", "ex. @bob:example.com": "ex. @bob:exemple.com", "Add User": "Ajouter l'utilisateur", - "This Home Server would like to make sure you are not a robot": "Ce homeserver veut vérifier que vous n’êtes pas un robot", + "This Home Server would like to make sure you are not a robot": "Ce serveur d'accueil veut vérifier que vous n’êtes pas un robot", "Sign in with CAS": "S'identifier avec CAS", "Custom Server Options": "Options de serveur personnalisées", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "Vous pouvez utiliser les options de serveur personnalisées pour vous identifier auprès d’un autre serveur Matrix en spécifiant l’URL d’un homeserver différent.", - "This allows you to use this app with an existing Matrix account on a different home server.": "Cela vous permet d’utiliser l’application avec un compte Matrix existant sur un homeserver différent.", - "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "Vous pouvez également configurer un serveur d’identité différent mais cela risque entre autres d’empêcher les interactions par e-mail avec les autres utilisateurs.", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "Vous pouvez utiliser les options de serveur personnalisées pour vous identifier auprès d’un autre serveur Matrix en spécifiant l’URL d’un serveur d'accueil différent.", + "This allows you to use this app with an existing Matrix account on a different home server.": "Cela vous permet d’utiliser l’application avec un compte Matrix existant sur un serveur d'accueil différent.", + "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "Vous pouvez également configurer un serveur d’identité différent mais cela risque entre autres d’empêcher les interactions basées sur l'adresse e-mail avec les autres utilisateurs.", "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", - "A text message has been sent to": "Un message texte a été envoyé au", - "Please enter the code it contains:": "Merci d'entre le code qu'il contient :", + "A text message has been sent to": "Un SMS a été envoyé au", + "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 n’entrez pas d’adresse e-mail, vous ne pourrez pas réinitialiser votre mot de passe. Êtes vous sûr ?", - "You are registering with %(SelectedTeamName)s": "Vous vous enregistrez auprès de %(SelectedTeamName)s", + "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) ?", + "You are registering with %(SelectedTeamName)s": "Vous vous inscrivez auprès de %(SelectedTeamName)s", "Default server": "Serveur par défaut", "Custom server": "Serveur personnalisé", - "Home server URL": "URL du homeserver", + "Home server URL": "URL du serveur d'accueil", "Identity server URL": "URL du serveur d’identité", "What does this mean?": "Qu’est ce que cela signifie ?", "Error decrypting audio": "Erreur lors du déchiffrement de l’audio", "Error decrypting image": "Erreur lors du déchiffrement de l’image", - "Image '%(Body)s' cannot be displayed.": "L'image '%(Body)s' ne peut être affichée.", - "This image cannot be displayed.": "Cette image ne peut être affichée.", + "Image '%(Body)s' cannot be displayed.": "L'image \"%(Body)s\" ne peut pas être affichée.", + "This image cannot be displayed.": "Cette image ne peut pas être affichée.", "Error decrypting video": "Erreur lors du déchiffrement de la vidéo", "Add an Integration": "Ajouter une intégration", - "URL Previews": "Aperçus d'URL", - "Disable URL previews by default for participants in this room": "Désactiver les aperçus d'URL par défaut pour les participants de ce salon", - "URL previews are %(globalDisableUrlPreview)s by default for participants in this room.": "Les aperçus d'URL sont %(globalDisableUrlPreview)s par défaut pour les participants de ce salon.", - "Enable URL previews for this room (affects only you)": "Activer les aperçus d'URL pour ce salon (n'affecte que vous)", - "Drop file here to upload": "Déposer le fichier ici pour le télécharger", - " (unsupported)": " (non supporté)", - "Ongoing conference call%(supportedText)s.": "Appel conférence en cours%(supportedText)s.", + "URL Previews": "Aperçus des liens", + "Disable URL previews by default for participants in this room": "Désactiver les aperçus des liens par défaut pour les participants de ce salon", + "URL previews are %(globalDisableUrlPreview)s by default for participants in this room.": "Les aperçus des liens sont %(globalDisableUrlPreview)s par défaut pour les participants de ce salon.", + "Enable URL previews for this room (affects only you)": "Activer les aperçus des liens pour ce salon (n'affecte que vous)", + "Drop file here to upload": "Déposer 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", - "Offline": "Déconnecté", - "Disable URL previews for this room (affects only you)": "Désactiver les aperçus d'URL pour ce salon (n'affecte que vous)", + "Offline": "Hors ligne", + "Disable URL previews for this room (affects only you)": "Désactiver les aperçus des liens pour ce salon (n'affecte que vous)", "Desktop specific": "Spécifique à l'application de bureau", "Start automatically after system login": "Démarrer automatiquement après la phase d'authentification du système", "Idle": "Inactif", - "Jump to first unread message.": "Aller au premier message non-lu.", + "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 ?", "Removed or unknown message type": "Type de message inconnu ou supprimé", "disabled": "désactivé", "enabled": "activé", - "Set a Display Name": "Définir un nom d’affichage", + "Set a Display Name": "Définir le nom affiché", "for %(amount)ss": "depuis %(amount)ss", "for %(amount)sm": "depuis %(amount)sm", "for %(amount)sh": "depuis %(amount)sh", "for %(amount)sd": "depuis %(amount)sj", - "$senderDisplayName changed the room avatar to ": "$senderDisplayName a changé l’image de profil du salon en ", - "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s a supprimé l’image de profil du salon.", - "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s a changé l’image de profil de %(roomName)s", + "$senderDisplayName changed the room avatar to ": "$senderDisplayName 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", "Device already verified!": "Appareil déjà vérifié !", "Export": "Exporter", "Failed to register as guest:": "Échec de l’inscription en tant que visiteur :", - "Guest access is disabled on this Home Server.": "L’accès en tant que visiteur est désactivé sur ce homeserver.", + "Guest access is disabled on this Home Server.": "L’accès en tant que visiteur est désactivé sur ce serveur d'accueil.", "Import": "Importer", "Incorrect username and/or password.": "Nom d’utilisateur et/ou mot de passe incorrect.", "Results from DuckDuckGo": "Résultats de DuckDuckGo", - "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Les clés de signature que vous avez transmises correspondent aux clés que vous avez reçues de l’appareil %(deviceId)s de %(userId)s. L’appareil est vérifié.", - "This Home Server does not support login using email address.": "Ce serveur ne supporte pas l’identification par e-mail.", - "There was a problem logging in.": "Un problème a été rencontré lors de l’identification.", + "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "La clé de signature que vous avez transmise correspond à la clé que vous avez reçue de l’appareil %(deviceId)s de %(userId)s. L’appareil est marqué comme vérifié.", + "This Home Server does not support login using email address.": "Ce serveur d'accueil ne supporte pas l’authentification par e-mail.", + "There was a problem logging in.": "Un problème est survenu lors de l’authentification.", "Unknown (user, device) pair:": "Couple (utilisateur, appareil) inconnu :", - "Unrecognised command:": "Commande non-reconnue :", - "Unrecognised room alias:": "Alias de salon non-reconnu :", + "Unrecognised command:": "Commande non reconnue :", + "Unrecognised room alias:": "Alias de salon non reconnu :", "Use compact timeline layout": "Utiliser l'affichage compact", "Verified key": "Clé vérifiée", "WARNING: Device already verified, but keys do NOT MATCH!": "ATTENTION : appareil déjà vérifié mais les clés NE CORRESPONDENT PAS !", @@ -678,78 +678,78 @@ "No Microphones detected": "Aucun micro détecté", "No Webcams detected": "Aucune webcam détectée", "No media permissions": "Pas de permission pour les médias", - "You may need to manually permit Riot to access your microphone/webcam": "Il est possible que vous deviez manuellement permettre à Riot d’accéder à votre micro/webcam", + "You may need to manually permit Riot to access your microphone/webcam": "Il est possible que vous deviez manuellement autoriser Riot à accéder à votre micro/webcam", "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'?": "Êtes-vous sûr de vouloir quitter le salon '%(roomName)s' ?", - "Custom level": "Niveau personnalisé", + "Are you sure you want to leave the room '%(roomName)s'?": "Voulez-vous vraiment quitter le salon \"%(roomName)s\" ?", + "Custom level": "Rang personnalisé", "Device ID:": "Identifiant de l'appareil :", - "device id: ": "identifiant appareil : ", + "device id: ": "identifiant de l'appareil : ", "Device key:": "Clé de l’appareil :", "Email address (optional)": "Adresse e-mail (facultatif)", "Mobile phone number (optional)": "Numéro de téléphone (facultatif)", "Password:": "Mot de passe :", "Register": "S'inscrire", - "Remote addresses for this room:": "Supprimer l'adresse pour ce salon :", + "Remote addresses for this room:": "Adresses distantes pour ce salon :", "Save": "Enregistrer", - "Tagged as: ": "Étiquetter comme : ", - "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.", - "You have entered an invalid contact. Try using their Matrix ID or email address.": "Vous avez entré un contact invalide. Essayez d’utiliser leur identifiant Matrix ou leur adresse email.", + "Tagged as: ": "Étiqueté comme : ", + "You have disabled URL previews by default.": "Vous avez désactivé les aperçus de lien par défaut.", + "You have enabled URL previews by default.": "Vous avez activé les aperçus de lien par défaut.", + "You have entered an invalid contact. Try using their Matrix ID or email address.": "Vous avez saisi un contact non valide. Essayez d’utiliser leur identifiant Matrix ou leur adresse e-mail.", "Hide removed messages": "Cacher les messages supprimés", "Add": "Ajouter", "%(count)s new messages|one": "%(count)s nouveau message", "%(count)s new messages|other": "%(count)s nouveaux messages", - "Disable markdown formatting": "Désactiver le formattage markdown", - "Error: Problem communicating with the given homeserver.": "Erreur : problème de communication avec le homeserver.", - "Failed to fetch avatar URL": "Échec lors de la récupération de l’URL de l’avatar", - "The phone number entered looks invalid": "Le numéro de téléphone entré semble être invalide", + "Disable markdown formatting": "Désactiver le formatage markdown", + "Error: Problem communicating with the given homeserver.": "Erreur : problème de communication avec le serveur d'accueil renseigné.", + "Failed to fetch avatar URL": "Échec de la récupération de l’URL de l’avatar", + "The phone number entered looks invalid": "Le numéro de téléphone entré ne semble pas être valide", "This room is private or inaccessible to guests. You may be able to join if you register.": "Ce salon est privé ou interdits aux visiteurs. Vous pourrez peut-être le joindre si vous vous enregistrez.", - "Uploading %(filename)s and %(count)s others|zero": "Téléchargement de %(filename)s", - "Uploading %(filename)s and %(count)s others|one": "Téléchargement de %(filename)s et %(count)s autre", - "Uploading %(filename)s and %(count)s others|other": "Téléchargement de %(filename)s et %(count)s autres", + "Uploading %(filename)s and %(count)s others|zero": "Envoi de %(filename)s", + "Uploading %(filename)s and %(count)s others|one": "Envoi de %(filename)s et %(count)s autre", + "Uploading %(filename)s and %(count)s others|other": "Envoi de %(filename)s et %(count)s autres", "You must register to use this functionality": "Vous devez vous inscrire pour utiliser cette fonctionnalité", - "Resend all or cancel all now. You can also select individual messages to resend or cancel.": "Tout renvoyer ou tout annuler maintenant. Vous pouvez aussi sélectionner des messages individuels à envoyer ou annuler.", + "Resend all or cancel all now. You can also select individual messages to resend or cancel.": "Tout renvoyer ou tout annuler maintenant. Vous pouvez aussi sélectionner des messages individuels à renvoyer ou annuler.", "Create new room": "Créer un nouveau salon", "Welcome page": "Page d'accueil", "Room directory": "Répertoire des salons", - "Start chat": "Démarrer une discussion", + "Start chat": "Commencer une discussion", "New Password": "Nouveau mot de passe", - "Start chatting": "Démarrer une discussion", - "Start Chatting": "Démarrer une discussion", + "Start chatting": "Commencer une discussion", + "Start Chatting": "Commencer une discussion", "Click on the button below to start chatting!": "Cliquer sur le bouton ci-dessous pour commencer une discussion !", - "Create a new chat or reuse an existing one": "Démarrer une nouvelle discussion ou en réutiliser une existante", - "You already have existing direct chats with this user:": "Vous avez déjà des discussions en cours avec cet utilisateur :", + "Create a new chat or reuse an existing one": "Commencer une nouvelle discussion ou en réutiliser une existante", + "You already have existing direct chats with this user:": "Vous avez déjà des discussions directes avec cet utilisateur :", "Username available": "Nom d'utilisateur disponible", "Username not available": "Nom d'utilisateur indisponible", "Something went wrong!": "Quelque chose s’est mal passé !", - "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 , 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 identifier à la place.", + "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.", "a room": "un salon", "Accept": "Accepter", "Active call (%(roomName)s)": "Appel en cours (%(roomName)s)", "Admin tools": "Outils d'administration", "Alias (optional)": "Alias (facultatif)", - "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.": "Impossible de se connecter au homeserver - veuillez vérifier votre connexion, assurez vous que vous faites confiance au certificat SSL de votre homeserver, et qu'aucune extension de navigateur ne bloque les requêtes.", - "Click here to join the discussion!": "Cliquer ici pour joindre la discussion !", + "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.": "Impossible de se connecter au serveur d'accueil - veuillez vérifier votre connexion, assurez-vous que le certificat SSL de votre serveur d'accueil est un certificat de confiance, et qu'aucune extension du navigateur ne bloque les requêtes.", + "Click here to join the discussion!": "Cliquer ici pour rejoindre la discussion !", "Close": "Fermer", "Custom": "Personnaliser", "Decline": "Refuser", "Disable Notifications": "Désactiver les notifications", "Drop File Here": "Déposer le fichier Ici", "Enable Notifications": "Activer les notifications", - "Failed to upload profile picture!": "Échec du téléchargement de la photo de profil !", + "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 d'affichage", + "No display name": "Pas de nom affiché", "Otherwise, click here to send a bug report.": "Sinon, cliquer ici pour envoyer un rapport d'erreur.", - "Private Chat": "Conversation privée", - "Public Chat": "Conversation publique", - "Reason: %(reasonText)s": "Raison: %(reasonText)s", + "Private Chat": "Discussion privée", + "Public Chat": "Discussion publique", + "Reason: %(reasonText)s": "Raison : %(reasonText)s", "Rejoin": "Rejoindre", "Room contains unknown devices": "Le salon contient des appareils inconnus", "%(roomName)s does not exist.": "%(roomName)s n'existe pas.", @@ -757,23 +757,23 @@ "Seen by %(userName)s at %(dateTime)s": "Vu par %(userName)s à %(dateTime)s", "Send anyway": "Envoyer quand même", "Show Text Formatting Toolbar": "Afficher la barre de formatage de texte", - "Start authentication": "Démarrer une authentification", + "Start authentication": "Commencer une authentification", "This invitation was sent to an email address which is not associated with this account:": "Cette invitation a été envoyée à une adresse e-mail qui n'est pas associée avec ce compte :", "This room": "Ce salon", "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Impossible de vérifier que l'adresse à qui cette invitation a été envoyée correspond à celle associée à votre compte.", "Undecryptable": "Indéchiffrable", "Unencrypted message": "Message non chiffré", "unknown caller": "appelant inconnu", - "Unnamed Room": "Salon sans nom", - "Unverified": "Non verifié", + "Unnamed Room": "Salon anonyme", + "Unverified": "Non vérifié", "%(user)s is a": "%(user)s est un(e)", - "Username invalid: %(errMessage)s": "Nom d'utilisateur invalide : %(errMessage)s", - "Verified": "Verifié", + "Username invalid: %(errMessage)s": "Nom d'utilisateur non valide : %(errMessage)s", + "Verified": "Vérifié", "Would you like to accept or decline this invitation?": "Souhaitez-vous accepter ou refuser cette invitation ?", - "You have been banned from %(roomName)s by %(userName)s.": "Vous avez été bannis de %(roomName)s par %(userName)s.", - "You have been kicked from %(roomName)s by %(userName)s.": "Vous avez été expulsé de %(roomName)s by %(userName)s.", + "You have been banned from %(roomName)s by %(userName)s.": "Vous avez été banni(e) de %(roomName)s par %(userName)s.", + "You have been kicked from %(roomName)s by %(userName)s.": "Vous avez été exclu de %(roomName)s par %(userName)s.", "You may wish to login with a different account, or add this email to this account.": "Vous souhaiteriez peut-être vous identifier avec un autre compte, ou ajouter cette e-mail à votre compte.", - "Your home server does not support device management.": "Votre homeserver ne supporte pas la gestion d'appareils.", + "Your home server does not support device management.": "Votre serveur d'accueil ne prend pas en charge la gestion d'appareils.", "(~%(count)s results)|one": "(~%(count)s résultat)", "(~%(count)s results)|other": "(~%(count)s résultats)", "Device Name": "Nom de l'appareil", @@ -783,57 +783,57 @@ "Encryption is not enabled in this room": "Le chiffrement n'est pas activé sur ce salon", "Home": "Accueil", "To link to a room it must have an address.": "Pour récupérer le lien vers un salon celui-ci doit avoir une adresse.", - "Upload new:": "Télécharger un nouveau :", + "Upload new:": "Envoyer un nouveau :", "And %(count)s more...": "Et %(count)s autres...", - "Join as voice or video.": "Joindre avec audio ou vidéo.", + "Join as voice or video.": "Rejoindre en audio ou en vidéo.", "Last seen": "Vu pour la dernière fois", - "Level:": "Niveau :", + "Level:": "Rang :", "Searching known users": "Recherche d'utilisateurs connus", "Set": "Défini", - "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (pouvoir %(powerLevelNumber)s)", + "%(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", "Not a valid Riot keyfile": "Fichier de clé Riot non valide", - "Authentication check failed: incorrect password?": "Erreur d’identification: mot de passe incorrect ?", - "Disable Peer-to-Peer for 1:1 calls": "Désactiver les appels 1:1 pair-à-pair", + "Authentication check failed: incorrect password?": "Erreur d’authentification : mot de passe incorrect ?", + "Disable Peer-to-Peer for 1:1 calls": "Désactiver les appels 1 à 1 pair-à-pair", "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 va vous permettre de réinitialiser votre mot de passe et de recevoir des notifications.", - "Press to start a chat with someone": "Cliquez sur pour entamer une discussion avec quelqu'un", - "You're not in any rooms yet! Press to make a room or to browse the directory": "Vous n'avez pas encore rejoint de salon ! Cliquez sur pour créer un salon ou sur pour explorer le répertoire", - "To return to your account in future you need to set a password": "Pour pouvoir accéder à votre compte dans le futur, vous devez enregistrer un mot de passe", + "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.", + "Press to start a chat with someone": "Appuyez sur pour commencer une discussion avec quelqu'un", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Vous n'avez pas encore rejoint de salon ! Appuyez sur pour créer un salon ou sur pour explorer le répertoire", + "To return to your account in future you need to set a password": "Pour pouvoir accéder à votre compte dans le futur, vous devez définir un mot de passe", "Skip": "Passer", "Start verification": "Commencer la vérification", "Share without verifying": "Partager sans vérifier", "Ignore request": "Ignorer la requête", - "You added a new device '%(displayName)s', which is requesting encryption keys.": "Vous avez ajouté un nouvel appareil, '%(displayName)s', qui demande des clés de chiffrement.", - "Your unverified device '%(displayName)s' is requesting encryption keys.": "Votre appareil non vérifié '%(displayName)s' demande des clés de chiffrement.", + "You added a new device '%(displayName)s', which is requesting encryption keys.": "Vous avez ajouté un nouvel appareil, \"%(displayName)s\", qui demande des clés de chiffrement.", + "Your unverified device '%(displayName)s' is requesting encryption keys.": "Votre appareil non vérifié \"%(displayName)s\" demande des clés de chiffrement.", "Encryption key request": "Requête de clé de chiffrement", "Updates": "Mises à jour", "Check for update": "Rechercher une mise à jour", "Add a widget": "Ajouter un widget", "Allow": "Autoriser", - "Changes colour scheme of current room": "Change le jeu de couleur du salon", + "Changes colour scheme of current room": "Change le jeu de couleurs du salon", "Delete widget": "Supprimer le widget", - "Define the power level of a user": "Définir le niveau de privilèges 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 langue pour la correction orthographique", + "Enable automatic language detection for syntax highlighting": "Activer la détection automatique de la langue pour la correction orthographique", "Hide Apps": "Masquer les applications", "Hide join/leave messages (invites/kicks/bans unaffected)": "Masquer les messages d'arrivée/départ (n'affecte pas les invitations/exclusions/bannissements)", - "Hide avatar and display name changes": "Masquer les changements d'avatar et de nom", - "Matrix Apps": "Matrix Apps", - "Revoke widget access": "Désactiver les accès du widget", - "Sets the room topic": "Configure le sujet du salon", + "Hide avatar and display name changes": "Masquer les changements d'avatar et de nom affiché", + "Matrix Apps": "Applications Matrix", + "Revoke widget access": "Révoquer les accès du widget", + "Sets the room topic": "Défini le sujet du salon", "Show Apps": "Afficher les applications", - "To get started, please pick a username!": "Pour débuter, choisissez un nom d'utilisateur !", + "To get started, please pick a username!": "Pour commencer, choisissez un nom d'utilisateur !", "Unable to create widget.": "Impossible de créer le widget.", - "Unbans user with given id": "Amnistie l'utilisateur à partir de son identifiant", + "Unbans user with given id": "Révoque le bannissement de l'utilisateur à partir de son identifiant", "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.", - "Autocomplete Delay (ms):": "Délai pour l'autocomplétion (ms) :", - "This Home server does not support groups": "Ce homeserver ne supporte pas les groupes", - "Loading device info...": "Chargement des informations sur l'appareil...", + "Autocomplete Delay (ms):": "Délai pour l'auto-complétion (ms) :", + "This Home server does not support groups": "Ce serveur d'accueil ne supporte pas les groupes", + "Loading device info...": "Chargement des informations de l'appareil...", "Groups": "Groupes", "Create a new group": "Créer un nouveau groupe", "Create Group": "Créer le groupe", @@ -842,27 +842,36 @@ "Create": "Créer", "Group ID": "Identifiant du groupe", "+example:%(domain)s": "+exemple:%(domain)s", - "Group IDs must be of the form +localpart:%(domain)s": "Les identifiants de groupe doivent être au format +localpart:%(domain)s", - "It is currently only possible to create groups on your own home server: use a group ID ending with %(domain)s": "Il n'est pas encore possible de créer des groupes sur votre propre homeserver : utilisez un identifiant de groupe terminant par %(domain)s", - "Room creation failed": "Impossible de créer le salon", + "Group IDs must be of the form +localpart:%(domain)s": "Les identifiants de groupe doivent être au format +partlocale:%(domain)s", + "It is currently only possible to create groups on your own home server: use a group ID ending with %(domain)s": "Pour le moment, il n'est possible de créer des groupes que sur votre propre serveur d'accueil : utilisez un identifiant de groupe terminant par %(domain)s", + "Room creation failed": "Échec de création du salon", "You are a member of these groups:": "Vous êtes membre des groupes suivants :", "Create a group to represent your community! Define a set of rooms and your own custom homepage to mark out your space in the Matrix universe.": "Créez un groupe pour représenter votre communauté ! Définissez un jeu de salons et votre propre page d'accueil pour marquer votre espace dans l'univers Matrix.", "Join an existing group": "Rejoindre un groupe existant", "To join an existing group you'll have to know its group identifier; this will look something like +example:matrix.org.": "Pour rejoindre un groupe existant, vous devez connaître l'identifiant de ce groupe ; il ressemblera à +exemple:matrix.org.", "Featured Rooms:": "Salons mis en avant :", - "Error whilst fetching joined groups": "Erreur en récupérant la liste des groupes", + "Error whilst fetching joined groups": "Erreur en récupérant la liste des groupes rejoints", "Featured Users:": "Utilisateurs mis en avant :", "Edit Group": "Modifier le groupe", - "Automatically replace plain text Emoji": "Remplacer automatiquement le texte par des Emoji", - "Failed to upload image": "Impossible de télécharger l'image", - "Failed to update group": "Impossible de modifier le groupe", + "Automatically replace plain text Emoji": "Remplacer automatiquement le texte par des Émoticônes", + "Failed to upload image": "Impossible d'envoyer l'image", + "Failed to update group": "Impossible de mettre à jour le groupe", "Hide avatars in user and room mentions": "Masquer les avatars dans les mentions d'utilisateur et de salon", - "Do you want to load widget from URL:": "Charger un widget venant de l’URL :", - "%(widgetName)s widget added by %(senderName)s": "%(widgetName)s widget ajouté par %(senderName)s", - "%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s widget supprimé par %(senderName)s", - "Publish this room to the public in %(domain)s's room directory?": "Publier ce salon dans le l'annuaire public de %(domain)s ?", + "Do you want to load widget from URL:": "Voulez-vous charger le widget depuis l’URL :", + "%(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 ?", "Integrations Error": "Erreur d'intégration", "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.", - "NOTE: Apps are not end-to-end encrypted": "NOTE : Les applications ne sont pas chiffrées de bout en bout" + "NOTE: Apps are not end-to-end encrypted": "NOTE : Les applications ne sont pas chiffrées de bout en bout", + "AM": "AM", + "PM": "PM", + "%(weekDayName)s, %(monthName)s %(day)s": "%(weekDayName)s %(day)s %(monthName)s", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s %(day)s %(monthName)s %(fullYear)s", + "Copied!": "Copié !", + "Failed to copy": "Échec de la copie", + "Verifies a user, device, and pubkey tuple": "Vérifie un utilisateur, un appareil et une clé publique", + "%(widgetName)s widget modified by %(senderName)s": "Widget %(widgetName)s modifié par %(senderName)s", + "Robot check is currently unavailable on desktop - please use a web browser": "La vérification robot n'est pas encore disponible pour le bureau - veuillez utiliser un navigateur" } From 7dfff429f221441680e4888799bb5e90ba6bac45 Mon Sep 17 00:00:00 2001 From: Walter Date: Sat, 23 Sep 2017 18:25:18 +0000 Subject: [PATCH 036/123] Translated using Weblate (Ukrainian) Currently translated at 13.0% (112 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/uk/ --- src/i18n/strings/uk.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/uk.json b/src/i18n/strings/uk.json index 8f9c18356a..27b36b8da5 100644 --- a/src/i18n/strings/uk.json +++ b/src/i18n/strings/uk.json @@ -101,5 +101,14 @@ "Bug Report": "Звіт про помилку", "Bulk Options": "Групові параметри", "Call Timeout": "Час очікування виклика", - "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.": "Не вдається підключитись до домашнього серверу - перевірте підключення, переконайтесь, що ваш SSL-сертифікат домашнього сервера є довіреним і що розширення браузера не блокує запити." + "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.": "Не вдається підключитись до домашнього серверу - перевірте підключення, переконайтесь, що ваш SSL-сертифікат домашнього сервера є довіреним і що розширення браузера не блокує запити.", + "Can't load user settings": "Неможливо завантажити настройки користувача", + "Cannot add any more widgets": "Неможливо додати більше віджетів", + "Change Password": "Поміняти пароль", + "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s змінено з %(oldDisplayName)s на %(displayName)s.", + "%(senderName)s changed their profile picture.": "%(senderName)s змінив зображення профіля.", + "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s змінив(ла) рівень доступу для %(powerLevelDiffText)s.", + "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s змінив(ла) назву кімнати на %(roomName)s.", + "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s видалив ім'я кімнати.", + "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s змінив тему на %(topic)s." } From 56bb932a9bb49bbfebf21db87aba7d88680f7f71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Mon, 25 Sep 2017 13:33:27 +0000 Subject: [PATCH 037/123] Translated using Weblate (French) Currently translated at 99.8% (854 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index bf83f394d5..85c9700bb8 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -50,7 +50,7 @@ "Favourite": "Favoris", "Notifications": "Notifications", "Settings": "Paramètres", - "Failed to join the room": "Échec de l'adhésion au salon", + "Failed to join the room": "Échec de l'inscription au salon", "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Un SMS a été envoyé à +%(msisdn)s. Merci de saisir le code de vérification qu'il contient", "accept": "Accepter", "%(targetName)s accepted an invitation.": "%(targetName)s a accepté une invitation.", @@ -75,8 +75,8 @@ "and %(count)s others...|one": "et un autre...", "An email has been sent to": "Un e-mail a été envoyé à", "A new password must be entered.": "Un nouveau mot de passe doit être saisi.", - "Anyone who knows the room's link, apart from guests": "Tout ceux qui connaissent le lien du salon, à part les visiteurs", - "Anyone who knows the room's link, including guests": "Tout ceux qui connaissent le lien du salon, y compris les visiteurs", + "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 you want to upload the following files?": "Voulez-vous vraiment envoyer les fichiers suivants ?", @@ -100,7 +100,7 @@ "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s a changé le sujet du salon en \"%(topic)s\".", "Changes to who can read history will only apply to future messages in this room": "Les changements de visibilité de l’historique de ce salon ne s’appliquent qu’aux futurs messages", "Changes your display nickname": "Change votre nom affiché", - "Claimed Ed25519 fingerprint key": "Clé de l'empreinte Ed25519 revendiquée", + "Claimed Ed25519 fingerprint key": "Clé d'empreinte Ed25519 déclarée", "Clear Cache and Reload": "Vider le cache et rafraîchir", "Clear Cache": "Vider le cache", "Click here": "Cliquer ici", @@ -138,10 +138,10 @@ "Devices": "Appareils", "Devices will not yet be able to decrypt history from before they joined the room": "Les appareils ne pourront pas encore déchiffrer l'historique de messages d'avant leur arrivée sur le salon", "ml": "Malayalam", - "Failed to join room": "Échec lors de l’adhésion au salon", + "Failed to join room": "Échec de l’inscription au salon", "Failed to kick": "Échec de l'exclusion", "Failed to leave room": "Échec du départ du salon", - "Failed to load timeline position": "Échec du chargement de la position dans la chronologie", + "Failed to load timeline position": "Échec du chargement de la position dans l'historique", "Failed to lookup current room": "Échec de la recherche du salon actuel", "Failed to mute user": "Échec de la mise en sourdine de l'utilisateur", "Failed to reject invite": "Échec du rejet de l'invitation", @@ -216,7 +216,7 @@ "Logged in as:": "Identifié en tant que :", "Login as guest": "Se connecter en tant que visiteur", "Logout": "Se déconnecter", - "Low priority": "Priorité faible", + "Low priority": "Priorité basse", "%(senderName)s made future room history visible to": "%(senderName)s a rendu l'historique futur visible à", "Manage Integrations": "Gestion des intégrations", "Markdown is disabled": "Le formatage Markdown est désactivé", @@ -384,8 +384,8 @@ "to tag as %(tagName)s": "pour étiqueter comme %(tagName)s", "to tag direct chat": "pour étiqueter comme discussion directe", "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 faites-les défiler 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.": "L'instant donné de la chronologie n’a pu être chargé car vous n’avez pas la permission de visualiser le message concerné.", - "Tried to load a specific point in this room's timeline, but was unable to find it.": "L'instant donné de la chronologie n’a pu être chargé car il n’a pas pu être trouvé.", + "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "L'instant donné dans l'historique n’a pas pu être chargé car vous n’avez pas l'autorisation de voir le message concerné.", + "Tried to load a specific point in this room's timeline, but was unable to find it.": "L'instant donné dans l'historique n’a pas pu être chargé car il n’a pas été trouvé.", "Turn Markdown off": "Désactiver le formatage Markdown", "Turn Markdown on": "Activer le formatage Markdown", "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s a activé le chiffrement de bout en bout (algorithme %(algorithm)s).", @@ -430,7 +430,7 @@ "Who can read history?": "Qui peut lire l'historique ?", "Who would you like to add to this room?": "Qui voulez-vous inviter dans ce salon ?", "Who would you like to communicate with?": "Avec qui voulez-vous communiquer ?", - "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s a révoqué l’invitation de %(targetName)s.", + "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s a annulé l’invitation de %(targetName)s.", "Would you like to": "Voulez-vous", "You are already in a call.": "Vous avez déjà un appel en cours.", "You're not in any rooms yet! Press": "Vous n’êtes dans aucun salon ! Cliquez", @@ -564,7 +564,7 @@ "Import room keys": "Importer les clés de salon", "File to import": "Fichier à importer", "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.": "Ce processus vous permet d’exporter dans un fichier local les clés pour les messages que vous avez reçus dans des salons chiffrés. Il sera ensuite possible d’importer ce fichier dans un autre client Matrix, afin de permettre à ce client de pouvoir déchiffrer ces messages.", - "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.": "Le fichier exporté permettra à tout ceux qui peuvent le lire de déchiffrer tous les messages chiffrés auxquels vous avez accès, vous devez donc être vigilant et le stocker dans un endroit sûr. Afin de protéger ce fichier, saisissez ci-dessous une phrase secrète qui sera utilisée pour chiffrer les données exportées. Seule l’utilisation de la même phrase secrète permettra de déchiffrer et importer les données.", + "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.": "Le fichier exporté permettra à tous ceux qui peuvent le lire de déchiffrer tous les messages chiffrés auxquels vous avez accès, vous devez donc être vigilant et le stocker dans un endroit sûr. Afin de protéger ce fichier, saisissez ci-dessous une phrase secrète qui sera utilisée pour chiffrer les données exportées. Seule l’utilisation de la même phrase secrète permettra de déchiffrer et importer les données.", "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.": "Ce processus vous permet d’importer les clés de chiffrement que vous avez précédemment exportées depuis un autre client Matrix. Vous serez alors capable de déchiffrer n’importe quel message que l’autre client pouvait déchiffrer.", "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Le fichier exporté est protégé par une phrase de passe. Vous devez saisir cette phrase de passe ici pour déchiffrer le fichier.", "You must join the room to see its files": "Vous devez rejoindre le salon pour voir ses fichiers", @@ -600,7 +600,7 @@ "Unknown Address": "Adresse inconnue", "Unblacklist": "Supprimer de la liste noire", "Blacklist": "Ajouter à la liste noire", - "Unverify": "Révoquer la vérification", + "Unverify": "Annuler la vérification", "Verify...": "Vérifier...", "ex. @bob:example.com": "ex. @bob:exemple.com", "Add User": "Ajouter l'utilisateur", @@ -669,7 +669,7 @@ "Unknown (user, device) pair:": "Couple (utilisateur, appareil) inconnu :", "Unrecognised command:": "Commande non reconnue :", "Unrecognised room alias:": "Alias de salon non reconnu :", - "Use compact timeline layout": "Utiliser l'affichage compact", + "Use compact timeline layout": "Utiliser l'affichage compact de l'historique", "Verified key": "Clé vérifiée", "WARNING: Device already verified, but keys do NOT MATCH!": "ATTENTION : appareil déjà vérifié mais les clés NE CORRESPONDENT PAS !", "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "ATTENTION : ERREUR DE VÉRIFICATION DES CLÉS ! La clé de signature pour %(userId)s et l'appareil %(deviceId)s est “%(fprint)s” et ne correspond pas à la clé “%(fingerprint)s” qui a été fournie. Cela peut signifier que vos communications sont interceptées !", From bb5551aeda5b79fe9eaf17cdcb372a6e60374bc2 Mon Sep 17 00:00:00 2001 From: "Iru Cai (vimacs)" Date: Tue, 26 Sep 2017 07:42:54 +0000 Subject: [PATCH 038/123] Translated using Weblate (Chinese (Simplified)) Currently translated at 85.1% (728 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hans/ --- src/i18n/strings/zh_Hans.json | 40 ++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index db45450a47..1a19ecf2ed 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -692,5 +692,43 @@ "Please select the destination room for this message": "请选择这条消息的目标聊天室", "Start automatically after system login": "在系统登录后自动启动", "Analytics": "分析", - "Reject all %(invitedRooms)s invites": "拒绝所有 %(invitedRooms)s 邀请" + "Reject all %(invitedRooms)s invites": "拒绝所有 %(invitedRooms)s 邀请", + "You may wish to login with a different account, or add this email to this account.": "你可能希望用另外一个账户登录,或者添加这个电子邮件到这个账户上。", + "Sun": "星期日", + "Mon": "星期一", + "Tue": "星期二", + "Wed": "星期三", + "Thu": "星期四", + "Fri": "星期五", + "Sat": "星期六", + "Jan": "一月", + "Feb": "二月", + "Mar": "三月", + "Apr": "四月", + "May": "五月", + "Jun": "六月", + "Jul": "七月", + "Aug": "八月", + "Sep": "九月", + "Oct": "十月", + "Nov": "十一月", + "Dec": "十二月", + "%(severalUsers)sjoined and left %(repeats)s times": "%(severalUsers)s 加入并离开了 %(repeats)s 次", + "were unbanned %(repeats)s times": "被解封 %(repeats)s 次", + "was unbanned %(repeats)s times": "被解封 %(repeats)s 次", + "were unbanned": "被解封", + "was unbanned": "被解封", + "were kicked %(repeats)s times": "被踢出 %(repeats)s 次", + "was kicked %(repeats)s times": "被踢出 %(repeats)s 次", + "were kicked": "被踢出", + "was kicked": "被踢出", + "Desktop specific": "桌面特有的", + "You must join the room to see its files": "你必须加入聊天室以看到它的文件", + "Failed to invite the following users to the %(roomName)s room:": "邀请以下用户到 %(roomName)s 聊天室失败:", + "Confirm Removal": "确认移除", + "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "这会让你的账户永远不可用。你无法重新注册同一个用户 ID.", + "Verifies a user, device, and pubkey tuple": "验证一个用户、设备和密钥元组", + "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "我们在尝试恢复你之前的会话时遇到了一个错误。如果你继续,你将需要重新登录,加密的聊天历史将会不可读。", + "Unknown devices": "未知设备", + "Unknown Address": "未知地址" } From 6bbf751f4bd6c416d22376ef6045b4c825cc7a4f Mon Sep 17 00:00:00 2001 From: Riot Administration Date: Wed, 27 Sep 2017 02:37:01 +0000 Subject: [PATCH 039/123] Translated using Weblate (English (United States)) Currently translated at 99.5% (851 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/en_US/ --- src/i18n/strings/en_US.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/en_US.json b/src/i18n/strings/en_US.json index dd94a82727..3f26e07fee 100644 --- a/src/i18n/strings/en_US.json +++ b/src/i18n/strings/en_US.json @@ -864,5 +864,6 @@ "Robot check is currently unavailable on desktop - please use a web browser": "Robot check is currently unavailable on desktop - please use a web browser", "Verifies a user, device, and pubkey tuple": "Verifies a user, device, and pubkey tuple", "It is currently only possible to create groups on your own home server: use a group ID ending with %(domain)s": "It is currently only possible to create groups on your own home server: use a group ID ending with %(domain)s", - "To join an existing group you'll have to know its group identifier; this will look something like +example:matrix.org.": "To join an existing group you'll have to know its group identifier; this will look something like +example:matrix.org." + "To join an existing group you'll have to know its group identifier; this will look something like +example:matrix.org.": "To join an existing group you'll have to know its group identifier; this will look something like +example:matrix.org.", + "%(weekDayName)s, %(monthName)s %(day)s": "print \"fdsafsdsad\"" } From 540885474ab3ce0d1ec34b20958f4b63d08597c9 Mon Sep 17 00:00:00 2001 From: Riot Administration Date: Wed, 27 Sep 2017 02:37:22 +0000 Subject: [PATCH 040/123] Translated using Weblate (English (United States)) Currently translated at 99.6% (852 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/en_US/ <<>>>xss --- src/i18n/strings/en_US.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/en_US.json b/src/i18n/strings/en_US.json index 3f26e07fee..2c5b2b3c26 100644 --- a/src/i18n/strings/en_US.json +++ b/src/i18n/strings/en_US.json @@ -865,5 +865,6 @@ "Verifies a user, device, and pubkey tuple": "Verifies a user, device, and pubkey tuple", "It is currently only possible to create groups on your own home server: use a group ID ending with %(domain)s": "It is currently only possible to create groups on your own home server: use a group ID ending with %(domain)s", "To join an existing group you'll have to know its group identifier; this will look something like +example:matrix.org.": "To join an existing group you'll have to know its group identifier; this will look something like +example:matrix.org.", - "%(weekDayName)s, %(monthName)s %(day)s": "print \"fdsafsdsad\"" + "%(weekDayName)s, %(monthName)s %(day)s": "print \"fdsafsdsad\"", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s" } From 955ca6cd2b19dfab7cc30b2303ba05f9885876b3 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 29 Sep 2017 17:59:24 +0100 Subject: [PATCH 041/123] Implement button to remove a room from a group NB: This doesn't provide any feedback to the user. We should use a GroupSummaryStore-style component to refresh the view after a successful hit to the API. This could affect the summary view as well, because when rooms are removed from a group, they are also removed from the summary (if necessary). --- src/components/views/groups/GroupRoomTile.js | 10 ++++++++++ src/groups.js | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/components/views/groups/GroupRoomTile.js b/src/components/views/groups/GroupRoomTile.js index 452f862d16..1081890f40 100644 --- a/src/components/views/groups/GroupRoomTile.js +++ b/src/components/views/groups/GroupRoomTile.js @@ -49,6 +49,13 @@ const GroupRoomTile = React.createClass({ }); }, + onDeleteClick: function(e) { + e.preventDefault(); + e.stopPropagation(); + this.context.matrixClient + .removeRoomFromGroup(this.props.groupId, this.props.groupRoom.roomId); + }, + render: function() { const BaseAvatar = sdk.getComponent('avatars.BaseAvatar'); const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); @@ -76,6 +83,9 @@ const GroupRoomTile = React.createClass({
{ name }
+ + + ); }, diff --git a/src/groups.js b/src/groups.js index 2ff95f7d65..69871c45e9 100644 --- a/src/groups.js +++ b/src/groups.js @@ -24,8 +24,7 @@ export const GroupMemberType = PropTypes.shape({ export const GroupRoomType = PropTypes.shape({ name: PropTypes.string, - // TODO: API doesn't return this yet - // roomId: PropTypes.string.isRequired, + roomId: PropTypes.string.isRequired, canonicalAlias: PropTypes.string, avatarUrl: PropTypes.string, }); @@ -41,6 +40,7 @@ export function groupMemberFromApiObject(apiObject) { export function groupRoomFromApiObject(apiObject) { return { name: apiObject.name, + roomId: apiObject.room_id, canonicalAlias: apiObject.canonical_alias, avatarUrl: apiObject.avatar_url, }; From 415693bd834b14b946e492c9914782632e4cfe0b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 29 Sep 2017 14:02:31 -0600 Subject: [PATCH 042/123] Support editing power levels of events. Signed-off-by: Travis Ralston --- src/components/views/rooms/RoomSettings.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index 0fea50d2fa..b2d8aa7fe5 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -364,6 +364,11 @@ module.exports = React.createClass({ var powerLevels = this.props.room.currentState.getStateEvents('m.room.power_levels', ''); powerLevels = powerLevels ? powerLevels.getContent() : {}; + for (let key of Object.keys(this.refs).filter(k => k.startsWith("event_levels_"))) { + const eventType = key.substring("event_levels_".length); + powerLevels.events[eventType] = parseInt(this.refs[key].getValue()); + } + var newPowerLevels = { ban: parseInt(this.refs.ban.getValue()), kick: parseInt(this.refs.kick.getValue()), @@ -883,7 +888,8 @@ module.exports = React.createClass({ return (
{ _t('To send events of type') } { event_type }, { _t('you must be a') } - +
); })} From 2e1b2178a1f12be3c9a0da8054d15b5220e51903 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 29 Sep 2017 14:35:49 -0600 Subject: [PATCH 043/123] Remove assumptions on how languages work in the power levels section This does mean that the strings will need to be re-translated, but now they may be more accurate because the comma is not assumed in the code. Signed-off-by: Travis Ralston --- src/components/views/rooms/RoomSettings.js | 14 +++++++------- src/i18n/strings/de_DE.json | 6 ------ src/i18n/strings/el.json | 7 ------- src/i18n/strings/en_EN.json | 14 +++++++------- src/i18n/strings/en_US.json | 14 +++++++------- src/i18n/strings/es.json | 7 ------- src/i18n/strings/eu.json | 7 ------- src/i18n/strings/fr.json | 7 ------- src/i18n/strings/hu.json | 7 ------- src/i18n/strings/ko.json | 7 ------- src/i18n/strings/lv.json | 7 ------- src/i18n/strings/nl.json | 7 ------- src/i18n/strings/pl.json | 7 ------- src/i18n/strings/pt.json | 7 ------- src/i18n/strings/pt_BR.json | 7 ------- src/i18n/strings/ru.json | 7 ------- src/i18n/strings/th.json | 6 ------ src/i18n/strings/tr.json | 7 ------- src/i18n/strings/zh_Hant.json | 7 ------- 19 files changed, 21 insertions(+), 131 deletions(-) diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index b2d8aa7fe5..942da9ba06 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -860,34 +860,34 @@ module.exports = React.createClass({
- { _t('To send messages') }, { _t('you must be a') } + { _t('To send messages, you must be a') }
- { _t('To invite users into the room') }, { _t('you must be a') } + { _t('To invite users into the room, you must be a') }
- { _t('To configure the room') }, { _t('you must be a') } + { _t('To configure the room, you must be a') }
- { _t('To kick users') }, { _t('you must be a') } + { _t('To kick users, you must be a') }
- { _t('To ban users') }, { _t('you must be a') } + { _t('To ban users, you must be a') }
- { _t('To remove other users\' messages') }, { _t('you must be a') } + { _t('To remove other users\' messages, you must be a') }
{Object.keys(events_levels).map(function(event_type, i) { return (
- { _t('To send events of type') } { event_type }, { _t('you must be a') } + { _tJsx("To send events of type , you must be a", //, () => { event_type }) }
diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index aa114e241d..1a05530890 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -212,11 +212,7 @@ "This is a preview of this room. Room interactions have been disabled": "Dies ist eine Vorschau dieses Raumes. Raum-Interaktionen wurden deaktiviert", "This room is not accessible by remote Matrix servers": "Remote-Matrix-Server können auf diesen Raum nicht zugreifen", "This room's internal ID is": "Die interne ID dieses Raumes ist", - "To ban users": "Um Benutzer zu verbannen", - "To configure the room": "Um den Raum zu konfigurieren", - "To invite users into the room": "Um Nutzer in den Raum einzuladen", "to join the discussion": "um an der Diskussion teilzunehmen", - "To kick users": "Um Benutzer zu kicken", "Admin": "Administrator", "Server may be unavailable, overloaded, or you hit a bug.": "Server ist nicht verfügbar, überlastet oder du bist auf einen Fehler gestoßen.", "Could not connect to the integration server": "Konnte keine Verbindung zum Integrations-Server herstellen", @@ -227,7 +223,6 @@ "Can't connect to homeserver - please check your connectivity and ensure your": "Die Verbindung mit dem Homeserver ist fehlgeschlagen. Bitte überprüfe deine Verbindung und stelle sicher, dass dein(e) ", "tag as": "kennzeichne als", "To reset your password, enter the email address linked to your account": "Um dein Passwort zurückzusetzen, gib bitte die mit deinem Account verknüpfte E-Mail-Adresse ein", - "To send messages": "Um Nachrichten zu senden", "turned on end-to-end encryption (algorithm": "aktivierte Ende-zu-Ende-Verschlüsselung (Algorithmus", "Unable to add email address": "E-Mail-Adresse konnte nicht hinzugefügt werden", "Unable to remove contact information": "Die Kontakt-Informationen konnten nicht gelöscht werden", @@ -412,7 +407,6 @@ "to tag direct chat": "als Direkt-Chat markieren", "You're not in any rooms yet! Press": "Du bist noch keinem Raum beigetreten! Drücke", "click to reveal": "anzeigen", - "To remove other users' messages": "Um Nachrichten anderer Nutzer zu verbergen", "You are trying to access %(roomName)s.": "Du versuchst, auf den Raum \"%(roomName)s\" zuzugreifen.", "Monday": "Montag", "Tuesday": "Dienstag", diff --git a/src/i18n/strings/el.json b/src/i18n/strings/el.json index bc45e6da9e..048de7e73f 100644 --- a/src/i18n/strings/el.json +++ b/src/i18n/strings/el.json @@ -344,14 +344,8 @@ "This room": "Αυτό το δωμάτιο", "This room's internal ID is": "Το εσωτερικό αναγνωριστικό του δωματίου είναι", "times": "φορές", - "To ban users": "Για αποκλεισμό χρηστών", "to browse the directory": "για περιήγηση στο ευρετήριο", - "To configure the room": "Για ρύθμιση του δωματίου", - "To invite users into the room": "Για πρόσκληση χρηστών στο δωμάτιο", - "To remove other users' messages": "Για αφαίρεση μηνυμάτων άλλων χρηστών", "to restore": "για επαναφορά", - "To send events of type": "Για αποστολή συμβάντων τύπου", - "To send messages": "Για αποστολή μηνυμάτων", "Turn Markdown off": "Απενεργοποίηση Markdown", "Turn Markdown on": "Ενεργοποίηση Markdown", "Unable to add email address": "Αδυναμία προσθήκης διεύθυνσης ηλ. αλληλογραφίας", @@ -574,7 +568,6 @@ "Some of your messages have not been sent.": "Μερικά από τα μηνύματα σας δεν έχουν αποσταλεί.", "This room is not recognised.": "Αυτό το δωμάτιο δεν αναγνωρίζεται.", "to favourite": "στα αγαπημένα", - "To kick users": "Για να διώξετε χρήστες", "to make a room or": "για δημιουργία ενός δωματίου ή", "to start a chat with someone": "για να ξεκινήσετε μια συνομιλία με κάποιον", "Unable to capture screen": "Αδυναμία σύλληψης οθόνης", diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 87fd6d4364..8873b54091 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -448,21 +448,14 @@ "This room is not accessible by remote Matrix servers": "This room is not accessible by remote Matrix servers", "This room's internal ID is": "This room's internal ID is", "times": "times", - "To ban users": "To ban users", "to browse the directory": "to browse the directory", - "To configure the room": "To configure the room", "to demote": "to demote", "to favourite": "to favourite", "To get started, please pick a username!": "To get started, please pick a username!", - "To invite users into the room": "To invite users into the room", - "To kick users": "To kick users", "To link to a room it must have an address.": "To link to a room it must have an address.", "to make a room or": "to make a room or", - "To remove other users' messages": "To remove other users' messages", "To reset your password, enter the email address linked to your account": "To reset your password, enter the email address linked to your account", "to restore": "to restore", - "To send events of type": "To send events of type", - "To send messages": "To send messages", "to start a chat with someone": "to start a chat with someone", "to tag direct chat": "to tag direct chat", "To use it, just wait for autocomplete results to load and tab through them.": "To use it, just wait for autocomplete results to load and tab through them.", @@ -832,6 +825,13 @@ "Join an existing group": "Join an existing group", "To join an existing group you'll have to know its group identifier; this will look something like +example:matrix.org.": "To join an existing group you'll have to know its group identifier; this will look something like +example:matrix.org.", "Featured Rooms:": "Featured Rooms:", + "To send messages, you must be a": "To send messages, you must be a", + "To invite users into the room, you must be a": "To invite users into the room, you must be a", + "To configure the room, you must be a": "To configure the room, you must be a", + "To kick users, you must be a": "To kick users, you must be a", + "To ban users, you must be a": "To ban users, you must be a", + "To remove other users' messages, you must be a": "To remove other users' messages, you must be a", + "To send events of type , you must be a": "To send events of type , you must be a", "Error whilst fetching joined groups": "Error whilst fetching joined groups", "Featured Users:": "Featured Users:", "Edit Group": "Edit Group", diff --git a/src/i18n/strings/en_US.json b/src/i18n/strings/en_US.json index 928f1a9d0f..c3b3b6a1bc 100644 --- a/src/i18n/strings/en_US.json +++ b/src/i18n/strings/en_US.json @@ -393,21 +393,14 @@ "This room is not accessible by remote Matrix servers": "This room is not accessible by remote Matrix servers", "This room's internal ID is": "This room's internal ID is", "times": "times", - "To ban users": "To ban users", "to browse the directory": "to browse the directory", - "To configure the room": "To configure the room", "to demote": "to demote", "to favourite": "to favorite", - "To invite users into the room": "To invite users into the room", "to join the discussion": "to join the discussion", - "To kick users": "To kick users", "To link to a room it must have": "To link to a room it must have", "to make a room or": "to make a room or", - "To remove other users' messages": "To remove other users' messages", "To reset your password, enter the email address linked to your account": "To reset your password, enter the email address linked to your account", "to restore": "to restore", - "To send events of type": "To send events of type", - "To send messages": "To send messages", "to start a chat with someone": "to start a chat with someone", "to tag direct chat": "to tag direct chat", "To use it, just wait for autocomplete results to load and tab through them.": "To use it, just wait for autocomplete results to load and tab through them.", @@ -656,6 +649,13 @@ "Verify...": "Verify...", "ex. @bob:example.com": "ex. @bob:example.com", "Add User": "Add User", + "To send messages, you must be a": "To send messages, you must be a", + "To invite users into the room, you must be a": "To invite users into the room, you must be a", + "To configure the room, you must be a": "To configure the room, you must be a", + "To kick users, you must be a": "To kick users, you must be a", + "To ban users, you must be a": "To ban users, you must be a", + "To remove other users' messages, you must be a": "To remove other users' messages, you must be a", + "To send events of type , you must be a": "To send events of type , you must be a", "This Home Server would like to make sure you are not a robot": "This Home Server would like to make sure you are not a robot", "Sign in with CAS": "Sign in with CAS", "Custom Server Options": "Custom Server Options", diff --git a/src/i18n/strings/es.json b/src/i18n/strings/es.json index bc2391a5c7..9838b915a4 100644 --- a/src/i18n/strings/es.json +++ b/src/i18n/strings/es.json @@ -470,16 +470,11 @@ "This room is not accessible by remote Matrix servers": "Esta sala no es accesible por otros servidores Matrix", "This room's internal ID is": "El ID interno de la sala es", "times": "veces", - "To ban users": "Expulsar usuarios", "to browse the directory": "navegar el directorio", - "To configure the room": "Configurar la sala", "to demote": "degradar", "to favourite": "marcar como favorito", - "To invite users into the room": "Invitar usuarios a la sala", - "To kick users": "Patear usuarios", "To link to a room it must have an address.": "Para enlazar una sala, debe tener una dirección.", "to make a room or": "hacer una sala o", - "To remove other users' messages": "Eliminar los mensajes de otros usuarios", "To reset your password, enter the email address linked to your account": "Para reiniciar su contraseña, introduzca el e-mail asociado a su cuenta", "to restore": "restaurar", "Cancel": "Cancelar", @@ -505,8 +500,6 @@ "Authentication check failed: incorrect password?": "La verificación de la autentificación ha fallado: ¿El password es el correcto?", "And %(count)s more...": "Y %(count)s más...", "Press to start a chat with someone": "Pulsa para empezar a charlar con alguien", - "To send events of type": "Para enviar eventos de tipo", - "To send messages": "Para enviar mensajes", "to start a chat with someone": "para empezar a charlar con alguien", "to tag direct chat": "para etiquetar como charla directa", "Add a widget": "Añadir widget", diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index 9f3d06ec52..fb2ec9f7b7 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -464,20 +464,13 @@ "This room is not accessible by remote Matrix servers": "Gela hau ez dago eskuragarri urruneko zerbitzarietan", "This room's internal ID is": "Gela honen barne ID-a:", "times": "aldi", - "To ban users": "Erabiltzaileak debekatzea", "to browse the directory": "direktorioa arakatzea", - "To configure the room": "Gela konfiguratzea", "to demote": "mailaz jaistea", "to favourite": "gogoko egitea", - "To invite users into the room": "Erabiltzaileak gela honetara gonbidatzea", - "To kick users": "Erabiltzaileak kaleratzea", "To link to a room it must have an address.": "Gelara estekatzeko honek helbide bat izan behar du.", "to make a room or": "gela bat egitea edo", - "To remove other users' messages": "Beste erabiltzaileen mezuak kentzea", "To reset your password, enter the email address linked to your account": "Zure pasahitza berrezartzeko, sartu zure kontuarekin lotutako e-mail helbidea", "to restore": "berreskuratzea", - "To send events of type": "Mota honetako gertaerak bidaltzea:", - "To send messages": "Mezuak bidaltzea", "to start a chat with someone": "norbaitekin txat bat hastea", "to tag direct chat": "txat zuzena etiketatzea", "To use it, just wait for autocomplete results to load and tab through them.": "Erabiltzeko, itxaron osatze automatikoaren emaitzak kargatu arte eta gero tabuladorearekin hautatu.", diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 585e47f5a3..8ab78d0436 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -354,21 +354,14 @@ "This room is not accessible by remote Matrix servers": "Ce salon n’est pas accessible par les serveurs Matrix distants", "This room's internal ID is": "L'identifiant interne de ce salon est", "times": "fois", - "To ban users": "Pour bannir des utilisateurs", "to browse the directory": "pour parcourir le répertoire", - "To configure the room": "Pour configurer le salon", "to demote": "pour réduire la priorité", "to favourite": "pour marquer comme favori", - "To invite users into the room": "Pour inviter des utilisateurs dans le salon", "to join the discussion": "pour rejoindre la discussion", - "To kick users": "Pour expulser des utilisateurs", "To link to a room it must have": "Pour avoir un lien vers un salon, il doit avoir", "to make a room or": "pour créer un salon ou", - "To remove other users' messages": "Pour supprimer les messages des autres utilisateurs", "To reset your password, enter the email address linked to your account": "Pour réinitialiser votre mot de passe, merci d’entrer l’adresse e-mail liée à votre compte", "to restore": "pour restaurer", - "To send events of type": "Pour envoyer des évènements du type", - "To send messages": "Pour envoyer des messages", "to start a chat with someone": "pour démarrer une discussion avec quelqu’un", "to tag direct chat": "pour marquer comme conversation directe", "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.", diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 2c34e05b1a..fb295535ca 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -432,19 +432,12 @@ "This room is not accessible by remote Matrix servers": "Ez a szoba távoli Matrix szerverről nem érhető el", "This room's internal ID is": "A szoba belső azonosítója:", "times": "alkalommal", - "To ban users": "Felhasználó kizárásához", "to browse the directory": "a könyvtárban való kereséshez", - "To configure the room": "A szoba beállításához", "to favourite": "kedvencekhez", - "To invite users into the room": "Felhasználó szobába való meghívásához", - "To kick users": "Felhasználó kirúgásához", "To link to a room it must have an address.": "Szobához való kötéshez szükséges egy cím.", "to make a room or": "szoba létrehozásához vagy", - "To remove other users' messages": "Más felhasználók üzeneteinek törléséhez", "To reset your password, enter the email address linked to your account": "A jelszó alaphelyzetbe állításához add meg a fiókodhoz kötött e-mail címet", "to restore": "visszaállításhoz", - "To send events of type": "Az alábbi típusú üzenetek küldéséhez", - "To send messages": "Üzenetek küldéséhez", "to start a chat with someone": "csevegés indításához valakivel", "to tag direct chat": "megjelölni közvetlen csevegésnek", "To use it, just wait for autocomplete results to load and tab through them.": "A használatához csak várd meg az automatikus kiegészítéshez a találatok betöltését és TAB-bal választhatsz közülük.", diff --git a/src/i18n/strings/ko.json b/src/i18n/strings/ko.json index 8b6e233437..96655ccf4f 100644 --- a/src/i18n/strings/ko.json +++ b/src/i18n/strings/ko.json @@ -434,20 +434,13 @@ "This room is not accessible by remote Matrix servers": "이 방은 원격 매트릭스 서버에 접근할 수 없어요", "This room's internal ID is": "방의 내부 ID", "times": "번", - "To ban users": "사용자를 차단하기", "to browse the directory": "목록에서 찾으려면", - "To configure the room": "방을 구성하기", "to demote": "우선순위 낮추기", "to favourite": "즐겨찾기", - "To invite users into the room": "방으로 사용자를 초대하기", - "To kick users": "사용자를 내쫓기", "To link to a room it must have an address.": "방에 연결하려면 주소가 있어야 해요.", "to make a room or": "방을 만들거나 혹은", - "To remove other users' messages": "다른 사용자의 메시지를 지우기", "To reset your password, enter the email address linked to your account": "비밀번호을 다시 설정하려면, 계정과 연결한 이메일 주소를 입력해주세요", "to restore": "복구하려면", - "To send events of type": "유형 이벤트 보내기", - "To send messages": "메시지 보내기", "to start a chat with someone": "다른 사람과 이야기하기", "to tag direct chat": "직접 이야기를 지정하려면", "To use it, just wait for autocomplete results to load and tab through them.": "이 기능을 사용하시려면, 자동완성 결과가 나오길 기다리신 뒤에 탭으로 움직여주세요.", diff --git a/src/i18n/strings/lv.json b/src/i18n/strings/lv.json index 5f58fd9515..fea8065a5f 100644 --- a/src/i18n/strings/lv.json +++ b/src/i18n/strings/lv.json @@ -502,20 +502,13 @@ "This room is not accessible by remote Matrix servers": "Šī istaba nav pieejama no attālinātajiem Matrix serveriem", "This room's internal ID is": "Šīs istabas iekšējais ID ir", "times": "reizes", - "To ban users": "lai banotu lietotājus", "to browse the directory": "lai pārlūkotu katalogu", - "To configure the room": "Lai konfigurētu istabu", "to demote": "lai samazinātu", "to favourite": "lai pievienotu favorītiem", - "To invite users into the room": "Lai uzaicinātu lietotājus uz istabu", - "To kick users": "Lai \"iespertu\" (kicks) lietotājiem", "To link to a room it must have an address.": "Lai ieliktu saiti uz istabu, tai ir jābūt piešķirtai adresei.", "to make a room or": "lai izveidotu istabu vai", - "To remove other users' messages": "Lai dzēstu citu lietotāju ziņas", "To reset your password, enter the email address linked to your account": "Lai atiestatītu savu paroli, ievadi tavam kontam piesaistīto epasta adresi", "to restore": "lai atjaunotu", - "To send events of type": "Lai sūtītu sekojošā tipa notikumus", - "To send messages": "Lai nosūtītu ziņas", "to start a chat with someone": "lai uzstāktu čatu ar kādu", "to tag direct chat": "lai pieliktu birku tiešajam čatam", "To use it, just wait for autocomplete results to load and tab through them.": "Lai to izmantotu, vienkārši gaidi, kamēr ielādējas automātiski ieteiktie rezultāti, un pārvietojies caur tiem.", diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index f770e335cf..10f7f4900e 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -459,20 +459,13 @@ "This room is not accessible by remote Matrix servers": "Deze ruimte is niet toegankelijk voor afgelegen Matrix-servers", "This room's internal ID is": "Het interne ID van deze ruimte is", "times": "keer", - "To ban users": "om gebruikers te verbannen", "to browse the directory": "om de catalogus door te bladeren", - "To configure the room": "Om de ruimte te configureren", "to demote": "om te degraderen", "to favourite": "om aan favorieten toe te voegen", - "To invite users into the room": "Om gebruikers in deze ruimte toe te voegen", - "To kick users": "Om gebruikers er uit te zetten", "To link to a room it must have an address.": "Om naar een ruimte te linken moet het een adres hebben.", "to make a room or": "om een ruimte te maken of", - "To remove other users' messages": "Om berichten van anderen gebruikers te verwijderen", "To reset your password, enter the email address linked to your account": "Voer het e-mailadres dat met je account verbonden is in om je wachtwoord opnieuw in te stellen", "to restore": "om te herstellen", - "To send events of type": "Om een bepaalde soort gebeurtenissen te sturen", - "To send messages": "Om berichten te versturen", "to start a chat with someone": "om een gesprek met iemand te starten", "to tag direct chat": "als directe chat etiketteren", "To use it, just wait for autocomplete results to load and tab through them.": "Om het te gebruiken, wacht tot de automatisch aangevulde resultaten geladen zijn en tab er doorheen.", diff --git a/src/i18n/strings/pl.json b/src/i18n/strings/pl.json index bd1e4c5c24..0805c8fb66 100644 --- a/src/i18n/strings/pl.json +++ b/src/i18n/strings/pl.json @@ -515,20 +515,13 @@ "This room is not accessible by remote Matrix servers": "Ten pokój nie jest dostępny na zdalnych serwerach Matrix", "This room's internal ID is": "Wewnętrzne ID tego pokoju to", "times": "razy", - "To ban users": "Żeby zablokować użytkowników", "to browse the directory": "żeby przeglądać katalog", - "To configure the room": "Żeby skonfigurować pokój", "to demote": "żeby zmniejszyć priorytet", "To get started, please pick a username!": "Aby rozpocząć, wybierz nazwę użytkownika!", - "To invite users into the room": "Żeby zaprosić użytkowników do pokoju", - "To kick users": "Żeby usuwać użytkowników", "to make a room or": "żeby utworzyć pokój lub", - "To remove other users' messages": "Żeby usuwać wiadomości innych użytkowników", "To reset your password, enter the email address linked to your account": "Aby zresetować swoje hasło, wpisz adres e-mail powiązany z twoim kontem", "to restore": "żeby przywrócić", - "To send messages": "Żeby wysyłać wiadomości", "to start a chat with someone": "żeby zacząć rozmowę z kimś", - "To send events of type": "Żeby wysyłać wydarzenia typu", "to tag direct chat": "żeby oznaczyć rozmowę bezpośrednią", "Turn Markdown off": "Wyłącz Markdown", "Turn Markdown on": "Włącz Markdown", diff --git a/src/i18n/strings/pt.json b/src/i18n/strings/pt.json index ba4968b7ad..a1e4cce4e9 100644 --- a/src/i18n/strings/pt.json +++ b/src/i18n/strings/pt.json @@ -215,16 +215,10 @@ "This room is not accessible by remote Matrix servers": "Esta sala não é acessível para servidores Matrix remotos", "This room's internal ID is": "O ID interno desta sala é", "times": "vezes", - "To ban users": "Para banir usuárias/os", - "To configure the room": "Para poder configurar a sala", - "To invite users into the room": "Para convidar usuárias/os para esta sala", "to join the discussion": "para se juntar à conversa", - "To kick users": "Para poder remover pessoas da sala", "To link to a room it must have": "Para fazer um link para uma sala, ela deve ter", "To redact messages": "Para poder apagar mensagens", "To reset your password, enter the email address linked to your account": "Para redefinir sua senha, entre com o email da sua conta", - "To send events of type": "Para enviar eventos do tipo", - "To send messages": "Para enviar mensagens", "turned on end-to-end encryption (algorithm": "acionou a encriptação ponta-a-ponta (algoritmo", "Unable to add email address": "Não foi possível adicionar endereço de email", "Unable to remove contact information": "Não foi possível remover informação de contato", @@ -365,7 +359,6 @@ "to demote": "para reduzir prioridade", "to favourite": "para favoritar", "to make a room or": "para criar uma sala ou", - "To remove other users' messages": "Para apagar mensagens de outras pessoas", "to restore": "para restaurar", "to start a chat with someone": "para iniciar uma conversa com alguém", "to tag direct chat": "para marcar a conversa como pessoal", diff --git a/src/i18n/strings/pt_BR.json b/src/i18n/strings/pt_BR.json index af4804bd85..0cefe77aa6 100644 --- a/src/i18n/strings/pt_BR.json +++ b/src/i18n/strings/pt_BR.json @@ -215,16 +215,10 @@ "This room is not accessible by remote Matrix servers": "Esta sala não é acessível para servidores Matrix remotos", "This room's internal ID is": "O ID interno desta sala é", "times": "vezes", - "To ban users": "Para banir usuárias/os", - "To configure the room": "Para poder configurar a sala", - "To invite users into the room": "Para convidar usuárias/os para esta sala", "to join the discussion": "para se juntar à conversa", - "To kick users": "Para poder remover pessoas da sala", "To link to a room it must have": "Para fazer um link para uma sala, ela deve ter", "To redact messages": "Para poder apagar mensagens", "To reset your password, enter the email address linked to your account": "Para redefinir sua senha, entre com o email da sua conta", - "To send events of type": "Para enviar eventos do tipo", - "To send messages": "Para enviar mensagens", "turned on end-to-end encryption (algorithm": "acionou a encriptação ponta-a-ponta (algoritmo", "Unable to add email address": "Não foi possível adicionar endereço de email", "Unable to remove contact information": "Não foi possível remover informação de contato", @@ -364,7 +358,6 @@ "to demote": "para reduzir prioridade", "to favourite": "para favoritar", "to make a room or": "para criar uma sala ou", - "To remove other users' messages": "Para apagar mensagens de outras pessoas", "to restore": "para restaurar", "to start a chat with someone": "para iniciar uma conversa com alguém", "to tag direct chat": "para marcar a conversa como pessoal", diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index cfab960e32..3ff06070c3 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -155,8 +155,6 @@ "Start Chat": "Начать чат", "tag as": "tag as", "These are experimental features that may break in unexpected ways. Use with caution": "These are experimental features that may break in unexpected ways. Use with caution", - "To send events of type": "Чтобы отправить тип события", - "To send messages": "Чтобы отправить сообщения", "turned on end-to-end encryption (algorithm": "turned on end-to-end encryption (algorithm", "Unable to add email address": "Не удается добавить адрес электронной почты", "Unable to remove contact information": "Не удалось удалить контактную информацию", @@ -596,15 +594,10 @@ "The visibility of existing history will be unchanged": "Видимость существующей истории не изменится", "this invitation?": "это приглашение?", "This room is not accessible by remote Matrix servers": "Это комната недоступна с удаленных серверов Matrix", - "To ban users": "Для блокировки пользователей", "to browse the directory": "для просмотра каталога", - "To configure the room": "Для настройки комнаты", - "To invite users into the room": "Чтобы приглашать пользователей в комнату", "to join the discussion": "присоединиться к дискуссии", - "To kick users": "Чтобы удалять пользователей", "To link to a room it must have": "Для создания ссылки на комнату она должна иметь", "to make a room or": "чтобы создать комнату или", - "To remove other users' messages": "Чтобы удалить сообщения других пользователей", "To reset your password, enter the email address linked to your account": "Чтобы сбросить пароль, введите адрес электронной почты, связанный с вашей учетной записью", "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Попытка загрузить выбранный интервал истории чата этой комнаты не удалась, так как у вас нет разрешений на просмотр.", "Tried to load a specific point in this room's timeline, but was unable to find it.": "Попытка загрузить выбранный интервал истории чата этой комнаты не удалась, так как запрошенный элемент не найден.", diff --git a/src/i18n/strings/th.json b/src/i18n/strings/th.json index d45cb86986..9ff6e5b151 100644 --- a/src/i18n/strings/th.json +++ b/src/i18n/strings/th.json @@ -323,7 +323,6 @@ "The phone number entered looks invalid": "ดูเหมือนว่าหมายเลขโทรศัพท์ที่กรอกรมาไม่ถูกต้อง", "The email address linked to your account must be entered.": "กรุณากรอกที่อยู่อีเมลที่เชื่อมกับบัญชีของคุณ", "The file '%(fileName)s' exceeds this home server's size limit for uploads": "ไฟล์ '%(fileName)s' มีขนาดใหญ่เกินจำกัดของเซิร์ฟเวอร์บ้าน", - "To send messages": "เพื่อส่งข้อความ", "to start a chat with someone": "เพื่อเริ่มแชทกับผู้อื่น", "to tag direct chat": "เพื่อแทกว่าแชทตรง", "Turn Markdown off": "ปิด markdown", @@ -488,13 +487,8 @@ "Otherwise, click here to send a bug report.": "หรือคลิกที่นี่เพื่อรายงานจุดบกพร่อง", "Power level must be positive integer.": "ระดับอำนาจต้องเป็นจำนวนเต็มบวก", "%(roomName)s does not exist.": "ไม่มีห้อง %(roomName)s อยู่จริง", - "To ban users": "จะแบนผู้ใช้ได้", - "To configure the room": "จะตั้งค่าห้องนี้ได้", "to browse the directory": "เพื่อเรียกดูไดเรกทอรี", - "To invite users into the room": "จะเชิญผู้ใช้เข้าห้องได้", - "To kick users": "จะเตะผู้ใช้ได้", "To link to a room it must have an address.": "ห้องต้องมีที่อยู่ก่อน ถึงจะลิงก์ได้", - "To remove other users' messages": "จะลบข้อความของผู้ใช้อื่นได้", "Enter passphrase": "กรอกรหัสผ่าน", "Seen by %(userName)s at %(dateTime)s": "%(userName)s เห็นแล้วเมื่อเวลา %(dateTime)s", "to restore": "เพื่อกู้คืน", diff --git a/src/i18n/strings/tr.json b/src/i18n/strings/tr.json index 23d4e284bc..5c1017d177 100644 --- a/src/i18n/strings/tr.json +++ b/src/i18n/strings/tr.json @@ -415,20 +415,13 @@ "This room is not accessible by remote Matrix servers": "Bu oda uzak Matrix Sunucuları tarafından erişilebilir değil", "This room's internal ID is": "Bu odanın Dahili ID'si", "times": "kere", - "To ban users": "Kullanıcıları yasaklamak(Ban) için", "to browse the directory": "Dizine göz atmak için", - "To configure the room": "Odayı yapılandırmak için", "to demote": "indirgemek için", "to favourite": "favorilemek", - "To invite users into the room": "Kullanıcıları odaya davet etmek", - "To kick users": "Kullanıcıları atmak", "To link to a room it must have an address.": "Bir odaya bağlanmak için oda bir adrese sahip olmalı.", "to make a room or": "bir oda oluşturmak için ya da", - "To remove other users' messages": "Diğer kullanıcıların mesajlarını silmek için", "To reset your password, enter the email address linked to your account": "Parolanızı sıfırlamak için hesabınıza bağlı e-posta adresinizi girin", "to restore": "yenilemek için", - "To send events of type": "Tip olayını göndermek için", - "To send messages": "Mesaj göndermek için", "to start a chat with someone": "birisiyle sohbet başlatmak için", "to tag direct chat": "doğrudan sohbeti etiketlemek için", "To use it, just wait for autocomplete results to load and tab through them.": "Kullanmak için , otomatik tamamlama sonuçlarının yüklenmesini ve bitmesini bekleyin.", diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 596bc55a01..cad8834052 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -483,20 +483,13 @@ "This room is not accessible by remote Matrix servers": "此房間無法被遠端的 Matrix 伺服器存取", "This room's internal ID is": "此房間的內部 ID 為", "times": "次數", - "To ban users": "要禁止使用者", "to browse the directory": "要瀏覽目錄", - "To configure the room": "要設定房間", "to demote": "要降級", "to favourite": "到喜歡", - "To invite users into the room": "要邀請使用者進入此房間", - "To kick users": "要踢出使用者", "To link to a room it must have an address.": "要連結到房間,它必須有地址。", "to make a room or": "要開房間或", - "To remove other users' messages": "要移除其他使用者的訊息", "To reset your password, enter the email address linked to your account": "要重設您的密碼,輸入連結到您的帳號的電子郵件地址", "to restore": "要復原", - "To send events of type": "要傳送活動類型", - "To send messages": "要傳送訊息", "to start a chat with someone": "要開始與某人聊天", "to tag direct chat": "要標記直接聊天", "To use it, just wait for autocomplete results to load and tab through them.": "要使用它,只要等待自動完成的結果載入並在它們上面按 Tab。", From 614cf950b63fc64a15f51bf1324eb99bc764eda9 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 29 Sep 2017 14:45:00 -0600 Subject: [PATCH 044/123] Supply user-friendly labels for common events Signed-off-by: Travis Ralston --- src/components/views/rooms/RoomSettings.js | 15 ++++++++++++++- src/i18n/strings/en_EN.json | 5 +++++ src/i18n/strings/en_US.json | 5 +++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index 942da9ba06..412f67fc23 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -35,6 +35,16 @@ function parseIntWithDefault(val, def) { return isNaN(res) ? def : res; } +const plEventsToLabels = { + // These will be translated for us later. + // TODO: _td() these when https://github.com/matrix-org/matrix-react-sdk/pull/1421 lands + "m.room.avatar": "To change the room's avatar, you must be a", + "m.room.name": "To change the room's name, you must be a", + "m.room.canonical_alias": "To change the room's main address, you must be a", + "m.room.history_visibility": "To change the room's history visibility, you must be a", + "m.room.power_levels": "To change the permissions in the room, you must be a", +}; + const BannedUser = React.createClass({ propTypes: { canUnban: React.PropTypes.bool, @@ -885,9 +895,12 @@ module.exports = React.createClass({ {Object.keys(events_levels).map(function(event_type, i) { + let label = plEventsToLabels[event_type]; + if (label) label = _t(label); + else label = _tJsx("To send events of type , you must be a", //, () => { event_type }); return (
- { _tJsx("To send events of type , you must be a", //, () => { event_type }) } + { label }
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 8873b54091..6309e60e82 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -832,6 +832,11 @@ "To ban users, you must be a": "To ban users, you must be a", "To remove other users' messages, you must be a": "To remove other users' messages, you must be a", "To send events of type , you must be a": "To send events of type , you must be a", + "To change the room's avatar, you must be a": "To change the room's avatar, you must be a", + "To change the room's name, you must be a": "To change the room's name, you must be a", + "To change the room's main address, you must be a": "To change the room's main address, you must be a", + "To change the room's history visibility, you must be a": "To change the room's history visibility, you must be a", + "To change the permissions in the room, you must be a": "To change the permissions in the room, you must be a", "Error whilst fetching joined groups": "Error whilst fetching joined groups", "Featured Users:": "Featured Users:", "Edit Group": "Edit Group", diff --git a/src/i18n/strings/en_US.json b/src/i18n/strings/en_US.json index c3b3b6a1bc..7f99f7789c 100644 --- a/src/i18n/strings/en_US.json +++ b/src/i18n/strings/en_US.json @@ -656,6 +656,11 @@ "To ban users, you must be a": "To ban users, you must be a", "To remove other users' messages, you must be a": "To remove other users' messages, you must be a", "To send events of type , you must be a": "To send events of type , you must be a", + "To change the room's avatar, you must be a": "To change the room's avatar, you must be a", + "To change the room's name, you must be a": "To change the room's name, you must be a", + "To change the room's main address, you must be a": "To change the room's main address, you must be a", + "To change the room's history visibility, you must be a": "To change the room's history visibility, you must be a", + "To change the permissions in the room, you must be a": "To change the permissions in the room, you must be a", "This Home Server would like to make sure you are not a robot": "This Home Server would like to make sure you are not a robot", "Sign in with CAS": "Sign in with CAS", "Custom Server Options": "Custom Server Options", From 8ab3d94c1ce3b972a77da331d910189256503996 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 29 Sep 2017 15:11:48 -0600 Subject: [PATCH 045/123] Always show common events in the PL section of room settings Signed-off-by: Travis Ralston --- src/components/views/rooms/RoomSettings.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index 412f67fc23..59b05dc4ac 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -45,6 +45,15 @@ const plEventsToLabels = { "m.room.power_levels": "To change the permissions in the room, you must be a", }; +const plEventsToShow = { + // If an event is listed here, it will be shown in the PL settings. Defaults will be calculated. + "m.room.avatar": {isState: true}, + "m.room.name": {isState: true}, + "m.room.canonical_alias": {isState: true}, + "m.room.history_visibility": {isState: true}, + "m.room.power_levels": {isState: true}, +} + const BannedUser = React.createClass({ propTypes: { canUnban: React.PropTypes.bool, @@ -556,6 +565,14 @@ module.exports = React.createClass({ this.forceUpdate(); }, + _populateDefaultPlEvents: function(eventsSection, stateLevel, eventsLevel) { + for (let desiredEvent of Object.keys(plEventsToShow)) { + if (!(desiredEvent in eventsSection)) { + eventsSection[desiredEvent] = (plEventsToShow[desiredEvent].isState ? stateLevel : eventsLevel); + } + } + }, + _renderEncryptionSection: function() { var cli = MatrixClientPeg.get(); var roomState = this.props.room.currentState; @@ -626,6 +643,8 @@ module.exports = React.createClass({ var state_level = power_level_event ? parseIntWithDefault(power_levels.state_default, 50) : 0; var default_user_level = parseIntWithDefault(power_levels.users_default, 0); + this._populateDefaultPlEvents(events_levels, state_level, send_level); + var current_user_level = user_levels[user_id]; if (current_user_level === undefined) { current_user_level = default_user_level; From 8ee9d39ffa19adb7182d8e61a9831bf2975cea52 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 29 Sep 2017 15:12:05 -0600 Subject: [PATCH 046/123] Expose option for m.room.topic power level Signed-off-by: Travis Ralston --- src/components/views/rooms/RoomSettings.js | 2 ++ src/i18n/strings/en_EN.json | 1 + src/i18n/strings/en_US.json | 1 + 3 files changed, 4 insertions(+) diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index 59b05dc4ac..f1dcfbfc64 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -43,6 +43,7 @@ const plEventsToLabels = { "m.room.canonical_alias": "To change the room's main address, you must be a", "m.room.history_visibility": "To change the room's history visibility, you must be a", "m.room.power_levels": "To change the permissions in the room, you must be a", + "m.room.topic": "To change the topic, you must be a", }; const plEventsToShow = { @@ -52,6 +53,7 @@ const plEventsToShow = { "m.room.canonical_alias": {isState: true}, "m.room.history_visibility": {isState: true}, "m.room.power_levels": {isState: true}, + "m.room.topic": {isState: true}, } const BannedUser = React.createClass({ diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 6309e60e82..ee1bed814a 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -837,6 +837,7 @@ "To change the room's main address, you must be a": "To change the room's main address, you must be a", "To change the room's history visibility, you must be a": "To change the room's history visibility, you must be a", "To change the permissions in the room, you must be a": "To change the permissions in the room, you must be a", + "To change the topic, you must be a": "To change the topic, you must be a", "Error whilst fetching joined groups": "Error whilst fetching joined groups", "Featured Users:": "Featured Users:", "Edit Group": "Edit Group", diff --git a/src/i18n/strings/en_US.json b/src/i18n/strings/en_US.json index 7f99f7789c..a1dd9d53cc 100644 --- a/src/i18n/strings/en_US.json +++ b/src/i18n/strings/en_US.json @@ -661,6 +661,7 @@ "To change the room's main address, you must be a": "To change the room's main address, you must be a", "To change the room's history visibility, you must be a": "To change the room's history visibility, you must be a", "To change the permissions in the room, you must be a": "To change the permissions in the room, you must be a", + "To change the topic, you must be a": "To change the topic, you must be a", "This Home Server would like to make sure you are not a robot": "This Home Server would like to make sure you are not a robot", "Sign in with CAS": "Sign in with CAS", "Custom Server Options": "Custom Server Options", From 20798dd2fa161d4e24229ef0f8fbf33e3ac08e06 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 29 Sep 2017 15:22:37 -0600 Subject: [PATCH 047/123] Expose power level setting for widgets Fixes https://github.com/vector-im/riot-web/issues/4866 Signed-off-by: Travis Ralston --- src/components/views/rooms/RoomSettings.js | 4 ++++ src/i18n/strings/en_EN.json | 1 + src/i18n/strings/en_US.json | 1 + 3 files changed, 6 insertions(+) diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index f1dcfbfc64..e3fe50713b 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -44,6 +44,8 @@ const plEventsToLabels = { "m.room.history_visibility": "To change the room's history visibility, you must be a", "m.room.power_levels": "To change the permissions in the room, you must be a", "m.room.topic": "To change the topic, you must be a", + + "im.vector.modular.widgets": "To modify widgets in the room, you must be a", }; const plEventsToShow = { @@ -54,6 +56,8 @@ const plEventsToShow = { "m.room.history_visibility": {isState: true}, "m.room.power_levels": {isState: true}, "m.room.topic": {isState: true}, + + "im.vector.modular.widgets": {isState: true}, } const BannedUser = React.createClass({ diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index ee1bed814a..792626ca7c 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -838,6 +838,7 @@ "To change the room's history visibility, you must be a": "To change the room's history visibility, you must be a", "To change the permissions in the room, you must be a": "To change the permissions in the room, you must be a", "To change the topic, you must be a": "To change the topic, you must be a", + "To modify widgets in the room, you must be a": "To modify widgets in the room, you must be a", "Error whilst fetching joined groups": "Error whilst fetching joined groups", "Featured Users:": "Featured Users:", "Edit Group": "Edit Group", diff --git a/src/i18n/strings/en_US.json b/src/i18n/strings/en_US.json index a1dd9d53cc..8a78a18407 100644 --- a/src/i18n/strings/en_US.json +++ b/src/i18n/strings/en_US.json @@ -662,6 +662,7 @@ "To change the room's history visibility, you must be a": "To change the room's history visibility, you must be a", "To change the permissions in the room, you must be a": "To change the permissions in the room, you must be a", "To change the topic, you must be a": "To change the topic, you must be a", + "To modify widgets in the room, you must be a": "To modify widgets in the room, you must be a", "This Home Server would like to make sure you are not a robot": "This Home Server would like to make sure you are not a robot", "Sign in with CAS": "Sign in with CAS", "Custom Server Options": "Custom Server Options", From b202601d650d981103fee66be869c47506a407d1 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 2 Oct 2017 15:10:32 +0100 Subject: [PATCH 048/123] Fix showing 3pid invites in member list --- src/components/views/rooms/MemberList.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/rooms/MemberList.js b/src/components/views/rooms/MemberList.js index 86d44f29d6..d1b456025f 100644 --- a/src/components/views/rooms/MemberList.js +++ b/src/components/views/rooms/MemberList.js @@ -372,7 +372,7 @@ module.exports = React.createClass({ }, _getChildrenInvited: function(start, end) { - return this._makeMemberTiles(this.state.filteredInvitedMembers.slice(start, end)); + return this._makeMemberTiles(this.state.filteredInvitedMembers.slice(start, end), 'invite'); }, _getChildCountInvited: function() { From 4361953d6d28091d623361bd4385d9e4e857f2dc Mon Sep 17 00:00:00 2001 From: Silke Date: Sat, 30 Sep 2017 09:37:11 +0000 Subject: [PATCH 049/123] Translated using Weblate (Dutch) Currently translated at 100.0% (855 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/nl/ --- src/i18n/strings/nl.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index fff3aaa4a5..88557516ed 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -108,7 +108,7 @@ "Drop here %(toAction)s": "%(toAction)s hier naartoe verplaatsen", "Error": "Fout", "Failed to forget room %(errCode)s": "Ruimte vergeten mislukt %(errCode)s", - "Failed to join the room": "Kamer binnengaan mislukt", + "Failed to join the room": "Ruimte toetreden mislukt", "Favourite": "Favoriet", "Mute": "Dempen", "Notifications": "Meldingen", From 3e34a460a411935ed994c469b8e87e6fa8b2f6d4 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 3 Oct 2017 10:06:18 +0100 Subject: [PATCH 050/123] Add error dialog for when removing room fails --- src/components/views/groups/GroupRoomTile.js | 34 +++++++++++++++----- src/i18n/strings/en_EN.json | 4 ++- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/components/views/groups/GroupRoomTile.js b/src/components/views/groups/GroupRoomTile.js index 1081890f40..eeba9d6d8a 100644 --- a/src/components/views/groups/GroupRoomTile.js +++ b/src/components/views/groups/GroupRoomTile.js @@ -21,6 +21,7 @@ import PropTypes from 'prop-types'; import sdk from '../../../index'; import dis from '../../../dispatcher'; import { GroupRoomType } from '../../../groups'; +import Modal from '../../../Modal'; const GroupRoomTile = React.createClass({ displayName: 'GroupRoomTile', @@ -31,7 +32,19 @@ const GroupRoomTile = React.createClass({ }, getInitialState: function() { - return {}; + return { + name: this.calculateRoomName(this.props.groupRoom), + }; + }, + + componentWillReceiveProps: function(newProps) { + this.setState({ + name: this.calculateRoomName(newProps.groupRoom), + }); + }, + + calculateRoomName: function(groupRoom) { + return groupRoom.name || groupRoom.canonicalAlias || _t("Unnamed Room"); }, onClick: function(e) { @@ -52,24 +65,29 @@ const GroupRoomTile = React.createClass({ onDeleteClick: function(e) { e.preventDefault(); e.stopPropagation(); + const groupId = this.props.groupId; + const roomName = this.state.name; this.context.matrixClient - .removeRoomFromGroup(this.props.groupId, this.props.groupRoom.roomId); + .removeRoomFromGroup(groupId, this.props.groupRoom.roomId) + .catch((err) => { + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + Modal.createTrackedDialog('Failed to remove room from group', '', ErrorDialog, { + title: _t("Failed to remove room from group"), + description: _t("Failed to remove '%(roomName)s' from %(groupId)s", {groupId, roomName}), + }); + }); }, render: function() { const BaseAvatar = sdk.getComponent('avatars.BaseAvatar'); const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); - - const name = this.props.groupRoom.name || - this.props.groupRoom.canonicalAlias || - _t("Unnamed Room"); const avatarUrl = this.context.matrixClient.mxcUrlToHttp( this.props.groupRoom.avatarUrl, 36, 36, 'crop', ); const av = ( - @@ -81,7 +99,7 @@ const GroupRoomTile = React.createClass({ { av }
- { name } + { this.state.name }
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 87fd6d4364..10e135fc6e 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -895,5 +895,7 @@ "Matrix Room ID": "Matrix Room ID", "email address": "email address", "Try using one of the following valid address types: %(validTypesList)s.": "Try using one of the following valid address types: %(validTypesList)s.", - "You have entered an invalid address.": "You have entered an invalid address." + "You have entered an invalid address.": "You have entered an invalid address.", + "Failed to remove room from group": "Failed to remove room from group", + "Failed to remove '%(roomName)s' from %(groupId)s": "Failed to remove '%(roomName)s' from %(groupId)s" } From 0116c4b48681a9ba90348010d7691befcdbcf386 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 3 Oct 2017 10:14:08 +0100 Subject: [PATCH 051/123] Log the error when failing to removie room from group --- src/components/views/groups/GroupRoomTile.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/views/groups/GroupRoomTile.js b/src/components/views/groups/GroupRoomTile.js index eeba9d6d8a..ea8b5b9993 100644 --- a/src/components/views/groups/GroupRoomTile.js +++ b/src/components/views/groups/GroupRoomTile.js @@ -67,9 +67,11 @@ const GroupRoomTile = React.createClass({ e.stopPropagation(); const groupId = this.props.groupId; const roomName = this.state.name; + const roomId = this.props.groupRoom.roomId; this.context.matrixClient - .removeRoomFromGroup(groupId, this.props.groupRoom.roomId) + .removeRoomFromGroup(groupId, roomId) .catch((err) => { + console.error(`Error whilst removing ${roomId} from ${groupId}`, err); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); Modal.createTrackedDialog('Failed to remove room from group', '', ErrorDialog, { title: _t("Failed to remove room from group"), From 6b834bc72e5bd073e572928e3aa8c0ed3e533123 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 3 Oct 2017 11:16:22 +0100 Subject: [PATCH 052/123] Add confirmation dialog for removing room from group --- src/components/views/groups/GroupRoomTile.js | 42 ++++++++++++++------ src/i18n/strings/en_EN.json | 4 +- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/components/views/groups/GroupRoomTile.js b/src/components/views/groups/GroupRoomTile.js index ea8b5b9993..b6bdb9735b 100644 --- a/src/components/views/groups/GroupRoomTile.js +++ b/src/components/views/groups/GroupRoomTile.js @@ -47,6 +47,22 @@ const GroupRoomTile = React.createClass({ return groupRoom.name || groupRoom.canonicalAlias || _t("Unnamed Room"); }, + removeRoomFromGroup: function() { + const groupId = this.props.groupId; + const roomName = this.state.name; + const roomId = this.props.groupRoom.roomId; + this.context.matrixClient + .removeRoomFromGroup(groupId, roomId) + .catch((err) => { + console.error(`Error whilst removing ${roomId} from ${groupId}`, err); + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + Modal.createTrackedDialog('Failed to remove room from group', '', ErrorDialog, { + title: _t("Failed to remove room from group"), + description: _t("Failed to remove '%(roomName)s' from %(groupId)s", {groupId, roomName}), + }); + }); + }, + onClick: function(e) { let roomId; let roomAlias; @@ -63,21 +79,21 @@ const GroupRoomTile = React.createClass({ }, onDeleteClick: function(e) { - e.preventDefault(); - e.stopPropagation(); const groupId = this.props.groupId; const roomName = this.state.name; - const roomId = this.props.groupRoom.roomId; - this.context.matrixClient - .removeRoomFromGroup(groupId, roomId) - .catch((err) => { - console.error(`Error whilst removing ${roomId} from ${groupId}`, err); - const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createTrackedDialog('Failed to remove room from group', '', ErrorDialog, { - title: _t("Failed to remove room from group"), - description: _t("Failed to remove '%(roomName)s' from %(groupId)s", {groupId, roomName}), - }); - }); + e.preventDefault(); + e.stopPropagation(); + const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); + Modal.createTrackedDialog('Confirm removal of group from room', '', QuestionDialog, { + title: _t("Are you sure you want to remove '%(roomName)s' from %(groupId)s?", {roomName, groupId}), + description: _t("Removing a room from the group will also remove it from the group page."), + button: _t("Remove"), + onFinished: (success) => { + if (success) { + this.removeRoomFromGroup(); + } + }, + }); }, render: function() { diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 10e135fc6e..bc377d8359 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -897,5 +897,7 @@ "Try using one of the following valid address types: %(validTypesList)s.": "Try using one of the following valid address types: %(validTypesList)s.", "You have entered an invalid address.": "You have entered an invalid address.", "Failed to remove room from group": "Failed to remove room from group", - "Failed to remove '%(roomName)s' from %(groupId)s": "Failed to remove '%(roomName)s' from %(groupId)s" + "Failed to remove '%(roomName)s' from %(groupId)s": "Failed to remove '%(roomName)s' from %(groupId)s", + "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Are you sure you want to remove '%(roomName)s' from %(groupId)s?", + "Removing a room from the group will also remove it from the group page.": "Removing a room from the group will also remove it from the group page." } From fa0a87ae398e2bad81d0f7a6fa69e1b8f0556cee Mon Sep 17 00:00:00 2001 From: Pitchaya Boonsarngsuk Date: Mon, 2 Oct 2017 14:35:15 +0000 Subject: [PATCH 053/123] Translated using Weblate (Thai) Currently translated at 61.4% (525 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/th/ --- src/i18n/strings/th.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/th.json b/src/i18n/strings/th.json index b7d2140f60..9a484dfd1a 100644 --- a/src/i18n/strings/th.json +++ b/src/i18n/strings/th.json @@ -226,7 +226,7 @@ "Markdown is enabled": "เปิดใช้งาน Markdown แล้ว", "Missing user_id in request": "ไม่พบ user_id ในคำขอ", "Moderator": "ผู้ช่วยดูแล", - "my Matrix ID": "Matrix ID ของฉัน", + "my Matrix ID": "ID Matrix ของฉัน", "New address (e.g. #foo:%(localDomain)s)": "ที่อยู่ใหม่ (เช่น #foo:%(localDomain)s)", "New password": "รหัสผ่านใหม่", "New passwords don't match": "รหัสผ่านใหม่ไม่ตรงกัน", @@ -457,7 +457,7 @@ "This allows you to use this app with an existing Matrix account on a different home server.": "ทั้งนี่เพื่อให้คุณสามารถใช้ Riot กับบัญชี Matrix ที่มีอยู่แล้วบนเซิร์ฟเวอร์บ้านอื่น ๆ ได้", "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "คุณอาจเลือกเซิร์ฟเวอร์ระบุตัวตนเองด้วยก็ได้ แต่คุณจะไม่สามารถเชิญผู้ใช้อื่นด้วยที่อยู่อีเมล หรือรับคำเชิญจากผู้ใช้อื่นทางที่อยู่อีเมลได้", "Default server": "เซิร์ฟเวอร์เริ่มต้น", - "Custom server": "เซิร์ฟเวอร์ที่กำหนดเอง", + "Custom server": "กำหนดเซิร์ฟเวอร์เอง", "Home server URL": "URL เซิร์ฟเวอร์บ้าน", "Identity server URL": "URL เซิร์ฟเวอร์ระบุตัวตน", "%(severalUsers)sleft %(repeats)s times": "%(severalUsers)sออกจากห้อง %(repeats)s ครั้ง", From 8243c39d830bfc6366fbe68b2856ea2c2277c29b Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 4 Oct 2017 10:00:01 +0100 Subject: [PATCH 054/123] Factor out EditableItemList from AliasSettings Such that we can reuse the same UI elsewhere, namely when editing related groups of a room (which is an upcoming feature). --- .../views/elements/EditableItemList.js | 162 ++++++++++++++++++ .../views/room_settings/AliasSettings.js | 116 +++++-------- 2 files changed, 204 insertions(+), 74 deletions(-) create mode 100644 src/components/views/elements/EditableItemList.js diff --git a/src/components/views/elements/EditableItemList.js b/src/components/views/elements/EditableItemList.js new file mode 100644 index 0000000000..1d269f26e2 --- /dev/null +++ b/src/components/views/elements/EditableItemList.js @@ -0,0 +1,162 @@ +/* +Copyright 2017 New Vector Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import React from 'react'; +import PropTypes from 'prop-types'; +import sdk from '../../../index'; +import {_t} from '../../../languageHandler.js'; + +const EditableItem = React.createClass({ + displayName: 'EditableItem', + + propTypes: { + initialValue: PropTypes.string, + index: PropTypes.number, + placeholder: PropTypes.string, + + onChange: PropTypes.func, + onRemove: PropTypes.func, + onAdd: PropTypes.func, + }, + + onChange: function(value) { + this.setState({ value }); + if (this.props.onChange) this.props.onChange(value, this.props.index); + }, + + onRemove: function() { + this.props.onRemove(this.props.index); + }, + + onAdd: function() { + this.props.onAdd(this.state.value); + }, + + render: function() { + const EditableText = sdk.getComponent('elements.EditableText'); + return
+ + { this.props.onAdd ? +
+ {_t("Add")} +
+ : +
+ {_t("Delete")} +
+ } +
; + }, +}); + +module.exports = React.createClass({ + displayName: 'EditableItemList', + + propTypes: { + items: PropTypes.arrayOf(PropTypes.string).isRequired, + onNewItemChanged: PropTypes.func, + onItemAdded: PropTypes.func, + onItemEdited: PropTypes.func, + onItemRemoved: PropTypes. func, + }, + + getDefaultProps: function() { + return { + onItemAdded: () => {}, + onItemEdited: () => {}, + onItemRemoved: () => {}, + }; + }, + + getInitialState: function() { + return {}; + }, + + componentWillReceiveProps: function(nextProps) { + }, + + componentWillMount: function() { + }, + + componentDidMount: function() { + }, + + onItemAdded: function(value) { + console.info('onItemAdded', value); + this.props.onItemAdded(value); + }, + + onItemEdited: function(value, index) { + console.info('onItemEdited', value, index); + if (value.length === 0) { + this.onItemRemoved(index); + } else { + this.onItemEdited(value, index); + } + }, + + onItemRemoved: function(index) { + console.info('onItemRemoved', index); + this.props.onItemRemoved(index); + }, + + onNewItemChanged: function(value) { + this.props.onNewItemChanged(value); + }, + + render: function() { + const editableItems = this.props.items.map((item, index) => { + return ; + }); + + const label = this.props.items.length > 0 ? + this.props.itemsLabel : this.props.noItemsLabel; + + console.info('New item:', this.props.newItem); + + return (
+
+ { label } +
+ { editableItems } + +
); + }, +}); diff --git a/src/components/views/room_settings/AliasSettings.js b/src/components/views/room_settings/AliasSettings.js index f37bd4271a..8a6abec35d 100644 --- a/src/components/views/room_settings/AliasSettings.js +++ b/src/components/views/room_settings/AliasSettings.js @@ -136,24 +136,25 @@ module.exports = React.createClass({ return ObjectUtils.getKeyValueArrayDiffs(oldAliases, this.state.domainToAliases); }, - onAliasAdded: function(alias) { + onNewAliasChanged: function(value) { + this.setState({newAlias: value}); + }, + + onLocalAliasAdded: function(alias) { if (!alias || alias.length === 0) return; // ignore attempts to create blank aliases - if (this.isAliasValid(alias)) { - // add this alias to the domain to aliases dict - var domain = alias.replace(/^.*?:/, ''); - // XXX: do we need to deep copy aliases before editing it? - this.state.domainToAliases[domain] = this.state.domainToAliases[domain] || []; - this.state.domainToAliases[domain].push(alias); - this.setState({ - domainToAliases: this.state.domainToAliases - }); + const localDomain = MatrixClientPeg.get().getDomain(); + if (this.isAliasValid(alias) && alias.endsWith(localDomain)) { + this.state.domainToAliases[localDomain] = this.state.domainToAliases[localDomain] || []; + this.state.domainToAliases[localDomain].push(alias); - // reset the add field - this.refs.add_alias.setValue(''); // FIXME - } - else { - var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + this.setState({ + domainToAliases: this.state.domainToAliases, + // Reset the add field + newAlias: "", + }); + } else { + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); Modal.createTrackedDialog('Invalid alias format', '', ErrorDialog, { title: _t('Invalid alias format'), description: _t('\'%(alias)s\' is not a valid format for an alias', { alias: alias }), @@ -161,15 +162,13 @@ module.exports = React.createClass({ } }, - onAliasChanged: function(domain, index, alias) { + onLocalAliasChanged: function(alias, index) { if (alias === "") return; // hit the delete button to delete please - var oldAlias; - if (this.isAliasValid(alias)) { - oldAlias = this.state.domainToAliases[domain][index]; - this.state.domainToAliases[domain][index] = alias; - } - else { - var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + const localDomain = MatrixClientPeg.get().getDomain(); + if (this.isAliasValid(alias) && alias.endsWith(localDomain)) { + this.state.domainToAliases[localDomain][index] = alias; + } else { + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); Modal.createTrackedDialog('Invalid address format', '', ErrorDialog, { title: _t('Invalid address format'), description: _t('\'%(alias)s\' is not a valid format for an address', { alias: alias }), @@ -177,15 +176,16 @@ module.exports = React.createClass({ } }, - onAliasDeleted: function(domain, index) { + onLocalAliasDeleted: function(index) { + const localDomain = MatrixClientPeg.get().getDomain(); // It's a bit naughty to directly manipulate this.state, and React would // normally whine at you, but it can't see us doing the splice. Given we // promptly setState anyway, it's just about acceptable. The alternative // would be to arbitrarily deepcopy to a temp variable and then setState // that, but why bother when we can cut this corner. - var alias = this.state.domainToAliases[domain].splice(index, 1); + this.state.domainToAliases[localDomain].splice(index, 1); this.setState({ - domainToAliases: this.state.domainToAliases + domainToAliases: this.state.domainToAliases, }); }, @@ -198,6 +198,7 @@ module.exports = React.createClass({ render: function() { var self = this; var EditableText = sdk.getComponent("elements.EditableText"); + var EditableItemList = sdk.getComponent("elements.EditableItemList"); var localDomain = MatrixClientPeg.get().getDomain(); var canonical_alias_section; @@ -257,58 +258,25 @@ module.exports = React.createClass({
{ _t('The main address for this room is') }: { canonical_alias_section }
-
- { (this.state.domainToAliases[localDomain] && - this.state.domainToAliases[localDomain].length > 0) - ? _t('Local addresses for this room:') - : _t('This room has no local addresses') } -
-
- { (this.state.domainToAliases[localDomain] || []).map((alias, i) => { - var deleteButton; - if (this.props.canSetAliases) { - deleteButton = ( - { - ); - } - return ( -
- -
- { deleteButton } -
-
- ); - })} - { this.props.canSetAliases ? -
- -
- Add -
-
: "" - } -
+ { remote_aliases_section } ); - } + }, }); From 00a89f8263ca68abb4c89698bc7a7150677b5812 Mon Sep 17 00:00:00 2001 From: Danilo Resende Date: Tue, 3 Oct 2017 22:14:16 +0000 Subject: [PATCH 055/123] Translated using Weblate (Portuguese (Brazil)) Currently translated at 92.3% (790 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/pt_BR/ --- src/i18n/strings/pt_BR.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/pt_BR.json b/src/i18n/strings/pt_BR.json index a52281c7c6..ad2811074b 100644 --- a/src/i18n/strings/pt_BR.json +++ b/src/i18n/strings/pt_BR.json @@ -772,7 +772,7 @@ "Create new room": "Criar nova sala", "Welcome page": "Página de boas vindas", "Room directory": "Lista pública de salas", - "Start chat": "Iniciar conversa pessoal", + "Start chat": "Iniciar conversa", "New Password": "Nova senha", "Start chatting": "Iniciar a conversa", "Start Chatting": "Iniciar a conversa", From a9a2b60dfc80dbaaca09d13bcf0cd3640e79df5a Mon Sep 17 00:00:00 2001 From: Walter Date: Tue, 3 Oct 2017 12:35:30 +0000 Subject: [PATCH 056/123] Translated using Weblate (Russian) Currently translated at 100.0% (855 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 48 ++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 48a070f066..8f317031be 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -3,7 +3,7 @@ "accepted an invitation": "принял приглашение", "accepted the invitation for": "принял приглашение на", "Account": "Аккаунт", - "Add email address": "Добавить адрес электронной почты", + "Add email address": "Добавить адрес эл. почты", "Add phone number": "Добавить номер телефона", "Admin": "Администратор", "Advanced": "Дополнительно", @@ -79,7 +79,7 @@ "Failed to forget room": "Не удалось забыть комнату", "Failed to leave room": "Не удалось выйти из комнаты", "Failed to reject invitation": "Не удалось отклонить приглашение", - "Failed to send email": "Ошибка отправки электронной почты", + "Failed to send email": "Ошибка отправки эл. почты", "Failed to unban": "Не удалось разблокировать", "Failed to upload file": "Не удалось отправить файл", "Favourite": "Избранное", @@ -95,9 +95,9 @@ "Historical": "Архив", "Homeserver is": "Домашний сервер это", "Identity Server is": "Сервер идентификации это", - "I have verified my email address": "Я подтвердил свой адрес электронной почты", + "I have verified my email address": "Я подтвердил свой адрес эл. почты", "Import E2E room keys": "Импорт ключей сквозного шифрования", - "Invalid Email Address": "Недопустимый адрес электронной почты", + "Invalid Email Address": "Недопустимый адрес эл. почты", "invited": "invited", "Invite new room members": "Пригласить новых участников в комнату", "Invites": "Приглашает", @@ -165,9 +165,9 @@ "To send events of type": "Чтобы отправить тип события", "To send messages": "Чтобы отправить сообщения", "turned on end-to-end encryption (algorithm": "turned on end-to-end encryption (algorithm", - "Unable to add email address": "Не удается добавить адрес электронной почты", + "Unable to add email address": "Не удается добавить адрес эл. почты", "Unable to remove contact information": "Не удалось удалить контактную информацию", - "Unable to verify email address.": "Не удалось проверить адрес электронной почты.", + "Unable to verify email address.": "Не удалось проверить адрес эл. почты.", "Unban": "Разблокировать", "Unencrypted room": "Незашифрованная комната", "unencrypted": "без шифрования", @@ -239,7 +239,7 @@ "Failed to lookup current room": "Не удалось выполнить поиск текущий комнаты", "Failed to send request.": "Не удалось отправить запрос.", "Failed to set up conference call": "Не удалось настроить групповой вызов", - "Failed to verify email address: make sure you clicked the link in the email": "Не удалось проверить адрес электронной почты: убедитесь, что вы перешли по ссылке в письме", + "Failed to verify email address: make sure you clicked the link in the email": "Не удалось проверить адрес эл. почты: убедитесь, что вы перешли по ссылке в письме", "Failure to create room": "Не удалось создать комнату", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s с %(fromPowerLevel)s на %(toPowerLevel)s", "Guest users can't create new rooms. Please register to create room and start a chat.": "Гости не могут создавать новые комнаты. Зарегистрируйтесь, чтобы создать комнату и начать чат.", @@ -267,7 +267,7 @@ "Set a display name:": "Введите отображаемое имя:", "Passwords don't match.": "Пароли не совпадают.", "Password too short (min %(MIN_PASSWORD_LENGTH)s).": "Пароль слишком короткий (мин. %(MIN_PASSWORD_LENGTH)s).", - "This doesn't look like a valid email address.": "Это не похоже на допустимый адрес электронной почты.", + "This doesn't look like a valid email address.": "Это не похоже на допустимый адрес эл. почты.", "This server does not support authentication with a phone number.": "Этот сервер не поддерживает аутентификацию с помощью номера телефона.", "User names may only contain letters, numbers, dots, hyphens and underscores.": "Имена пользователей могут содержать только буквы, цифры, точки, дефисы и символы подчеркивания.", "An unknown error occurred.": "Произошла неизвестная ошибка.", @@ -314,7 +314,7 @@ "Thu": "Чт", "Fri": "Пт", "Sat": "Сб", - "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Ваш адрес электронной почты, кажется, не связан с Matrix ID на этом домашнем сервере.", + "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Ваш адрес эл. почты, кажется, не связан с Matrix ID на этом домашнем сервере.", "to start a chat with someone": "чтобы начать чат с кем-то", "to tag direct chat": "отметить прямой чат", "To use it, just wait for autocomplete results to load and tab through them.": "Для того, чтобы использовать эту функцию, просто подождите автозаполнения результатов, а затем используйте клавишу TAB для прокрутки.", @@ -366,7 +366,7 @@ "Command error": "Ошибка команды", "Confirm password": "Подтвердите пароль", "Current password": "Текущий пароль", - "Email": "Электронная почта", + "Email": "Эл. почта", "Failed to kick": "Не удалось выгнать", "Failed to load timeline position": "Не удалось загрузить метку из хронологии", "Failed to mute user": "Не удалось заглушить пользователя", @@ -452,15 +452,15 @@ "The default role for new room members is": "Роль по умолчанию для новых участников комнаты", "The main address for this room is": "Основной адрес для этой комнаты", "This action cannot be performed by a guest user. Please register to be able to do this.": "Это действие не может быть выполнено гостем. Пожалуйста, зарегистрируйтесь, чтобы получить возможность сделать то что вы хотите.", - "This email address is already in use": "Этот адрес электронной почты уже используется", - "This email address was not found": "Этот адрес электронной почты не найден", - "The email address linked to your account must be entered.": "Необходимо ввести адрес электронной почты, связанный с вашей учетной записью.", + "This email address is already in use": "Этот адрес эл. почты уже используется", + "This email address was not found": "Этот адрес эл. почты не найден", + "The email address linked to your account must be entered.": "Необходимо ввести адрес эл. почты, связанный с вашей учетной записью.", "The file '%(fileName)s' failed to upload": "Не удалось отправить файл '%(fileName)s'", "The remote side failed to pick up": "Вызываемый абонент не ответил", "This room has no local addresses": "В этой комнате нет локальных адресов", "This room is not recognised.": "Эта комната не опознана.", "These are experimental features that may break in unexpected ways": "Это экспериментальные функции, которые могут себя вести неожиданным образом", - "This doesn't appear to be a valid email address": "Похоже, это недействительный адрес электронной почты", + "This doesn't appear to be a valid email address": "Похоже, это недействительный адрес эл. почты", "This is a preview of this room. Room interactions have been disabled": "Это предпросмотр комнаты. Взаимодействие с комнатой отключено", "This phone number is already in use": "Этот номер телефона уже используется", "This room's internal ID is": "Внутренний ID этой комнаты", @@ -567,8 +567,8 @@ "Device key:": "Ключ устройства:", "disabled": "отключено", "Disable markdown formatting": "Отключить Markdown-форматирование", - "Email address": "Адрес электронной почты", - "Email address (optional)": "Адрес электронной почты (необязательно)", + "Email address": "Адрес эл. почты", + "Email address (optional)": "Адрес эл. почты (необязательно)", "enabled": "включено", "Error decrypting attachment": "Ошибка при расшифровке вложения", "Export": "Экспорт", @@ -608,7 +608,7 @@ "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Предоставленный ключ подписи соответствует ключу, полученному от %(userId)s с устройства %(deviceId)s. Устройство помечено как проверенное.", "%(actionVerb)s this person?": "%(actionVerb)s этот человек?", "The file '%(fileName)s' exceeds this home server's size limit for uploads": "Файл '%(fileName)s' превышает предельный размер, допустимый к отправке на этом домашнем сервере", - "This Home Server does not support login using email address.": "Этот домашний сервер не поддерживает авторизацию с использованием адреса электронной почты.", + "This Home Server does not support login using email address.": "Этот домашний сервер не поддерживает авторизацию с использованием адреса эл. почты.", "There was a problem logging in.": "Возникла проблема при авторизации.", "The visibility of existing history will be unchanged": "Видимость существующей истории не изменится", "this invitation?": "это приглашение?", @@ -622,7 +622,7 @@ "To link to a room it must have": "Для создания ссылки на комнату она должна иметь", "to make a room or": "чтобы создать комнату или", "To remove other users' messages": "Чтобы удалить сообщения других пользователей", - "To reset your password, enter the email address linked to your account": "Чтобы сбросить пароль, введите адрес электронной почты, связанный с вашей учетной записью", + "To reset your password, enter the email address linked to your account": "Чтобы сбросить пароль, введите адрес эл. почты, связанный с вашей учетной записью", "to tag as %(tagName)s": "пометить как %(tagName)s", "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Попытка загрузить выбранный интервал истории чата этой комнаты не удалась, так как у вас нет разрешений на просмотр.", "Tried to load a specific point in this room's timeline, but was unable to find it.": "Попытка загрузить выбранный интервал истории чата этой комнаты не удалась, так как запрошенный элемент не найден.", @@ -636,7 +636,7 @@ "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "ВНИМАНИЕ: ОШИБКА ПРОВЕРКИ КЛЮЧЕЙ! Ключ подписи пользователя %(userId)s на устройстве %(deviceId)s — \"%(fprint)s\", и он не соответствует предоставленному ключу \"%(fingerprint)s\". Это может означать, что ваше общение перехватывается!", "You have disabled URL previews by default.": "Предварительный просмотр ссылок отключен по-умолчанию.", "You have enabled URL previews by default.": "Предварительный просмотр ссылок включен по-умолчанию.", - "You have entered an invalid contact. Try using their Matrix ID or email address.": "Вы ввели недопустимый контакт. Попробуйте использовать Matrix ID или адрес электронной почты.", + "You have entered an invalid contact. Try using their Matrix ID or email address.": "Вы ввели недопустимый контакт. Попробуйте использовать Matrix ID или адрес эл. почты.", "You need to enter a user name.": "Необходимо ввести имя пользователя.", "You seem to be in a call, are you sure you want to quit?": "Звонок не завершен, вы уверены, что хотите выйти?", "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Вы не сможете отменить это изменение, так как этот пользователь получит уровень доступа, аналогичный вашему.", @@ -699,12 +699,12 @@ "Sign in with CAS": "Войти с помощью CAS", "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "Вы можете использовать настраиваемые параметры сервера для входа на другие серверы Matrix, указав другой URL-адрес домашнего сервера.", "This allows you to use this app with an existing Matrix account on a different home server.": "Это позволяет использовать это приложение с существующей учетной записью Matrix на другом домашнем сервере.", - "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "Вы также можете установить другой сервер идентификации, но это, как правило, будет препятствовать взаимодействию с пользователями на основе адреса электронной почты.", + "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "Вы также можете установить другой сервер идентификации, но это, как правило, будет препятствовать взаимодействию с пользователями на основе адреса эл. почты.", "Please check your email to continue registration.": "Проверьте электронную почту, чтобы продолжить регистрацию.", "Token incorrect": "Неверный токен", "A text message has been sent to": "Текстовое сообщение отправлено", "Please enter the code it contains:": "Введите полученный код:", - "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Если адрес электронной почты не указан, сброс пароля будет невозможным. Уверены?", + "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Если адрес эл. почты не указан, сброс пароля будет невозможным. Уверены?", "You are registering with %(SelectedTeamName)s": "Вы регистрируетесь на %(SelectedTeamName)s", "Default server": "Сервер по умолчанию", "Custom server": "Пользовательский сервер", @@ -807,7 +807,7 @@ "Seen by %(userName)s at %(dateTime)s": "Просмотрено %(userName)s в %(dateTime)s", "Send anyway": "Отправить в любом случае", "Show Text Formatting Toolbar": "Показать панель инструментов форматирования текста", - "This invitation was sent to an email address which is not associated with this account:": "Это приглашение было отправлено на адрес электронной почты, не связанный с этой учетной записью:", + "This invitation was sent to an email address which is not associated with this account:": "Это приглашение было отправлено на адрес эл. почты, не связанный с этой учетной записью:", "To link to a room it must have an address.": "Чтобы связаться с комнатой, она должна иметь адрес.", "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Не удалось установить соответствует ли адрес, по которому этому приглашение было послано, вашей учетной записи.", "Undecryptable": "Невозможно расшифровать", @@ -824,7 +824,7 @@ "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.": "Не удается подключиться к домашнему серверу - проверьте подключение, убедитесь, что ваш SSL-сертификат домашнего сервера является доверенным и что расширение браузера не блокирует запросы.", "You have been banned from %(roomName)s by %(userName)s.": "%(userName)s заблокировал вас в %(roomName)s.", "You have been kicked from %(roomName)s by %(userName)s.": "%(userName)s выгнал вас из %(roomName)s.", - "You may wish to login with a different account, or add this email to this account.": "При желании вы можете войти в систему с другой учетной записью или добавить этот адрес электронной почты в эту учетную запись.", + "You may wish to login with a different account, or add this email to this account.": "При желании вы можете войти в систему с другой учетной записью или добавить этот адрес эл. почты в эту учетную запись.", "Your home server does not support device management.": "Ваш домашний сервер не поддерживает управление устройствами.", "(could not connect media)": "(подключение к СМИ не может быть установлено)", "(no answer)": "(нет ответа)", @@ -833,7 +833,7 @@ "Not a valid Riot keyfile": "Недействительный файл ключа Riot", "Your browser does not support the required cryptography extensions": "Ваш браузер не поддерживает требуемые криптографические расширения", "Authentication check failed: incorrect password?": "Ошибка аутентификации: неправильный пароль?", - "Do you want to set an email address?": "Хотите указать адрес электронной почты?", + "Do you want to set an email address?": "Хотите указать адрес эл. почты?", "This will allow you to reset your password and receive notifications.": "Это позволит при необходимости сбросить пароль и получать уведомления.", "Press to start a chat with someone": "Нажмите для начала чата с кем-либо", "You're not in any rooms yet! Press to make a room or to browse the directory": "Вы еще не вошли ни в одну из комнат! Нажмите , чтобы создать комнату или для просмотра каталога", From 5abf30f37358a3c39cd510c446a9846582fc92fd Mon Sep 17 00:00:00 2001 From: Walter Date: Tue, 3 Oct 2017 12:47:27 +0000 Subject: [PATCH 057/123] Translated using Weblate (Ukrainian) Currently translated at 13.6% (117 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/uk/ --- src/i18n/strings/uk.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/uk.json b/src/i18n/strings/uk.json index 27b36b8da5..25827a77db 100644 --- a/src/i18n/strings/uk.json +++ b/src/i18n/strings/uk.json @@ -110,5 +110,10 @@ "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s змінив(ла) рівень доступу для %(powerLevelDiffText)s.", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s змінив(ла) назву кімнати на %(roomName)s.", "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s видалив ім'я кімнати.", - "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s змінив тему на %(topic)s." + "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s змінив тему на %(topic)s.", + "Email": "е-почта", + "Email address": "Адреса е-почти", + "Email address (optional)": "Адреса е-почти (не обов'язково)", + "Email, name or matrix ID": "Е-почта, ім'я або matrix ID", + "Failed to send email": "Помилка відправки е-почти" } From d25ebfb8447385d53a37aaaaceca31798003808a Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 4 Oct 2017 10:15:44 +0100 Subject: [PATCH 058/123] Remove cruft from EIL --- .../views/elements/EditableItemList.js | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/src/components/views/elements/EditableItemList.js b/src/components/views/elements/EditableItemList.js index 1d269f26e2..6675e162c4 100644 --- a/src/components/views/elements/EditableItemList.js +++ b/src/components/views/elements/EditableItemList.js @@ -89,29 +89,15 @@ module.exports = React.createClass({ onItemAdded: () => {}, onItemEdited: () => {}, onItemRemoved: () => {}, + onNewItemChanged: () => {}, }; }, - getInitialState: function() { - return {}; - }, - - componentWillReceiveProps: function(nextProps) { - }, - - componentWillMount: function() { - }, - - componentDidMount: function() { - }, - onItemAdded: function(value) { - console.info('onItemAdded', value); this.props.onItemAdded(value); }, onItemEdited: function(value, index) { - console.info('onItemEdited', value, index); if (value.length === 0) { this.onItemRemoved(index); } else { @@ -120,7 +106,6 @@ module.exports = React.createClass({ }, onItemRemoved: function(index) { - console.info('onItemRemoved', index); this.props.onItemRemoved(index); }, @@ -143,8 +128,6 @@ module.exports = React.createClass({ const label = this.props.items.length > 0 ? this.props.itemsLabel : this.props.noItemsLabel; - console.info('New item:', this.props.newItem); - return (
{ label } From 407a632a8d51add81d4fd9df97f93406170618a8 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 4 Oct 2017 10:26:43 +0100 Subject: [PATCH 059/123] Fix typo --- src/components/views/room_settings/AliasSettings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/room_settings/AliasSettings.js b/src/components/views/room_settings/AliasSettings.js index 8a6abec35d..8bccac0f93 100644 --- a/src/components/views/room_settings/AliasSettings.js +++ b/src/components/views/room_settings/AliasSettings.js @@ -263,7 +263,7 @@ module.exports = React.createClass({ className={"mx_RoomSettings_localAliases"} items={this.state.domainToAliases[localDomain] || []} newItem={this.state.newAlias} - onNewItemChanged={onNewAliasChanged} + onNewItemChanged={this.onNewAliasChanged} onItemAdded={this.onLocalAliasAdded} onItemEdited={this.onLocalAliasChanged} onItemRemoved={this.onLocalAliasDeleted} From 4e9694be6d4f7817d7f39536b55349c127c59765 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 4 Oct 2017 10:28:26 +0100 Subject: [PATCH 060/123] Maintain "blur to add" function to match previous UX --- src/components/views/elements/EditableItemList.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/views/elements/EditableItemList.js b/src/components/views/elements/EditableItemList.js index 6675e162c4..267244759a 100644 --- a/src/components/views/elements/EditableItemList.js +++ b/src/components/views/elements/EditableItemList.js @@ -30,19 +30,22 @@ const EditableItem = React.createClass({ onChange: PropTypes.func, onRemove: PropTypes.func, onAdd: PropTypes.func, + + addOnChange: PropTypes.bool, }, onChange: function(value) { this.setState({ value }); if (this.props.onChange) this.props.onChange(value, this.props.index); + if (this.props.addOnChange && this.props.onAdd) this.props.onAdd(value); }, onRemove: function() { - this.props.onRemove(this.props.index); + if (this.props.onRemove) this.props.onRemove(this.props.index); }, onAdd: function() { - this.props.onAdd(this.state.value); + if (this.props.onAdd) this.props.onAdd(this.state.value); }, render: function() { @@ -138,6 +141,7 @@ module.exports = React.createClass({ initialValue={this.props.newItem} onAdd={this.onItemAdded} onChange={this.onNewItemChanged} + addOnChange={true} placeholder={this.props.placeholder} />
); From 9e3954865a2de182503422c19f93648c35c5eccf Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 4 Oct 2017 13:15:38 +0100 Subject: [PATCH 061/123] Fix a couple of bugs with EditableItemList - fix entering the same thing twice (which had the bug of not emptying the "new" field) - fix editing items in the list (which would stack overflow because of typo) --- src/components/views/elements/EditableItemList.js | 2 +- src/components/views/elements/EditableText.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/views/elements/EditableItemList.js b/src/components/views/elements/EditableItemList.js index 267244759a..35e207daef 100644 --- a/src/components/views/elements/EditableItemList.js +++ b/src/components/views/elements/EditableItemList.js @@ -104,7 +104,7 @@ module.exports = React.createClass({ if (value.length === 0) { this.onItemRemoved(index); } else { - this.onItemEdited(value, index); + this.props.onItemEdited(value, index); } }, diff --git a/src/components/views/elements/EditableText.js b/src/components/views/elements/EditableText.js index 3ce8c90447..b6a0ec1d5c 100644 --- a/src/components/views/elements/EditableText.js +++ b/src/components/views/elements/EditableText.js @@ -65,7 +65,9 @@ module.exports = React.createClass({ }, componentWillReceiveProps: function(nextProps) { - if (nextProps.initialValue !== this.props.initialValue) { + if (nextProps.initialValue !== this.props.initialValue || + nextProps.initialValue !== this.value + ) { this.value = nextProps.initialValue; if (this.refs.editable_div) { this.showPlaceholder(!this.value); From 7be5e685f74be2e79b341a1e61a8be478d05d2f6 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 4 Oct 2017 13:19:57 +0100 Subject: [PATCH 062/123] Implement UI for editing related groups of a room (using the new EditableItemList) --- .../room_settings/RelatedGroupSettings.js | 130 ++++++++++++++++++ src/components/views/rooms/RoomSettings.js | 14 ++ src/i18n/strings/en_EN.json | 6 +- 3 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 src/components/views/room_settings/RelatedGroupSettings.js diff --git a/src/components/views/room_settings/RelatedGroupSettings.js b/src/components/views/room_settings/RelatedGroupSettings.js new file mode 100644 index 0000000000..942251e54b --- /dev/null +++ b/src/components/views/room_settings/RelatedGroupSettings.js @@ -0,0 +1,130 @@ +/* +Copyright 2017 New Vector Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// import Promise from 'bluebird'; +import React from 'react'; +import {MatrixEvent, MatrixClient} from 'matrix-js-sdk'; +// var ObjectUtils = require("../../../ObjectUtils"); +// var MatrixClientPeg = require('../../../MatrixClientPeg'); +import sdk from '../../../index'; +import { _t } from '../../../languageHandler'; +import Modal from '../../../Modal'; + +const GROUP_ID_REGEX = /\+\S+\:\S+/; + +module.exports = React.createClass({ + displayName: 'RelatedGroupSettings', + + propTypes: { + roomId: React.PropTypes.string.isRequired, + canSetRelatedRooms: React.PropTypes.bool.isRequired, + relatedGroupsEvent: React.PropTypes.instanceOf(MatrixEvent), + }, + + contextTypes: { + matrixClient: React.PropTypes.instanceOf(MatrixClient), + }, + + getDefaultProps: function() { + return { + canSetRelatedRooms: false, + }; + }, + + getInitialState: function() { + return { + newGroupsList: this.props.relatedGroupsEvent ? + (this.props.relatedGroupsEvent.getContent().groups || []) : [], + newGroupId: null, + }; + }, + + saveSettings: function() { + return this.context.matrixClient.sendStateEvent( + this.props.roomId, + 'm.room.related_groups', + { + groups: this.state.newGroupsList, + }, + '', + ); + }, + + validateGroupId: function(groupId) { + const localDomain = this.context.matrixClient.getDomain(); + if (!GROUP_ID_REGEX.test(groupId) || !groupId.endsWith(localDomain)) { + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + Modal.createTrackedDialog('Invalid related group ID', '', ErrorDialog, { + title: _t('Invalid group ID'), + description: _t('\'%(groupId)s\' is not a valid group ID', { groupId }), + }); + return false; + } + return true; + }, + + onNewGroupChanged: function(newGroupId) { + this.setState({ newGroupId }); + }, + + onGroupAdded: function(groupId) { + if (groupId.length === 0 || !this.validateGroupId(groupId)) { + return; + } + this.setState({ + newGroupsList: this.state.newGroupsList.concat([groupId]), + newGroupId: '', + }); + }, + + onGroupEdited: function(groupId, index) { + if (groupId.length === 0 || !this.validateGroupId(groupId)) { + return; + } + this.setState({ + newGroupsList: Object.assign(this.state.newGroupsList, {[index]: groupId}), + }); + }, + + onGroupDeleted: function(index) { + const newGroupsList = this.state.newGroupsList.slice(); + newGroupsList.splice(index, 1), + this.setState({ newGroupsList }); + }, + + render: function() { + const localDomain = this.context.matrixClient.getDomain(); + const EditableItemList = sdk.getComponent('elements.EditableItemList'); + console.info(this.state.newGroupsList); + return (
+

{ _t('Related Groups') }

+ +
); + }, +}); diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index 0fea50d2fa..d1d32d8c71 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -287,6 +287,9 @@ module.exports = React.createClass({ promises.push(ps); } + // related groups + promises.push(this.saveRelatedGroups()); + // encryption p = this.saveEnableEncryption(); if (!p.isFulfilled()) { @@ -304,6 +307,11 @@ module.exports = React.createClass({ return this.refs.alias_settings.saveSettings(); }, + saveRelatedGroups: function() { + if (!this.refs.related_groups) { return Promise.resolve(); } + return this.refs.related_groups.saveSettings(); + }, + saveColor: function() { if (!this.refs.color_settings) { return Promise.resolve(); } return this.refs.color_settings.saveSettings(); @@ -590,6 +598,7 @@ module.exports = React.createClass({ var AliasSettings = sdk.getComponent("room_settings.AliasSettings"); var ColorSettings = sdk.getComponent("room_settings.ColorSettings"); var UrlPreviewSettings = sdk.getComponent("room_settings.UrlPreviewSettings"); + var RelatedGroupSettings = sdk.getComponent("room_settings.RelatedGroupSettings"); var EditableText = sdk.getComponent('elements.EditableText'); var PowerSelector = sdk.getComponent('elements.PowerSelector'); var Loader = sdk.getComponent("elements.Spinner"); @@ -846,6 +855,11 @@ module.exports = React.createClass({ canonicalAliasEvent={this.props.room.currentState.getStateEvents('m.room.canonical_alias', '')} aliasEvents={this.props.room.currentState.getStateEvents('m.room.aliases')} /> + +

{ _t('Permissions') }

diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 6a8c848f14..6acaba9fae 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -902,5 +902,9 @@ "Failed to remove room from group": "Failed to remove room from group", "Failed to remove '%(roomName)s' from %(groupId)s": "Failed to remove '%(roomName)s' from %(groupId)s", "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Are you sure you want to remove '%(roomName)s' from %(groupId)s?", - "Removing a room from the group will also remove it from the group page.": "Removing a room from the group will also remove it from the group page." + "Removing a room from the group will also remove it from the group page.": "Removing a room from the group will also remove it from the group page.", + "Related Groups": "Related Groups", + "Related groups for this room:": "Related groups for this room:", + "This room has no related groups": "This room has no related groups", + "New group ID (e.g. +foo:%(localDomain)s)": "New group ID (e.g. +foo:%(localDomain)s)" } From 8d46b199168ec54c373317e7e53a51dbfe0409d9 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 4 Oct 2017 14:06:49 +0100 Subject: [PATCH 063/123] Restrict Flair in the timeline to related groups of the room --- src/components/views/elements/Flair.js | 30 +++++++++++++++++++ .../views/messages/SenderProfile.js | 8 ++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/components/views/elements/Flair.js b/src/components/views/elements/Flair.js index 61df660fd5..84c0c2a187 100644 --- a/src/components/views/elements/Flair.js +++ b/src/components/views/elements/Flair.js @@ -183,10 +183,12 @@ export default class Flair extends React.Component { this.state = { profiles: [], }; + this.onRoomStateEvents = this.onRoomStateEvents.bind(this); } componentWillUnmount() { this._unmounted = true; + this.context.matrixClient.removeListener('RoomState.events', this.onRoomStateEvents); } componentWillMount() { @@ -194,6 +196,13 @@ export default class Flair extends React.Component { if (UserSettingsStore.isFeatureEnabled('feature_groups') && groupSupport) { this._generateAvatars(); } + this.context.matrixClient.on('RoomState.events', this.onRoomStateEvents); + } + + onRoomStateEvents(event) { + if (event.getType() === 'm.room.related_groups' && groupSupport) { + this._generateAvatars(); + } } async _getGroupProfiles(groups) { @@ -224,6 +233,21 @@ export default class Flair extends React.Component { } console.error('Could not get groups for user', this.props.userId, err); } + if (this.props.roomId && this.props.showRelated) { + const relatedGroupsEvent = this.context.matrixClient + .getRoom(this.props.roomId) + .currentState + .getStateEvents('m.room.related_groups', ''); + const relatedGroups = relatedGroupsEvent ? + relatedGroupsEvent.getContent().groups || [] : []; + if (relatedGroups && relatedGroups.length > 0) { + groups = groups.filter((groupId) => { + return relatedGroups.includes(groupId); + }); + } else { + groups = []; + } + } if (!groups || groups.length === 0) { return; } @@ -250,6 +274,12 @@ export default class Flair extends React.Component { Flair.propTypes = { userId: PropTypes.string, + + // Whether to show only the flair associated with related groups of the given room, + // or all flair associated with a user. + showRelated: PropTypes.bool, + // The room that this flair will be displayed in. Optional. Only applies when showRelated = true. + roomId: PropTypes.string, }; // TODO: We've decided that all components should follow this pattern, which means removing withMatrixClient and using diff --git a/src/components/views/messages/SenderProfile.js b/src/components/views/messages/SenderProfile.js index 0311239e7a..63e3144115 100644 --- a/src/components/views/messages/SenderProfile.js +++ b/src/components/views/messages/SenderProfile.js @@ -33,7 +33,13 @@ export default function SenderProfile(props) { return (
{ name || '' } - { props.enableFlair ? : null } + { props.enableFlair ? + + : null + } { props.aux ? { props.aux } : null }
); From 02e7287123b9fe70e2baef9bd581e5ab2132077c Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 4 Oct 2017 14:08:31 +0100 Subject: [PATCH 064/123] Remove constraint on groups being local, remove logging --- src/components/views/room_settings/RelatedGroupSettings.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/views/room_settings/RelatedGroupSettings.js b/src/components/views/room_settings/RelatedGroupSettings.js index 942251e54b..d3be2c88b5 100644 --- a/src/components/views/room_settings/RelatedGroupSettings.js +++ b/src/components/views/room_settings/RelatedGroupSettings.js @@ -64,8 +64,7 @@ module.exports = React.createClass({ }, validateGroupId: function(groupId) { - const localDomain = this.context.matrixClient.getDomain(); - if (!GROUP_ID_REGEX.test(groupId) || !groupId.endsWith(localDomain)) { + if (!GROUP_ID_REGEX.test(groupId)) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); Modal.createTrackedDialog('Invalid related group ID', '', ErrorDialog, { title: _t('Invalid group ID'), @@ -108,7 +107,6 @@ module.exports = React.createClass({ render: function() { const localDomain = this.context.matrixClient.getDomain(); const EditableItemList = sdk.getComponent('elements.EditableItemList'); - console.info(this.state.newGroupsList); return (

{ _t('Related Groups') }

Date: Wed, 4 Oct 2017 14:09:51 +0100 Subject: [PATCH 065/123] Remove commented imports --- src/components/views/room_settings/RelatedGroupSettings.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/components/views/room_settings/RelatedGroupSettings.js b/src/components/views/room_settings/RelatedGroupSettings.js index d3be2c88b5..60bdbf1481 100644 --- a/src/components/views/room_settings/RelatedGroupSettings.js +++ b/src/components/views/room_settings/RelatedGroupSettings.js @@ -14,11 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -// import Promise from 'bluebird'; import React from 'react'; import {MatrixEvent, MatrixClient} from 'matrix-js-sdk'; -// var ObjectUtils = require("../../../ObjectUtils"); -// var MatrixClientPeg = require('../../../MatrixClientPeg'); import sdk from '../../../index'; import { _t } from '../../../languageHandler'; import Modal from '../../../Modal'; From ed74ac394bfa5d44240ac0cedfccda22576edddb Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 4 Oct 2017 14:35:13 +0100 Subject: [PATCH 066/123] Put related groups UI behind groups labs flag --- src/components/views/rooms/RoomSettings.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index d1d32d8c71..b542dbaf55 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -631,6 +631,14 @@ module.exports = React.createClass({ var self = this; + let relatedGroupsSection; + if (UserSettingsStore.isFeatureEnabled('feature_groups')) { + relatedGroupsSection = ; + } + var userLevelsSection; if (Object.keys(user_levels).length) { userLevelsSection = @@ -855,10 +863,7 @@ module.exports = React.createClass({ canonicalAliasEvent={this.props.room.currentState.getStateEvents('m.room.canonical_alias', '')} aliasEvents={this.props.room.currentState.getStateEvents('m.room.aliases')} /> - + { relatedGroupsSection } From 4017fa7f1d4581423feff35cdf070bcddfe0b5e2 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 4 Oct 2017 16:56:35 +0100 Subject: [PATCH 067/123] Factor-out GroupStore and create GroupStoreCache In order to provide feedback when adding a room to a group, the group summarry store needs to be extended to store the list of rooms in a group. This commit is the first step required. The next step is to get the GroupRoomList listening to updates from GroupStore and expose the list of rooms from GroupStore. (We're running out of words to describe the hierachy of things that store things) --- src/GroupAddressPicker.js | 6 ++- src/components/structures/GroupView.js | 49 +++++++++---------- .../{GroupSummaryStore.js => GroupStore.js} | 10 +++- src/stores/GroupStoreCache.js | 37 ++++++++++++++ 4 files changed, 73 insertions(+), 29 deletions(-) rename src/stores/{GroupSummaryStore.js => GroupStore.js} (89%) create mode 100644 src/stores/GroupStoreCache.js diff --git a/src/GroupAddressPicker.js b/src/GroupAddressPicker.js index 00eed78f76..cfd2590780 100644 --- a/src/GroupAddressPicker.js +++ b/src/GroupAddressPicker.js @@ -19,6 +19,7 @@ import sdk from './'; import MultiInviter from './utils/MultiInviter'; import { _t } from './languageHandler'; import MatrixClientPeg from './MatrixClientPeg'; +import GroupStoreCache from './stores/GroupStoreCache'; export function showGroupInviteDialog(groupId) { const AddressPickerDialog = sdk.getComponent("dialogs.AddressPickerDialog"); @@ -86,10 +87,11 @@ function _onGroupInviteFinished(groupId, addrs) { } function _onGroupAddRoomFinished(groupId, addrs) { + const groupStore = GroupStoreCache.getGroupStore(MatrixClientPeg.get(), groupId); const errorList = []; return Promise.all(addrs.map((addr) => { - return MatrixClientPeg.get() - .addRoomToGroup(groupId, addr.address) + return groupStore + .addRoomToGroup(addr.address) .catch(() => { errorList.push(addr.address); }) .reflect(); })).then(() => { diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index 5381f9add3..337ac6ab75 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -27,7 +27,8 @@ import AccessibleButton from '../views/elements/AccessibleButton'; import Modal from '../../Modal'; import classnames from 'classnames'; -import GroupSummaryStore from '../../stores/GroupSummaryStore'; +import GroupStoreCache from '../../stores/GroupStoreCache'; +import GroupStore from '../../stores/GroupStore'; const RoomSummaryType = PropTypes.shape({ room_id: PropTypes.string.isRequired, @@ -78,7 +79,7 @@ const CategoryRoomList = React.createClass({ if (!success) return; const errorList = []; Promise.all(addrs.map((addr) => { - return this.context.groupSummaryStore + return this.context.groupStore .addRoomToGroupSummary(addr.address) .catch(() => { errorList.push(addr.address); }) .reflect(); @@ -157,7 +158,7 @@ const FeaturedRoom = React.createClass({ onDeleteClicked: function(e) { e.preventDefault(); e.stopPropagation(); - this.context.groupSummaryStore.removeRoomFromGroupSummary( + this.context.groupStore.removeRoomFromGroupSummary( this.props.summaryInfo.room_id, ).catch((err) => { console.error('Error whilst removing room from group summary', err); @@ -252,7 +253,7 @@ const RoleUserList = React.createClass({ if (!success) return; const errorList = []; Promise.all(addrs.map((addr) => { - return this.context.groupSummaryStore + return this.context.groupStore .addUserToGroupSummary(addr.address) .catch(() => { errorList.push(addr.address); }) .reflect(); @@ -327,7 +328,7 @@ const FeaturedUser = React.createClass({ onDeleteClicked: function(e) { e.preventDefault(); e.stopPropagation(); - this.context.groupSummaryStore.removeUserFromGroupSummary( + this.context.groupStore.removeUserFromGroupSummary( this.props.summaryInfo.user_id, ).catch((err) => { console.error('Error whilst removing user from group summary', err); @@ -373,14 +374,14 @@ const FeaturedUser = React.createClass({ }, }); -const GroupSummaryContext = { - groupSummaryStore: React.PropTypes.instanceOf(GroupSummaryStore).isRequired, +const GroupContext = { + groupStore: React.PropTypes.instanceOf(GroupStore).isRequired, }; -CategoryRoomList.contextTypes = GroupSummaryContext; -FeaturedRoom.contextTypes = GroupSummaryContext; -RoleUserList.contextTypes = GroupSummaryContext; -FeaturedUser.contextTypes = GroupSummaryContext; +CategoryRoomList.contextTypes = GroupContext; +FeaturedRoom.contextTypes = GroupContext; +RoleUserList.contextTypes = GroupContext; +FeaturedUser.contextTypes = GroupContext; export default React.createClass({ displayName: 'GroupView', @@ -390,12 +391,12 @@ export default React.createClass({ }, childContextTypes: { - groupSummaryStore: React.PropTypes.instanceOf(GroupSummaryStore), + groupStore: React.PropTypes.instanceOf(GroupStore), }, getChildContext: function() { return { - groupSummaryStore: this._groupSummaryStore, + groupStore: this._groupStore, }; }, @@ -413,14 +414,14 @@ export default React.createClass({ componentWillMount: function() { this._changeAvatarComponent = null; - this._initGroupSummaryStore(this.props.groupId); + this._initGroupStore(this.props.groupId); MatrixClientPeg.get().on("Group.myMembership", this._onGroupMyMembership); }, componentWillUnmount: function() { MatrixClientPeg.get().removeListener("Group.myMembership", this._onGroupMyMembership); - this._groupSummaryStore.removeAllListeners(); + this._groupStore.removeAllListeners(); }, componentWillReceiveProps: function(newProps) { @@ -429,7 +430,7 @@ export default React.createClass({ summary: null, error: null, }, () => { - this._initGroupSummaryStore(newProps.groupId); + this._initGroupStore(newProps.groupId); }); } }, @@ -440,17 +441,15 @@ export default React.createClass({ this.setState({membershipBusy: false}); }, - _initGroupSummaryStore: function(groupId) { - this._groupSummaryStore = new GroupSummaryStore( - MatrixClientPeg.get(), this.props.groupId, - ); - this._groupSummaryStore.on('update', () => { + _initGroupStore: function(groupId) { + this._groupStore = GroupStoreCache.getGroupStore(MatrixClientPeg.get(), groupId); + this._groupStore.on('update', () => { this.setState({ - summary: this._groupSummaryStore.getSummary(), + summary: this._groupStore.getSummary(), error: null, }); }); - this._groupSummaryStore.on('error', (err) => { + this._groupStore.on('error', (err) => { this.setState({ summary: null, error: err, @@ -527,7 +526,7 @@ export default React.createClass({ editing: false, summary: null, }); - this._initGroupSummaryStore(this.props.groupId); + this._initGroupStore(this.props.groupId); }).catch((e) => { this.setState({ saving: false, @@ -606,7 +605,7 @@ export default React.createClass({ this.setState({ publicityBusy: true, }); - this._groupSummaryStore.setGroupPublicity(publicity).then(() => { + this._groupStore.setGroupPublicity(publicity).then(() => { this.setState({ publicityBusy: false, }); diff --git a/src/stores/GroupSummaryStore.js b/src/stores/GroupStore.js similarity index 89% rename from src/stores/GroupSummaryStore.js rename to src/stores/GroupStore.js index aa6e74529b..cffffd8b2e 100644 --- a/src/stores/GroupSummaryStore.js +++ b/src/stores/GroupStore.js @@ -17,9 +17,10 @@ limitations under the License. import EventEmitter from 'events'; /** - * Stores the group summary for a room and provides an API to change it + * Stores the group summary for a room and provides an API to change it and + * other useful group APIs may have an effect on the group summary. */ -export default class GroupSummaryStore extends EventEmitter { +export default class GroupStore extends EventEmitter { constructor(matrixClient, groupId) { super(); this._groupId = groupId; @@ -45,6 +46,11 @@ export default class GroupSummaryStore extends EventEmitter { return this._summary; } + addRoomToGroup(roomId) { + return this._matrixClient + .addRoomToGroup(this._groupId, roomId); + } + addRoomToGroupSummary(roomId, categoryId) { return this._matrixClient .addRoomToGroupSummary(this._groupId, roomId, categoryId) diff --git a/src/stores/GroupStoreCache.js b/src/stores/GroupStoreCache.js new file mode 100644 index 0000000000..ade0445e97 --- /dev/null +++ b/src/stores/GroupStoreCache.js @@ -0,0 +1,37 @@ +/* +Copyright 2017 New Vector Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import GroupStore from './GroupStore'; + +class GroupStoreCache { + constructor() { + this.groupStores = {}; + } + + getGroupStore(matrixClient, groupId) { + if (!this.groupStores[groupId]) { + this.groupStores[groupId] = new GroupStore(matrixClient, groupId); + } + return this.groupStores[groupId]; + } +} + + +let singletonGroupStoreCache = null; +if (!singletonGroupStoreCache) { + singletonGroupStoreCache = new GroupStoreCache(); +} +module.exports = singletonGroupStoreCache; From b16eb1713e3ad231d9b578d9b3259813d8cff60e Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 4 Oct 2017 17:01:44 +0100 Subject: [PATCH 068/123] Typo --- src/stores/GroupStore.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stores/GroupStore.js b/src/stores/GroupStore.js index cffffd8b2e..f15561bbb0 100644 --- a/src/stores/GroupStore.js +++ b/src/stores/GroupStore.js @@ -18,7 +18,7 @@ import EventEmitter from 'events'; /** * Stores the group summary for a room and provides an API to change it and - * other useful group APIs may have an effect on the group summary. + * other useful group APIs that may have an effect on the group summary. */ export default class GroupStore extends EventEmitter { constructor(matrixClient, groupId) { From c1318e91024323fe466a3092f2d664dc7716b8f7 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 4 Oct 2017 17:51:38 +0100 Subject: [PATCH 069/123] Only maintain one GroupStore in the GroupStoreCache So that the group store data is up-to-date and to prevent group stores hanging around in memory --- src/stores/GroupStore.js | 16 ++++++++-------- src/stores/GroupStoreCache.js | 12 +++++++----- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/stores/GroupStore.js b/src/stores/GroupStore.js index f15561bbb0..941f4c8ec2 100644 --- a/src/stores/GroupStore.js +++ b/src/stores/GroupStore.js @@ -23,14 +23,14 @@ import EventEmitter from 'events'; export default class GroupStore extends EventEmitter { constructor(matrixClient, groupId) { super(); - this._groupId = groupId; + this.groupId = groupId; this._matrixClient = matrixClient; this._summary = {}; this._fetchSummary(); } _fetchSummary() { - this._matrixClient.getGroupSummary(this._groupId).then((resp) => { + this._matrixClient.getGroupSummary(this.groupId).then((resp) => { this._summary = resp; this._notifyListeners(); }).catch((err) => { @@ -48,36 +48,36 @@ export default class GroupStore extends EventEmitter { addRoomToGroup(roomId) { return this._matrixClient - .addRoomToGroup(this._groupId, roomId); + .addRoomToGroup(this.groupId, roomId); } addRoomToGroupSummary(roomId, categoryId) { return this._matrixClient - .addRoomToGroupSummary(this._groupId, roomId, categoryId) + .addRoomToGroupSummary(this.groupId, roomId, categoryId) .then(this._fetchSummary.bind(this)); } addUserToGroupSummary(userId, roleId) { return this._matrixClient - .addUserToGroupSummary(this._groupId, userId, roleId) + .addUserToGroupSummary(this.groupId, userId, roleId) .then(this._fetchSummary.bind(this)); } removeRoomFromGroupSummary(roomId) { return this._matrixClient - .removeRoomFromGroupSummary(this._groupId, roomId) + .removeRoomFromGroupSummary(this.groupId, roomId) .then(this._fetchSummary.bind(this)); } removeUserFromGroupSummary(userId) { return this._matrixClient - .removeUserFromGroupSummary(this._groupId, userId) + .removeUserFromGroupSummary(this.groupId, userId) .then(this._fetchSummary.bind(this)); } setGroupPublicity(isPublished) { return this._matrixClient - .setGroupPublicity(this._groupId, isPublished) + .setGroupPublicity(this.groupId, isPublished) .then(this._fetchSummary.bind(this)); } } diff --git a/src/stores/GroupStoreCache.js b/src/stores/GroupStoreCache.js index ade0445e97..fbe456f5dc 100644 --- a/src/stores/GroupStoreCache.js +++ b/src/stores/GroupStoreCache.js @@ -18,18 +18,20 @@ import GroupStore from './GroupStore'; class GroupStoreCache { constructor() { - this.groupStores = {}; + this.groupStore = null; } getGroupStore(matrixClient, groupId) { - if (!this.groupStores[groupId]) { - this.groupStores[groupId] = new GroupStore(matrixClient, groupId); + if (!this.groupStore || this.groupStore._groupId !== groupId) { + // This effectively throws away the reference to any previous GroupStore, + // allowing it to be GCd once the components referencing it have stopped + // referencing it. + this.groupStore = new GroupStore(matrixClient, groupId); } - return this.groupStores[groupId]; + return this.groupStore; } } - let singletonGroupStoreCache = null; if (!singletonGroupStoreCache) { singletonGroupStoreCache = new GroupStoreCache(); From cbb36b163b3d2dbd6f9a95bae1fab994287d0721 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 4 Oct 2017 18:05:40 +0100 Subject: [PATCH 070/123] Typo --- src/stores/GroupStoreCache.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stores/GroupStoreCache.js b/src/stores/GroupStoreCache.js index fbe456f5dc..bf340521b5 100644 --- a/src/stores/GroupStoreCache.js +++ b/src/stores/GroupStoreCache.js @@ -22,7 +22,7 @@ class GroupStoreCache { } getGroupStore(matrixClient, groupId) { - if (!this.groupStore || this.groupStore._groupId !== groupId) { + if (!this.groupStore || this.groupStore.groupId !== groupId) { // This effectively throws away the reference to any previous GroupStore, // allowing it to be GCd once the components referencing it have stopped // referencing it. From 38de4ae1524bb34e3d54b0c12f802ac2f4c95097 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 5 Oct 2017 08:00:22 +0100 Subject: [PATCH 071/123] delint Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/dialogs/CreateRoomDialog.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/views/dialogs/CreateRoomDialog.js b/src/components/views/dialogs/CreateRoomDialog.js index 20eeb5b591..d5a99dd4bf 100644 --- a/src/components/views/dialogs/CreateRoomDialog.js +++ b/src/components/views/dialogs/CreateRoomDialog.js @@ -48,21 +48,21 @@ export default React.createClass({ >
- +
- +
-
+
{ _t('Advanced options') }
- +
From c115980f21c83c598786f4deed375a1b469b6b53 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 5 Oct 2017 08:08:39 +0100 Subject: [PATCH 072/123] remove redundant&stale onKeyDown Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/dialogs/CreateRoomDialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/dialogs/CreateRoomDialog.js b/src/components/views/dialogs/CreateRoomDialog.js index d5a99dd4bf..f7be47b3eb 100644 --- a/src/components/views/dialogs/CreateRoomDialog.js +++ b/src/components/views/dialogs/CreateRoomDialog.js @@ -51,7 +51,7 @@ export default React.createClass({
- +

From a8231f7bf9b8a0d3bdaf7fc1d6ce6ee1d61df4dc Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 5 Oct 2017 08:26:57 +0100 Subject: [PATCH 073/123] Remove redundant stale onKeyDown Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/dialogs/TextInputDialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/dialogs/TextInputDialog.js b/src/components/views/dialogs/TextInputDialog.js index c924da7745..5ea4191e5e 100644 --- a/src/components/views/dialogs/TextInputDialog.js +++ b/src/components/views/dialogs/TextInputDialog.js @@ -68,7 +68,7 @@ export default React.createClass({
- +
From 917957c1dcb8911c2013fa8862a885a26227f3c1 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 5 Oct 2017 14:30:04 +0100 Subject: [PATCH 074/123] Modify the group store to include group rooms and modify components to use this new part of the store such that feedback can be given when adding or removing a room from the room list. --- .../views/dialogs/AddressPickerDialog.js | 42 ++++++++----------- src/components/views/groups/GroupRoomList.js | 39 +++++++++-------- src/components/views/groups/GroupRoomTile.js | 5 ++- src/stores/GroupStore.js | 26 +++++++++++- src/stores/GroupStoreCache.js | 1 + 5 files changed, 68 insertions(+), 45 deletions(-) diff --git a/src/components/views/dialogs/AddressPickerDialog.js b/src/components/views/dialogs/AddressPickerDialog.js index 6a027ac034..2637f9d466 100644 --- a/src/components/views/dialogs/AddressPickerDialog.js +++ b/src/components/views/dialogs/AddressPickerDialog.js @@ -23,6 +23,7 @@ import MatrixClientPeg from '../../../MatrixClientPeg'; import AccessibleButton from '../elements/AccessibleButton'; import Promise from 'bluebird'; import { addressTypes, getAddressType } from '../../../UserAddress.js'; +import GroupStoreCache from '../../../stores/GroupStoreCache'; const TRUNCATE_QUERY_LIST = 40; const QUERY_USER_DIRECTORY_DEBOUNCE_MS = 200; @@ -241,32 +242,25 @@ module.exports = React.createClass({ _doNaiveGroupRoomSearch: function(query) { const lowerCaseQuery = query.toLowerCase(); - MatrixClientPeg.get().getGroupRooms(this.props.groupId).then((resp) => { - const results = []; - resp.chunk.forEach((r) => { - const nameMatch = (r.name || '').toLowerCase().includes(lowerCaseQuery); - const topicMatch = (r.topic || '').toLowerCase().includes(lowerCaseQuery); - const aliasMatch = (r.canonical_alias || '').toLowerCase().includes(lowerCaseQuery); - if (!(nameMatch || topicMatch || aliasMatch)) { - return; - } - results.push({ - room_id: r.room_id, - avatar_url: r.avatar_url, - name: r.name || r.canonical_alias, - }); - }); - this._processResults(results, query); - }).catch((err) => { - console.error('Error whilst searching group users: ', err); - this.setState({ - searchError: err.errcode ? err.message : _t('Something went wrong!'), - }); - }).done(() => { - this.setState({ - busy: false, + const groupStore = GroupStoreCache.getGroupStore(MatrixClientPeg.get(), this.props.groupId); + const results = []; + groupStore.getGroupRooms().forEach((r) => { + const nameMatch = (r.name || '').toLowerCase().includes(lowerCaseQuery); + const topicMatch = (r.topic || '').toLowerCase().includes(lowerCaseQuery); + const aliasMatch = (r.canonical_alias || '').toLowerCase().includes(lowerCaseQuery); + if (!(nameMatch || topicMatch || aliasMatch)) { + return; + } + results.push({ + room_id: r.room_id, + avatar_url: r.avatar_url, + name: r.name || r.canonical_alias, }); }); + this._processResults(results, query); + this.setState({ + busy: false, + }); }, _doRoomSearch: function(query) { diff --git a/src/components/views/groups/GroupRoomList.js b/src/components/views/groups/GroupRoomList.js index 39ff3e4a07..4ff68a7f4d 100644 --- a/src/components/views/groups/GroupRoomList.js +++ b/src/components/views/groups/GroupRoomList.js @@ -17,6 +17,7 @@ import React from 'react'; import { _t } from '../../../languageHandler'; import sdk from '../../../index'; import { groupRoomFromApiObject } from '../../../groups'; +import GroupStoreCache from '../../../stores/GroupStoreCache'; import GeminiScrollbar from 'react-gemini-scrollbar'; import PropTypes from 'prop-types'; import {MatrixClient} from 'matrix-js-sdk'; @@ -34,7 +35,6 @@ export default React.createClass({ getInitialState: function() { return { - fetching: false, rooms: null, truncateAt: INITIAL_LOAD_NUM_ROOMS, searchQuery: "", @@ -43,21 +43,29 @@ export default React.createClass({ componentWillMount: function() { this._unmounted = false; + this._initGroupStore(this.props.groupId); + }, + + _initGroupStore: function(groupId) { + this._groupStore = GroupStoreCache.getGroupStore(this.context.matrixClient, groupId); + this._groupStore.on('update', () => { + this._fetchRooms(); + }); + this._groupStore.on('error', (err) => { + console.error('Error in group store (listened to by GroupRoomList)', err); + this.setState({ + rooms: null, + }); + }); this._fetchRooms(); }, _fetchRooms: function() { - this.setState({fetching: true}); - this.context.matrixClient.getGroupRooms(this.props.groupId).then((result) => { - this.setState({ - rooms: result.chunk.map((apiRoom) => { - return groupRoomFromApiObject(apiRoom); - }), - fetching: false, - }); - }).catch((e) => { - this.setState({fetching: false}); - console.error("Failed to get group room list: ", e); + if (this._unmounted) return; + this.setState({ + rooms: this._groupStore.getGroupRooms().map((apiRoom) => { + return groupRoomFromApiObject(apiRoom); + }), }); }, @@ -110,12 +118,7 @@ export default React.createClass({ }, render: function() { - if (this.state.fetching) { - const Spinner = sdk.getComponent("elements.Spinner"); - return (
- -
); - } else if (this.state.rooms === null) { + if (this.state.rooms === null) { return null; } diff --git a/src/components/views/groups/GroupRoomTile.js b/src/components/views/groups/GroupRoomTile.js index b6bdb9735b..bb0fdb03f4 100644 --- a/src/components/views/groups/GroupRoomTile.js +++ b/src/components/views/groups/GroupRoomTile.js @@ -21,6 +21,7 @@ import PropTypes from 'prop-types'; import sdk from '../../../index'; import dis from '../../../dispatcher'; import { GroupRoomType } from '../../../groups'; +import GroupStoreCache from '../../../stores/GroupStoreCache'; import Modal from '../../../Modal'; const GroupRoomTile = React.createClass({ @@ -49,10 +50,10 @@ const GroupRoomTile = React.createClass({ removeRoomFromGroup: function() { const groupId = this.props.groupId; + const groupStore = GroupStoreCache.getGroupStore(this.context.matrixClient, groupId); const roomName = this.state.name; const roomId = this.props.groupRoom.roomId; - this.context.matrixClient - .removeRoomFromGroup(groupId, roomId) + groupStore.removeRoomFromGroup(roomId) .catch((err) => { console.error(`Error whilst removing ${roomId} from ${groupId}`, err); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); diff --git a/src/stores/GroupStore.js b/src/stores/GroupStore.js index 941f4c8ec2..73118993f9 100644 --- a/src/stores/GroupStore.js +++ b/src/stores/GroupStore.js @@ -26,7 +26,9 @@ export default class GroupStore extends EventEmitter { this.groupId = groupId; this._matrixClient = matrixClient; this._summary = {}; + this._rooms = []; this._fetchSummary(); + this._fetchRooms(); } _fetchSummary() { @@ -38,6 +40,15 @@ export default class GroupStore extends EventEmitter { }); } + _fetchRooms() { + this._matrixClient.getGroupRooms(this.groupId).then((resp) => { + this._rooms = resp.chunk; + this._notifyListeners(); + }).catch((err) => { + this.emit('error', err); + }); + } + _notifyListeners() { this.emit('update'); } @@ -46,9 +57,22 @@ export default class GroupStore extends EventEmitter { return this._summary; } + getGroupRooms() { + return this._rooms; + } + addRoomToGroup(roomId) { return this._matrixClient - .addRoomToGroup(this.groupId, roomId); + .addRoomToGroup(this.groupId, roomId) + .then(this._fetchRooms.bind(this)); + } + + removeRoomFromGroup(roomId) { + return this._matrixClient + .removeRoomFromGroup(this.groupId, roomId) + // Room might be in the summary, refresh just in case + .then(this._fetchSummary.bind(this)) + .then(this._fetchRooms.bind(this)); } addRoomToGroupSummary(roomId, categoryId) { diff --git a/src/stores/GroupStoreCache.js b/src/stores/GroupStoreCache.js index bf340521b5..551b155615 100644 --- a/src/stores/GroupStoreCache.js +++ b/src/stores/GroupStoreCache.js @@ -28,6 +28,7 @@ class GroupStoreCache { // referencing it. this.groupStore = new GroupStore(matrixClient, groupId); } + this.groupStore._fetchSummary(); return this.groupStore; } } From 6a4e3792d4aa563c521eadfd1bc858a343894742 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 6 Oct 2017 12:07:38 +0100 Subject: [PATCH 075/123] split handlers into state and non-states Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/TextForEvent.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/TextForEvent.js b/src/TextForEvent.js index a21eb5c251..fa8efe028f 100644 --- a/src/TextForEvent.js +++ b/src/TextForEvent.js @@ -291,12 +291,15 @@ function textForWidgetEvent(event) { const handlers = { 'm.room.message': textForMessageEvent, - 'm.room.name': textForRoomNameEvent, - 'm.room.topic': textForTopicEvent, - 'm.room.member': textForMemberEvent, 'm.call.invite': textForCallInviteEvent, 'm.call.answer': textForCallAnswerEvent, 'm.call.hangup': textForCallHangupEvent, +}; + +const stateHandlers = { + 'm.room.name': textForRoomNameEvent, + 'm.room.topic': textForTopicEvent, + 'm.room.member': textForMemberEvent, 'm.room.third_party_invite': textForThreePidInviteEvent, 'm.room.history_visibility': textForHistoryVisibilityEvent, 'm.room.encryption': textForEncryptionEvent, @@ -307,8 +310,8 @@ const handlers = { module.exports = { textForEvent: function(ev) { - const hdlr = handlers[ev.getType()]; - if (!hdlr) return ''; - return hdlr(ev); + const handler = ev.isState() ? stateHandlers[ev.getType()] : handlers[ev.getType()]; + if (handler) return handler(ev); + return ''; }, }; From 91ba939e23eef52634a5618041008cbe30c73e2b Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 6 Oct 2017 12:10:07 +0100 Subject: [PATCH 076/123] tiny bit of de-lint for consistency Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/TextForEvent.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/TextForEvent.js b/src/TextForEvent.js index fa8efe028f..ccb4c29a9c 100644 --- a/src/TextForEvent.js +++ b/src/TextForEvent.js @@ -243,7 +243,7 @@ function textForPowerEvent(event) { if (to !== from) { diff.push( _t('%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s', { - userId: userId, + userId, fromPowerLevel: Roles.textualPowerLevel(from, userDefault), toPowerLevel: Roles.textualPowerLevel(to, userDefault), }), @@ -254,7 +254,7 @@ function textForPowerEvent(event) { return ''; } return _t('%(senderName)s changed the power level of %(powerLevelDiffText)s.', { - senderName: senderName, + senderName, powerLevelDiffText: diff.join(", "), }); } From 152499a17d0683a565608a7f019ae99740a29b97 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 6 Oct 2017 12:16:54 +0100 Subject: [PATCH 077/123] DRY map lookup Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/TextForEvent.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TextForEvent.js b/src/TextForEvent.js index ccb4c29a9c..6345403f09 100644 --- a/src/TextForEvent.js +++ b/src/TextForEvent.js @@ -310,7 +310,7 @@ const stateHandlers = { module.exports = { textForEvent: function(ev) { - const handler = ev.isState() ? stateHandlers[ev.getType()] : handlers[ev.getType()]; + const handler = (ev.isState() ? stateHandlers : handlers)[ev.getType()]; if (handler) return handler(ev); return ''; }, From 8855a5e30acb078bdd56721613b8b7b1f5da456a Mon Sep 17 00:00:00 2001 From: "Iru Cai (vimacs)" Date: Sat, 7 Oct 2017 11:44:25 +0000 Subject: [PATCH 078/123] Translated using Weblate (Chinese (Simplified)) Currently translated at 89.7% (767 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hans/ --- src/i18n/strings/zh_Hans.json | 51 ++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index 1a19ecf2ed..5b1964f37a 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -32,7 +32,7 @@ "Encrypted room": "加密聊天室", "%(senderName)s ended the call.": "%(senderName)s 结束了通话。.", "End-to-end encryption information": "端到端加密信息", - "End-to-end encryption is in beta and may not be reliable": "端到端加密现为测试版,不一定可靠", + "End-to-end encryption is in beta and may not be reliable": "端到端加密现为 beta 版,不一定可靠", "Enter Code": "输入代码", "Error": "错误", "Error decrypting attachment": "解密附件时出错", @@ -87,7 +87,7 @@ "Homeserver is": "主服务器是", "Identity Server is": "身份认证服务器是", "I have verified my email address": "我已经验证了我的邮箱地址", - "Import E2E room keys": "导入聊天室端对端加密密钥", + "Import E2E room keys": "导入聊天室端到端加密密钥", "Incorrect verification code": "验证码错误", "Interface Language": "界面语言", "Invalid alias format": "别名格式错误", @@ -236,7 +236,7 @@ "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s 把话题修改为 “%(topic)s”。", "Changes to who can read history will only apply to future messages in this room": "修改阅读历史的权限仅对此聊天室以后的消息有效", "Changes your display nickname": "修改昵称", - "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "目前,修改密码会导致所有设备上的端对端密钥被重置,使得加密的聊天记录不再可读。除非你事先导出聊天室密钥,修改密码后再导入。这个问题未来会改善。", + "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "目前,修改密码会导致所有设备上的端到端密钥被重置,使得加密的聊天记录不再可读。除非你事先导出聊天室密钥,修改密码后再导入。这个问题未来会改善。", "Clear Cache and Reload": "清除缓存并刷新", "Clear Cache": "清除缓存", "Click here to join the discussion!": "点此 加入讨论!", @@ -292,7 +292,7 @@ "Invites user with given id to current room": "邀请指定 ID 的用户加入当前聊天室", "'%(alias)s' is not a valid format for an address": "'%(alias)s' 不是一个合法的电子邮件地址格式", "'%(alias)s' is not a valid format for an alias": "'%(alias)s' 不是一个合法的昵称格式", - "%(displayName)s is typing": "%(displayName)s 正在输入", + "%(displayName)s is typing": "%(displayName)s 正在打字", "Sign in with": "第三方登录", "Message not sent due to unknown devices being present": "消息未发送,因为有未知的设备存在", "Missing room_id in request": "请求中没有 room_id", @@ -562,7 +562,7 @@ "%(senderName)s made future room history visible to": "%(senderName)s 设定历史浏览功能为", "AM": "上午", "PM": "下午", - "NOTE: Apps are not end-to-end encrypted": "提示:APP不支持端对端加密", + "NOTE: Apps are not end-to-end encrypted": "提示:APP不支持端到端加密", "People": "联系人", "Press": "点击", "Profile": "个人配置", @@ -730,5 +730,44 @@ "Verifies a user, device, and pubkey tuple": "验证一个用户、设备和密钥元组", "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "我们在尝试恢复你之前的会话时遇到了一个错误。如果你继续,你将需要重新登录,加密的聊天历史将会不可读。", "Unknown devices": "未知设备", - "Unknown Address": "未知地址" + "Unknown Address": "未知地址", + "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s 删除了他们的昵称 (%(oldDisplayName)s).", + "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "你提供的签名密钥和你从 %(userId)s 的设备 (deviceId)s 收到的签名密钥匹配。设备被标记为已验证。", + "These are experimental features that may break in unexpected ways": "这些是可能以意外的方式坏掉的实验性的特性", + "The visibility of existing history will be unchanged": "现有历史记录的可见性不会被改变", + "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s 打开了端到端加密 (算法 %(algorithm)s).", + "Unable to remove contact information": "无法移除联系人信息", + "Resend all or cancel all now. You can also select individual messages to resend or cancel.": "现在 重发全部 或者 取消全部。你也可以选择重发或取消单独的消息。", + "were invited %(repeats)s times": "被邀请 %(repeats)s 次", + "was invited %(repeats)s times": "被邀请 %(repeats)s 次", + "Riot collects anonymous analytics to allow us to improve the application.": "Riot 收集匿名的分析数据来允许我们改善这个应用。", + "\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" 包含你以前没见过的设备。", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "你可以使用自定义的服务器选项来通过指定一个不同的主服务器 URL 来登录其他 Matrix 服务器。", + "This allows you to use this app with an existing Matrix account on a different home server.": "这允许你用一个已有在不同主服务器的 Matrix 账户使用这个应用。", + "Please check your email to continue registration.": "请查看你的电子邮件以继续注册。", + "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "如果你不指定一个电子邮箱地址,你将不能重置你的密码。你确定吗?", + "Home server URL": "主服务器 URL", + "Identity server URL": "身份服务器 URL", + "What does this mean?": "这是什么意思?", + "Image '%(Body)s' cannot be displayed.": "图像 '%(Body)s' 无法显示。", + "This image cannot be displayed.": "图像无法显示。", + "Add an Integration": "添加一个集成", + "Removed or unknown message type": "被移除或未知的消息类型", + "Disable URL previews by default for participants in this room": "对这个聊天室的参与者默认禁用 URL 预览", + "Enable URL previews for this room (affects only you)": "在这个聊天室启用 URL 预览(只影响你)", + "Ongoing conference call%(supportedText)s.": "正在进行的会议通话 %(supportedText)s.", + "$senderDisplayName changed the room avatar to ": "$senderDisplayName 把聊天室的头像改为了 ", + "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s 修改了 %(roomName)s 的头像", + "This will be your account name on the homeserver, or you can pick a different server.": "这将会成为你在 主服务器上的账户名,或者你可以选择一个 不同的服务器。", + "Your browser does not support the required cryptography extensions": "你的浏览器不支持所需的密码学扩展", + "Authentication check failed: incorrect password?": "身份验证失败:密码错误?", + "This will allow you to reset your password and receive notifications.": "这将允许你重置你的密码和接收通知。", + "Share without verifying": "不验证就分享", + "You added a new device '%(displayName)s', which is requesting encryption keys.": "你添加了一个新的设备 '%(displayName)s',它正在请求加密密钥。", + "Your unverified device '%(displayName)s' is requesting encryption keys.": "你的未验证的设备 '%(displayName)s' 正在请求加密密钥。", + "Encryption key request": "加密密钥请求", + "Autocomplete Delay (ms):": "自动完成延迟(毫秒):", + "%(widgetName)s widget added by %(senderName)s": "%(widgetName)s 小组建被 %(senderName)s 添加", + "%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s 小组建被 %(senderName)s 移除", + "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s 小组建被 %(senderName)s 修改" } From 92be3af990ecd96cfa1bbef3bc2cdab3554b819b Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 10 Oct 2017 19:16:42 +0100 Subject: [PATCH 079/123] Make it clearer which HS you're logging into Otherwise there's no indication without clicking 'custom server' --- src/components/structures/login/Login.js | 1 + src/components/views/elements/Dropdown.js | 10 ++++++++++ src/components/views/login/PasswordLogin.js | 14 +++++++++++++- src/i18n/strings/en_EN.json | 3 ++- 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/components/structures/login/Login.js b/src/components/structures/login/Login.js index a6c0a70c66..b88aa094dc 100644 --- a/src/components/structures/login/Login.js +++ b/src/components/structures/login/Login.js @@ -290,6 +290,7 @@ module.exports = React.createClass({ onPhoneNumberChanged={this.onPhoneNumberChanged} onForgotPasswordClick={this.props.onForgotPasswordClick} loginIncorrect={this.state.loginIncorrect} + hsUrl={this.state.enteredHomeserverUrl} /> ); case 'm.login.cas': diff --git a/src/components/views/elements/Dropdown.js b/src/components/views/elements/Dropdown.js index c049c38a68..1b2117bb6a 100644 --- a/src/components/views/elements/Dropdown.js +++ b/src/components/views/elements/Dropdown.js @@ -26,6 +26,12 @@ class MenuOption extends React.Component { this._onClick = this._onClick.bind(this); } + getDefaultProps() { + return { + disabled: false, + } + } + _onMouseEnter() { this.props.onMouseEnter(this.props.dropdownKey); } @@ -153,6 +159,8 @@ export default class Dropdown extends React.Component { } _onInputClick(ev) { + if (this.props.disabled) return; + if (!this.state.expanded) { this.setState({ expanded: true, @@ -329,4 +337,6 @@ Dropdown.propTypes = { // in the dropped-down menu. getShortOption: React.PropTypes.func, value: React.PropTypes.string, + // negative for consistency with HTML + disabled: React.PropTypes.bool, } diff --git a/src/components/views/login/PasswordLogin.js b/src/components/views/login/PasswordLogin.js index 9f855616fc..4e37e30f65 100644 --- a/src/components/views/login/PasswordLogin.js +++ b/src/components/views/login/PasswordLogin.js @@ -186,6 +186,17 @@ class PasswordLogin extends React.Component { const loginField = this.renderLoginField(this.state.loginType); + let matrixIdText = ''; + if (this.props.hsUrl) { + try { + const parsedHsUrl = new URL(this.props.hsUrl); + matrixIdText = _t('%(serverName)s Matrix ID', {serverName: parsedHsUrl.hostname}); + } catch (e) { + console.log(e); + // pass + } + } + return (
@@ -194,8 +205,9 @@ class PasswordLogin extends React.Component { - { _t('my Matrix ID') } + {matrixIdText} { _t('Email address') } { _t('Phone') } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 6acaba9fae..8ec975987c 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -906,5 +906,6 @@ "Related Groups": "Related Groups", "Related groups for this room:": "Related groups for this room:", "This room has no related groups": "This room has no related groups", - "New group ID (e.g. +foo:%(localDomain)s)": "New group ID (e.g. +foo:%(localDomain)s)" + "New group ID (e.g. +foo:%(localDomain)s)": "New group ID (e.g. +foo:%(localDomain)s)", + "%(serverName)s Matrix ID": "%(serverName)s Matrix ID" } From 80ad7d4ad670f23e8c7ae3e6d8146df5f50541f9 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 10 Oct 2017 19:27:51 +0100 Subject: [PATCH 080/123] Update translations --- src/i18n/strings/de_DE.json | 2 +- src/i18n/strings/el.json | 1 - src/i18n/strings/en_EN.json | 1 - src/i18n/strings/en_US.json | 1 - src/i18n/strings/es.json | 2 +- src/i18n/strings/eu.json | 1 - src/i18n/strings/fi.json | 2 +- src/i18n/strings/fr.json | 2 +- src/i18n/strings/hu.json | 2 +- src/i18n/strings/id.json | 1 - src/i18n/strings/ko.json | 1 - src/i18n/strings/lv.json | 2 +- src/i18n/strings/nl.json | 2 +- src/i18n/strings/pl.json | 2 +- src/i18n/strings/pt.json | 1 - src/i18n/strings/pt_BR.json | 1 - src/i18n/strings/ru.json | 2 +- src/i18n/strings/sv.json | 2 +- src/i18n/strings/th.json | 1 - src/i18n/strings/tr.json | 1 - src/i18n/strings/zh_Hans.json | 1 - src/i18n/strings/zh_Hant.json | 1 - 22 files changed, 10 insertions(+), 22 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index aa114e241d..71adaba704 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -146,7 +146,7 @@ "Members only": "Nur Mitglieder", "Mobile phone number": "Mobiltelefonnummer", "Moderator": "Moderator", - "my Matrix ID": "meiner Matrix-ID", + "%(serverName)s Matrix ID": "%(serverName)s Matrix-ID", "Never send encrypted messages to unverified devices from this device": "Niemals verschlüsselte Nachrichten an unverifizierte Geräte von diesem Gerät aus versenden", "Never send encrypted messages to unverified devices in this room from this device": "Niemals verschlüsselte Nachrichten an unverifizierte Geräte in diesem Raum von diesem Gerät aus senden", "New password": "Neues Passwort", diff --git a/src/i18n/strings/el.json b/src/i18n/strings/el.json index bc45e6da9e..2a51f6cae5 100644 --- a/src/i18n/strings/el.json +++ b/src/i18n/strings/el.json @@ -188,7 +188,6 @@ "Failure to create room": "Δεν ήταν δυνατή η δημιουργία δωματίου", "Join Room": "Είσοδος σε δωμάτιο", "Moderator": "Συντονιστής", - "my Matrix ID": "το Matrix ID μου", "Name": "Όνομα", "New address (e.g. #foo:%(localDomain)s)": "Νέα διεύθυνση (e.g. #όνομα:%(localDomain)s)", "New password": "Νέος κωδικός πρόσβασης", diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 8ec975987c..37c7655ed6 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -295,7 +295,6 @@ "Moderator": "Moderator", "Must be viewing a room": "Must be viewing a room", "Mute": "Mute", - "my Matrix ID": "my Matrix ID", "Name": "Name", "Never send encrypted messages to unverified devices from this device": "Never send encrypted messages to unverified devices from this device", "Never send encrypted messages to unverified devices in this room": "Never send encrypted messages to unverified devices in this room", diff --git a/src/i18n/strings/en_US.json b/src/i18n/strings/en_US.json index 928f1a9d0f..3954b2b6fa 100644 --- a/src/i18n/strings/en_US.json +++ b/src/i18n/strings/en_US.json @@ -262,7 +262,6 @@ "Moderator": "Moderator", "Must be viewing a room": "Must be viewing a room", "Mute": "Mute", - "my Matrix ID": "my Matrix ID", "Name": "Name", "Never send encrypted messages to unverified devices from this device": "Never send encrypted messages to unverified devices from this device", "Never send encrypted messages to unverified devices in this room": "Never send encrypted messages to unverified devices in this room", diff --git a/src/i18n/strings/es.json b/src/i18n/strings/es.json index bc2391a5c7..68f27c23e9 100644 --- a/src/i18n/strings/es.json +++ b/src/i18n/strings/es.json @@ -379,7 +379,7 @@ "Moderator": "Moderador", "Must be viewing a room": "Debe estar viendo una sala", "Mute": "Silenciar", - "my Matrix ID": "Mi ID de Matrix", + "%(serverName)s Matrix ID": "%(serverName)s ID de Matrix", "Name": "Nombre", "Never send encrypted messages to unverified devices from this device": "No enviar nunca mensajes cifrados, desde este dispositivo, a dispositivos sin verificar", "Never send encrypted messages to unverified devices in this room": "No enviar nunca mensajes cifrados a dispositivos no verificados, en esta sala", diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index 9f3d06ec52..9ef02d7b9b 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -346,7 +346,6 @@ "Missing room_id in request": "Gelaren ID-a falta da eskaeran", "Missing user_id in request": "Erabiltzailearen ID-a falta da eskaeran", "Mobile phone number": "Mugikorraren telefono zenbakia", - "my Matrix ID": "Nire Matrix ID-a", "Never send encrypted messages to unverified devices in this room": "Ez bidali inoiz zifratutako mezuak egiaztatu gabeko gailuetara gela honetan", "Never send encrypted messages to unverified devices in this room from this device": "Ez bidali inoiz zifratutako mezuak egiaztatu gabeko gailuetara gela honetan gailu honetatik", "New address (e.g. #foo:%(localDomain)s)": "Helbide berria (adib. #foo:%(localDomain)s)", diff --git a/src/i18n/strings/fi.json b/src/i18n/strings/fi.json index a59e5b1edd..7ffbf39e8e 100644 --- a/src/i18n/strings/fi.json +++ b/src/i18n/strings/fi.json @@ -245,7 +245,7 @@ "Mobile phone number": "Matkapuhelinnumero", "Mobile phone number (optional)": "Matkapuhelinnumero (valinnainen)", "Moderator": "Moderaattori", - "my Matrix ID": "minun Matrix tunniste", + "%(serverName)s Matrix ID": "%(serverName)s Matrix tunniste", "Name": "Nimi", "New password": "Uusi salasana", "New passwords don't match": "Uudet salasanat eivät täsmää", diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 585e47f5a3..51c496ab96 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -224,7 +224,7 @@ "Mobile phone number": "Numéro de téléphone mobile", "Moderator": "Modérateur", "Must be viewing a room": "Doit être en train de visualiser un salon", - "my Matrix ID": "mon identifiant Matrix", + "%(serverName)s Matrix ID": "%(serverName)s identifiant Matrix", "Name": "Nom", "Never send encrypted messages to unverified devices from this device": "Ne jamais envoyer de message chiffré aux appareils non-vérifiés depuis cet appareil", "Never send encrypted messages to unverified devices in this room": "Ne jamais envoyer de message chiffré aux appareils non-vérifiés dans ce salon", diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 2c34e05b1a..edf0a83ac6 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -293,7 +293,7 @@ "Mobile phone number (optional)": "Mobill telefonszám (opcionális)", "Moderator": "Moderátor", "Must be viewing a room": "Meg kell nézni a szobát", - "my Matrix ID": "Matrix azonosítóm", + "%(serverName)s Matrix ID": "%(serverName)s Matrix azonosítóm", "Name": "Név", "Never send encrypted messages to unverified devices from this device": "Soha ne küldj titkosított üzenetet ellenőrizetlen eszközre erről az eszközről", "Never send encrypted messages to unverified devices in this room": "Soha ne küldj titkosított üzenetet ebből a szobából ellenőrizetlen eszközre", diff --git a/src/i18n/strings/id.json b/src/i18n/strings/id.json index dc057c2a95..27bcc41dc8 100644 --- a/src/i18n/strings/id.json +++ b/src/i18n/strings/id.json @@ -78,7 +78,6 @@ "Members only": "Hanya anggota", "Mobile phone number": "Nomor telpon seluler", "Mute": "Bisu", - "my Matrix ID": "ID Matrix saya", "Name": "Nama", "New password": "Password Baru", "New passwords don't match": "Password baru tidak cocok", diff --git a/src/i18n/strings/ko.json b/src/i18n/strings/ko.json index 8b6e233437..5933b6abc2 100644 --- a/src/i18n/strings/ko.json +++ b/src/i18n/strings/ko.json @@ -293,7 +293,6 @@ "Mobile phone number (optional)": "휴대 전화번호 (선택)", "Moderator": "조정자", "Must be viewing a room": "방을 둘러봐야만 해요", - "my Matrix ID": "내 매트릭스 ID", "Name": "이름", "Never send encrypted messages to unverified devices from this device": "이 장치에서 인증받지 않은 장치로 암호화한 메시지를 보내지 마세요", "Never send encrypted messages to unverified devices in this room": "이 방에서 인증받지 않은 장치로 암호화한 메시지를 보내지 마세요", diff --git a/src/i18n/strings/lv.json b/src/i18n/strings/lv.json index 5f58fd9515..424a831ac5 100644 --- a/src/i18n/strings/lv.json +++ b/src/i18n/strings/lv.json @@ -274,7 +274,7 @@ "Moderator": "Moderators", "Must be viewing a room": "Jāapskata istaba", "Mute": "Apklusināt", - "my Matrix ID": "mans Matrix ID", + "%(serverName)s Matrix ID": "%(serverName)s Matrix ID", "Name": "Vārds", "Never send encrypted messages to unverified devices from this device": "Nekad nesūti no šīs ierīces šifrētas ziņas uz neverificētām ierīcēm", "Never send encrypted messages to unverified devices in this room": "Nekad nesūti šifrētas ziņas uz neverificētām ierīcēm šajā istabā", diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index f770e335cf..67fa97a5d7 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -126,7 +126,7 @@ "disabled": "uitgeschakeld", "Moderator": "Moderator", "Must be viewing a room": "Moet een ruimte weergeven", - "my Matrix ID": "mijn Matrix-ID", + "%(serverName)s Matrix ID": "%(serverName)s Matrix-ID", "Name": "Naam", "New password": "Nieuw wachtwoord", "none": "geen", diff --git a/src/i18n/strings/pl.json b/src/i18n/strings/pl.json index bd1e4c5c24..a3e2af956f 100644 --- a/src/i18n/strings/pl.json +++ b/src/i18n/strings/pl.json @@ -363,7 +363,7 @@ "Mobile phone number": "Numer telefonu komórkowego", "Mobile phone number (optional)": "Numer telefonu komórkowego (opcjonalne)", "Moderator": "Moderator", - "my Matrix ID": "mój Matrix ID", + "%(serverName)s Matrix ID": "%(serverName)s Matrix ID", "Name": "Imię", "Never send encrypted messages to unverified devices from this device": "Nigdy nie wysyłaj zaszyfrowanych wiadomości do niezweryfikowanych urządzeń z tego urządzenia", "Never send encrypted messages to unverified devices in this room": "Nigdy nie wysyłaj zaszyfrowanych wiadomości do niezweryfikowanych urządzeń w tym pokoju", diff --git a/src/i18n/strings/pt.json b/src/i18n/strings/pt.json index ba4968b7ad..1bf7fd00b1 100644 --- a/src/i18n/strings/pt.json +++ b/src/i18n/strings/pt.json @@ -127,7 +127,6 @@ "Members only": "Apenas integrantes da sala", "Mobile phone number": "Telefone celular", "Moderator": "Moderador/a", - "my Matrix ID": "com meu ID do Matrix", "Name": "Nome", "Never send encrypted messages to unverified devices from this device": "Nunca envie mensagens criptografada para um dispositivo não verificado a partir deste dispositivo", "Never send encrypted messages to unverified devices in this room from this device": "Nunca envie mensagens criptografadas para dispositivos não verificados nesta sala a partir deste dispositivo", diff --git a/src/i18n/strings/pt_BR.json b/src/i18n/strings/pt_BR.json index af4804bd85..116142c29c 100644 --- a/src/i18n/strings/pt_BR.json +++ b/src/i18n/strings/pt_BR.json @@ -127,7 +127,6 @@ "Members only": "Apenas integrantes da sala", "Mobile phone number": "Telefone celular", "Moderator": "Moderador/a", - "my Matrix ID": "com meu ID do Matrix", "Name": "Nome", "Never send encrypted messages to unverified devices from this device": "Nunca envie mensagens criptografada para um dispositivo não verificado a partir deste dispositivo", "Never send encrypted messages to unverified devices in this room from this device": "Nunca envie mensagens criptografadas para dispositivos não verificados nesta sala a partir deste dispositivo", diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index cfab960e32..8dc2d80001 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -117,7 +117,7 @@ "Members only": "Только участники", "Mobile phone number": "Номер мобильного телефона", "Moderator": "Модератор", - "my Matrix ID": "мой Matrix ID", + "%(serverName)s Matrix ID": "%(serverName)s Matrix ID", "Name": "Имя", "Never send encrypted messages to unverified devices from this device": "Никогда не отправлять зашифрованные сообщения на непроверенные устройства с этого устройства", "Never send encrypted messages to unverified devices in this room from this device": "Никогда не отправлять зашифрованные сообщения на непроверенные устройства в этой комнате с этого устройства", diff --git a/src/i18n/strings/sv.json b/src/i18n/strings/sv.json index fb7257ecf9..fd15771cec 100644 --- a/src/i18n/strings/sv.json +++ b/src/i18n/strings/sv.json @@ -273,7 +273,7 @@ "Moderator": "Moderator", "Must be viewing a room": "Du måste ha ett öppet rum", "Mute": "Dämpa", - "my Matrix ID": "mitt Matrix-ID", + "%(serverName)s Matrix ID": "%(serverName)s Matrix-ID", "Name": "Namn", "Never send encrypted messages to unverified devices from this device": "Skicka aldrig krypterade meddelanden till overifierade enheter från den här enheten", "Never send encrypted messages to unverified devices in this room": "Skicka aldrig krypterade meddelanden till overifierade enheter i det här rummet", diff --git a/src/i18n/strings/th.json b/src/i18n/strings/th.json index d45cb86986..47a5fd3049 100644 --- a/src/i18n/strings/th.json +++ b/src/i18n/strings/th.json @@ -219,7 +219,6 @@ "Markdown is enabled": "เปิดใช้งาน Markdown แล้ว", "Missing user_id in request": "ไม่พบ user_id ในคำขอ", "Moderator": "ผู้ช่วยดูแล", - "my Matrix ID": "Matrix ID ของฉัน", "New address (e.g. #foo:%(localDomain)s)": "ที่อยู่ใหม่ (เช่น #foo:%(localDomain)s)", "New password": "รหัสผ่านใหม่", "New passwords don't match": "รหัสผ่านใหม่ไม่ตรงกัน", diff --git a/src/i18n/strings/tr.json b/src/i18n/strings/tr.json index 23d4e284bc..6e8e4f25f8 100644 --- a/src/i18n/strings/tr.json +++ b/src/i18n/strings/tr.json @@ -269,7 +269,6 @@ "Moderator": "Moderatör", "Must be viewing a room": "Bir oda görüntülemeli olmalı", "Mute": "Sessiz", - "my Matrix ID": "Benim Matrix ID'm", "Name": "İsim", "Never send encrypted messages to unverified devices from this device": "Bu cihazdan doğrulanmamış cihazlara asla şifrelenmiş mesajlar göndermeyin", "Never send encrypted messages to unverified devices in this room": "Bu odada doğrulanmamış cihazlara asla şifreli mesajlar göndermeyin", diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index 69ba19ca27..f185640572 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -289,7 +289,6 @@ "Mobile phone number (optional)": "手机号码 (可选)", "Moderator": "管理员", "Mute": "静音", - "my Matrix ID": "我的 Matrix ID", "Name": "姓名", "Never send encrypted messages to unverified devices from this device": "不要从此设备向未验证的设备发送消息", "Never send encrypted messages to unverified devices in this room": "不要在此聊天室里向未验证的设备发送消息", diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 596bc55a01..49890005a1 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -403,7 +403,6 @@ "Mobile phone number (optional)": "行動電話號碼(選擇性)", "Moderator": "仲裁者", "Must be viewing a room": "必須檢視房間", - "my Matrix ID": "我的 Matrix ID", "Name": "名稱", "Never send encrypted messages to unverified devices from this device": "從不自此裝置傳送加密的訊息到未驗證的裝置", "Never send encrypted messages to unverified devices in this room": "從不在此房間傳送加密的訊息到未驗證的裝置", From 8266286e99240058df7d2c5d727c362e990c4164 Mon Sep 17 00:00:00 2001 From: Stefan Parviainen Date: Wed, 11 Oct 2017 08:39:46 +0200 Subject: [PATCH 081/123] Ignore VS16 char in RTE Signed-off-by: Stefan Parviainen --- src/RichText.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/RichText.js b/src/RichText.js index cbd3b9ae18..dca14813f2 100644 --- a/src/RichText.js +++ b/src/RichText.js @@ -67,8 +67,14 @@ function unicodeToEmojiUri(str) { // if the unicodeChar doesnt exist just return the entire match return unicodeChar; } else { + // Remove variant selector VS16 (explicitly emoji) as it is unnecessary and leads to an incorrect URL below + if(unicodeChar.length == 2 && unicodeChar[1] == '\ufe0f') { + unicodeChar = unicodeChar[0]; + } + // get the unicode codepoint from the actual char unicode = emojione.jsEscapeMap[unicodeChar]; + return emojione.imagePathSVG+unicode+'.svg'+emojione.cacheBustParam; } }); From ce607d18b924d25d90bb4d63e42c856fef35c815 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20Nenad=C3=A1l?= Date: Sun, 8 Oct 2017 20:57:44 +0000 Subject: [PATCH 082/123] Translated using Weblate (Czech) Currently translated at 59.0% (505 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/cs/ --- src/i18n/strings/cs.json | 100 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 99 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index 31a52593b0..0100711b2e 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -405,5 +405,103 @@ "Updates": "Aktualizace", "Check for update": "Zkontrolovat aktualizace", "Start chatting": "Začít chatovat", - "Start Chatting": "Začít chatovat" + "Start Chatting": "Začít chatovat", + "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Textová zpráva byla odeslána na +%(msisdn)s. Prosím vložte ověřovací kód z dané zprávy", + "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s přijmul/a pozvánku pro %(displayName)s.", + "Active call (%(roomName)s)": "Probíhající hovor (%(roomName)s)", + "An email has been sent to": "Email byl odeslán odeslán na", + "%(senderName)s banned %(targetName)s.": "%(senderName)s zablokoval/a %(targetName)s.", + "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Nelze se připojit k homeserveru přes HTTP pokud je v adresním řádku HTTPS. Buď použijte HTTPS nebo povolte nebezpečné scripty.", + "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s změnil/a zobrazované jméno z %(oldDisplayName)s na %(displayName)s.", + "Click here to fix": "Klikněte zde pro opravu", + "Click to mute video": "Klikněte pro zakázání videa", + "click to reveal": "klikněte pro odhalení", + "Click to unmute video": "Klikněte pro povolení videa", + "Click to unmute audio": "Klikněte pro povolení zvuku", + "demote": "degradovat", + "Devices will not yet be able to decrypt history from before they joined the room": "Zařízení nebudou schopna dešifrovat historii před tím než se připojila k místnosti", + "Disable markdown formatting": "Zakázat formátování v markdownu", + "Displays action": "Zobrazí akci", + "Do you want to load widget from URL:": "Chcete načíst widget z URL:", + "Ed25519 fingerprint": "Ed25519 otisk", + "favourite": "oblíbené", + "Fill screen": "Vyplnit obrazovku", + "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s z %(fromPowerLevel)s na %(toPowerLevel)s", + "This doesn't appear to be a valid email address": "Emailová adresa se zdá být nevalidní", + "This is a preview of this room. Room interactions have been disabled": "Toto je náhled místnosti. Interakce byly zakázány", + "This phone number is already in use": "Tohle číslo už se používá", + "This room is not accessible by remote Matrix servers": "Tahle místnost není přístupná vzdálenými Matrix servery", + "This room's internal ID is": "Vnitřní ID místnosti je", + "times": "krát", + "To ban users": "Zablokovat uživatele", + "to browse the directory": "prohlížet adresář", + "To configure the room": "Nastavit místnost", + "To invite users into the room": "Pozvat uživatele do místnosti", + "To kick users": "Vyhodit uživatele", + "to make a room or": "vytvořit místnost nebo", + "To remove other users' messages": "Smazat zprávy ostatních uživatelů", + "To reset your password, enter the email address linked to your account": "K resetování hesla, vložte emailovou adresu spojenou s vaším účtem", + "to restore": "obnovit", + "To send events of type": "Odeslat události typu", + "To send messages": "Odeslat zprávy", + "to start a chat with someone": "začít chat s někým", + "to tag as %(tagName)s": "oštítkovat jako %(tagName)s", + "to tag direct chat": "oštítkovat přímý chat", + "To use it, just wait for autocomplete results to load and tab through them.": "Pro použití vyčkejte k načtení automatického doplňování a tabem přeskakujte mezi výsledky.", + "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Nemáte práva k zobrazení zprávy v daném časovém úseku.", + "Tried to load a specific point in this room's timeline, but was unable to find it.": "Zpráva v daném časovém úsaku nenalezena.", + "Turn Markdown off": "Vypnout Markdown", + "Turn Markdown on": "Zapnout Markdown", + "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s zapnul end-to-end šifrování (algoritmus %(algorithm)s).", + "Unable to add email address": "Nepodařilo se přidat emailovou adresu", + "Unable to create widget.": "Nepodařilo se vytvořit widget.", + "Unable to remove contact information": "Nepodařilo se smazat kontaktní údaje", + "Unable to restore previous session": "Nepodařilo se obnovit předchozí sezení", + "Unable to verify email address.": "Nepodařilo se ověřit emailovou adresu.", + "Unban": "Odblokovat", + "Unbans user with given id": "Odblokuje uživatele s daným id", + "%(senderName)s unbanned %(targetName)s.": "%(senderName)s odblokoval/a %(targetName)s.", + "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Nepodařilo se prokázat že adresa na kterou byla tato pozvánka odeslána se shoduje s adresou přiřazenou Vašemu účtu.", + "Unable to capture screen": "Nepodařilo se zachytit obrazovku", + "Unable to enable Notifications": "Nepodařilo se povolit Notifikace", + "Unable to load device list": "Nepodařilo se načíst list zařízení", + "Undecryptable": "Nerozšifrovatelné", + "unencrypted": "nešifrované", + "Unencrypted message": "Nešifrovaná zpráva", + "unknown caller": "neznámý volající", + "unknown device": "neznámé zařízení", + "Unknown room %(roomId)s": "Neznámá místnost %(roomId)s", + "Unknown (user, device) pair:": "Neznámý pár (uživatel, zařízení):", + "unknown": "neznámý", + "Unmute": "Povolit", + "Unnamed Room": "Nepojmenovaná Místnost", + "Unrecognised command:": "Nerozpoznaný příkaz:", + "Unrecognised room alias:": "Nerozpoznaný alias místnosti:", + "Unverified": "Neověřený", + "Uploading %(filename)s and %(count)s others|zero": "Nahrávám %(filename)s", + "Uploading %(filename)s and %(count)s others|one": "Nahrávám %(filename)s a %(count)s další", + "Uploading %(filename)s and %(count)s others|other": "Nahrávám %(filename)s a %(count)s další", + "Upload Failed": "Nahrávání Selhalo", + "Upload Files": "Nahrát Soubory", + "Upload file": "Nahrát soubor", + "Upload new:": "Nahrát nový:", + "Usage": "Použití", + "Use compact timeline layout": "Použít kompaktní rozvržení timeline", + "Use with caution": "Používejte s opatrností", + "User ID": "Uživatelské ID", + "User Interface": "Uživatelské rozhraní", + "%(user)s is a": "%(user)s je", + "User name": "Uživatelské jméno", + "Username invalid: %(errMessage)s": "Nevalidní uživatelské jméno: %(errMessage)s", + "Users": "Uživatelé", + "User": "Uživatel", + "Verification Pending": "Čeká na ověření", + "Verification": "Ověření", + "verified": "ověreno", + "Verified": "Ověřeno", + "Verified key": "Ověřen klíč", + "(no answer)": "(žádná odpověď)", + "(unknown failure: %(reason)s)": "(neznámá chyba: %(reason)s)", + "(warning: cannot be disabled again!)": "(varování: nemůže být opět zakázáno!)", + "WARNING: Device already verified, but keys do NOT MATCH!": "VAROVÁNÍ: Zařízení ověřeno, ale klíče se NESHODUJÍ!" } From 9cee2b3662adbded6cdc62a996d3b6dec112d450 Mon Sep 17 00:00:00 2001 From: Andrey Date: Mon, 9 Oct 2017 19:13:50 +0000 Subject: [PATCH 083/123] Translated using Weblate (Russian) Currently translated at 100.0% (855 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 48 ++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 8f317031be..2bbf72f87c 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -3,7 +3,7 @@ "accepted an invitation": "принял приглашение", "accepted the invitation for": "принял приглашение на", "Account": "Аккаунт", - "Add email address": "Добавить адрес эл. почты", + "Add email address": "Добавить адрес email", "Add phone number": "Добавить номер телефона", "Admin": "Администратор", "Advanced": "Дополнительно", @@ -79,7 +79,7 @@ "Failed to forget room": "Не удалось забыть комнату", "Failed to leave room": "Не удалось выйти из комнаты", "Failed to reject invitation": "Не удалось отклонить приглашение", - "Failed to send email": "Ошибка отправки эл. почты", + "Failed to send email": "Ошибка отправки email", "Failed to unban": "Не удалось разблокировать", "Failed to upload file": "Не удалось отправить файл", "Favourite": "Избранное", @@ -95,9 +95,9 @@ "Historical": "Архив", "Homeserver is": "Домашний сервер это", "Identity Server is": "Сервер идентификации это", - "I have verified my email address": "Я подтвердил свой адрес эл. почты", + "I have verified my email address": "Я подтвердил свой адрес email", "Import E2E room keys": "Импорт ключей сквозного шифрования", - "Invalid Email Address": "Недопустимый адрес эл. почты", + "Invalid Email Address": "Недопустимый адрес email", "invited": "invited", "Invite new room members": "Пригласить новых участников в комнату", "Invites": "Приглашает", @@ -165,9 +165,9 @@ "To send events of type": "Чтобы отправить тип события", "To send messages": "Чтобы отправить сообщения", "turned on end-to-end encryption (algorithm": "turned on end-to-end encryption (algorithm", - "Unable to add email address": "Не удается добавить адрес эл. почты", + "Unable to add email address": "Не удается добавить адрес email", "Unable to remove contact information": "Не удалось удалить контактную информацию", - "Unable to verify email address.": "Не удалось проверить адрес эл. почты.", + "Unable to verify email address.": "Не удалось проверить адрес email.", "Unban": "Разблокировать", "Unencrypted room": "Незашифрованная комната", "unencrypted": "без шифрования", @@ -239,7 +239,7 @@ "Failed to lookup current room": "Не удалось выполнить поиск текущий комнаты", "Failed to send request.": "Не удалось отправить запрос.", "Failed to set up conference call": "Не удалось настроить групповой вызов", - "Failed to verify email address: make sure you clicked the link in the email": "Не удалось проверить адрес эл. почты: убедитесь, что вы перешли по ссылке в письме", + "Failed to verify email address: make sure you clicked the link in the email": "Не удалось проверить адрес email: убедитесь, что вы перешли по ссылке в письме", "Failure to create room": "Не удалось создать комнату", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s с %(fromPowerLevel)s на %(toPowerLevel)s", "Guest users can't create new rooms. Please register to create room and start a chat.": "Гости не могут создавать новые комнаты. Зарегистрируйтесь, чтобы создать комнату и начать чат.", @@ -267,7 +267,7 @@ "Set a display name:": "Введите отображаемое имя:", "Passwords don't match.": "Пароли не совпадают.", "Password too short (min %(MIN_PASSWORD_LENGTH)s).": "Пароль слишком короткий (мин. %(MIN_PASSWORD_LENGTH)s).", - "This doesn't look like a valid email address.": "Это не похоже на допустимый адрес эл. почты.", + "This doesn't look like a valid email address.": "Это не похоже на допустимый адрес email.", "This server does not support authentication with a phone number.": "Этот сервер не поддерживает аутентификацию с помощью номера телефона.", "User names may only contain letters, numbers, dots, hyphens and underscores.": "Имена пользователей могут содержать только буквы, цифры, точки, дефисы и символы подчеркивания.", "An unknown error occurred.": "Произошла неизвестная ошибка.", @@ -314,7 +314,7 @@ "Thu": "Чт", "Fri": "Пт", "Sat": "Сб", - "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Ваш адрес эл. почты, кажется, не связан с Matrix ID на этом домашнем сервере.", + "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Ваш адрес email, кажется, не связан с Matrix ID на этом домашнем сервере.", "to start a chat with someone": "чтобы начать чат с кем-то", "to tag direct chat": "отметить прямой чат", "To use it, just wait for autocomplete results to load and tab through them.": "Для того, чтобы использовать эту функцию, просто подождите автозаполнения результатов, а затем используйте клавишу TAB для прокрутки.", @@ -366,7 +366,7 @@ "Command error": "Ошибка команды", "Confirm password": "Подтвердите пароль", "Current password": "Текущий пароль", - "Email": "Эл. почта", + "Email": "Электронная почта", "Failed to kick": "Не удалось выгнать", "Failed to load timeline position": "Не удалось загрузить метку из хронологии", "Failed to mute user": "Не удалось заглушить пользователя", @@ -452,15 +452,15 @@ "The default role for new room members is": "Роль по умолчанию для новых участников комнаты", "The main address for this room is": "Основной адрес для этой комнаты", "This action cannot be performed by a guest user. Please register to be able to do this.": "Это действие не может быть выполнено гостем. Пожалуйста, зарегистрируйтесь, чтобы получить возможность сделать то что вы хотите.", - "This email address is already in use": "Этот адрес эл. почты уже используется", - "This email address was not found": "Этот адрес эл. почты не найден", - "The email address linked to your account must be entered.": "Необходимо ввести адрес эл. почты, связанный с вашей учетной записью.", + "This email address is already in use": "Этот адрес email уже используется", + "This email address was not found": "Этот адрес email не найден", + "The email address linked to your account must be entered.": "Необходимо ввести адрес email, связанный с вашей учетной записью.", "The file '%(fileName)s' failed to upload": "Не удалось отправить файл '%(fileName)s'", "The remote side failed to pick up": "Вызываемый абонент не ответил", "This room has no local addresses": "В этой комнате нет локальных адресов", "This room is not recognised.": "Эта комната не опознана.", "These are experimental features that may break in unexpected ways": "Это экспериментальные функции, которые могут себя вести неожиданным образом", - "This doesn't appear to be a valid email address": "Похоже, это недействительный адрес эл. почты", + "This doesn't appear to be a valid email address": "Похоже, это недействительный адрес email", "This is a preview of this room. Room interactions have been disabled": "Это предпросмотр комнаты. Взаимодействие с комнатой отключено", "This phone number is already in use": "Этот номер телефона уже используется", "This room's internal ID is": "Внутренний ID этой комнаты", @@ -567,8 +567,8 @@ "Device key:": "Ключ устройства:", "disabled": "отключено", "Disable markdown formatting": "Отключить Markdown-форматирование", - "Email address": "Адрес эл. почты", - "Email address (optional)": "Адрес эл. почты (необязательно)", + "Email address": "Адрес email", + "Email address (optional)": "Адрес email (необязательно)", "enabled": "включено", "Error decrypting attachment": "Ошибка при расшифровке вложения", "Export": "Экспорт", @@ -608,7 +608,7 @@ "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Предоставленный ключ подписи соответствует ключу, полученному от %(userId)s с устройства %(deviceId)s. Устройство помечено как проверенное.", "%(actionVerb)s this person?": "%(actionVerb)s этот человек?", "The file '%(fileName)s' exceeds this home server's size limit for uploads": "Файл '%(fileName)s' превышает предельный размер, допустимый к отправке на этом домашнем сервере", - "This Home Server does not support login using email address.": "Этот домашний сервер не поддерживает авторизацию с использованием адреса эл. почты.", + "This Home Server does not support login using email address.": "Этот домашний сервер не поддерживает авторизацию с использованием адреса email.", "There was a problem logging in.": "Возникла проблема при авторизации.", "The visibility of existing history will be unchanged": "Видимость существующей истории не изменится", "this invitation?": "это приглашение?", @@ -622,7 +622,7 @@ "To link to a room it must have": "Для создания ссылки на комнату она должна иметь", "to make a room or": "чтобы создать комнату или", "To remove other users' messages": "Чтобы удалить сообщения других пользователей", - "To reset your password, enter the email address linked to your account": "Чтобы сбросить пароль, введите адрес эл. почты, связанный с вашей учетной записью", + "To reset your password, enter the email address linked to your account": "Чтобы сбросить пароль, введите адрес email, связанный с вашей учетной записью", "to tag as %(tagName)s": "пометить как %(tagName)s", "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Попытка загрузить выбранный интервал истории чата этой комнаты не удалась, так как у вас нет разрешений на просмотр.", "Tried to load a specific point in this room's timeline, but was unable to find it.": "Попытка загрузить выбранный интервал истории чата этой комнаты не удалась, так как запрошенный элемент не найден.", @@ -636,7 +636,7 @@ "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "ВНИМАНИЕ: ОШИБКА ПРОВЕРКИ КЛЮЧЕЙ! Ключ подписи пользователя %(userId)s на устройстве %(deviceId)s — \"%(fprint)s\", и он не соответствует предоставленному ключу \"%(fingerprint)s\". Это может означать, что ваше общение перехватывается!", "You have disabled URL previews by default.": "Предварительный просмотр ссылок отключен по-умолчанию.", "You have enabled URL previews by default.": "Предварительный просмотр ссылок включен по-умолчанию.", - "You have entered an invalid contact. Try using their Matrix ID or email address.": "Вы ввели недопустимый контакт. Попробуйте использовать Matrix ID или адрес эл. почты.", + "You have entered an invalid contact. Try using their Matrix ID or email address.": "Вы ввели недопустимый контакт. Попробуйте использовать Matrix ID или адрес email.", "You need to enter a user name.": "Необходимо ввести имя пользователя.", "You seem to be in a call, are you sure you want to quit?": "Звонок не завершен, вы уверены, что хотите выйти?", "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Вы не сможете отменить это изменение, так как этот пользователь получит уровень доступа, аналогичный вашему.", @@ -699,12 +699,12 @@ "Sign in with CAS": "Войти с помощью CAS", "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "Вы можете использовать настраиваемые параметры сервера для входа на другие серверы Matrix, указав другой URL-адрес домашнего сервера.", "This allows you to use this app with an existing Matrix account on a different home server.": "Это позволяет использовать это приложение с существующей учетной записью Matrix на другом домашнем сервере.", - "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "Вы также можете установить другой сервер идентификации, но это, как правило, будет препятствовать взаимодействию с пользователями на основе адреса эл. почты.", + "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "Вы также можете установить другой сервер идентификации, но это, как правило, будет препятствовать взаимодействию с пользователями на основе адреса email.", "Please check your email to continue registration.": "Проверьте электронную почту, чтобы продолжить регистрацию.", "Token incorrect": "Неверный токен", "A text message has been sent to": "Текстовое сообщение отправлено", "Please enter the code it contains:": "Введите полученный код:", - "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Если адрес эл. почты не указан, сброс пароля будет невозможным. Уверены?", + "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Если адрес email не указан, сброс пароля будет невозможным. Уверены?", "You are registering with %(SelectedTeamName)s": "Вы регистрируетесь на %(SelectedTeamName)s", "Default server": "Сервер по умолчанию", "Custom server": "Пользовательский сервер", @@ -807,7 +807,7 @@ "Seen by %(userName)s at %(dateTime)s": "Просмотрено %(userName)s в %(dateTime)s", "Send anyway": "Отправить в любом случае", "Show Text Formatting Toolbar": "Показать панель инструментов форматирования текста", - "This invitation was sent to an email address which is not associated with this account:": "Это приглашение было отправлено на адрес эл. почты, не связанный с этой учетной записью:", + "This invitation was sent to an email address which is not associated with this account:": "Это приглашение было отправлено на адрес email, не связанный с этой учетной записью:", "To link to a room it must have an address.": "Чтобы связаться с комнатой, она должна иметь адрес.", "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Не удалось установить соответствует ли адрес, по которому этому приглашение было послано, вашей учетной записи.", "Undecryptable": "Невозможно расшифровать", @@ -824,7 +824,7 @@ "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.": "Не удается подключиться к домашнему серверу - проверьте подключение, убедитесь, что ваш SSL-сертификат домашнего сервера является доверенным и что расширение браузера не блокирует запросы.", "You have been banned from %(roomName)s by %(userName)s.": "%(userName)s заблокировал вас в %(roomName)s.", "You have been kicked from %(roomName)s by %(userName)s.": "%(userName)s выгнал вас из %(roomName)s.", - "You may wish to login with a different account, or add this email to this account.": "При желании вы можете войти в систему с другой учетной записью или добавить этот адрес эл. почты в эту учетную запись.", + "You may wish to login with a different account, or add this email to this account.": "При желании вы можете войти в систему с другой учетной записью или добавить этот адрес email в эту учетную запись.", "Your home server does not support device management.": "Ваш домашний сервер не поддерживает управление устройствами.", "(could not connect media)": "(подключение к СМИ не может быть установлено)", "(no answer)": "(нет ответа)", @@ -833,7 +833,7 @@ "Not a valid Riot keyfile": "Недействительный файл ключа Riot", "Your browser does not support the required cryptography extensions": "Ваш браузер не поддерживает требуемые криптографические расширения", "Authentication check failed: incorrect password?": "Ошибка аутентификации: неправильный пароль?", - "Do you want to set an email address?": "Хотите указать адрес эл. почты?", + "Do you want to set an email address?": "Хотите указать адрес email?", "This will allow you to reset your password and receive notifications.": "Это позволит при необходимости сбросить пароль и получать уведомления.", "Press to start a chat with someone": "Нажмите для начала чата с кем-либо", "You're not in any rooms yet! Press to make a room or to browse the directory": "Вы еще не вошли ни в одну из комнат! Нажмите , чтобы создать комнату или для просмотра каталога", From b4d6d654ca20d40f37162e92cbcf4b4ec6c8900d Mon Sep 17 00:00:00 2001 From: Pitchaya Boonsarngsuk Date: Thu, 5 Oct 2017 00:10:05 +0000 Subject: [PATCH 084/123] Translated using Weblate (Thai) Currently translated at 61.4% (525 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/th/ --- src/i18n/strings/th.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/th.json b/src/i18n/strings/th.json index 9a484dfd1a..4a08e3d1eb 100644 --- a/src/i18n/strings/th.json +++ b/src/i18n/strings/th.json @@ -525,7 +525,7 @@ "Verified": "ตรวจสอบแล้ว", "You are already in a call.": "คุณอยู่ในสายแล้ว", "You cannot place a call with yourself.": "คุณไม่สามารถโทรหาตัวเองได้", - "Unverify": "ถอนการตรวสอบ", + "Unverify": "ถอนการตรวจสอบ", "Verify...": "ตรวจสอบ...", "What does this mean?": "นี่แปลว่าอะไร?", "Error decrypting audio": "เกิดข้อผิดพลาดในการถอดรหัสเสียง", From fa24b4bd2de325154cc32d0237b9fe5904c794cd Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 11 Oct 2017 09:48:12 +0100 Subject: [PATCH 085/123] Remove this log - it's not an error worth logging --- src/components/views/login/PasswordLogin.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/views/login/PasswordLogin.js b/src/components/views/login/PasswordLogin.js index 4e37e30f65..7e78de3f54 100644 --- a/src/components/views/login/PasswordLogin.js +++ b/src/components/views/login/PasswordLogin.js @@ -192,7 +192,6 @@ class PasswordLogin extends React.Component { const parsedHsUrl = new URL(this.props.hsUrl); matrixIdText = _t('%(serverName)s Matrix ID', {serverName: parsedHsUrl.hostname}); } catch (e) { - console.log(e); // pass } } From 6ad0f2d8f8f77b96d07a38bf280f599eb0c550e3 Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 11 Oct 2017 10:50:03 +0000 Subject: [PATCH 086/123] Translated using Weblate (Russian) Currently translated at 100.0% (855 of 855 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-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 2bbf72f87c..d1449ae7c1 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -262,7 +262,7 @@ "Connectivity to the server has been lost.": "Связь с сервером потеряна.", "Sent messages will be stored until your connection has returned.": "Отправленные сообщения будут сохранены, пока соединение не восстановится.", "There are no visible files in this room": "В этой комнате нет видимых файлов", - "This doesn't look like a valid phone number.": "Это не похоже на допустимый телефонный номер.", + "This doesn't look like a valid phone number.": "Недопустимый номер телефона.", "Missing password.": "Отсутствует пароль.", "Set a display name:": "Введите отображаемое имя:", "Passwords don't match.": "Пароли не совпадают.", From 0f84216a9fea9c0cf38d6ae1ab30e0062bf707a1 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 11 Oct 2017 14:05:34 +0100 Subject: [PATCH 087/123] Grey out login form when no valid HS --- src/components/views/elements/Dropdown.js | 1 + src/components/views/login/CountryDropdown.js | 3 +- src/components/views/login/PasswordLogin.js | 46 +++++++++++++------ 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/components/views/elements/Dropdown.js b/src/components/views/elements/Dropdown.js index 1b2117bb6a..0fb5a37414 100644 --- a/src/components/views/elements/Dropdown.js +++ b/src/components/views/elements/Dropdown.js @@ -302,6 +302,7 @@ export default class Dropdown extends React.Component { const dropdownClasses = { mx_Dropdown: true, + mx_Dropdown_disabled: this.props.disabled, }; if (this.props.className) { dropdownClasses[this.props.className] = true; diff --git a/src/components/views/login/CountryDropdown.js b/src/components/views/login/CountryDropdown.js index 7024db339c..56ab962d98 100644 --- a/src/components/views/login/CountryDropdown.js +++ b/src/components/views/login/CountryDropdown.js @@ -123,7 +123,7 @@ export default class CountryDropdown extends React.Component { return {options} ; @@ -137,4 +137,5 @@ CountryDropdown.propTypes = { showPrefix: React.PropTypes.bool, onOptionChange: React.PropTypes.func.isRequired, value: React.PropTypes.string, + disabled: React.PropTypes.bool, }; diff --git a/src/components/views/login/PasswordLogin.js b/src/components/views/login/PasswordLogin.js index 7e78de3f54..d532c400bc 100644 --- a/src/components/views/login/PasswordLogin.js +++ b/src/components/views/login/PasswordLogin.js @@ -116,11 +116,17 @@ class PasswordLogin extends React.Component { this.props.onPasswordChanged(ev.target.value); } - renderLoginField(loginType) { + renderLoginField(loginType, disabled) { + const classes = { + mx_Login_field: true, + mx_Login_field_disabled: disabled, + }; + switch(loginType) { case PasswordLogin.LOGIN_FIELD_EMAIL: + classes.mx_Login_email = true; return ; case PasswordLogin.LOGIN_FIELD_MXID: + classes.mx_Login_username = true; return ; case PasswordLogin.LOGIN_FIELD_PHONE: const CountryDropdown = sdk.getComponent('views.login.CountryDropdown'); + classes.mx_Login_phoneNumberField = true; + classes.mx_Login_field_has_prefix = true; return
; } @@ -177,15 +190,6 @@ class PasswordLogin extends React.Component { ); } - const pwFieldClass = classNames({ - mx_Login_field: true, - error: this.props.loginIncorrect, - }); - - const Dropdown = sdk.getComponent('elements.Dropdown'); - - const loginField = this.renderLoginField(this.state.loginType); - let matrixIdText = ''; if (this.props.hsUrl) { try { @@ -196,6 +200,16 @@ class PasswordLogin extends React.Component { } } + const pwFieldClass = classNames({ + mx_Login_field: true, + mx_Login_field_disabled: matrixIdText === '', + error: this.props.loginIncorrect, + }); + + const Dropdown = sdk.getComponent('elements.Dropdown'); + + const loginField = this.renderLoginField(this.state.loginType, matrixIdText === ''); + return (
@@ -215,10 +229,12 @@ class PasswordLogin extends React.Component { {this._passwordField = e;}} type="password" name="password" value={this.state.password} onChange={this.onPasswordChanged} - placeholder={ _t('Password') } /> + placeholder={ _t('Password') } + disabled={matrixIdText === ''} + />
{forgotPasswordJsx} - +
); From 36666b3fc387ef7888f477f019ffc8546c76501a Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 11 Oct 2017 15:04:52 +0100 Subject: [PATCH 088/123] Add warm fuzzy dialog for inviting users to a group --- src/GroupAddressPicker.js | 7 +++++++ src/i18n/strings/en_EN.json | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/GroupAddressPicker.js b/src/GroupAddressPicker.js index cfd2590780..ca495de16d 100644 --- a/src/GroupAddressPicker.js +++ b/src/GroupAddressPicker.js @@ -76,6 +76,13 @@ function _onGroupInviteFinished(groupId, addrs) { title: _t("Failed to invite the following users to %(groupId)s:", {groupId: groupId}), description: errorList.join(", "), }); + } else { + const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); + Modal.createTrackedDialog('Group invitations sent', '', QuestionDialog, { + title: _t("Invites sent"), + description: _t("Your group invitations have been sent."), + hasCancelButton: false, + }); } }).catch((err) => { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 6acaba9fae..aaabea1011 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -906,5 +906,7 @@ "Related Groups": "Related Groups", "Related groups for this room:": "Related groups for this room:", "This room has no related groups": "This room has no related groups", - "New group ID (e.g. +foo:%(localDomain)s)": "New group ID (e.g. +foo:%(localDomain)s)" + "New group ID (e.g. +foo:%(localDomain)s)": "New group ID (e.g. +foo:%(localDomain)s)", + "Invites sent": "Invites sent", + "Your group invitations have been sent.": "Your group invitations have been sent." } From 0ab5b1a6af3598c52102bcea24029244c398e54d Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 11 Oct 2017 08:50:28 -0600 Subject: [PATCH 089/123] _td translatable strings Signed-off-by: Travis Ralston --- src/components/views/rooms/RoomSettings.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index b3b27875a0..e6d3bc7d71 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -17,7 +17,7 @@ limitations under the License. import Promise from 'bluebird'; import React from 'react'; -import { _t, _tJsx } from '../../../languageHandler'; +import { _t, _tJsx, _td } from '../../../languageHandler'; import MatrixClientPeg from '../../../MatrixClientPeg'; import SdkConfig from '../../../SdkConfig'; import sdk from '../../../index'; @@ -37,15 +37,14 @@ function parseIntWithDefault(val, def) { const plEventsToLabels = { // These will be translated for us later. - // TODO: _td() these when https://github.com/matrix-org/matrix-react-sdk/pull/1421 lands - "m.room.avatar": "To change the room's avatar, you must be a", - "m.room.name": "To change the room's name, you must be a", - "m.room.canonical_alias": "To change the room's main address, you must be a", - "m.room.history_visibility": "To change the room's history visibility, you must be a", - "m.room.power_levels": "To change the permissions in the room, you must be a", - "m.room.topic": "To change the topic, you must be a", + "m.room.avatar": _td("To change the room's avatar, you must be a"), + "m.room.name": _td("To change the room's name, you must be a"), + "m.room.canonical_alias": _td("To change the room's main address, you must be a"), + "m.room.history_visibility": _td("To change the room's history visibility, you must be a"), + "m.room.power_levels": _td("To change the permissions in the room, you must be a"), + "m.room.topic": _td("To change the topic, you must be a"), - "im.vector.modular.widgets": "To modify widgets in the room, you must be a", + "im.vector.modular.widgets": _td("To modify widgets in the room, you must be a"), }; const plEventsToShow = { From 060bf3bdf64a7e23c24d19f35c0e2f4f3910afe2 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 11 Oct 2017 16:02:01 +0100 Subject: [PATCH 090/123] Remove inline CSS --- src/components/views/elements/Flair.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/elements/Flair.js b/src/components/views/elements/Flair.js index 84c0c2a187..ceab20bf19 100644 --- a/src/components/views/elements/Flair.js +++ b/src/components/views/elements/Flair.js @@ -265,7 +265,7 @@ export default class Flair extends React.Component { return ; }); return ( - + { avatars } ); From d1fdd208097142b9bfdbbf2fc115b271af2bf2bf Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 29 Sep 2017 16:04:12 -0600 Subject: [PATCH 091/123] Show who banned the user on hover Fixes https://github.com/vector-im/riot-web/issues/5039 Signed-off-by: Travis Ralston --- src/components/views/rooms/RoomSettings.js | 10 +++++++--- src/i18n/strings/en_EN.json | 1 + src/i18n/strings/en_US.json | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index 031e089c4e..05116bc097 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -39,6 +39,7 @@ const BannedUser = React.createClass({ propTypes: { canUnban: React.PropTypes.bool, member: React.PropTypes.object.isRequired, // js-sdk RoomMember + by: React.PropTypes.object.isRequired, // js-sdk RoomMember reason: React.PropTypes.string, }, @@ -77,8 +78,10 @@ const BannedUser = React.createClass({ return (
  • { unbanButton } - {this.props.member.name} {this.props.member.userId} - {this.props.reason ? " " +_t('Reason') + ": " + this.props.reason : ""} + + {this.props.member.name} {this.props.member.userId} + {this.props.reason ? " " +_t('Reason') + ": " + this.props.reason : ""} +
  • ); }, @@ -670,8 +673,9 @@ module.exports = React.createClass({
      {banned.map(function(member) { const banEvent = member.events.member.getContent(); + const bannedBy = self.props.room.getMember(member.events.member.getSender()); return ( - + ); })}
    diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index cf2be3c2f8..9e5524d80c 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -808,6 +808,7 @@ "This will allow you to reset your password and receive notifications.": "This will allow you to reset your password and receive notifications.", "To return to your account in future you need to set a password": "To return to your account in future you need to set a password", "Skip": "Skip", + "Banned by %(displayName)s (%(userId)s)": "Banned by %(displayName)s (%(userId)s)", "Start verification": "Start verification", "Share without verifying": "Share without verifying", "Ignore request": "Ignore request", diff --git a/src/i18n/strings/en_US.json b/src/i18n/strings/en_US.json index 3954b2b6fa..93b3e88332 100644 --- a/src/i18n/strings/en_US.json +++ b/src/i18n/strings/en_US.json @@ -607,6 +607,7 @@ "Desktop specific": "Desktop specific", "Analytics": "Analytics", "Opt out of analytics": "Opt out of analytics", + "Banned by %(displayName)s (%(userId)s)": "Banned by %(displayName)s (%(userId)s)", "Options": "Options", "Riot collects anonymous analytics to allow us to improve the application.": "Riot collects anonymous analytics to allow us to improve the application.", "Passphrases must match": "Passphrases must match", From 8a2813ac08e212fef2aa62b14ff7d800f7ab2923 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 11 Oct 2017 09:05:54 -0600 Subject: [PATCH 092/123] Fallback to MXID instead of relying on the user being in the room Signed-off-by: Travis Ralston --- src/components/views/rooms/RoomSettings.js | 8 +++++--- src/i18n/strings/en_EN.json | 2 +- src/i18n/strings/en_US.json | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index 05116bc097..b62b72bf18 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -39,7 +39,7 @@ const BannedUser = React.createClass({ propTypes: { canUnban: React.PropTypes.bool, member: React.PropTypes.object.isRequired, // js-sdk RoomMember - by: React.PropTypes.object.isRequired, // js-sdk RoomMember + by: React.PropTypes.string.isRequired, reason: React.PropTypes.string, }, @@ -78,7 +78,7 @@ const BannedUser = React.createClass({ return (
  • { unbanButton } - + {this.props.member.name} {this.props.member.userId} {this.props.reason ? " " +_t('Reason') + ": " + this.props.reason : ""} @@ -673,7 +673,9 @@ module.exports = React.createClass({
      {banned.map(function(member) { const banEvent = member.events.member.getContent(); - const bannedBy = self.props.room.getMember(member.events.member.getSender()); + const sender = self.props.room.getMember(member.events.member.getSender()); + let bannedBy = member.events.member.getSender(); // start by falling back to mxid + if (sender) bannedBy = sender.name; return ( ); diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 9e5524d80c..f6edae19a9 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -808,7 +808,7 @@ "This will allow you to reset your password and receive notifications.": "This will allow you to reset your password and receive notifications.", "To return to your account in future you need to set a password": "To return to your account in future you need to set a password", "Skip": "Skip", - "Banned by %(displayName)s (%(userId)s)": "Banned by %(displayName)s (%(userId)s)", + "Banned by %(displayName)s": "Banned by %(displayName)s", "Start verification": "Start verification", "Share without verifying": "Share without verifying", "Ignore request": "Ignore request", diff --git a/src/i18n/strings/en_US.json b/src/i18n/strings/en_US.json index 93b3e88332..fccf387f30 100644 --- a/src/i18n/strings/en_US.json +++ b/src/i18n/strings/en_US.json @@ -607,7 +607,7 @@ "Desktop specific": "Desktop specific", "Analytics": "Analytics", "Opt out of analytics": "Opt out of analytics", - "Banned by %(displayName)s (%(userId)s)": "Banned by %(displayName)s (%(userId)s)", + "Banned by %(displayName)s": "Banned by %(displayName)s", "Options": "Options", "Riot collects anonymous analytics to allow us to improve the application.": "Riot collects anonymous analytics to allow us to improve the application.", "Passphrases must match": "Passphrases must match", From 5626c06b3ccc0de5b02ea4ab9ced91f7f0fd6651 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 11 Oct 2017 17:42:54 +0100 Subject: [PATCH 093/123] Show failures when sending messages This is useful for the spam checking where otherwise you don't really know why your message has failed to send --- src/components/structures/RoomView.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index e0332b1b19..e5c730233d 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -738,6 +738,17 @@ module.exports = React.createClass({ _getUnsentMessageError: function(room) { const unsentMessages = this._getUnsentMessages(room); if (!unsentMessages.length) return ""; + + if ( + unsentMessages.length === 1 && + unsentMessages[0].error && + unsentMessages[0].error.data && + unsentMessages[0].error.data.error && + unsentMessages[0].error.name !== "UnknownDeviceError" + ) { + return unsentMessages[0].error.data.error; + } + for (const event of unsentMessages) { if (!event.error || event.error.name !== "UnknownDeviceError") { return _t("Some of your messages have not been sent."); From d3f9a3aeb55aaf6a746a12d9d6f9a27df54654fe Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 11 Oct 2017 17:56:17 +0100 Subject: [PATCH 094/123] Run eslint --fix Fixing 1000s of lint issues. Some rules cannot be `--fix`ed but this goes some way to linting the entire codebase. --- src/CallHandler.js | 89 ++--- src/ContentMessages.js | 53 ++- src/HtmlUtils.js | 65 ++-- src/ImageUtils.js | 7 +- src/Login.js | 16 +- src/Markdown.js | 6 +- src/MatrixClientPeg.js | 8 +- src/Modal.js | 22 +- src/Notifier.js | 4 +- src/Presence.js | 14 +- src/RichText.js | 34 +- src/Rooms.js | 3 +- src/ScalarAuthClient.js | 14 +- src/ScalarMessaging.js | 21 +- src/Tinter.js | 83 +++-- src/Unread.js | 19 +- src/Velociraptor.js | 32 +- src/VelocityBounce.js | 4 +- src/WhoIsTyping.js | 16 +- .../views/dialogs/EncryptedEventDialog.js | 38 +-- src/autocomplete/Autocompleter.js | 2 +- src/autocomplete/Components.js | 18 +- src/autocomplete/DuckDuckGoProvider.js | 6 +- src/autocomplete/EmojiProvider.js | 7 +- src/autocomplete/UserProvider.js | 6 +- src/components/structures/ContextualMenu.js | 34 +- src/components/structures/CreateRoom.js | 70 ++-- src/components/structures/FilePanel.js | 35 +- src/components/structures/InteractiveAuth.js | 8 +- src/components/structures/LoggedInView.js | 17 +- src/components/structures/MessagePanel.js | 102 +++--- .../structures/NotificationPanel.js | 31 +- src/components/structures/RoomStatusBar.js | 64 ++-- src/components/structures/RoomView.js | 322 +++++++++--------- src/components/structures/ScrollPanel.js | 65 ++-- src/components/structures/TimelinePanel.js | 185 +++++----- src/components/structures/UploadBar.js | 32 +- .../structures/login/ForgotPassword.js | 82 +++-- src/components/structures/login/Login.js | 40 +-- .../structures/login/PostRegistration.js | 22 +- .../structures/login/Registration.js | 30 +- src/components/views/avatars/BaseAvatar.js | 53 ++- src/components/views/avatars/MemberAvatar.js | 16 +- .../views/create_room/CreateRoomButton.js | 4 +- src/components/views/create_room/Presets.js | 14 +- src/components/views/create_room/RoomAlias.js | 26 +- .../views/dialogs/ChatCreateOrReuseDialog.js | 4 +- .../views/dialogs/DeactivateAccountDialog.js | 20 +- .../views/dialogs/InteractiveAuthDialog.js | 8 +- .../views/dialogs/UnknownDeviceDialog.js | 34 +- .../views/elements/AccessibleButton.js | 2 +- src/components/views/elements/ActionButton.js | 4 +- .../views/elements/AddressSelector.js | 34 +- src/components/views/elements/AddressTile.js | 10 +- .../views/elements/CreateRoomButton.js | 2 +- .../views/elements/DeviceVerifyButtons.js | 18 +- .../views/elements/DirectorySearchBox.js | 2 +- src/components/views/elements/Dropdown.js | 26 +- src/components/views/elements/EditableText.js | 29 +- .../views/elements/EditableTextContainer.js | 10 +- src/components/views/elements/HomeButton.js | 2 +- .../views/elements/LanguageDropdown.js | 10 +- .../views/elements/MemberEventListSummary.js | 46 ++- .../views/elements/PowerSelector.js | 39 +-- src/components/views/elements/ProgressBar.js | 10 +- .../views/elements/RoomDirectoryButton.js | 2 +- .../views/elements/SettingsButton.js | 2 +- .../views/elements/StartChatButton.js | 2 +- src/components/views/elements/TintableSvg.js | 18 +- src/components/views/elements/UserSelector.js | 14 +- src/components/views/login/CaptchaForm.js | 25 +- src/components/views/login/CasLogin.js | 4 +- src/components/views/login/CountryDropdown.js | 8 +- .../views/login/CustomServerDialog.js | 24 +- .../login/InteractiveAuthEntryComponents.js | 36 +- src/components/views/login/LoginHeader.js | 4 +- src/components/views/login/PasswordLogin.js | 14 +- .../views/login/RegistrationForm.js | 60 ++-- src/components/views/login/ServerConfig.js | 57 ++-- src/components/views/messages/MAudioBody.js | 13 +- src/components/views/messages/MFileBody.js | 27 +- src/components/views/messages/MImageBody.js | 12 +- src/components/views/messages/MVideoBody.js | 19 +- src/components/views/messages/MessageEvent.js | 16 +- .../views/messages/RoomAvatarEvent.js | 28 +- src/components/views/messages/TextualBody.js | 92 +++-- src/components/views/messages/TextualEvent.js | 10 +- .../views/room_settings/AliasSettings.js | 81 +++-- .../views/room_settings/ColorSettings.js | 52 +-- .../views/room_settings/UrlPreviewSettings.js | 83 +++-- src/components/views/rooms/Autocomplete.js | 6 +- src/components/views/rooms/AuxPanel.js | 20 +- src/components/views/rooms/EntityTile.js | 61 ++-- src/components/views/rooms/EventTile.js | 147 ++++---- .../views/rooms/LinkPreviewWidget.js | 48 +-- .../views/rooms/MemberDeviceInfo.js | 16 +- src/components/views/rooms/MemberInfo.js | 201 ++++++----- src/components/views/rooms/MemberList.js | 77 ++--- src/components/views/rooms/MemberTile.js | 34 +- src/components/views/rooms/MessageComposer.js | 38 +-- .../views/rooms/MessageComposerInput.js | 13 +- src/components/views/rooms/PresenceLabel.js | 29 +- .../views/rooms/ReadReceiptMarker.js | 32 +- src/components/views/rooms/RoomList.js | 271 +++++++-------- src/components/views/rooms/RoomNameEditor.js | 22 +- src/components/views/rooms/RoomPreviewBar.js | 66 ++-- src/components/views/rooms/RoomSettings.js | 279 ++++++++------- src/components/views/rooms/RoomTile.js | 99 +++--- src/components/views/rooms/RoomTopicEditor.js | 14 +- .../views/rooms/SearchResultTile.js | 26 +- .../views/rooms/SearchableEntityList.js | 57 ++-- .../views/rooms/TopUnreadMessagesBar.js | 8 +- src/components/views/rooms/UserTile.js | 32 +- .../views/settings/AddPhoneNumber.js | 22 +- src/components/views/settings/ChangeAvatar.js | 50 +-- .../views/settings/ChangeDisplayName.js | 19 +- .../views/settings/ChangePassword.js | 20 +- src/components/views/settings/DevicesPanel.js | 20 +- .../views/settings/DevicesPanelEntry.js | 16 +- .../settings/EnableNotificationsButton.js | 14 +- src/languageHandler.js | 32 +- src/linkify-matrix.js | 75 ++-- src/ratelimitedfunc.js | 12 +- src/utils/DecryptFile.js | 6 +- src/utils/Receipt.js | 6 +- test/all-tests.js | 2 +- .../structures/MessagePanel-test.js | 74 ++-- .../components/structures/ScrollPanel-test.js | 54 +-- .../structures/TimelinePanel-test.js | 116 +++---- test/components/stub-component.js | 6 +- .../dialogs/InteractiveAuthDialog-test.js | 20 +- .../elements/MemberEventListSummary-test.js | 74 ++-- .../views/rooms/MessageComposerInput-test.js | 2 +- test/mock-clock.js | 64 ++-- test/skinned-sdk.js | 8 +- test/test-utils.js | 37 +- 136 files changed, 2540 insertions(+), 2657 deletions(-) diff --git a/src/CallHandler.js b/src/CallHandler.js index 8331d579df..a9539d40e1 100644 --- a/src/CallHandler.js +++ b/src/CallHandler.js @@ -63,23 +63,22 @@ import dis from './dispatcher'; global.mxCalls = { //room_id: MatrixCall }; -var calls = global.mxCalls; -var ConferenceHandler = null; +const calls = global.mxCalls; +let ConferenceHandler = null; -var audioPromises = {}; +const audioPromises = {}; function play(audioId) { // TODO: Attach an invisible element for this instead // which listens? - var audio = document.getElementById(audioId); + const audio = document.getElementById(audioId); if (audio) { if (audioPromises[audioId]) { audioPromises[audioId] = audioPromises[audioId].then(()=>{ audio.load(); return audio.play(); }); - } - else { + } else { audioPromises[audioId] = audio.play(); } } @@ -88,12 +87,11 @@ function play(audioId) { function pause(audioId) { // TODO: Attach an invisible element for this instead // which listens? - var audio = document.getElementById(audioId); + const audio = document.getElementById(audioId); if (audio) { if (audioPromises[audioId]) { audioPromises[audioId] = audioPromises[audioId].then(()=>audio.pause()); - } - else { + } else { // pause doesn't actually return a promise, but might as well do this for symmetry with play(); audioPromises[audioId] = audio.pause(); } @@ -125,38 +123,32 @@ function _setCallListeners(call) { if (newState === "ringing") { _setCallState(call, call.roomId, "ringing"); pause("ringbackAudio"); - } - else if (newState === "invite_sent") { + } else if (newState === "invite_sent") { _setCallState(call, call.roomId, "ringback"); play("ringbackAudio"); - } - else if (newState === "ended" && oldState === "connected") { + } else if (newState === "ended" && oldState === "connected") { _setCallState(undefined, call.roomId, "ended"); pause("ringbackAudio"); play("callendAudio"); - } - else if (newState === "ended" && oldState === "invite_sent" && + } else if (newState === "ended" && oldState === "invite_sent" && (call.hangupParty === "remote" || (call.hangupParty === "local" && call.hangupReason === "invite_timeout") )) { _setCallState(call, call.roomId, "busy"); pause("ringbackAudio"); play("busyAudio"); - var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); Modal.createTrackedDialog('Call Handler', 'Call Timeout', ErrorDialog, { title: _t('Call Timeout'), description: _t('The remote side failed to pick up') + '.', }); - } - else if (oldState === "invite_sent") { + } else if (oldState === "invite_sent") { _setCallState(call, call.roomId, "stop_ringback"); pause("ringbackAudio"); - } - else if (oldState === "ringing") { + } else if (oldState === "ringing") { _setCallState(call, call.roomId, "stop_ringing"); pause("ringbackAudio"); - } - else if (newState === "connected") { + } else if (newState === "connected") { _setCallState(call, call.roomId, "connected"); pause("ringbackAudio"); } @@ -165,14 +157,13 @@ function _setCallListeners(call) { function _setCallState(call, roomId, status) { console.log( - "Call state in %s changed to %s (%s)", roomId, status, (call ? call.call_state : "-") + "Call state in %s changed to %s (%s)", roomId, status, (call ? call.call_state : "-"), ); calls[roomId] = call; if (status === "ringing") { play("ringAudio"); - } - else if (call && call.call_state === "ringing") { + } else if (call && call.call_state === "ringing") { pause("ringAudio"); } @@ -192,14 +183,12 @@ function _onAction(payload) { _setCallState(newCall, newCall.roomId, "ringback"); if (payload.type === 'voice') { newCall.placeVoiceCall(); - } - else if (payload.type === 'video') { + } else if (payload.type === 'video') { newCall.placeVideoCall( payload.remote_element, - payload.local_element + payload.local_element, ); - } - else if (payload.type === 'screensharing') { + } else if (payload.type === 'screensharing') { const screenCapErrorString = PlatformPeg.get().screenCaptureErrorString(); if (screenCapErrorString) { _setCallState(undefined, newCall.roomId, "ended"); @@ -213,10 +202,9 @@ function _onAction(payload) { } newCall.placeScreenSharingCall( payload.remote_element, - payload.local_element + payload.local_element, ); - } - else { + } else { console.error("Unknown conf call type: %s", payload.type); } } @@ -255,21 +243,19 @@ function _onAction(payload) { description: _t('You cannot place a call with yourself.'), }); return; - } - else if (members.length === 2) { + } else if (members.length === 2) { console.log("Place %s call in %s", payload.type, payload.room_id); const call = Matrix.createNewMatrixCall(MatrixClientPeg.get(), payload.room_id, { forceTURN: UserSettingsStore.getLocalSetting('webRtcForceTURN', false), }); placeCall(call); - } - else { // > 2 + } else { // > 2 dis.dispatch({ action: "place_conference_call", room_id: payload.room_id, type: payload.type, remote_element: payload.remote_element, - local_element: payload.local_element + local_element: payload.local_element, }); } break; @@ -280,15 +266,13 @@ function _onAction(payload) { Modal.createTrackedDialog('Call Handler', 'Conference call unsupported client', ErrorDialog, { description: _t('Conference calls are not supported in this client'), }); - } - else if (!MatrixClientPeg.get().supportsVoip()) { + } else if (!MatrixClientPeg.get().supportsVoip()) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); Modal.createTrackedDialog('Call Handler', 'VoIP is unsupported', ErrorDialog, { title: _t('VoIP is unsupported'), description: _t('You cannot place VoIP calls in this browser.'), }); - } - else if (MatrixClientPeg.get().isRoomEncrypted(payload.room_id)) { + } else if (MatrixClientPeg.get().isRoomEncrypted(payload.room_id)) { // Conference calls are implemented by sending the media to central // server which combines the audio from all the participants together // into a single stream. This is incompatible with end-to-end encryption @@ -299,16 +283,15 @@ function _onAction(payload) { Modal.createTrackedDialog('Call Handler', 'Conference calls unsupported e2e', ErrorDialog, { description: _t('Conference calls are not supported in encrypted rooms'), }); - } - else { - var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); + } else { + const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); Modal.createTrackedDialog('Call Handler', 'Conference calling in development', QuestionDialog, { title: _t('Warning!'), description: _t('Conference calling is in development and may not be reliable.'), - onFinished: confirm=>{ + onFinished: (confirm)=>{ if (confirm) { ConferenceHandler.createNewMatrixCall( - MatrixClientPeg.get(), payload.room_id + MatrixClientPeg.get(), payload.room_id, ).done(function(call) { placeCall(call); }, function(err) { @@ -357,7 +340,7 @@ function _onAction(payload) { _setCallState(calls[payload.room_id], payload.room_id, "connected"); dis.dispatch({ action: "view_room", - room_id: payload.room_id + room_id: payload.room_id, }); break; } @@ -368,9 +351,9 @@ if (!global.mxCallHandler) { dis.register(_onAction); } -var callHandler = { +const callHandler = { getCallForRoom: function(roomId) { - var call = module.exports.getCall(roomId); + let call = module.exports.getCall(roomId); if (call) return call; if (ConferenceHandler) { @@ -386,8 +369,8 @@ var callHandler = { }, getAnyActiveCall: function() { - var roomsWithCalls = Object.keys(calls); - for (var i = 0; i < roomsWithCalls.length; i++) { + const roomsWithCalls = Object.keys(calls); + for (let i = 0; i < roomsWithCalls.length; i++) { if (calls[roomsWithCalls[i]] && calls[roomsWithCalls[i]].call_state !== "ended") { return calls[roomsWithCalls[i]]; @@ -402,7 +385,7 @@ var callHandler = { getConferenceHandler: function() { return ConferenceHandler; - } + }, }; // Only things in here which actually need to be global are the // calls list (done separately) and making sure we only register diff --git a/src/ContentMessages.js b/src/ContentMessages.js index 93057fafed..00728061a2 100644 --- a/src/ContentMessages.js +++ b/src/ContentMessages.js @@ -17,14 +17,14 @@ limitations under the License. 'use strict'; import Promise from 'bluebird'; -var extend = require('./extend'); -var dis = require('./dispatcher'); -var MatrixClientPeg = require('./MatrixClientPeg'); -var sdk = require('./index'); +const extend = require('./extend'); +const dis = require('./dispatcher'); +const MatrixClientPeg = require('./MatrixClientPeg'); +const sdk = require('./index'); import { _t } from './languageHandler'; -var Modal = require('./Modal'); +const Modal = require('./Modal'); -var encrypt = require("browser-encrypt-attachment"); +const encrypt = require("browser-encrypt-attachment"); // Polyfill for Canvas.toBlob API using Canvas.toDataURL require("blueimp-canvas-to-blob"); @@ -54,8 +54,8 @@ const MAX_HEIGHT = 600; function createThumbnail(element, inputWidth, inputHeight, mimeType) { const deferred = Promise.defer(); - var targetWidth = inputWidth; - var targetHeight = inputHeight; + let targetWidth = inputWidth; + let targetHeight = inputHeight; if (targetHeight > MAX_HEIGHT) { targetWidth = Math.floor(targetWidth * (MAX_HEIGHT / targetHeight)); targetHeight = MAX_HEIGHT; @@ -81,7 +81,7 @@ function createThumbnail(element, inputWidth, inputHeight, mimeType) { w: inputWidth, h: inputHeight, }, - thumbnail: thumbnail + thumbnail: thumbnail, }); }, mimeType); @@ -129,12 +129,12 @@ function loadImageElement(imageFile) { * @return {Promise} A promise that resolves with the attachment info. */ function infoForImageFile(matrixClient, roomId, imageFile) { - var thumbnailType = "image/png"; + let thumbnailType = "image/png"; if (imageFile.type == "image/jpeg") { thumbnailType = "image/jpeg"; } - var imageInfo; + let imageInfo; return loadImageElement(imageFile).then(function(img) { return createThumbnail(img, img.width, img.height, thumbnailType); }).then(function(result) { @@ -191,7 +191,7 @@ function loadVideoElement(videoFile) { function infoForVideoFile(matrixClient, roomId, videoFile) { const thumbnailType = "image/jpeg"; - var videoInfo; + let videoInfo; return loadVideoElement(videoFile).then(function(video) { return createThumbnail(video, video.videoWidth, video.videoHeight, thumbnailType); }).then(function(result) { @@ -286,7 +286,7 @@ class ContentMessages { body: file.name || 'Attachment', info: { size: file.size, - } + }, }; // if we have a mime type for the file, add it to the message metadata @@ -297,10 +297,10 @@ class ContentMessages { const def = Promise.defer(); if (file.type.indexOf('image/') == 0) { content.msgtype = 'm.image'; - infoForImageFile(matrixClient, roomId, file).then(imageInfo=>{ + infoForImageFile(matrixClient, roomId, file).then((imageInfo)=>{ extend(content.info, imageInfo); def.resolve(); - }, error=>{ + }, (error)=>{ console.error(error); content.msgtype = 'm.file'; def.resolve(); @@ -310,10 +310,10 @@ class ContentMessages { def.resolve(); } else if (file.type.indexOf('video/') == 0) { content.msgtype = 'm.video'; - infoForVideoFile(matrixClient, roomId, file).then(videoInfo=>{ + infoForVideoFile(matrixClient, roomId, file).then((videoInfo)=>{ extend(content.info, videoInfo); def.resolve(); - }, error=>{ + }, (error)=>{ content.msgtype = 'm.file'; def.resolve(); }); @@ -331,7 +331,7 @@ class ContentMessages { this.inprogress.push(upload); dis.dispatch({action: 'upload_started'}); - var error; + let error; function onProgress(ev) { upload.total = ev.total; @@ -355,11 +355,11 @@ class ContentMessages { }, function(err) { error = err; if (!upload.canceled) { - var desc = _t('The file \'%(fileName)s\' failed to upload', {fileName: upload.fileName}) + '.'; + let desc = _t('The file \'%(fileName)s\' failed to upload', {fileName: upload.fileName}) + '.'; if (err.http_status == 413) { desc = _t('The file \'%(fileName)s\' exceeds this home server\'s size limit for uploads', {fileName: upload.fileName}); } - var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); Modal.createTrackedDialog('Upload failed', '', ErrorDialog, { title: _t('Upload Failed'), description: desc, @@ -367,8 +367,8 @@ class ContentMessages { } }).finally(() => { const inprogressKeys = Object.keys(this.inprogress); - for (var i = 0; i < this.inprogress.length; ++i) { - var k = inprogressKeys[i]; + for (let i = 0; i < this.inprogress.length; ++i) { + const k = inprogressKeys[i]; if (this.inprogress[k].promise === upload.promise) { this.inprogress.splice(k, 1); break; @@ -376,8 +376,7 @@ class ContentMessages { } if (error) { dis.dispatch({action: 'upload_failed', upload: upload}); - } - else { + } else { dis.dispatch({action: 'upload_finished', upload: upload}); } }); @@ -389,9 +388,9 @@ class ContentMessages { cancelUpload(promise) { const inprogressKeys = Object.keys(this.inprogress); - var upload; - for (var i = 0; i < this.inprogress.length; ++i) { - var k = inprogressKeys[i]; + let upload; + for (let i = 0; i < this.inprogress.length; ++i) { + const k = inprogressKeys[i]; if (this.inprogress[k].promise === promise) { upload = this.inprogress[k]; break; diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index ee2bcd2b0f..5620bc06df 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -17,10 +17,10 @@ limitations under the License. 'use strict'; -var React = require('react'); -var sanitizeHtml = require('sanitize-html'); -var highlight = require('highlight.js'); -var linkifyMatrix = require('./linkify-matrix'); +const React = require('react'); +const sanitizeHtml = require('sanitize-html'); +const highlight = require('highlight.js'); +const linkifyMatrix = require('./linkify-matrix'); import escape from 'lodash/escape'; import emojione from 'emojione'; import classNames from 'classnames'; @@ -66,8 +66,7 @@ function unicodeToImage(str) { if ( (typeof unicodeChar === 'undefined') || (unicodeChar === '') || (!(unicodeChar in emojione.jsEscapeMap)) ) { // if the unicodeChar doesnt exist just return the entire match return unicodeChar; - } - else { + } else { // get the unicode codepoint from the actual char unicode = emojione.jsEscapeMap[unicodeChar]; @@ -183,21 +182,19 @@ const sanitizeHtmlParams = { if (attribs.href) { attribs.target = '_blank'; // by default - var m; + let m; // FIXME: horrible duplication with linkify-matrix m = attribs.href.match(linkifyMatrix.VECTOR_URL_PATTERN); if (m) { attribs.href = m[1]; delete attribs.target; - } - else { + } else { m = attribs.href.match(linkifyMatrix.MATRIXTO_URL_PATTERN); if (m) { - var entity = m[1]; + const entity = m[1]; if (entity[0] === '@') { attribs.href = '#/user/' + entity; - } - else if (entity[0] === '#' || entity[0] === '!') { + } else if (entity[0] === '#' || entity[0] === '!') { attribs.href = '#/room/' + entity; } delete attribs.target; @@ -205,7 +202,7 @@ const sanitizeHtmlParams = { } } attribs.rel = 'noopener'; // https://mathiasbynens.github.io/rel-noopener/ - return { tagName: tagName, attribs : attribs }; + return { tagName: tagName, attribs: attribs }; }, 'img': function(tagName, attribs) { // Strip out imgs that aren't `mxc` here instead of using allowedSchemesByTag @@ -224,7 +221,7 @@ const sanitizeHtmlParams = { 'code': function(tagName, attribs) { if (typeof attribs.class !== 'undefined') { // Filter out all classes other than ones starting with language- for syntax highlighting. - let classes = attribs.class.split(/\s+/).filter(function(cl) { + const classes = attribs.class.split(/\s+/).filter(function(cl) { return cl.startsWith('language-'); }); attribs.class = classes.join(' '); @@ -287,11 +284,11 @@ class BaseHighlighter { * TextHighlighter). */ applyHighlights(safeSnippet, safeHighlights) { - var lastOffset = 0; - var offset; - var nodes = []; + let lastOffset = 0; + let offset; + let nodes = []; - var safeHighlight = safeHighlights[0]; + const safeHighlight = safeHighlights[0]; while ((offset = safeSnippet.toLowerCase().indexOf(safeHighlight.toLowerCase(), lastOffset)) >= 0) { // handle preamble if (offset > lastOffset) { @@ -301,7 +298,7 @@ class BaseHighlighter { // do highlight. use the original string rather than safeHighlight // to preserve the original casing. - var endOffset = offset + safeHighlight.length; + const endOffset = offset + safeHighlight.length; nodes.push(this._processSnippet(safeSnippet.substring(offset, endOffset), true)); lastOffset = endOffset; @@ -319,8 +316,7 @@ class BaseHighlighter { if (safeHighlights[1]) { // recurse into this range to check for the next set of highlight matches return this.applyHighlights(safeSnippet, safeHighlights.slice(1)); - } - else { + } else { // no more highlights to be found, just return the unhighlighted string return [this._processSnippet(safeSnippet, false)]; } @@ -341,7 +337,7 @@ class HtmlHighlighter extends BaseHighlighter { return snippet; } - var span = "" + let span = "" + snippet + ""; if (this.highlightLink) { @@ -366,15 +362,15 @@ class TextHighlighter extends BaseHighlighter { * returns a React node */ _processSnippet(snippet, highlight) { - var key = this._key++; + const key = this._key++; - var node = - + let node = + { snippet } ; if (highlight && this.highlightLink) { - node = {node}; + node = { node }; } return node; @@ -393,20 +389,20 @@ class TextHighlighter extends BaseHighlighter { export function bodyToHtml(content, highlights, opts) { opts = opts || {}; - var isHtml = (content.format === "org.matrix.custom.html"); - let body = isHtml ? content.formatted_body : escape(content.body); + const isHtml = (content.format === "org.matrix.custom.html"); + const body = isHtml ? content.formatted_body : escape(content.body); let bodyHasEmoji = false; - var safeBody; + let safeBody; // XXX: We sanitize the HTML whilst also highlighting its text nodes, to avoid accidentally trying // to highlight HTML tags themselves. However, this does mean that we don't highlight textnodes which // are interrupted by HTML tags (not that we did before) - e.g. foobar won't get highlighted // by an attempt to search for 'foobar'. Then again, the search query probably wouldn't work either try { if (highlights && highlights.length > 0) { - var highlighter = new HtmlHighlighter("mx_EventTile_searchHighlight", opts.highlightLink); - var safeHighlights = highlights.map(function(highlight) { + const highlighter = new HtmlHighlighter("mx_EventTile_searchHighlight", opts.highlightLink); + const safeHighlights = highlights.map(function(highlight) { return sanitizeHtml(highlight, sanitizeHtmlParams); }); // XXX: hacky bodge to temporarily apply a textFilter to the sanitizeHtmlParams structure. @@ -417,16 +413,15 @@ export function bodyToHtml(content, highlights, opts) { safeBody = sanitizeHtml(body, sanitizeHtmlParams); bodyHasEmoji = containsEmoji(body); if (bodyHasEmoji) safeBody = unicodeToImage(safeBody); - } - finally { + } finally { delete sanitizeHtmlParams.textFilter; } let emojiBody = false; if (bodyHasEmoji) { EMOJI_REGEX.lastIndex = 0; - let contentBodyTrimmed = content.body !== undefined ? content.body.trim() : ''; - let match = EMOJI_REGEX.exec(contentBodyTrimmed); + const contentBodyTrimmed = content.body !== undefined ? content.body.trim() : ''; + const match = EMOJI_REGEX.exec(contentBodyTrimmed); emojiBody = match && match[0] && match[0].length === contentBodyTrimmed.length; } diff --git a/src/ImageUtils.js b/src/ImageUtils.js index 3744241874..a83d94a633 100644 --- a/src/ImageUtils.js +++ b/src/ImageUtils.js @@ -42,13 +42,12 @@ module.exports = { // no scaling needs to be applied return fullHeight; } - var widthMulti = thumbWidth / fullWidth; - var heightMulti = thumbHeight / fullHeight; + const widthMulti = thumbWidth / fullWidth; + const heightMulti = thumbHeight / fullHeight; if (widthMulti < heightMulti) { // width is the dominant dimension so scaling will be fixed on that return Math.floor(widthMulti * fullHeight); - } - else { + } else { // height is the dominant dimension so scaling will be fixed on that return Math.floor(heightMulti * fullHeight); } diff --git a/src/Login.js b/src/Login.js index 049b79c2f4..0eff94ce60 100644 --- a/src/Login.js +++ b/src/Login.js @@ -59,8 +59,8 @@ export default class Login { } getFlows() { - var self = this; - var client = this._createTemporaryClient(); + const self = this; + const client = this._createTemporaryClient(); return client.loginFlows().then(function(result) { self._flows = result.flows; self._currentFlowIndex = 0; @@ -77,12 +77,12 @@ export default class Login { getCurrentFlowStep() { // technically the flow can have multiple steps, but no one does this // for login so we can ignore it. - var flowStep = this._flows[this._currentFlowIndex]; + const flowStep = this._flows[this._currentFlowIndex]; return flowStep ? flowStep.type : null; } loginAsGuest() { - var client = this._createTemporaryClient(); + const client = this._createTemporaryClient(); return client.registerGuest({ body: { initial_device_display_name: this._defaultDeviceDisplayName, @@ -94,7 +94,7 @@ export default class Login { accessToken: creds.access_token, homeserverUrl: this._hsUrl, identityServerUrl: this._isUrl, - guest: true + guest: true, }; }, (error) => { throw error; @@ -149,12 +149,12 @@ export default class Login { identityServerUrl: self._isUrl, userId: data.user_id, deviceId: data.device_id, - accessToken: data.access_token + accessToken: data.access_token, }); }, function(error) { if (error.httpStatus === 403) { if (self._fallbackHsUrl) { - var fbClient = Matrix.createClient({ + const fbClient = Matrix.createClient({ baseUrl: self._fallbackHsUrl, idBaseUrl: this._isUrl, }); @@ -165,7 +165,7 @@ export default class Login { identityServerUrl: self._isUrl, userId: data.user_id, deviceId: data.device_id, - accessToken: data.access_token + accessToken: data.access_token, }); }, function(fallback_error) { // throw the original error diff --git a/src/Markdown.js b/src/Markdown.js index 455d5e95bd..e05f163ba5 100644 --- a/src/Markdown.js +++ b/src/Markdown.js @@ -48,7 +48,7 @@ function html_if_tag_allowed(node) { * or false if it is only a single line. */ function is_multi_line(node) { - var par = node; + let par = node; while (par.parent) { par = par.parent; } @@ -143,7 +143,7 @@ export default class Markdown { if (isMultiLine) this.cr(); html_if_tag_allowed.call(this, node); if (isMultiLine) this.cr(); - } + }; return renderer.render(this.parsed); } @@ -178,7 +178,7 @@ export default class Markdown { renderer.html_block = function(node) { this.lit(node.literal); if (is_multi_line(node) && node.next) this.lit('\n\n'); - } + }; return renderer.render(this.parsed); } diff --git a/src/MatrixClientPeg.js b/src/MatrixClientPeg.js index 4264828c7b..0c3d5b3775 100644 --- a/src/MatrixClientPeg.js +++ b/src/MatrixClientPeg.js @@ -95,7 +95,7 @@ class MatrixClientPeg { opts.pendingEventOrdering = "detached"; try { - let promise = this.matrixClient.store.startup(); + const promise = this.matrixClient.store.startup(); console.log(`MatrixClientPeg: waiting for MatrixClient store to initialise`); await promise; } catch(err) { @@ -136,7 +136,7 @@ class MatrixClientPeg { } _createClient(creds: MatrixClientCreds) { - var opts = { + const opts = { baseUrl: creds.homeserverUrl, idBaseUrl: creds.identityServerUrl, accessToken: creds.accessToken, @@ -153,8 +153,8 @@ class MatrixClientPeg { this.matrixClient.setGuest(Boolean(creds.guest)); - var notifTimelineSet = new EventTimelineSet(null, { - timelineSupport: true + const notifTimelineSet = new EventTimelineSet(null, { + timelineSupport: true, }); // XXX: what is our initial pagination token?! it somehow needs to be synchronised with /sync. notifTimelineSet.getLiveTimeline().setPaginationToken("", EventTimeline.BACKWARDS); diff --git a/src/Modal.js b/src/Modal.js index 056b6d8bf2..68d75d1ff1 100644 --- a/src/Modal.js +++ b/src/Modal.js @@ -17,8 +17,8 @@ limitations under the License. 'use strict'; -var React = require('react'); -var ReactDOM = require('react-dom'); +const React = require('react'); +const ReactDOM = require('react-dom'); import Analytics from './Analytics'; import sdk from './index'; @@ -137,15 +137,15 @@ class ModalManager { * @param {String} className CSS class to apply to the modal wrapper */ createDialogAsync(loader, props, className) { - var self = this; + const self = this; const modal = {}; // never call this from onFinished() otherwise it will loop // // nb explicit function() rather than arrow function, to get `arguments` - var closeDialog = function() { + const closeDialog = function() { if (props && props.onFinished) props.onFinished.apply(null, arguments); - var i = self._modals.indexOf(modal); + const i = self._modals.indexOf(modal); if (i >= 0) { self._modals.splice(i, 1); } @@ -160,7 +160,7 @@ class ModalManager { // property set here so you can't close the dialog from a button click! modal.elem = ( + onFinished={closeDialog} /> ); modal.onFinished = props ? props.onFinished : null; modal.className = className; @@ -191,13 +191,13 @@ class ModalManager { return; } - var modal = this._modals[0]; - var dialog = ( -
      + const modal = this._modals[0]; + const dialog = ( +
      - {modal.elem} + { modal.elem }
      -
      +
      ); diff --git a/src/Notifier.js b/src/Notifier.js index 155564dcdf..a2e80353e1 100644 --- a/src/Notifier.js +++ b/src/Notifier.js @@ -81,7 +81,7 @@ const Notifier = { } const avatarUrl = ev.sender ? Avatar.avatarUrlForMember( - ev.sender, 40, 40, 'crop' + ev.sender, 40, 40, 'crop', ) : null; const notif = plaf.displayNotification(title, msg, avatarUrl, room); @@ -303,7 +303,7 @@ const Notifier = { this._playAudioNotification(ev, room); } } - } + }, }; if (!global.mxNotifier) { diff --git a/src/Presence.js b/src/Presence.js index c45d571217..fab518e1cb 100644 --- a/src/Presence.js +++ b/src/Presence.js @@ -14,12 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -var MatrixClientPeg = require("./MatrixClientPeg"); -var dis = require("./dispatcher"); +const MatrixClientPeg = require("./MatrixClientPeg"); +const dis = require("./dispatcher"); // Time in ms after that a user is considered as unavailable/away -var UNAVAILABLE_TIME_MS = 3 * 60 * 1000; // 3 mins -var PRESENCE_STATES = ["online", "offline", "unavailable"]; +const UNAVAILABLE_TIME_MS = 3 * 60 * 1000; // 3 mins +const PRESENCE_STATES = ["online", "offline", "unavailable"]; class Presence { @@ -71,14 +71,14 @@ class Presence { if (!this.running) { return; } - var old_state = this.state; + const old_state = this.state; this.state = newState; if (MatrixClientPeg.get().isGuest()) { return; // don't try to set presence when a guest; it won't work. } - var self = this; + const self = this; MatrixClientPeg.get().setPresence(this.state).done(function() { console.log("Presence: %s", newState); }, function(err) { @@ -104,7 +104,7 @@ class Presence { * @private */ _resetTimer() { - var self = this; + const self = this; this.setState("online"); // Re-arm the timer clearTimeout(this.timer); diff --git a/src/RichText.js b/src/RichText.js index cbd3b9ae18..4bc3815d25 100644 --- a/src/RichText.js +++ b/src/RichText.js @@ -44,9 +44,9 @@ export const contentStateToHTML = (contentState: ContentState) => { return stateToHTML(contentState, { inlineStyles: { UNDERLINE: { - element: 'u' - } - } + element: 'u', + }, + }, }); }; @@ -59,7 +59,7 @@ function unicodeToEmojiUri(str) { let replaceWith, unicode, alt; if ((!emojione.unicodeAlt) || (emojione.sprites)) { // if we are using the shortname as the alt tag then we need a reversed array to map unicode code point to shortnames - let mappedUnicode = emojione.mapUnicodeToShort(); + const mappedUnicode = emojione.mapUnicodeToShort(); } str = str.replace(emojione.regUnicode, function(unicodeChar) { @@ -90,14 +90,14 @@ function findWithRegex(regex, contentBlock: ContentBlock, callback: (start: numb } // Workaround for https://github.com/facebook/draft-js/issues/414 -let emojiDecorator = { +const emojiDecorator = { strategy: (contentState, contentBlock, callback) => { findWithRegex(EMOJI_REGEX, contentBlock, callback); }, component: (props) => { - let uri = unicodeToEmojiUri(props.children[0].props.text); - let shortname = emojione.toShort(props.children[0].props.text); - let style = { + const uri = unicodeToEmojiUri(props.children[0].props.text); + const shortname = emojione.toShort(props.children[0].props.text); + const style = { display: 'inline-block', width: '1em', maxHeight: '1em', @@ -106,7 +106,7 @@ let emojiDecorator = { backgroundPosition: 'center center', overflow: 'hidden', }; - return ({props.children}); + return ({ props.children }); }, }; @@ -118,16 +118,16 @@ export function getScopedRTDecorators(scope: any): CompositeDecorator { } export function getScopedMDDecorators(scope: any): CompositeDecorator { - let markdownDecorators = ['HR', 'BOLD', 'ITALIC', 'CODE', 'STRIKETHROUGH'].map( + const markdownDecorators = ['HR', 'BOLD', 'ITALIC', 'CODE', 'STRIKETHROUGH'].map( (style) => ({ strategy: (contentState, contentBlock, callback) => { return findWithRegex(MARKDOWN_REGEX[style], contentBlock, callback); }, component: (props) => ( - {props.children} + { props.children } - ) + ), })); markdownDecorators.push({ @@ -136,9 +136,9 @@ export function getScopedMDDecorators(scope: any): CompositeDecorator { }, component: (props) => ( - {props.children} + { props.children } - ) + ), }); // markdownDecorators.push(emojiDecorator); // TODO Consider renabling "syntax highlighting" when we can do it properly @@ -161,7 +161,7 @@ export function modifyText(contentState: ContentState, rangeToReplace: Selection for (let currentKey = startKey; currentKey && currentKey !== endKey; currentKey = contentState.getKeyAfter(currentKey)) { - let blockText = getText(currentKey); + const blockText = getText(currentKey); text += blockText.substring(startOffset, blockText.length); // from now on, we'll take whole blocks @@ -182,7 +182,7 @@ export function modifyText(contentState: ContentState, rangeToReplace: Selection export function selectionStateToTextOffsets(selectionState: SelectionState, contentBlocks: Array): {start: number, end: number} { let offset = 0, start = 0, end = 0; - for (let block of contentBlocks) { + for (const block of contentBlocks) { if (selectionState.getStartKey() === block.getKey()) { start = offset + selectionState.getStartOffset(); } @@ -259,7 +259,7 @@ export function attachImmutableEntitiesToEmoji(editorState: EditorState): Editor .set('focusOffset', end); const emojiText = plainText.substring(start, end); newContentState = newContentState.createEntity( - 'emoji', 'IMMUTABLE', { emojiUnicode: emojiText } + 'emoji', 'IMMUTABLE', { emojiUnicode: emojiText }, ); const entityKey = newContentState.getLastCreatedEntityKey(); newContentState = Modifier.replaceText( diff --git a/src/Rooms.js b/src/Rooms.js index 2e3f4457f0..6cc2d867a6 100644 --- a/src/Rooms.js +++ b/src/Rooms.js @@ -62,8 +62,7 @@ export function isConfCallRoom(room, me, conferenceHandler) { export function looksLikeDirectMessageRoom(room, me) { if (me.membership == "join" || me.membership === "ban" || - (me.membership === "leave" && me.events.member.getSender() !== me.events.member.getStateKey())) - { + (me.membership === "leave" && me.events.member.getSender() !== me.events.member.getStateKey())) { // Used to split rooms via tags const tagNames = Object.keys(room.tags); // Used for 1:1 direct chats diff --git a/src/ScalarAuthClient.js b/src/ScalarAuthClient.js index 0b753cf3ab..c9d056f88e 100644 --- a/src/ScalarAuthClient.js +++ b/src/ScalarAuthClient.js @@ -15,10 +15,10 @@ limitations under the License. */ import Promise from 'bluebird'; -var request = require('browser-request'); +const request = require('browser-request'); -var SdkConfig = require('./SdkConfig'); -var MatrixClientPeg = require('./MatrixClientPeg'); +const SdkConfig = require('./SdkConfig'); +const MatrixClientPeg = require('./MatrixClientPeg'); class ScalarAuthClient { @@ -38,7 +38,7 @@ class ScalarAuthClient { // Returns a scalar_token string getScalarToken() { - var tok = window.localStorage.getItem("mx_scalar_token"); + const tok = window.localStorage.getItem("mx_scalar_token"); if (tok) return Promise.resolve(tok); // No saved token, so do the dance to get one. First, we @@ -53,9 +53,9 @@ class ScalarAuthClient { } exchangeForScalarToken(openid_token_object) { - var defer = Promise.defer(); + const defer = Promise.defer(); - var scalar_rest_url = SdkConfig.get().integrations_rest_url; + const scalar_rest_url = SdkConfig.get().integrations_rest_url; request({ method: 'POST', uri: scalar_rest_url+'/register', @@ -77,7 +77,7 @@ class ScalarAuthClient { } getScalarInterfaceUrlForRoom(roomId, screen, id) { - var url = SdkConfig.get().integrations_ui_url; + let url = SdkConfig.get().integrations_ui_url; url += "?scalar_token=" + encodeURIComponent(this.scalarToken); url += "&room_id=" + encodeURIComponent(roomId); if (id) { diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index d14d439d66..7698829647 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -356,12 +356,12 @@ function getWidgets(event, roomId) { } const stateEvents = room.currentState.getStateEvents("im.vector.modular.widgets"); // Only return widgets which have required fields - let widgetStateEvents = []; + const widgetStateEvents = []; stateEvents.forEach((ev) => { if (ev.getContent().type && ev.getContent().url) { widgetStateEvents.push(ev.event); // return the raw event } - }) + }); sendResponse(event, widgetStateEvents); } @@ -376,7 +376,7 @@ function setPlumbingState(event, roomId, status) { sendError(event, _t('You need to be logged in.')); return; } - client.sendStateEvent(roomId, "m.room.plumbing", { status : status }).done(() => { + client.sendStateEvent(roomId, "m.room.plumbing", { status: status }).done(() => { sendResponse(event, { success: true, }); @@ -415,11 +415,11 @@ function setBotPower(event, roomId, userId, level) { } client.getStateEvent(roomId, "m.room.power_levels", "").then((powerLevels) => { - let powerEvent = new MatrixEvent( + const powerEvent = new MatrixEvent( { type: "m.room.power_levels", content: powerLevels, - } + }, ); client.setPowerLevel(roomId, userId, level, powerEvent).done(() => { @@ -485,8 +485,7 @@ function canSendEvent(event, roomId) { let canSend = false; if (isState) { canSend = room.currentState.maySendStateEvent(evType, me); - } - else { + } else { canSend = room.currentState.maySendEvent(evType, me); } @@ -517,8 +516,8 @@ function returnStateEvent(event, roomId, eventType, stateKey) { sendResponse(event, stateEvent.getContent()); } -var currentRoomId = null; -var currentRoomAlias = null; +let currentRoomId = null; +let currentRoomAlias = null; // Listen for when a room is viewed dis.register(onAction); @@ -542,7 +541,7 @@ const onMessage = function(event) { // // All strings start with the empty string, so for sanity return if the length // of the event origin is 0. - let url = SdkConfig.get().integrations_ui_url; + const url = SdkConfig.get().integrations_ui_url; if (event.origin.length === 0 || !url.startsWith(event.origin) || !event.data.action) { return; // don't log this - debugging APIs like to spam postMessage which floods the log otherwise } @@ -647,7 +646,7 @@ module.exports = { // Make an error so we get a stack trace const e = new Error( "ScalarMessaging: mismatched startListening / stopListening detected." + - " Negative count" + " Negative count", ); console.error(e); } diff --git a/src/Tinter.js b/src/Tinter.js index 5bf13e6d4a..6b23df8c9b 100644 --- a/src/Tinter.js +++ b/src/Tinter.js @@ -18,10 +18,10 @@ limitations under the License. // module.exports otherwise this will break when included by both // react-sdk and apps layered on top. -var DEBUG = 0; +const DEBUG = 0; // The colour keys to be replaced as referred to in CSS -var keyRgb = [ +const keyRgb = [ "rgb(118, 207, 166)", // Vector Green "rgb(234, 245, 240)", // Vector Light Green "rgb(211, 239, 225)", // BottomLeftMenu overlay (20% Vector Green) @@ -35,7 +35,7 @@ var keyRgb = [ // x = (255 - 234) / (255 - 118) = 0.16 // The colour keys to be replaced as referred to in SVGs -var keyHex = [ +const keyHex = [ "#76CFA6", // Vector Green "#EAF5F0", // Vector Light Green "#D3EFE1", // BottomLeftMenu overlay (20% Vector Green overlaid on Vector Light Green) @@ -44,14 +44,14 @@ var keyHex = [ // cache of our replacement colours // defaults to our keys. -var colors = [ +const colors = [ keyHex[0], keyHex[1], keyHex[2], keyHex[3], ]; -var cssFixups = [ +const cssFixups = [ // { // style: a style object that should be fixed up taken from a stylesheet // attr: name of the attribute to be clobbered, e.g. 'color' @@ -60,7 +60,7 @@ var cssFixups = [ ]; // CSS attributes to be fixed up -var cssAttrs = [ +const cssAttrs = [ "color", "backgroundColor", "borderColor", @@ -69,17 +69,17 @@ var cssAttrs = [ "borderLeftColor", ]; -var svgAttrs = [ +const svgAttrs = [ "fill", "stroke", ]; -var cached = false; +let cached = false; function calcCssFixups() { if (DEBUG) console.log("calcSvgFixups start"); - for (var i = 0; i < document.styleSheets.length; i++) { - var ss = document.styleSheets[i]; + for (let i = 0; i < document.styleSheets.length; i++) { + const ss = document.styleSheets[i]; if (!ss) continue; // well done safari >:( // Chromium apparently sometimes returns null here; unsure why. // see $14534907369972FRXBx:matrix.org in HQ @@ -104,12 +104,12 @@ function calcCssFixups() { if (ss.href && !ss.href.match(/\/bundle.*\.css$/)) continue; if (!ss.cssRules) continue; - for (var j = 0; j < ss.cssRules.length; j++) { - var rule = ss.cssRules[j]; + for (let j = 0; j < ss.cssRules.length; j++) { + const rule = ss.cssRules[j]; if (!rule.style) continue; - for (var k = 0; k < cssAttrs.length; k++) { - var attr = cssAttrs[k]; - for (var l = 0; l < keyRgb.length; l++) { + for (let k = 0; k < cssAttrs.length; k++) { + const attr = cssAttrs[k]; + for (let l = 0; l < keyRgb.length; l++) { if (rule.style[attr] === keyRgb[l]) { cssFixups.push({ style: rule.style, @@ -126,8 +126,8 @@ function calcCssFixups() { function applyCssFixups() { if (DEBUG) console.log("applyCssFixups start"); - for (var i = 0; i < cssFixups.length; i++) { - var cssFixup = cssFixups[i]; + for (let i = 0; i < cssFixups.length; i++) { + const cssFixup = cssFixups[i]; cssFixup.style[cssFixup.attr] = colors[cssFixup.index]; } if (DEBUG) console.log("applyCssFixups end"); @@ -140,15 +140,15 @@ function hexToRgb(color) { color[1] + color[1] + color[2] + color[2]; } - var val = parseInt(color, 16); - var r = (val >> 16) & 255; - var g = (val >> 8) & 255; - var b = val & 255; + const val = parseInt(color, 16); + const r = (val >> 16) & 255; + const g = (val >> 8) & 255; + const b = val & 255; return [r, g, b]; } function rgbToHex(rgb) { - var val = (rgb[0] << 16) | (rgb[1] << 8) | rgb[2]; + const val = (rgb[0] << 16) | (rgb[1] << 8) | rgb[2]; return '#' + (0x1000000 + val).toString(16).slice(1); } @@ -167,12 +167,11 @@ module.exports = { * * @param {Function} tintable Function to call when the tint changes. */ - registerTintable : function(tintable) { + registerTintable: function(tintable) { tintables.push(tintable); }, tint: function(primaryColor, secondaryColor, tertiaryColor) { - if (!cached) { calcCssFixups(); cached = true; @@ -185,7 +184,7 @@ module.exports = { if (!secondaryColor) { const x = 0.16; // average weighting factor calculated from vector green & light green - var rgb = hexToRgb(primaryColor); + const rgb = hexToRgb(primaryColor); rgb[0] = x * rgb[0] + (1 - x) * 255; rgb[1] = x * rgb[1] + (1 - x) * 255; rgb[2] = x * rgb[2] + (1 - x) * 255; @@ -194,8 +193,8 @@ module.exports = { if (!tertiaryColor) { const x = 0.19; - var rgb1 = hexToRgb(primaryColor); - var rgb2 = hexToRgb(secondaryColor); + const rgb1 = hexToRgb(primaryColor); + const rgb2 = hexToRgb(secondaryColor); rgb1[0] = x * rgb1[0] + (1 - x) * rgb2[0]; rgb1[1] = x * rgb1[1] + (1 - x) * rgb2[1]; rgb1[2] = x * rgb1[2] + (1 - x) * rgb2[2]; @@ -204,8 +203,7 @@ module.exports = { if (colors[0] === primaryColor && colors[1] === secondaryColor && - colors[2] === tertiaryColor) - { + colors[2] === tertiaryColor) { return; } @@ -248,14 +246,13 @@ module.exports = { // key colour; cache the element and apply. if (DEBUG) console.log("calcSvgFixups start for " + svgs); - var fixups = []; - for (var i = 0; i < svgs.length; i++) { + const fixups = []; + for (let i = 0; i < svgs.length; i++) { var svgDoc; try { svgDoc = svgs[i].contentDocument; - } - catch(e) { - var msg = 'Failed to get svg.contentDocument of ' + svgs[i].toString(); + } catch(e) { + let msg = 'Failed to get svg.contentDocument of ' + svgs[i].toString(); if (e.message) { msg += e.message; } @@ -265,12 +262,12 @@ module.exports = { console.error(e); } if (!svgDoc) continue; - var tags = svgDoc.getElementsByTagName("*"); - for (var j = 0; j < tags.length; j++) { - var tag = tags[j]; - for (var k = 0; k < svgAttrs.length; k++) { - var attr = svgAttrs[k]; - for (var l = 0; l < keyHex.length; l++) { + const tags = svgDoc.getElementsByTagName("*"); + for (let j = 0; j < tags.length; j++) { + const tag = tags[j]; + for (let k = 0; k < svgAttrs.length; k++) { + const attr = svgAttrs[k]; + for (let l = 0; l < keyHex.length; l++) { if (tag.getAttribute(attr) && tag.getAttribute(attr).toUpperCase() === keyHex[l]) { fixups.push({ node: tag, @@ -289,10 +286,10 @@ module.exports = { applySvgFixups: function(fixups) { if (DEBUG) console.log("applySvgFixups start for " + fixups); - for (var i = 0; i < fixups.length; i++) { - var svgFixup = fixups[i]; + for (let i = 0; i < fixups.length; i++) { + const svgFixup = fixups[i]; svgFixup.node.setAttribute(svgFixup.attr, colors[svgFixup.index]); } if (DEBUG) console.log("applySvgFixups end"); - } + }, }; diff --git a/src/Unread.js b/src/Unread.js index 8fffc2a429..20e876ad88 100644 --- a/src/Unread.js +++ b/src/Unread.js @@ -14,10 +14,10 @@ See the License for the specific language governing permissions and limitations under the License. */ -var MatrixClientPeg = require('./MatrixClientPeg'); +const MatrixClientPeg = require('./MatrixClientPeg'); import UserSettingsStore from './UserSettingsStore'; import shouldHideEvent from './shouldHideEvent'; -var sdk = require('./index'); +const sdk = require('./index'); module.exports = { /** @@ -34,17 +34,17 @@ module.exports = { } else if (ev.getType == 'm.room.message' && ev.getContent().msgtype == 'm.notify') { return false; } - var EventTile = sdk.getComponent('rooms.EventTile'); + const EventTile = sdk.getComponent('rooms.EventTile'); return EventTile.haveTileForEvent(ev); }, doesRoomHaveUnreadMessages: function(room) { - var myUserId = MatrixClientPeg.get().credentials.userId; + const myUserId = MatrixClientPeg.get().credentials.userId; // get the most recent read receipt sent by our account. // N.B. this is NOT a read marker (RM, aka "read up to marker"), // despite the name of the method :(( - var readUpToId = room.getEventReadUpTo(myUserId); + const readUpToId = room.getEventReadUpTo(myUserId); // as we don't send RRs for our own messages, make sure we special case that // if *we* sent the last message into the room, we consider it not unread! @@ -54,8 +54,7 @@ module.exports = { // https://github.com/vector-im/riot-web/issues/3363 if (room.timeline.length && room.timeline[room.timeline.length - 1].sender && - room.timeline[room.timeline.length - 1].sender.userId === myUserId) - { + room.timeline[room.timeline.length - 1].sender.userId === myUserId) { return false; } @@ -67,8 +66,8 @@ module.exports = { const syncedSettings = UserSettingsStore.getSyncedSettings(); // Loop through messages, starting with the most recent... - for (var i = room.timeline.length - 1; i >= 0; --i) { - var ev = room.timeline[i]; + for (let i = room.timeline.length - 1; i >= 0; --i) { + const ev = room.timeline[i]; if (ev.getId() == readUpToId) { // If we've read up to this event, there's nothing more recents @@ -86,5 +85,5 @@ module.exports = { // is unread on the theory that false positives are better than // false negatives here. return true; - } + }, }; diff --git a/src/Velociraptor.js b/src/Velociraptor.js index 9c85bafca0..9a674d4f09 100644 --- a/src/Velociraptor.js +++ b/src/Velociraptor.js @@ -1,6 +1,6 @@ -var React = require('react'); -var ReactDom = require('react-dom'); -var Velocity = require('velocity-vector'); +const React = require('react'); +const ReactDom = require('react-dom'); +const Velocity = require('velocity-vector'); /** * The Velociraptor contains components and animates transitions with velocity. @@ -46,13 +46,13 @@ module.exports = React.createClass({ * update `this.children` according to the new list of children given */ _updateChildren: function(newChildren) { - var self = this; - var oldChildren = this.children || {}; + const self = this; + const oldChildren = this.children || {}; this.children = {}; React.Children.toArray(newChildren).forEach(function(c) { if (oldChildren[c.key]) { - var old = oldChildren[c.key]; - var oldNode = ReactDom.findDOMNode(self.nodes[old.key]); + const old = oldChildren[c.key]; + const oldNode = ReactDom.findDOMNode(self.nodes[old.key]); if (oldNode && oldNode.style.left != c.props.style.left) { Velocity(oldNode, { left: c.props.style.left }, self.props.transition).then(function() { @@ -71,18 +71,18 @@ module.exports = React.createClass({ } else { // new element. If we have a startStyle, use that as the style and go through // the enter animations - var newProps = {}; - var restingStyle = c.props.style; + const newProps = {}; + const restingStyle = c.props.style; - var startStyles = self.props.startStyles; + const startStyles = self.props.startStyles; if (startStyles.length > 0) { - var startStyle = startStyles[0]; + const startStyle = startStyles[0]; newProps.style = startStyle; // console.log("mounted@startstyle0: "+JSON.stringify(startStyle)); } - newProps.ref = (n => self._collectNode( - c.key, n, restingStyle + newProps.ref = ((n) => self._collectNode( + c.key, n, restingStyle, )); self.children[c.key] = React.cloneElement(c, newProps); @@ -103,8 +103,8 @@ module.exports = React.createClass({ this.nodes[k] === undefined && this.props.startStyles.length > 0 ) { - var startStyles = this.props.startStyles; - var transitionOpts = this.props.enterTransitionOpts; + const startStyles = this.props.startStyles; + const transitionOpts = this.props.enterTransitionOpts; const domNode = ReactDom.findDOMNode(node); // start from startStyle 1: 0 is the one we gave it // to start with, so now we animate 1 etc. @@ -154,7 +154,7 @@ module.exports = React.createClass({ render: function() { return ( - {Object.values(this.children)} + { Object.values(this.children) } ); }, diff --git a/src/VelocityBounce.js b/src/VelocityBounce.js index 3ad7d207a9..2141b05325 100644 --- a/src/VelocityBounce.js +++ b/src/VelocityBounce.js @@ -1,9 +1,9 @@ -var Velocity = require('velocity-vector'); +const Velocity = require('velocity-vector'); // courtesy of https://github.com/julianshapiro/velocity/issues/283 // We only use easeOutBounce (easeInBounce is just sort of nonsensical) function bounce( p ) { - var pow2, + let pow2, bounce = 4; while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) { diff --git a/src/WhoIsTyping.js b/src/WhoIsTyping.js index 2a12703a27..6bea2cbb92 100644 --- a/src/WhoIsTyping.js +++ b/src/WhoIsTyping.js @@ -14,19 +14,19 @@ See the License for the specific language governing permissions and limitations under the License. */ -var MatrixClientPeg = require("./MatrixClientPeg"); +const MatrixClientPeg = require("./MatrixClientPeg"); import { _t } from './languageHandler'; module.exports = { usersTypingApartFromMeAndIgnored: function(room) { return this.usersTyping( - room, [MatrixClientPeg.get().credentials.userId].concat(MatrixClientPeg.get().getIgnoredUsers()) + room, [MatrixClientPeg.get().credentials.userId].concat(MatrixClientPeg.get().getIgnoredUsers()), ); }, usersTypingApartFromMe: function(room) { return this.usersTyping( - room, [MatrixClientPeg.get().credentials.userId] + room, [MatrixClientPeg.get().credentials.userId], ); }, @@ -35,15 +35,15 @@ module.exports = { * to exclude, return a list of user objects who are typing. */ usersTyping: function(room, exclude) { - var whoIsTyping = []; + const whoIsTyping = []; if (exclude === undefined) { exclude = []; } - var memberKeys = Object.keys(room.currentState.members); - for (var i = 0; i < memberKeys.length; ++i) { - var userId = memberKeys[i]; + const memberKeys = Object.keys(room.currentState.members); + for (let i = 0; i < memberKeys.length; ++i) { + const userId = memberKeys[i]; if (room.currentState.members[userId].typing) { if (exclude.indexOf(userId) == -1) { @@ -76,5 +76,5 @@ module.exports = { const lastPerson = names.pop(); return _t('%(names)s and %(lastPerson)s are typing', {names: names.join(', '), lastPerson: lastPerson}); } - } + }, }; diff --git a/src/async-components/views/dialogs/EncryptedEventDialog.js b/src/async-components/views/dialogs/EncryptedEventDialog.js index cec2f05de2..a8f588d39a 100644 --- a/src/async-components/views/dialogs/EncryptedEventDialog.js +++ b/src/async-components/views/dialogs/EncryptedEventDialog.js @@ -14,10 +14,10 @@ See the License for the specific language governing permissions and limitations under the License. */ -var React = require("react"); +const React = require("react"); import { _t } from '../../../languageHandler'; -var sdk = require('../../../index'); -var MatrixClientPeg = require("../../../MatrixClientPeg"); +const sdk = require('../../../index'); +const MatrixClientPeg = require("../../../MatrixClientPeg"); module.exports = React.createClass({ displayName: 'EncryptedEventDialog', @@ -33,7 +33,7 @@ module.exports = React.createClass({ componentWillMount: function() { this._unmounted = false; - var client = MatrixClientPeg.get(); + const client = MatrixClientPeg.get(); // first try to load the device from our store. // @@ -60,7 +60,7 @@ module.exports = React.createClass({ componentWillUnmount: function() { this._unmounted = true; - var client = MatrixClientPeg.get(); + const client = MatrixClientPeg.get(); if (client) { client.removeListener("deviceVerificationChanged", this.onDeviceVerificationChanged); } @@ -89,12 +89,12 @@ module.exports = React.createClass({ }, _renderDeviceInfo: function() { - var device = this.state.device; + const device = this.state.device; if (!device) { return ({ _t('unknown device') }); } - var verificationStatus = ({ _t('NOT verified') }); + let verificationStatus = ({ _t('NOT verified') }); if (device.isBlocked()) { verificationStatus = ({ _t('Blacklisted') }); } else if (device.isVerified()) { @@ -118,7 +118,7 @@ module.exports = React.createClass({ { _t('Ed25519 fingerprint') } - {device.getFingerprint()} + { device.getFingerprint() } @@ -126,7 +126,7 @@ module.exports = React.createClass({ }, _renderEventInfo: function() { - var event = this.props.event; + const event = this.props.event; return ( @@ -165,36 +165,36 @@ module.exports = React.createClass({ }, render: function() { - var DeviceVerifyButtons = sdk.getComponent('elements.DeviceVerifyButtons'); + const DeviceVerifyButtons = sdk.getComponent('elements.DeviceVerifyButtons'); - var buttons = null; + let buttons = null; if (this.state.device) { buttons = ( - ); } return ( -
      +
      { _t('End-to-end encryption information') }

      { _t('Event information') }

      - {this._renderEventInfo()} + { this._renderEventInfo() }

      { _t('Sender device information') }

      - {this._renderDeviceInfo()} + { this._renderDeviceInfo() }
      - - {buttons} + { buttons }
      ); - } + }, }); diff --git a/src/autocomplete/Autocompleter.js b/src/autocomplete/Autocompleter.js index 7a64fb154c..5b10110f04 100644 --- a/src/autocomplete/Autocompleter.js +++ b/src/autocomplete/Autocompleter.js @@ -45,7 +45,7 @@ const PROVIDERS = [ EmojiProvider, CommandProvider, DuckDuckGoProvider, -].map(completer => completer.getInstance()); +].map((completer) => completer.getInstance()); // Providers will get rejected if they take longer than this. const PROVIDER_COMPLETION_TIMEOUT = 3000; diff --git a/src/autocomplete/Components.js b/src/autocomplete/Components.js index 0f0399cf7d..a27533f7c2 100644 --- a/src/autocomplete/Components.js +++ b/src/autocomplete/Components.js @@ -30,13 +30,13 @@ export class TextualCompletion extends React.Component { subtitle, description, className, - ...restProps, + ...restProps } = this.props; return (
      - {title} - {subtitle} - {description} + { title } + { subtitle } + { description }
      ); } @@ -56,14 +56,14 @@ export class PillCompletion extends React.Component { description, initialComponent, className, - ...restProps, + ...restProps } = this.props; return (
      - {initialComponent} - {title} - {subtitle} - {description} + { initialComponent } + { title } + { subtitle } + { description }
      ); } diff --git a/src/autocomplete/DuckDuckGoProvider.js b/src/autocomplete/DuckDuckGoProvider.js index 9c996bb1cc..b2e85c4668 100644 --- a/src/autocomplete/DuckDuckGoProvider.js +++ b/src/autocomplete/DuckDuckGoProvider.js @@ -38,7 +38,7 @@ export default class DuckDuckGoProvider extends AutocompleteProvider { } async getCompletions(query: string, selection: {start: number, end: number}) { - let {command, range} = this.getCurrentCommand(query, selection); + const {command, range} = this.getCurrentCommand(query, selection); if (!query || !command) { return []; } @@ -47,7 +47,7 @@ export default class DuckDuckGoProvider extends AutocompleteProvider { method: 'GET', }); const json = await response.json(); - let results = json.Results.map(result => { + const results = json.Results.map((result) => { return { completion: result.Text, component: ( @@ -105,7 +105,7 @@ export default class DuckDuckGoProvider extends AutocompleteProvider { renderCompletions(completions: [React.Component]): ?React.Component { return
      - {completions} + { completions }
      ; } } diff --git a/src/autocomplete/EmojiProvider.js b/src/autocomplete/EmojiProvider.js index 35a2ee6b53..a5b80e3b0e 100644 --- a/src/autocomplete/EmojiProvider.js +++ b/src/autocomplete/EmojiProvider.js @@ -138,7 +138,7 @@ export default class EmojiProvider extends AutocompleteProvider { return { completion: unicode, component: ( - {unicode}} /> + { unicode }} /> ), range, }; @@ -152,14 +152,13 @@ export default class EmojiProvider extends AutocompleteProvider { } static getInstance() { - if (instance == null) - {instance = new EmojiProvider();} + if (instance == null) {instance = new EmojiProvider();} return instance; } renderCompletions(completions: [React.Component]): ?React.Component { return
      - {completions} + { completions }
      ; } } diff --git a/src/autocomplete/UserProvider.js b/src/autocomplete/UserProvider.js index 26b30a3d27..296399c06c 100644 --- a/src/autocomplete/UserProvider.js +++ b/src/autocomplete/UserProvider.js @@ -59,7 +59,7 @@ export default class UserProvider extends AutocompleteProvider { if (this.users === null) this._makeUsers(); let completions = []; - let {command, range} = this.getCurrentCommand(query, selection, force); + const {command, range} = this.getCurrentCommand(query, selection, force); if (command) { completions = this.matcher.match(command[0]).map((user) => { const displayName = (user.name || user.userId || '').replace(' (IRC)', ''); // FIXME when groups are done @@ -71,7 +71,7 @@ export default class UserProvider extends AutocompleteProvider { href: 'https://matrix.to/#/' + user.userId, component: ( } + initialComponent={} title={displayName} description={user.userId} /> ), @@ -132,7 +132,7 @@ export default class UserProvider extends AutocompleteProvider { renderCompletions(completions: [React.Component]): ?React.Component { return
      - {completions} + { completions }
      ; } diff --git a/src/components/structures/ContextualMenu.js b/src/components/structures/ContextualMenu.js index e5a62b8345..c3ad7f9cd1 100644 --- a/src/components/structures/ContextualMenu.js +++ b/src/components/structures/ContextualMenu.js @@ -17,9 +17,9 @@ limitations under the License. 'use strict'; -var classNames = require('classnames'); -var React = require('react'); -var ReactDOM = require('react-dom'); +const classNames = require('classnames'); +const React = require('react'); +const ReactDOM = require('react-dom'); // Shamelessly ripped off Modal.js. There's probably a better way // of doing reusable widgets like dialog boxes & menus where we go and @@ -36,7 +36,7 @@ module.exports = { }, getOrCreateContainer: function() { - var container = document.getElementById(this.ContextualMenuContainerId); + let container = document.getElementById(this.ContextualMenuContainerId); if (!container) { container = document.createElement("div"); @@ -48,9 +48,9 @@ module.exports = { }, createMenu: function(Element, props) { - var self = this; + const self = this; - var closeMenu = function() { + const closeMenu = function() { ReactDOM.unmountComponentAtNode(self.getOrCreateContainer()); if (props && props.onFinished) { @@ -58,17 +58,17 @@ module.exports = { } }; - var position = { + const position = { top: props.top, }; - var chevronOffset = {}; + const chevronOffset = {}; if (props.chevronOffset) { chevronOffset.top = props.chevronOffset; } // To override the default chevron colour, if it's been set - var chevronCSS = ""; + let chevronCSS = ""; if (props.menuColour) { chevronCSS = ` .mx_ContextualMenu_chevron_left:after { @@ -81,7 +81,7 @@ module.exports = { `; } - var chevron = null; + let chevron = null; if (props.left) { chevron =
      ; position.left = props.left; @@ -90,15 +90,15 @@ module.exports = { position.right = props.right; } - var className = 'mx_ContextualMenu_wrapper'; + const className = 'mx_ContextualMenu_wrapper'; - var menuClasses = classNames({ + const menuClasses = classNames({ 'mx_ContextualMenu': true, 'mx_ContextualMenu_left': props.left, 'mx_ContextualMenu_right': !props.left, }); - var menuStyle = {}; + const menuStyle = {}; if (props.menuWidth) { menuStyle.width = props.menuWidth; } @@ -113,14 +113,14 @@ module.exports = { // FIXME: If a menu uses getDefaultProps it clobbers the onFinished // property set here so you can't close the menu from a button click! - var menu = ( + const menu = (
      - {chevron} - + { chevron } +
      - +
      ); diff --git a/src/components/structures/CreateRoom.js b/src/components/structures/CreateRoom.js index 7ecc315ba7..26454c5ea6 100644 --- a/src/components/structures/CreateRoom.js +++ b/src/components/structures/CreateRoom.js @@ -61,7 +61,7 @@ module.exports = React.createClass({ }, onCreateRoom: function() { - var options = {}; + const options = {}; if (this.state.room_name) { options.name = this.state.room_name; @@ -79,14 +79,14 @@ module.exports = React.createClass({ { type: "m.room.join_rules", content: { - "join_rule": this.state.is_private ? "invite" : "public" - } + "join_rule": this.state.is_private ? "invite" : "public", + }, }, { type: "m.room.history_visibility", content: { - "history_visibility": this.state.share_history ? "shared" : "invited" - } + "history_visibility": this.state.share_history ? "shared" : "invited", + }, }, ]; } @@ -94,19 +94,19 @@ module.exports = React.createClass({ options.invite = this.state.invited_users; - var alias = this.getAliasLocalpart(); + const alias = this.getAliasLocalpart(); if (alias) { options.room_alias_name = alias; } - var cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.get(); if (!cli) { // TODO: Error. console.error("Cannot create room: No matrix client."); return; } - var deferred = cli.createRoom(options); + const deferred = cli.createRoom(options); if (this.state.encrypt) { // TODO @@ -116,7 +116,7 @@ module.exports = React.createClass({ phase: this.phases.CREATING, }); - var self = this; + const self = this; deferred.then(function(resp) { self.setState({ @@ -209,7 +209,7 @@ module.exports = React.createClass({ onAliasChanged: function(alias) { this.setState({ - alias: alias + alias: alias, }); }, @@ -220,64 +220,64 @@ module.exports = React.createClass({ }, render: function() { - var curr_phase = this.state.phase; + const curr_phase = this.state.phase; if (curr_phase == this.phases.CREATING) { - var Loader = sdk.getComponent("elements.Spinner"); + const Loader = sdk.getComponent("elements.Spinner"); return ( - + ); } else { - var error_box = ""; + let error_box = ""; if (curr_phase == this.phases.ERROR) { error_box = (
      - {_t('An error occurred: %(error_string)s', {error_string: this.state.error_string})} + { _t('An error occurred: %(error_string)s', {error_string: this.state.error_string}) }
      ); } - var CreateRoomButton = sdk.getComponent("create_room.CreateRoomButton"); - var RoomAlias = sdk.getComponent("create_room.RoomAlias"); - var Presets = sdk.getComponent("create_room.Presets"); - var UserSelector = sdk.getComponent("elements.UserSelector"); - var SimpleRoomHeader = sdk.getComponent("rooms.SimpleRoomHeader"); + const CreateRoomButton = sdk.getComponent("create_room.CreateRoomButton"); + const RoomAlias = sdk.getComponent("create_room.RoomAlias"); + const Presets = sdk.getComponent("create_room.Presets"); + const UserSelector = sdk.getComponent("elements.UserSelector"); + const SimpleRoomHeader = sdk.getComponent("rooms.SimpleRoomHeader"); - var domain = MatrixClientPeg.get().getDomain(); + const domain = MatrixClientPeg.get().getDomain(); return (
      - +
      -
      -