From d5bc24d9f76fbcef01263f99f39cdc788de7cde7 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Fri, 19 May 2017 09:54:29 +0100 Subject: [PATCH 01/20] Initial implementation of KeyRequestHandler, KeyShareDialog etc --- src/KeyRequestHandler.js | 89 ++++++++++ src/components/structures/MatrixChat.js | 6 + .../views/dialogs/KeyShareDialog.js | 164 ++++++++++++++++++ 3 files changed, 259 insertions(+) create mode 100644 src/KeyRequestHandler.js create mode 100644 src/components/views/dialogs/KeyShareDialog.js diff --git a/src/KeyRequestHandler.js b/src/KeyRequestHandler.js new file mode 100644 index 0000000000..90ff00d47e --- /dev/null +++ b/src/KeyRequestHandler.js @@ -0,0 +1,89 @@ +/* +Copyright 2017 Vector Creations Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import sdk from './index'; +import Modal from './Modal'; + +export default class KeyRequestHandler { + constructor(matrixClient) { + this._matrixClient = matrixClient; + + this._isDialogOpen = false; + + // userId -> deviceId -> [keyRequest] + this._pendingKeyRequests = {}; + } + + + handleKeyRequest(keyRequest) { + const userId = keyRequest.userId; + const deviceId = keyRequest.deviceId; + + if (!this._pendingKeyRequests[userId]) { + this._pendingKeyRequests[userId] = {}; + } + if (!this._pendingKeyRequests[userId][deviceId]) { + this._pendingKeyRequests[userId][deviceId] = []; + } + this._pendingKeyRequests[userId][deviceId].push(keyRequest); + + if (this._isDialogOpen) { + // ignore for now + console.log("Key request, but we already have a dialog open"); + return; + } + + this._processNextRequest(); + } + + _processNextRequest() { + const userId = Object.keys(this._pendingKeyRequests)[0]; + if (!userId) { + return; + } + const deviceId = Object.keys(this._pendingKeyRequests[userId])[0]; + if (!deviceId) { + return; + } + console.log(`Starting KeyShareDialog for ${userId}:${deviceId}`); + + const finished = (r) => { + this._isDialogOpen = false; + + if (r) { + for (const req of this._pendingKeyRequests[userId][deviceId]) { + req.share(); + } + } + delete this._pendingKeyRequests[userId][deviceId]; + if (Object.keys(this._pendingKeyRequests[userId]).length === 0) { + delete this._pendingKeyRequests[userId]; + } + + this._processNextRequest(); + }; + + const KeyShareDialog = sdk.getComponent("dialogs.KeyShareDialog"); + Modal.createDialog(KeyShareDialog, { + matrixClient: this._matrixClient, + userId: userId, + deviceId: deviceId, + onFinished: finished, + }); + this._isDialogOpen = true; + } +} + diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index f53128fba9..544213edc6 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -38,6 +38,7 @@ import PageTypes from '../../PageTypes'; import createRoom from "../../createRoom"; import * as UDEHandler from '../../UnknownDeviceErrorHandler'; +import KeyRequestHandler from '../../KeyRequestHandler'; import { _t } from '../../languageHandler'; module.exports = React.createClass({ @@ -914,6 +915,11 @@ module.exports = React.createClass({ } } }); + + const krh = new KeyRequestHandler(cli); + cli.on("crypto.roomKeyRequest", (req) => { + krh.handleKeyRequest(req); + }); }, showScreen: function(screen, params) { diff --git a/src/components/views/dialogs/KeyShareDialog.js b/src/components/views/dialogs/KeyShareDialog.js new file mode 100644 index 0000000000..5b66944dbc --- /dev/null +++ b/src/components/views/dialogs/KeyShareDialog.js @@ -0,0 +1,164 @@ +/* +Copyright 2017 Vector Creations Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import Modal from '../../../Modal'; +import React from 'react'; +import sdk from '../../../index'; + +import { _t } from '../../../languageHandler'; + +export default React.createClass({ + propTypes: { + matrixClient: React.PropTypes.object.isRequired, + userId: React.PropTypes.string.isRequired, + deviceId: React.PropTypes.string.isRequired, + onFinished: React.PropTypes.func.isRequired, + }, + + getInitialState: function() { + return { + deviceInfo: null, + wasNewDevice: false, + }; + }, + + componentDidMount: function() { + this._unmounted = false; + const userId = this.props.userId; + const deviceId = this.props.deviceId; + + // give the client a chance to refresh the device list + this.props.matrixClient.downloadKeys([userId], false).then((r) => { + if (this._unmounted) { return; } + + const deviceInfo = r[userId][deviceId]; + + if(!deviceInfo) { + console.warn(`No details found for device ${userId}:${deviceId}`); + + this.props.onFinished(false); + return; + } + + const wasNewDevice = !deviceInfo.isKnown(); + + this.setState({ + deviceInfo: deviceInfo, + wasNewDevice: wasNewDevice, + }); + + // if the device was new before, it's not any more. + if (wasNewDevice) { + this.props.matrixClient.setDeviceKnown( + userId, + deviceId, + true, + ); + } + }).done(); + }, + + componentWillUnmount: function() { + this._unmounted = true; + }, + + + _onVerifyClicked: function() { + const DeviceVerifyDialog = sdk.getComponent('views.dialogs.DeviceVerifyDialog'); + + console.log("KeyShareDialog: Starting verify dialog"); + Modal.createDialog(DeviceVerifyDialog, { + userId: this.props.userId, + device: this.state.deviceInfo, + onFinished: (verified) => { + if (verified) { + // can automatically share the keys now. + this.props.onFinished(true); + } + }, + }); + }, + + _onShareClicked: function() { + console.log("KeyShareDialog: User clicked 'share'"); + this.props.onFinished(true); + }, + + _onIgnoreClicked: function() { + console.log("KeyShareDialog: User clicked 'ignore'"); + this.props.onFinished(false); + }, + + _renderContent: function() { + const displayName = this.state.deviceInfo.getDisplayName() || + this.state.deviceInfo.deviceId; + + let text; + if (this.state.wasNewDevice) { + text = "You added a new device '%(displayName)s', which is" + + " requesting encryption keys."; + } else { + text = "Your unverified device '%(displayName)s' is requesting" + + " encryption keys."; + } + text = _t(text, {displayName: displayName}); + + return ( +
+

{text}

+ +
+ + + +
+
+ ); + }, + + render: function() { + const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); + const Spinner = sdk.getComponent('views.elements.Spinner'); + + let content; + + if (this.state.deviceInfo) { + content = this._renderContent(); + } else { + content = ( +
+

{_t('Loading device info...')}

+ +
+ ); + } + + return ( + + {content} + + ); + }, +}); From 7d55f3e75d55edef5a0303ab8c0f8909cce2d57e Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 1 Jun 2017 17:49:24 +0100 Subject: [PATCH 02/20] handle room key request cancellations --- src/KeyRequestHandler.js | 55 ++++++++++++++++++++++--- src/components/structures/MatrixChat.js | 3 ++ 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/KeyRequestHandler.js b/src/KeyRequestHandler.js index 90ff00d47e..fbb869d468 100644 --- a/src/KeyRequestHandler.js +++ b/src/KeyRequestHandler.js @@ -21,16 +21,18 @@ export default class KeyRequestHandler { constructor(matrixClient) { this._matrixClient = matrixClient; - this._isDialogOpen = false; + // the user/device for which we currently have a dialog open + this._currentUser = null; + this._currentDevice = null; // userId -> deviceId -> [keyRequest] this._pendingKeyRequests = {}; } - handleKeyRequest(keyRequest) { const userId = keyRequest.userId; const deviceId = keyRequest.deviceId; + const requestId = keyRequest.requestId; if (!this._pendingKeyRequests[userId]) { this._pendingKeyRequests[userId] = {}; @@ -38,9 +40,17 @@ export default class KeyRequestHandler { if (!this._pendingKeyRequests[userId][deviceId]) { this._pendingKeyRequests[userId][deviceId] = []; } - this._pendingKeyRequests[userId][deviceId].push(keyRequest); - if (this._isDialogOpen) { + // check if we already have this request + const requests = this._pendingKeyRequests[userId][deviceId]; + if (requests.find((r) => r.requestId === requestId)) { + console.log("Already have this key request, ignoring"); + return; + } + + requests.push(keyRequest); + + if (this._currentUser) { // ignore for now console.log("Key request, but we already have a dialog open"); return; @@ -49,6 +59,37 @@ export default class KeyRequestHandler { this._processNextRequest(); } + handleKeyRequestCancellation(cancellation) { + // see if we can find the request in the queue + const userId = cancellation.userId; + const deviceId = cancellation.deviceId; + const requestId = cancellation.requestId; + + if (userId === this._currentUser && deviceId === this._currentDevice) { + console.log( + "room key request cancellation for the user we currently have a" + + " dialog open for", + ); + // TODO: update the dialog. For now, we just ignore the + // cancellation. + return; + } + + if (!this._pendingKeyRequests[userId]) { + return; + } + const requests = this._pendingKeyRequests[userId][deviceId]; + if (!requests) { + return; + } + const idx = requests.findIndex((r) => r.requestId === requestId); + if (idx < 0) { + return; + } + console.log("Forgetting room key request"); + requests.splice(idx, 1); + } + _processNextRequest() { const userId = Object.keys(this._pendingKeyRequests)[0]; if (!userId) { @@ -61,7 +102,8 @@ export default class KeyRequestHandler { console.log(`Starting KeyShareDialog for ${userId}:${deviceId}`); const finished = (r) => { - this._isDialogOpen = false; + this._currentUser = null; + this._currentDevice = null; if (r) { for (const req of this._pendingKeyRequests[userId][deviceId]) { @@ -83,7 +125,8 @@ export default class KeyRequestHandler { deviceId: deviceId, onFinished: finished, }); - this._isDialogOpen = true; + this._currentUser = userId; + this._currentDevice = deviceId; } } diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 544213edc6..afb3c57818 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -920,6 +920,9 @@ module.exports = React.createClass({ cli.on("crypto.roomKeyRequest", (req) => { krh.handleKeyRequest(req); }); + cli.on("crypto.roomKeyRequestCancellation", (req) => { + krh.handleKeyRequestCancellation(req); + }); }, showScreen: function(screen, params) { From 21277557f80a725ac0ee0175633d198ecbae263a Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Fri, 2 Jun 2017 10:10:40 +0100 Subject: [PATCH 03/20] Add translations for new dialog --- src/i18n/strings/en_EN.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 95baf1f50e..6e7648f00d 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -779,5 +779,10 @@ "Disable URL previews for this room (affects only you)": "Disable URL previews for this room (affects only you)", "$senderDisplayName changed the room avatar to ": "$senderDisplayName changed the room avatar to ", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s removed the room avatar.", - "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s changed the avatar for %(roomName)s" + "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s changed the avatar for %(roomName)s", + "Start verification": "Start verification", + "Share without verifying": "Share without verifying", + "Ignore request": "Ignore request", + "You added a new device '%(displayName)s', which is requesting encryption keys.": "You added a new device '%(displayName)s', which is requesting encryption keys.", + "Your unverified device '%(displayName)s' is requesting encryption keys.": "Your unverified device '%(displayName)s' is requesting encryption keys." } From 7a9784fd6ef39e4fc214e8416456b9d92cb9f7e8 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 5 Jun 2017 17:26:25 +0100 Subject: [PATCH 04/20] KeyRequestHandler: clear redundant users/devices on cancellations ... otherwise _processNextRequest will get confused --- src/KeyRequestHandler.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/KeyRequestHandler.js b/src/KeyRequestHandler.js index fbb869d468..4354fba269 100644 --- a/src/KeyRequestHandler.js +++ b/src/KeyRequestHandler.js @@ -88,6 +88,12 @@ export default class KeyRequestHandler { } console.log("Forgetting room key request"); requests.splice(idx, 1); + if (requests.length === 0) { + delete this._pendingKeyRequests[userId][deviceId]; + if (Object.keys(this._pendingKeyRequests[userId]).length === 0) { + delete this._pendingKeyRequests[userId]; + } + } } _processNextRequest() { From 32e3ea0601355fc366fddee43194f9c7b1492238 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 5 Jun 2017 17:58:11 +0100 Subject: [PATCH 05/20] Address review comments --- src/KeyRequestHandler.js | 4 ++-- src/components/views/dialogs/KeyShareDialog.js | 10 +++++++++- src/i18n/strings/en_EN.json | 4 +++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/KeyRequestHandler.js b/src/KeyRequestHandler.js index 4354fba269..1da4922153 100644 --- a/src/KeyRequestHandler.js +++ b/src/KeyRequestHandler.js @@ -26,7 +26,7 @@ export default class KeyRequestHandler { this._currentDevice = null; // userId -> deviceId -> [keyRequest] - this._pendingKeyRequests = {}; + this._pendingKeyRequests = Object.create(null); } handleKeyRequest(keyRequest) { @@ -35,7 +35,7 @@ export default class KeyRequestHandler { const requestId = keyRequest.requestId; if (!this._pendingKeyRequests[userId]) { - this._pendingKeyRequests[userId] = {}; + this._pendingKeyRequests[userId] = Object.create(null); } if (!this._pendingKeyRequests[userId][deviceId]) { this._pendingKeyRequests[userId][deviceId] = []; diff --git a/src/components/views/dialogs/KeyShareDialog.js b/src/components/views/dialogs/KeyShareDialog.js index 5b66944dbc..61391d281c 100644 --- a/src/components/views/dialogs/KeyShareDialog.js +++ b/src/components/views/dialogs/KeyShareDialog.js @@ -20,6 +20,14 @@ import sdk from '../../../index'; import { _t } from '../../../languageHandler'; +/** + * Dialog which asks the user whether they want to share their keys with + * an unverified device. + * + * onFinished is called with `true` if the key should be shared, `false` if it + * should not, and `undefined` if the dialog is cancelled. (In other words: + * truthy: do the key share. falsy: don't share the keys). + */ export default React.createClass({ propTypes: { matrixClient: React.PropTypes.object.isRequired, @@ -155,7 +163,7 @@ export default React.createClass({ return ( {content} diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 7421ccad76..f6c044deac 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -809,5 +809,7 @@ "Share without verifying": "Share without verifying", "Ignore request": "Ignore request", "You added a new device '%(displayName)s', which is requesting encryption keys.": "You added a new device '%(displayName)s', which is requesting encryption keys.", - "Your unverified device '%(displayName)s' is requesting encryption keys.": "Your unverified device '%(displayName)s' is requesting encryption keys." + "Your unverified device '%(displayName)s' is requesting encryption keys.": "Your unverified device '%(displayName)s' is requesting encryption keys.", + "Encryption key request": "Encryption key request" + } From 83d5822c85035a2507d90ed45dee1023780751ed Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 19 Jun 2017 13:17:12 +0100 Subject: [PATCH 06/20] Show a "Skip" button instead of "Cancel" in SetEmailDialog Fixes https://github.com/vector-im/riot-web/issues/4309 --- src/components/views/dialogs/SetEmailDialog.js | 2 +- src/i18n/strings/en_EN.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/views/dialogs/SetEmailDialog.js b/src/components/views/dialogs/SetEmailDialog.js index 82256970de..3c38064ee1 100644 --- a/src/components/views/dialogs/SetEmailDialog.js +++ b/src/components/views/dialogs/SetEmailDialog.js @@ -154,7 +154,7 @@ export default React.createClass({ /> diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index ad00ea9275..9bd263c243 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -910,5 +910,6 @@ "Authentication check failed: incorrect password?": "Authentication check failed: incorrect password?", "Disable Peer-to-Peer for 1:1 calls": "Disable Peer-to-Peer for 1:1 calls", "Do you want to set an email address?": "Do you want to set an email address?", - "This will allow you to reset your password and receive notifications.": "This will allow you to reset your password and receive notifications." + "This will allow you to reset your password and receive notifications.": "This will allow you to reset your password and receive notifications.", + "Skip":"Skip" } From a8165d1707c0ae495f660074560fe1d9bf76d17d Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 19 Jun 2017 16:40:33 +0100 Subject: [PATCH 07/20] Fix infinite spinner on email registration Remove setTimeout on dialog display as it's no longer necessary and causes races. --- src/createRoom.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/createRoom.js b/src/createRoom.js index bf0c0fee1c..8f0f9bd148 100644 --- a/src/createRoom.js +++ b/src/createRoom.js @@ -76,10 +76,7 @@ function createRoom(opts) { } ]; - let modal; - setTimeout(()=>{ - modal = Modal.createDialog(Loader, null, 'mx_Dialog_spinner'); - }, 0); + const modal = Modal.createDialog(Loader, null, 'mx_Dialog_spinner'); let roomId; return client.createRoom(createOpts).finally(function() { From 26cb1404c22445ad73f3e258d916980997df5eaf Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 19 Jun 2017 16:45:40 +0100 Subject: [PATCH 08/20] Remove unnecessary if --- src/createRoom.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/createRoom.js b/src/createRoom.js index 8f0f9bd148..ce83f31c27 100644 --- a/src/createRoom.js +++ b/src/createRoom.js @@ -80,7 +80,7 @@ function createRoom(opts) { let roomId; return client.createRoom(createOpts).finally(function() { - if (modal) modal.close(); + modal.close(); }).then(function(res) { roomId = res.room_id; if (opts.dmUserId) { From 09b91f4af9cc5d8a20291b22a55891981c9dbc5d Mon Sep 17 00:00:00 2001 From: daniel tygel Date: Mon, 19 Jun 2017 13:20:16 -0300 Subject: [PATCH 09/20] add two strings to translation --- src/components/views/rooms/RoomList.js | 24 ++++++++++++++++++++---- src/i18n/strings/en_EN.json | 3 ++- src/i18n/strings/pt_BR.json | 3 ++- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index f90d89c8c1..c898431d33 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -18,7 +18,7 @@ limitations under the License. 'use strict'; var React = require("react"); var ReactDOM = require("react-dom"); -import { _t } from '../../../languageHandler'; +import { _t, _tJsx } from '../../../languageHandler'; var GeminiScrollbar = require('react-gemini-scrollbar'); var MatrixClientPeg = require("../../../MatrixClientPeg"); var CallHandler = require('../../../CallHandler'); @@ -478,12 +478,28 @@ module.exports = React.createClass({ switch (section) { case 'im.vector.fake.direct': return
- Press - - to start a chat with someone + {_tJsx( + "Press to start a chat with someone", + [//], + [ + (sub) => + ] + )}
; case 'im.vector.fake.recent': return
+ {_tJsx( + "You're not in any rooms yet! Press to make a room or"+ + " to browse the directory", + [//, //], + [ + (sub) => , + (sub) => + ] + )} + + + You're not in any rooms yet! Press to make a room or diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index ad00ea9275..e7f8199f9c 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -440,6 +440,7 @@ "Please Register": "Please Register", "Power level must be positive integer.": "Power level must be positive integer.", "Press": "Press", + "Press to start a chat with someone": "Press to start a chat with someone", "Privacy warning": "Privacy warning", "Private Chat": "Private Chat", "Privileged Users": "Privileged Users", @@ -648,7 +649,7 @@ "Would you like to accept or decline this invitation?": "Would you like to accept or decline this invitation?", "You already have existing direct chats with this user:": "You already have existing direct chats with this user:", "You are already in a call.": "You are already in a call.", - "You're not in any rooms yet! Press": "You're not in any rooms yet! Press", + "You're not in any rooms yet! Press to make a room or to browse the directory": "You're not in any rooms yet! Press to make a room or to browse the directory", "You are trying to access %(roomName)s.": "You are trying to access %(roomName)s.", "You cannot place a call with yourself.": "You cannot place a call with yourself.", "You cannot place VoIP calls in this browser.": "You cannot place VoIP calls in this browser.", diff --git a/src/i18n/strings/pt_BR.json b/src/i18n/strings/pt_BR.json index 2c18b0507d..b7ea693a50 100644 --- a/src/i18n/strings/pt_BR.json +++ b/src/i18n/strings/pt_BR.json @@ -356,6 +356,7 @@ "%(senderName)s placed a %(callType)s call.": "%(senderName)s fez uma chamada de %(callType)s.", "Power level must be positive integer.": "O nível de permissões tem que ser um número inteiro e positivo.", "Press": "Aperte", + "Press to start a chat with someone": "Clique em para iniciar a conversa com alguém", "Reason": "Razão", "%(targetName)s rejected the invitation.": "%(targetName)s recusou o convite.", "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s removeu o seu nome público (%(oldDisplayName)s).", @@ -398,7 +399,7 @@ "VoIP is unsupported": "Chamada de voz não permitida", "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s desfez o convite a %(targetName)s.", "You are already in a call.": "Você já está em uma chamada.", - "You're not in any rooms yet! Press": "Você ainda não está em nenhuma sala! Pressione", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Você ainda não está em nenhuma sala! Clique em para criar uma sala ou em para navegar pela lista pública de salas", "You are trying to access %(roomName)s.": "Você está tentando acessar a sala %(roomName)s.", "You cannot place a call with yourself.": "Você não pode iniciar uma chamada.", "You cannot place VoIP calls in this browser.": "Você não pode fazer chamadas de voz neste navegador.", From 7b82385084b599bea614a0380b3e7341be2155b8 Mon Sep 17 00:00:00 2001 From: daniel tygel Date: Mon, 19 Jun 2017 13:21:23 -0300 Subject: [PATCH 10/20] add two strings to translation --- src/components/views/rooms/RoomList.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index c898431d33..008d6d3a47 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -497,14 +497,6 @@ module.exports = React.createClass({ (sub) => ] )} - - - - You're not in any rooms yet! Press - - to make a room or - - to browse the directory
; } From 17899dd3bf92ab804d17ed0628166a285a44efa0 Mon Sep 17 00:00:00 2001 From: daniel tygel Date: Mon, 19 Jun 2017 13:22:23 -0300 Subject: [PATCH 11/20] typo --- src/components/views/rooms/RoomList.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 008d6d3a47..e1fe075f42 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -490,7 +490,7 @@ module.exports = React.createClass({ return
{_tJsx( "You're not in any rooms yet! Press to make a room or"+ - " to browse the directory", + " to browse the directory", [//, //], [ (sub) => , From 692b03f2e78e5db80270476ba53508552f69aa5f Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 19 Jun 2017 17:49:22 +0100 Subject: [PATCH 12/20] Internationalise the drop targets Unsure how these had got missed (and yet still had the translation strings in the json) --- src/components/views/rooms/RoomList.js | 29 ++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index e1fe075f42..9f9f030c27 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -33,11 +33,28 @@ var Receipt = require('../../../utils/Receipt'); const HIDE_CONFERENCE_CHANS = true; -const VERBS = { - 'm.favourite': 'favourite', - 'im.vector.fake.direct': 'tag direct chat', - 'im.vector.fake.recent': 'restore', - 'm.lowpriority': 'demote', +function phraseForSection(section) { + // These would probably be better as individual strings, + // but for some reason we have translations for these strings + // as-is, so keeping it like this for now. + let verb; + switch (section) { + case 'm.favourite': + verb = _t('to favourite'); + break; + case 'im.vector.fake.direct': + verb = _t('to tag direct chat'); + break; + case 'im.vector.fake.recent': + verb = _t('to restore'); + break; + case 'm.lowpriority': + verb = _t('to demote'); + break; + default: + return _t('Drop here to tag %(section)s', {section: section}); + } + return _t('Drop here %(toAction)s', {toAction: verb}); }; module.exports = React.createClass({ @@ -505,7 +522,7 @@ module.exports = React.createClass({ return null; } - const labelText = 'Drop here to ' + (VERBS[section] || 'tag ' + section); + const labelText = phraseForSection(section); return ; }, From 0e71918ba174d3d6a7e9aa4b78aebb27552b88ae Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 20 Jun 2017 10:05:50 +0100 Subject: [PATCH 13/20] Merge pull request #1119 from RiotTranslateBot/weblate-riot-web-matrix-react-sdk Update from Weblate. --- src/i18n/strings/de_DE.json | 18 ++-- src/i18n/strings/el.json | 4 +- src/i18n/strings/fr.json | 6 +- src/i18n/strings/hu.json | 172 +++++++++++++++++++++++++++++++++++- src/i18n/strings/ko.json | 21 ++++- src/i18n/strings/nl.json | 34 +++++-- src/i18n/strings/pt_BR.json | 11 ++- src/i18n/strings/ru.json | 32 +++---- 8 files changed, 263 insertions(+), 35 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index a4ac23581d..a99671402b 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -105,7 +105,7 @@ "Can't load user settings": "Benutzereinstellungen können nicht geladen werden", "changed name": "änderte Namen", "changed the power level of": "änderte Berechtigungslevel von", - "Clear Cache": "Leere Cache", + "Clear Cache": "Cache leeren", "Click here to fix": "Zum reparieren hier klicken", "*️⃣ Commands": "*️⃣ Befehle", "Default": "Standard", @@ -207,7 +207,7 @@ "since they joined": "ab dem Zeitpunkt, an dem sie beigetreten sind", "since they were invited": "ab dem Zeitpunkt, an dem sie eingeladen wurden", "Someone": "Jemand", - "Start a chat": "Starte einen Chat", + "Start a chat": "Chat starten", "Start Chat": "Chat beginnen", "Success": "Erfolg", "tag direct chat": "Zum kennzeichnen als direkten Chat", @@ -425,7 +425,7 @@ "to start a chat with someone": "um einen Chat mit jemandem zu starten", "to tag direct chat": "als Direkt-Chat markieren", "You're not in any rooms yet! Press": "Du bist noch keinem Raum beigetreten! Drücke", - "click to reveal": "Klicke zum anzeigen", + "click to reveal": "anzeigen", "To remove other users' messages": "Um Nachrichten anderer Nutzer zu verbergen", "You are trying to access %(roomName)s.": "Du versuchst, auf den Raum \"%(roomName)s\" zuzugreifen.", "af": "Afrikaans", @@ -671,7 +671,7 @@ "%(oneUser)srejected their invitation %(repeats)s times": "%(oneUser)shat die Einladung %(repeats)s mal abgelehnt", "%(severalUsers)srejected their invitations": "%(severalUsers)shaben ihre Einladung abgelehnt", "%(oneUser)srejected their invitation": "%(oneUser)shat die Einladung abgelehnt", - "%(severalUsers)shad their invitations withdrawn %(repeats)s times": "%(severalUsers)szogen ihre Einladungen %(repeats)s mal zurück", + "%(severalUsers)shad their invitations withdrawn %(repeats)s times": "%(severalUsers)swurden die ursprünglichen Einladungen %(repeats)s mal wieder entzogen", "%(oneUser)shad their invitation withdrawn %(repeats)s times": "%(oneUser)swurde die Einladung %(repeats)s mal wieder entzogen", "%(severalUsers)shad their invitations withdrawn": "%(severalUsers)szogen ihre Einladungen zurück", "%(oneUser)shad their invitation withdrawn": "%(oneUser)swurde die ursprüngliche Einladung wieder entzogen", @@ -710,7 +710,7 @@ "New passwords don't match": "Die neuen Passwörter stimmen nicht überein", "olm version:": "Version von olm:", "Passwords can't be empty": "Passwortfelder dürfen nicht leer sein", - "Report it": "Melde ihn", + "Report it": "Melden", "riot-web version:": "Version von riot-web:", "Scroll to bottom of page": "Zum Ende der Seite springen", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Zeitstempel im 12-Stunden-Format anzeigen (z. B. 2:30pm)", @@ -815,14 +815,14 @@ "Ongoing conference call%(supportedText)s.": "Laufendes Konferenzgespräch%(supportedText)s.", "You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "Du wirst jetzt auf die Website eines Drittanbieters weitergeleitet, damit du dein Konto für die Verwendung von %(integrationsUrl)s authentifizieren kannst. Möchtest du fortfahren?", "Disable URL previews for this room (affects only you)": "URL-Vorschau für diesen Raum deaktivieren (betrifft nur dich)", - "Start automatically after system login": "Starte automatisch nach System-Login", + "Start automatically after system login": "Nach System-Login automatisch starten", "Desktop specific": "Desktopspezifisch", "Jump to first unread message.": "Zur ersten ungelesenen Nachricht springen.", "Options": "Optionen", "disabled": "deaktiviert", "enabled": "aktiviert", "Invited": "Eingeladen", - "Set a Display Name": "Setze einen Anzeigenamen", + "Set a Display Name": "Anzeigenamen festlegen", "for %(amount)ss": "für %(amount)ss", "for %(amount)sm": "seit %(amount)smin", "for %(amount)sh": "für %(amount)sh", @@ -974,5 +974,7 @@ "Authentication check failed: incorrect password?": "Authentifizierung fehlgeschlagen: Falsches Passwort?", "Disable Peer-to-Peer for 1:1 calls": "Peer-to-Peer-Verbindung für 1-zu-1-Anrufe deaktivieren", "Do you want to set an email address?": "Möchtest du eine E-Mail-Adresse setzen?", - "This will allow you to reset your password and receive notifications.": "Dies erlaubt dir dein Passwort zurückzusetzen und Benachrichtigungen zu empfangen." + "This will allow you to reset your password and receive notifications.": "Dies erlaubt dir dein Passwort zurückzusetzen und Benachrichtigungen zu empfangen.", + "Press to start a chat with someone": "Klicke auf um einen Chat mit jemanden zu starten", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Du bist bisher in keinem Raum! Klicke auf um einen Raum zu erstellen oder um das Verzeichnis zu durchsuchen" } diff --git a/src/i18n/strings/el.json b/src/i18n/strings/el.json index cdfb558f3a..4e09fd7f2a 100644 --- a/src/i18n/strings/el.json +++ b/src/i18n/strings/el.json @@ -914,5 +914,7 @@ "were unbanned %(repeats)s times": "ξεμπλοκαρίστηκαν %(repeats)s φορές", "was unbanned %(repeats)s times": "ξεμπλοκαρίστηκε %(repeats)s φορές", "were unbanned": "ξεμπλοκαρίστηκαν", - "was unbanned": "ξεμπλοκαρίστηκε" + "was unbanned": "ξεμπλοκαρίστηκε", + "Press to start a chat with someone": "Πατήστε για να ξεκινήσετε μια συνομιλία", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Δεν είστε σε κανένα δωμάτιο! Πατήστε για να δημιουργήσετε ένα δωμάτιο ή για να δείτε το ευρετήριο" } diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 0d33ad711f..039198f0cf 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -557,7 +557,7 @@ "You're not in any rooms yet! Press": "Vous n’êtes dans aucun salon ! Cliquez", "You are trying to access %(roomName)s.": "Vous essayez d'accéder à %(roomName)s.", "You cannot place a call with yourself.": "Vous ne pouvez pas passer d'appel avec vous-même.", - "You cannot place VoIP calls in this browser.": "Vous ne pouvez pas passer d'appel voix dans cet explorateur.", + "You cannot place VoIP calls in this browser.": "Vous ne pouvez pas passer d'appel vocal dans ce navigateur.", "You do not have permission to post to this room": "Vous n’avez pas la permission de poster dans ce salon", "You have been invited to join this room by %(inviterName)s": "Vous avez été invité à joindre ce salon par %(inviterName)s", "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Vous avez été déconnecté de tous vos appareils et ne recevrez plus de notifications. Pour réactiver les notifications, identifiez vous à nouveau sur tous les appareils", @@ -922,5 +922,7 @@ "Authentication check failed: incorrect password?": "Erreur d’identification: mot de passe incorrect ?", "Disable Peer-to-Peer for 1:1 calls": "Désactiver les appels 1:1 pair-à-pair", "Do you want to set an email address?": "Souhaitez-vous configurer une adresse e-mail ?", - "This will allow you to reset your password and receive notifications.": "Ceci va vous permettre de réinitialiser votre mot de passe et de recevoir des notifications." + "This will allow you to reset your password and receive notifications.": "Ceci va vous permettre de réinitialiser votre mot de passe et de recevoir des notifications.", + "Press to start a chat with someone": "Cliquez sur pour entamer une discussion avec quelqu'un", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Vous n'avez pas encore rejoint de salle ! Cliquez sur pour créer une salle ou sur pour explorer l'annuaire" } diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 696a548b4a..f2fa3bb63e 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -508,5 +508,175 @@ "%(senderDisplayName)s sent an image.": "%(senderDisplayName)s képet küldött.", "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s meghívót küldött %(targetDisplayName)s felhasználónak, hogy lépjen be a szobába.", "sent a video": "videó küldve", - "Server error": "Szerver hiba" + "Server error": "Szerver hiba", + "Server may be unavailable or overloaded": "A szerver elérhetetlen vagy túlterhelt", + "Server may be unavailable, overloaded, or search timed out :(": "A szerver elérhetetlen, túlterhelt vagy a keresés túllépte az időkorlátot :(", + "Server may be unavailable, overloaded, or the file too big": "A szerver elérhetetlen, túlterhelt vagy a fájl túl nagy", + "Server may be unavailable, overloaded, or you hit a bug.": "A szerver elérhetetlen, túlterhelt vagy hibára futott.", + "Server unavailable, overloaded, or something else went wrong.": "A szerver elérhetetlen, túlterhelt vagy valami más probléma van.", + "Session ID": "Kapcsolat azonosító", + "%(senderName)s set a profile picture.": "%(senderName)s profil képet állított be.", + "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s a megjelenítési nevét megváltoztatta erre: %(displayName)s.", + "Set": "Beállít", + "Show panel": "Panel megjelenítése", + "Show Text Formatting Toolbar": "Szöveg formázási eszköztár megjelenítése", + "Show timestamps in 12 hour format (e.g. 2:30pm)": "Az időbélyegek 12 órás formátumban mutatása (pl.: 2:30pm)", + "Signed Out": "Kijelentkezett", + "Sign in": "Bejelentkezett", + "Sign out": "Kijelentkezés", + "since the point in time of selecting this option": "onnantól, hogy ez az opció kiválasztásra került", + "since they joined": "onnantól, hogy csatlakozott", + "since they were invited": "onnantól, hogy meg lett hívva", + "Some of your messages have not been sent.": "Néhány üzeneted nem lett elküldve.", + "Someone": "Valaki", + "Sorry, this homeserver is using a login which is not recognised ": "Bocs, ez a saját szerver olyan beléptetést használ ami nem ismert ", + "Start a chat": "Csevegés indítása", + "Start authentication": "Azonosítás indítása", + "Start Chat": "Csevegés indítása", + "Submit": "Elküld", + "Success": "Sikeres", + "tag as %(tagName)s": "címke beállítása: %(tagName)s", + "tag direct chat": "megjelölés közvetlen csevegésnek", + "Tagged as: ": "Címkék: ", + "The default role for new room members is": "Az alapértelmezett szerep új tagoknak:", + "The main address for this room is": "A szoba elsődleges címe:", + "The phone number entered looks invalid": "A megadott telefonszám érvénytelennek tűnik", + "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Az általad megadott aláíró kulcs megegyezik %(userId)s felhasználótól kapott kulccsal amit %(deviceId)s eszközhöz használ. Az eszköz ellenőrzöttnek jelölve.", + "This action cannot be performed by a guest user. Please register to be able to do this.": "Ezt nem teheti vendég felhasználó. Kérlek regisztrálj, hogy megtehesd.", + "This email address is already in use": "Ez az e-mail cím már használatban van", + "This email address was not found": "Az e-mail cím nem található", + "%(actionVerb)s this person?": "Ezt a felhasználót %(actionVerb)s?", + "The email address linked to your account must be entered.": "A fiókodhoz kötött e-mail címet add meg.", + "Press to start a chat with someone": "Nyomd meg a gombot ha szeretnél csevegni valakivel", + "Privacy warning": "Magánéleti figyelmeztetés", + "The file '%(fileName)s' exceeds this home server's size limit for uploads": "'%(fileName)s' fájl túllépte az egyedi szerverben beállított feltöltési méret határt", + "The file '%(fileName)s' failed to upload": "'%(fileName)s' fájl feltöltése sikertelen", + "The remote side failed to pick up": "A hívott fél nem vette fel", + "This Home Server does not support login using email address.": "Az egyedi szerver nem támogatja a belépést e-mail címmel.", + "This invitation was sent to an email address which is not associated with this account:": "A meghívó olyan e-mail címre lett küldve ami nincs összekötve ezzel a fiókkal:", + "There was a problem logging in.": "Hiba történt a bejelentkezésnél.", + "This room has no local addresses": "Ennek a szobának nincs helyi címe", + "This room is not recognised.": "Ez a szoba nem ismerős.", + "These are experimental features that may break in unexpected ways": "Ezek kísérleti funkciók amik kiszámíthatatlanok lehetnek", + "The visibility of existing history will be unchanged": "A már meglévő csevegés előzmények láthatósága nem változik", + "This doesn't appear to be a valid email address": "Ez nem tűnik helyes e-mail címnek", + "This is a preview of this room. Room interactions have been disabled": "Ez a szoba előnézete. Minden tevékenység ezzel a szobával ki van kapcsolva", + "This phone number is already in use": "Ez a telefonszám már használatban van", + "This room": "Ez a szoba", + "This room is not accessible by remote Matrix servers": "Ez a szoba távoli Matrix szerverről nem érhető el", + "This room's internal ID is": "A szoba belső azonosítója:", + "times": "alkalommal", + "To ban users": "Felhasználó kizárásához", + "to browse the directory": "a könyvtárban való kereséshez", + "To configure the room": "A szoba beállításához", + "to favourite": "kedvencekhez", + "To invite users into the room": "Felhasználó szobába való meghívásához", + "To kick users": "Felhasználó kirúgásához", + "To link to a room it must have an address.": "Szobához való kötéshez szükséges egy cím.", + "to make a room or": "szoba létrehozásához vagy", + "To remove other users' messages": "Más felhasználók üzeneteinek törléséhez", + "To reset your password, enter the email address linked to your account": "A jelszó alaphelyzetbe állításához add meg a fiókodhoz kötött e-mail címet", + "to restore": "visszaállításhoz", + "To send events of type": "Az alábbi típusú üzenetek küldéséhez", + "To send messages": "Üzenetek küldéséhez", + "to start a chat with someone": "csevegés indításához valakivel", + "to tag as %(tagName)s": "megjelölni mint: %(tagName)s", + "to tag direct chat": "megjelölni közvetlen csevegésnek", + "To use it, just wait for autocomplete results to load and tab through them.": "A használatához csak várd meg az automatikus kiegészítéshez a találatok betöltését és TAB-bal választhatsz közülük.", + "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Megpróbáltam betölteni a szoba megadott időpontjának megfelelő adatait, de nincs jogod a kérdéses üzenetek megjelenítéséhez.", + "Tried to load a specific point in this room's timeline, but was unable to find it.": "Megpróbáltam betölteni a szoba megadott időpontjának megfelelő adatait, de nem találom.", + "Turn Markdown off": "Markdown kikapcsolása", + "Turn Markdown on": "Markdown bekapcsolása", + "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s bekapcsolta a titkosítást végponttól végpontig (algoritmus %(algorithm)s).", + "Unable to add email address": "Az e-mail címet nem sikerült hozzáadni", + "Unable to remove contact information": "A névjegy információkat nem sikerült törölni", + "Unable to restore previous session": "Az előző kapcsolat visszaállítása sikertelen", + "Unable to verify email address.": "Az e-mail cím ellenőrzése sikertelen.", + "Unban": "Kitiltás visszavonása", + "%(senderName)s unbanned %(targetName)s.": "%(senderName)s visszaengedte %(targetName)s felhasználót.", + "Unable to capture screen": "A képernyő felvétele sikertelen", + "Unable to enable Notifications": "Az értesítések engedélyezése sikertelen", + "Unable to load device list": "Az eszközlista betöltése sikertelen", + "Undecryptable": "Visszafejthetetlen", + "Unencrypted room": "Titkosítatlan szoba", + "unencrypted": "titkosítatlan", + "Unencrypted message": "Titkosítatlan üzenet", + "unknown caller": "ismeretlen hívó", + "Unknown command": "Ismeretlen parancs", + "unknown device": "ismeretlen eszköz", + "Unknown room %(roomId)s": "Ismeretlen szoba %(roomId)s", + "Unknown (user, device) pair:": "Ismeretlen (felhasználó, eszköz) pár:", + "unknown": "ismeretlen", + "Unmute": "Némítás kikapcsolása", + "Unnamed Room": "Névtelen szoba", + "Unrecognised command:": "Ismeretlen parancs:", + "Unrecognised room alias:": "Ismeretlen szoba becenév:", + "Unverified": "Nem ellenőrzött", + "Uploading %(filename)s and %(count)s others.zero": "%(filename)s feltöltése", + "Uploading %(filename)s and %(count)s others.one": "%(filename)s és még %(count)s db másik feltöltése", + "Uploading %(filename)s and %(count)s others.other": "%(filename)s és még %(count)s db másik feltöltése", + "uploaded a file": "fájl feltöltése", + "Upload avatar": "Avatar kép feltöltése", + "Upload Failed": "Feltöltés sikertelen", + "Upload Files": "Fájlok feltöltése", + "Upload file": "Fájl feltöltése", + "Upload new:": "Új feltöltése:", + "Usage": "Használat", + "Use compact timeline layout": "Egyszerű idővonal séma használata", + "Use with caution": "Használd körültekintéssel", + "User ID": "Felhasználói azonosító", + "User Interface": "Felhasználói felület", + "%(user)s is a": "%(user)s egy", + "User name": "Felhasználói név", + "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (szint: %(powerLevelNumber)s)", + "Username invalid: %(errMessage)s": "Felhasználói név érvénytelen: %(errMessage)s", + "Users": "Felhasználók", + "User": "Felhasználó", + "Verification Pending": "Ellenőrzés függőben", + "Verification": "Ellenőrzés", + "verified": "ellenőrizve", + "Verified": "Ellenőrizve", + "Verified key": "Ellenőrzött kulcs", + "Video call": "Videó hívás", + "Voice call": "Hang hívás", + "VoIP conference finished.": "VoIP konferencia befejeződött.", + "VoIP conference started.": "VoIP konferencia elkezdődött.", + "VoIP is unsupported": "VoIP nem támogatott", + "(could not connect media)": "(média kapcsolat nem hozható létre)", + "(no answer)": "(nincs válasz)", + "(unknown failure: %(reason)s)": "(ismeretlen hiba: %(reason)s)", + "(warning: cannot be disabled again!)": "(figyelmeztetés: nem lehet újra kikapcsolni!)", + "Warning!": "Figyelem!", + "WARNING: Device already verified, but keys do NOT MATCH!": "Figyelem: Az eszköz már ellenőrzött, de a kulcsok NEM EGYEZNEK!", + "Who can access this room?": "Ki éri el ezt a szobát?", + "Who can read history?": "Ki olvashatja a régi üzeneteket?", + "Who would you like to add to this room?": "Kit szeretnél hozzáadni ehhez a szobához?", + "Who would you like to communicate with?": "Kivel szeretnél beszélgetni?", + "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s visszavonta %(targetName)s meghívóját.", + "Would you like to accept or decline this invitation?": "Ezt a meghívót szeretnéd elfogadni vagy elutasítani?", + "You already have existing direct chats with this user:": "Már van közvetlen csevegésed ezzel a felhasználóval:", + "You are already in a call.": "Már hívásban vagy.", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Még egyetlen szobába sem léptél be! Szoba létrehozáshoz nyomd meg: vagy a szobák közötti kereséshez nyomd meg: ", + "You are trying to access %(roomName)s.": "%(roomName)s szobába próbálsz belépni.", + "You cannot place a call with yourself.": "Nem hívhatod fel saját magadat.", + "You cannot place VoIP calls in this browser.": "Nem indíthatsz VoIP hívást ebben a böngészőben.", + "You do not have permission to post to this room": "Nincs jogod írni ebben a szobában", + "You have been banned from %(roomName)s by %(userName)s.": "%(userName)s kitiltott a szobából: %(roomName)s.", + "You have been invited to join this room by %(inviterName)s": "%(inviterName)s meghívott ebbe a szobába", + "You have been kicked from %(roomName)s by %(userName)s.": "%(userName)s kirúgott ebből a szobából: %(roomName)s.", + "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Kijelentkeztél minden eszközről így nem fogsz \"push\" értesítéseket kapni. Az értesítések engedélyezéséhez jelentkezz vissza mindegyik eszközön", + "You have disabled URL previews by default.": "Az URL előnézet alapból tiltva van.", + "You have enabled URL previews by default.": "Az URL előnézet alapból engedélyezve van.", + "You have entered an invalid contact. Try using their Matrix ID or email address.": "Érvénytelen kapcsolatot adtál meg. Próbáld meg a Matrix azonosítóját vagy e-mail címét használni.", + "You have no visible notifications": "Nincsenek látható értesítéseid", + "You may wish to login with a different account, or add this email to this account.": "Lehet, hogy más fiókba szeretnél belépni vagy ezt az e-mail címet szeretnéd ehhez a fiókhoz kötni.", + "you must be a": "szükséges szerep:", + "You must register to use this functionality": "Regisztrálnod kell hogy ezt használhasd", + "You need to be able to invite users to do that.": "Hogy ezt csinálhasd meg kell tudnod hívni felhasználókat.", + "You need to be logged in.": "Be kell jelentkezz.", + "You need to enter a user name.": "Be kell írnod a felhasználói nevet.", + "You need to log back in to generate end-to-end encryption keys for this device and submit the public key to your homeserver. This is a once off; sorry for the inconvenience.": "Ahhoz, hogy kulcsot tudjál készíteni a végponttól végpontig való titkosításhoz ehhez az eszközhöz és elküld a kulcsot a egyéni szerverhez vissza kell jelentkezned. Ez egyszeri alkalom, elnézést a kellemetlenségér.", + "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Ez az e-mail cím, úgy néz ki, nincs összekötve a Matrix azonosítóval ezen az egyedi szerveren.", + "Your password has been reset": "A jelszavad visszaállítottuk", + "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "A jelszavadat sikeresen megváltoztattuk. Nem kapsz \"push\" értesítéseket amíg a többi eszközön vissza nem jelentkezel" } diff --git a/src/i18n/strings/ko.json b/src/i18n/strings/ko.json index f7f0654276..c2969ad966 100644 --- a/src/i18n/strings/ko.json +++ b/src/i18n/strings/ko.json @@ -651,5 +651,24 @@ "(unknown failure: %(reason)s)": "(알 수 없는 오류: %(reason)s)", "(warning: cannot be disabled again!)": "(주의: 다시 끌 수 없어요!)", "Warning!": "주의!", - "WARNING: Device already verified, but keys do NOT MATCH!": "주의: 장치는 이미 인증했지만, 키가 맞지 않아요!" + "WARNING: Device already verified, but keys do NOT MATCH!": "주의: 장치는 이미 인증했지만, 키가 맞지 않아요!", + "Who can access this room?": "누가 이 방에 들어올 수 있나요?", + "Who can read history?": "누가 기록을 읽을 수 있나요?", + "Who would you like to add to this room?": "이 방에 누구를 초대하고 싶으세요?", + "Who would you like to communicate with?": "누구와 이야기하고 싶으세요?", + "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s님이 %(targetName)s니의 초대를 취소하셨어요.", + "Would you like to accept or decline this invitation?": "초대를 받아들이거나 거절하시겠어요?", + "You already have existing direct chats with this user:": "이미 이 사용자와 직접 이야기하는 중이에요:", + "You are already in a call.": "이미 자신이 통화 중이네요.", + "You're not in any rooms yet! Press": "어떤 방에도 들어가 있지 않으세요! 누르세요", + "Press to start a chat with someone": "다른 사람과 이야기하려면 을 누르세요", + "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "주의: 키 확인 실패! %(userId)s와 장치 %(deviceId)s의 서명 키 \"%(fprint)s\"는 주어진 키 \"%(fingerprint)s\"와 맞지 않아요. 누가 이야기를 가로채는 중일 수도 있어요!", + "You're not in any rooms yet! Press to make a room or to browse the directory": "어떤 방에도 들어가 있지 않으세요! 을 눌러서 방을 만들거나 를 눌러 목록에서 방을 찾아보세요", + "You are trying to access %(roomName)s.": "%(roomName)s에 들어가려고 하는 중이에요.", + "You cannot place a call with yourself.": "자신에게 전화를 걸 수는 없어요.", + "You cannot place VoIP calls in this browser.": "이 브라우저에서는 인터넷전화를 걸 수 없어요.", + "You do not have permission to post to this room": "이 방에서 글을 올릴 권한이 없어요", + "You have been banned from %(roomName)s by %(userName)s.": "%(userName)s님이 %(roomName)s에서 차단하셨어요.", + "You have been invited to join this room by %(inviterName)s": "%(inviterName)s님이 이 방에 초대하셨어요", + "You have been kicked from %(roomName)s by %(userName)s.": "%(userName)s님이 %(roomName)s에서 추방하셨어요." } diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index e7a9f6e4b6..eae3d7bc87 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -234,7 +234,7 @@ "Mute": "Dempen", "Notifications": "Meldingen", "Operation failed": "Actie mislukt", - "Please Register": "Registreer alstublieft", + "Please Register": "Registreer Alstublieft", "powered by Matrix": "mogelijk gemaakt door Matrix", "Remove": "Verwijderen", "Room directory": "Kamerlijst", @@ -279,10 +279,10 @@ "%(senderName)s placed a %(callType)s call.": "%(senderName)s heeft een %(callType)s-gesprek gestart.", "Press": "Druk", "Privacy warning": "Privacywaarschuwing", - "Private Chat": "Direct chatten", + "Private Chat": "Privégesprek", "Privileged Users": "Gebruikers met rechten", "Profile": "Profiel", - "Public Chat": "Publiek gesprek", + "Public Chat": "Publiek Gesprek", "Reason": "Reden", "Reason: %(reasonText)s": "Reden: %(reasonText)s", "Revoke Moderator": "Beheerder terugtrekken", @@ -291,9 +291,9 @@ "rejected": "verworpen", "%(targetName)s rejected the invitation.": "%(targetName)s heeft de uitnodiging geweigerd.", "Reject invitation": "Uitnodiging weigeren", - "Rejoin": "Opnieuw lid wordne", + "Rejoin": "Opnieuw toetreden", "Remote addresses for this room:": "Adres op afstand voor deze ruimte:", - "Remove Contact Information?": "Contactinformatie verwijderen?", + "Remove Contact Information?": "Contactinformatie Verwijderen?", "Send Invites": "Uitnodigingen versturen", "Start a chat": "Gesprek starten", "Start authentication": "Authenticatie starten", @@ -502,5 +502,27 @@ "New Composer & Autocomplete": "Nieuwe Componist & Automatisch Aanvullen", "New passwords don't match": "Nieuwe wachtwoorden komen niet overeen", "New passwords must match each other.": "Nieuwe wachtwoorden moeten overeenkomen.", - "Once encryption is enabled for a room it cannot be turned off again (for now)": "Zodra versleuteling in een kamer is ingeschakeld kan het niet meer worden uitgeschakeld (voor nu)" + "Once encryption is enabled for a room it cannot be turned off again (for now)": "Zodra versleuteling in een kamer is ingeschakeld kan het niet meer worden uitgeschakeld (voor nu)", + "Once you've followed the link it contains, click below": "Zodra je de link dat het bevat hebt gevolgd, klik hieronder", + "Only people who have been invited": "Alleen personen die zijn uitgenodigd", + "Otherwise, click here to send a bug report.": "Klik anders hier om een foutmelding te versturen.", + "Please check your email and click on the link it contains. Once this is done, click continue.": "Bekijk je e-mail en klik op de link die het bevat. Zodra dit klaar is, klik op verder gaan.", + "Power level must be positive integer.": "Machtsniveau moet een positief heel getal zijn.", + "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s heeft zijn of haar weergavenaam (%(oldDisplayName)s) verwijderd.", + "%(senderName)s removed their profile picture.": "%(senderName)s heeft zijn of haar profielfoto verwijderd.", + "Failed to kick": "Niet gelukt om te kicken", + "Press to start a chat with someone": "Druk op om een gesprek met iemand te starten", + "Remove %(threePid)s?": "%(threePid)s verwijderen?", + "%(senderName)s requested a VoIP conference.": "%(senderName)s heeft een VoIP gesprek aangevraagd.", + "Report it": "Melden", + "Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Het wachtwoord veranderen betekent momenteel dat alle eind-tot-eind versleutelingssleutels op alle apparaten veranderen waardoor versleutelde gespreksgeschiedenis onleesbaar wordt, behalve als je eerst de ruimte sleutels exporteert en daarna opnieuw importeert. Dit zal in de toekomst verbeterd worden.", + "restore": "herstellen", + "Results from DuckDuckGo": "Resultaten van DuckDuckGo", + "Return to app": "Naar de app terugkeren", + "Return to login screen": "Naar het inlogscherm terugkeren", + "Riot does not have permission to send you notifications - please check your browser settings": "Riot heeft geen permissie om je notificaties te versturen - controleer je browser instellingen", + "Riot was not given permission to send notifications - please try again": "Riot heeft geen permissie gekregen om notificaties te versturen - probeer het opnieuw", + "riot-web version:": "riot-web versie:", + "Room %(roomId)s not visible": "Ruimte %(roomId)s is niet zichtbaar", + "Room Colour": "Ruimte Kleur" } diff --git a/src/i18n/strings/pt_BR.json b/src/i18n/strings/pt_BR.json index b7ea693a50..1e915a5491 100644 --- a/src/i18n/strings/pt_BR.json +++ b/src/i18n/strings/pt_BR.json @@ -961,5 +961,14 @@ "Your home server does not support device management.": "O seu Servidor de Base não suporta o gerenciamento de dispositivos.", "(~%(count)s results).one": "(~%(count)s resultado)", "(~%(count)s results).other": "(~%(count)s resultados)", - "Device Name": "Nome do dispositivo" + "Device Name": "Nome do dispositivo", + "(could not connect media)": "(não foi possível conectar-se à mídia)", + "(no answer)": "(sem resposta)", + "(unknown failure: %(reason)s)": "(falha desconhecida: %(reason)s)", + "Your browser does not support the required cryptography extensions": "O seu navegador não suporta as extensões de criptografia necessárias", + "Not a valid Riot keyfile": "Não é um arquivo de chaves Riot válido", + "Authentication check failed: incorrect password?": "Falha ao checar a autenticação: senha incorreta?", + "Disable Peer-to-Peer for 1:1 calls": "Desabilitar as chamadas 1:1 par-a-par", + "Do you want to set an email address?": "Você deseja definir um endereço de e-mail?", + "This will allow you to reset your password and receive notifications.": "Isso permitirá que você redefina sua senha e receba notificações." } diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index d69282a07e..6b6eadf928 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -85,7 +85,7 @@ "Favourite": "Избранное", "favourite": "Избранное", "Favourites": "Избранное", - "Filter room members": "Фильтр участников комнаты", + "Filter room members": "Поиск участников комнаты", "Forget room": "Забыть комнату", "Forgot your password?": "Вы забыли пароль?", "For security, this session has been signed out. Please sign in again.": "Для обеспечения безопасности эта сессия была завершена. Войдите в систему еще раз.", @@ -100,14 +100,14 @@ "Invalid Email Address": "Недействительный адрес электронной почты", "invited": "invited", "Invite new room members": "Пригласить новых участников в комнату", - "Invites": "Приглашать", - "Invites user with given id to current room": "Пригласить пользователя с данным ID в текущую комнату", + "Invites": "Приглашает", + "Invites user with given id to current room": "Приглашает пользователя с этим ID в текущую комнату", "is a": "является", "Sign in with": "Я хочу регистрироваться с", - "joined and left": "присоединенный и оставленный", - "joined": "присоединенный", + "joined and left": "зашёл и ушёл", + "joined": "зашёл", "joined the room": "joined the room", - "Joins room with given alias": "Присоединяется к комнате с данным псевдонимом", + "Joins room with given alias": "зашёл в комнату с этим именем", "Kicks user with given id": "Выгнать пользователя с заданным id", "Labs": "Лаборатория", "Leave room": "Уйти из комнаты", @@ -116,7 +116,7 @@ "left the room": "left the room", "Logged in as": "Зарегистрированный как", "Login as guest": "Вход в систему как гость", - "Logout": "Выход из системы", + "Logout": "Выйти", "Low priority": "Низкий приоритет", "made future room history visible to": "made future room history visible to", "Manage Integrations": "Управление Интеграциями", @@ -128,7 +128,7 @@ "Never send encrypted messages to unverified devices from this device": "Никогда не отправлять зашифрованные сообщения на не верифицированные устройства с этого устройства", "Never send encrypted messages to unverified devices in this room from this device": "Никогда не отправляйте зашифрованные сообщения на непроверенные устройства в этой комнате из вашего устройства", "New password": "Новый пароль", - "New passwords must match each other.": "Новые пароли должны соответствовать друг другу.", + "New passwords must match each other.": "Новые пароли должны совпадать.", "none": "никто", "Notifications": "Уведомления", " (not supported by this browser)": " (not supported by this browser)", @@ -193,7 +193,7 @@ "(warning: cannot be disabled again!)": "(предупреждение: не может быть отключено!)", "Warning!": "Предупреждение!", "was banned": "запрещен", - "was invited": "приглашенный", + "was invited": "был приглашён", "was kicked": "выброшен", "was unbanned": "незапрещенный", "was": "был", @@ -650,10 +650,10 @@ "%(oneUser)schanged their avatar": "%(oneUser)sизменил своё изображение", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Не возможно подключиться к серверу через HTTP, когда в строке браузера HTTPS. Используйте HTTPS или включив небезопасные скрипты.", "Dismiss": "Отказ", - "Custom Server Options": "Расширенные настройки сервера", + "Custom Server Options": "Собственные настройки сервера", "Mute": "Беззвучный", "Operation failed": "Действие не удалось", - "powered by Matrix": "управляемый с Matrix", + "powered by Matrix": "Основано на Matrix", "Add a topic": "Добавить тему", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Время отображать в 12 часовом формате (напр. 2:30pm)", "Use compact timeline layout": "Компактное отображение", @@ -700,7 +700,7 @@ "Import": "Импорт", "Incorrect username and/or password.": "Неверное имя пользователя и/или пароль.", "Invalid file%(extra)s": "Неправильный файл%(extra)s", - "Invited": "Приглашен", + "Invited": "Приглашён", "Jump to first unread message.": "Перейти к первому непрочитанному сообщению.", "List this room in %(domain)s's room directory?": "Показывать эту комнату в списке комнат %(domain)s?", "Message not sent due to unknown devices being present": "Сообщение не было отправлено из-за присутствия неизвестного устройства", @@ -896,7 +896,7 @@ "Admin tools": "Админ утилита", "And %(count)s more...": "И %(count)s больше...", "Alias (optional)": "Псевдоним (опционально)", - "Click here to join the discussion!": " Нажми здесь чтоб присоединиться к обсуждению!", + "Click here to join the discussion!": "Нажмите здесь, чтобы присоединиться к обсуждению!", "Close": "Закрыть", "Disable Notifications": "Отключить оповещение", "Drop File Here": "Вставить сюда файл", @@ -909,7 +909,7 @@ "Incoming call from %(name)s": "Входящий вызов от %(name)s", "Incoming video call from %(name)s": "Входящий видио вызов от %(name)s", "Incoming voice call from %(name)s": "Входящий голосовой вызов от %(name)s", - "Join as voice or video.": "Присоединен как голос или видио .", + "Join as voice or video.": "Войти как голос или видео.", "Last seen": "В последний раз видели", "Level:": "Уровень:", "No display name": "Нет отображаемое имя", @@ -958,5 +958,7 @@ "Your browser does not support the required cryptography extensions": "Ваш браузер не поддерживает требуемые расширения для криптографии", "Authentication check failed: incorrect password?": "Ошибка авторизации: неверный пароль?", "Do you want to set an email address?": "Вы хотите указать адрес электронной почты?", - "This will allow you to reset your password and receive notifications.": "Это позволит вам сбросить пароль и получить уведомления." + "This will allow you to reset your password and receive notifications.": "Это позволит вам сбросить пароль и получить уведомления.", + "Press to start a chat with someone": "Нажмите для начала чата с кем либо", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Вы еще не в комнатах! Нажмите , чтобы создать комнату или , чтобы просмотреть каталог" } From e16d1b3cfb345fbef76dddb5210870c00fa3f44e Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 20 Jun 2017 11:22:07 +0100 Subject: [PATCH 14/20] Implement password nag warning in user settings account section "To return to your account in future you need to set a password" in the account section when a user has not yet set a password (is a PWLU). --- src/components/structures/UserSettings.js | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index fc13f0bdcf..58ae46e18a 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -21,6 +21,7 @@ const MatrixClientPeg = require("../../MatrixClientPeg"); const PlatformPeg = require("../../PlatformPeg"); const Modal = require('../../Modal'); const dis = require("../../dispatcher"); +import sessionStore from '../../stores/SessionStore'; const q = require('q'); const packageJson = require('../../../package.json'); const UserSettingsStore = require('../../UserSettingsStore'); @@ -243,6 +244,12 @@ module.exports = React.createClass({ this.setState({ language: languageHandler.getCurrentLanguage(), }); + + this._sessionStore = sessionStore; + this._sessionStoreToken = this._sessionStore.addListener( + this._setStateFromSessionStore, + ); + this._setStateFromSessionStore(); }, componentDidMount: function() { @@ -269,6 +276,12 @@ module.exports = React.createClass({ } }, + _setStateFromSessionStore: function() { + this.setState({ + userHasGeneratedPassword: Boolean(this._sessionStore.getCachedPassword()), + }); + }, + _electronSettings: function(ev, settings) { this.setState({ electron_settings: settings }); }, @@ -1201,7 +1214,12 @@ module.exports = React.createClass({

{ _t("Account") }

- + { this.state.userHasGeneratedPassword ? +
+ Warning + { _t("To return to your account in future you need to set a password") } +
: null + } { _t("Sign out") } From e15aedfeb2fad2f0d2b17b93aefa96eae1cdbd69 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 20 Jun 2017 12:03:37 +0100 Subject: [PATCH 15/20] Fix another infinite spin on register Don't set ready on logging_in, set it before we start the client, as commented --- src/components/structures/MatrixChat.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index e1a491d6f5..ef6260c5b9 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -533,12 +533,10 @@ module.exports = React.createClass({ break; case 'on_logging_in': // We are now logging in, so set the state to reflect that - // and also that we're not ready (we'll be marked as logged - // in once the login completes, then ready once the sync - // completes). + // NB. This does not touch 'ready' since if our dispatches + // are delayed, the sync could already have completed this.setStateForNewView({ view: VIEWS.LOGGING_IN, - ready: false, }); break; case 'on_logged_in': @@ -1012,6 +1010,10 @@ module.exports = React.createClass({ */ _onWillStartClient() { const self = this; + // if the client is about to start, we are, by definition, not ready. + // Set ready to false now, then it'll be set to true when the sync + // listener we set below fires. + this.setState({ready: false}); const cli = MatrixClientPeg.get(); // Allow the JS SDK to reap timeline events. This reduces the amount of From 61c538485548001aa44844fbc0258cd1a7d3345b Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 20 Jun 2017 12:03:37 +0100 Subject: [PATCH 16/20] Fix another infinite spin on register Don't set ready on logging_in, set it before we start the client, as commented --- src/components/structures/MatrixChat.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 7b1855b678..e5aefdf665 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -500,10 +500,9 @@ module.exports = React.createClass({ break; case 'on_logging_in': // We are now logging in, so set the state to reflect that - // and also that we're not ready (we'll be marked as logged - // in once the login completes, then ready once the sync - // completes). - this.setState({loggingIn: true, ready: false}); + // NB. This does not touch 'ready' since if our dispatches + // are delayed, the sync could already have completed + this.setState({loggingIn: true}); break; case 'on_logged_in': this._onLoggedIn(payload.teamToken); @@ -989,6 +988,10 @@ module.exports = React.createClass({ */ _onWillStartClient() { const self = this; + // if the client is about to start, we are, by definition, not ready. + // Set ready to false now, then it'll be set to true when the sync + // listener we set below fires. + this.setState({ready: false}); const cli = MatrixClientPeg.get(); // Allow the JS SDK to reap timeline events. This reduces the amount of From 3f5a6236bb0b31339417b3859753b393c6a466de Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 20 Jun 2017 13:08:05 +0100 Subject: [PATCH 17/20] Prepare changelog for v0.9.6 --- CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b4210ac07..22049b6af6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +Changes in [0.9.6](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.9.6) (2017-06-20) +=================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.9.5...v0.9.6) + + * Fix infinite spinner on email registration + [\#1120](https://github.com/matrix-org/matrix-react-sdk/pull/1120) + * Translate help promots in room list + [\#1121](https://github.com/matrix-org/matrix-react-sdk/pull/1121) + * Internationalise the drop targets + [\#1122](https://github.com/matrix-org/matrix-react-sdk/pull/1122) + * Fix another infinite spin on register + [\#1124](https://github.com/matrix-org/matrix-react-sdk/pull/1124) + + Changes in [0.9.5](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.9.5) (2017-06-19) =================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.9.5-rc.2...v0.9.5) From 529e014739da87e21448b3091a1fc92e037821a5 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 20 Jun 2017 13:08:06 +0100 Subject: [PATCH 18/20] v0.9.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0e8c948973..f49fc04661 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.9.5", + "version": "0.9.6", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From 5b6daba18250c6ddf47209e28c6cea01351c4d42 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 20 Jun 2017 13:33:18 +0100 Subject: [PATCH 19/20] Add en_EN translations --- 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 ad00ea9275..c01f5c1aad 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -910,5 +910,6 @@ "Authentication check failed: incorrect password?": "Authentication check failed: incorrect password?", "Disable Peer-to-Peer for 1:1 calls": "Disable Peer-to-Peer for 1:1 calls", "Do you want to set an email address?": "Do you want to set an email address?", - "This will allow you to reset your password and receive notifications.": "This will allow you to reset your password and receive notifications." + "This will allow you to reset your password and receive notifications.": "This will allow you to reset your password and receive notifications.", + "To return to your account in future you need to set a password": "To return to your account in future you need to set a password" } From c337485d9081402bf0a2839daf48ae3f2922ba54 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 20 Jun 2017 15:01:53 +0100 Subject: [PATCH 20/20] Redesign the warning to be red text, move below "Sign out" --- src/components/structures/UserSettings.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 58ae46e18a..686e63cd75 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -1214,15 +1214,14 @@ module.exports = React.createClass({

{ _t("Account") }

- { this.state.userHasGeneratedPassword ? -
- Warning - { _t("To return to your account in future you need to set a password") } -
: null - } { _t("Sign out") } + { this.state.userHasGeneratedPassword ? +
+ { _t("To return to your account in future you need to set a password") } +
: null + } {accountJsx}