From a8231f7bf9b8a0d3bdaf7fc1d6ce6ee1d61df4dc Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Thu, 5 Oct 2017 08:26:57 +0100
Subject: [PATCH 1/8] Remove redundant stale onKeyDown

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
---
 src/components/views/dialogs/TextInputDialog.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/views/dialogs/TextInputDialog.js b/src/components/views/dialogs/TextInputDialog.js
index c924da7745..5ea4191e5e 100644
--- a/src/components/views/dialogs/TextInputDialog.js
+++ b/src/components/views/dialogs/TextInputDialog.js
@@ -68,7 +68,7 @@ export default React.createClass({
                         <label htmlFor="textinput"> { this.props.description } </label>
                     </div>
                     <div>
-                        <input id="textinput" ref="textinput" className="mx_TextInputDialog_input" defaultValue={this.props.value} autoFocus={this.props.focus} size="64" onKeyDown={this.onKeyDown} />
+                        <input id="textinput" ref="textinput" className="mx_TextInputDialog_input" defaultValue={this.props.value} autoFocus={this.props.focus} size="64" />
                     </div>
                 </div>
                 <div className="mx_Dialog_buttons">

From 6a4e3792d4aa563c521eadfd1bc858a343894742 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Fri, 6 Oct 2017 12:07:38 +0100
Subject: [PATCH 2/8] split handlers into state and non-states

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
---
 src/TextForEvent.js | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/src/TextForEvent.js b/src/TextForEvent.js
index a21eb5c251..fa8efe028f 100644
--- a/src/TextForEvent.js
+++ b/src/TextForEvent.js
@@ -291,12 +291,15 @@ function textForWidgetEvent(event) {
 
 const handlers = {
     'm.room.message': textForMessageEvent,
-    'm.room.name': textForRoomNameEvent,
-    'm.room.topic': textForTopicEvent,
-    'm.room.member': textForMemberEvent,
     'm.call.invite': textForCallInviteEvent,
     'm.call.answer': textForCallAnswerEvent,
     'm.call.hangup': textForCallHangupEvent,
+};
+
+const stateHandlers = {
+    'm.room.name': textForRoomNameEvent,
+    'm.room.topic': textForTopicEvent,
+    'm.room.member': textForMemberEvent,
     'm.room.third_party_invite': textForThreePidInviteEvent,
     'm.room.history_visibility': textForHistoryVisibilityEvent,
     'm.room.encryption': textForEncryptionEvent,
@@ -307,8 +310,8 @@ const handlers = {
 
 module.exports = {
     textForEvent: function(ev) {
-        const hdlr = handlers[ev.getType()];
-        if (!hdlr) return '';
-        return hdlr(ev);
+        const handler = ev.isState() ? stateHandlers[ev.getType()] : handlers[ev.getType()];
+        if (handler) return handler(ev);
+        return '';
     },
 };

From 91ba939e23eef52634a5618041008cbe30c73e2b Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Fri, 6 Oct 2017 12:10:07 +0100
Subject: [PATCH 3/8] tiny bit of de-lint for consistency

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
---
 src/TextForEvent.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/TextForEvent.js b/src/TextForEvent.js
index fa8efe028f..ccb4c29a9c 100644
--- a/src/TextForEvent.js
+++ b/src/TextForEvent.js
@@ -243,7 +243,7 @@ function textForPowerEvent(event) {
         if (to !== from) {
             diff.push(
                 _t('%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s', {
-                    userId: userId,
+                    userId,
                     fromPowerLevel: Roles.textualPowerLevel(from, userDefault),
                     toPowerLevel: Roles.textualPowerLevel(to, userDefault),
                 }),
@@ -254,7 +254,7 @@ function textForPowerEvent(event) {
         return '';
     }
     return _t('%(senderName)s changed the power level of %(powerLevelDiffText)s.', {
-        senderName: senderName,
+        senderName,
         powerLevelDiffText: diff.join(", "),
     });
 }

From 152499a17d0683a565608a7f019ae99740a29b97 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Fri, 6 Oct 2017 12:16:54 +0100
Subject: [PATCH 4/8] DRY map lookup

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
---
 src/TextForEvent.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/TextForEvent.js b/src/TextForEvent.js
index ccb4c29a9c..6345403f09 100644
--- a/src/TextForEvent.js
+++ b/src/TextForEvent.js
@@ -310,7 +310,7 @@ const stateHandlers = {
 
 module.exports = {
     textForEvent: function(ev) {
-        const handler = ev.isState() ? stateHandlers[ev.getType()] : handlers[ev.getType()];
+        const handler = (ev.isState() ? stateHandlers : handlers)[ev.getType()];
         if (handler) return handler(ev);
         return '';
     },

From 92be3af990ecd96cfa1bbef3bc2cdab3554b819b Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Tue, 10 Oct 2017 19:16:42 +0100
Subject: [PATCH 5/8] Make it clearer which HS you're logging into

Otherwise there's no indication without clicking 'custom server'
---
 src/components/structures/login/Login.js    |  1 +
 src/components/views/elements/Dropdown.js   | 10 ++++++++++
 src/components/views/login/PasswordLogin.js | 14 +++++++++++++-
 src/i18n/strings/en_EN.json                 |  3 ++-
 4 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/src/components/structures/login/Login.js b/src/components/structures/login/Login.js
index a6c0a70c66..b88aa094dc 100644
--- a/src/components/structures/login/Login.js
+++ b/src/components/structures/login/Login.js
@@ -290,6 +290,7 @@ module.exports = React.createClass({
                         onPhoneNumberChanged={this.onPhoneNumberChanged}
                         onForgotPasswordClick={this.props.onForgotPasswordClick}
                         loginIncorrect={this.state.loginIncorrect}
+                        hsUrl={this.state.enteredHomeserverUrl}
                     />
                 );
             case 'm.login.cas':
diff --git a/src/components/views/elements/Dropdown.js b/src/components/views/elements/Dropdown.js
index c049c38a68..1b2117bb6a 100644
--- a/src/components/views/elements/Dropdown.js
+++ b/src/components/views/elements/Dropdown.js
@@ -26,6 +26,12 @@ class MenuOption extends React.Component {
         this._onClick = this._onClick.bind(this);
     }
 
+    getDefaultProps() {
+        return {
+            disabled: false,
+        }
+    }
+
     _onMouseEnter() {
         this.props.onMouseEnter(this.props.dropdownKey);
     }
@@ -153,6 +159,8 @@ export default class Dropdown extends React.Component {
     }
 
     _onInputClick(ev) {
+        if (this.props.disabled) return;
+
         if (!this.state.expanded) {
             this.setState({
                 expanded: true,
@@ -329,4 +337,6 @@ Dropdown.propTypes = {
     // in the dropped-down menu.
     getShortOption: React.PropTypes.func,
     value: React.PropTypes.string,
+    // negative for consistency with HTML
+    disabled: React.PropTypes.bool,
 }
diff --git a/src/components/views/login/PasswordLogin.js b/src/components/views/login/PasswordLogin.js
index 9f855616fc..4e37e30f65 100644
--- a/src/components/views/login/PasswordLogin.js
+++ b/src/components/views/login/PasswordLogin.js
@@ -186,6 +186,17 @@ class PasswordLogin extends React.Component {
 
         const loginField = this.renderLoginField(this.state.loginType);
 
+        let matrixIdText = '';
+        if (this.props.hsUrl) {
+            try {
+                const parsedHsUrl = new URL(this.props.hsUrl);
+                matrixIdText = _t('%(serverName)s Matrix ID', {serverName: parsedHsUrl.hostname});
+            } catch (e) {
+                console.log(e);
+                // pass
+            }
+        }
+
         return (
             <div>
                 <form onSubmit={this.onSubmitForm}>
@@ -194,8 +205,9 @@ class PasswordLogin extends React.Component {
                     <Dropdown
                         className="mx_Login_type_dropdown"
                         value={this.state.loginType}
+                        disabled={matrixIdText === ''}
                         onOptionChange={this.onLoginTypeChange}>
-                            <span key={PasswordLogin.LOGIN_FIELD_MXID}>{ _t('my Matrix ID') }</span>
+                            <span key={PasswordLogin.LOGIN_FIELD_MXID}>{matrixIdText}</span>
                             <span key={PasswordLogin.LOGIN_FIELD_EMAIL}>{ _t('Email address') }</span>
                             <span key={PasswordLogin.LOGIN_FIELD_PHONE}>{ _t('Phone') }</span>
                     </Dropdown>
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index 6acaba9fae..8ec975987c 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -906,5 +906,6 @@
     "Related Groups": "Related Groups",
     "Related groups for this room:": "Related groups for this room:",
     "This room has no related groups": "This room has no related groups",
-    "New group ID (e.g. +foo:%(localDomain)s)": "New group ID (e.g. +foo:%(localDomain)s)"
+    "New group ID (e.g. +foo:%(localDomain)s)": "New group ID (e.g. +foo:%(localDomain)s)",
+    "%(serverName)s Matrix ID": "%(serverName)s Matrix ID"
 }

From 80ad7d4ad670f23e8c7ae3e6d8146df5f50541f9 Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Tue, 10 Oct 2017 19:27:51 +0100
Subject: [PATCH 6/8] Update translations

---
 src/i18n/strings/de_DE.json   | 2 +-
 src/i18n/strings/el.json      | 1 -
 src/i18n/strings/en_EN.json   | 1 -
 src/i18n/strings/en_US.json   | 1 -
 src/i18n/strings/es.json      | 2 +-
 src/i18n/strings/eu.json      | 1 -
 src/i18n/strings/fi.json      | 2 +-
 src/i18n/strings/fr.json      | 2 +-
 src/i18n/strings/hu.json      | 2 +-
 src/i18n/strings/id.json      | 1 -
 src/i18n/strings/ko.json      | 1 -
 src/i18n/strings/lv.json      | 2 +-
 src/i18n/strings/nl.json      | 2 +-
 src/i18n/strings/pl.json      | 2 +-
 src/i18n/strings/pt.json      | 1 -
 src/i18n/strings/pt_BR.json   | 1 -
 src/i18n/strings/ru.json      | 2 +-
 src/i18n/strings/sv.json      | 2 +-
 src/i18n/strings/th.json      | 1 -
 src/i18n/strings/tr.json      | 1 -
 src/i18n/strings/zh_Hans.json | 1 -
 src/i18n/strings/zh_Hant.json | 1 -
 22 files changed, 10 insertions(+), 22 deletions(-)

diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json
index aa114e241d..71adaba704 100644
--- a/src/i18n/strings/de_DE.json
+++ b/src/i18n/strings/de_DE.json
@@ -146,7 +146,7 @@
     "Members only": "Nur Mitglieder",
     "Mobile phone number": "Mobiltelefonnummer",
     "Moderator": "Moderator",
-    "my Matrix ID": "meiner Matrix-ID",
+    "%(serverName)s Matrix ID": "%(serverName)s Matrix-ID",
     "Never send encrypted messages to unverified devices from this device": "Niemals verschlüsselte Nachrichten an unverifizierte Geräte von diesem Gerät aus versenden",
     "Never send encrypted messages to unverified devices in this room from this device": "Niemals verschlüsselte Nachrichten an unverifizierte Geräte in diesem Raum von diesem Gerät aus senden",
     "New password": "Neues Passwort",
diff --git a/src/i18n/strings/el.json b/src/i18n/strings/el.json
index bc45e6da9e..2a51f6cae5 100644
--- a/src/i18n/strings/el.json
+++ b/src/i18n/strings/el.json
@@ -188,7 +188,6 @@
     "Failure to create room": "Δεν ήταν δυνατή η δημιουργία δωματίου",
     "Join Room": "Είσοδος σε δωμάτιο",
     "Moderator": "Συντονιστής",
-    "my Matrix ID": "το Matrix ID μου",
     "Name": "Όνομα",
     "New address (e.g. #foo:%(localDomain)s)": "Νέα διεύθυνση (e.g. #όνομα:%(localDomain)s)",
     "New password": "Νέος κωδικός πρόσβασης",
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index 8ec975987c..37c7655ed6 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -295,7 +295,6 @@
     "Moderator": "Moderator",
     "Must be viewing a room": "Must be viewing a room",
     "Mute": "Mute",
-    "my Matrix ID": "my Matrix ID",
     "Name": "Name",
     "Never send encrypted messages to unverified devices from this device": "Never send encrypted messages to unverified devices from this device",
     "Never send encrypted messages to unverified devices in this room": "Never send encrypted messages to unverified devices in this room",
diff --git a/src/i18n/strings/en_US.json b/src/i18n/strings/en_US.json
index 928f1a9d0f..3954b2b6fa 100644
--- a/src/i18n/strings/en_US.json
+++ b/src/i18n/strings/en_US.json
@@ -262,7 +262,6 @@
     "Moderator": "Moderator",
     "Must be viewing a room": "Must be viewing a room",
     "Mute": "Mute",
-    "my Matrix ID": "my Matrix ID",
     "Name": "Name",
     "Never send encrypted messages to unverified devices from this device": "Never send encrypted messages to unverified devices from this device",
     "Never send encrypted messages to unverified devices in this room": "Never send encrypted messages to unverified devices in this room",
diff --git a/src/i18n/strings/es.json b/src/i18n/strings/es.json
index bc2391a5c7..68f27c23e9 100644
--- a/src/i18n/strings/es.json
+++ b/src/i18n/strings/es.json
@@ -379,7 +379,7 @@
     "Moderator": "Moderador",
     "Must be viewing a room": "Debe estar viendo una sala",
     "Mute": "Silenciar",
-    "my Matrix ID": "Mi ID de Matrix",
+    "%(serverName)s Matrix ID": "%(serverName)s ID de Matrix",
     "Name": "Nombre",
     "Never send encrypted messages to unverified devices from this device": "No enviar nunca mensajes cifrados, desde este dispositivo, a dispositivos sin verificar",
     "Never send encrypted messages to unverified devices in this room": "No enviar nunca mensajes cifrados a dispositivos no verificados, en esta sala",
diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json
index 9f3d06ec52..9ef02d7b9b 100644
--- a/src/i18n/strings/eu.json
+++ b/src/i18n/strings/eu.json
@@ -346,7 +346,6 @@
     "Missing room_id in request": "Gelaren ID-a falta da eskaeran",
     "Missing user_id in request": "Erabiltzailearen ID-a falta da eskaeran",
     "Mobile phone number": "Mugikorraren telefono zenbakia",
-    "my Matrix ID": "Nire Matrix ID-a",
     "Never send encrypted messages to unverified devices in this room": "Ez bidali inoiz zifratutako mezuak egiaztatu gabeko gailuetara gela honetan",
     "Never send encrypted messages to unverified devices in this room from this device": "Ez bidali inoiz zifratutako mezuak egiaztatu gabeko gailuetara gela honetan gailu honetatik",
     "New address (e.g. #foo:%(localDomain)s)": "Helbide berria (adib. #foo:%(localDomain)s)",
diff --git a/src/i18n/strings/fi.json b/src/i18n/strings/fi.json
index a59e5b1edd..7ffbf39e8e 100644
--- a/src/i18n/strings/fi.json
+++ b/src/i18n/strings/fi.json
@@ -245,7 +245,7 @@
     "Mobile phone number": "Matkapuhelinnumero",
     "Mobile phone number (optional)": "Matkapuhelinnumero (valinnainen)",
     "Moderator": "Moderaattori",
-    "my Matrix ID": "minun Matrix tunniste",
+    "%(serverName)s Matrix ID": "%(serverName)s Matrix tunniste",
     "Name": "Nimi",
     "New password": "Uusi salasana",
     "New passwords don't match": "Uudet salasanat eivät täsmää",
diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json
index 585e47f5a3..51c496ab96 100644
--- a/src/i18n/strings/fr.json
+++ b/src/i18n/strings/fr.json
@@ -224,7 +224,7 @@
     "Mobile phone number": "Numéro de téléphone mobile",
     "Moderator": "Modérateur",
     "Must be viewing a room": "Doit être en train de visualiser un salon",
-    "my Matrix ID": "mon identifiant Matrix",
+    "%(serverName)s Matrix ID": "%(serverName)s identifiant Matrix",
     "Name": "Nom",
     "Never send encrypted messages to unverified devices from this device": "Ne jamais envoyer de message chiffré aux appareils non-vérifiés depuis cet appareil",
     "Never send encrypted messages to unverified devices in this room": "Ne jamais envoyer de message chiffré aux appareils non-vérifiés dans ce salon",
diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json
index 2c34e05b1a..edf0a83ac6 100644
--- a/src/i18n/strings/hu.json
+++ b/src/i18n/strings/hu.json
@@ -293,7 +293,7 @@
     "Mobile phone number (optional)": "Mobill telefonszám (opcionális)",
     "Moderator": "Moderátor",
     "Must be viewing a room": "Meg kell nézni a szobát",
-    "my Matrix ID": "Matrix azonosítóm",
+    "%(serverName)s Matrix ID": "%(serverName)s Matrix azonosítóm",
     "Name": "Név",
     "Never send encrypted messages to unverified devices from this device": "Soha ne küldj titkosított üzenetet ellenőrizetlen eszközre erről az eszközről",
     "Never send encrypted messages to unverified devices in this room": "Soha ne küldj titkosított üzenetet ebből a szobából ellenőrizetlen eszközre",
diff --git a/src/i18n/strings/id.json b/src/i18n/strings/id.json
index dc057c2a95..27bcc41dc8 100644
--- a/src/i18n/strings/id.json
+++ b/src/i18n/strings/id.json
@@ -78,7 +78,6 @@
     "Members only": "Hanya anggota",
     "Mobile phone number": "Nomor telpon seluler",
     "Mute": "Bisu",
-    "my Matrix ID": "ID Matrix saya",
     "Name": "Nama",
     "New password": "Password Baru",
     "New passwords don't match": "Password baru tidak cocok",
diff --git a/src/i18n/strings/ko.json b/src/i18n/strings/ko.json
index 8b6e233437..5933b6abc2 100644
--- a/src/i18n/strings/ko.json
+++ b/src/i18n/strings/ko.json
@@ -293,7 +293,6 @@
     "Mobile phone number (optional)": "휴대 전화번호 (선택)",
     "Moderator": "조정자",
     "Must be viewing a room": "방을 둘러봐야만 해요",
-    "my Matrix ID": "내 매트릭스 ID",
     "Name": "이름",
     "Never send encrypted messages to unverified devices from this device": "이 장치에서 인증받지 않은 장치로 암호화한 메시지를 보내지 마세요",
     "Never send encrypted messages to unverified devices in this room": "이 방에서 인증받지 않은 장치로 암호화한 메시지를 보내지 마세요",
diff --git a/src/i18n/strings/lv.json b/src/i18n/strings/lv.json
index 5f58fd9515..424a831ac5 100644
--- a/src/i18n/strings/lv.json
+++ b/src/i18n/strings/lv.json
@@ -274,7 +274,7 @@
     "Moderator": "Moderators",
     "Must be viewing a room": "Jāapskata istaba",
     "Mute": "Apklusināt",
-    "my Matrix ID": "mans Matrix ID",
+    "%(serverName)s Matrix ID": "%(serverName)s Matrix ID",
     "Name": "Vārds",
     "Never send encrypted messages to unverified devices from this device": "Nekad nesūti no šīs ierīces šifrētas ziņas uz neverificētām ierīcēm",
     "Never send encrypted messages to unverified devices in this room": "Nekad nesūti šifrētas ziņas uz neverificētām ierīcēm šajā istabā",
diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json
index f770e335cf..67fa97a5d7 100644
--- a/src/i18n/strings/nl.json
+++ b/src/i18n/strings/nl.json
@@ -126,7 +126,7 @@
     "disabled": "uitgeschakeld",
     "Moderator": "Moderator",
     "Must be viewing a room": "Moet een ruimte weergeven",
-    "my Matrix ID": "mijn Matrix-ID",
+    "%(serverName)s Matrix ID": "%(serverName)s Matrix-ID",
     "Name": "Naam",
     "New password": "Nieuw wachtwoord",
     "none": "geen",
diff --git a/src/i18n/strings/pl.json b/src/i18n/strings/pl.json
index bd1e4c5c24..a3e2af956f 100644
--- a/src/i18n/strings/pl.json
+++ b/src/i18n/strings/pl.json
@@ -363,7 +363,7 @@
     "Mobile phone number": "Numer telefonu komórkowego",
     "Mobile phone number (optional)": "Numer telefonu komórkowego (opcjonalne)",
     "Moderator": "Moderator",
-    "my Matrix ID": "mój Matrix ID",
+    "%(serverName)s Matrix ID": "%(serverName)s Matrix ID",
     "Name": "Imię",
     "Never send encrypted messages to unverified devices from this device": "Nigdy nie wysyłaj zaszyfrowanych wiadomości do niezweryfikowanych urządzeń z tego urządzenia",
     "Never send encrypted messages to unverified devices in this room": "Nigdy nie wysyłaj zaszyfrowanych wiadomości do niezweryfikowanych urządzeń w tym pokoju",
diff --git a/src/i18n/strings/pt.json b/src/i18n/strings/pt.json
index ba4968b7ad..1bf7fd00b1 100644
--- a/src/i18n/strings/pt.json
+++ b/src/i18n/strings/pt.json
@@ -127,7 +127,6 @@
     "Members only": "Apenas integrantes da sala",
     "Mobile phone number": "Telefone celular",
     "Moderator": "Moderador/a",
-    "my Matrix ID": "com meu ID do Matrix",
     "Name": "Nome",
     "Never send encrypted messages to unverified devices from this device": "Nunca envie mensagens criptografada para um dispositivo não verificado a partir deste dispositivo",
     "Never send encrypted messages to unverified devices in this room from this device": "Nunca envie mensagens criptografadas para dispositivos não verificados nesta sala a partir deste dispositivo",
diff --git a/src/i18n/strings/pt_BR.json b/src/i18n/strings/pt_BR.json
index af4804bd85..116142c29c 100644
--- a/src/i18n/strings/pt_BR.json
+++ b/src/i18n/strings/pt_BR.json
@@ -127,7 +127,6 @@
     "Members only": "Apenas integrantes da sala",
     "Mobile phone number": "Telefone celular",
     "Moderator": "Moderador/a",
-    "my Matrix ID": "com meu ID do Matrix",
     "Name": "Nome",
     "Never send encrypted messages to unverified devices from this device": "Nunca envie mensagens criptografada para um dispositivo não verificado a partir deste dispositivo",
     "Never send encrypted messages to unverified devices in this room from this device": "Nunca envie mensagens criptografadas para dispositivos não verificados nesta sala a partir deste dispositivo",
diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json
index cfab960e32..8dc2d80001 100644
--- a/src/i18n/strings/ru.json
+++ b/src/i18n/strings/ru.json
@@ -117,7 +117,7 @@
     "Members only": "Только участники",
     "Mobile phone number": "Номер мобильного телефона",
     "Moderator": "Модератор",
-    "my Matrix ID": "мой Matrix ID",
+    "%(serverName)s Matrix ID": "%(serverName)s Matrix ID",
     "Name": "Имя",
     "Never send encrypted messages to unverified devices from this device": "Никогда не отправлять зашифрованные сообщения на непроверенные устройства с этого устройства",
     "Never send encrypted messages to unverified devices in this room from this device": "Никогда не отправлять зашифрованные сообщения на непроверенные устройства в этой комнате с этого устройства",
diff --git a/src/i18n/strings/sv.json b/src/i18n/strings/sv.json
index fb7257ecf9..fd15771cec 100644
--- a/src/i18n/strings/sv.json
+++ b/src/i18n/strings/sv.json
@@ -273,7 +273,7 @@
     "Moderator": "Moderator",
     "Must be viewing a room": "Du måste ha ett öppet rum",
     "Mute": "Dämpa",
-    "my Matrix ID": "mitt Matrix-ID",
+    "%(serverName)s Matrix ID": "%(serverName)s Matrix-ID",
     "Name": "Namn",
     "Never send encrypted messages to unverified devices from this device": "Skicka aldrig krypterade meddelanden till overifierade enheter från den här enheten",
     "Never send encrypted messages to unverified devices in this room": "Skicka aldrig krypterade meddelanden till overifierade enheter i det här rummet",
diff --git a/src/i18n/strings/th.json b/src/i18n/strings/th.json
index d45cb86986..47a5fd3049 100644
--- a/src/i18n/strings/th.json
+++ b/src/i18n/strings/th.json
@@ -219,7 +219,6 @@
     "Markdown is enabled": "เปิดใช้งาน Markdown แล้ว",
     "Missing user_id in request": "ไม่พบ user_id ในคำขอ",
     "Moderator": "ผู้ช่วยดูแล",
-    "my Matrix ID": "Matrix ID ของฉัน",
     "New address (e.g. #foo:%(localDomain)s)": "ที่อยู่ใหม่ (เช่น #foo:%(localDomain)s)",
     "New password": "รหัสผ่านใหม่",
     "New passwords don't match": "รหัสผ่านใหม่ไม่ตรงกัน",
diff --git a/src/i18n/strings/tr.json b/src/i18n/strings/tr.json
index 23d4e284bc..6e8e4f25f8 100644
--- a/src/i18n/strings/tr.json
+++ b/src/i18n/strings/tr.json
@@ -269,7 +269,6 @@
     "Moderator": "Moderatör",
     "Must be viewing a room": "Bir oda görüntülemeli olmalı",
     "Mute": "Sessiz",
-    "my Matrix ID": "Benim Matrix ID'm",
     "Name": "İsim",
     "Never send encrypted messages to unverified devices from this device": "Bu cihazdan doğrulanmamış cihazlara asla şifrelenmiş mesajlar göndermeyin",
     "Never send encrypted messages to unverified devices in this room": "Bu odada doğrulanmamış cihazlara asla şifreli mesajlar göndermeyin",
diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json
index 69ba19ca27..f185640572 100644
--- a/src/i18n/strings/zh_Hans.json
+++ b/src/i18n/strings/zh_Hans.json
@@ -289,7 +289,6 @@
     "Mobile phone number (optional)": "手机号码 (可选)",
     "Moderator": "管理员",
     "Mute": "静音",
-    "my Matrix ID": "我的 Matrix ID",
     "Name": "姓名",
     "Never send encrypted messages to unverified devices from this device": "不要从此设备向未验证的设备发送消息",
     "Never send encrypted messages to unverified devices in this room": "不要在此聊天室里向未验证的设备发送消息",
diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json
index 596bc55a01..49890005a1 100644
--- a/src/i18n/strings/zh_Hant.json
+++ b/src/i18n/strings/zh_Hant.json
@@ -403,7 +403,6 @@
     "Mobile phone number (optional)": "行動電話號碼(選擇性)",
     "Moderator": "仲裁者",
     "Must be viewing a room": "必須檢視房間",
-    "my Matrix ID": "我的 Matrix ID",
     "Name": "名稱",
     "Never send encrypted messages to unverified devices from this device": "從不自此裝置傳送加密的訊息到未驗證的裝置",
     "Never send encrypted messages to unverified devices in this room": "從不在此房間傳送加密的訊息到未驗證的裝置",

From fa24b4bd2de325154cc32d0237b9fe5904c794cd Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Wed, 11 Oct 2017 09:48:12 +0100
Subject: [PATCH 7/8] Remove this log - it's not an error worth logging

---
 src/components/views/login/PasswordLogin.js | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/components/views/login/PasswordLogin.js b/src/components/views/login/PasswordLogin.js
index 4e37e30f65..7e78de3f54 100644
--- a/src/components/views/login/PasswordLogin.js
+++ b/src/components/views/login/PasswordLogin.js
@@ -192,7 +192,6 @@ class PasswordLogin extends React.Component {
                 const parsedHsUrl = new URL(this.props.hsUrl);
                 matrixIdText = _t('%(serverName)s Matrix ID', {serverName: parsedHsUrl.hostname});
             } catch (e) {
-                console.log(e);
                 // pass
             }
         }

From 0f84216a9fea9c0cf38d6ae1ab30e0062bf707a1 Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Wed, 11 Oct 2017 14:05:34 +0100
Subject: [PATCH 8/8] Grey out login form when no valid HS

---
 src/components/views/elements/Dropdown.js     |  1 +
 src/components/views/login/CountryDropdown.js |  3 +-
 src/components/views/login/PasswordLogin.js   | 46 +++++++++++++------
 3 files changed, 34 insertions(+), 16 deletions(-)

diff --git a/src/components/views/elements/Dropdown.js b/src/components/views/elements/Dropdown.js
index 1b2117bb6a..0fb5a37414 100644
--- a/src/components/views/elements/Dropdown.js
+++ b/src/components/views/elements/Dropdown.js
@@ -302,6 +302,7 @@ export default class Dropdown extends React.Component {
 
         const dropdownClasses = {
             mx_Dropdown: true,
+            mx_Dropdown_disabled: this.props.disabled,
         };
         if (this.props.className) {
             dropdownClasses[this.props.className] = true;
diff --git a/src/components/views/login/CountryDropdown.js b/src/components/views/login/CountryDropdown.js
index 7024db339c..56ab962d98 100644
--- a/src/components/views/login/CountryDropdown.js
+++ b/src/components/views/login/CountryDropdown.js
@@ -123,7 +123,7 @@ export default class CountryDropdown extends React.Component {
         return <Dropdown className={this.props.className + " left_aligned"}
             onOptionChange={this._onOptionChange} onSearchChange={this._onSearchChange}
             menuWidth={298} getShortOption={this._getShortOption}
-            value={value} searchEnabled={true}
+            value={value} searchEnabled={true} disabled={this.props.disabled}
         >
             {options}
         </Dropdown>;
@@ -137,4 +137,5 @@ CountryDropdown.propTypes = {
     showPrefix: React.PropTypes.bool,
     onOptionChange: React.PropTypes.func.isRequired,
     value: React.PropTypes.string,
+    disabled: React.PropTypes.bool,
 };
diff --git a/src/components/views/login/PasswordLogin.js b/src/components/views/login/PasswordLogin.js
index 7e78de3f54..d532c400bc 100644
--- a/src/components/views/login/PasswordLogin.js
+++ b/src/components/views/login/PasswordLogin.js
@@ -116,11 +116,17 @@ class PasswordLogin extends React.Component {
         this.props.onPasswordChanged(ev.target.value);
     }
 
-    renderLoginField(loginType) {
+    renderLoginField(loginType, disabled) {
+        const classes = {
+            mx_Login_field: true,
+            mx_Login_field_disabled: disabled,
+        };
+
         switch(loginType) {
             case PasswordLogin.LOGIN_FIELD_EMAIL:
+                classes.mx_Login_email = true;
                 return <input
-                    className="mx_Login_field mx_Login_email"
+                    className={classNames(classes)}
                     key="email_input"
                     type="text"
                     name="username" // make it a little easier for browser's remember-password
@@ -128,10 +134,12 @@ class PasswordLogin extends React.Component {
                     placeholder="joe@example.com"
                     value={this.state.username}
                     autoFocus
+                    disabled={disabled}
                 />;
             case PasswordLogin.LOGIN_FIELD_MXID:
+                classes.mx_Login_username = true;
                 return <input
-                    className="mx_Login_field mx_Login_username"
+                    className={classNames(classes)}
                     key="username_input"
                     type="text"
                     name="username" // make it a little easier for browser's remember-password
@@ -139,9 +147,12 @@ class PasswordLogin extends React.Component {
                     placeholder={_t('User name')}
                     value={this.state.username}
                     autoFocus
+                    disabled={disabled}
                 />;
             case PasswordLogin.LOGIN_FIELD_PHONE:
                 const CountryDropdown = sdk.getComponent('views.login.CountryDropdown');
+                classes.mx_Login_phoneNumberField = true;
+                classes.mx_Login_field_has_prefix = true;
                 return <div className="mx_Login_phoneSection">
                     <CountryDropdown
                         className="mx_Login_phoneCountry mx_Login_field_prefix"
@@ -150,9 +161,10 @@ class PasswordLogin extends React.Component {
                         value={this.state.phoneCountry}
                         isSmall={true}
                         showPrefix={true}
+                        disabled={disabled}
                     />
                     <input
-                        className="mx_Login_phoneNumberField mx_Login_field mx_Login_field_has_prefix"
+                        className={classNames(classes)}
                         ref="phoneNumber"
                         key="phone_input"
                         type="text"
@@ -161,6 +173,7 @@ class PasswordLogin extends React.Component {
                         placeholder={_t("Mobile phone number")}
                         value={this.state.phoneNumber}
                         autoFocus
+                        disabled={disabled}
                     />
                 </div>;
         }
@@ -177,15 +190,6 @@ class PasswordLogin extends React.Component {
             );
         }
 
-        const pwFieldClass = classNames({
-            mx_Login_field: true,
-            error: this.props.loginIncorrect,
-        });
-
-        const Dropdown = sdk.getComponent('elements.Dropdown');
-
-        const loginField = this.renderLoginField(this.state.loginType);
-
         let matrixIdText = '';
         if (this.props.hsUrl) {
             try {
@@ -196,6 +200,16 @@ class PasswordLogin extends React.Component {
             }
         }
 
+        const pwFieldClass = classNames({
+            mx_Login_field: true,
+            mx_Login_field_disabled: matrixIdText === '',
+            error: this.props.loginIncorrect,
+        });
+
+        const Dropdown = sdk.getComponent('elements.Dropdown');
+
+        const loginField = this.renderLoginField(this.state.loginType, matrixIdText === '');
+
         return (
             <div>
                 <form onSubmit={this.onSubmitForm}>
@@ -215,10 +229,12 @@ class PasswordLogin extends React.Component {
                 <input className={pwFieldClass} ref={(e) => {this._passwordField = e;}} type="password"
                     name="password"
                     value={this.state.password} onChange={this.onPasswordChanged}
-                    placeholder={ _t('Password') } />
+                    placeholder={ _t('Password') }
+                    disabled={matrixIdText === ''}
+                />
                 <br />
                 {forgotPasswordJsx}
-                <input className="mx_Login_submit" type="submit" value={ _t('Sign in') } />
+                <input className="mx_Login_submit" type="submit" value={ _t('Sign in') } disabled={matrixIdText === ''} />
                 </form>
             </div>
         );