From b813e3b71479badf13aa8555e3739b85f79f1ad6 Mon Sep 17 00:00:00 2001
From: Karol Kosek <krkkx@protonmail.com>
Date: Fri, 12 Oct 2018 16:31:25 +0000
Subject: [PATCH 01/47] Translated using Weblate (Polish)

Currently translated at 89.9% (1140 of 1267 strings)

Translation: Riot Web/matrix-react-sdk
Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/pl/
---
 src/i18n/strings/pl.json | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/src/i18n/strings/pl.json b/src/i18n/strings/pl.json
index 3bbc9b1d73..245ee0c395 100644
--- a/src/i18n/strings/pl.json
+++ b/src/i18n/strings/pl.json
@@ -1146,5 +1146,14 @@
     "was invited %(count)s times|one": "został zaproszony",
     "was banned %(count)s times|one": "został zablokowany",
     "was kicked %(count)s times|one": "został wyrzucony",
-    "Whether or not you're using the Richtext mode of the Rich Text Editor": ""
+    "Whether or not you're using the Richtext mode of the Rich Text Editor": "",
+    "Call in Progress": "Łączenie w toku",
+    "Permission Required": "Wymagane Pozwolenie",
+    "Registration Required": "Wymagana Rejestracja",
+    "You need to register to do this. Would you like to register now?": "Musisz się zarejestrować, aby to zrobić. Czy chcesz się teraz zarejestrować?",
+    "underlined": "podkreślenie",
+    "deleted": "przekreślenie",
+    "numbered-list": "lista numerowana",
+    "bulleted-list": "wykropkowana lista",
+    "block-quote": "blok cytowany"
 }

From 94aac62f255859a95d22b813e4e1004dca21449c Mon Sep 17 00:00:00 2001
From: Travis Ralston <travpc@gmail.com>
Date: Mon, 15 Oct 2018 14:26:02 -0600
Subject: [PATCH 02/47] Move the login box from the left sidebar to where the
 composer is

Fixes https://github.com/vector-im/riot-web/issues/4227

This includes removing the collapse button that isn't needed anymore.
---
 res/css/structures/_LoginBox.scss      |  1 +
 src/components/structures/LeftPanel.js | 10 +----
 src/components/structures/LoginBox.js  | 62 ++++++--------------------
 src/components/structures/RoomView.js  |  7 ++-
 4 files changed, 22 insertions(+), 58 deletions(-)

diff --git a/res/css/structures/_LoginBox.scss b/res/css/structures/_LoginBox.scss
index 7f6199c451..0a3e21a980 100644
--- a/res/css/structures/_LoginBox.scss
+++ b/res/css/structures/_LoginBox.scss
@@ -19,6 +19,7 @@ limitations under the License.
     height: unset !important;
     padding-top: 13px !important;
     padding-bottom: 14px !important;
+    order: 4;
 }
 
 .mx_LoginBox_loginButton_wrapper {
diff --git a/src/components/structures/LeftPanel.js b/src/components/structures/LeftPanel.js
index ebe5d7f507..72d640bcac 100644
--- a/src/components/structures/LeftPanel.js
+++ b/src/components/structures/LeftPanel.js
@@ -181,14 +181,8 @@ var LeftPanel = React.createClass({
         const BottomLeftMenu = sdk.getComponent('structures.BottomLeftMenu');
         const CallPreview = sdk.getComponent('voip.CallPreview');
 
-        let topBox;
-        if (this.context.matrixClient.isGuest()) {
-            const LoginBox = sdk.getComponent('structures.LoginBox');
-            topBox = <LoginBox collapsed={ this.props.collapsed }/>;
-        } else {
-            const SearchBox = sdk.getComponent('structures.SearchBox');
-            topBox = <SearchBox collapsed={ this.props.collapsed } onSearch={ this.onSearch } />;
-        }
+        const SearchBox = sdk.getComponent('structures.SearchBox');
+        const topBox = <SearchBox collapsed={ this.props.collapsed } onSearch={ this.onSearch } />;
 
         const classes = classNames(
             "mx_LeftPanel",
diff --git a/src/components/structures/LoginBox.js b/src/components/structures/LoginBox.js
index a9ea1f95c6..a2269706ee 100644
--- a/src/components/structures/LoginBox.js
+++ b/src/components/structures/LoginBox.js
@@ -1,5 +1,6 @@
 /*
 Copyright 2017 Vector Creations Ltd
+Copyright 2018 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.
@@ -16,31 +17,15 @@ limitations under the License.
 
 'use strict';
 
-var React = require('react');
+const React = require('react');
 import { _t } from '../../languageHandler';
-var sdk = require('../../index')
-var dis = require('../../dispatcher');
-var rate_limited_func = require('../../ratelimitedfunc');
-var AccessibleButton = require('../../components/views/elements/AccessibleButton');
+const dis = require('../../dispatcher');
+const AccessibleButton = require('../../components/views/elements/AccessibleButton');
 
 module.exports = React.createClass({
     displayName: 'LoginBox',
 
     propTypes: {
-        collapsed: React.PropTypes.bool,
-    },
-
-    onToggleCollapse: function(show) {
-        if (show) {
-            dis.dispatch({
-                action: 'show_left_panel',
-            });
-        }
-        else {
-            dis.dispatch({
-                action: 'hide_left_panel',
-            });
-        }
     },
 
     onLoginClick: function() {
@@ -52,41 +37,20 @@ module.exports = React.createClass({
     },
 
     render: function() {
-        var TintableSvg = sdk.getComponent('elements.TintableSvg');
-
-        var toggleCollapse;
-        if (this.props.collapsed) {
-            toggleCollapse =
-                <AccessibleButton className="mx_SearchBox_maximise" onClick={ this.onToggleCollapse.bind(this, true) }>
-                    <TintableSvg src="img/maximise.svg" width="10" height="16" alt="Expand panel"/>
+        const loginButton = (
+            <div className="mx_LoginBox_loginButton_wrapper">
+                <AccessibleButton className="mx_LoginBox_loginButton" element="button" onClick={this.onLoginClick}>
+                    { _t("Login") }
                 </AccessibleButton>
-        }
-        else {
-            toggleCollapse =
-                <AccessibleButton className="mx_SearchBox_minimise" onClick={ this.onToggleCollapse.bind(this, false) }>
-                    <TintableSvg src="img/minimise.svg" width="10" height="16" alt="Collapse panel"/>
+                <AccessibleButton className="mx_LoginBox_registerButton" element="button" onClick={this.onRegisterClick}>
+                    { _t("Register") }
                 </AccessibleButton>
-        }
+            </div>
+        );
 
-        var loginButton;
-        if (!this.props.collapsed) {
-            loginButton = (
-                <div className="mx_LoginBox_loginButton_wrapper">
-                    <AccessibleButton className="mx_LoginBox_loginButton" element="button" onClick={this.onLoginClick}>
-                        { _t("Login") }
-                    </AccessibleButton>
-                    <AccessibleButton className="mx_LoginBox_registerButton" element="button" onClick={this.onRegisterClick}>
-                        { _t("Register") }
-                    </AccessibleButton>
-                </div>
-            );
-        }
-
-        var self = this;
         return (
-            <div className="mx_SearchBox mx_LoginBox">
+            <div className="mx_LoginBox">
                 { loginButton }
-                { toggleCollapse }
             </div>
         );
     }
diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js
index 32121d6de5..62c596e939 100644
--- a/src/components/structures/RoomView.js
+++ b/src/components/structures/RoomView.js
@@ -1669,7 +1669,7 @@ module.exports = React.createClass({
         let messageComposer, searchInfo;
         const canSpeak = (
             // joined and not showing search results
-            myMembership == 'join' && !this.state.searchResults
+            myMembership === 'join' && !this.state.searchResults
         );
         if (canSpeak) {
             messageComposer =
@@ -1683,6 +1683,11 @@ module.exports = React.createClass({
                 />;
         }
 
+        if (MatrixClientPeg.get().isGuest()) {
+            const LoginBox = sdk.getComponent('structures.LoginBox');
+            messageComposer = <LoginBox/>;
+        }
+
         // TODO: Why aren't we storing the term/scope/count in this format
         // in this.state if this is what RoomHeader desires?
         if (this.state.searchResults) {

From d504cdeb8592adc6ff9834559ee51e2c7170343b Mon Sep 17 00:00:00 2001
From: Krombel <krombel@krombel.de>
Date: Tue, 16 Oct 2018 15:51:58 +0000
Subject: [PATCH 03/47] Translated using Weblate (German)

Currently translated at 100.0% (1269 of 1269 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 | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json
index b183c8bfcd..5cb856b651 100644
--- a/src/i18n/strings/de_DE.json
+++ b/src/i18n/strings/de_DE.json
@@ -1289,5 +1289,7 @@
     "You've previously used Riot on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, Riot needs to resync your account.": "Du hast zuvor Riot auf %(host)s ohne verzögertem Laden von Mitgliedern genutzt. In dieser Version war das verzögerte Laden deaktiviert. Da die lokal zwischengespeicherten Daten zwischen diesen Einstellungen nicht kompatibel ist, muss Riot dein Konto neu synchronisieren.",
     "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "Wenn Riot mit der alten Version in einem anderen Tab geöffnet ist, schließe dies bitte, da das parallele Nutzen von Riot auf demselben Host mit aktivierten und deaktivierten verzögertem Laden, Probleme verursachen wird.",
     "Incompatible local cache": "Inkompatibler lokaler Zwischenspeicher",
-    "Clear cache and resync": "Zwischenspeicher löschen und erneut synchronisieren"
+    "Clear cache and resync": "Zwischenspeicher löschen und erneut synchronisieren",
+    "Please accept all of the policies": "Bitte akzeptiere alle Bedingungen",
+    "Please review and accept the policies of this homeserver:": "Bitte sieh dir alle Bedingungen dieses Heimservers an und akzeptiere sie:"
 }

From 7d60e09f8ebef8fb6330f33d220ed1cbb08b49e8 Mon Sep 17 00:00:00 2001
From: Szimszon <github@oregpreshaz.eu>
Date: Tue, 16 Oct 2018 18:03:52 +0000
Subject: [PATCH 04/47] Translated using Weblate (Hungarian)

Currently translated at 100.0% (1269 of 1269 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 | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json
index 51105ed5c5..5a7c5d210a 100644
--- a/src/i18n/strings/hu.json
+++ b/src/i18n/strings/hu.json
@@ -1291,5 +1291,7 @@
     "You've previously used Riot on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, Riot needs to resync your account.": "Előzőleg a szoba tagság késleltetett betöltésének engedélyével itt használtad a Riotot: %(host)s. Ebben a verzióban viszont a késleltetett betöltés nem engedélyezett. Mivel a két gyorsítótár nem kompatibilis egymással így Riotnak újra kell szinkronizálnia a fiókot.",
     "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "Ha a másik Riot verzió fut még egy másik fülön, kérlek zárd be, mivel ha ugyanott használod a Riotot bekapcsolt késleltetett betöltéssel és kikapcsolva is akkor problémák adódhatnak.",
     "Incompatible local cache": "A helyi gyorsítótár nem kompatibilis ezzel a verzióval",
-    "Clear cache and resync": "Gyorsítótár törlése és újraszinkronizálás"
+    "Clear cache and resync": "Gyorsítótár törlése és újraszinkronizálás",
+    "Please accept all of the policies": "Kérlek fogadd el az összes előírást",
+    "Please review and accept the policies of this homeserver:": "Kérlek nézd át és fogadd el a Matrix szerver felhasználói feltételeit:"
 }

From 8668faa6b0f3d1ee643b70884253978fcfda5626 Mon Sep 17 00:00:00 2001
From: Travis Ralston <travpc@gmail.com>
Date: Tue, 16 Oct 2018 19:14:06 -0600
Subject: [PATCH 05/47] Show the group member list again

Fixes https://github.com/vector-im/riot-web/issues/7511
---
 res/css/views/rooms/_MemberList.scss | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/res/css/views/rooms/_MemberList.scss b/res/css/views/rooms/_MemberList.scss
index 83fc70aefb..cfac8797b9 100644
--- a/res/css/views/rooms/_MemberList.scss
+++ b/res/css/views/rooms/_MemberList.scss
@@ -111,6 +111,3 @@ limitations under the License.
     width: 100%;
 }
 
-.mx_MemberList_outerWrapper {
-    height: 0px;
-}

From 2295347d8d3356337e6893410b20e54cb29dbfc4 Mon Sep 17 00:00:00 2001
From: random <dictionary@tutamail.com>
Date: Wed, 17 Oct 2018 09:24:25 +0000
Subject: [PATCH 06/47] Translated using Weblate (Italian)

Currently translated at 100.0% (1269 of 1269 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 d877be6c9e..962e179cc8 100644
--- a/src/i18n/strings/it.json
+++ b/src/i18n/strings/it.json
@@ -1288,5 +1288,7 @@
     "You've previously used Riot on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, Riot needs to resync your account.": "Hai usato Riot precedentemente su %(host)s con il caricamento lento dei membri attivato. In questa versione il caricamento lento è disattivato. Dato che la cache locale non è compatibile tra queste due impostazioni, Riot deve risincronizzare il tuo account.",
     "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "Se l'altra versione di Riot è ancora aperta in un'altra scheda, chiudila perchè usare Riot nello stesso host con il caricamento lento sia attivato che disattivato può causare errori.",
     "Incompatible local cache": "Cache locale non compatibile",
-    "Clear cache and resync": "Svuota cache e risincronizza"
+    "Clear cache and resync": "Svuota cache e risincronizza",
+    "Please accept all of the policies": "Si prega di accettare tutte le condizioni",
+    "Please review and accept the policies of this homeserver:": "Consulta ed accetta le condizioni di questo homeserver:"
 }

From 482360742ffdffe5a976a97aab48a4b442f38361 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?K=C3=A9vin=20C?= <zecakeh@posteo.net>
Date: Tue, 16 Oct 2018 22:07:53 +0000
Subject: [PATCH 07/47] Translated using Weblate (French)

Currently translated at 100.0% (1269 of 1269 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 | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json
index ede9c26656..196ea4bcd9 100644
--- a/src/i18n/strings/fr.json
+++ b/src/i18n/strings/fr.json
@@ -1291,5 +1291,7 @@
     "You've previously used Riot on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, Riot needs to resync your account.": "Vous avez utilisé auparavant Riot sur %(host)s avec le chargement différé activé. Dans cette version le chargement différé est désactivé. Comme le cache local n'est pas compatible entre ces deux réglages, Riot doit resynchroniser votre compte.",
     "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "Si l'autre version de Riot est encore ouverte dans un autre onglet, merci de le fermer car l'utilisation de Riot sur le même hôte avec le chargement différé activé et désactivé à la fois causera des problèmes.",
     "Incompatible local cache": "Cache local incompatible",
-    "Clear cache and resync": "Vider le cache et resynchroniser"
+    "Clear cache and resync": "Vider le cache et resynchroniser",
+    "Please accept all of the policies": "Veuillez accepter toutes les politiques",
+    "Please review and accept the policies of this homeserver:": "Veuillez lire et accepter les politiques de ce serveur d'accueil :"
 }

From 336ea96c91d869ef2b975e70b4f1c7f116981a08 Mon Sep 17 00:00:00 2001
From: Szimszon <github@oregpreshaz.eu>
Date: Tue, 16 Oct 2018 18:06:25 +0000
Subject: [PATCH 08/47] Translated using Weblate (Hungarian)

Currently translated at 100.0% (1269 of 1269 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 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json
index 5a7c5d210a..e4bf2e3036 100644
--- a/src/i18n/strings/hu.json
+++ b/src/i18n/strings/hu.json
@@ -1292,6 +1292,6 @@
     "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "Ha a másik Riot verzió fut még egy másik fülön, kérlek zárd be, mivel ha ugyanott használod a Riotot bekapcsolt késleltetett betöltéssel és kikapcsolva is akkor problémák adódhatnak.",
     "Incompatible local cache": "A helyi gyorsítótár nem kompatibilis ezzel a verzióval",
     "Clear cache and resync": "Gyorsítótár törlése és újraszinkronizálás",
-    "Please accept all of the policies": "Kérlek fogadd el az összes előírást",
+    "Please accept all of the policies": "Kérlek fogadd el a felhasználói feltételeket",
     "Please review and accept the policies of this homeserver:": "Kérlek nézd át és fogadd el a Matrix szerver felhasználói feltételeit:"
 }

From e1be8966bcf805bcdb5de3d542e453b7c4f88112 Mon Sep 17 00:00:00 2001
From: Osoitz <oelkoro@gmail.com>
Date: Wed, 17 Oct 2018 15:45:48 +0000
Subject: [PATCH 09/47] Translated using Weblate (Basque)

Currently translated at 100.0% (1270 of 1270 strings)

Translation: Riot Web/matrix-react-sdk
Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eu/
---
 src/i18n/strings/eu.json | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json
index 96f201672d..5adbe476e7 100644
--- a/src/i18n/strings/eu.json
+++ b/src/i18n/strings/eu.json
@@ -1285,5 +1285,12 @@
     "<h1>HTML for your community's page</h1>\r\n<p>\r\n    Use the long description to introduce new members to the community, or distribute\r\n    some important <a href=\"foo\">links</a>\r\n</p>\r\n<p>\r\n    You can even use 'img' tags\r\n</p>\r\n": "<h1>Zure komunitatearen orriaren HTMLa</h1>\n<p>\n    Erabili deskripzio luzea kide berriek komunitatea ezagutu dezaten, edo eman ezagutzera <a href=\"foo\">esteka</a> garrantzitsuak\n</p>\n<p>\n    'img' etiketak erabili ditzakezu ere\n</p>\n",
     "Submit Debug Logs": "Bidali arazketa egunkariak",
     "An email address is required to register on this homeserver.": "e-mail helbide bat behar da hasiera-zerbitzari honetan izena emateko.",
-    "A phone number is required to register on this homeserver.": "telefono zenbaki bat behar da hasiera-zerbitzari honetan izena emateko."
+    "A phone number is required to register on this homeserver.": "telefono zenbaki bat behar da hasiera-zerbitzari honetan izena emateko.",
+    "Please accept all of the policies": "Onartu mesedez politika guztiak",
+    "Please review and accept the policies of this homeserver:": "Irakurri eta onartu hasiera zerbitzari honen politikak:",
+    "You've previously used Riot on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, Riot needs to resync your account.": "Aurretik Riot erabili duzu %(host)s zerbitzarian kideen karga alferra gaituta zenuela. Bertsio honetan karga alferra desgaituta dago. Katxe lokala bi ezarpen hauen artean bateragarria ez denez, Riotek zure kontua berriro sinkronizatu behar du.",
+    "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "Rioten beste bertsioa oraindik beste fitxat batean irekita badago, itxi ezazu zerbitzari bera aldi berean karga alferra gaituta eta desgaituta erabiltzeak arazoak sor ditzakeelako.",
+    "Incompatible local cache": "Katxe lokal bateraezina",
+    "Clear cache and resync": "Garbitu katxea eta sinkronizatu berriro",
+    "Add some now": "Gehitu batzuk orain"
 }

From 2f94631720a870ca881a494acaccc90853ddd832 Mon Sep 17 00:00:00 2001
From: Szimszon <github@oregpreshaz.eu>
Date: Tue, 16 Oct 2018 18:06:25 +0000
Subject: [PATCH 10/47] Translated using Weblate (Hungarian)

Currently translated at 100.0% (1270 of 1270 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 | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json
index e4bf2e3036..8ce023f377 100644
--- a/src/i18n/strings/hu.json
+++ b/src/i18n/strings/hu.json
@@ -1293,5 +1293,6 @@
     "Incompatible local cache": "A helyi gyorsítótár nem kompatibilis ezzel a verzióval",
     "Clear cache and resync": "Gyorsítótár törlése és újraszinkronizálás",
     "Please accept all of the policies": "Kérlek fogadd el a felhasználói feltételeket",
-    "Please review and accept the policies of this homeserver:": "Kérlek nézd át és fogadd el a Matrix szerver felhasználói feltételeit:"
+    "Please review and accept the policies of this homeserver:": "Kérlek nézd át és fogadd el a Matrix szerver felhasználói feltételeit:",
+    "Add some now": "Adj hozzá párat"
 }

From af8dfda9a7a78873d5e0b7f5aede5cd266ed270c Mon Sep 17 00:00:00 2001
From: Travis Ralston <travpc@gmail.com>
Date: Wed, 17 Oct 2018 13:53:12 -0600
Subject: [PATCH 11/47] Add a bit of text to explain the purpose of the
 RoomPreviewSpinner

Fixes https://github.com/vector-im/riot-web/issues/5869
---
 res/css/views/rooms/_RoomPreviewBar.scss     |  4 ++++
 src/components/structures/RoomView.js        |  3 +++
 src/components/views/rooms/RoomPreviewBar.js | 11 ++++++++++-
 src/i18n/strings/en_EN.json                  |  1 +
 4 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/res/css/views/rooms/_RoomPreviewBar.scss b/res/css/views/rooms/_RoomPreviewBar.scss
index 331eb582ea..8196740499 100644
--- a/res/css/views/rooms/_RoomPreviewBar.scss
+++ b/res/css/views/rooms/_RoomPreviewBar.scss
@@ -56,3 +56,7 @@ limitations under the License.
 .mx_RoomPreviewBar_warningIcon {
     padding: 12px;
 }
+
+.mx_RoomPreviewBar_spinnerIntro {
+    margin-top: 50px;
+}
\ No newline at end of file
diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js
index 8e226bdfcf..52264266a8 100644
--- a/src/components/structures/RoomView.js
+++ b/src/components/structures/RoomView.js
@@ -1514,6 +1514,7 @@ module.exports = React.createClass({
                                             canPreview={false} error={this.state.roomLoadError}
                                             roomAlias={roomAlias}
                                             spinner={this.state.joining}
+                                            spinnerState="joining"
                                             inviterName={inviterName}
                                             invitedEmail={invitedEmail}
                                             room={this.state.room}
@@ -1558,6 +1559,7 @@ module.exports = React.createClass({
                                             inviterName={inviterName}
                                             canPreview={false}
                                             spinner={this.state.joining}
+                                            spinnerState="joining"
                                             room={this.state.room}
                             />
                         </div>
@@ -1645,6 +1647,7 @@ module.exports = React.createClass({
                                 onForgetClick={this.onForgetClick}
                                 onRejectClick={this.onRejectThreepidInviteButtonClicked}
                                 spinner={this.state.joining}
+                                spinnerState="joining"
                                 inviterName={inviterName}
                                 invitedEmail={invitedEmail}
                                 canPreview={this.state.canPeek}
diff --git a/src/components/views/rooms/RoomPreviewBar.js b/src/components/views/rooms/RoomPreviewBar.js
index 5ec19d185e..9d3dbe5217 100644
--- a/src/components/views/rooms/RoomPreviewBar.js
+++ b/src/components/views/rooms/RoomPreviewBar.js
@@ -44,9 +44,13 @@ module.exports = React.createClass({
         error: PropTypes.object,
 
         canPreview: PropTypes.bool,
-        spinner: PropTypes.bool,
         room: PropTypes.object,
 
+        // When a spinner is present, a spinnerState can be specified to indicate the
+        // purpose of the spinner.
+        spinner: PropTypes.bool,
+        spinnerState: PropTypes.oneOf(["joining"]),
+
         // The alias that was used to access this room, if appropriate
         // If given, this will be how the room is referred to (eg.
         // in error messages).
@@ -93,7 +97,12 @@ module.exports = React.createClass({
 
         if (this.props.spinner || this.state.busy) {
             const Spinner = sdk.getComponent("elements.Spinner");
+            let spinnerIntro = "";
+            if (this.props.spinnerState === "joining") {
+                spinnerIntro = _t("Joining room...");
+            }
             return (<div className="mx_RoomPreviewBar">
+                <p className="mx_RoomPreviewBar_spinnerIntro">{ spinnerIntro }</p>
                 <Spinner />
             </div>);
         }
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index e42d3ce434..e0f4663532 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -512,6 +512,7 @@
     "You have no historical rooms": "You have no historical rooms",
     "Historical": "Historical",
     "System Alerts": "System Alerts",
+    "Joining room...": "Joining room...",
     "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Unable to ascertain that the address this invite was sent to matches one associated with your account.",
     "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:",
     "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.",

From 7b8506ba653548a040822a75814ea3a19c553c38 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?K=C3=A9vin=20C?= <zecakeh@posteo.net>
Date: Tue, 16 Oct 2018 22:07:53 +0000
Subject: [PATCH 12/47] Translated using Weblate (French)

Currently translated at 100.0% (1270 of 1270 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 | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json
index 196ea4bcd9..125ac49b79 100644
--- a/src/i18n/strings/fr.json
+++ b/src/i18n/strings/fr.json
@@ -1293,5 +1293,6 @@
     "Incompatible local cache": "Cache local incompatible",
     "Clear cache and resync": "Vider le cache et resynchroniser",
     "Please accept all of the policies": "Veuillez accepter toutes les politiques",
-    "Please review and accept the policies of this homeserver:": "Veuillez lire et accepter les politiques de ce serveur d'accueil :"
+    "Please review and accept the policies of this homeserver:": "Veuillez lire et accepter les politiques de ce serveur d'accueil :",
+    "Add some now": "En ajouter maintenant"
 }

From fc4d4acacea7418dfd71eaa6011ac2e66f70e6cf Mon Sep 17 00:00:00 2001
From: Slavi Pantaleev <slavi@devture.com>
Date: Thu, 18 Oct 2018 12:07:22 +0000
Subject: [PATCH 13/47] Translated using Weblate (Bulgarian)

Currently translated at 100.0% (1270 of 1270 strings)

Translation: Riot Web/matrix-react-sdk
Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/
---
 src/i18n/strings/bg.json | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json
index 9921662964..b49384891c 100644
--- a/src/i18n/strings/bg.json
+++ b/src/i18n/strings/bg.json
@@ -1288,5 +1288,8 @@
     "You've previously used Riot on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, Riot needs to resync your account.": "Преди сте използвали Riot на %(host)s с включено постепенно зареждане на членове. В тази версия, тази настройка е изключена. Понеже локалният кеш не е съвместим при тези две настройки, Riot трябва да синхронизира акаунта Ви наново.",
     "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "Ако другата версия на Riot все още е отворена в друг таб, моля затворете я. Използването на Riot на един адрес във версии с постепенно и без постепенно зареждане ще причини проблеми.",
     "Incompatible local cache": "Несъвместим локален кеш",
-    "Clear cache and resync": "Изчисти кеша и ресинхронизирай"
+    "Clear cache and resync": "Изчисти кеша и ресинхронизирай",
+    "Please accept all of the policies": "Моля, приемете всички политики",
+    "Please review and accept the policies of this homeserver:": "Моля, прегледайте и приемете политиките на този сървър:",
+    "Add some now": "Добави сега"
 }

From eb517fe2e9a1199a070152f90f1e1e229aea27bc Mon Sep 17 00:00:00 2001
From: Jeff Huang <s8321414@gmail.com>
Date: Fri, 19 Oct 2018 01:18:29 +0000
Subject: [PATCH 14/47] Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (1270 of 1270 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 | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json
index 5b259066a7..e3492d1ef6 100644
--- a/src/i18n/strings/zh_Hant.json
+++ b/src/i18n/strings/zh_Hant.json
@@ -1289,5 +1289,8 @@
     "You've previously used Riot on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, Riot needs to resync your account.": "您之前曾在 %(host)s 上使用 Riot 並啟用成員列表的延遲載入。在此版本中延遲載入已停用。由於本機快取在這兩個設定間不相容,Riot 必須重新同步您的帳號。",
     "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "若其他分頁仍有不同版本的 Riot,請將其關閉,因為在同一個主機上同時啟用和停用延遲載入將會發生問題。",
     "Incompatible local cache": "不相容的本機快取",
-    "Clear cache and resync": "清除快取並重新同步"
+    "Clear cache and resync": "清除快取並重新同步",
+    "Please accept all of the policies": "請接受所有政策",
+    "Please review and accept the policies of this homeserver:": "請審閱並接受此家伺服器的政策:",
+    "Add some now": "現在就新增一些"
 }

From 49efefa6307e6eb42ac64dfb0a9f7af5e8220b00 Mon Sep 17 00:00:00 2001
From: Travis Ralston <travpc@gmail.com>
Date: Fri, 19 Oct 2018 14:18:05 -0600
Subject: [PATCH 15/47] Fix an error where React doesn't like value=null on a
 select

This only happens when there are no canonical aliases for a room.
---
 src/components/views/room_settings/AliasSettings.js | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/components/views/room_settings/AliasSettings.js b/src/components/views/room_settings/AliasSettings.js
index f9bf52cd24..92a025f10c 100644
--- a/src/components/views/room_settings/AliasSettings.js
+++ b/src/components/views/room_settings/AliasSettings.js
@@ -220,8 +220,9 @@ module.exports = React.createClass({
         let canonical_alias_section;
         if (this.props.canSetCanonicalAlias) {
             let found = false;
+            const canonicalValue = this.state.canonicalAlias || "";
             canonical_alias_section = (
-                <select onChange={this.onCanonicalAliasChange} value={this.state.canonicalAlias}>
+                <select onChange={this.onCanonicalAliasChange} value={canonicalValue}>
                     <option value="" key="unset">{ _t('not specified') }</option>
                     {
                         Object.keys(self.state.domainToAliases).map((domain, i) => {

From 9582c1e65a490c7797236b1740332d014a3bd66e Mon Sep 17 00:00:00 2001
From: Travis Ralston <travpc@gmail.com>
Date: Fri, 19 Oct 2018 15:33:23 -0600
Subject: [PATCH 16/47] Move all dialog buttons to the right and fix their
 order

Fixes https://github.com/vector-im/riot-web/issues/5689

Some dialogs had their own CSS that prevented the buttons from being placed in the right spot. This has been fixed by using a generic standard for the buttons. The only strange dialog that needed more CSS was the devtools dialog due to the header.

Not all dialogs have been checked - I spot-checked about half of them and verified the CSS manually on an established account. It's hard to get at all the dialogs without convoluted testing.
---
 res/css/_common.scss                           |  5 +++++
 res/css/_components.scss                       |  1 -
 res/css/views/dialogs/_ChatInviteDialog.scss   |  8 --------
 res/css/views/dialogs/_DevtoolsDialog.scss     |  4 ++++
 res/css/views/dialogs/_QuestionDialog.scss     | 18 ------------------
 src/components/views/dialogs/DevtoolsDialog.js |  4 ++--
 src/components/views/elements/DialogButtons.js | 10 +++++-----
 7 files changed, 16 insertions(+), 34 deletions(-)
 delete mode 100644 res/css/views/dialogs/_QuestionDialog.scss

diff --git a/res/css/_common.scss b/res/css/_common.scss
index 38f576a532..bf67edc1c3 100644
--- a/res/css/_common.scss
+++ b/res/css/_common.scss
@@ -222,6 +222,11 @@ textarea {
     word-wrap: break-word;
 }
 
+.mx_Dialog_buttons {
+    padding-right: 58px;
+    text-align: right;
+}
+
 .mx_Dialog button, .mx_Dialog input[type="submit"] {
     @mixin mx_DialogButton;
     margin-left: 0px;
diff --git a/res/css/_components.scss b/res/css/_components.scss
index 0e40b40a29..a09f895d5f 100644
--- a/res/css/_components.scss
+++ b/res/css/_components.scss
@@ -38,7 +38,6 @@
 @import "./views/dialogs/_DevtoolsDialog.scss";
 @import "./views/dialogs/_EncryptedEventDialog.scss";
 @import "./views/dialogs/_GroupAddressPicker.scss";
-@import "./views/dialogs/_QuestionDialog.scss";
 @import "./views/dialogs/_RoomUpgradeDialog.scss";
 @import "./views/dialogs/_SetEmailDialog.scss";
 @import "./views/dialogs/_SetMxIdDialog.scss";
diff --git a/res/css/views/dialogs/_ChatInviteDialog.scss b/res/css/views/dialogs/_ChatInviteDialog.scss
index 6fc211743d..dcc0f5921a 100644
--- a/res/css/views/dialogs/_ChatInviteDialog.scss
+++ b/res/css/views/dialogs/_ChatInviteDialog.scss
@@ -14,14 +14,6 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-.mx_ChatInviteDialog {
-    /* XXX: padding-left is on mx_Dialog but padding-right has subsequently
-     * been added on other dialogs. Surely all our dialogs should have consistent
-     * right hand padding?
-     */
-    padding-right: 58px;
-}
-
 /* Using a textarea for this element, to circumvent autofill */
 .mx_ChatInviteDialog_input,
 .mx_ChatInviteDialog_input:focus
diff --git a/res/css/views/dialogs/_DevtoolsDialog.scss b/res/css/views/dialogs/_DevtoolsDialog.scss
index a4a868bd11..3764bb13b3 100644
--- a/res/css/views/dialogs/_DevtoolsDialog.scss
+++ b/res/css/views/dialogs/_DevtoolsDialog.scss
@@ -14,6 +14,10 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
+.mx_DevTools_dialog {
+    padding-right: 58px;
+}
+
 .mx_DevTools_content {
     margin: 10px 0;
 }
diff --git a/res/css/views/dialogs/_QuestionDialog.scss b/res/css/views/dialogs/_QuestionDialog.scss
deleted file mode 100644
index 3d47f17592..0000000000
--- a/res/css/views/dialogs/_QuestionDialog.scss
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
-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.
-*/
-.mx_QuestionDialog {
-    padding-right: 58px;
-}
diff --git a/src/components/views/dialogs/DevtoolsDialog.js b/src/components/views/dialogs/DevtoolsDialog.js
index ea198461c5..22ee44f81a 100644
--- a/src/components/views/dialogs/DevtoolsDialog.js
+++ b/src/components/views/dialogs/DevtoolsDialog.js
@@ -625,7 +625,7 @@ export default class DevtoolsDialog extends React.Component {
         let body;
 
         if (this.state.mode) {
-            body = <div>
+            body = <div className="mx_DevTools_dialog">
                 <div className="mx_DevTools_label_left">{ this.state.mode.getLabel() }</div>
                 <div className="mx_DevTools_label_right">Room ID: { this.props.roomId }</div>
                 <div className="mx_DevTools_label_bottom" />
@@ -634,7 +634,7 @@ export default class DevtoolsDialog extends React.Component {
         } else {
             const classes = "mx_DevTools_RoomStateExplorer_button";
             body = <div>
-                <div>
+                <div className="mx_DevTools_dialog">
                     <div className="mx_DevTools_label_left">{ _t('Toolbox') }</div>
                     <div className="mx_DevTools_label_right">Room ID: { this.props.roomId }</div>
                     <div className="mx_DevTools_label_bottom" />
diff --git a/src/components/views/elements/DialogButtons.js b/src/components/views/elements/DialogButtons.js
index baf831415f..f314588caa 100644
--- a/src/components/views/elements/DialogButtons.js
+++ b/src/components/views/elements/DialogButtons.js
@@ -70,15 +70,15 @@ module.exports = React.createClass({
         }
         return (
             <div className="mx_Dialog_buttons">
+                { cancelButton }
+                { this.props.children }
                 <button className={primaryButtonClassName}
-                    onClick={this.props.onPrimaryButtonClick}
-                    autoFocus={this.props.focus}
-                    disabled={this.props.disabled}
+                        onClick={this.props.onPrimaryButtonClick}
+                        autoFocus={this.props.focus}
+                        disabled={this.props.disabled}
                 >
                     { this.props.primaryButton }
                 </button>
-                { this.props.children }
-                { cancelButton }
             </div>
         );
     },

From 51a03a700a08eaf625d2f7f0f22af3154e555fe6 Mon Sep 17 00:00:00 2001
From: Oliwer <Lup3@xmcode.pl>
Date: Sat, 20 Oct 2018 15:16:06 +0000
Subject: [PATCH 17/47] Translated using Weblate (Polish)

Currently translated at 91.6% (1164 of 1270 strings)

Translation: Riot Web/matrix-react-sdk
Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/pl/
---
 src/i18n/strings/pl.json | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/src/i18n/strings/pl.json b/src/i18n/strings/pl.json
index 245ee0c395..cc6d7ebd84 100644
--- a/src/i18n/strings/pl.json
+++ b/src/i18n/strings/pl.json
@@ -1146,7 +1146,7 @@
     "was invited %(count)s times|one": "został zaproszony",
     "was banned %(count)s times|one": "został zablokowany",
     "was kicked %(count)s times|one": "został wyrzucony",
-    "Whether or not you're using the Richtext mode of the Rich Text Editor": "",
+    "Whether or not you're using the Richtext mode of the Rich Text Editor": "Niezależnie od tego, czy używasz trybu Richtext edytora tekstu w formacie RTF",
     "Call in Progress": "Łączenie w toku",
     "Permission Required": "Wymagane Pozwolenie",
     "Registration Required": "Wymagana Rejestracja",
@@ -1155,5 +1155,28 @@
     "deleted": "przekreślenie",
     "numbered-list": "lista numerowana",
     "bulleted-list": "wykropkowana lista",
-    "block-quote": "blok cytowany"
+    "block-quote": "blok cytowany",
+    "A conference call could not be started because the intgrations server is not available": "Połączenie grupowe nie może zostać rozpoczęte, ponieważ serwer jest niedostępny",
+    "A call is currently being placed!": "W tej chwili trwa rozmowa!",
+    "A call is already in progress!": "W tej chwili trwa połączenie!",
+    "You do not have permission to start a conference call in this room": "Nie posiadasz permisji do rozpoczęcia rozmowy grupowej w tym pokoju",
+    "Unignored user": "Nieignorowany użytkownik",
+    "Forces the current outbound group session in an encrypted room to be discarded": "Wymusza odrzucenie bieżącej sesji grupy wychodzącej w zaszyfrowanym pokoju",
+    "%(senderName)s added %(count)s %(addedAddresses)s as addresses for this room.|other": "%(senderName)s dodał %(addedAddresses)s jako adres tego pokoju.",
+    "%(senderName)s added %(count)s %(addedAddresses)s as addresses for this room.|one": "%(senderName)s dodał %(addedAddresses)s jako adresy tego pokoju.",
+    "%(senderName)s removed %(count)s %(removedAddresses)s as addresses for this room.|other": "%(senderName)s usunął %(removedAddresses)s jako adres tego pokoju.",
+    "%(senderName)s removed %(count)s %(removedAddresses)s as addresses for this room.|one": "%(senderName)s usunął %(removedAddresses)s jako adresy tego pokoju.",
+    "%(senderName)s added %(addedAddresses)s and removed %(removedAddresses)s as addresses for this room.": "%(senderName)s dodał %(addedAddresses)s i %(removedAddresses)s usunął adresy z tego pokoju.",
+    "%(senderName)s set the main address for this room to %(address)s.": "%(senderName)s ustawił domyślny adres dla tego pokoju jako %(address)s.",
+    "%(senderName)s removed the main address for this room.": "%(senderName)s usunął domyślny adres tego pokoju.",
+    "This homeserver has hit its Monthly Active User limit.": "Ten serwer osiągnął miesięczny limit aktywnego użytkownika.",
+    "This homeserver has exceeded one of its resource limits.": "Ten serwer przekroczył jeden z limitów.",
+    "Please <a>contact your service administrator</a> to continue using the service.": "Proszę, <a>skontaktuj się z administratorem</a> aby korzystać dalej z funkcji.",
+    "Unable to connect to Homeserver. Retrying...": "Nie można się połączyć z serwerem. Ponawanianie...",
+    "Sorry, your homeserver is too old to participate in this room.": "Przepraszamy, twój serwer jest zbyt stary by wziąć udział w tym pokoju.",
+    "Please contact your homeserver administrator.": "Proszę o kontakt z administratorem serwera.",
+    "Increase performance by only loading room members on first view": "Zwiększ wydajność, ładując tylko członków pokoju w pierwszym widoku",
+    "Enable widget screenshots on supported widgets": "Włącz widżety zrzutów ekranów na obsługiwanych widżetach",
+    "Show empty room list headings": "Pokaż nagłówki z pustym pokojem",
+    "In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.": "W zaszyfrowanych pokojach, takich jak ten, podgląd adresów URL jest domyślnie wyłączony, aby upewnić się, że serwer (w którym generowane są podglądy) nie może zbierać informacji o linkach widocznych w tym pokoju."
 }

From 2a6ae17e6a80d5b395da6ae3f152efc9194bb862 Mon Sep 17 00:00:00 2001
From: Karol Kosek <krkkx@protonmail.com>
Date: Sat, 20 Oct 2018 15:47:21 +0000
Subject: [PATCH 18/47] Translated using Weblate (Polish)

Currently translated at 91.6% (1164 of 1270 strings)

Translation: Riot Web/matrix-react-sdk
Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/pl/
---
 src/i18n/strings/pl.json | 38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/src/i18n/strings/pl.json b/src/i18n/strings/pl.json
index cc6d7ebd84..ee868b4d0b 100644
--- a/src/i18n/strings/pl.json
+++ b/src/i18n/strings/pl.json
@@ -143,11 +143,11 @@
     "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or <a>enable unsafe scripts</a>.": "Nie można nawiązać połączenia z serwerem przy użyciu HTTP podczas korzystania z HTTPS dla bieżącej strony. Użyj HTTPS lub <a>włącz niebezpieczne skrypty</a>.",
     "Can't load user settings": "Nie można załadować ustawień użytkownika",
     "Cannot add any more widgets": "Nie można dodać już więcej widżetów",
-    "%(senderName)s changed their profile picture.": "%(senderName)s zmienił swoje zdjęcie profilowe.",
-    "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s zmienił poziom mocy %(powerLevelDiffText)s.",
-    "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s zmienił nazwę pokoju na %(roomName)s.",
-    "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s usunął nazwę pokoju.",
-    "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s zmienił temat na \"%(topic)s\".",
+    "%(senderName)s changed their profile picture.": "%(senderName)s zmienił(a) swoje zdjęcie profilowe.",
+    "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s zmienił(a) poziom mocy %(powerLevelDiffText)s.",
+    "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s zmienił(a) nazwę pokoju na %(roomName)s.",
+    "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s usunął(-ęła) nazwę pokoju.",
+    "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s zmienił(a) temat na \"%(topic)s\".",
     "Changes to who can read history will only apply to future messages in this room": "Zmiany w dostępie do historii będą dotyczyć tylko przyszłych wiadomości w tym pokoju",
     "Changes your display nickname": "Zmień swój pseudonim",
     "Changes colour scheme of current room": "Zmień schemat kolorystyczny bieżącego pokoju",
@@ -370,8 +370,8 @@
     "Rejoin": "Dołącz ponownie",
     "Remote addresses for this room:": "Adresy zdalne dla tego pokoju:",
     "Remove Contact Information?": "Usunąć dane kontaktowe?",
-    "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s usunął swoją nazwę ekranową (%(oldDisplayName)s).",
-    "%(senderName)s removed their profile picture.": "%(senderName)s usunął swoje zdjęcie profilowe.",
+    "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s usunął(-ęła) swoją wyświetlaną nazwę (%(oldDisplayName)s).",
+    "%(senderName)s removed their profile picture.": "%(senderName)s usunął(-ęła) swoje zdjęcie profilowe.",
     "Remove %(threePid)s?": "Usunąć %(threePid)s?",
     "%(senderName)s requested a VoIP conference.": "%(senderName)s zażądał grupowego połączenia głosowego VoIP.",
     "Results from DuckDuckGo": "Wyniki z DuckDuckGo",
@@ -629,9 +629,9 @@
     " (unsupported)": " (niewspierany)",
     "Idle": "Bezczynny",
     "Check for update": "Sprawdź aktualizacje",
-    "%(senderDisplayName)s changed the room avatar to <img/>": "%(senderDisplayName)s zmienił awatar pokoju na <img/>",
-    "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s usunął awatar pokoju.",
-    "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s zmienił awatar %(roomName)s",
+    "%(senderDisplayName)s changed the room avatar to <img/>": "%(senderDisplayName)s zmienił(a) awatar pokoju na <img/>",
+    "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s usunął(-ęła) awatar pokoju.",
+    "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s zmienił(a) awatar %(roomName)s",
     "This will be your account name on the <span></span> homeserver, or you can pick a <a>different server</a>.": "To będzie twoja nazwa konta na <span></span> serwerze domowym; możesz też wybrać <a>inny serwer</a>.",
     "If you already have a Matrix account you can <a>log in</a> instead.": "Jeśli już posiadasz konto Matrix możesz się <a>zalogować</a>.",
     "Not a valid Riot keyfile": "Niepoprawny plik klucza Riot",
@@ -640,7 +640,7 @@
     "Do you want to set an email address?": "Czy chcesz ustawić adres e-mail?",
     "To return to your account in future you need to set a password": "By móc powrócić do swojego konta w przyszłości musisz ustawić hasło",
     "Share without verifying": "Udostępnij bez weryfikacji",
-    "You added a new device '%(displayName)s', which is requesting encryption keys.": "Dodałeś nowe urządzenie '%(displayName)s', które żąda kluczy szyfrujących.",
+    "You added a new device '%(displayName)s', which is requesting encryption keys.": "Dodałeś(-aś) nowe urządzenie '%(displayName)s', które żąda kluczy szyfrujących.",
     "Your unverified device '%(displayName)s' is requesting encryption keys.": "Twoje niezweryfikowane urządzenie '%(displayName)s' żąda kluczy szyfrujących.",
     "Encryption key request": "Żądanie klucza szyfrującego",
     "Autocomplete Delay (ms):": "Opóźnienie autouzupełniania (ms):",
@@ -700,8 +700,8 @@
     "Ignored user": "Użytkownik ignorowany",
     "You are now ignoring %(userId)s": "Ignorujesz teraz %(userId)s",
     "You are no longer ignoring %(userId)s": "Nie ignorujesz już %(userId)s",
-    "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s zmienił swoją wyświetlaną nazwę na %(displayName)s.",
-    "%(senderName)s changed the pinned messages for the room.": "%(senderName)s zmienił przypiętą wiadomość dla tego pokoju.",
+    "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s zmienił(a) swoją wyświetlaną nazwę na %(displayName)s.",
+    "%(senderName)s changed the pinned messages for the room.": "%(senderName)s zmienił(a) przypiętą wiadomość dla tego pokoju.",
     "Message Pinning": "Przypinanie wiadomości",
     "%(names)s and %(count)s others are typing|other": "%(names)s oraz %(count)s innych piszą",
     "%(names)s and %(count)s others are typing|one": "%(names)s oraz jedna inna osoba piszą",
@@ -1162,13 +1162,13 @@
     "You do not have permission to start a conference call in this room": "Nie posiadasz permisji do rozpoczęcia rozmowy grupowej w tym pokoju",
     "Unignored user": "Nieignorowany użytkownik",
     "Forces the current outbound group session in an encrypted room to be discarded": "Wymusza odrzucenie bieżącej sesji grupy wychodzącej w zaszyfrowanym pokoju",
-    "%(senderName)s added %(count)s %(addedAddresses)s as addresses for this room.|other": "%(senderName)s dodał %(addedAddresses)s jako adres tego pokoju.",
-    "%(senderName)s added %(count)s %(addedAddresses)s as addresses for this room.|one": "%(senderName)s dodał %(addedAddresses)s jako adresy tego pokoju.",
-    "%(senderName)s removed %(count)s %(removedAddresses)s as addresses for this room.|other": "%(senderName)s usunął %(removedAddresses)s jako adres tego pokoju.",
-    "%(senderName)s removed %(count)s %(removedAddresses)s as addresses for this room.|one": "%(senderName)s usunął %(removedAddresses)s jako adresy tego pokoju.",
+    "%(senderName)s added %(count)s %(addedAddresses)s as addresses for this room.|other": "%(senderName)s dodał(a) %(addedAddresses)s jako adres tego pokoju.",
+    "%(senderName)s added %(count)s %(addedAddresses)s as addresses for this room.|one": "%(senderName)s dodał(a) %(addedAddresses)s jako adres tego pokoju.",
+    "%(senderName)s removed %(count)s %(removedAddresses)s as addresses for this room.|other": "%(senderName)s usunął(-ęła) %(removedAddresses)s jako adres tego pokoju.",
+    "%(senderName)s removed %(count)s %(removedAddresses)s as addresses for this room.|one": "%(senderName)s usunął(-ęła) %(removedAddresses)s jako adres tego pokoju.",
     "%(senderName)s added %(addedAddresses)s and removed %(removedAddresses)s as addresses for this room.": "%(senderName)s dodał %(addedAddresses)s i %(removedAddresses)s usunął adresy z tego pokoju.",
-    "%(senderName)s set the main address for this room to %(address)s.": "%(senderName)s ustawił domyślny adres dla tego pokoju jako %(address)s.",
-    "%(senderName)s removed the main address for this room.": "%(senderName)s usunął domyślny adres tego pokoju.",
+    "%(senderName)s set the main address for this room to %(address)s.": "%(senderName)s ustawił(a) główny adres dla tego pokoju na %(address)s.",
+    "%(senderName)s removed the main address for this room.": "%(senderName)s usunął(-ęła) główny adres tego pokoju.",
     "This homeserver has hit its Monthly Active User limit.": "Ten serwer osiągnął miesięczny limit aktywnego użytkownika.",
     "This homeserver has exceeded one of its resource limits.": "Ten serwer przekroczył jeden z limitów.",
     "Please <a>contact your service administrator</a> to continue using the service.": "Proszę, <a>skontaktuj się z administratorem</a> aby korzystać dalej z funkcji.",

From 2ac10dd6b15edc8bb9a3d782546fccb46017dae2 Mon Sep 17 00:00:00 2001
From: FeiYang <feiyang@fyol.xyz>
Date: Sat, 20 Oct 2018 09:54:35 +0000
Subject: [PATCH 19/47] Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (1270 of 1270 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 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json
index e3492d1ef6..ad14a6a94c 100644
--- a/src/i18n/strings/zh_Hant.json
+++ b/src/i18n/strings/zh_Hant.json
@@ -165,7 +165,7 @@
     "Success": "成功",
     "The default role for new room members is": "此聊天室新成員的預設角色是",
     "The main address for this room is": "此聊天室的主要地址是",
-    "This email address is already in use": "此電子郵件地址已經被使用",
+    "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' exceeds this home server's size limit for uploads": "文件 '%(fileName)s' 超過了這個家伺服器的上傳大小限制",

From b3d5612746048364128a521489a1953395e3c10f Mon Sep 17 00:00:00 2001
From: Victor Grousset <victor@tuxayo.net>
Date: Sun, 21 Oct 2018 15:19:21 +0000
Subject: [PATCH 20/47] Translated using Weblate (Esperanto)

Currently translated at 86.4% (1098 of 1270 strings)

Translation: Riot Web/matrix-react-sdk
Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eo/
---
 src/i18n/strings/eo.json | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json
index 74cd5b255f..ccbf327f59 100644
--- a/src/i18n/strings/eo.json
+++ b/src/i18n/strings/eo.json
@@ -251,7 +251,7 @@
     "Encrypted by a verified device": "Ĉifrita de kontrolita aparato",
     "Encrypted by an unverified device": "Ĉifrita de nekontrolita aparato",
     "Unencrypted message": "Neĉifrita mesaĝo",
-    "Please select the destination room for this message": "Bonvolu elekti celan ĉambron por ĉi tiu mesaĝo",
+    "Please select the destination room for this message": "Bonvolu elekti celan babilejon por tiu mesaĝo",
     "Blacklisted": "Senpova legi ĉifritajn mesaĝojn",
     "Verified": "Kontrolita",
     "Unverified": "Nekontrolita",
@@ -292,19 +292,19 @@
     "and %(count)s others...|other": "kaj %(count)s aliaj…",
     "and %(count)s others...|one": "kaj unu alia…",
     "Invited": "Invititaj",
-    "Filter room members": "Filtri ĉambranojn",
+    "Filter room members": "Filtri babilejanojn",
     "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (potenco je %(powerLevelNumber)s)",
     "Attachment": "Kunsendaĵo",
     "Upload Files": "Alŝuti dosierojn",
     "Are you sure you want to upload the following files?": "Ĉu vi certe volas alŝuti la jenajn dosierojn?",
-    "Encrypted room": "Ĉifrita ĉambro",
-    "Unencrypted room": "Neĉifrita ĉambro",
+    "Encrypted room": "Ĉifrita babilejo",
+    "Unencrypted room": "Neĉifrita babilejo",
     "Hangup": "Fini vokon",
     "Voice call": "Voĉvoko",
     "Video call": "Vidvoko",
     "Upload file": "Alŝuti dosieron",
     "Show Text Formatting Toolbar": "Montri tekstaranĝan breton",
-    "You do not have permission to post to this room": "Mankas al vi permeso afiŝi en la ĉambro",
+    "You do not have permission to post to this room": "Mankas al vi permeso afiŝi en tiu babilejo",
     "Turn Markdown on": "Ŝalti Marksubon",
     "Turn Markdown off": "Malŝalti Marksubon",
     "Hide Text Formatting Toolbar": "Kaŝi tekstaranĝan breton",
@@ -339,7 +339,7 @@
     "Offline": "Eksterreta",
     "Unknown": "Nekonata",
     "Seen by %(userName)s at %(dateTime)s": "Vidita de %(userName)s je %(dateTime)s",
-    "Unnamed room": "Sennoma ĉambro",
+    "Unnamed room": "Sennoma babilejo",
     "World readable": "Legebla de ĉiuj",
     "Guests can join": "Gastoj povas aliĝi",
     "No rooms to show": "Neniuj ĉambroj montreblas",
@@ -347,11 +347,11 @@
     "Save": "Konservi",
     "(~%(count)s results)|other": "(~%(count)s rezultoj)",
     "(~%(count)s results)|one": "(~%(count)s rezulto)",
-    "Join Room": "Aliĝi al ĉambro",
+    "Join Room": "Aliĝi al Babilejo",
     "Upload avatar": "Alŝuti profilbildon",
     "Remove avatar": "Forigi profilbildon",
     "Settings": "Agordoj",
-    "Forget room": "Forgesi ĉambron",
+    "Forget room": "Forgesi babilejon",
     "Search": "Serĉi",
     "Show panel": "Montri panelon",
     "Drop here to favourite": "Demetu tien ĉi por ŝati",
@@ -453,17 +453,17 @@
     "not set": "neagordita",
     "Remote addresses for this room:": "Foraj adresoj de ĉi tiu ĉambro:",
     "Addresses": "Adresoj",
-    "The main address for this room is": "La ĉefadreso por ĉi tiu ĉambro estas",
-    "Local addresses for this room:": "Lokaj adresoj por ĉi tiu ĉambro:",
-    "This room has no local addresses": "Ĉi tiu ĉambro ne havas lokajn adresojn",
+    "The main address for this room is": "La ĉefadreso por ĉi tiu babilejo estas",
+    "Local addresses for this room:": "Lokaj adresoj por ĉi tiu babilejo:",
+    "This room has no local addresses": "Ĉi tiu babilejo ne havas lokajn adresojn",
     "New address (e.g. #foo:%(localDomain)s)": "Nova adreso (ekz-e #io:%(localDomain)s)",
     "Invalid community ID": "Malvalida komunuma identigaĵo",
     "'%(groupId)s' is not a valid community ID": "‹%(groupId)s› ne estas valida komunuma identigaĵo",
     "New community ID (e.g. +foo:%(localDomain)s)": "Nova komunuma identigaĵo (ekz-e +io:%(localDomain)s)",
     "You have <a>enabled</a> URL previews by default.": "Vi <a>ŝaltis</a> implicitajn antaŭrigardojn al retpaĝoj.",
     "You have <a>disabled</a> URL previews by default.": "Vi <a>malŝaltis</a> implicitajn antaŭrigardojn al retpaĝoj.",
-    "URL previews are enabled by default for participants in this room.": "Antaŭrigardoj al retpaĝoj estas implicite ŝaltitaj por ĉambranoj ĉi tie.",
-    "URL previews are disabled by default for participants in this room.": "Antaŭrigardoj al retpaĝoj estas implicite malŝaltitaj por ĉambranoj ĉi tie.",
+    "URL previews are enabled by default for participants in this room.": "Antaŭrigardoj de URL-oj estas implicite ŝaltitaj por anoj de tiu ĉi babilejo.",
+    "URL previews are disabled by default for participants in this room.": "Antaŭrigardoj de URL-oj estas implicite malŝaltitaj por anoj de tiu ĉi babilejo.",
     "URL Previews": "Antaŭrigardoj al retpaĝoj",
     "Error decrypting audio": "Eraro malĉifrante sonon",
     "Error decrypting attachment": "Eraro malĉifrante kunsendaĵon",

From 83ebe3752dce748509f0cc3cbc9075296bcf177c Mon Sep 17 00:00:00 2001
From: hamster <Lup3@xmcode.pl>
Date: Sat, 20 Oct 2018 16:07:20 +0000
Subject: [PATCH 21/47] Translated using Weblate (Polish)

Currently translated at 91.8% (1166 of 1270 strings)

Translation: Riot Web/matrix-react-sdk
Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/pl/
---
 src/i18n/strings/pl.json | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/i18n/strings/pl.json b/src/i18n/strings/pl.json
index ee868b4d0b..977b94c718 100644
--- a/src/i18n/strings/pl.json
+++ b/src/i18n/strings/pl.json
@@ -1178,5 +1178,7 @@
     "Increase performance by only loading room members on first view": "Zwiększ wydajność, ładując tylko członków pokoju w pierwszym widoku",
     "Enable widget screenshots on supported widgets": "Włącz widżety zrzutów ekranów na obsługiwanych widżetach",
     "Show empty room list headings": "Pokaż nagłówki z pustym pokojem",
-    "In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.": "W zaszyfrowanych pokojach, takich jak ten, podgląd adresów URL jest domyślnie wyłączony, aby upewnić się, że serwer (w którym generowane są podglądy) nie może zbierać informacji o linkach widocznych w tym pokoju."
+    "In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.": "W zaszyfrowanych pokojach, takich jak ten, podgląd adresów URL jest domyślnie wyłączony, aby upewnić się, że serwer (w którym generowane są podglądy) nie może zbierać informacji o linkach widocznych w tym pokoju.",
+    "When someone puts a URL in their message, a URL preview can be shown to give more information about that link such as the title, description, and an image from the website.": "Gdy ktoś umieści URL w wiadomości, można wyświetlić podgląd adresu URL, aby podać więcej informacji o tym łączu, takich jak tytuł, opis i obraz ze strony internetowej.",
+    "This event could not be displayed": "Ten event nie może zostać wyświetlony"
 }

From e9a62bff2ebd0398fc313a6aec0c3f8ecf2e2fe7 Mon Sep 17 00:00:00 2001
From: sergio <sergio+it@outerface.net>
Date: Sat, 20 Oct 2018 19:20:01 +0000
Subject: [PATCH 22/47] Translated using Weblate (Russian)

Currently translated at 95.9% (1219 of 1270 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 | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json
index 25e0d0b78d..b711b43447 100644
--- a/src/i18n/strings/ru.json
+++ b/src/i18n/strings/ru.json
@@ -1234,5 +1234,7 @@
     "Put a link back to the old room at the start of the new room so people can see old messages": "Разместим ссылку на старую комнату, чтобы люди могли видеть старые сообщения",
     "Please <a>contact your service administrator</a> to continue using this service.": "Пожалуйста, <a>обратитесь к вашему администратору</a>, чтобы продолжить использовать этот сервис.",
     "Increase performance by only loading room members on first view": "Увеличьте производительность, загрузив только список участников комнаты",
-    "Lazy loading members not supported": "Задержка загрузки элементов не поддерживается"
+    "Lazy loading members not supported": "Задержка загрузки элементов не поддерживается",
+    "Registration Required": "Требуется регистрация",
+    "You need to register to do this. Would you like to register now?": "Необходимо зарегистрироваться. Хотите зарегистрироваться?"
 }

From 4335dfea16875804fdacfd2fc5d25dedc93b27ad Mon Sep 17 00:00:00 2001
From: "J. Ryan Stinnett" <jryans@gmail.com>
Date: Mon, 22 Oct 2018 09:56:55 +0000
Subject: [PATCH 23/47] Translated using Weblate (English (United States))

Currently translated at 65.1% (828 of 1270 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 | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/src/i18n/strings/en_US.json b/src/i18n/strings/en_US.json
index 6f0708f0c2..d8733ab05a 100644
--- a/src/i18n/strings/en_US.json
+++ b/src/i18n/strings/en_US.json
@@ -567,7 +567,7 @@
     "Active call (%(roomName)s)": "Active call (%(roomName)s)",
     "Accept": "Accept",
     "Add": "Add",
-    "Admin Tools": "Admin tools",
+    "Admin Tools": "Admin Tools",
     "Alias (optional)": "Alias (optional)",
     "Can't connect to homeserver - please check your connectivity, ensure your <a>homeserver's SSL certificate</a> is trusted, and that a browser extension is not blocking requests.": "Can't connect to homeserver - please check your connectivity, ensure your <a>homeserver's SSL certificate</a> is trusted, and that a browser extension is not blocking requests.",
     "<a>Click here</a> to join the discussion!": "<a>Click here</a> to join the discussion!",
@@ -828,5 +828,15 @@
     "Collapse panel": "Collapse panel",
     "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!",
     "Checking for an update...": "Checking for an update...",
-    "There are advanced notifications which are not shown here": "There are advanced notifications which are not shown here"
+    "There are advanced notifications which are not shown here": "There are advanced notifications which are not shown here",
+    "The platform you're on": "The platform you're on",
+    "The version of Riot.im": "The version of Riot.im",
+    "Whether or not you're logged in (we don't record your user name)": "Whether or not you're logged in (we don't record your user name)",
+    "Your language of choice": "Your language of choice",
+    "Which officially provided instance you are using, if any": "Which officially provided instance you are using, if any",
+    "Whether or not you're using the Richtext mode of the Rich Text Editor": "Whether or not you're using the Richtext mode of the Rich Text Editor",
+    "Your homeserver's URL": "Your homeserver's URL",
+    "Your identity server's URL": "Your identity server's URL",
+    "e.g. %(exampleValue)s": "e.g. %(exampleValue)s",
+    "Every page you use in the app": "Every page you use in the app"
 }

From 60b1b30c5194105bcfd78744990266b431077c72 Mon Sep 17 00:00:00 2001
From: Victor Grousset <victor@tuxayo.net>
Date: Mon, 22 Oct 2018 16:58:20 +0000
Subject: [PATCH 24/47] Translated using Weblate (Esperanto)

Currently translated at 86.4% (1098 of 1270 strings)

Translation: Riot Web/matrix-react-sdk
Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eo/
---
 src/i18n/strings/eo.json | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json
index ccbf327f59..6835ca355c 100644
--- a/src/i18n/strings/eo.json
+++ b/src/i18n/strings/eo.json
@@ -360,7 +360,7 @@
     "Drop here to demote": "Demeti tien ĉi por malpligravigi",
     "Drop here to tag %(section)s": "Demeti tien ĉi por marki %(section)s",
     "Press <StartChatButton> to start a chat with someone": "Premu <StartChatButton> por komenci babilon kun iu",
-    "You're not in any rooms yet! Press <CreateRoomButton> to make a room or <RoomDirectoryButton> to browse the directory": "Vi ankoraŭ estas en neniu ĉambro! Premu <CreateRoomButton> por krei ĉambron aŭ <RoomDirectoryButton> por esplori la ĉambrujon",
+    "You're not in any rooms yet! Press <CreateRoomButton> to make a room or <RoomDirectoryButton> to browse the directory": "Vi ankoraŭ estas en neniuj Babilejoj! Premu <CreateRoomButton> por krei Babilejon aŭ <RoomDirectoryButton> por esplori la Babilejujon",
     "Community Invites": "Komunumaj invitoj",
     "Invites": "Invitoj",
     "Favourites": "Ŝatataj",
@@ -371,7 +371,7 @@
     "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Ne certigeblas, ke la adreso, kien ĉi tiu invito sendiĝis, kongruas kun tiu rilata al via konto.",
     "This invitation was sent to an email address which is not associated with this account:": "Ĉi tiu invito sendiĝis al retpoŝtadreso, kiu ne rilatas al ĉi tiu konto:",
     "You may wish to login with a different account, or add this email to this account.": "Vi povas saluti per alia konto, aŭ aldoni ĉi tiun retpoŝtadreson al tiu ĉi konto.",
-    "You have been invited to join this room by %(inviterName)s": "%(inviterName)s vin invitis al ĉi tiu ĉambro",
+    "You have been invited to join this room by %(inviterName)s": "%(inviterName)s vin invitis al ĉi tiu babilejo",
     "Would you like to <acceptText>accept</acceptText> or <declineText>decline</declineText> this invitation?": "Ĉu vi volas <acceptText>akcepti</acceptText> aŭ <declineText>rifuzi</declineText> ĉi tiun inviton?",
     "Reason: %(reasonText)s": "Kialo: %(reasonText)s",
     "Rejoin": "Realiĝi",

From 2b9a646760da91163eb22a2875f6e55453ac2e0f Mon Sep 17 00:00:00 2001
From: Szimszon <github@oregpreshaz.eu>
Date: Wed, 17 Oct 2018 17:50:11 +0000
Subject: [PATCH 25/47] Translated using Weblate (Hungarian)

Currently translated at 100.0% (1271 of 1271 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 | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json
index 8ce023f377..05dc1d479c 100644
--- a/src/i18n/strings/hu.json
+++ b/src/i18n/strings/hu.json
@@ -1294,5 +1294,6 @@
     "Clear cache and resync": "Gyorsítótár törlése és újraszinkronizálás",
     "Please accept all of the policies": "Kérlek fogadd el a felhasználói feltételeket",
     "Please review and accept the policies of this homeserver:": "Kérlek nézd át és fogadd el a Matrix szerver felhasználói feltételeit:",
-    "Add some now": "Adj hozzá párat"
+    "Add some now": "Adj hozzá párat",
+    "Joining room...": "Belépés a szobába.."
 }

From 78f527cf950a9c8ec6b27fc09b3e5b9f7e208a74 Mon Sep 17 00:00:00 2001
From: Travis Ralston <travpc@gmail.com>
Date: Mon, 22 Oct 2018 15:14:21 -0600
Subject: [PATCH 26/47] Remove unused classes

---
 src/components/views/groups/GroupMemberList.js | 2 +-
 src/components/views/rooms/MemberList.js       | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/components/views/groups/GroupMemberList.js b/src/components/views/groups/GroupMemberList.js
index faf172083f..38c679a5b5 100644
--- a/src/components/views/groups/GroupMemberList.js
+++ b/src/components/views/groups/GroupMemberList.js
@@ -165,7 +165,7 @@ export default React.createClass({
         return (
             <div className="mx_MemberList">
                 { inputBox }
-                <GeminiScrollbarWrapper autoshow={true} className="mx_MemberList_outerWrapper">
+                <GeminiScrollbarWrapper autoshow={true}>
                     { joined }
                     { invited }
                 </GeminiScrollbarWrapper>
diff --git a/src/components/views/rooms/MemberList.js b/src/components/views/rooms/MemberList.js
index 67a6effc81..41434cc6f9 100644
--- a/src/components/views/rooms/MemberList.js
+++ b/src/components/views/rooms/MemberList.js
@@ -447,7 +447,7 @@ module.exports = React.createClass({
         return (
             <div className="mx_MemberList">
                 { inputBox }
-                <GeminiScrollbarWrapper autoshow={true} className="mx_MemberList_joined mx_MemberList_outerWrapper">
+                <GeminiScrollbarWrapper autoshow={true} className="mx_MemberList_joined">
                     <TruncatedList className="mx_MemberList_wrapper" truncateAt={this.state.truncateAtJoined}
                             createOverflowElement={this._createOverflowTileJoined}
                             getChildren={this._getChildrenJoined}

From 41bd6e436608cdbffbe90508c615d8cffd2d16cb Mon Sep 17 00:00:00 2001
From: Aaron Raimist <aaron@raim.ist>
Date: Mon, 22 Oct 2018 20:55:21 -0500
Subject: [PATCH 27/47] Change leave room button text, OK -> Leave

Signed-off-by: Aaron Raimist <aaron@raim.ist>
---
 src/components/structures/MatrixChat.js | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js
index f385aacd40..b725e5f9ab 100644
--- a/src/components/structures/MatrixChat.js
+++ b/src/components/structures/MatrixChat.js
@@ -1034,6 +1034,7 @@ export default React.createClass({
                 { warnings }
                 </span>
             ),
+            button: _t("Leave"),
             onFinished: (shouldLeave) => {
                 if (shouldLeave) {
                     const d = MatrixClientPeg.get().leave(roomId);

From 6774fd7acc12aa1472f0ba1775f9bd9f1c0b2112 Mon Sep 17 00:00:00 2001
From: FeiYang <feiyang@fyol.xyz>
Date: Sat, 20 Oct 2018 09:54:35 +0000
Subject: [PATCH 28/47] Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (1271 of 1271 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 | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json
index ad14a6a94c..ba23947fc2 100644
--- a/src/i18n/strings/zh_Hant.json
+++ b/src/i18n/strings/zh_Hant.json
@@ -1292,5 +1292,6 @@
     "Clear cache and resync": "清除快取並重新同步",
     "Please accept all of the policies": "請接受所有政策",
     "Please review and accept the policies of this homeserver:": "請審閱並接受此家伺服器的政策:",
-    "Add some now": "現在就新增一些"
+    "Add some now": "現在就新增一些",
+    "Joining room...": "正在加入聊天室……"
 }

From 4b3c86595949b49ba278938ad18e038e2178d3ec Mon Sep 17 00:00:00 2001
From: Aaron Raimist <aaron@raim.ist>
Date: Mon, 22 Oct 2018 23:07:41 -0500
Subject: [PATCH 29/47] lint: make colorScheme camel case

Signed-off-by: Aaron Raimist <aaron@raim.ist>
---
 src/components/structures/MatrixChat.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js
index f385aacd40..dce1ac698d 100644
--- a/src/components/structures/MatrixChat.js
+++ b/src/components/structures/MatrixChat.js
@@ -1406,8 +1406,8 @@ export default React.createClass({
 
         // Fire the tinter right on startup to ensure the default theme is applied
         // A later sync can/will correct the tint to be the right value for the user
-        const color_scheme = SettingsStore.getValue("roomColor");
-        Tinter.tint(color_scheme.primary_color, color_scheme.secondary_color);
+        const colorScheme = SettingsStore.getValue("roomColor");
+        Tinter.tint(colorScheme.primary_color, colorScheme.secondary_color);
     },
 
     /**

From cb033bcaddb08e649b2f3de804c992e7dca6ca2f Mon Sep 17 00:00:00 2001
From: Aaron Raimist <aaron@raim.ist>
Date: Mon, 22 Oct 2018 23:15:28 -0500
Subject: [PATCH 30/47] Why not change it everywhere while we're at it

Signed-off-by: Aaron Raimist <aaron@raim.ist>
---
 src/components/structures/RoomView.js               | 10 +++++-----
 src/settings/handlers/RoomAccountSettingsHandler.js |  4 ++--
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js
index 54f51c7a71..5bf6146525 100644
--- a/src/components/structures/RoomView.js
+++ b/src/components/structures/RoomView.js
@@ -678,8 +678,8 @@ module.exports = React.createClass({
         if (!room) return;
 
         console.log("Tinter.tint from updateTint");
-        const color_scheme = SettingsStore.getValue("roomColor", room.roomId);
-        Tinter.tint(color_scheme.primary_color, color_scheme.secondary_color);
+        const colorScheme = SettingsStore.getValue("roomColor", room.roomId);
+        Tinter.tint(colorScheme.primary_color, colorScheme.secondary_color);
     },
 
     onAccountData: function(event) {
@@ -693,11 +693,11 @@ module.exports = React.createClass({
     onRoomAccountData: function(event, room) {
         if (room.roomId == this.state.roomId) {
             const type = event.getType();
-            if (type === "org.matrix.room.color_scheme") {
-                const color_scheme = event.getContent();
+            if (type === "org.matrix.room.colorScheme") {
+                const colorScheme = event.getContent();
                 // XXX: we should validate the event
                 console.log("Tinter.tint from onRoomAccountData");
-                Tinter.tint(color_scheme.primary_color, color_scheme.secondary_color);
+                Tinter.tint(colorScheme.primary_color, colorScheme.secondary_color);
             } else if (type === "org.matrix.room.preview_urls" || type === "im.vector.web.settings") {
                 // non-e2ee url previews are stored in legacy event type `org.matrix.room.preview_urls`
                 this._updatePreviewUrlVisibility(room);
diff --git a/src/settings/handlers/RoomAccountSettingsHandler.js b/src/settings/handlers/RoomAccountSettingsHandler.js
index d0dadc2de7..ae8fb79297 100644
--- a/src/settings/handlers/RoomAccountSettingsHandler.js
+++ b/src/settings/handlers/RoomAccountSettingsHandler.js
@@ -36,7 +36,7 @@ export default class RoomAccountSettingsHandler extends SettingsHandler {
             // The event content should already be in an appropriate format, we just need
             // to get the right value.
             // don't fallback to {} because thats truthy and would imply there is an event specifying tint
-            return this._getSettings(roomId, "org.matrix.room.color_scheme");
+            return this._getSettings(roomId, "org.matrix.room.colorScheme");
         }
 
         const settings = this._getSettings(roomId) || {};
@@ -54,7 +54,7 @@ export default class RoomAccountSettingsHandler extends SettingsHandler {
         // Special case room color
         if (settingName === "roomColor") {
             // The new value should match our requirements, we just need to store it in the right place.
-            return MatrixClientPeg.get().setRoomAccountData(roomId, "org.matrix.room.color_scheme", newValue);
+            return MatrixClientPeg.get().setRoomAccountData(roomId, "org.matrix.room.colorScheme", newValue);
         }
 
         const content = this._getSettings(roomId) || {};

From 1aa308595859469cd592a7166c1ac1c37f23c059 Mon Sep 17 00:00:00 2001
From: Aaron Raimist <aaron@raim.ist>
Date: Mon, 22 Oct 2018 23:33:33 -0500
Subject: [PATCH 31/47] Oh right, can't change these

Signed-off-by: Aaron Raimist <aaron@raim.ist>
---
 src/components/structures/RoomView.js               | 2 +-
 src/settings/handlers/RoomAccountSettingsHandler.js | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js
index 5bf6146525..e20ac54006 100644
--- a/src/components/structures/RoomView.js
+++ b/src/components/structures/RoomView.js
@@ -693,7 +693,7 @@ module.exports = React.createClass({
     onRoomAccountData: function(event, room) {
         if (room.roomId == this.state.roomId) {
             const type = event.getType();
-            if (type === "org.matrix.room.colorScheme") {
+            if (type === "org.matrix.room.color_scheme") {
                 const colorScheme = event.getContent();
                 // XXX: we should validate the event
                 console.log("Tinter.tint from onRoomAccountData");
diff --git a/src/settings/handlers/RoomAccountSettingsHandler.js b/src/settings/handlers/RoomAccountSettingsHandler.js
index ae8fb79297..d0dadc2de7 100644
--- a/src/settings/handlers/RoomAccountSettingsHandler.js
+++ b/src/settings/handlers/RoomAccountSettingsHandler.js
@@ -36,7 +36,7 @@ export default class RoomAccountSettingsHandler extends SettingsHandler {
             // The event content should already be in an appropriate format, we just need
             // to get the right value.
             // don't fallback to {} because thats truthy and would imply there is an event specifying tint
-            return this._getSettings(roomId, "org.matrix.room.colorScheme");
+            return this._getSettings(roomId, "org.matrix.room.color_scheme");
         }
 
         const settings = this._getSettings(roomId) || {};
@@ -54,7 +54,7 @@ export default class RoomAccountSettingsHandler extends SettingsHandler {
         // Special case room color
         if (settingName === "roomColor") {
             // The new value should match our requirements, we just need to store it in the right place.
-            return MatrixClientPeg.get().setRoomAccountData(roomId, "org.matrix.room.colorScheme", newValue);
+            return MatrixClientPeg.get().setRoomAccountData(roomId, "org.matrix.room.color_scheme", newValue);
         }
 
         const content = this._getSettings(roomId) || {};

From 690405d3f6fa545033f8840c68ee48584ca7ecc2 Mon Sep 17 00:00:00 2001
From: RainSlide <RainSlide@outlook.com>
Date: Tue, 23 Oct 2018 05:12:50 +0000
Subject: [PATCH 32/47] Translated using Weblate (Chinese (Simplified))

Currently translated at 98.7% (1255 of 1271 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 | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json
index cd8ae2f0e3..90c162e39b 100644
--- a/src/i18n/strings/zh_Hans.json
+++ b/src/i18n/strings/zh_Hans.json
@@ -17,7 +17,7 @@
     "Disinvite": "取消邀请",
     "Display name": "昵称",
     "Displays action": "显示操作",
-    "Don't send typing notifications": "不要发送我的打字状态",
+    "Don't send typing notifications": "不要发送“正在输入”提示",
     "Download %(text)s": "下载 %(text)s",
     "Email": "电子邮箱",
     "Email address": "邮箱地址",
@@ -488,7 +488,7 @@
     "This room is not recognised.": "无法识别此聊天室。",
     "To get started, please pick a username!": "请点击用户名!",
     "Unable to add email address": "无法添加邮箱地址",
-    "Automatically replace plain text Emoji": "文字、表情自动转换",
+    "Automatically replace plain text Emoji": "将符号表情转换为 Emoji",
     "To reset your password, enter the email address linked to your account": "要重置你的密码,请输入关联你的帐号的邮箱地址",
     "Unable to verify email address.": "无法验证邮箱地址。",
     "Unknown room %(roomId)s": "未知聊天室 %(roomId)s",
@@ -1210,7 +1210,7 @@
     "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "这些聊天室对社区成员可见。社区成员可通过点击来加入它们。",
     "Your community hasn't got a Long Description, a HTML page to show to community members.<br />Click here to open settings and give it one!": "您的社区还没有详细介绍,一个展示给社区成员的 HTML 页面。<br>点击这里即可打开设置添加详细介绍!",
     "Failed to load %(groupId)s": "%(groupId)s 加载失败",
-    "This room is not public. You will not be able to rejoin without an invite.": "此聊天室不是公开的。没有邀请的话,您将无法重新加入。",
+    "This room is not public. You will not be able to rejoin without an invite.": "此聊天室不是公开聊天室。如果没有成员邀请,您将无法重新加入。",
     "Can't leave Server Notices room": "无法退出服务器公告聊天室",
     "This room is used for important messages from the Homeserver, so you cannot leave it.": "此聊天室是用于发布来自主服务器的重要讯息的,所以您不能退出它。",
     "Terms and Conditions": "条款与要求",

From a6c78ace4fbb2e64ca7935c19edf189517e3042e Mon Sep 17 00:00:00 2001
From: Aaron Raimist <aaron@raim.ist>
Date: Tue, 23 Oct 2018 12:25:08 -0500
Subject: [PATCH 33/47] Add warning when administrator leaves community

Signed-off-by: Aaron Raimist <aaron@raim.ist>
---
 src/components/structures/GroupView.js | 28 ++++++++-
 src/i18n/strings/en_EN.json            | 85 +++++++++++++-------------
 2 files changed, 68 insertions(+), 45 deletions(-)

diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js
index d104019a01..ddd3cb87bb 100644
--- a/src/components/structures/GroupView.js
+++ b/src/components/structures/GroupView.js
@@ -746,13 +746,37 @@ export default React.createClass({
         });
     },
 
+    _leaveGroupWarnings: function() {
+        const warnings = [];
+
+        if (this.state.isUserPrivileged) {
+            warnings.push((
+                <span className="warning">
+                    { " " /* Whitespace, otherwise the sentences get smashed together */ }
+                    { _t("You are an administrator of this community") + ". " }
+                    { _t("You will not be able to rejoin without an invite from another administrator.") }
+                </span>
+            ));
+        }
+
+        return warnings;
+    },
+
+
     _onLeaveClick: function() {
         const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
+        const warnings = this._leaveGroupWarnings();
+
         Modal.createTrackedDialog('Leave Group', '', QuestionDialog, {
             title: _t("Leave Community"),
-            description: _t("Leave %(groupName)s?", {groupName: this.props.groupId}),
+            description: (
+                <span>
+                { _t("Leave %(groupName)s?", {groupName: this.props.groupId}) }
+                { warnings }
+                </span>
+            ),
             button: _t("Leave"),
-            danger: true,
+            danger: this.state.isUserPrivileged,
             onFinished: async (confirmed) => {
                 if (!confirmed) return;
 
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index e0f4663532..364aaeac9a 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -43,10 +43,6 @@
     "The file '%(fileName)s' failed to upload": "The file '%(fileName)s' failed to upload",
     "The file '%(fileName)s' exceeds this home server's size limit for uploads": "The file '%(fileName)s' exceeds this home server's size limit for uploads",
     "Upload Failed": "Upload Failed",
-    "Failure to create room": "Failure to create room",
-    "Server may be unavailable, overloaded, or you hit a bug.": "Server may be unavailable, overloaded, or you hit a bug.",
-    "Send anyway": "Send anyway",
-    "Send": "Send",
     "Sun": "Sun",
     "Mon": "Mon",
     "Tue": "Tue",
@@ -86,7 +82,6 @@
     "Failed to invite users to community": "Failed to invite users to community",
     "Failed to invite users to %(groupId)s": "Failed to invite users to %(groupId)s",
     "Failed to add the following rooms to %(groupId)s:": "Failed to add the following rooms to %(groupId)s:",
-    "Unnamed Room": "Unnamed Room",
     "Riot does not have permission to send you notifications - please check your browser settings": "Riot does not have permission to send you notifications - please check your browser settings",
     "Riot was not given permission to send notifications - please try again": "Riot was not given permission to send notifications - please try again",
     "Unable to enable Notifications": "Unable to enable Notifications",
@@ -211,6 +206,11 @@
     "%(names)s and %(count)s others are typing|other": "%(names)s and %(count)s others are typing",
     "%(names)s and %(count)s others are typing|one": "%(names)s and one other is typing",
     "%(names)s and %(lastPerson)s are typing": "%(names)s and %(lastPerson)s are typing",
+    "Failure to create room": "Failure to create room",
+    "Server may be unavailable, overloaded, or you hit a bug.": "Server may be unavailable, overloaded, or you hit a bug.",
+    "Send anyway": "Send anyway",
+    "Send": "Send",
+    "Unnamed Room": "Unnamed Room",
     "This homeserver has hit its Monthly Active User limit.": "This homeserver has hit its Monthly Active User limit.",
     "This homeserver has exceeded one of its resource limits.": "This homeserver has exceeded one of its resource limits.",
     "Please <a>contact your service administrator</a> to continue using the service.": "Please <a>contact your service administrator</a> to continue using the service.",
@@ -331,31 +331,6 @@
     "Off": "Off",
     "On": "On",
     "Noisy": "Noisy",
-    "Invalid alias format": "Invalid alias format",
-    "'%(alias)s' is not a valid format for an alias": "'%(alias)s' is not a valid format for an alias",
-    "Invalid address format": "Invalid address format",
-    "'%(alias)s' is not a valid format for an address": "'%(alias)s' is not a valid format for an address",
-    "not specified": "not specified",
-    "not set": "not set",
-    "Remote addresses for this room:": "Remote addresses for this room:",
-    "Addresses": "Addresses",
-    "The main address for this room is": "The main address for this room is",
-    "Local addresses for this room:": "Local addresses for this room:",
-    "This room has no local addresses": "This room has no local addresses",
-    "New address (e.g. #foo:%(localDomain)s)": "New address (e.g. #foo:%(localDomain)s)",
-    "Invalid community ID": "Invalid community ID",
-    "'%(groupId)s' is not a valid community ID": "'%(groupId)s' is not a valid community ID",
-    "Flair": "Flair",
-    "Showing flair for these communities:": "Showing flair for these communities:",
-    "This room is not showing flair for any communities": "This room is not showing flair for any communities",
-    "New community ID (e.g. +foo:%(localDomain)s)": "New community ID (e.g. +foo:%(localDomain)s)",
-    "You have <a>enabled</a> URL previews by default.": "You have <a>enabled</a> URL previews by default.",
-    "You have <a>disabled</a> URL previews by default.": "You have <a>disabled</a> URL previews by default.",
-    "URL previews are enabled by default for participants in this room.": "URL previews are enabled by default for participants in this room.",
-    "URL previews are disabled by default for participants in this room.": "URL previews are disabled by default for participants in this room.",
-    "In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.": "In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.",
-    "URL Previews": "URL Previews",
-    "When someone puts a URL in their message, a URL preview can be shown to give more information about that link such as the title, description, and an image from the website.": "When someone puts a URL in their message, a URL preview can be shown to give more information about that link such as the title, description, and an image from the website.",
     "Cannot add any more widgets": "Cannot add any more widgets",
     "The maximum permitted number of widgets have already been added to this room.": "The maximum permitted number of widgets have already been added to this room.",
     "Add a widget": "Add a widget",
@@ -419,6 +394,7 @@
     "Make Moderator": "Make Moderator",
     "Admin Tools": "Admin Tools",
     "Level:": "Level:",
+    "Close": "Close",
     "and %(count)s others...|other": "and %(count)s others...",
     "and %(count)s others...|one": "and one other...",
     "Invited": "Invited",
@@ -460,11 +436,11 @@
     "At this time it is not possible to reply with an emote.": "At this time it is not possible to reply with an emote.",
     "Markdown is disabled": "Markdown is disabled",
     "Markdown is enabled": "Markdown is enabled",
+    "Unpin Message": "Unpin Message",
+    "Jump to message": "Jump to message",
     "No pinned messages.": "No pinned messages.",
     "Loading...": "Loading...",
     "Pinned Messages": "Pinned Messages",
-    "Unpin Message": "Unpin Message",
-    "Jump to message": "Jump to message",
     "%(duration)ss": "%(duration)ss",
     "%(duration)sm": "%(duration)sm",
     "%(duration)sh": "%(duration)sh",
@@ -599,13 +575,37 @@
     "All Rooms": "All Rooms",
     "Cancel": "Cancel",
     "You don't currently have any stickerpacks enabled": "You don't currently have any stickerpacks enabled",
-    "Add a stickerpack": "Add a stickerpack",
+    "Add some now": "Add some now",
     "Stickerpack": "Stickerpack",
     "Hide Stickers": "Hide Stickers",
     "Show Stickers": "Show Stickers",
     "Scroll to unread messages": "Scroll to unread messages",
     "Jump to first unread message.": "Jump to first unread message.",
-    "Close": "Close",
+    "Invalid alias format": "Invalid alias format",
+    "'%(alias)s' is not a valid format for an alias": "'%(alias)s' is not a valid format for an alias",
+    "Invalid address format": "Invalid address format",
+    "'%(alias)s' is not a valid format for an address": "'%(alias)s' is not a valid format for an address",
+    "not specified": "not specified",
+    "not set": "not set",
+    "Remote addresses for this room:": "Remote addresses for this room:",
+    "Addresses": "Addresses",
+    "The main address for this room is": "The main address for this room is",
+    "Local addresses for this room:": "Local addresses for this room:",
+    "This room has no local addresses": "This room has no local addresses",
+    "New address (e.g. #foo:%(localDomain)s)": "New address (e.g. #foo:%(localDomain)s)",
+    "Invalid community ID": "Invalid community ID",
+    "'%(groupId)s' is not a valid community ID": "'%(groupId)s' is not a valid community ID",
+    "Flair": "Flair",
+    "Showing flair for these communities:": "Showing flair for these communities:",
+    "This room is not showing flair for any communities": "This room is not showing flair for any communities",
+    "New community ID (e.g. +foo:%(localDomain)s)": "New community ID (e.g. +foo:%(localDomain)s)",
+    "You have <a>enabled</a> URL previews by default.": "You have <a>enabled</a> URL previews by default.",
+    "You have <a>disabled</a> URL previews by default.": "You have <a>disabled</a> URL previews by default.",
+    "URL previews are enabled by default for participants in this room.": "URL previews are enabled by default for participants in this room.",
+    "URL previews are disabled by default for participants in this room.": "URL previews are disabled by default for participants in this room.",
+    "In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.": "In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.",
+    "URL Previews": "URL Previews",
+    "When someone puts a URL in their message, a URL preview can be shown to give more information about that link such as the title, description, and an image from the website.": "When someone puts a URL in their message, a URL preview can be shown to give more information about that link such as the title, description, and an image from the website.",
     "Sunday": "Sunday",
     "Monday": "Monday",
     "Tuesday": "Tuesday",
@@ -644,7 +644,6 @@
     "Dismiss": "Dismiss",
     "To continue, please enter your password.": "To continue, please enter your password.",
     "Password:": "Password:",
-    "Please accept all of the policies": "Please accept all of the policies",
     "Please review and accept the policies of this homeserver:": "Please review and accept the policies of this homeserver:",
     "An email has been sent to %(emailAddress)s": "An email has been sent to %(emailAddress)s",
     "Please check your email to continue registration.": "Please check your email to continue registration.",
@@ -887,6 +886,10 @@
     "Ignore request": "Ignore request",
     "Loading device info...": "Loading device info...",
     "Encryption key request": "Encryption key request",
+    "You've previously used Riot on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, Riot needs to resync your account.": "You've previously used Riot on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, Riot needs to resync your account.",
+    "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.",
+    "Incompatible local cache": "Incompatible local cache",
+    "Clear cache and resync": "Clear cache and resync",
     "Riot now uses 3-5x less memory, by only loading information about other users when needed. Please wait whilst we resynchronise with the server!": "Riot now uses 3-5x less memory, by only loading information about other users when needed. Please wait whilst we resynchronise with the server!",
     "Updating Riot": "Updating Riot",
     "Failed to upgrade room": "Failed to upgrade room",
@@ -987,7 +990,7 @@
     "You must <a>register</a> to use this functionality": "You must <a>register</a> to use this functionality",
     "You must join the room to see its files": "You must join the room to see its files",
     "There are no visible files in this room": "There are no visible files in this room",
-    "<h1>HTML for your community's page</h1>\r\n<p>\r\n    Use the long description to introduce new members to the community, or distribute\r\n    some important <a href=\"foo\">links</a>\r\n</p>\r\n<p>\r\n    You can even use 'img' tags\r\n</p>\r\n": "<h1>HTML for your community's page</h1>\r\n<p>\r\n    Use the long description to introduce new members to the community, or distribute\r\n    some important <a href=\"foo\">links</a>\r\n</p>\r\n<p>\r\n    You can even use 'img' tags\r\n</p>\r\n",
+    "<h1>HTML for your community's page</h1>\n<p>\n    Use the long description to introduce new members to the community, or distribute\n    some important <a href=\"foo\">links</a>\n</p>\n<p>\n    You can even use 'img' tags\n</p>\n": "<h1>HTML for your community's page</h1>\n<p>\n    Use the long description to introduce new members to the community, or distribute\n    some important <a href=\"foo\">links</a>\n</p>\n<p>\n    You can even use 'img' tags\n</p>\n",
     "Add rooms to the community summary": "Add rooms to the community summary",
     "Which rooms would you like to add to this summary?": "Which rooms would you like to add to this summary?",
     "Add to summary": "Add to summary",
@@ -1005,6 +1008,8 @@
     "Failed to update community": "Failed to update community",
     "Unable to accept invite": "Unable to accept invite",
     "Unable to join community": "Unable to join community",
+    "You are an administrator of this community": "You are an administrator of this community",
+    "You will not be able to rejoin without an invite from another administrator.": "You will not be able to rejoin without an invite from another administrator.",
     "Leave Community": "Leave Community",
     "Leave %(groupName)s?": "Leave %(groupName)s?",
     "Unable to leave community": "Unable to leave community",
@@ -1017,7 +1022,6 @@
     "%(inviter)s has invited you to join this community": "%(inviter)s has invited you to join this community",
     "Join this community": "Join this community",
     "Leave this community": "Leave this community",
-    "You are an administrator of this community": "You are an administrator of this community",
     "You are a member of this community": "You are a member of this community",
     "Who can join this community?": "Who can join this community?",
     "Everyone": "Everyone",
@@ -1264,10 +1268,5 @@
     "Import": "Import",
     "Failed to set direct chat tag": "Failed to set direct chat tag",
     "Failed to remove tag %(tagName)s from room": "Failed to remove tag %(tagName)s from room",
-    "Failed to add tag %(tagName)s to room": "Failed to add tag %(tagName)s to room",
-    "You've previously used Riot on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, Riot needs to resync your account.": "You've previously used Riot on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, Riot needs to resync your account.",
-    "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.",
-    "Incompatible local cache": "Incompatible local cache",
-    "Clear cache and resync": "Clear cache and resync",
-    "Add some now": "Add some now"
+    "Failed to add tag %(tagName)s to room": "Failed to add tag %(tagName)s to room"
 }

From 92bfb42784393b0e83dc52740fbe2cb4248f7b26 Mon Sep 17 00:00:00 2001
From: Aaron Raimist <aaron@raim.ist>
Date: Tue, 23 Oct 2018 13:11:34 -0500
Subject: [PATCH 34/47] Use one string instead of two

Signed-off-by: Aaron Raimist <aaron@raim.ist>
---
 src/components/structures/GroupView.js | 5 +++--
 src/i18n/strings/en_EN.json            | 4 ++--
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js
index ddd3cb87bb..8a2b7a23ca 100644
--- a/src/components/structures/GroupView.js
+++ b/src/components/structures/GroupView.js
@@ -753,8 +753,9 @@ export default React.createClass({
             warnings.push((
                 <span className="warning">
                     { " " /* Whitespace, otherwise the sentences get smashed together */ }
-                    { _t("You are an administrator of this community") + ". " }
-                    { _t("You will not be able to rejoin without an invite from another administrator.") }
+                    { /* eslint-disable max-len */ }
+                    { _t("You are an administrator of this community. You will not be able to rejoin without an invite from another administrator.") }
+                    { /* eslint-enable max-len */ }
                 </span>
             ));
         }
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index 364aaeac9a..2885eb68a7 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -1008,8 +1008,7 @@
     "Failed to update community": "Failed to update community",
     "Unable to accept invite": "Unable to accept invite",
     "Unable to join community": "Unable to join community",
-    "You are an administrator of this community": "You are an administrator of this community",
-    "You will not be able to rejoin without an invite from another administrator.": "You will not be able to rejoin without an invite from another administrator.",
+    "You are an administrator of this community. You will not be able to rejoin without an invite from another administrator.": "You are an administrator of this community. You will not be able to rejoin without an invite from another administrator.",
     "Leave Community": "Leave Community",
     "Leave %(groupName)s?": "Leave %(groupName)s?",
     "Unable to leave community": "Unable to leave community",
@@ -1022,6 +1021,7 @@
     "%(inviter)s has invited you to join this community": "%(inviter)s has invited you to join this community",
     "Join this community": "Join this community",
     "Leave this community": "Leave this community",
+    "You are an administrator of this community": "You are an administrator of this community",
     "You are a member of this community": "You are a member of this community",
     "Who can join this community?": "Who can join this community?",
     "Everyone": "Everyone",

From fe901142aa669e329458ec517560e11194d6b1ad Mon Sep 17 00:00:00 2001
From: Aaron Raimist <aaron@raim.ist>
Date: Tue, 23 Oct 2018 17:20:54 -0500
Subject: [PATCH 35/47] Split long string over two lines

Signed-off-by: Aaron Raimist <aaron@raim.ist>
---
 src/components/structures/GroupView.js | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js
index 8a2b7a23ca..5d23194702 100644
--- a/src/components/structures/GroupView.js
+++ b/src/components/structures/GroupView.js
@@ -753,9 +753,8 @@ export default React.createClass({
             warnings.push((
                 <span className="warning">
                     { " " /* Whitespace, otherwise the sentences get smashed together */ }
-                    { /* eslint-disable max-len */ }
-                    { _t("You are an administrator of this community. You will not be able to rejoin without an invite from another administrator.") }
-                    { /* eslint-enable max-len */ }
+                    { _t("You are an administrator of this community. You will not be " +
+                         "able to rejoin without an invite from another administrator.") }
                 </span>
             ));
         }

From ef50e05580d9c2dc09d80d8b095d4e6ddb09d7fe Mon Sep 17 00:00:00 2001
From: Victor Grousset <victor@tuxayo.net>
Date: Tue, 23 Oct 2018 12:26:40 +0000
Subject: [PATCH 36/47] Translated using Weblate (Esperanto)

Currently translated at 86.3% (1098 of 1271 strings)

Translation: Riot Web/matrix-react-sdk
Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eo/
---
 src/i18n/strings/eo.json | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json
index 6835ca355c..84912dccf9 100644
--- a/src/i18n/strings/eo.json
+++ b/src/i18n/strings/eo.json
@@ -376,14 +376,14 @@
     "Reason: %(reasonText)s": "Kialo: %(reasonText)s",
     "Rejoin": "Realiĝi",
     "You have been kicked from %(roomName)s by %(userName)s.": "%(userName)s vin forpelis de %(roomName)s.",
-    "You have been kicked from this room by %(userName)s.": "%(userName)s vin forpelis de tiu ĉi ĉambro.",
+    "You have been kicked from this room by %(userName)s.": "%(userName)s vin forpelis de tiu babilejo.",
     "You have been banned from %(roomName)s by %(userName)s.": "%(userName)s vi forbaris de %(roomName)s.",
-    "You have been banned from this room by %(userName)s.": "%(userName)s vin forbaris de tiu ĉi ĉambro.",
-    "This room": "Ĉi tiu ĉambro",
+    "You have been banned from this room by %(userName)s.": "%(userName)s vin forbaris de tiu babilejo.",
+    "This room": "Ĉi tiu babilejo",
     "%(roomName)s does not exist.": "%(roomName)s ne ekzistas.",
     "%(roomName)s is not accessible at this time.": "%(roomName)s ne estas atingebla nun.",
     "You are trying to access %(roomName)s.": "Vi provas atingi %(roomName)s.",
-    "You are trying to access a room.": "Vi provas atingi ĉambron.",
+    "You are trying to access a room.": "Vi provas aliri babilejon.",
     "<a>Click here</a> to join the discussion!": "<a>Klaku ĉi tie</a> por aliĝi al la diskuto!",
     "This is a preview of this room. Room interactions have been disabled": "Tio ĉi estas antaŭrigardo al la ĉambro. Ĉambraj interagoj estas malŝaltitaj",
     "To change the room's avatar, you must be a": "Por ŝanĝi la ĉambran profilbildon, vi devas esti",
@@ -419,7 +419,7 @@
     "To link to a room it must have <a>an address</a>.": "Por esti ligebla, ĉambro devas havi <a>adreson</a>.",
     "Guests cannot join this room even if explicitly invited.": "Gastoj ne povas aliĝi ĉi tiun ĉambron eĉ kun malimplica invito.",
     "Click here to fix": "Klaku ĉi tie por riparo",
-    "Who can access this room?": "Kiu povas atingi ĉi tiun ĉambron?",
+    "Who can access this room?": "Kiu povas aliri ĉi tiun ĉambron?",
     "Only people who have been invited": "Nur invititaj uzantoj",
     "Anyone who knows the room's link, apart from guests": "Iu ajn kun la ligilo, krom gastoj",
     "Anyone who knows the room's link, including guests": "Iu ajn kun la ligilo, inkluzive gastojn",

From 78d8d22457fd481e4b961e7c65cd5646c1b15557 Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Wed, 24 Oct 2018 16:46:06 +0100
Subject: [PATCH 37/47] Fix emoji replacement in composer

 * Re-scan the slate document tree on each emoji replacement since
   doing a replacement will invalidate all the offsets we have.
 * Reset the emoji regex each time we use it.

Fixes https://github.com/vector-im/riot-web/issues/7550
---
 .../views/rooms/MessageComposerInput.js       | 56 ++++++++++++-------
 1 file changed, 35 insertions(+), 21 deletions(-)

diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js
index 04f9299825..604c797fe4 100644
--- a/src/components/views/rooms/MessageComposerInput.js
+++ b/src/components/views/rooms/MessageComposerInput.js
@@ -573,29 +573,43 @@ export default class MessageComposerInput extends React.Component {
         }
 
         // emojioneify any emoji
-        editorState.document.getTexts().forEach(node => {
-            if (node.text !== '' && HtmlUtils.containsEmoji(node.text)) {
-                let match;
-                while ((match = EMOJI_REGEX.exec(node.text)) !== null) {
-                    const range = Range.create({
-                        anchor: {
-                            key: node.key,
-                            offset: match.index,
-                        },
-                        focus: {
-                            key: node.key,
-                            offset: match.index + match[0].length,
-                        },
-                    });
-                    const inline = Inline.create({
-                        type: 'emoji',
-                        data: { emojiUnicode: match[0] },
-                    });
-                    change = change.insertInlineAtRange(range, inline);
-                    editorState = change.value;
+        while (true) {
+            let foundEmoji = false;
+
+            for (const node of editorState.document.getTexts()) {
+                if (node.text !== '' && HtmlUtils.containsEmoji(node.text)) {
+                    let match;
+                    EMOJI_REGEX.lastIndex = 0;
+                    while ((match = EMOJI_REGEX.exec(node.text)) !== null) {
+                        const range = Range.create({
+                            anchor: {
+                                key: node.key,
+                                offset: match.index,
+                            },
+                            focus: {
+                                key: node.key,
+                                offset: match.index + match[0].length,
+                            },
+                        });
+                        const inline = Inline.create({
+                            type: 'emoji',
+                            data: { emojiUnicode: match[0] },
+                        });
+                        change = change.insertInlineAtRange(range, inline);
+                        editorState = change.value;
+
+                        // if we replaced an emoji, start again looking for more
+                        // emoji in the new editor state since doing the replacement
+                        // will change the node structure & offsets so we can't compute
+                        // insertion ranges from node.key / match.index anymore.
+                        foundEmoji = true;
+                        break;
+                    }
                 }
             }
-        });
+
+            if (!foundEmoji) break;
+        }
 
         // work around weird bug where inserting emoji via the macOS
         // emoji picker can leave the selection stuck in the emoji's

From 79d467c551c1ebaf60abed2375f9b29be0563046 Mon Sep 17 00:00:00 2001
From: Will Hunt <will@half-shot.uk>
Date: Wed, 24 Oct 2018 17:36:58 +0100
Subject: [PATCH 38/47] Add button to open devtools in roomsettings

---
 src/components/views/rooms/RoomSettings.js | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js
index 46869c1773..23c2dbc93d 100644
--- a/src/components/views/rooms/RoomSettings.js
+++ b/src/components/views/rooms/RoomSettings.js
@@ -590,6 +590,11 @@ module.exports = React.createClass({
         }
     },
 
+    _openDevtools: function() {
+        const DevtoolsDialog = sdk.getComponent('dialogs.DevtoolsDialog');
+        Modal.createDialog(DevtoolsDialog, {roomId: this.props.room.roomId});
+    },
+
     _renderEncryptionSection: function() {
         const SettingsFlag = sdk.getComponent("elements.SettingsFlag");
 
@@ -942,6 +947,10 @@ module.exports = React.createClass({
             </AccessibleButton>;
         }
 
+        devtoolsButton = <AccessibleButton onClick={this._openDevtools}>
+            { _t("Open Devtools") }
+        </AccessibleButton>;
+
         return (
             <div className="mx_RoomSettings">
 
@@ -1055,6 +1064,7 @@ module.exports = React.createClass({
                     { _t('Internal room ID: ') } <code>{ this.props.room.roomId }</code><br />
                     { _t('Room version number: ') } <code>{ this.props.room.getVersion() }</code><br />
                     { roomUpgradeButton }
+                    { devtoolsButton }
                 </div>
             </div>
         );

From 06c34cff9c2e7dddca4b69f2826dfbd3b218a3d7 Mon Sep 17 00:00:00 2001
From: Will Hunt <will@half-shot.uk>
Date: Wed, 24 Oct 2018 17:37:13 +0100
Subject: [PATCH 39/47] Add devtools string

---
 src/i18n/strings/en_EN.json | 3 ++-
 src/i18n/strings/en_US.json | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index 2885eb68a7..cbb688f448 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -1268,5 +1268,6 @@
     "Import": "Import",
     "Failed to set direct chat tag": "Failed to set direct chat tag",
     "Failed to remove tag %(tagName)s from room": "Failed to remove tag %(tagName)s from room",
-    "Failed to add tag %(tagName)s to room": "Failed to add tag %(tagName)s to room"
+    "Failed to add tag %(tagName)s to room": "Failed to add tag %(tagName)s to room",
+    "Open Devtools": "Open Devtools",
 }
diff --git a/src/i18n/strings/en_US.json b/src/i18n/strings/en_US.json
index d8733ab05a..9146fdf586 100644
--- a/src/i18n/strings/en_US.json
+++ b/src/i18n/strings/en_US.json
@@ -838,5 +838,6 @@
     "Your homeserver's URL": "Your homeserver's URL",
     "Your identity server's URL": "Your identity server's URL",
     "e.g. %(exampleValue)s": "e.g. %(exampleValue)s",
-    "Every page you use in the app": "Every page you use in the app"
+    "Every page you use in the app": "Every page you use in the app",
+    "Open Devtools": "Open Devtools"
 }

From 44a41b589d55a3cb8cbc7828353ddc75ad3f2a13 Mon Sep 17 00:00:00 2001
From: Will Hunt <will@half-shot.uk>
Date: Wed, 24 Oct 2018 17:50:15 +0100
Subject: [PATCH 40/47] Comma on strings and styling button

---
 res/css/views/rooms/_RoomSettings.scss     | 7 +++++++
 src/components/views/rooms/RoomSettings.js | 2 +-
 src/i18n/strings/en_EN.json                | 2 +-
 3 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/res/css/views/rooms/_RoomSettings.scss b/res/css/views/rooms/_RoomSettings.scss
index f04042ea77..b3858f3ba7 100644
--- a/res/css/views/rooms/_RoomSettings.scss
+++ b/res/css/views/rooms/_RoomSettings.scss
@@ -28,6 +28,13 @@ limitations under the License.
     margin-right: 8px;
 }
 
+.mx_RoomSettings_devtoolsButton {
+    @mixin mx_DialogButton;
+    position: relative;
+    padding: 4px 1.5em;
+    margin-top: 8px;
+}
+
 .mx_RoomSettings_upgradeButton,
 .mx_RoomSettings_leaveButton:hover,
 .mx_RoomSettings_unbanButton:hover {
diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js
index 23c2dbc93d..774d136e45 100644
--- a/src/components/views/rooms/RoomSettings.js
+++ b/src/components/views/rooms/RoomSettings.js
@@ -947,7 +947,7 @@ module.exports = React.createClass({
             </AccessibleButton>;
         }
 
-        devtoolsButton = <AccessibleButton onClick={this._openDevtools}>
+        const devtoolsButton = <AccessibleButton className="mx_RoomSettings_devtoolsButton" onClick={this._openDevtools}>
             { _t("Open Devtools") }
         </AccessibleButton>;
 
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index cbb688f448..45fb0351a7 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -1269,5 +1269,5 @@
     "Failed to set direct chat tag": "Failed to set direct chat tag",
     "Failed to remove tag %(tagName)s from room": "Failed to remove tag %(tagName)s from room",
     "Failed to add tag %(tagName)s to room": "Failed to add tag %(tagName)s to room",
-    "Open Devtools": "Open Devtools",
+    "Open Devtools": "Open Devtools"
 }

From 3c045f3f65f4940889d1a646fafeb85f544173fb Mon Sep 17 00:00:00 2001
From: Will Hunt <will@half-shot.uk>
Date: Wed, 24 Oct 2018 18:02:45 +0100
Subject: [PATCH 41/47] Revert i18n changes for en_US

---
 src/i18n/strings/en_US.json | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/i18n/strings/en_US.json b/src/i18n/strings/en_US.json
index 9146fdf586..d8733ab05a 100644
--- a/src/i18n/strings/en_US.json
+++ b/src/i18n/strings/en_US.json
@@ -838,6 +838,5 @@
     "Your homeserver's URL": "Your homeserver's URL",
     "Your identity server's URL": "Your identity server's URL",
     "e.g. %(exampleValue)s": "e.g. %(exampleValue)s",
-    "Every page you use in the app": "Every page you use in the app",
-    "Open Devtools": "Open Devtools"
+    "Every page you use in the app": "Every page you use in the app"
 }

From a5ae599dcb819c0c919af61065d998c652934bb4 Mon Sep 17 00:00:00 2001
From: Will Hunt <will@half-shot.uk>
Date: Wed, 24 Oct 2018 18:15:25 +0100
Subject: [PATCH 42/47] Add show developer tools option

---
 src/settings/Settings.js | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/settings/Settings.js b/src/settings/Settings.js
index 021942c6f2..547c71bac8 100644
--- a/src/settings/Settings.js
+++ b/src/settings/Settings.js
@@ -290,4 +290,9 @@ export const SETTINGS = {
         displayName: _td('Show empty room list headings'),
         default: true,
     },
+    "showDeveloperTools": {
+        supportedLevels: LEVELS_ACCOUNT_SETTINGS,
+        displayName: _td('Show developer tools'),
+        default: false,
+    },
 };

From 8118a9c71a394665a1497e9408d9a2b6d54fb1d5 Mon Sep 17 00:00:00 2001
From: Will Hunt <will@half-shot.uk>
Date: Wed, 24 Oct 2018 18:15:35 +0100
Subject: [PATCH 43/47] Wall devtools button behind a setting

---
 src/components/views/rooms/RoomSettings.js | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js
index 774d136e45..b69938a117 100644
--- a/src/components/views/rooms/RoomSettings.js
+++ b/src/components/views/rooms/RoomSettings.js
@@ -947,9 +947,10 @@ module.exports = React.createClass({
             </AccessibleButton>;
         }
 
-        const devtoolsButton = <AccessibleButton className="mx_RoomSettings_devtoolsButton" onClick={this._openDevtools}>
+        const devtoolsButton = SettingsStore.getValue("showDeveloperTools") ?
+        (<AccessibleButton className="mx_RoomSettings_devtoolsButton" onClick={this._openDevtools}>
             { _t("Open Devtools") }
-        </AccessibleButton>;
+        </AccessibleButton>) : null;
 
         return (
             <div className="mx_RoomSettings">

From 27a0f0ca62ab93b2390556003406fdc9f98434e0 Mon Sep 17 00:00:00 2001
From: Will Hunt <will@half-shot.uk>
Date: Wed, 24 Oct 2018 18:16:55 +0100
Subject: [PATCH 44/47] Add i18n string

---
 src/i18n/strings/en_EN.json | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index 45fb0351a7..8e1f75f25c 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -1269,5 +1269,6 @@
     "Failed to set direct chat tag": "Failed to set direct chat tag",
     "Failed to remove tag %(tagName)s from room": "Failed to remove tag %(tagName)s from room",
     "Failed to add tag %(tagName)s to room": "Failed to add tag %(tagName)s to room",
-    "Open Devtools": "Open Devtools"
+    "Open Devtools": "Open Devtools",
+    "Show developer tools": "Show developer tools"
 }

From def0b2d8fb393bfa027b605f04b4ebc819763a92 Mon Sep 17 00:00:00 2001
From: Will Hunt <will@half-shot.uk>
Date: Wed, 24 Oct 2018 18:20:16 +0100
Subject: [PATCH 45/47] Add developertools option to UserSettings

---
 src/components/structures/UserSettings.js | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js
index 129278907f..f32026511b 100644
--- a/src/components/structures/UserSettings.js
+++ b/src/components/structures/UserSettings.js
@@ -82,6 +82,7 @@ const SIMPLE_SETTINGS = [
     { id: "TagPanel.disableTagPanel" },
     { id: "enableWidgetScreenshots" },
     { id: "RoomSubList.showEmpty" },
+    { id: "showDeveloperTools" },
 ];
 
 // These settings must be defined in SettingsStore

From 401f6333ed18e0981a0c3fff2936e303d9e1fef3 Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Thu, 25 Oct 2018 14:54:32 +0100
Subject: [PATCH 46/47] Do...while loops are a thing

---
 src/components/views/rooms/MessageComposerInput.js | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js
index 604c797fe4..792dcede8a 100644
--- a/src/components/views/rooms/MessageComposerInput.js
+++ b/src/components/views/rooms/MessageComposerInput.js
@@ -573,7 +573,7 @@ export default class MessageComposerInput extends React.Component {
         }
 
         // emojioneify any emoji
-        while (true) {
+        do {
             let foundEmoji = false;
 
             for (const node of editorState.document.getTexts()) {
@@ -607,9 +607,7 @@ export default class MessageComposerInput extends React.Component {
                     }
                 }
             }
-
-            if (!foundEmoji) break;
-        }
+        } while (foundEmoji);
 
         // work around weird bug where inserting emoji via the macOS
         // emoji picker can leave the selection stuck in the emoji's

From 5e81e5b8b84ff3954bb9b19cffeb80b679cabc44 Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Thu, 25 Oct 2018 15:07:19 +0100
Subject: [PATCH 47/47] Fix variable scope

---
 src/components/views/rooms/MessageComposerInput.js | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js
index 792dcede8a..570cb8a59b 100644
--- a/src/components/views/rooms/MessageComposerInput.js
+++ b/src/components/views/rooms/MessageComposerInput.js
@@ -573,8 +573,9 @@ export default class MessageComposerInput extends React.Component {
         }
 
         // emojioneify any emoji
+        let foundEmoji;
         do {
-            let foundEmoji = false;
+            foundEmoji = false;
 
             for (const node of editorState.document.getTexts()) {
                 if (node.text !== '' && HtmlUtils.containsEmoji(node.text)) {