From 10017522e2556d85018b3a9ebaa165dd39916c0b Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 19 Dec 2016 17:59:13 +0000 Subject: [PATCH 0001/1160] Use correct 1-1 room avatar after users leave The correct 1-1 avatar is used with rooms in which there are only two users with either "join" or "invite" as their membership (importantly, not "leave" or otherwise). (This is important when a user moves accounts and re-joins previously left 1-1 chats) --- src/components/views/avatars/RoomAvatar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/avatars/RoomAvatar.js b/src/components/views/avatars/RoomAvatar.js index dcb25eff61..2bb6caddb7 100644 --- a/src/components/views/avatars/RoomAvatar.js +++ b/src/components/views/avatars/RoomAvatar.js @@ -86,7 +86,7 @@ module.exports = React.createClass({ var userIds = []; // for .. in optimisation to return early if there are >2 keys for (var uid in mlist) { - if (mlist.hasOwnProperty(uid)) { + if (mlist.hasOwnProperty(uid) && ["join", "invite"].includes(mlist[uid].membership)) { userIds.push(uid); } if (userIds.length > 2) { From 583f86eb06d7df4b49378ce7e2101311223b1104 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 19 Dec 2016 18:41:34 +0000 Subject: [PATCH 0002/1160] Handle the case where the other 1-1 user left --- src/components/views/avatars/RoomAvatar.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/components/views/avatars/RoomAvatar.js b/src/components/views/avatars/RoomAvatar.js index 2bb6caddb7..09a9e6c6c0 100644 --- a/src/components/views/avatars/RoomAvatar.js +++ b/src/components/views/avatars/RoomAvatar.js @@ -84,10 +84,15 @@ module.exports = React.createClass({ var mlist = props.room.currentState.members; var userIds = []; + var leftUserIds = []; // for .. in optimisation to return early if there are >2 keys for (var uid in mlist) { - if (mlist.hasOwnProperty(uid) && ["join", "invite"].includes(mlist[uid].membership)) { - userIds.push(uid); + if (mlist.hasOwnProperty(uid)) { + if (["join", "invite"].includes(mlist[uid].membership)) { + userIds.push(uid); + } else { + leftUserIds.push(uid); + } } if (userIds.length > 2) { return null; @@ -101,12 +106,21 @@ module.exports = React.createClass({ } else { theOtherGuy = mlist[userIds[0]]; } + return theOtherGuy.getAvatarUrl( MatrixClientPeg.get().getHomeserverUrl(), props.width, props.height, props.resizeMethod, false ); } else if (userIds.length == 1) { + // The other 1-1 user left, leaving just the current user, so show the left user's avatar + if (leftUserIds.length === 1) { + return mlist[leftUserIds[0]].getAvatarUrl( + MatrixClientPeg.get().getHomeserverUrl(), + props.width, props.height, props.resizeMethod, + false + ); + } return mlist[userIds[0]].getAvatarUrl( MatrixClientPeg.get().getHomeserverUrl(), props.width, props.height, props.resizeMethod, From 714b63519a8ebac1c58404236cd811f59259a905 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 20 Dec 2016 11:50:35 +0000 Subject: [PATCH 0003/1160] Remove empty line --- src/components/views/avatars/RoomAvatar.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/views/avatars/RoomAvatar.js b/src/components/views/avatars/RoomAvatar.js index 09a9e6c6c0..f5f42318eb 100644 --- a/src/components/views/avatars/RoomAvatar.js +++ b/src/components/views/avatars/RoomAvatar.js @@ -106,7 +106,6 @@ module.exports = React.createClass({ } else { theOtherGuy = mlist[userIds[0]]; } - return theOtherGuy.getAvatarUrl( MatrixClientPeg.get().getHomeserverUrl(), props.width, props.height, props.resizeMethod, From cb5c9f2c5ae34e019d34b121e1ee32ce4ab7c6c0 Mon Sep 17 00:00:00 2001 From: Stefan Parviainen Date: Wed, 29 Nov 2017 21:13:48 +0100 Subject: [PATCH 0004/1160] Make Dialogs more accessible Signed-off-by: Stefan Parviainen --- src/components/views/dialogs/BaseDialog.js | 8 ++++++-- src/components/views/dialogs/QuestionDialog.js | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index 295bb21ea1..aec9af4e98 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -45,6 +45,10 @@ export default React.createClass({ // children should be the content of the dialog children: React.PropTypes.node, + + // Id of content element + // If provided, this is used to add a aria-describedby attribute + contentId: React.PropTypes.string }, _onKeyDown: function(e) { @@ -69,13 +73,13 @@ export default React.createClass({ const TintableSvg = sdk.getComponent("elements.TintableSvg"); return ( -
+
-
+
{ this.props.title }
{ this.props.children } diff --git a/src/components/views/dialogs/QuestionDialog.js b/src/components/views/dialogs/QuestionDialog.js index 339b284e2f..db20fd00ed 100644 --- a/src/components/views/dialogs/QuestionDialog.js +++ b/src/components/views/dialogs/QuestionDialog.js @@ -66,6 +66,7 @@ export default React.createClass({
{ this.props.description } From 437a440bdfa17553e83e5d7e762b7494bb803ddb Mon Sep 17 00:00:00 2001 From: Stefan Parviainen Date: Thu, 30 Nov 2017 08:32:18 +0100 Subject: [PATCH 0005/1160] Add missing id Signed-off-by: Stefan Parviainen --- src/components/views/dialogs/QuestionDialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/dialogs/QuestionDialog.js b/src/components/views/dialogs/QuestionDialog.js index db20fd00ed..92051a0df7 100644 --- a/src/components/views/dialogs/QuestionDialog.js +++ b/src/components/views/dialogs/QuestionDialog.js @@ -68,7 +68,7 @@ export default React.createClass({ title={this.props.title} contentId='mx_Dialog_content' > -
+
{ this.props.description }
From 26c6c25a4cce7a87799ffd52ec86b41a418f6192 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Sun, 3 Dec 2017 11:23:44 +0000 Subject: [PATCH 0006/1160] Add dom-to-image dep. --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index b443b4c72a..dc526b7105 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "classnames": "^2.1.2", "commonmark": "^0.27.0", "counterpart": "^0.18.0", + "dom-to-image": "^2.6.0", "draft-js": "^0.11.0-alpha", "draft-js-export-html": "^0.6.0", "draft-js-export-markdown": "^0.3.0", From 3a89b90e57c7e2b13a2fe623e71495da2e0603ca Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Sun, 3 Dec 2017 11:25:15 +0000 Subject: [PATCH 0007/1160] Add stub handler for image snapshot --- src/components/views/elements/AppTile.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index a005406133..db722bd66d 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -221,6 +221,10 @@ export default React.createClass({ }, "mx_IntegrationsManager"); }, + _onSnapshotClick(e) { + console.log("Snapshot widget ID ", this.props.id); + }, + /* If user has permission to modify widgets, delete the widget, * otherwise revoke access for the widget to load in the user's browser */ @@ -379,11 +383,25 @@ export default React.createClass({ deleteClasses += ' mx_AppTileMenuBarWidgetDelete'; } + // Picture snapshot + const showPictureSnapshotButton = true; // FIXME - Make this dynamic + const showPictureSnapshotIcon = 'img/camera_green.svg'; + return (
{ this.formatAppTileName() } + { /* Snapshot widget */ } + { showPictureSnapshotButton && } + { /* Edit widget */ } { showEditButton && Date: Sun, 3 Dec 2017 19:44:59 +0000 Subject: [PATCH 0008/1160] Workings for future posterity - Can't access iframe content from parent. iframe needs to initiate. Postmessage data up the stack. --- src/components/structures/RoomView.js | 3 +++ src/components/views/elements/AppTile.js | 22 +++++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 1fda05fb76..cf3320b607 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -468,6 +468,9 @@ module.exports = React.createClass({ unsentMessageError: this._getUnsentMessageError(this.state.room), }); break; + case 'picture_snapshot': + this.uploadFile(payload.file); + break; case 'notifier_enabled': case 'upload_failed': case 'upload_started': diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index db722bd66d..a0eb7efe52 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -32,6 +32,7 @@ import AppWarning from './AppWarning'; import MessageSpinner from './MessageSpinner'; import WidgetUtils from '../../../WidgetUtils'; import dis from '../../../dispatcher'; +import domtoimage from 'dom-to-image'; const ALLOWED_APP_URL_SCHEMES = ['https:', 'http:']; @@ -222,7 +223,14 @@ export default React.createClass({ }, _onSnapshotClick(e) { - console.log("Snapshot widget ID ", this.props.id); + const iframe = this.refs.appFrame; + domtoimage.toPng(iframe).then(function(dataUrl) { + console.log("Image data URL:", dataUrl); + dis.dispatch({ + action: 'picture_snapshot', + file: dataURLtoBlob(dataUrl), + }, true); + }); }, /* If user has permission to modify widgets, delete the widget, @@ -428,3 +436,15 @@ export default React.createClass({ ); }, }); + +function dataURLtoBlob(dataurl) { + const arr = dataurl.split(','); + const mime = arr[0].match(/:(.*?);/)[1]; + const bstr = atob(arr[1]); + let n = bstr.length; + const u8arr = new Uint8Array(n); + while (n--) { + u8arr[n] = bstr.charCodeAt(n); + } + return new Blob([u8arr], {type: mime}); +} From 5ccbcf02e200aa8348a7415dda40a0c73e35937d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Sun, 3 Dec 2017 21:38:21 +0100 Subject: [PATCH 0009/1160] Several changes improving accessibility of the dialogs - Wrapped all the modals inside a react-focus-trap component disabling keyboard navigation outside the modal dialogs - Disabled our custom key handling at dialog level. Cancelling on esc key is now handled via FocusTrap component. - Removed onEnter prop from the BaseDialog component. Dialogs that submit data all now embed a form with onSubmit handler. And since keyboard focus is now managed better via FocusTrap it no longer makes sense for the other dialog types. Fixes https://github.com/vector-im/riot-web/issues/5736 - Set aria-hidden on the matrixChat outer node when showing dialogs to disable navigating outside the modals by using screen reader specific features. --- package.json | 1 + src/Modal.js | 6 +- src/components/views/dialogs/BaseDialog.js | 26 ++++----- .../views/dialogs/ConfirmUserActionDialog.js | 4 +- .../views/dialogs/CreateGroupDialog.js | 1 - .../views/dialogs/CreateRoomDialog.js | 57 +++++++++---------- .../views/dialogs/QuestionDialog.js | 1 - .../views/dialogs/TextInputDialog.js | 29 +++++----- 8 files changed, 60 insertions(+), 65 deletions(-) diff --git a/package.json b/package.json index b443b4c72a..46517230a7 100644 --- a/package.json +++ b/package.json @@ -78,6 +78,7 @@ "react": "^15.4.0", "react-addons-css-transition-group": "15.3.2", "react-dom": "^15.4.0", + "react-focus-trap": "^2.5.0", "react-gemini-scrollbar": "matrix-org/react-gemini-scrollbar#5e97aef", "sanitize-html": "^1.14.1", "text-encoding-utf-8": "^1.0.1", diff --git a/src/Modal.js b/src/Modal.js index 68d75d1ff1..daf66a37de 100644 --- a/src/Modal.js +++ b/src/Modal.js @@ -19,6 +19,7 @@ limitations under the License. const React = require('react'); const ReactDOM = require('react-dom'); +import FocusTrap from 'react-focus-trap'; import Analytics from './Analytics'; import sdk from './index'; @@ -164,6 +165,7 @@ class ModalManager { ); modal.onFinished = props ? props.onFinished : null; modal.className = className; + modal.closeDialog = closeDialog; this._modals.unshift(modal); @@ -194,9 +196,9 @@ class ModalManager { const modal = this._modals[0]; const dialog = (
-
+ { modal.elem } -
+
); diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index aec9af4e98..1f29f2d1f4 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -33,9 +33,6 @@ export default React.createClass({ // onFinished callback to call when Escape is pressed onFinished: React.PropTypes.func.isRequired, - // callback to call when Enter is pressed - onEnterPressed: React.PropTypes.func, - // CSS class to apply to dialog div className: React.PropTypes.string, @@ -51,17 +48,16 @@ export default React.createClass({ contentId: React.PropTypes.string }, - _onKeyDown: function(e) { - if (e.keyCode === KeyCode.ESCAPE) { - e.stopPropagation(); - e.preventDefault(); - this.props.onFinished(); - } else if (e.keyCode === KeyCode.ENTER) { - if (this.props.onEnterPressed) { - e.stopPropagation(); - e.preventDefault(); - this.props.onEnterPressed(e); - } + componentDidMount: function() { + this.applicationNode = document.getElementById('matrixchat'); + if (this.applicationNode) { + this.applicationNode.setAttribute('aria-hidden', 'true'); + } + }, + + componentWillUnmount: function() { + if (this.applicationNode) { + this.applicationNode.setAttribute('aria-hidden', 'false'); } }, @@ -73,7 +69,7 @@ export default React.createClass({ const TintableSvg = sdk.getComponent("elements.TintableSvg"); return ( -
+
diff --git a/src/components/views/dialogs/ConfirmUserActionDialog.js b/src/components/views/dialogs/ConfirmUserActionDialog.js index 78d084b709..1c246a580b 100644 --- a/src/components/views/dialogs/ConfirmUserActionDialog.js +++ b/src/components/views/dialogs/ConfirmUserActionDialog.js @@ -116,10 +116,10 @@ export default React.createClass({ return ( -
+
{ avatar }
diff --git a/src/components/views/dialogs/CreateGroupDialog.js b/src/components/views/dialogs/CreateGroupDialog.js index 168fe75947..8e262a6e51 100644 --- a/src/components/views/dialogs/CreateGroupDialog.js +++ b/src/components/views/dialogs/CreateGroupDialog.js @@ -116,7 +116,6 @@ export default React.createClass({ return (
diff --git a/src/components/views/dialogs/CreateRoomDialog.js b/src/components/views/dialogs/CreateRoomDialog.js index f7be47b3eb..f5a5f87b72 100644 --- a/src/components/views/dialogs/CreateRoomDialog.js +++ b/src/components/views/dialogs/CreateRoomDialog.js @@ -43,38 +43,37 @@ export default React.createClass({ const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); return ( -
-
- -
-
- -
-
- -
- { _t('Advanced options') } -
- - + +
+
+
-
-
-
- - -
+
+ +
+
+ +
+ { _t('Advanced options') } +
+ + +
+
+
+
+ + +
+ ); }, diff --git a/src/components/views/dialogs/QuestionDialog.js b/src/components/views/dialogs/QuestionDialog.js index 92051a0df7..41733470a1 100644 --- a/src/components/views/dialogs/QuestionDialog.js +++ b/src/components/views/dialogs/QuestionDialog.js @@ -64,7 +64,6 @@ export default React.createClass({ }); return ( diff --git a/src/components/views/dialogs/TextInputDialog.js b/src/components/views/dialogs/TextInputDialog.js index 5ea4191e5e..907848b3b8 100644 --- a/src/components/views/dialogs/TextInputDialog.js +++ b/src/components/views/dialogs/TextInputDialog.js @@ -60,25 +60,24 @@ export default React.createClass({ const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); return ( -
-
- +
+
+
+ +
+
+ +
-
- +
+ +
-
-
- - -
+
); }, From 4f83f6cf25480776c04329a0463d8f6fe82f48ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Tue, 5 Dec 2017 08:50:40 +0100 Subject: [PATCH 0010/1160] Move keyboard focus management back to the BaseDialog rather than leaving it in the Modal manager. We are using Modal manager to load other components not just BaseDialog and its subclasses and they might require different keyboard handling. Also depend on focus-trap-react rather than react-focus-trap for locking keyboard focus inside the dialog. The experience is much nicer and even the FocusTrap element it-self no longer gains the focus. On a side note using the FocusTrap element outside the dialog (on its parent) stops it from working properly. --- package.json | 2 +- src/Modal.js | 6 ++---- src/components/views/dialogs/BaseDialog.js | 13 +++++++++++-- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 46517230a7..ee089daf29 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "file-saver": "^1.3.3", "filesize": "3.5.6", "flux": "2.1.1", + "focus-trap-react": "^3.0.5", "fuse.js": "^2.2.0", "glob": "^5.0.14", "highlight.js": "^8.9.1", @@ -78,7 +79,6 @@ "react": "^15.4.0", "react-addons-css-transition-group": "15.3.2", "react-dom": "^15.4.0", - "react-focus-trap": "^2.5.0", "react-gemini-scrollbar": "matrix-org/react-gemini-scrollbar#5e97aef", "sanitize-html": "^1.14.1", "text-encoding-utf-8": "^1.0.1", diff --git a/src/Modal.js b/src/Modal.js index daf66a37de..68d75d1ff1 100644 --- a/src/Modal.js +++ b/src/Modal.js @@ -19,7 +19,6 @@ limitations under the License. const React = require('react'); const ReactDOM = require('react-dom'); -import FocusTrap from 'react-focus-trap'; import Analytics from './Analytics'; import sdk from './index'; @@ -165,7 +164,6 @@ class ModalManager { ); modal.onFinished = props ? props.onFinished : null; modal.className = className; - modal.closeDialog = closeDialog; this._modals.unshift(modal); @@ -196,9 +194,9 @@ class ModalManager { const modal = this._modals[0]; const dialog = (
- +
{ modal.elem } - +
); diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index 1f29f2d1f4..25909a18fa 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -15,6 +15,7 @@ limitations under the License. */ import React from 'react'; +import FocusTrap from 'focus-trap-react'; import * as KeyCode from '../../../KeyCode'; import AccessibleButton from '../elements/AccessibleButton'; @@ -61,6 +62,14 @@ export default React.createClass({ } }, + _onKeyDown: function(e) { + if (e.keyCode === KeyCode.ESCAPE) { + e.stopPropagation(); + e.preventDefault(); + this.props.onFinished(); + } + }, + _onCancelClick: function(e) { this.props.onFinished(); }, @@ -69,7 +78,7 @@ export default React.createClass({ const TintableSvg = sdk.getComponent("elements.TintableSvg"); return ( -
+ @@ -79,7 +88,7 @@ export default React.createClass({ { this.props.title }
{ this.props.children } -
+ ); }, }); From a31af39ca8af8da06462d6d2cc3dd8d20093ca64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Tue, 5 Dec 2017 13:52:20 +0100 Subject: [PATCH 0011/1160] Applied aria-describedby to all other dialogs that are using BaseDialog. Also added initial focus where it has not been set. --- .../views/dialogs/ChatCreateOrReuseDialog.js | 11 +++++----- src/components/views/dialogs/ErrorDialog.js | 14 +++++-------- .../views/dialogs/InteractiveAuthDialog.js | 8 +++++--- .../views/dialogs/KeyShareDialog.js | 7 ++++--- .../dialogs/SessionRestoreErrorDialog.js | 16 +++++++++++---- .../views/dialogs/SetEmailDialog.js | 5 ++++- src/components/views/dialogs/SetMxIdDialog.js | 7 ++++--- .../views/dialogs/UnknownDeviceDialog.js | 5 +++-- .../login/InteractiveAuthEntryComponents.js | 20 +++++++++++++------ 9 files changed, 57 insertions(+), 36 deletions(-) diff --git a/src/components/views/dialogs/ChatCreateOrReuseDialog.js b/src/components/views/dialogs/ChatCreateOrReuseDialog.js index e0578f3b53..0623177e1a 100644 --- a/src/components/views/dialogs/ChatCreateOrReuseDialog.js +++ b/src/components/views/dialogs/ChatCreateOrReuseDialog.js @@ -127,7 +127,7 @@ export default class ChatCreateOrReuseDialog extends React.Component {
{ _t("Start new chat") }
; - content =
+ content =
{ _t('You already have existing direct chats with this user:') }
{ this.state.tiles } @@ -144,7 +144,7 @@ export default class ChatCreateOrReuseDialog extends React.Component { if (this.state.busyProfile) { profile = ; } else if (this.state.profileError) { - profile =
+ profile =
Unable to load profile information for { this.props.userId }
; } else { @@ -160,14 +160,14 @@ export default class ChatCreateOrReuseDialog extends React.Component {
; } content =
-
+

{ _t('Click on the button below to start chatting!') }

{ profile }
-
@@ -179,6 +179,7 @@ export default class ChatCreateOrReuseDialog extends React.Component { { content } @@ -186,7 +187,7 @@ export default class ChatCreateOrReuseDialog extends React.Component { } } -ChatCreateOrReuseDialog.propTyps = { +ChatCreateOrReuseDialog.propTypes = { userId: React.PropTypes.string.isRequired, // Called when clicking outside of the dialog onFinished: React.PropTypes.func.isRequired, diff --git a/src/components/views/dialogs/ErrorDialog.js b/src/components/views/dialogs/ErrorDialog.js index 97ed47e10f..0910264cef 100644 --- a/src/components/views/dialogs/ErrorDialog.js +++ b/src/components/views/dialogs/ErrorDialog.js @@ -51,22 +51,18 @@ export default React.createClass({ }; }, - componentDidMount: function() { - if (this.props.focus) { - this.refs.button.focus(); - } - }, - render: function() { const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); return ( -
+ title={this.props.title || _t('Error')} + contentId='mx_Dialog_content' + > +
{ this.props.description || _t('An error has occurred.') }
-
diff --git a/src/components/views/dialogs/InteractiveAuthDialog.js b/src/components/views/dialogs/InteractiveAuthDialog.js index 59de7c7f59..d1273849ae 100644 --- a/src/components/views/dialogs/InteractiveAuthDialog.js +++ b/src/components/views/dialogs/InteractiveAuthDialog.js @@ -72,11 +72,12 @@ export default React.createClass({ let content; if (this.state.authError) { content = ( -
-
{ this.state.authError.message || this.state.authError.toString() }
+
+
{ this.state.authError.message || this.state.authError.toString() }

{ _t("Dismiss") } @@ -84,7 +85,7 @@ export default React.createClass({ ); } else { content = ( -
+
{ content } diff --git a/src/components/views/dialogs/KeyShareDialog.js b/src/components/views/dialogs/KeyShareDialog.js index 9c8be27c89..821939ff0d 100644 --- a/src/components/views/dialogs/KeyShareDialog.js +++ b/src/components/views/dialogs/KeyShareDialog.js @@ -125,11 +125,11 @@ export default React.createClass({ text = _t(text, {displayName: displayName}); return ( -
+

{ text }

- diff --git a/src/components/views/dialogs/SetEmailDialog.js b/src/components/views/dialogs/SetEmailDialog.js index 2dd996953d..5a9569c1b5 100644 --- a/src/components/views/dialogs/SetEmailDialog.js +++ b/src/components/views/dialogs/SetEmailDialog.js @@ -41,6 +41,7 @@ export default React.createClass({ }, componentDidMount: function() { + this.refs.emailInputField.focus(); }, onEmailAddressChanged: function(value) { @@ -130,6 +131,7 @@ export default React.createClass({ const emailInput = this.state.emailBusy ? :
-

+

{ _t('This will allow you to reset your password and receive notifications.') }

{ emailInput } diff --git a/src/components/views/dialogs/SetMxIdDialog.js b/src/components/views/dialogs/SetMxIdDialog.js index 6fc1d77682..5ef04f5be1 100644 --- a/src/components/views/dialogs/SetMxIdDialog.js +++ b/src/components/views/dialogs/SetMxIdDialog.js @@ -234,14 +234,14 @@ export default React.createClass({ "error": Boolean(this.state.usernameError), "success": usernameAvailable, }); - usernameIndicator =
+ usernameIndicator =
{ usernameAvailable ? _t('Username available') : this.state.usernameError }
; } let authErrorIndicator = null; if (this.state.authError) { - authErrorIndicator =
+ authErrorIndicator =
{ this.state.authError }
; } @@ -253,8 +253,9 @@ export default React.createClass({ -
+
- +

{ _t('"%(RoomName)s" contains devices that you haven\'t seen before.', {RoomName: this.props.room.name}) }

@@ -161,7 +162,7 @@ export default React.createClass({ }}> { _t("Send anyway") } - - +
diff --git a/src/components/views/dialogs/SessionRestoreErrorDialog.js b/src/components/views/dialogs/SessionRestoreErrorDialog.js index e68a097e80..f018a83301 100644 --- a/src/components/views/dialogs/SessionRestoreErrorDialog.js +++ b/src/components/views/dialogs/SessionRestoreErrorDialog.js @@ -54,7 +54,8 @@ export default React.createClass({ { _t( "Otherwise, click here to send a bug report.", {}, - { 'a': (sub) => { sub } }, + { 'a': (sub) => { sub } }, ) }

); diff --git a/src/components/views/dialogs/TextInputDialog.js b/src/components/views/dialogs/TextInputDialog.js index 907848b3b8..4d73752641 100644 --- a/src/components/views/dialogs/TextInputDialog.js +++ b/src/components/views/dialogs/TextInputDialog.js @@ -75,7 +75,7 @@ export default React.createClass({ - +
From ab0ff9b7814240f91ba0ad03351adf26cf4a63e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Tue, 12 Dec 2017 18:55:57 +0100 Subject: [PATCH 0018/1160] BaseDialog: split a very long line --- src/components/views/dialogs/BaseDialog.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index fbeb35c808..db8e530fa0 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -83,7 +83,12 @@ export default React.createClass({ const TintableSvg = sdk.getComponent("elements.TintableSvg"); return ( - + From 642675c96da9fb31d191539f884872d2b7717c27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Thu, 14 Dec 2017 10:31:28 +0100 Subject: [PATCH 0019/1160] Address review request comments --- .../views/dialogs/InteractiveAuthDialog.js | 2 +- .../dialogs/SessionRestoreErrorDialog.js | 5 +- .../login/InteractiveAuthEntryComponents.js | 51 ++++++++++++++----- 3 files changed, 43 insertions(+), 15 deletions(-) diff --git a/src/components/views/dialogs/InteractiveAuthDialog.js b/src/components/views/dialogs/InteractiveAuthDialog.js index d1273849ae..5b0e34df2c 100644 --- a/src/components/views/dialogs/InteractiveAuthDialog.js +++ b/src/components/views/dialogs/InteractiveAuthDialog.js @@ -73,7 +73,7 @@ export default React.createClass({ if (this.state.authError) { content = (
-
{ this.state.authError.message || this.state.authError.toString() }
+
{ this.state.authError.message || this.state.authError.toString() }

); } + const shouldFocusContinueButton =!(bugreport==true); return ( -
-
diff --git a/src/components/views/login/InteractiveAuthEntryComponents.js b/src/components/views/login/InteractiveAuthEntryComponents.js index 81b84684fc..a0bb1065f2 100644 --- a/src/components/views/login/InteractiveAuthEntryComponents.js +++ b/src/components/views/login/InteractiveAuthEntryComponents.js @@ -127,6 +127,15 @@ export const PasswordAuthEntry = React.createClass({ ); } + let errorSection; + if (this.props.errorText) { + errorSection = ( +
+ { this.props.errorText } +
+ ); + } + return (

{ _t("To continue, please enter your password.") }

@@ -143,9 +152,7 @@ export const PasswordAuthEntry = React.createClass({ { submitButtonOrSpinner }
-
- { this.props.errorText } -
+ { errorSection }
); }, @@ -180,14 +187,22 @@ export const RecaptchaAuthEntry = React.createClass({ const CaptchaForm = sdk.getComponent("views.login.CaptchaForm"); const sitePublicKey = this.props.stageParams.public_key; + + let errorSection; + if (this.props.errorText) { + errorSection = ( +
+ { this.props.errorText } +
+ ); + } + return (
-
- { this.props.errorText } -
+ { errorSection }
); }, @@ -372,6 +387,14 @@ export const MsisdnAuthEntry = React.createClass({ mx_InteractiveAuthEntryComponents_msisdnSubmit: true, mx_UserSettings_button: true, // XXX button classes }); + let errorSection; + if (this.state.errorText) { + errorSection = ( +
+ { this.state.errorText } +
+ ); + } return (

{ _t("A text message has been sent to %(msisdn)s", @@ -393,9 +416,7 @@ export const MsisdnAuthEntry = React.createClass({ disabled={!enableSubmit} /> -

- { this.state.errorText } -
+ {errorSection}
); @@ -452,12 +473,18 @@ export const FallbackAuthEntry = React.createClass({ }, render: function() { + let errorSection; + if (this.props.errorText) { + errorSection = ( +
+ { this.props.errorText } +
+ ); + } return (
{ _t("Start authentication") } -
- { this.props.errorText } -
+ {errorSection}
); }, From c234e209fbb375b8ef227fa1d27648d961bb496b Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Fri, 15 Dec 2017 15:24:22 +0000 Subject: [PATCH 0020/1160] Add postmessage api and move functions in to class --- src/MatrixPostMessageApi.js | 101 +++++++++++ src/WidgetMessaging.js | 348 +++++++++++++++++++----------------- 2 files changed, 286 insertions(+), 163 deletions(-) create mode 100644 src/MatrixPostMessageApi.js diff --git a/src/MatrixPostMessageApi.js b/src/MatrixPostMessageApi.js new file mode 100644 index 0000000000..dd65cbd8fa --- /dev/null +++ b/src/MatrixPostMessageApi.js @@ -0,0 +1,101 @@ +import Promise from "bluebird"; + + +function defer() { + let resolve, reject; + let isPending = true; + let promise = new Promise(function(...args) { + resolve = args[0]; + reject = args[1]; + }); + return { + resolve: function(...args) { + if (!isPending) { + return; + } + isPending = false; + resolve(args[0]); + }, + reject: function(...args) { + if (!isPending) { + return; + } + isPending = false; + reject(args[0]); + }, + isPending: function() { + return isPending; + }, + promise: promise, + }; +} + +// NOTE: PostMessageApi only handles message events with a data payload with a +// response field +export default class PostMessageApi { + constructor(targetWindow, timeoutMs) { + this._window = targetWindow || window.parent; // default to parent window + this._timeoutMs = timeoutMs || 5000; // default to 5s timer + this._counter = 0; + this._pending = { + // $ID: Deferred + }; + } + + start() { + addEventListener('message', this.getOnMessageCallback()); + } + + stop() { + removeEventListener('message', this.getOnMessageCallback()); + } + + // Somewhat convoluted so we can successfully capture the PostMessageApi 'this' instance. + getOnMessageCallback() { + if (this._onMsgCallback) { + return this._onMsgCallback; + } + let self = this; + this._onMsgCallback = function(ev) { + // THIS IS ALL UNSAFE EXECUTION. + // We do not verify who the sender of `ev` is! + let payload = ev.data; + // NOTE: Workaround for running in a mobile WebView where a + // postMessage immediately triggers this callback even though it is + // not the response. + if (payload.response === undefined) { + return; + } + let deferred = self._pending[payload._id]; + if (!deferred) { + return; + } + if (!deferred.isPending()) { + return; + } + delete self._pending[payload._id]; + deferred.resolve(payload); + }; + return this._onMsgCallback; + } + + exec(action, target) { + this._counter += 1; + target = target || "*"; + action._id = Date.now() + "-" + Math.random().toString(36) + "-" + this._counter; + let d = defer(); + this._pending[action._id] = d; + this._window.postMessage(action, target); + + if (this._timeoutMs > 0) { + setTimeout(function() { + if (!d.isPending()) { + return; + } + console.error("postMessage request timed out. Sent object: " + JSON.stringify(action)); + d.reject(new Error("Timed out")); + }, this._timeoutMs); + } + return d.promise; + } +} diff --git a/src/WidgetMessaging.js b/src/WidgetMessaging.js index 0f23413b5f..7cd18132af 100644 --- a/src/WidgetMessaging.js +++ b/src/WidgetMessaging.js @@ -112,14 +112,14 @@ Example: */ import URL from 'url'; +import dis from './dispatcher'; +import MatrixPostMessageApi from './MatrixPostMessageApi'; const WIDGET_API_VERSION = '0.0.1'; // Current API version const SUPPORTED_WIDGET_API_VERSIONS = [ '0.0.1', ]; -import dis from './dispatcher'; - if (!global.mxWidgetMessagingListenerCount) { global.mxWidgetMessagingListenerCount = 0; } @@ -127,176 +127,205 @@ if (!global.mxWidgetMessagingMessageEndpoints) { global.mxWidgetMessagingMessageEndpoints = []; } - -/** - * Register widget message event listeners - */ -function startListening() { - if (global.mxWidgetMessagingListenerCount === 0) { - window.addEventListener("message", onMessage, false); - } - global.mxWidgetMessagingListenerCount += 1; -} - -/** - * De-register widget message event listeners - */ -function stopListening() { - global.mxWidgetMessagingListenerCount -= 1; - if (global.mxWidgetMessagingListenerCount === 0) { - window.removeEventListener("message", onMessage); - } - if (global.mxWidgetMessagingListenerCount < 0) { - // Make an error so we get a stack trace - const e = new Error( - "WidgetMessaging: mismatched startListening / stopListening detected." + - " Negative count", - ); - console.error(e); - } -} - -/** - * Register a widget endpoint for trusted postMessage communication - * @param {string} widgetId Unique widget identifier - * @param {string} endpointUrl Widget wurl origin (protocol + (optional port) + host) - */ -function addEndpoint(widgetId, endpointUrl) { - const u = URL.parse(endpointUrl); - if (!u || !u.protocol || !u.host) { - console.warn("Invalid origin:", endpointUrl); - return; +export default class WidgetMessaging extends MatrixPostMessageApi { + constructor(targetWindow) { + super(targetWindow); } - const origin = u.protocol + '//' + u.host; - const endpoint = new WidgetMessageEndpoint(widgetId, origin); - if (global.mxWidgetMessagingMessageEndpoints) { - if (global.mxWidgetMessagingMessageEndpoints.some(function(ep) { - return (ep.widgetId === widgetId && ep.endpointUrl === endpointUrl); - })) { - // Message endpoint already registered - console.warn("Endpoint already registered"); + exec(action) { + return super.exec(action).then((data) => { + // check for errors and reject if found + if (data.response === undefined) { // null is valid + throw new Error("Missing 'response' field"); + } + if (data.response && data.response.error) { + const err = data.response.error; + const msg = String(err.message ? err.message : "An error was returned"); + if (err._error) { + console.error(err._error); + } + // Potential XSS attack if 'msg' is not appropriately sanitized, + // as it is untrusted input by our parent window (which we assume is Riot). + // We can't aggressively sanitize [A-z0-9] since it might be a translation. + throw new Error(msg); + } + // return the response field for the request + return data.response; + }); + } + + /** + * Register widget message event listeners + */ + startListening() { + if (global.mxWidgetMessagingListenerCount === 0) { + window.addEventListener("message", this.onMessage, false); + } + global.mxWidgetMessagingListenerCount += 1; + } + + /** + * De-register widget message event listeners + */ + stopListening() { + global.mxWidgetMessagingListenerCount -= 1; + if (global.mxWidgetMessagingListenerCount === 0) { + window.removeEventListener("message", this.onMessage); + } + if (global.mxWidgetMessagingListenerCount < 0) { + // Make an error so we get a stack trace + const e = new Error( + "WidgetMessaging: mismatched startListening / stopListening detected." + + " Negative count", + ); + console.error(e); + } + } + + /** + * Register a widget endpoint for trusted postMessage communication + * @param {string} widgetId Unique widget identifier + * @param {string} endpointUrl Widget wurl origin (protocol + (optional port) + host) + */ + addEndpoint(widgetId, endpointUrl) { + const u = URL.parse(endpointUrl); + if (!u || !u.protocol || !u.host) { + console.warn("Invalid origin:", endpointUrl); return; } - global.mxWidgetMessagingMessageEndpoints.push(endpoint); - } -} -/** - * De-register a widget endpoint from trusted communication sources - * @param {string} widgetId Unique widget identifier - * @param {string} endpointUrl Widget wurl origin (protocol + (optional port) + host) - * @return {boolean} True if endpoint was successfully removed - */ -function removeEndpoint(widgetId, endpointUrl) { - const u = URL.parse(endpointUrl); - if (!u || !u.protocol || !u.host) { - console.warn("Invalid origin"); - return; + const origin = u.protocol + '//' + u.host; + const endpoint = new WidgetMessageEndpoint(widgetId, origin); + if (global.mxWidgetMessagingMessageEndpoints) { + if (global.mxWidgetMessagingMessageEndpoints.some(function(ep) { + return (ep.widgetId === widgetId && ep.endpointUrl === endpointUrl); + })) { + // Message endpoint already registered + console.warn("Endpoint already registered"); + return; + } + global.mxWidgetMessagingMessageEndpoints.push(endpoint); + } } - const origin = u.protocol + '//' + u.host; - if (global.mxWidgetMessagingMessageEndpoints && global.mxWidgetMessagingMessageEndpoints.length > 0) { - const length = global.mxWidgetMessagingMessageEndpoints.length; - global.mxWidgetMessagingMessageEndpoints = global.mxWidgetMessagingMessageEndpoints.filter(function(endpoint) { - return (endpoint.widgetId != widgetId || endpoint.endpointUrl != origin); - }); - return (length > global.mxWidgetMessagingMessageEndpoints.length); - } - return false; -} + /** + * De-register a widget endpoint from trusted communication sources + * @param {string} widgetId Unique widget identifier + * @param {string} endpointUrl Widget wurl origin (protocol + (optional port) + host) + * @return {boolean} True if endpoint was successfully removed + */ + removeEndpoint(widgetId, endpointUrl) { + const u = URL.parse(endpointUrl); + if (!u || !u.protocol || !u.host) { + console.warn("Invalid origin"); + return; + } - -/** - * Handle widget postMessage events - * @param {Event} event Event to handle - * @return {undefined} - */ -function onMessage(event) { - if (!event.origin) { // Handle chrome - event.origin = event.originalEvent.origin; - } - - // Event origin is empty string if undefined - if ( - event.origin.length === 0 || - !trustedEndpoint(event.origin) || - event.data.api !== "widget" || - !event.data.widgetId - ) { - return; // don't log this - debugging APIs like to spam postMessage which floods the log otherwise - } - - const action = event.data.action; - const widgetId = event.data.widgetId; - if (action === 'content_loaded') { - dis.dispatch({ - action: 'widget_content_loaded', - widgetId: widgetId, - }); - sendResponse(event, {success: true}); - } else if (action === 'supported_api_versions') { - sendResponse(event, { - api: "widget", - supported_versions: SUPPORTED_WIDGET_API_VERSIONS, - }); - } else if (action === 'api_version') { - sendResponse(event, { - api: "widget", - version: WIDGET_API_VERSION, - }); - } else { - console.warn("Widget postMessage event unhandled"); - sendError(event, {message: "The postMessage was unhandled"}); - } -} - -/** - * Check if message origin is registered as trusted - * @param {string} origin PostMessage origin to check - * @return {boolean} True if trusted - */ -function trustedEndpoint(origin) { - if (!origin) { + const origin = u.protocol + '//' + u.host; + if (global.mxWidgetMessagingMessageEndpoints && global.mxWidgetMessagingMessageEndpoints.length > 0) { + const length = global.mxWidgetMessagingMessageEndpoints.length; + global.mxWidgetMessagingMessageEndpoints = global.mxWidgetMessagingMessageEndpoints. + filter(function(endpoint) { + return (endpoint.widgetId != widgetId || endpoint.endpointUrl != origin); + }); + return (length > global.mxWidgetMessagingMessageEndpoints.length); + } return false; } - return global.mxWidgetMessagingMessageEndpoints.some((endpoint) => { - return endpoint.endpointUrl === origin; - }); -} -/** - * Send a postmessage response to a postMessage request - * @param {Event} event The original postMessage request event - * @param {Object} res Response data - */ -function sendResponse(event, res) { - const data = JSON.parse(JSON.stringify(event.data)); - data.response = res; - event.source.postMessage(data, event.origin); -} + /** + * Handle widget postMessage events + * @param {Event} event Event to handle + * @return {undefined} + */ + onMessage(event) { + if (!event.origin) { // Handle chrome + event.origin = event.originalEvent.origin; + } -/** - * Send an error response to a postMessage request - * @param {Event} event The original postMessage request event - * @param {string} msg Error message - * @param {Error} nestedError Nested error event (optional) - */ -function sendError(event, msg, nestedError) { - console.error("Action:" + event.data.action + " failed with message: " + msg); - const data = JSON.parse(JSON.stringify(event.data)); - data.response = { - error: { - message: msg, - }, - }; - if (nestedError) { - data.response.error._error = nestedError; + // Event origin is empty string if undefined + if ( + event.origin.length === 0 || + !this.trustedEndpoint(event.origin) || + event.data.api !== "widget" || + !event.data.widgetId + ) { + return; // don't log this - debugging APIs like to spam postMessage which floods the log otherwise + } + + const action = event.data.action; + const widgetId = event.data.widgetId; + if (action === 'content_loaded') { + dis.dispatch({ + action: 'widget_content_loaded', + widgetId: widgetId, + }); + this.sendResponse(event, {success: true}); + } else if (action === 'supported_api_versions') { + this.sendResponse(event, { + api: "widget", + supported_versions: SUPPORTED_WIDGET_API_VERSIONS, + }); + } else if (action === 'api_version') { + this.sendResponse(event, { + api: "widget", + version: WIDGET_API_VERSION, + }); + } else { + console.warn("Widget postMessage event unhandled"); + this.sendError(event, {message: "The postMessage was unhandled"}); + } + } + + /** + * Check if message origin is registered as trusted + * @param {string} origin PostMessage origin to check + * @return {boolean} True if trusted + */ + trustedEndpoint(origin) { + if (!origin) { + return false; + } + + return global.mxWidgetMessagingMessageEndpoints.some((endpoint) => { + return endpoint.endpointUrl === origin; + }); + } + + /** + * Send a postmessage response to a postMessage request + * @param {Event} event The original postMessage request event + * @param {Object} res Response data + */ + sendResponse(event, res) { + const data = JSON.parse(JSON.stringify(event.data)); + data.response = res; + event.source.postMessage(data, event.origin); + } + + /** + * Send an error response to a postMessage request + * @param {Event} event The original postMessage request event + * @param {string} msg Error message + * @param {Error} nestedError Nested error event (optional) + */ + sendError(event, msg, nestedError) { + console.error("Action:" + event.data.action + " failed with message: " + msg); + const data = JSON.parse(JSON.stringify(event.data)); + data.response = { + error: { + message: msg, + }, + }; + if (nestedError) { + data.response.error._error = nestedError; + } + event.source.postMessage(data, event.origin); } - event.source.postMessage(data, event.origin); } + /** * Represents mapping of widget instance to URLs for trusted postMessage communication. */ @@ -317,10 +346,3 @@ class WidgetMessageEndpoint { this.endpointUrl = endpointUrl; } } - -export default { - startListening: startListening, - stopListening: stopListening, - addEndpoint: addEndpoint, - removeEndpoint: removeEndpoint, -}; From 56f497d39eddefa036bb9c81fe1c27e9f799f69a Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Fri, 15 Dec 2017 16:39:04 +0000 Subject: [PATCH 0021/1160] Add comments and outbound postmessage action to request a widget screenshot. --- src/WidgetMessaging.js | 53 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/src/WidgetMessaging.js b/src/WidgetMessaging.js index 7cd18132af..a35dc3d714 100644 --- a/src/WidgetMessaging.js +++ b/src/WidgetMessaging.js @@ -52,8 +52,8 @@ They look like: } The "message" key should be a human-friendly string. -ACTIONS -======= +INBOUND ACTIONS +=============== ** All actions must include an "api" field with valie "widget".** All actions can return an error response instead of the response outlined below. @@ -109,6 +109,45 @@ Example: action: "supported_api_versions", } + +OUTBOUND ACTIONS +================ + +In addition to listening for inbound requests, the API can be used to initiate +actionss in the widget iframe, and request data from the widget instance. + +Outbound actions use the "widget_client" API key / name, which must be included +on all requests. + +{ + api: "widget_client", + action: "screenshot", + widgetId: $WIDGET_ID, + data: {} + // additional request fields +} + + +screenshot +---------- + +Request a screenshot from the widget (if supported). +This can only be supported by widgets that have access to all of their DOM tree. +For example, widgets that nest further levels of iframes can not support this. + +Request: + - No additional fields. +Response: +{ + screenshot: {data...} +} +Example: +{ + api: "widget_client", + action: "screenshot", + widgetId: $WIDGET_ID +} + */ import URL from 'url'; @@ -323,6 +362,16 @@ export default class WidgetMessaging extends MatrixPostMessageApi { } event.source.postMessage(data, event.origin); } + + /** + * Request a screenshot from a widget + */ + getScreenshot() { + const screenshot = this.exec({ + action: "screenshot", + }); + console.warn("got screenshot", screenshot); + } } From 9f733ebc940760059ecf6321163b1c2f67a9098c Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Fri, 15 Dec 2017 16:55:33 +0000 Subject: [PATCH 0022/1160] Fix binding and promise handling --- src/WidgetMessaging.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/WidgetMessaging.js b/src/WidgetMessaging.js index a35dc3d714..1180dd2df2 100644 --- a/src/WidgetMessaging.js +++ b/src/WidgetMessaging.js @@ -198,7 +198,7 @@ export default class WidgetMessaging extends MatrixPostMessageApi { */ startListening() { if (global.mxWidgetMessagingListenerCount === 0) { - window.addEventListener("message", this.onMessage, false); + window.addEventListener("message", () => this.onMessage, false); } global.mxWidgetMessagingListenerCount += 1; } @@ -209,7 +209,7 @@ export default class WidgetMessaging extends MatrixPostMessageApi { stopListening() { global.mxWidgetMessagingListenerCount -= 1; if (global.mxWidgetMessagingListenerCount === 0) { - window.removeEventListener("message", this.onMessage); + window.removeEventListener("message", () => this.onMessage); } if (global.mxWidgetMessagingListenerCount < 0) { // Make an error so we get a stack trace @@ -367,10 +367,11 @@ export default class WidgetMessaging extends MatrixPostMessageApi { * Request a screenshot from a widget */ getScreenshot() { - const screenshot = this.exec({ + this.exec({ action: "screenshot", + }).then(function(screenshot) { + console.warn("got screenshot", screenshot); }); - console.warn("got screenshot", screenshot); } } From f2ad7be3f3e77a38bb15aa5a2faffa50b54f38c8 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Fri, 15 Dec 2017 16:56:02 +0000 Subject: [PATCH 0023/1160] Add event handlers and comments. --- src/components/views/elements/AppTile.js | 33 ++++++++++++++++-------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 812d8e8bdd..d97f844038 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -155,12 +155,15 @@ export default React.createClass({ }, componentWillMount() { - WidgetMessaging.startListening(); - WidgetMessaging.addEndpoint(this.props.id, this.props.url); - window.addEventListener('message', this._onMessage, false); this.setScalarToken(); }, + componentDidMount() { + // Legacy Jitsi widget messaging -- TODO replace this with standard widget + // postMessaging API + window.addEventListener('message', this._onMessage, false); + }, + /** * Adds a scalar token to the widget URL, if required * Component initialisation is only complete when this function has resolved @@ -234,6 +237,8 @@ export default React.createClass({ } }, + // Legacy Jitsi widget messaging + // TODO -- This should be replaced with the new widget postMessaging API _onMessage(event) { if (this.props.type !== 'jitsi') { return; @@ -268,14 +273,16 @@ export default React.createClass({ }, _onSnapshotClick(e) { - const iframe = this.refs.appFrame; - domtoimage.toPng(iframe).then(function(dataUrl) { - console.log("Image data URL:", dataUrl); - dis.dispatch({ - action: 'picture_snapshot', - file: dataURLtoBlob(dataUrl), - }, true); - }); + console.warn("Requesting widget snapshot"); + this.widgetMessaging.getScreenshot(); + // const iframe = this.refs.appFrame; + // domtoimage.toPng(iframe).then(function(dataUrl) { + // console.log("Image data URL:", dataUrl); + // dis.dispatch({ + // action: 'picture_snapshot', + // file: dataURLtoBlob(dataUrl), + // }, true); + // }); }, /* If user has permission to modify widgets, delete the widget, @@ -317,6 +324,10 @@ export default React.createClass({ * Called when widget iframe has finished loading */ _onLoaded() { + // console.warn("App frame", this.refs.appFrame.contentWindow); + this.widgetMessaging = new WidgetMessaging(this.refs.appFrame.contentWindow); + this.widgetMessaging.startListening(); + this.widgetMessaging.addEndpoint(this.props.id, this.props.url); this.setState({loading: false}); }, From 954c6eecd6665d204a4fb9ec7767971b4db84dc2 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Fri, 15 Dec 2017 19:42:06 +0000 Subject: [PATCH 0024/1160] Set correct API name. --- src/WidgetMessaging.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/WidgetMessaging.js b/src/WidgetMessaging.js index 1180dd2df2..134f93f0f7 100644 --- a/src/WidgetMessaging.js +++ b/src/WidgetMessaging.js @@ -368,6 +368,7 @@ export default class WidgetMessaging extends MatrixPostMessageApi { */ getScreenshot() { this.exec({ + api: "widget_client", action: "screenshot", }).then(function(screenshot) { console.warn("got screenshot", screenshot); From e63f5696a6897341d24909bb53bb97e049654be0 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Fri, 15 Dec 2017 21:36:02 +0000 Subject: [PATCH 0025/1160] Screenshot handlers --- src/WidgetMessaging.js | 19 ++++++++++++++----- src/components/views/elements/AppTile.js | 17 ++++++++--------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/WidgetMessaging.js b/src/WidgetMessaging.js index 134f93f0f7..2efdc366b6 100644 --- a/src/WidgetMessaging.js +++ b/src/WidgetMessaging.js @@ -153,6 +153,7 @@ Example: import URL from 'url'; import dis from './dispatcher'; import MatrixPostMessageApi from './MatrixPostMessageApi'; +import Promise from 'bluebird'; const WIDGET_API_VERSION = '0.0.1'; // Current API version const SUPPORTED_WIDGET_API_VERSIONS = [ @@ -197,6 +198,7 @@ export default class WidgetMessaging extends MatrixPostMessageApi { * Register widget message event listeners */ startListening() { + this.start(); if (global.mxWidgetMessagingListenerCount === 0) { window.addEventListener("message", () => this.onMessage, false); } @@ -207,6 +209,7 @@ export default class WidgetMessaging extends MatrixPostMessageApi { * De-register widget message event listeners */ stopListening() { + this.stop(); global.mxWidgetMessagingListenerCount -= 1; if (global.mxWidgetMessagingListenerCount === 0) { window.removeEventListener("message", () => this.onMessage); @@ -365,13 +368,19 @@ export default class WidgetMessaging extends MatrixPostMessageApi { /** * Request a screenshot from a widget + * @return {Promise} To be resolved when screenshot has been generated */ getScreenshot() { - this.exec({ - api: "widget_client", - action: "screenshot", - }).then(function(screenshot) { - console.warn("got screenshot", screenshot); + return new Promise((resolve, reject) => { + this.exec({ + api: "widget_client", + action: "screenshot", + }).then(function(response) { + // console.warn("got screenshot", response.screenshot); + resolve(response.screenshot); + }).catch((error) => { + reject(Error("Failed to get screenshot: " + error.message)); + }); }); } } diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index d97f844038..b10d7f91ad 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -274,15 +274,14 @@ export default React.createClass({ _onSnapshotClick(e) { console.warn("Requesting widget snapshot"); - this.widgetMessaging.getScreenshot(); - // const iframe = this.refs.appFrame; - // domtoimage.toPng(iframe).then(function(dataUrl) { - // console.log("Image data URL:", dataUrl); - // dis.dispatch({ - // action: 'picture_snapshot', - // file: dataURLtoBlob(dataUrl), - // }, true); - // }); + this.widgetMessaging.getScreenshot().then((screenshot) => { + dis.dispatch({ + action: 'picture_snapshot', + file: screenshot, + }, true); + }).catch((err) => { + console.error("Failed to get screenshot", err); + }); }, /* If user has permission to modify widgets, delete the widget, From 83f9a4162b1fd3d5dcd279dc227583fb142a25d6 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Sat, 16 Dec 2017 09:16:24 +0000 Subject: [PATCH 0026/1160] Request capabilities (e.g. ability to take snapshots) from widgets. --- src/WidgetMessaging.js | 14 +++++++++++ src/components/views/elements/AppTile.js | 32 +++++++++++++----------- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/WidgetMessaging.js b/src/WidgetMessaging.js index 2efdc366b6..d71d86f8f5 100644 --- a/src/WidgetMessaging.js +++ b/src/WidgetMessaging.js @@ -383,6 +383,20 @@ export default class WidgetMessaging extends MatrixPostMessageApi { }); }); } + + getCapabilities() { + return new Promise((resolve, reject) => { + this.exec({ + api: "widget_client", + action: "capabilities", + }).then(function(response) { + // console.warn("got capabilities", response.capabilities); + resolve(response.capabilities); + }).catch((error) => { + reject(Error("Failed to get capabilities: " + error.message)); + }); + }); + } } diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index b10d7f91ad..770406e645 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -33,7 +33,6 @@ import AppWarning from './AppWarning'; import MessageSpinner from './MessageSpinner'; import WidgetUtils from '../../../WidgetUtils'; import dis from '../../../dispatcher'; -import domtoimage from 'dom-to-image'; const ALLOWED_APP_URL_SCHEMES = ['https:', 'http:']; @@ -83,9 +82,20 @@ export default React.createClass({ error: null, deleting: false, widgetPageTitle: newProps.widgetPageTitle, + capabilities: [], }; }, + + /** + * Does the widget support a given capability + * @param {[type]} capability Capability to check for + * @return {Boolean} True if capability supported + */ + _hasCapability(capability) { + return this.state.capabilities.some((c) => {return c === capability;}); + }, + /** * Add widget instance specific parameters to pass in wUrl * Properties passed to widget instance: @@ -327,6 +337,12 @@ export default React.createClass({ this.widgetMessaging = new WidgetMessaging(this.refs.appFrame.contentWindow); this.widgetMessaging.startListening(); this.widgetMessaging.addEndpoint(this.props.id, this.props.url); + this.widgetMessaging.getCapabilities().then((capabilities) => { + console.log("Got widget capabilities", this.widgetId, capabilities); + this.setState({capabilities}); + }).catch((err) => { + console.log("Failed to get widget capabilities", this.widgetId, err); + }); this.setState({loading: false}); }, @@ -468,7 +484,7 @@ export default React.createClass({ } // Picture snapshot - const showPictureSnapshotButton = true; // FIXME - Make this dynamic + const showPictureSnapshotButton = this._hasCapability('screenshot'); const showPictureSnapshotIcon = 'img/camera_green.svg'; const windowStateIcon = (this.props.show ? 'img/minimize.svg' : 'img/maximize.svg'); @@ -525,15 +541,3 @@ export default React.createClass({ ); }, }); - -function dataURLtoBlob(dataurl) { - const arr = dataurl.split(','); - const mime = arr[0].match(/:(.*?);/)[1]; - const bstr = atob(arr[1]); - let n = bstr.length; - const u8arr = new Uint8Array(n); - while (n--) { - u8arr[n] = bstr.charCodeAt(n); - } - return new Blob([u8arr], {type: mime}); -} From 774774c365a69ec4a563f972c608bf9f05dd45b5 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Tue, 19 Dec 2017 17:06:08 +0000 Subject: [PATCH 0027/1160] Remove unused dep. --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 0e2074f381..943c443c59 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,6 @@ "classnames": "^2.1.2", "commonmark": "^0.27.0", "counterpart": "^0.18.0", - "dom-to-image": "^2.6.0", "draft-js": "^0.11.0-alpha", "draft-js-export-html": "^0.6.0", "draft-js-export-markdown": "^0.3.0", From 8e5c3f01b47da99b6188805d671e792d4eb6b0d6 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Tue, 19 Dec 2017 17:08:17 +0000 Subject: [PATCH 0028/1160] License and linting fixes. --- src/MatrixPostMessageApi.js | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/MatrixPostMessageApi.js b/src/MatrixPostMessageApi.js index dd65cbd8fa..d6417f8764 100644 --- a/src/MatrixPostMessageApi.js +++ b/src/MatrixPostMessageApi.js @@ -1,10 +1,26 @@ +/* +Copyright 2017 New Vector Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + import Promise from "bluebird"; - function defer() { - let resolve, reject; + let resolve; + let reject; let isPending = true; - let promise = new Promise(function(...args) { + const promise = new Promise(function(...args) { resolve = args[0]; reject = args[1]; }); @@ -55,18 +71,18 @@ export default class PostMessageApi { if (this._onMsgCallback) { return this._onMsgCallback; } - let self = this; + const self = this; this._onMsgCallback = function(ev) { // THIS IS ALL UNSAFE EXECUTION. // We do not verify who the sender of `ev` is! - let payload = ev.data; + const payload = ev.data; // NOTE: Workaround for running in a mobile WebView where a // postMessage immediately triggers this callback even though it is // not the response. if (payload.response === undefined) { return; } - let deferred = self._pending[payload._id]; + const deferred = self._pending[payload._id]; if (!deferred) { return; } @@ -83,7 +99,7 @@ export default class PostMessageApi { this._counter += 1; target = target || "*"; action._id = Date.now() + "-" + Math.random().toString(36) + "-" + this._counter; - let d = defer(); + const d = defer(); this._pending[action._id] = d; this._window.postMessage(action, target); From 536d4efc4059127c6e407524436e1ea034057a99 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Tue, 19 Dec 2017 17:11:36 +0000 Subject: [PATCH 0029/1160] Fix comments. --- src/WidgetMessaging.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/WidgetMessaging.js b/src/WidgetMessaging.js index d71d86f8f5..2ca8589b54 100644 --- a/src/WidgetMessaging.js +++ b/src/WidgetMessaging.js @@ -54,7 +54,7 @@ The "message" key should be a human-friendly string. INBOUND ACTIONS =============== -** All actions must include an "api" field with valie "widget".** +** All actions must include an "api" field with value of "widget".** All actions can return an error response instead of the response outlined below. content_loaded @@ -66,7 +66,7 @@ Request: - No additional fields. Response: { - success: true + success: "true" } Example: { @@ -114,7 +114,7 @@ OUTBOUND ACTIONS ================ In addition to listening for inbound requests, the API can be used to initiate -actionss in the widget iframe, and request data from the widget instance. +actions in the widget iframe, and request data from the widget instance. Outbound actions use the "widget_client" API key / name, which must be included on all requests. @@ -135,11 +135,13 @@ Request a screenshot from the widget (if supported). This can only be supported by widgets that have access to all of their DOM tree. For example, widgets that nest further levels of iframes can not support this. +The screenshot is returned as a Blob object. + Request: - No additional fields. Response: { - screenshot: {data...} + screenshot: {data...} } Example: { From 08bcfc5c4e123f7382c06d182350b6df70438c47 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Tue, 19 Dec 2017 17:15:06 +0000 Subject: [PATCH 0030/1160] Make sure that capabilities array is initialised. --- src/components/views/elements/AppTile.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 770406e645..ea4f07e657 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -339,6 +339,7 @@ export default React.createClass({ this.widgetMessaging.addEndpoint(this.props.id, this.props.url); this.widgetMessaging.getCapabilities().then((capabilities) => { console.log("Got widget capabilities", this.widgetId, capabilities); + capabilities = capabilities || []; this.setState({capabilities}); }).catch((err) => { console.log("Failed to get widget capabilities", this.widgetId, err); From baf472b4a32d91992e3b774c6f2bfeff1df3f306 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Tue, 19 Dec 2017 17:16:38 +0000 Subject: [PATCH 0031/1160] Only show snapshot button when apps are maximised. --- src/components/views/elements/AppTile.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index ea4f07e657..07a24cba5b 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -484,8 +484,8 @@ export default React.createClass({ deleteClasses += ' mx_AppTileMenuBarWidgetDelete'; } - // Picture snapshot - const showPictureSnapshotButton = this._hasCapability('screenshot'); + // Picture snapshot - only show button when apps are maximised. + const showPictureSnapshotButton = this._hasCapability('screenshot') && this.props.show; const showPictureSnapshotIcon = 'img/camera_green.svg'; const windowStateIcon = (this.props.show ? 'img/minimize.svg' : 'img/maximize.svg'); From 20c485d85e4deaae0a8090496241133902a76486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Wed, 20 Dec 2017 10:09:26 +0100 Subject: [PATCH 0032/1160] Move aria-hidden management from the BaseDialog component to the Modal --- src/Modal.js | 14 ++++++++++++++ src/components/views/dialogs/BaseDialog.js | 18 ------------------ 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/Modal.js b/src/Modal.js index 68d75d1ff1..69ff806045 100644 --- a/src/Modal.js +++ b/src/Modal.js @@ -186,11 +186,25 @@ class ModalManager { } _reRender() { + // Retrieve the root node of the Riot application outside the modal + let applicationNode = document.getElementById('matrixchat'); if (this._modals.length == 0) { + if (applicationNode) { + // If there is no modal to render, make all of Riot available + // to screen reader users again + applicationNode.setAttribute('aria-hidden', 'false'); + } ReactDOM.unmountComponentAtNode(this.getOrCreateContainer()); return; } + if (applicationNode) { + // Hide the content outside the modal to screen reader users + // so they won't be able to navigate into it and act on it using + // screen reader specific features + applicationNode.setAttribute('aria-hidden', 'true'); + } + const modal = this._modals[0]; const dialog = (
diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index db8e530fa0..7fb642b560 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -49,24 +49,6 @@ export default React.createClass({ contentId: React.PropTypes.string, }, - componentDidMount: function() { - // Retrieve the root node of the Riot application outside the dialog - this.applicationNode = document.getElementById('matrixchat'); - if (this.applicationNode) { - // Hide the content outside the dialog to screen reader users - // so they won't be able to navigate into it and act on it using - // screen reader specific features - this.applicationNode.setAttribute('aria-hidden', 'true'); - } - }, - - componentWillUnmount: function() { - if (this.applicationNode) { - // When dismissing the dialog, make all of Riot available to screen reader users again - this.applicationNode.setAttribute('aria-hidden', 'false'); - } - }, - _onKeyDown: function(e) { if (e.keyCode === KeyCode.ESCAPE) { e.stopPropagation(); From f2ca02eaf8aa7b4cd997526bc23396bddf25b8ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Wed, 20 Dec 2017 10:13:37 +0100 Subject: [PATCH 0033/1160] SetEmailDialog: use autoFocus prop on the EditableText rather than using its ref inside onComponentDidMount function. This is shorter better and has been requested. --- src/components/views/dialogs/SetEmailDialog.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/components/views/dialogs/SetEmailDialog.js b/src/components/views/dialogs/SetEmailDialog.js index 5a9569c1b5..ba054b0c27 100644 --- a/src/components/views/dialogs/SetEmailDialog.js +++ b/src/components/views/dialogs/SetEmailDialog.js @@ -40,10 +40,6 @@ export default React.createClass({ }; }, - componentDidMount: function() { - this.refs.emailInputField.focus(); - }, - onEmailAddressChanged: function(value) { this.setState({ emailAddress: value, @@ -131,7 +127,7 @@ export default React.createClass({ const emailInput = this.state.emailBusy ? : Date: Mon, 25 Dec 2017 14:25:13 -0700 Subject: [PATCH 0034/1160] Remove presence management The feature is incredibly buggy and doesn't work as expected due to server behaviour and client interaction. One of the major problems is the constantly confused presence state - this is caused by the mobile apps conflicting on the state of the web app, causing it to consider the user offline or online (and rarely away) depending on how riot-android/ios is behaving at the time. This reverts two PRs: * https://github.com/matrix-org/matrix-react-sdk/pull/1620 * https://github.com/matrix-org/matrix-react-sdk/pull/1482 The changes to the context menu positioning were not reverted as they are useful outside of presence management. Signed-off-by: Travis Ralston --- src/MatrixClientPeg.js | 1 - src/Presence.js | 39 +--- .../views/avatars/MemberPresenceAvatar.js | 168 ------------------ src/components/views/rooms/MessageComposer.js | 4 +- src/i18n/strings/en_EN.json | 1 + 5 files changed, 7 insertions(+), 206 deletions(-) delete mode 100644 src/components/views/avatars/MemberPresenceAvatar.js diff --git a/src/MatrixClientPeg.js b/src/MatrixClientPeg.js index 14dfa91fa4..6e3a380396 100644 --- a/src/MatrixClientPeg.js +++ b/src/MatrixClientPeg.js @@ -98,7 +98,6 @@ class MatrixClientPeg { const opts = utils.deepCopy(this.opts); // the react sdk doesn't work without this, so don't allow opts.pendingEventOrdering = "detached"; - opts.disablePresence = true; // we do this manually try { const promise = this.matrixClient.store.startup(); diff --git a/src/Presence.js b/src/Presence.js index 2652c64c96..fab518e1cb 100644 --- a/src/Presence.js +++ b/src/Presence.js @@ -56,27 +56,13 @@ class Presence { return this.state; } - /** - * Get the current status message. - * @returns {String} the status message, may be null - */ - getStatusMessage() { - return this.statusMessage; - } - /** * Set the presence state. * If the state has changed, the Home Server will be notified. * @param {string} newState the new presence state (see PRESENCE enum) - * @param {String} statusMessage an optional status message for the presence - * @param {boolean} maintain true to have this status maintained by this tracker */ - setState(newState, statusMessage=null, maintain=false) { - if (this.maintain) { - // Don't update presence if we're maintaining a particular status - return; - } - if (newState === this.state && statusMessage === this.statusMessage) { + setState(newState) { + if (newState === this.state) { return; } if (PRESENCE_STATES.indexOf(newState) === -1) { @@ -86,37 +72,21 @@ class Presence { return; } const old_state = this.state; - const old_message = this.statusMessage; this.state = newState; - this.statusMessage = statusMessage; - this.maintain = maintain; if (MatrixClientPeg.get().isGuest()) { return; // don't try to set presence when a guest; it won't work. } - const updateContent = { - presence: this.state, - status_msg: this.statusMessage ? this.statusMessage : '', - }; - const self = this; - MatrixClientPeg.get().setPresence(updateContent).done(function() { + MatrixClientPeg.get().setPresence(this.state).done(function() { console.log("Presence: %s", newState); - - // We have to dispatch because the js-sdk is unreliable at telling us about our own presence - dis.dispatch({action: "self_presence_updated", statusInfo: updateContent}); }, function(err) { console.error("Failed to set presence: %s", err); self.state = old_state; - self.statusMessage = old_message; }); } - stopMaintainingStatus() { - this.maintain = false; - } - /** * Callback called when the user made no action on the page for UNAVAILABLE_TIME ms. * @private @@ -125,8 +95,7 @@ class Presence { this.setState("unavailable"); } - _onUserActivity(payload) { - if (payload.action === "sync_state" || payload.action === "self_presence_updated") return; + _onUserActivity() { this._resetTimer(); } diff --git a/src/components/views/avatars/MemberPresenceAvatar.js b/src/components/views/avatars/MemberPresenceAvatar.js deleted file mode 100644 index 49cfee2cff..0000000000 --- a/src/components/views/avatars/MemberPresenceAvatar.js +++ /dev/null @@ -1,168 +0,0 @@ -/* - Copyright 2017 Travis Ralston - - 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. - */ - -'use strict'; - -import React from "react"; -import * as sdk from "../../../index"; -import MatrixClientPeg from "../../../MatrixClientPeg"; -import AccessibleButton from '../elements/AccessibleButton'; -import Presence from "../../../Presence"; -import dispatcher from "../../../dispatcher"; -import * as ContextualMenu from "../../structures/ContextualMenu"; -import SettingsStore from "../../../settings/SettingsStore"; - -// This is an avatar with presence information and controls on it. -module.exports = React.createClass({ - displayName: 'MemberPresenceAvatar', - - propTypes: { - member: React.PropTypes.object.isRequired, - width: React.PropTypes.number, - height: React.PropTypes.number, - resizeMethod: React.PropTypes.string, - }, - - getDefaultProps: function() { - return { - width: 40, - height: 40, - resizeMethod: 'crop', - }; - }, - - getInitialState: function() { - let presenceState = null; - let presenceMessage = null; - - // RoomMembers do not necessarily have a user. - if (this.props.member.user) { - presenceState = this.props.member.user.presence; - presenceMessage = this.props.member.user.presenceStatusMsg; - } - - return { - status: presenceState, - message: presenceMessage, - }; - }, - - componentWillMount: function() { - MatrixClientPeg.get().on("User.presence", this.onUserPresence); - this.dispatcherRef = dispatcher.register(this.onAction); - }, - - componentWillUnmount: function() { - if (MatrixClientPeg.get()) { - MatrixClientPeg.get().removeListener("User.presence", this.onUserPresence); - } - dispatcher.unregister(this.dispatcherRef); - }, - - onAction: function(payload) { - if (payload.action !== "self_presence_updated") return; - if (this.props.member.userId !== MatrixClientPeg.get().getUserId()) return; - this.setState({ - status: payload.statusInfo.presence, - message: payload.statusInfo.status_msg, - }); - }, - - onUserPresence: function(event, user) { - if (user.userId !== MatrixClientPeg.get().getUserId()) return; - this.setState({ - status: user.presence, - message: user.presenceStatusMsg, - }); - }, - - onStatusChange: function(newStatus) { - Presence.stopMaintainingStatus(); - if (newStatus === "online") { - Presence.setState(newStatus); - } else Presence.setState(newStatus, null, true); - }, - - onClick: function(e) { - const PresenceContextMenu = sdk.getComponent('context_menus.PresenceContextMenu'); - const elementRect = e.target.getBoundingClientRect(); - - // The window X and Y offsets are to adjust position when zoomed in to page - const x = (elementRect.left + window.pageXOffset) - (elementRect.width / 2) + 3; - const chevronOffset = 12; - let y = elementRect.top + (elementRect.height / 2) + window.pageYOffset; - y = y - (chevronOffset + 4); // where 4 is 1/4 the height of the chevron - - ContextualMenu.createMenu(PresenceContextMenu, { - chevronOffset: chevronOffset, - chevronFace: 'bottom', - left: x, - top: y, - menuWidth: 125, - currentStatus: this.state.status, - onChange: this.onStatusChange, - }); - - e.stopPropagation(); - - // XXX NB the following assumes that user is non-null, which is not valid - // const presenceState = this.props.member.user.presence; - // const presenceLastActiveAgo = this.props.member.user.lastActiveAgo; - // const presenceLastTs = this.props.member.user.lastPresenceTs; - // const presenceCurrentlyActive = this.props.member.user.currentlyActive; - // const presenceMessage = this.props.member.user.presenceStatusMsg; - }, - - render: function() { - const MemberAvatar = sdk.getComponent("avatars.MemberAvatar"); - - let onClickFn = null; - if (this.props.member.userId === MatrixClientPeg.get().getUserId()) { - onClickFn = this.onClick; - } - - const avatarNode = ( - - ); - let statusNode = ( - - ); - - // LABS: Disable presence management functions for now - // Also disable the presence information if there's no status information - if (!SettingsStore.isFeatureEnabled("feature_presence_management") || !this.state.status) { - statusNode = null; - onClickFn = null; - } - - let avatar = ( -
- { avatarNode } - { statusNode } -
- ); - if (onClickFn) { - avatar = ( - - { avatarNode } - { statusNode } - - ); - } - return avatar; - }, -}); diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 2841f30423..665f6a8382 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -238,7 +238,7 @@ export default class MessageComposer extends React.Component { render() { const me = this.props.room.getMember(MatrixClientPeg.get().credentials.userId); const uploadInputStyle = {display: 'none'}; - const MemberPresenceAvatar = sdk.getComponent('avatars.MemberPresenceAvatar'); + const MemberAvatar = sdk.getComponent('avatars.MemberAvatar'); const TintableSvg = sdk.getComponent("elements.TintableSvg"); const MessageComposerInput = sdk.getComponent("rooms.MessageComposerInput"); @@ -246,7 +246,7 @@ export default class MessageComposer extends React.Component { controls.push(
- +
, ); diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index f28322398c..9da79e93fe 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -157,6 +157,7 @@ "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s widget modified by %(senderName)s", "%(widgetName)s widget added by %(senderName)s": "%(widgetName)s widget added by %(senderName)s", "%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s widget removed by %(senderName)s", + "Message Pinning": "Message Pinning", "%(displayName)s is typing": "%(displayName)s is typing", "%(names)s and %(count)s others are typing|other": "%(names)s and %(count)s others are typing", "%(names)s and %(count)s others are typing|one": "%(names)s and one other is typing", From 99d3045b4f3e2128968104452f872212d98a8b8f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 25 Dec 2017 14:33:46 -0700 Subject: [PATCH 0035/1160] Also remove the setting Signed-off-by: Travis Ralston --- src/settings/Settings.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/settings/Settings.js b/src/settings/Settings.js index 07de17ccfd..917d17854a 100644 --- a/src/settings/Settings.js +++ b/src/settings/Settings.js @@ -82,12 +82,6 @@ export const SETTINGS = { supportedLevels: LEVELS_FEATURE, default: false, }, - "feature_presence_management": { - isFeature: true, - displayName: _td("Presence Management"), - supportedLevels: LEVELS_FEATURE, - default: false, - }, "feature_tag_panel": { isFeature: true, displayName: _td("Tag Panel"), From 3724a1a6060f474cc85df167c7b4a885b53a55c7 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 28 Dec 2017 13:07:09 +0000 Subject: [PATCH 0036/1160] Bump build From 7b59774b34b18b8a3f029f9c7d811cb3aa9536cc Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 28 Dec 2017 17:08:50 +0000 Subject: [PATCH 0037/1160] Update comment. --- src/WidgetMessaging.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WidgetMessaging.js b/src/WidgetMessaging.js index 2ca8589b54..37dd6b8be4 100644 --- a/src/WidgetMessaging.js +++ b/src/WidgetMessaging.js @@ -132,7 +132,7 @@ screenshot ---------- Request a screenshot from the widget (if supported). -This can only be supported by widgets that have access to all of their DOM tree. +This can currently only be supported by widgets that have access to all of their DOM tree. For example, widgets that nest further levels of iframes can not support this. The screenshot is returned as a Blob object. From 76601760793b577706016354ecd7b11a5e831143 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 28 Dec 2017 22:27:12 +0000 Subject: [PATCH 0038/1160] Fix comment linting errors. Stop listening and cleanup endpoints correctly. --- src/components/views/elements/AppTile.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 07a24cba5b..8032b9d76b 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -72,8 +72,8 @@ export default React.createClass({ const widgetPermissionId = [newProps.room.roomId, encodeURIComponent(newProps.url)].join('_'); const hasPermissionToLoad = localStorage.getItem(widgetPermissionId); return { - initialising: true, // True while we are mangling the widget URL - loading: this.props.waitForIframeLoad, // True while the iframe content is loading + initialising: true, // True while we are mangling the widget URL + loading: this.props.waitForIframeLoad, // True while the iframe content is loading widgetUrl: this._addWurlParams(newProps.url), widgetPermissionId: widgetPermissionId, // Assume that widget has permission to load if we are the user who @@ -227,8 +227,8 @@ export default React.createClass({ }, componentWillUnmount() { - WidgetMessaging.stopListening(); - WidgetMessaging.removeEndpoint(this.props.id, this.props.url); + this.widgetMessaging.stopListening(); + this.widgetMessaging.removeEndpoint(this.props.id, this.props.url); window.removeEventListener('message', this._onMessage); }, From a408b985049a7f7ce816dd423dfa60d3fa240c19 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Fri, 29 Dec 2017 14:34:52 +0000 Subject: [PATCH 0039/1160] Set widget ID on WidgetMessaging instance. --- src/WidgetMessaging.js | 3 ++- src/components/views/elements/AppTile.js | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/WidgetMessaging.js b/src/WidgetMessaging.js index 37dd6b8be4..7918e435cb 100644 --- a/src/WidgetMessaging.js +++ b/src/WidgetMessaging.js @@ -170,8 +170,9 @@ if (!global.mxWidgetMessagingMessageEndpoints) { } export default class WidgetMessaging extends MatrixPostMessageApi { - constructor(targetWindow) { + constructor(widgetId, targetWindow) { super(targetWindow); + this.widgetId = widgetId; } exec(action) { diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 8032b9d76b..2fbb30ff90 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -334,11 +334,11 @@ export default React.createClass({ */ _onLoaded() { // console.warn("App frame", this.refs.appFrame.contentWindow); - this.widgetMessaging = new WidgetMessaging(this.refs.appFrame.contentWindow); + this.widgetMessaging = new WidgetMessaging(this.props.id, this.refs.appFrame.contentWindow); this.widgetMessaging.startListening(); this.widgetMessaging.addEndpoint(this.props.id, this.props.url); this.widgetMessaging.getCapabilities().then((capabilities) => { - console.log("Got widget capabilities", this.widgetId, capabilities); + console.log("Got widget capabilities", this.props.id, capabilities); capabilities = capabilities || []; this.setState({capabilities}); }).catch((err) => { From e96d199b282fdd875d26761a327dcaba23eade72 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 4 Jan 2018 09:53:26 +0000 Subject: [PATCH 0040/1160] Inject stickers --- src/ContentMessages.js | 6 ++++++ src/WidgetMessaging.js | 21 +++++++++++++-------- src/components/structures/RoomView.js | 18 ++++++++++++++++++ 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/ContentMessages.js b/src/ContentMessages.js index 8d40b65124..a173a9f727 100644 --- a/src/ContentMessages.js +++ b/src/ContentMessages.js @@ -275,6 +275,12 @@ class ContentMessages { this.nextId = 0; } + sendURLContentToRoom(url, roomId, info, text, matrixClient) { + return MatrixClientPeg.get().sendImageMessage(roomId, url, info, text).catch((e) => { + console.warn(`Failed to send content with URL ${url} to room ${roomId}`, e); + }); + } + sendContentToRoom(file, roomId, matrixClient) { const content = { body: file.name || 'Attachment', diff --git a/src/WidgetMessaging.js b/src/WidgetMessaging.js index 37dd6b8be4..9db88ae441 100644 --- a/src/WidgetMessaging.js +++ b/src/WidgetMessaging.js @@ -15,6 +15,9 @@ limitations under the License. */ /* +POSTMESSAGE API +=============== + Listens for incoming postMessage requests from embedded widgets. The following API is exposed: { api: "widget", @@ -38,7 +41,7 @@ The "api" field is required to use this API, and must be set to "widget" in all The "action" determines the format of the request and response. All actions can return an error response. -Additional data can be sent as additional, abritrary fields. However, typically the data object should be used. +Additional data can be sent as abritrary fields. However, typically the data object should be used. A success response is an object with zero or more keys. @@ -52,8 +55,8 @@ They look like: } The "message" key should be a human-friendly string. -INBOUND ACTIONS -=============== +ACTIONS +======= ** All actions must include an "api" field with value of "widget".** All actions can return an error response instead of the response outlined below. @@ -110,11 +113,13 @@ Example: } -OUTBOUND ACTIONS -================ +OUTBOUND POSTMESSAGE API +======================== -In addition to listening for inbound requests, the API can be used to initiate -actions in the widget iframe, and request data from the widget instance. +This API can be used to initiate actions in remote widget instances. + +ACTIONS +======= Outbound actions use the "widget_client" API key / name, which must be included on all requests. @@ -133,7 +138,7 @@ screenshot Request a screenshot from the widget (if supported). This can currently only be supported by widgets that have access to all of their DOM tree. -For example, widgets that nest further levels of iframes can not support this. +For example, widgets that nest further levels of iframes can not support this capability. The screenshot is returned as a Blob object. diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index f68348c13d..a5e5273b82 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -459,6 +459,9 @@ module.exports = React.createClass({ case 'message_sent': this._checkIfAlone(this.state.room); break; + case 'inject_sticker': + this.injectSticker(payload.url, payload.info, payload.text); + break; case 'picture_snapshot': this.uploadFile(payload.file); break; @@ -904,6 +907,21 @@ module.exports = React.createClass({ }); }, + injectSticker: function(url, info, text) { + if (MatrixClientPeg.get().isGuest()) { + dis.dispatch({action: 'view_set_mxid'}); + return; + } + + ContentMessages.sendURLContentToRoom(url, this.state.room.roomId, info, text, MatrixClientPeg.get()) + .done(undefined, (error) => { + if (error.name === "UnknownDeviceError") { + // Let the staus bar handle this + return; + } + }); + }, + onSearch: function(term, scope) { this.setState({ searchTerm: term, From eb4053bc9945690a489b86ce2fa8df5456267320 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 4 Jan 2018 18:41:47 +0000 Subject: [PATCH 0041/1160] Handle sticker message payloads --- src/WidgetMessaging.js | 7 ++++++- src/components/structures/RoomView.js | 7 +++++-- src/components/views/elements/AppTile.js | 16 +++++++++++++++- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/WidgetMessaging.js b/src/WidgetMessaging.js index 4b50b21626..43d72e9ba0 100644 --- a/src/WidgetMessaging.js +++ b/src/WidgetMessaging.js @@ -253,8 +253,10 @@ export default class WidgetMessaging extends MatrixPostMessageApi { // Message endpoint already registered console.warn("Endpoint already registered"); return; + } else { + console.warn(`Adding widget messaging endpoint for ${widgetId}`); + global.mxWidgetMessagingMessageEndpoints.push(endpoint); } - global.mxWidgetMessagingMessageEndpoints.push(endpoint); } } @@ -322,6 +324,9 @@ export default class WidgetMessaging extends MatrixPostMessageApi { api: "widget", version: WIDGET_API_VERSION, }); + } else if (action === 'sticker_message') { + console.warn('got widget sticker message', widgetId); + dis.dispatch({action: 'sticker_message', data: event.data.data}); } else { console.warn("Widget postMessage event unhandled"); this.sendError(event, {message: "The postMessage was unhandled"}); diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index a5e5273b82..7980e100ba 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -459,8 +459,11 @@ module.exports = React.createClass({ case 'message_sent': this._checkIfAlone(this.state.room); break; - case 'inject_sticker': - this.injectSticker(payload.url, payload.info, payload.text); + case 'post_sticker_message': + this.injectSticker( + payload.data.content.url, + payload.data.content.info, + payload.data.description || payload.data.name); break; case 'picture_snapshot': this.uploadFile(payload.file); diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 2fbb30ff90..9e24c12cd5 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -333,7 +333,7 @@ export default React.createClass({ * Called when widget iframe has finished loading */ _onLoaded() { - // console.warn("App frame", this.refs.appFrame.contentWindow); + console.warn("App frame loaded", this.props.id); this.widgetMessaging = new WidgetMessaging(this.props.id, this.refs.appFrame.contentWindow); this.widgetMessaging.startListening(); this.widgetMessaging.addEndpoint(this.props.id, this.props.url); @@ -345,8 +345,22 @@ export default React.createClass({ console.log("Failed to get widget capabilities", this.widgetId, err); }); this.setState({loading: false}); + + dis.register(this._onAction); }, + _onAction(payload) { + switch (payload) { + case payload.action === 'sticker_message': + if (this._hasCapability('sticker_message')) { + dis.dispatch({action: 'post_sticker_message', data: payload.data}); + } else { + console.warn('Ignoring sticker message. Invalid capability'); + } + break; + } + }, + /** * Set remote content title on AppTile * @param {string} url Url to check for title From 32aecd06304ccac283eba35b6c9a77233508888e Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 4 Jan 2018 18:43:08 +0000 Subject: [PATCH 0042/1160] Fix event call --- src/WidgetMessaging.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WidgetMessaging.js b/src/WidgetMessaging.js index 4b50b21626..934f9bc3f2 100644 --- a/src/WidgetMessaging.js +++ b/src/WidgetMessaging.js @@ -208,7 +208,7 @@ export default class WidgetMessaging extends MatrixPostMessageApi { startListening() { this.start(); if (global.mxWidgetMessagingListenerCount === 0) { - window.addEventListener("message", () => this.onMessage, false); + window.addEventListener("message", (evt) => this.onMessage(evt), false); } global.mxWidgetMessagingListenerCount += 1; } From d20aebfbd76ef038d3c96322ffe3b9d52b56bdeb Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 4 Jan 2018 18:58:55 +0000 Subject: [PATCH 0043/1160] Correctly handle sticker message events. --- src/WidgetMessaging.js | 3 +-- src/components/views/elements/AppTile.js | 22 ++++++++++++---------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/WidgetMessaging.js b/src/WidgetMessaging.js index 1b66dd89dd..4e64cedbc1 100644 --- a/src/WidgetMessaging.js +++ b/src/WidgetMessaging.js @@ -325,8 +325,7 @@ export default class WidgetMessaging extends MatrixPostMessageApi { version: WIDGET_API_VERSION, }); } else if (action === 'sticker_message') { - console.warn('got widget sticker message', widgetId); - dis.dispatch({action: 'sticker_message', data: event.data.data}); + dis.dispatch({action: 'sticker_message', data: event.data.widgetData, widgetId: event.data.widgetId}); } else { console.warn("Widget postMessage event unhandled"); this.sendError(event, {message: "The postMessage was unhandled"}); diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 9e24c12cd5..49e747b05e 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -350,16 +350,18 @@ export default React.createClass({ }, _onAction(payload) { - switch (payload) { - case payload.action === 'sticker_message': - if (this._hasCapability('sticker_message')) { - dis.dispatch({action: 'post_sticker_message', data: payload.data}); - } else { - console.warn('Ignoring sticker message. Invalid capability'); - } - break; - } - }, + if (payload.widgetId === this.props.id) { + switch (payload.action) { + case 'sticker_message': + if (this._hasCapability('sticker_message')) { + dis.dispatch({action: 'post_sticker_message', data: payload.data}); + } else { + console.warn('Ignoring sticker message. Invalid capability'); + } + break; + } + } + }, /** * Set remote content title on AppTile From 54671ab67ed65f31ba5bc9e74a4f57ff9c6f6f79 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 4 Jan 2018 21:57:24 +0000 Subject: [PATCH 0044/1160] Send m.sticker messages --- src/ContentMessages.js | 4 ++-- src/components/structures/RoomView.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ContentMessages.js b/src/ContentMessages.js index a173a9f727..47ad87a8d7 100644 --- a/src/ContentMessages.js +++ b/src/ContentMessages.js @@ -275,8 +275,8 @@ class ContentMessages { this.nextId = 0; } - sendURLContentToRoom(url, roomId, info, text, matrixClient) { - return MatrixClientPeg.get().sendImageMessage(roomId, url, info, text).catch((e) => { + sendStickerContentToRoom(url, roomId, info, text, matrixClient) { + return MatrixClientPeg.get().sendStickerMessage(roomId, url, info, text).catch((e) => { console.warn(`Failed to send content with URL ${url} to room ${roomId}`, e); }); } diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 7980e100ba..60987fe26e 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -916,7 +916,7 @@ module.exports = React.createClass({ return; } - ContentMessages.sendURLContentToRoom(url, this.state.room.roomId, info, text, MatrixClientPeg.get()) + ContentMessages.sendStickerContentToRoom(url, this.state.room.roomId, info, text, MatrixClientPeg.get()) .done(undefined, (error) => { if (error.name === "UnknownDeviceError") { // Let the staus bar handle this From 1c8586e80294ba1e281b13dee5074356873235f2 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 4 Jan 2018 22:21:38 +0000 Subject: [PATCH 0045/1160] Add sticker message rendering. --- src/components/views/messages/MStickerBody.js | 253 ++++++++++++++++++ src/components/views/messages/MessageEvent.js | 13 +- 2 files changed, 261 insertions(+), 5 deletions(-) create mode 100644 src/components/views/messages/MStickerBody.js diff --git a/src/components/views/messages/MStickerBody.js b/src/components/views/messages/MStickerBody.js new file mode 100644 index 0000000000..8424bbca22 --- /dev/null +++ b/src/components/views/messages/MStickerBody.js @@ -0,0 +1,253 @@ +/* +Copyright 2017 New Vector Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +'use strict'; + +import React from 'react'; +import MFileBody from './MFileBody'; +import MatrixClientPeg from '../../../MatrixClientPeg'; +import ImageUtils from '../../../ImageUtils'; +import Modal from '../../../Modal'; +import sdk from '../../../index'; +import dis from '../../../dispatcher'; +import { decryptFile, readBlobAsDataUri } from '../../../utils/DecryptFile'; +import Promise from 'bluebird'; +import { _t } from '../../../languageHandler'; +import SettingsStore from "../../../settings/SettingsStore"; + +module.exports = React.createClass({ + displayName: 'MStickerBody', + + propTypes: { + /* the MatrixEvent to show */ + mxEvent: React.PropTypes.object.isRequired, + + /* called when the image has loaded */ + onWidgetLoad: React.PropTypes.func.isRequired, + }, + + getInitialState: function() { + return { + decryptedUrl: null, + decryptedThumbnailUrl: null, + decryptedBlob: null, + error: null, + }; + }, + + + onClick: function onClick(ev) { + if (ev.button == 0 && !ev.metaKey) { + ev.preventDefault(); + const content = this.props.mxEvent.getContent(); + const httpUrl = this._getContentUrl(); + const ImageView = sdk.getComponent("elements.ImageView"); + const params = { + src: httpUrl, + name: content.body && content.body.length > 0 ? content.body : _t('Attachment'), + mxEvent: this.props.mxEvent, + }; + + if (content.info) { + params.width = content.info.w; + params.height = content.info.h; + params.fileSize = content.info.size; + } + + Modal.createDialog(ImageView, params, "mx_Dialog_lightbox"); + } + }, + + _isGif: function() { + const content = this.props.mxEvent.getContent(); + return ( + content && + content.info && + content.info.mimetype === "image/gif" + ); + }, + + onImageEnter: function(e) { + if (!this._isGif() || SettingsStore.getValue("autoplayGifsAndVideos")) { + return; + } + const imgElement = e.target; + imgElement.src = this._getContentUrl(); + }, + + onImageLeave: function(e) { + if (!this._isGif() || SettingsStore.getValue("autoplayGifsAndVideos")) { + return; + } + const imgElement = e.target; + imgElement.src = this._getThumbUrl(); + }, + + _getContentUrl: function() { + const content = this.props.mxEvent.getContent(); + if (content.file !== undefined) { + return this.state.decryptedUrl; + } else { + return MatrixClientPeg.get().mxcUrlToHttp(content.url); + } + }, + + _getThumbUrl: function() { + const content = this.props.mxEvent.getContent(); + if (content.file !== undefined) { + // Don't use the thumbnail for clients wishing to autoplay gifs. + if (this.state.decryptedThumbnailUrl) { + return this.state.decryptedThumbnailUrl; + } + return this.state.decryptedUrl; + } else { + return MatrixClientPeg.get().mxcUrlToHttp(content.url, 800, 600); + } + }, + + componentDidMount: function() { + this.dispatcherRef = dis.register(this.onAction); + this.fixupHeight(); + const content = this.props.mxEvent.getContent(); + if (content.file !== undefined && this.state.decryptedUrl === null) { + let thumbnailPromise = Promise.resolve(null); + if (content.info.thumbnail_file) { + thumbnailPromise = decryptFile( + content.info.thumbnail_file, + ).then(function(blob) { + return readBlobAsDataUri(blob); + }); + } + let decryptedBlob; + thumbnailPromise.then((thumbnailUrl) => { + return decryptFile(content.file).then(function(blob) { + decryptedBlob = blob; + return readBlobAsDataUri(blob); + }).then((contentUrl) => { + this.setState({ + decryptedUrl: contentUrl, + decryptedThumbnailUrl: thumbnailUrl, + decryptedBlob: decryptedBlob, + }); + this.props.onWidgetLoad(); + }); + }).catch((err) => { + console.warn("Unable to decrypt attachment: ", err); + // Set a placeholder image when we can't decrypt the image. + this.setState({ + error: err, + }); + }).done(); + } + }, + + componentWillUnmount: function() { + dis.unregister(this.dispatcherRef); + }, + + onAction: function(payload) { + if (payload.action === "timeline_resize") { + this.fixupHeight(); + } + }, + + fixupHeight: function() { + if (!this.refs.image) { + console.warn("Refusing to fix up height on MStickerBody with no image element"); + return; + } + + const content = this.props.mxEvent.getContent(); + const timelineWidth = this.refs.body.offsetWidth; + const maxHeight = 600; // let images take up as much width as they can so long as the height doesn't exceed 600px. + // the alternative here would be 600*timelineWidth/800; to scale them down to fit inside a 4:3 bounding box + + //console.log("trying to fit image into timelineWidth of " + this.refs.body.offsetWidth + " or " + this.refs.body.clientWidth); + let thumbHeight = null; + if (content.info) { + thumbHeight = ImageUtils.thumbHeight(content.info.w, content.info.h, timelineWidth, maxHeight); + } + this.refs.image.style.height = thumbHeight + "px"; + // console.log("Image height now", thumbHeight); + }, + + render: function() { + const TintableSvg = sdk.getComponent("elements.TintableSvg"); + const content = this.props.mxEvent.getContent(); + + if (this.state.error !== null) { + return ( + + + { _t("Error decrypting image") } + + ); + } + + if (content.file !== undefined && this.state.decryptedUrl === null) { + // Need to decrypt the attachment + // The attachment is decrypted in componentDidMount. + // For now add an img tag with a spinner. + return ( + +
+ {content.body} +
+
+ ); + } + + const contentUrl = this._getContentUrl(); + let thumbUrl; + if (this._isGif() && SettingsStore.getValue("autoplayGifsAndVideos")) { + thumbUrl = contentUrl; + } else { + thumbUrl = this._getThumbUrl(); + } + + if (thumbUrl) { + return ( + + + {content.body} + + + ); + } else if (content.body) { + return ( + + { _t("Image '%(Body)s' cannot be displayed.", {Body: content.body}) } + + ); + } else { + return ( + + { _t("This image cannot be displayed.") } + + ); + } + }, +}); diff --git a/src/components/views/messages/MessageEvent.js b/src/components/views/messages/MessageEvent.js index deda1d8d20..7dd5661bb8 100644 --- a/src/components/views/messages/MessageEvent.js +++ b/src/components/views/messages/MessageEvent.js @@ -54,6 +54,7 @@ module.exports = React.createClass({ 'm.notice': sdk.getComponent('messages.TextualBody'), 'm.emote': sdk.getComponent('messages.TextualBody'), 'm.image': sdk.getComponent('messages.MImageBody'), + 'm.sticker': sdk.getComponent('messages.MStickerBody'), 'm.file': sdk.getComponent('messages.MFileBody'), 'm.audio': sdk.getComponent('messages.MAudioBody'), 'm.video': sdk.getComponent('messages.MVideoBody'), @@ -69,10 +70,12 @@ module.exports = React.createClass({ BodyType = bodyTypes['m.file']; } - return ; + return ; }, }); From d652f117fb350c6de7fe5ccd309b356f32ed7521 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 4 Jan 2018 22:36:29 +0000 Subject: [PATCH 0046/1160] Remove click handlers etc. --- src/components/views/messages/MStickerBody.js | 37 +++---------------- 1 file changed, 5 insertions(+), 32 deletions(-) diff --git a/src/components/views/messages/MStickerBody.js b/src/components/views/messages/MStickerBody.js index 8424bbca22..38b45e4789 100644 --- a/src/components/views/messages/MStickerBody.js +++ b/src/components/views/messages/MStickerBody.js @@ -17,7 +17,6 @@ limitations under the License. 'use strict'; import React from 'react'; -import MFileBody from './MFileBody'; import MatrixClientPeg from '../../../MatrixClientPeg'; import ImageUtils from '../../../ImageUtils'; import Modal from '../../../Modal'; @@ -48,29 +47,6 @@ module.exports = React.createClass({ }; }, - - onClick: function onClick(ev) { - if (ev.button == 0 && !ev.metaKey) { - ev.preventDefault(); - const content = this.props.mxEvent.getContent(); - const httpUrl = this._getContentUrl(); - const ImageView = sdk.getComponent("elements.ImageView"); - const params = { - src: httpUrl, - name: content.body && content.body.length > 0 ? content.body : _t('Attachment'), - mxEvent: this.props.mxEvent, - }; - - if (content.info) { - params.width = content.info.w; - params.height = content.info.h; - params.fileSize = content.info.size; - } - - Modal.createDialog(ImageView, params, "mx_Dialog_lightbox"); - } - }, - _isGif: function() { const content = this.props.mxEvent.getContent(); return ( @@ -185,7 +161,6 @@ module.exports = React.createClass({ }, render: function() { - const TintableSvg = sdk.getComponent("elements.TintableSvg"); const content = this.props.mxEvent.getContent(); if (this.state.error !== null) { @@ -227,13 +202,11 @@ module.exports = React.createClass({ if (thumbUrl) { return ( - - {content.body} - + {content.body} ); } else if (content.body) { From 7b313b7acf31588d6018dc0b4669dab0269860c0 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 4 Jan 2018 22:38:52 +0000 Subject: [PATCH 0047/1160] Comment logging. --- src/WidgetMessaging.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WidgetMessaging.js b/src/WidgetMessaging.js index 4e64cedbc1..cd1e4a0996 100644 --- a/src/WidgetMessaging.js +++ b/src/WidgetMessaging.js @@ -254,7 +254,7 @@ export default class WidgetMessaging extends MatrixPostMessageApi { console.warn("Endpoint already registered"); return; } else { - console.warn(`Adding widget messaging endpoint for ${widgetId}`); + // console.warn(`Adding widget messaging endpoint for ${widgetId}`); global.mxWidgetMessagingMessageEndpoints.push(endpoint); } } From d256e473eb71b63dc2f9b18dbc2ceaeb7d1ac140 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 4 Jan 2018 22:51:49 +0000 Subject: [PATCH 0048/1160] Fix header and remove unused deps. --- src/components/views/messages/MStickerBody.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/messages/MStickerBody.js b/src/components/views/messages/MStickerBody.js index 38b45e4789..3fbd1b23e5 100644 --- a/src/components/views/messages/MStickerBody.js +++ b/src/components/views/messages/MStickerBody.js @@ -1,5 +1,5 @@ /* -Copyright 2017 New Vector Ltd +Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From 57247493d9e9daedafdea78cb120df5448f8b71d Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 4 Jan 2018 22:59:50 +0000 Subject: [PATCH 0049/1160] Remove unused deps. --- src/components/views/messages/MStickerBody.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/views/messages/MStickerBody.js b/src/components/views/messages/MStickerBody.js index 3fbd1b23e5..bd86eed568 100644 --- a/src/components/views/messages/MStickerBody.js +++ b/src/components/views/messages/MStickerBody.js @@ -19,8 +19,6 @@ limitations under the License. import React from 'react'; import MatrixClientPeg from '../../../MatrixClientPeg'; import ImageUtils from '../../../ImageUtils'; -import Modal from '../../../Modal'; -import sdk from '../../../index'; import dis from '../../../dispatcher'; import { decryptFile, readBlobAsDataUri } from '../../../utils/DecryptFile'; import Promise from 'bluebird'; From 54d128658e5926eb095b3c5edc03d1b8b151aa0d Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 4 Jan 2018 23:00:10 +0000 Subject: [PATCH 0050/1160] Comment logging. --- src/components/views/elements/AppTile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 49e747b05e..a9ea8c6cf9 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -333,7 +333,7 @@ export default React.createClass({ * Called when widget iframe has finished loading */ _onLoaded() { - console.warn("App frame loaded", this.props.id); + // console.warn("App frame loaded", this.props.id); this.widgetMessaging = new WidgetMessaging(this.props.id, this.refs.appFrame.contentWindow); this.widgetMessaging.startListening(); this.widgetMessaging.addEndpoint(this.props.id, this.props.url); From cf472c791d580ccc0f5b3e419ec3f69e49ec50e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Fri, 5 Jan 2018 11:45:45 +0100 Subject: [PATCH 0051/1160] Consume all combinations of space / enter, keyDown / keyUp presses and try to explain this key handling inconsistency with some additional comments as per the review discussion. --- src/components/views/elements/AccessibleButton.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/components/views/elements/AccessibleButton.js b/src/components/views/elements/AccessibleButton.js index f5254de490..ee8fd20d6f 100644 --- a/src/components/views/elements/AccessibleButton.js +++ b/src/components/views/elements/AccessibleButton.js @@ -32,12 +32,20 @@ export default function AccessibleButton(props) { // We need to consume enter onKeyDown and space onKeyUp // otherwise we are risking also activating other keyboard focusable elements // that might receive focus as a result of the AccessibleButtonClick action + // It's because we are using html buttons at a few places e.g. inside dialogs + // And divs which we report as role button to assistive technologies. + // Browsers handle space and enter keypresses differently and we are only adjusting to the + // inconsistencies here restProps.onKeyDown = function(e) { if (e.keyCode === KeyCode.ENTER) { e.stopPropagation(); e.preventDefault(); return onClick(e); } + if (e.keyCode === KeyCode.SPACE) { + e.stopPropagation(); + e.preventDefault(); + } }; restProps.onKeyUp = function(e) { if (e.keyCode === KeyCode.SPACE) { @@ -45,6 +53,10 @@ export default function AccessibleButton(props) { e.preventDefault(); return onClick(e); } + if (e.keyCode === KeyCode.ENTER) { + e.stopPropagation(); + e.preventDefault(); + } }; restProps.tabIndex = restProps.tabIndex || "0"; restProps.role = "button"; From d3624886a7d7c8f67a3ca1cc78e3db557353bfef Mon Sep 17 00:00:00 2001 From: Andrey Date: Fri, 5 Jan 2018 12:09:17 +0000 Subject: [PATCH 0052/1160] Translated using Weblate (Russian) Currently translated at 100.0% (958 of 958 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index e3da0401bd..7a0fa54c22 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -1048,10 +1048,10 @@ "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Обнаружены данные из более старой версии Riot. Это приведет к сбою криптографии в более ранней версии. В этой версии не могут быть расшифрованы сообщения, которые использовались недавно при использовании старой версии. Это также может привести к сбою обмена сообщениями с этой версией. Если возникают неполадки, выйдите и снова войдите в систему. Чтобы сохранить журнал сообщений, экспортируйте и повторно импортируйте ключи.", "Show devices or cancel all.": "Показать устройства или отменить все.", "Warning": "Предупреждение", - "Showing flair for these communities:": "Показ таланта этим сообществам:", - "This room is not showing flair for any communities": "Эта комната не показывает талант любым сообществам", - "Flair will appear if enabled in room settings": "Талант появится, если включено в настройках комнаты", - "Flair": "Чутье", - "Flair will not appear": "Талант не появится", - "Display your community flair in rooms configured to show it.": "Покажите свое чутье в комнатах, настроенных для показа." + "Showing flair for these communities:": "Показ таланта в следующих сообществах:", + "This room is not showing flair for any communities": "В этой комнате не отображается талант для любых сообществ", + "Flair will appear if enabled in room settings": "Талант появится, если он активирован в настройках комнаты", + "Flair": "Талант", + "Flair will not appear": "Талант не отображается", + "Display your community flair in rooms configured to show it.": "Покажите свой талант в комнатах, которых это разрешено." } From 44d920afc81cf8e5b530fa3fff517228005f480b Mon Sep 17 00:00:00 2001 From: Andrey Date: Fri, 5 Jan 2018 12:26:31 +0000 Subject: [PATCH 0053/1160] Translated using Weblate (Russian) Currently translated at 100.0% (961 of 961 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 1eb0e0e73c..59f639d5e3 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -1053,5 +1053,9 @@ "Flair will appear if enabled in room settings": "Талант появится, если он активирован в настройках комнаты", "Flair": "Талант", "Flair will not appear": "Талант не отображается", - "Display your community flair in rooms configured to show it.": "Покажите свой талант в комнатах, которых это разрешено." + "Display your community flair in rooms configured to show it.": "Покажите свой талант в комнатах, которых это разрешено.", + "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Вы не сможете отменить это изменение после понижения себя, в случае если вы являетесь последним привилегированным пользователем в этой комнате.", + "%(count)s of your messages have not been sent.|one": "Ваше сообщение не было отправлено.", + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "Отправить все или отменить все сейчас. Можно также выбрать отдельные сообщения для отправки или отмены.", + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Отправить или отменить сообщение сейчас." } From f1850d188ece109724c5d60bc79f03d4277f0717 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Fri, 5 Jan 2018 13:17:02 +0000 Subject: [PATCH 0054/1160] Translated using Weblate (French) Currently translated at 100.0% (961 of 961 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ Correction (Seul -> Seules) --- src/i18n/strings/fr.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 450fa424d3..7f7db6a0b2 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -1050,5 +1050,9 @@ "Old cryptography data detected": "Anciennes données de chiffrement détectées", "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Nous avons détecté des données d'une ancienne version de Riot. Le chiffrement de bout-en-bout n'aura pas fonctionné correctement sur l'ancienne version. Les messages chiffrés échangés récemment dans l'ancienne version ne sont peut-être pas déchiffrables dans cette version. Les échanges de message avec cette version peuvent aussi échouer. Si vous rencontrez des problèmes, déconnectez-vous puis reconnectez-vous. Pour conserver l'historique des messages, exportez puis réimportez vos clés de chiffrement.", "Show devices or cancel all.": "Afficher les appareils ou tout annuler.", - "Warning": "Attention" + "Warning": "Attention", + "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Vous ne pourrez pas annuler cette modification car vous vous destituez. Si vous êtes le dernier utilisateur privilégié de ce salon, il sera impossible de récupérer les privilèges.", + "%(count)s of your messages have not been sent.|one": "Votre message n'a pas été envoyé.", + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "Tout renvoyer ou tout annuler maintenant. Vous pouvez aussi choisir des messages individuels à renvoyer ou annuler.", + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Renvoyer le message ou annuler le message maintenant." } From 1e66f4f0ed8c8d75b7626725c8cec4a88bfb9022 Mon Sep 17 00:00:00 2001 From: Osoitz Date: Fri, 5 Jan 2018 14:31:01 +0000 Subject: [PATCH 0055/1160] Translated using Weblate (Basque) Currently translated at 100.0% (961 of 961 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eu/ --- src/i18n/strings/eu.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index cbdd6509cc..f34bee26ca 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -1042,5 +1042,9 @@ "Dark theme": "Gai iluna", "Status.im theme": "Status.im gaia", "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "%(emailAddress)s helbidera e-mail bat bidali da. Behin dakarren esteka jarraituta, egin klik behean.", - "This homeserver doesn't offer any login flows which are supported by this client.": "Hasiera zerbitzari honek ez du bezero honek onartzen duen fluxurik eskaintzen." + "This homeserver doesn't offer any login flows which are supported by this client.": "Hasiera zerbitzari honek ez du bezero honek onartzen duen fluxurik eskaintzen.", + "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Ezin izango duzu hau aldatu zure burua mailaz jaisten ari zarelako, zu bazara gelan baimenak dituen azken erabiltzailea ezin izango dira baimenak berreskuratu.", + "%(count)s of your messages have not been sent.|one": "Zure mezua ez da bidali.", + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "Birbidali guztiak edo baztertu guztiak orain. Mezuak banaka birbidali edo baztertu ditzakezu ere.", + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Birbidali mezua edo baztertu mezua orain." } From f6b24b749fdf95552743e970bd4661c535ddc7b2 Mon Sep 17 00:00:00 2001 From: Osoitz Date: Fri, 5 Jan 2018 14:49:38 +0000 Subject: [PATCH 0056/1160] Translated using Weblate (Basque) Currently translated at 100.0% (961 of 961 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eu/ --- src/i18n/strings/eu.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index f34bee26ca..9b93d88bc2 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -88,7 +88,7 @@ "Please check your email and click on the link it contains. Once this is done, click continue.": "Irakurri zure e-maila eta egin klik dakarren estekan. Behin eginda, egin klik Jarraitu botoian.", "This email address is already in use": "E-mail helbide hau erabilita dago", "This phone number is already in use": "Telefono zenbaki hau erabilita dago", - "Topic": "Gaia", + "Topic": "Mintzagaia", "none": "bat ere ez", "Who can read history?": "Nork irakurri dezake historiala?", "Who can access this room?": "Nor sartu daiteke gelara?", @@ -149,7 +149,7 @@ "Access Token:": "Sarbide tokena:", "Active call (%(roomName)s)": "Dei aktiboa (%(roomName)s)", "Add": "Gehitu", - "Add a topic": "Gehitu gai bat", + "Add a topic": "Gehitu mintzagai bat", "Admin": "Kudeatzailea", "Admin Tools": "Administrazio-tresnak", "VoIP": "VoIP", @@ -222,7 +222,7 @@ "%(senderName)s answered the call.": "%(senderName)s erabiltzaileak deia erantzun du.", "Can't load user settings": "Ezin izan dira erabiltzailearen ezarpenak kargatu", "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s erabiltzaileak gelaren izena kendu du.", - "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s erabiltzaileak gaia aldatu du beste honetara: \"%(topic)s\".", + "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s erabiltzaileak mintzagaia aldatu du beste honetara: \"%(topic)s\".", "Changes to who can read history will only apply to future messages in this room": "Historiala irakurtzeko baimenen aldaketak gela honetara hemendik aurrera heldutako mezuei aplikatuko zaizkie", "Clear Cache and Reload": "Garbitu cachea eta birkargatu", "Devices will not yet be able to decrypt history from before they joined the room": "Gailuek ezin izango dute taldera elkartu aurretiko historiala deszifratu", @@ -647,7 +647,7 @@ "Failed to invite user": "Huts egin du erabiltzailea gonbidatzean", "Failed to invite the following users to the %(roomName)s room:": "Huts egin du honako erabiltzaile hauek %(roomName)s gelara gonbidatzean:", "Confirm Removal": "Berretsi kentzea", - "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Ziur gertaera hau kendu (ezabatu) nahi duzula? Jakin gelaren izenaren edo gaiaren aldaketa ezabatzen baduzu, desegitea dagoela.", + "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Ziur gertaera hau kendu (ezabatu) nahi duzula? Jakin gelaren izenaren edo mintzagaiaren aldaketa ezabatzen baduzu, aldaketa desegin daitekeela.", "Unknown error": "Errore ezezaguna", "Incorrect password": "Pasahitz okerra", "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Honek zure kontua behin betiko erabilezin bihurtuko du. Ezin izango duzu ID honekin berriro erregistratu.", @@ -749,7 +749,7 @@ "PM": "PM", "NOTE: Apps are not end-to-end encrypted": "OHARRA: Aplikazioek ez dute muturretik muturrerako zifratzea", "Revoke widget access": "Indargabetu trepetaren sarbidea", - "Sets the room topic": "Gelaren gaia ezartzen du", + "Sets the room topic": "Gelaren mintzagaia ezartzen du", "Show Apps": "Erakutsi aplikazioak", "The maximum permitted number of widgets have already been added to this room.": "Gehienez onartzen diren trepeta kopurua gehitu da gela honetara.", "To get started, please pick a username!": "Hasteko, hautatu erabiltzaile-izen bat!", @@ -876,7 +876,7 @@ "To change the room's main address, you must be a": "Gelaren helbide nagusia aldatzeko, hau izan behar zara:", "To change the room's history visibility, you must be a": "Gelaren ikusgaitasuna aldatzeko, hau izan behar zara:", "To change the permissions in the room, you must be a": "Gelaren baimenak aldatzeko, hau izan behar zara:", - "To change the topic, you must be a": "Gaia aldatzeko, hau izan behar zara:", + "To change the topic, you must be a": "Mintzagaia aldatzeko, hau izan behar zara:", "To modify widgets in the room, you must be a": "Gelaren trepetak aldatzeko, hau izan behar zara:", "Members only (since the point in time of selecting this option)": "Kideak besterik ez (aukera hau hautatzen den unetik)", "Members only (since they were invited)": "Kideak besterik ez (gonbidatu zaienetik)", @@ -1038,9 +1038,9 @@ "Show devices or cancel all.": "Erakutsi gailuak edo baztertu guztia.", "Resend all or cancel all now. You can also select individual messages to resend or cancel.": "Birbidali guztia edo baztertu guztia orain. Banakako mezuak aukeratu ditzakezu ere birbidali edo baztertzeko.", "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Ez dago beste inor hemen! Beste batzuk gonbidatu nahi dituzu edo gela hutsik dagoela abisatzeari utzi?", - "Light theme": "Gai argia", - "Dark theme": "Gai iluna", - "Status.im theme": "Status.im gaia", + "Light theme": "Itxura argia", + "Dark theme": "Itxura iluna", + "Status.im theme": "Status.im itxura", "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "%(emailAddress)s helbidera e-mail bat bidali da. Behin dakarren esteka jarraituta, egin klik behean.", "This homeserver doesn't offer any login flows which are supported by this client.": "Hasiera zerbitzari honek ez du bezero honek onartzen duen fluxurik eskaintzen.", "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Ezin izango duzu hau aldatu zure burua mailaz jaisten ari zarelako, zu bazara gelan baimenak dituen azken erabiltzailea ezin izango dira baimenak berreskuratu.", From b49c5a4c161e7d6900efa7c11f719f243743832a Mon Sep 17 00:00:00 2001 From: Szimszon Date: Fri, 5 Jan 2018 17:26:53 +0000 Subject: [PATCH 0057/1160] Translated using Weblate (Hungarian) Currently translated at 100.0% (961 of 961 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 45109d2a85..92f1005376 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -1054,5 +1054,9 @@ "Old cryptography data detected": "Régi titkosítási adatot találhatók", "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Régebbi Riot verzióból származó adatok találhatók. Ezek hibás működéshez vezethettek a végponttól-végpontig titkosításban régebbi verzióknál. A nemrég küldött/fogadott titkosított üzenetek ha a régi adatokat használták lehetséges hogy nem lesznek visszafejthetők ebben a verzióban. Ha problémákba ütközöl jelentkezz ki és vissza. A régi üzenetek elérésének biztosításához mentsd ki a kulcsokat és töltsd be újra.", "Show devices or cancel all.": "Eszközök megmutatása vagy mind elutasítása.", - "Warning": "Figyelmeztetés" + "Warning": "Figyelmeztetés", + "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Ahogy lefokozod magad a változás visszafordíthatatlan, ha te vagy az utolsó jogosultságokkal bíró felhasználó a szobában a jogok már nem szerezhetők vissza.", + "%(count)s of your messages have not been sent.|one": "Az üzeneted nem lett elküldve.", + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "Újraküldöd mind vagy elveted mind. Az üzeneteket egyenként is elküldheted vagy elvetheted.", + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Üzenet újraküldése vagy üzenet elvetése most." } From f6851101cc435597d44bceb425328dcd48119543 Mon Sep 17 00:00:00 2001 From: Osoitz Date: Sun, 7 Jan 2018 17:33:13 +0000 Subject: [PATCH 0058/1160] Translated using Weblate (Basque) Currently translated at 100.0% (961 of 961 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eu/ --- src/i18n/strings/eu.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index 9b93d88bc2..2019c76dbc 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -300,7 +300,7 @@ "'%(alias)s' is not a valid format for an address": "'%(alias)s' ez da baliozko formatua helbide batentzat", "'%(alias)s' is not a valid format for an alias": "'%(alias)s' ez da baliozko formatua ezizen batentzat", "%(displayName)s is typing": "%(displayName)s idazten ari da", - "Sign in with": "Hasi saioa honekin:", + "Sign in with": "Hasi saioa hau erabilita:", "Join as voice or video.": "Elkartu ahotsa edo bideoa erabiliz.", "%(targetName)s joined the room.": "%(targetName)s erabiltzailea gelara elkartu da.", "Joins room with given alias": "Gelara emandako ezizenarekin elkartu da", @@ -676,8 +676,8 @@ "Please enter the code it contains:": "Sartu dakarren kodea:", "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Ez baduzu e-mail helbide bat zehazten, ezin izango duzu zure pasahitza berrezarri. Ziur zaude?", "You are registering with %(SelectedTeamName)s": "%(SelectedTeamName)s erabiliz erregistratzen ari zara", - "Default server": "Lehenetsitako zerbitzaria", - "Custom server": "Zerbitzari pertsonalizatua", + "Default server": "Zerbitzari lenetetsia", + "Custom server": "Zerbitzari aukeratua", "Home server URL": "Hasiera zerbitzariaren URLa", "Identity server URL": "Identitate zerbitzariaren URLa", "What does this mean?": "Zer esan nahi du honek?", From 275c960337a4930855f31557bb7b58ad7ac168a8 Mon Sep 17 00:00:00 2001 From: "Iru Cai (vimacs)" Date: Mon, 8 Jan 2018 02:00:48 +0000 Subject: [PATCH 0059/1160] Translated using Weblate (Chinese (Simplified)) Currently translated at 76.8% (739 of 961 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hans/ --- src/i18n/strings/zh_Hans.json | 99 ++++++++++++++++++++++++++++++++++- 1 file changed, 98 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index 11aa4330ff..976b39a8bd 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -712,5 +712,102 @@ "%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s 小组建被 %(senderName)s 移除", "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s 小组建被 %(senderName)s 修改", "Unpin Message": "取消置顶消息", - "Add rooms to this community": "添加聊天室到此社区" + "Add rooms to this community": "添加聊天室到此社区", + "Call Failed": "呼叫失败", + "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "聊天室里有未知设备:如果你不检查它们而继续,可能有人窃听你的通话。", + "Review Devices": "复查设备", + "Call Anyway": "无论如何呼叫", + "Answer Anyway": "无论如何接听", + "Call": "呼叫", + "Answer": "接听", + "Invite new community members": "邀请新的社区成员", + "Invite to Community": "邀请到社区", + "Room name or alias": "聊天室名称或别名", + "Ignored user": "忽视用户", + "You are now ignoring %(userId)s": "你正在忽视 %(userId)s", + "Unignored user": "接触忽视用户", + "You are no longer ignoring %(userId)s": "你不再忽视 %(userId)s", + "%(senderName)s unbanned %(targetName)s.": "%(senderName)s 解除了 %(targetName)s 的封禁。", + "(could not connect media)": "(无法连接媒体)", + "%(senderName)s changed the pinned messages for the room.": "%(senderName)s 更改了聊天室的置顶消息。", + "%(names)s and %(count)s others are typing|other": "%(names)s 和另外 %(count)s 个人正在打字", + "%(names)s and %(count)s others are typing|one": "%(names)s 和另一个人正在打字", + "Send": "发送", + "Message Pinning": "消息置顶", + "Disable Emoji suggestions while typing": "禁用打字时Emoji建议", + "Use compact timeline layout": "使用紧凑的时间线布局", + "Hide avatar changes": "隐藏头像修改", + "Hide display name changes": "隐藏显示名称的修改", + "Disable big emoji in chat": "禁用聊天中的大Emoji", + "Never send encrypted messages to unverified devices in this room from this device": "在这个聊天室永不从这个设备发送加密消息到未验证的设备", + "Enable URL previews for this room (only affects you)": "在这个聊天室启用 URL 预览(只影响你)", + "Enable URL previews by default for participants in this room": "对这个聊天室的参与者默认启用 URL 预览", + "Delete %(count)s devices|other": "删除了 %(count)s 个设备", + "Delete %(count)s devices|one": "删除设备", + "Select devices": "选择设备", + "%(senderName)s sent an image": "%(senderName)s 发送了一张图片", + "%(senderName)s sent a video": "%(senderName)s 发送了一个视频", + "%(senderName)s uploaded a file": "%(senderName)s 上传了一个文件", + "Unignore": "取消忽视", + "Ignore": "忽视", + "Jump to read receipt": "跳到阅读回执", + "Mention": "提及", + "Invite": "邀请", + "User Options": "用户选项", + "Jump to message": "跳到消息", + "No pinned messages.": "没有置顶消息。", + "Loading...": "正在加载...", + "Pinned Messages": "置顶的消息", + "Unknown": "未知的", + "Unnamed room": "未命名的聊天室", + "World readable": "公开可读", + "Guests can join": "访客可以加入", + "No rooms to show": "无聊天室", + "Addresses": "地址", + "Message removed": "消息已移除", + "An email has been sent to %(emailAddress)s": "一封邮件已发送到 %(emailAddress)s", + "A text message has been sent to %(msisdn)s": "一封短信已发送到 %(msisdn)s", + "Username on %(hs)s": "在 %(hs)s 上的用户名", + "Visible to everyone": "对所有人可见", + "Delete Widget": "删除小组件", + "were invited %(count)s times|other": "被邀请 %(count)s 次", + "were invited %(count)s times|one": "被邀请", + "was invited %(count)s times|other": "被邀请 %(count)s 次", + "was invited %(count)s times|one": "被邀请", + "were banned %(count)s times|other": "被封禁 %(count)s 次", + "were banned %(count)s times|one": "被封禁", + "was banned %(count)s times|other": "被封禁 %(count)s 次", + "was banned %(count)s times|one": "被封禁", + "were unbanned %(count)s times|other": "被解封 %(count)s 次", + "were unbanned %(count)s times|one": "被解封", + "was unbanned %(count)s times|other": "被解封 %(count)s 次", + "was unbanned %(count)s times|one": "被解封", + "were kicked %(count)s times|other": "被踢出 %(count)s 次", + "were kicked %(count)s times|one": "被踢出", + "was kicked %(count)s times|other": "被踢出 %(count)s 次", + "was kicked %(count)s times|one": "被踢出", + "%(severalUsers)schanged their name %(count)s times|other": "%(severalUsers)s 改了他们的名字 %(count)s 次", + "%(severalUsers)schanged their name %(count)s times|one": "%(severalUsers)s 改了他们的名字", + "%(oneUser)schanged their name %(count)s times|other": "%(oneUser)s 改了他们的名字 %(count)s 次", + "%(oneUser)schanged their name %(count)s times|one": "%(oneUser)s 改了他们的名字", + "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)s 更换了他们的的头像 %(count)s 次", + "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)s 更换了他们的头像", + "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)s 更换了他们的头像 %(count)s 次", + "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)s 更换了他们的头像", + "%(items)s and %(count)s others|other": "%(items)s 和其他 %(count)s 人", + "%(items)s and %(count)s others|one": "%(items)s 和另一个人", + "collapse": "折叠", + "expand": "展开", + "email address": "电子邮箱地址", + "You have entered an invalid address.": "你输入了一个无效地址。", + "Advanced options": "高级选项", + "Leave": "离开", + "Unable to leave room": "无法离开聊天室", + "Description": "描述", + "Warning": "警告", + "Light theme": "浅色主题", + "Dark theme": "深色主题", + "Status.im theme": "Status.im 主题", + "Ignored Users": "忽视用户", + "Room Notification": "聊天室通知" } From dc1423052fc4fcceda6f7997e48e898ed93928ff Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Mon, 8 Jan 2018 11:32:23 +0000 Subject: [PATCH 0060/1160] De-register listener. --- src/components/views/elements/AppTile.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index a9ea8c6cf9..fa8696ea74 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -229,6 +229,7 @@ export default React.createClass({ componentWillUnmount() { this.widgetMessaging.stopListening(); this.widgetMessaging.removeEndpoint(this.props.id, this.props.url); + dis.unregister(this._onAction); window.removeEventListener('message', this._onMessage); }, From 486b2cf10259170c7478726c089ecd1bf9b749e4 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Mon, 8 Jan 2018 11:32:38 +0000 Subject: [PATCH 0061/1160] Handle sticker message event. --- src/components/views/messages/MessageEvent.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/views/messages/MessageEvent.js b/src/components/views/messages/MessageEvent.js index 7dd5661bb8..53cbc3e5d3 100644 --- a/src/components/views/messages/MessageEvent.js +++ b/src/components/views/messages/MessageEvent.js @@ -54,7 +54,6 @@ module.exports = React.createClass({ 'm.notice': sdk.getComponent('messages.TextualBody'), 'm.emote': sdk.getComponent('messages.TextualBody'), 'm.image': sdk.getComponent('messages.MImageBody'), - 'm.sticker': sdk.getComponent('messages.MStickerBody'), 'm.file': sdk.getComponent('messages.MFileBody'), 'm.audio': sdk.getComponent('messages.MAudioBody'), 'm.video': sdk.getComponent('messages.MVideoBody'), @@ -65,6 +64,8 @@ module.exports = React.createClass({ let BodyType = UnknownBody; if (msgtype && bodyTypes[msgtype]) { BodyType = bodyTypes[msgtype]; + } else if (this.props.mxEvent.getType() === 'm.room.sticker') { + BodyType = sdk.getComponent('messages.MStickerBody'); } else if (content.url) { // Fallback to MFileBody if there's a content URL BodyType = bodyTypes['m.file']; From 5df9a01e6488a7d58904988c0a81e59d81193281 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Mon, 8 Jan 2018 12:06:32 +0000 Subject: [PATCH 0062/1160] Use m.room.sticker event. --- src/components/structures/FilePanel.js | 3 +++ src/components/views/rooms/EventTile.js | 1 + 2 files changed, 4 insertions(+) diff --git a/src/components/structures/FilePanel.js b/src/components/structures/FilePanel.js index ffa5e45249..6a8d0c5bdd 100644 --- a/src/components/structures/FilePanel.js +++ b/src/components/structures/FilePanel.js @@ -67,6 +67,9 @@ const FilePanel = React.createClass({ "room": { "timeline": { "contains_url": true, + "not_types": [ + "m.room.sticker", + ], }, }, }, diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 3407ea159d..46dc0d19db 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -33,6 +33,7 @@ const ObjectUtils = require('../../../ObjectUtils'); const eventTileTypes = { 'm.room.message': 'messages.MessageEvent', + 'm.room.sticker': 'messages.MessageEvent', 'm.call.invite': 'messages.TextualEvent', 'm.call.answer': 'messages.TextualEvent', 'm.call.hangup': 'messages.TextualEvent', From 0577316c8680c2d24b47b9d4699395a35fcdc2d9 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Mon, 8 Jan 2018 13:40:33 +0000 Subject: [PATCH 0063/1160] Fix duplicate event registration. --- src/components/views/elements/AppTile.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index fa8696ea74..46cccde19f 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -171,6 +171,7 @@ export default React.createClass({ componentDidMount() { // Legacy Jitsi widget messaging -- TODO replace this with standard widget // postMessaging API + dis.register(this._onAction); window.addEventListener('message', this._onMessage, false); }, @@ -346,8 +347,6 @@ export default React.createClass({ console.log("Failed to get widget capabilities", this.widgetId, err); }); this.setState({loading: false}); - - dis.register(this._onAction); }, _onAction(payload) { From adebf71a1d8b3d8bee237f6639fe7343314285d6 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Mon, 8 Jan 2018 15:38:01 +0000 Subject: [PATCH 0064/1160] Set user widgets on application data. --- src/ScalarMessaging.js | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index 7bde607451..7befee217a 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -291,6 +291,7 @@ function setWidget(event, roomId) { const widgetUrl = event.data.url; const widgetName = event.data.name; // optional const widgetData = event.data.data; // optional + const userWidget = event.data.userWidget; const client = MatrixClientPeg.get(); if (!client) { @@ -330,17 +331,32 @@ function setWidget(event, roomId) { name: widgetName, data: widgetData, }; - if (widgetUrl === null) { // widget is being deleted - content = {}; - } - client.sendStateEvent(roomId, "im.vector.modular.widgets", content, widgetId).done(() => { - sendResponse(event, { - success: true, + if (userWidget) { + const client = MatrixClientPeg.get(); + let userWidgets = client.getAccountData('m.widgets'); + + // Delete existing widget with ID + userWidgets = userWidgets.filter((widget) => widget.data.id === widgetId ? false : true); + + // Add new widget / update + if (widgetUrl !== null) { + userWidgets.push(content); + } + + client.setAccountData('m.widgets', userWidgets); + } else { // Room widget + if (widgetUrl === null) { // widget is being deleted + content = {}; + } + client.sendStateEvent(roomId, "im.vector.modular.widgets", content, widgetId).done(() => { + sendResponse(event, { + success: true, + }); + }, (err) => { + sendError(event, _t('Failed to send request.'), err); }); - }, (err) => { - sendError(event, _t('Failed to send request.'), err); - }); + } } function getWidgets(event, roomId) { From 60e7646f928e10845816b38810702f369ae15937 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Mon, 8 Jan 2018 16:47:49 +0000 Subject: [PATCH 0065/1160] Save user widgets in accountData --- src/ScalarMessaging.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index 7befee217a..41c667be25 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -333,18 +333,27 @@ function setWidget(event, roomId) { }; if (userWidget) { + console.warn('Adding user widget'); const client = MatrixClientPeg.get(); - let userWidgets = client.getAccountData('m.widgets'); + let userWidgets = client.getAccountData('m.widgets') || {}; // Delete existing widget with ID - userWidgets = userWidgets.filter((widget) => widget.data.id === widgetId ? false : true); + delete userWidgets[widgetId]; // Add new widget / update if (widgetUrl !== null) { - userWidgets.push(content); + userWidgets[widgetId] = { + content: content, + sender: client.getUserId(), + stateKey: widgetId, + type: 'm.widget', + }; } - client.setAccountData('m.widgets', userWidgets); + client.setAccountData('m.widgets', {widgets: userWidgets}); + sendResponse(event, { + success: true, + }); } else { // Room widget if (widgetUrl === null) { // widget is being deleted content = {}; From 9e9de765dc3ffad4362bf5bc061a7f744149719a Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Tue, 9 Jan 2018 14:37:45 +0000 Subject: [PATCH 0066/1160] Handle user widgets. --- src/ScalarMessaging.js | 70 +++++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 22 deletions(-) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index 41c667be25..40e985a5aa 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -335,10 +335,15 @@ function setWidget(event, roomId) { if (userWidget) { console.warn('Adding user widget'); const client = MatrixClientPeg.get(); - let userWidgets = client.getAccountData('m.widgets') || {}; + // client.setAccountData('m.widgets', {}); + const userWidgets = client.getAccountData('m.widgets').getContent() || {}; // Delete existing widget with ID - delete userWidgets[widgetId]; + try { + delete userWidgets[widgetId]; + } catch (e) { + console.error(`$widgetId is non-configurable`); + } // Add new widget / update if (widgetUrl !== null) { @@ -346,15 +351,21 @@ function setWidget(event, roomId) { content: content, sender: client.getUserId(), stateKey: widgetId, - type: 'm.widget', + type: 'im.vector.modular.widgets', + id: widgetId, }; } - client.setAccountData('m.widgets', {widgets: userWidgets}); + client.setAccountData('m.widgets', userWidgets); + console.warn(`Set user widgets to:`, client.getAccountData('m.widgets')); sendResponse(event, { success: true, }); } else { // Room widget + if (!roomId) { + sendError(event, _t('Missing roomId.'), null); + } + if (widgetUrl === null) { // widget is being deleted content = {}; } @@ -374,19 +385,30 @@ function getWidgets(event, roomId) { sendError(event, _t('You need to be logged in.')); return; } - const room = client.getRoom(roomId); - if (!room) { - sendError(event, _t('This room is not recognised.')); - return; - } - const stateEvents = room.currentState.getStateEvents("im.vector.modular.widgets"); - // Only return widgets which have required fields - const widgetStateEvents = []; - stateEvents.forEach((ev) => { - if (ev.getContent().type && ev.getContent().url) { - widgetStateEvents.push(ev.event); // return the raw event + let widgetStateEvents = []; + + if (roomId) { + const room = client.getRoom(roomId); + if (!room) { + sendError(event, _t('This room is not recognised.')); + return; } - }); + const stateEvents = room.currentState.getStateEvents("im.vector.modular.widgets"); + // Only return widgets which have required fields + if (room) { + stateEvents.forEach((ev) => { + if (ev.getContent().type && ev.getContent().url) { + widgetStateEvents.push(ev.event); // return the raw event + } + }); + } + } + + // Add user widgets (not linked to a specific room) + const userWidgets = client.getAccountData('m.widgets').getContent() || {}; + const userWidgetArray = Object.keys(userWidgets).map((key) => userWidgets[key]); + widgetStateEvents = widgetStateEvents.concat(userWidgetArray); + console.warn('Sending user widgets', userWidgetArray); sendResponse(event, widgetStateEvents); } @@ -595,6 +617,16 @@ const onMessage = function(event) { const roomId = event.data.room_id; const userId = event.data.user_id; + + // These APIs don't require roomId + if (event.data.action === "get_widgets") { + getWidgets(event, roomId); + return; + } else if (event.data.action === "set_widget") { + setWidget(event, roomId); + return; + } + if (!roomId) { sendError(event, _t('Missing room_id in request')); return; @@ -628,12 +660,6 @@ const onMessage = function(event) { } else if (event.data.action === "get_membership_count") { getMembershipCount(event, roomId); return; - } else if (event.data.action === "set_widget") { - setWidget(event, roomId); - return; - } else if (event.data.action === "get_widgets") { - getWidgets(event, roomId); - return; } else if (event.data.action === "get_room_enc_state") { getRoomEncState(event, roomId); return; From 6b0b25c2d26a34d7c4ba109ed25c268a7125134b Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Tue, 9 Jan 2018 16:01:53 +0000 Subject: [PATCH 0067/1160] Translations --- src/i18n/strings/en_EN.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index f28322398c..41f1b75e43 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -304,6 +304,8 @@ "Video call": "Video call", "Hide Apps": "Hide Apps", "Show Apps": "Show Apps", + "Hide Stickers": "Hide Stickers", + "Show Stickers": "Show Stickers", "Upload file": "Upload file", "Show Text Formatting Toolbar": "Show Text Formatting Toolbar", "Send an encrypted message": "Send an encrypted message", From 9abb1601207c4b41c37b83e9e5e289f47d3bd72a Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Tue, 9 Jan 2018 16:02:17 +0000 Subject: [PATCH 0068/1160] Replace apps button with stickers button in message composer. --- src/components/views/rooms/MessageComposer.js | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 2841f30423..84091e8a68 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -31,8 +31,8 @@ export default class MessageComposer extends React.Component { this.onCallClick = this.onCallClick.bind(this); this.onHangupClick = this.onHangupClick.bind(this); this.onUploadClick = this.onUploadClick.bind(this); - this.onShowAppsClick = this.onShowAppsClick.bind(this); - this.onHideAppsClick = this.onHideAppsClick.bind(this); + this.onShowStickersClick = this.onShowStickersClick.bind(this); + this.onHideStickersClick = this.onHideStickersClick.bind(this); this.onUploadFileSelected = this.onUploadFileSelected.bind(this); this.uploadFiles = this.uploadFiles.bind(this); this.onVoiceCallClick = this.onVoiceCallClick.bind(this); @@ -53,6 +53,7 @@ export default class MessageComposer extends React.Component { wordCount: 0, }, showFormatting: SettingsStore.getValue('MessageComposer.showFormatting'), + showStickers: false, }; } @@ -189,18 +190,12 @@ export default class MessageComposer extends React.Component { // this._startCallApp(true); } - onShowAppsClick(ev) { - dis.dispatch({ - action: 'appsDrawer', - show: true, - }); + onShowStickersClick(ev) { + this.setState({showStickers: true}); } - onHideAppsClick(ev) { - dis.dispatch({ - action: 'appsDrawer', - show: false, - }); + onHideStickersClick(ev) { + this.setState({showStickers: false}); } onInputContentChanged(content: string, selection: {start: number, end: number}) { @@ -268,7 +263,7 @@ export default class MessageComposer extends React.Component { alt={e2eTitle} title={e2eTitle} />, ); - let callButton, videoCallButton, hangupButton, showAppsButton, hideAppsButton; + let callButton, videoCallButton, hangupButton, showStickersButton, hideStickersButton; if (this.props.callState && this.props.callState !== 'ended') { hangupButton =
@@ -286,15 +281,23 @@ export default class MessageComposer extends React.Component { } // Apps - if (this.props.showApps) { - hideAppsButton = -
- + if (this.state.showStickers) { + hideStickersButton = +
+
; } else { - showAppsButton = -
- + showStickersButton = +
+
; } @@ -343,8 +346,8 @@ export default class MessageComposer extends React.Component { hangupButton, callButton, videoCallButton, - showAppsButton, - hideAppsButton, + showStickersButton, + hideStickersButton, ); } else { controls.push( @@ -409,7 +412,4 @@ MessageComposer.propTypes = { // callback when a file to upload is chosen uploadFile: React.PropTypes.func.isRequired, - - // string representing the current room app drawer state - showApps: React.PropTypes.bool, }; From 53b590f55e57031abf7c006058146a0ab0ed382b Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Wed, 10 Jan 2018 20:27:43 +0000 Subject: [PATCH 0069/1160] Add stickers popover. --- package.json | 1 + src/components/views/rooms/MessageComposer.js | 24 +++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 943c443c59..24f5e3ef58 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,7 @@ "react-dnd-html5-backend": "^2.1.2", "react-dom": "^15.4.0", "react-gemini-scrollbar": "matrix-org/react-gemini-scrollbar#5e97aef", + "react-simple-popover": "^0.2.2", "sanitize-html": "^1.14.1", "text-encoding-utf-8": "^1.0.1", "url": "^0.11.0", diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 84091e8a68..64dd6cf4ba 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -23,7 +23,7 @@ import sdk from '../../../index'; import dis from '../../../dispatcher'; import Autocomplete from './Autocomplete'; import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore"; - +import Popover from 'react-simple-popover'; export default class MessageComposer extends React.Component { constructor(props, context) { @@ -42,6 +42,7 @@ export default class MessageComposer extends React.Component { this.onToggleMarkdownClicked = this.onToggleMarkdownClicked.bind(this); this.onInputStateChanged = this.onInputStateChanged.bind(this); this.onEvent = this.onEvent.bind(this); + this.render = this.render.bind(this); this.state = { autocompleteQuery: '', @@ -280,15 +281,27 @@ export default class MessageComposer extends React.Component {
; } - // Apps + // Stickers if (this.state.showStickers) { + const children =

Stickers popover

; hideStickersButton =
+
; } else { showStickersButton = @@ -300,6 +313,10 @@ export default class MessageComposer extends React.Component {
; } + const stickersContainer =
+ { showStickersButton } + { hideStickersButton } +
; const canSendMessages = this.props.room.currentState.maySendMessage( MatrixClientPeg.get().credentials.userId); @@ -346,8 +363,7 @@ export default class MessageComposer extends React.Component { hangupButton, callButton, videoCallButton, - showStickersButton, - hideStickersButton, + stickersContainer, ); } else { controls.push( From 2bb51bafe1f865286749203aded16d460a7e11a1 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Wed, 10 Jan 2018 20:29:36 +0000 Subject: [PATCH 0070/1160] Content placeholder. --- src/components/views/rooms/MessageComposer.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 64dd6cf4ba..5c131c8a20 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -283,7 +283,7 @@ export default class MessageComposer extends React.Component { // Stickers if (this.state.showStickers) { - const children =

Stickers popover

; + const stickersContent =

Click here to add your first sitckerpack

; hideStickersButton =
; } else { From 52f28d09e0bdbac532b74f0763a56e65a4036d10 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Wed, 10 Jan 2018 20:44:14 +0000 Subject: [PATCH 0071/1160] Stickerpack styling --- src/components/views/rooms/MessageComposer.js | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 5c131c8a20..37e5e1f911 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -283,7 +283,15 @@ export default class MessageComposer extends React.Component { // Stickers if (this.state.showStickers) { - const stickersContent =

Click here to add your first sitckerpack

; + let stickerpackWidget = ''; + let stickersContent =

Click here to add your first sitckerpack

; + if (true) { + stickersContent = ; + } + hideStickersButton =
; From 1a994b88f52885350b75e0a825cbce90fca1f872 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 11 Jan 2018 10:32:37 +0000 Subject: [PATCH 0072/1160] Move widget utility functions in to their own file. --- src/ScalarMessaging.js | 7 +++--- src/utils/widgets.js | 56 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 src/utils/widgets.js diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index 40e985a5aa..9a57ab5bce 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -235,6 +235,7 @@ const SdkConfig = require('./SdkConfig'); const MatrixClientPeg = require("./MatrixClientPeg"); const MatrixEvent = require("matrix-js-sdk").MatrixEvent; const dis = require("./dispatcher"); +const Widgets = require('./utils/widgets'); import { _t } from './languageHandler'; function sendResponse(event, res) { @@ -405,10 +406,8 @@ function getWidgets(event, roomId) { } // Add user widgets (not linked to a specific room) - const userWidgets = client.getAccountData('m.widgets').getContent() || {}; - const userWidgetArray = Object.keys(userWidgets).map((key) => userWidgets[key]); - widgetStateEvents = widgetStateEvents.concat(userWidgetArray); - console.warn('Sending user widgets', userWidgetArray); + const userWidgets = Widgets.getUserWidgets(); + widgetStateEvents = widgetStateEvents.concat(userWidgets); sendResponse(event, widgetStateEvents); } diff --git a/src/utils/widgets.js b/src/utils/widgets.js new file mode 100644 index 0000000000..4e26fa6ceb --- /dev/null +++ b/src/utils/widgets.js @@ -0,0 +1,56 @@ +import MatrixClientPeg from '../MatrixClientPeg'; + +/** + * Get all widgets (user and room) for the current user + * @param {object} room The room to get widgets for + * @return {[object]} Array containing current / active room and user widget state events + */ +function getWidgets(room) { + const widgets = getRoomWidgets(room); + widgets.concat(getUserWidgets()); + return widgets; +} + +/** + * Get room specific widgets + * @param {object} room The room to get widgets force + * @return {[object]} Array containing current / active room widgets + */ +function getRoomWidgets(room) { + const appsStateEvents = room.currentState.getStateEvents('im.vector.modular.widgets'); + if (!appsStateEvents) { + return []; + } + + return appsStateEvents.filter((ev) => { + return ev.getContent().type && ev.getContent().url; + }); +} + +/** + * Get user specific widgets (not linked to a specific room) + * @return {[object]} Array containing current / active user widgets + */ +function getUserWidgets() { + const client = MatrixClientPeg.get(); + if (!client) { + throw new Error('User not logged in'); + } + const userWidgets = client.getAccountData('m.widgets').getContent() || {}; + return Object.keys(userWidgets).map((key) => userWidgets[key]); +} + +/** + * Get active stickerpack widgets (stickerpacks are user widgets by nature) + * @return {[object]} Array containing current / active stickerpack widgets + */ +function getStickerpackWidgets() { + return getUserWidgets().filter((widget) => widget.type='stickerpack'); +} + +export default { + getWidgets, + getRoomWidgets, + getUserWidgets, + getStickerpackWidgets, +}; From 5e7fab1e15cb01cea6c9ef4575db2de3642993ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Thu, 11 Jan 2018 10:39:19 +0000 Subject: [PATCH 0073/1160] Translated using Weblate (French) Currently translated at 100.0% (967 of 967 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 3efb93b125..2929e0f3a3 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -957,5 +957,14 @@ "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Vous ne pourrez pas annuler cette modification car vous vous destituez. Si vous êtes le dernier utilisateur privilégié de ce salon, il sera impossible de récupérer les privilèges.", "%(count)s of your messages have not been sent.|one": "Votre message n'a pas été envoyé.", "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "Tout renvoyer ou tout annuler maintenant. Vous pouvez aussi choisir des messages individuels à renvoyer ou annuler.", - "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Renvoyer le message ou annuler le message maintenant." + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Renvoyer le message ou annuler le message maintenant.", + "Message Replies": "Réponses", + "Send an encrypted reply…": "Envoyer une réponse chiffrée…", + "Send a reply (unencrypted)…": "Envoyer une réponse (non chiffrée)…", + "Send an encrypted message…": "Envoyer un message chiffré…", + "Send a message (unencrypted)…": "Envoyer un message (non chiffré)…", + "Replying": "Répond", + "Minimize apps": "Minimiser les applications", + "Quote": "Citer", + "Show devices, mark devices known and send or cancel all.": "Afficher les appareils, marquer les appareils comme connus et envoyer ou tout annuler." } From 0ce043ab12b4075a58f9020c21836ba9ef43c4cb Mon Sep 17 00:00:00 2001 From: Andrey Date: Thu, 11 Jan 2018 10:49:04 +0000 Subject: [PATCH 0074/1160] Translated using Weblate (Russian) Currently translated at 99.5% (963 of 967 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index c56beebf7f..a060e1398b 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -957,5 +957,10 @@ "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Вы не сможете отменить это изменение после понижения себя, в случае если вы являетесь последним привилегированным пользователем в этой комнате.", "%(count)s of your messages have not been sent.|one": "Ваше сообщение не было отправлено.", "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "Отправить все или отменить все сейчас. Можно также выбрать отдельные сообщения для отправки или отмены.", - "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Отправить или отменить сообщение сейчас." + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Отправить или отменить сообщение сейчас.", + "Message Replies": "Ответы на сообщения", + "Send an encrypted reply…": "Отправить зашифрованный ответ…", + "Send a reply (unencrypted)…": "Отправить ответ (незашифрованный)…", + "Send an encrypted message…": "Отправить зашифрованное сообщение…", + "Send a message (unencrypted)…": "Отправить сообщение (незашифрованное)…" } From 62ced91356c6eb8d3c2c08a9fc91a76fda192ecd Mon Sep 17 00:00:00 2001 From: Andrey Date: Thu, 11 Jan 2018 10:51:03 +0000 Subject: [PATCH 0075/1160] Translated using Weblate (Russian) Currently translated at 100.0% (967 of 967 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index a060e1398b..33d1474c2b 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -962,5 +962,9 @@ "Send an encrypted reply…": "Отправить зашифрованный ответ…", "Send a reply (unencrypted)…": "Отправить ответ (незашифрованный)…", "Send an encrypted message…": "Отправить зашифрованное сообщение…", - "Send a message (unencrypted)…": "Отправить сообщение (незашифрованное)…" + "Send a message (unencrypted)…": "Отправить сообщение (незашифрованное)…", + "Replying": "Отвечая", + "Minimize apps": "Свернуть приложения", + "Quote": "Цитата", + "Show devices, mark devices known and send or cancel all.": "Показать устройства, отметить известные устройства и отправить или отменить все." } From 2cf9da8c954f85e20faea386a92936867332e748 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 11 Jan 2018 11:12:46 +0000 Subject: [PATCH 0076/1160] Load user stickerpacks --- src/components/views/rooms/MessageComposer.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 37e5e1f911..b26a3b2c17 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -24,6 +24,7 @@ import dis from '../../../dispatcher'; import Autocomplete from './Autocomplete'; import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore"; import Popover from 'react-simple-popover'; +import Widgets from '../../../utils/widgets'; export default class MessageComposer extends React.Component { constructor(props, context) { @@ -283,10 +284,11 @@ export default class MessageComposer extends React.Component { // Stickers if (this.state.showStickers) { - let stickerpackWidget = ''; + const stickerpackWidget = Widgets.getStickerpackWidgets()[0]; + console.warn('Stickerpack widgets', stickerpackWidget); let stickersContent =

Click here to add your first sitckerpack

; - if (true) { - stickersContent = ; From 8f26155c16678fd7ec7fc9d31e82ac3185153f42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Thu, 11 Jan 2018 11:19:52 +0000 Subject: [PATCH 0077/1160] Translated using Weblate (French) Currently translated at 100.0% (980 of 980 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 2929e0f3a3..c62e564d46 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -966,5 +966,18 @@ "Replying": "Répond", "Minimize apps": "Minimiser les applications", "Quote": "Citer", - "Show devices, mark devices known and send or cancel all.": "Afficher les appareils, marquer les appareils comme connus et envoyer ou tout annuler." + "Show devices, mark devices known and send or cancel all.": "Afficher les appareils, marquer les appareils comme connus et envoyer ou tout annuler.", + "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Le respect de votre vie privée est important pour nous, donc nous ne collectons aucune donnée personnelle ou permettant de vous identifier pour nos statistiques.", + "Learn more about how we use analytics.": "En savoir plus sur notre utilisation des statistiques.", + "The information being sent to us to help make Riot.im better includes:": "Les informations qui nous sont envoyées pour nous aider à améliorer Riot.im comprennent :", + "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "Nous enregistrons aussi chaque page que vous utilisez dans l'application (en ce moment ), votre User Agent () et la résolution de votre appareil ().", + "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Si la page contient des informations permettant de vous identifier, comme un salon, un identifiant d'utilisateur ou de groupe, ces données sont enlevées avant qu'elle ne soit envoyée au serveur.", + "The platform you're on": "La plateforme que vous utilisez", + "The version of Riot.im": "La version de Riot.im", + "Whether or not you're logged in (we don't record your user name)": "Si vous êtes connecté ou non (nous n'enregistrons pas votre nom d'utilisateur)", + "Your language of choice": "La langue que vous avez choisie", + "Which officially provided instance you are using, if any": "Quelle instance officielle vous utilisez, si c'est le cas", + "Whether or not you're using the Richtext mode of the Rich Text Editor": "Si vous utilisez le mode de texte enrichi de l'éditeur de texte enrichi", + "Your homeserver's URL": "L'URL de votre serveur d'accueil", + "Your identity server's URL": "L'URL de votre serveur d'identité" } From 78bd25eff0a75a2c6bacc41460085ec3651624f7 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 11 Jan 2018 11:36:19 +0000 Subject: [PATCH 0078/1160] Sticker popover styling --- src/components/views/rooms/MessageComposer.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index b26a3b2c17..ba7b238bd3 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -289,8 +289,8 @@ export default class MessageComposer extends React.Component { let stickersContent =

Click here to add your first sitckerpack

; if (stickerpackWidget && stickerpackWidget.content && stickerpackWidget.content.url) { stickersContent = ; } @@ -309,12 +309,14 @@ export default class MessageComposer extends React.Component { show={this.state.showStickers} onHide={this.onHideStickersClick} containerStyle={{ - zIndex: 100, + zIndex: 1000, }} style={{ borderRadius: '5px', width: 'initial', padding: 0, + overflow: 'hidden', + height: '160px' }} children={stickersContent} /> From d0c16fa7a1fa604425102d9e45768c494f7b2028 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 11 Jan 2018 11:49:46 +0000 Subject: [PATCH 0079/1160] Convert to ES6 class. --- src/components/views/elements/AppTile.js | 104 +++++++++++------------ 1 file changed, 51 insertions(+), 53 deletions(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 46cccde19f..4759537960 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -1,4 +1,4 @@ -/* +/** Copyright 2017 Vector Creations Ltd Licensed under the Apache License, Version 2.0 (the "License"); @@ -36,31 +36,8 @@ import dis from '../../../dispatcher'; const ALLOWED_APP_URL_SCHEMES = ['https:', 'http:']; -export default React.createClass({ - displayName: 'AppTile', - - propTypes: { - id: React.PropTypes.string.isRequired, - url: React.PropTypes.string.isRequired, - name: React.PropTypes.string.isRequired, - room: React.PropTypes.object.isRequired, - type: React.PropTypes.string.isRequired, - // Specifying 'fullWidth' as true will render the app tile to fill the width of the app drawer continer. - // This should be set to true when there is only one widget in the app drawer, otherwise it should be false. - fullWidth: React.PropTypes.bool, - // UserId of the current user - userId: React.PropTypes.string.isRequired, - // UserId of the entity that added / modified the widget - creatorUserId: React.PropTypes.string, - waitForIframeLoad: React.PropTypes.bool, - }, - - getDefaultProps() { - return { - url: "", - waitForIframeLoad: true, - }; - }, +export default class AppTile extends React.Component { + static displayName ='AppTile'; /** * Set initial component state when the App wUrl (widget URL) is being updated. @@ -84,7 +61,7 @@ export default React.createClass({ widgetPageTitle: newProps.widgetPageTitle, capabilities: [], }; - }, + } /** @@ -94,7 +71,7 @@ export default React.createClass({ */ _hasCapability(capability) { return this.state.capabilities.some((c) => {return c === capability;}); - }, + } /** * Add widget instance specific parameters to pass in wUrl @@ -122,11 +99,11 @@ export default React.createClass({ u.query = params; return u.format(); - }, + } getInitialState() { return this._getNewState(this.props); - }, + } /** * Returns true if specified url is a scalar URL, typically https://scalar.vector.im/api @@ -150,7 +127,7 @@ export default React.createClass({ } } return false; - }, + } isMixedContent() { const parentContentProtocol = window.location.protocol; @@ -162,18 +139,18 @@ export default React.createClass({ return true; } return false; - }, + } componentWillMount() { this.setScalarToken(); - }, + } componentDidMount() { // Legacy Jitsi widget messaging -- TODO replace this with standard widget // postMessaging API dis.register(this._onAction); window.addEventListener('message', this._onMessage, false); - }, + } /** * Adds a scalar token to the widget URL, if required @@ -225,14 +202,14 @@ export default React.createClass({ initialising: false, }); }); - }, + } componentWillUnmount() { this.widgetMessaging.stopListening(); this.widgetMessaging.removeEndpoint(this.props.id, this.props.url); dis.unregister(this._onAction); window.removeEventListener('message', this._onMessage); - }, + } componentWillReceiveProps(nextProps) { if (nextProps.url !== this.props.url) { @@ -247,7 +224,7 @@ export default React.createClass({ widgetPageTitle: nextProps.widgetPageTitle, }); } - }, + } // Legacy Jitsi widget messaging // TODO -- This should be replaced with the new widget postMessaging API @@ -268,11 +245,11 @@ export default React.createClass({ .document.querySelector('iframe[id^="jitsiConferenceFrame"]'); PlatformPeg.get().setupScreenSharingForIframe(iframe); } - }, + } _canUserModify() { return WidgetUtils.canUserModifyWidgets(this.props.room.roomId); - }, + } _onEditClick(e) { console.log("Edit widget ID ", this.props.id); @@ -282,7 +259,7 @@ export default React.createClass({ Modal.createTrackedDialog('Integrations Manager', '', IntegrationsManager, { src: src, }, "mx_IntegrationsManager"); - }, + } _onSnapshotClick(e) { console.warn("Requesting widget snapshot"); @@ -294,7 +271,7 @@ export default React.createClass({ }).catch((err) => { console.error("Failed to get screenshot", err); }); - }, + } /* If user has permission to modify widgets, delete the widget, * otherwise revoke access for the widget to load in the user's browser @@ -329,7 +306,7 @@ export default React.createClass({ console.log("Revoke widget permissions - %s", this.props.id); this._revokeWidgetPermission(); } - }, + } /** * Called when widget iframe has finished loading @@ -347,7 +324,7 @@ export default React.createClass({ console.log("Failed to get widget capabilities", this.widgetId, err); }); this.setState({loading: false}); - }, + } _onAction(payload) { if (payload.widgetId === this.props.id) { @@ -361,7 +338,7 @@ export default React.createClass({ break; } } - }, + } /** * Set remote content title on AppTile @@ -375,7 +352,7 @@ export default React.createClass({ }, (err) =>{ console.error("Failed to get page title", err); }); - }, + } // Widget labels to render, depending upon user permissions // These strings are translated at the point that they are inserted in to the DOM, in the render method @@ -384,20 +361,20 @@ export default React.createClass({ return _td('Delete widget'); } return _td('Revoke widget access'); - }, + } /* TODO -- Store permission in account data so that it is persisted across multiple devices */ _grantWidgetPermission() { console.warn('Granting permission to load widget - ', this.state.widgetUrl); localStorage.setItem(this.state.widgetPermissionId, true); this.setState({hasPermissionToLoad: true}); - }, + } _revokeWidgetPermission() { console.warn('Revoking permission to load widget - ', this.state.widgetUrl); localStorage.removeItem(this.state.widgetPermissionId); this.setState({hasPermissionToLoad: false}); - }, + } formatAppTileName() { let appTileName = "No name"; @@ -405,7 +382,7 @@ export default React.createClass({ appTileName = this.props.name.trim(); } return appTileName; - }, + } onClickMenuBar(ev) { ev.preventDefault(); @@ -420,7 +397,7 @@ export default React.createClass({ action: 'appsDrawer', show: !this.props.show, }); - }, + } _getSafeUrl() { const parsedWidgetUrl = url.parse(this.state.widgetUrl); @@ -429,7 +406,7 @@ export default React.createClass({ safeWidgetUrl = url.format(parsedWidgetUrl); } return safeWidgetUrl; - }, + } render() { let appTileBody; @@ -556,5 +533,26 @@ export default React.createClass({ { appTileBody }
); - }, -}); + } +} + +AppTile.propTypes = { + id: React.PropTypes.string.isRequired, + url: React.PropTypes.string.isRequired, + name: React.PropTypes.string.isRequired, + room: React.PropTypes.object.isRequired, + type: React.PropTypes.string.isRequired, + // Specifying 'fullWidth' as true will render the app tile to fill the width of the app drawer continer. + // This should be set to true when there is only one widget in the app drawer, otherwise it should be false. + fullWidth: React.PropTypes.bool, + // UserId of the current user + userId: React.PropTypes.string.isRequired, + // UserId of the entity that added / modified the widget + creatorUserId: React.PropTypes.string, + waitForIframeLoad: React.PropTypes.bool, +}; + +AppTile.defaultProps = { + url: "", + waitForIframeLoad: true, +}; From da562e015cbef4df56e89c805c72e31037b97a01 Mon Sep 17 00:00:00 2001 From: Klaus Marx Date: Thu, 11 Jan 2018 11:16:26 +0000 Subject: [PATCH 0080/1160] Translated using Weblate (German) Currently translated at 99.2% (973 of 980 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index ec2d43aed7..f60b4e582d 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -952,5 +952,25 @@ "Show devices or cancel all.": "Geräte anzeigen oder alle abbrechen.", "Warning": "Warnung", "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "Eine tiefgreifende Migration im Kontext der Verschlüsselungsdaten wurde durchgeführt. Ende-zu-Ende-Verschlüsselung wird nicht mehr funktionieren, wenn du zu einer älteren Version von Riot zurückkehrst. Wenn du Ende-zu-Ende-Verschlüssung bei einer älteren Version von Riot brauchst, melde dich bitte vorher ab. Um die Historie zu behalten, ex- und reimportiere deine Schlüssel.", - "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Es wurden Daten von einer älteren Version von Riot entdeckt. Dies wird zu Fehlern in der Ende-zu-Ende-Verschlüsselung der älteren Version geführt haben. Ende-zu-Ende verschlüsselte Nachrichten, die ausgetauscht wruden, während die ältere Version genutzt wurde, werden in dieser Version nicht entschlüsselbar sein. Es kann auch zu Fehlern mit Nachrichten führen, die mit dieser Version versendet werden. Wenn du Probleme feststellst, melde dich ab und wieder an. Um die Historie zu behalten, ex- und reimportiere deine Schlüssel." + "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Es wurden Daten von einer älteren Version von Riot entdeckt. Dies wird zu Fehlern in der Ende-zu-Ende-Verschlüsselung der älteren Version geführt haben. Ende-zu-Ende verschlüsselte Nachrichten, die ausgetauscht wruden, während die ältere Version genutzt wurde, werden in dieser Version nicht entschlüsselbar sein. Es kann auch zu Fehlern mit Nachrichten führen, die mit dieser Version versendet werden. Wenn du Probleme feststellst, melde dich ab und wieder an. Um die Historie zu behalten, ex- und reimportiere deine Schlüssel.", + "Send an encrypted reply…": "Verschlüsselte Antwort senden…", + "Send a reply (unencrypted)…": "Antwort senden (unverschlüsselt)…", + "Send an encrypted message…": "Verschlüsselte Nachricht senden…", + "Send a message (unencrypted)…": "Nachricht senden (unverschlüsselt)…", + "Replying": "Antwortet", + "Minimize apps": "Apps minimieren", + "Quote": "Zitat", + "Show devices, mark devices known and send or cancel all.": "Geräte anzeigen, Geräte als bekannt markieren und senden oder alles abbrechen.", + "%(count)s of your messages have not been sent.|one": "Deine Nachricht wurde nicht gesendet.", + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "Jetzt alle erneut senden oder alle abbrechen. Du kannst auch einzelne Nachrichten auswählen und erneut senden oder abbrechen.", + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Nachricht jetzt erneut senden oder senden abbrechen now.", + "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Privatsphäre ist uns wichtig, deshalb sammeln wir keine persönlichen oder identifizierbaren Daten für unsere Analysen.", + "The information being sent to us to help make Riot.im better includes:": "Die Informationen, die an uns gesendet werden um Riot.im zu verbessern enthalten:", + "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "Wir speichern auch jede Seite, die du in der App benutzt (currently ), deinen User Agent () und die Bildschirmauflösung deines Gerätes ().", + "The platform you're on": "Benutzte Plattform", + "The version of Riot.im": "Riot.im Version", + "Your language of choice": "Deine ausgewählte Sprache", + "Whether or not you're using the Richtext mode of the Rich Text Editor": "Ob du den Richtext-Modus des Editors benutzt oder nicht", + "Your homeserver's URL": "Die URL deines Homeservers", + "Your identity server's URL": "Die URL deines Identitätsservers" } From 0ad84f4ab5fe896d598c2061d3960a91f530046d Mon Sep 17 00:00:00 2001 From: Andrey Date: Thu, 11 Jan 2018 11:24:36 +0000 Subject: [PATCH 0081/1160] Translated using Weblate (Russian) Currently translated at 99.7% (978 of 980 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 33d1474c2b..6e8bbdb7a4 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -966,5 +966,16 @@ "Replying": "Отвечая", "Minimize apps": "Свернуть приложения", "Quote": "Цитата", - "Show devices, mark devices known and send or cancel all.": "Показать устройства, отметить известные устройства и отправить или отменить все." + "Show devices, mark devices known and send or cancel all.": "Показать устройства, отметить известные устройства и отправить или отменить все.", + "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Конфиденциальность важна для нас, поэтому мы не собираем никаких личных или идентифицируемых данных для нашей аналитики.", + "Learn more about how we use analytics.": "Подробнее о том, как мы используем аналитику.", + "The information being sent to us to help make Riot.im better includes:": "Информация направляемая нам, чтобы помочь сделать Riot.im лучше включает в себя:", + "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "Мы также записываем каждую страницу, которую вы используете в приложении (в данный момент ), ваш пользовательский агент () и разрешение экрана вашего устройства ().", + "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Если на этой странице содержатся идентифицируемые сведения, например номер, идентификатор пользователя или группы, эти данные удаляются перед отправкой на сервер.", + "The platform you're on": "Используемая платформа", + "The version of Riot.im": "Версия Riot.im", + "Whether or not you're logged in (we don't record your user name)": "Независимо от того, вошли вы или нет (мы не записываем ваше имя пользователя)", + "Your language of choice": "Выбранный вами язык", + "Your homeserver's URL": "URL-адрес домашнего сервера", + "Your identity server's URL": "URL-адрес вашего идентификационного сервера" } From 3163673705dfafeb276d2806821bb230077f82eb Mon Sep 17 00:00:00 2001 From: Szimszon Date: Thu, 11 Jan 2018 12:30:29 +0000 Subject: [PATCH 0082/1160] Translated using Weblate (Hungarian) Currently translated at 100.0% (980 of 980 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 936d152e3e..885d7a89b7 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -957,5 +957,27 @@ "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Ahogy lefokozod magad a változás visszafordíthatatlan, ha te vagy az utolsó jogosultságokkal bíró felhasználó a szobában a jogok már nem szerezhetők vissza.", "%(count)s of your messages have not been sent.|one": "Az üzeneted nem lett elküldve.", "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "Újraküldöd mind vagy elveted mind. Az üzeneteket egyenként is elküldheted vagy elvetheted.", - "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Üzenet újraküldése vagy üzenet elvetése most." + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Üzenet újraküldése vagy üzenet elvetése most.", + "Message Replies": "Üzenet válaszok", + "Send an encrypted reply…": "Titkosított válasz küldése…", + "Send a reply (unencrypted)…": "Válasz küldése (titkosítatlanul)…", + "Send an encrypted message…": "Titkosított üzenet küldése…", + "Send a message (unencrypted)…": "Üzenet küldése (titkosítás nélkül)…", + "Replying": "Válaszolni", + "Minimize apps": "Alkalmazás összecsukása", + "Quote": "Idézet", + "Show devices, mark devices known and send or cancel all.": "Eszközök megjelenítése, eszközök ismertnek jelölése és küldés vagy mindent megszakít.", + "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "A személyes adatok védelme fontos számunkra, így mi nem gyűjtünk személyes és személyhez köthető adatokat az analitikánkhoz.", + "Learn more about how we use analytics.": "Tudj meg többet arról hogyan használjuk az analitikai adatokat.", + "The information being sent to us to help make Riot.im better includes:": "Az adatok amiket a Riot.im javításához felhasználunk az alábbiak:", + "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "Felvesszük az összes oldalt amit az alkalmazásban használsz (jelenleg ), a \"User Agent\"-et () és az eszköz felbontását ().", + "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Minden azonosításra alkalmas adatot mint a szoba, felhasználó vagy csoport azonosítót mielőtt az adatokat elküldenénk eltávolításra kerülnek.", + "The platform you're on": "Ezt a platformot használod:", + "The version of Riot.im": "Riot.im verziója", + "Whether or not you're logged in (we don't record your user name)": "Be vagy-e jelentkezve vagy nem (a felhasználói nevedet nem tároljuk)", + "Your language of choice": "A használt nyelv", + "Which officially provided instance you are using, if any": "Milyen hivatalosan nyújtott verziót használsz", + "Whether or not you're using the Richtext mode of the Rich Text Editor": "Használod-e a Richtext módot a szerkesztőben vagy nem", + "Your homeserver's URL": "Az egyedi szerver URL-t", + "Your identity server's URL": "Az azonosítási szerver URL-t" } From 4f3670941d187ecba0e2223543abfe824c718eca Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 11 Jan 2018 12:33:02 +0000 Subject: [PATCH 0083/1160] Bind functions --- src/components/views/elements/AppTile.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 4759537960..4bbc06413d 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -39,6 +39,19 @@ const ALLOWED_APP_URL_SCHEMES = ['https:', 'http:']; export default class AppTile extends React.Component { static displayName ='AppTile'; + constructor(props) { + super(props); + this.state = this._getNewState(this.props); + + this._onAction = this._onAction.bind(this); + this._onMessage = this._onMessage.bind(this); + this._onLoaded = this._onLoaded.bind(this); + this._onEditClick = this._onEditClick.bind(this); + this._onDeleteClick = this._onDeleteClick.bind(this); + this._onSnapshotClick = this._onSnapshotClick.bind(this); + this.onClickMenuBar = this.onClickMenuBar.bind(this); + } + /** * Set initial component state when the App wUrl (widget URL) is being updated. * Component props *must* be passed (rather than relying on this.props). @@ -101,9 +114,6 @@ export default class AppTile extends React.Component { return u.format(); } - getInitialState() { - return this._getNewState(this.props); - } /** * Returns true if specified url is a scalar URL, typically https://scalar.vector.im/api From 1ab71f6f50092aeafc4de44bc9f248c9e8a021d9 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 11 Jan 2018 13:20:58 +0000 Subject: [PATCH 0084/1160] Load stickers in AppTile --- src/components/views/elements/AppTile.js | 16 ++++++++++---- src/components/views/rooms/MessageComposer.js | 22 +++++++++++++++---- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 4bbc06413d..60df6ade9b 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -41,7 +41,8 @@ export default class AppTile extends React.Component { constructor(props) { super(props); - this.state = this._getNewState(this.props); + console.warn('AppTile constructor', props); + this.state = this._getNewState(props); this._onAction = this._onAction.bind(this); this._onMessage = this._onMessage.bind(this); @@ -158,8 +159,10 @@ export default class AppTile extends React.Component { componentDidMount() { // Legacy Jitsi widget messaging -- TODO replace this with standard widget // postMessaging API - dis.register(this._onAction); window.addEventListener('message', this._onMessage, false); + + // General event handler + dis.register(this._onAction); } /** @@ -322,7 +325,7 @@ export default class AppTile extends React.Component { * Called when widget iframe has finished loading */ _onLoaded() { - // console.warn("App frame loaded", this.props.id); + console.warn("App frame loaded", this.props.id); this.widgetMessaging = new WidgetMessaging(this.props.id, this.refs.appFrame.contentWindow); this.widgetMessaging.startListening(); this.widgetMessaging.addEndpoint(this.props.id, this.props.url); @@ -494,6 +497,7 @@ export default class AppTile extends React.Component { return (
+ { this.props.showMenubar &&
-
+
} { appTileBody }
); @@ -560,9 +564,13 @@ AppTile.propTypes = { // UserId of the entity that added / modified the widget creatorUserId: React.PropTypes.string, waitForIframeLoad: React.PropTypes.bool, + showMenubar: React.PropTypes.bool, + // Should the AppTile render itself + show: React.PropTypes.bool, }; AppTile.defaultProps = { url: "", waitForIframeLoad: true, + showMenubar: true, }; diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index ba7b238bd3..7e318c57d5 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -25,6 +25,7 @@ import Autocomplete from './Autocomplete'; import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore"; import Popover from 'react-simple-popover'; import Widgets from '../../../utils/widgets'; +import AppTile from '../elements/AppTile'; export default class MessageComposer extends React.Component { constructor(props, context) { @@ -285,13 +286,26 @@ export default class MessageComposer extends React.Component { // Stickers if (this.state.showStickers) { const stickerpackWidget = Widgets.getStickerpackWidgets()[0]; - console.warn('Stickerpack widgets', stickerpackWidget); let stickersContent =

Click here to add your first sitckerpack

; if (stickerpackWidget && stickerpackWidget.content && stickerpackWidget.content.url) { - stickersContent = ; + }}> + +
; } hideStickersButton = @@ -316,7 +330,7 @@ export default class MessageComposer extends React.Component { width: 'initial', padding: 0, overflow: 'hidden', - height: '160px' + height: '160px', }} children={stickersContent} /> From 9df4dae9755c14619c4a55c283b58b5d14ef42fc Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 11 Jan 2018 13:41:20 +0000 Subject: [PATCH 0085/1160] Used forked version of react-popover --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 24f5e3ef58..43a5ebfcfd 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "react-dnd-html5-backend": "^2.1.2", "react-dom": "^15.4.0", "react-gemini-scrollbar": "matrix-org/react-gemini-scrollbar#5e97aef", - "react-simple-popover": "^0.2.2", + "react-simple-popover": "matrix-org/react-popover", "sanitize-html": "^1.14.1", "text-encoding-utf-8": "^1.0.1", "url": "^0.11.0", From 90b7cb37607477a3a59253db5d0722db2caf1c70 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 11 Jan 2018 13:41:55 +0000 Subject: [PATCH 0086/1160] Consistent popover size --- src/components/views/rooms/MessageComposer.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 7e318c57d5..9f4a017689 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -285,12 +285,15 @@ export default class MessageComposer extends React.Component { // Stickers if (this.state.showStickers) { + const popoverWidth = '300px'; + const popoverHeight = '300px'; const stickerpackWidget = Widgets.getStickerpackWidgets()[0]; let stickersContent =

Click here to add your first sitckerpack

; if (stickerpackWidget && stickerpackWidget.content && stickerpackWidget.content.url) { stickersContent =
From 18098da94a10e04e162c03c4d56b9982def5f1b2 Mon Sep 17 00:00:00 2001 From: Osoitz Date: Thu, 11 Jan 2018 12:57:54 +0000 Subject: [PATCH 0087/1160] Translated using Weblate (Basque) Currently translated at 98.8% (969 of 980 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eu/ --- src/i18n/strings/eu.json | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index c6d09f115a..c50ba9ed77 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -957,5 +957,16 @@ "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Ezin izango duzu hau aldatu zure burua mailaz jaisten ari zarelako, zu bazara gelan baimenak dituen azken erabiltzailea ezin izango dira baimenak berreskuratu.", "%(count)s of your messages have not been sent.|one": "Zure mezua ez da bidali.", "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "Birbidali guztiak edo baztertu guztiak orain. Mezuak banaka birbidali edo baztertu ditzakezu ere.", - "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Birbidali mezua edo baztertu mezua orain." + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Birbidali mezua edo baztertu mezua orain.", + "Message Replies": "Mezuei erantzunak", + "Send an encrypted reply…": "Bidali zifratutako erantzun bat…", + "Send a reply (unencrypted)…": "Bidali erantzun bat (zifratu gabea)…", + "Send an encrypted message…": "Bidali zifratutako mezu bat…", + "Send a message (unencrypted)…": "Bidali mezu bat (zifratu gabea)…", + "Replying": "Erantzuten", + "Minimize apps": "Minimizatu aplikazioak", + "Quote": "Aipua", + "The platform you're on": "Zauden plataforma", + "The version of Riot.im": "Riot.im bertsioa", + "Your language of choice": "Zure aukerako hizkuntza" } From 7a324b4104fc3ca5a3cfde2f350e835aae91acec Mon Sep 17 00:00:00 2001 From: Szimszon Date: Thu, 11 Jan 2018 12:34:08 +0000 Subject: [PATCH 0088/1160] Translated using Weblate (Hungarian) Currently translated at 100.0% (980 of 980 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 885d7a89b7..6384644925 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -972,7 +972,7 @@ "The information being sent to us to help make Riot.im better includes:": "Az adatok amiket a Riot.im javításához felhasználunk az alábbiak:", "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "Felvesszük az összes oldalt amit az alkalmazásban használsz (jelenleg ), a \"User Agent\"-et () és az eszköz felbontását ().", "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Minden azonosításra alkalmas adatot mint a szoba, felhasználó vagy csoport azonosítót mielőtt az adatokat elküldenénk eltávolításra kerülnek.", - "The platform you're on": "Ezt a platformot használod:", + "The platform you're on": "A platform amit használsz", "The version of Riot.im": "Riot.im verziója", "Whether or not you're logged in (we don't record your user name)": "Be vagy-e jelentkezve vagy nem (a felhasználói nevedet nem tároljuk)", "Your language of choice": "A használt nyelv", From 23543614e1752be9c29ba5ad399ecb9b650cef9b Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Fri, 12 Jan 2018 09:52:53 +0000 Subject: [PATCH 0089/1160] Add react-popover-tiny --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 43a5ebfcfd..36f35556fc 100644 --- a/package.json +++ b/package.json @@ -82,6 +82,7 @@ "react-dom": "^15.4.0", "react-gemini-scrollbar": "matrix-org/react-gemini-scrollbar#5e97aef", "react-simple-popover": "matrix-org/react-popover", + "react-tiny-popover": "^3.2.5", "sanitize-html": "^1.14.1", "text-encoding-utf-8": "^1.0.1", "url": "^0.11.0", From a40dafd701d35346e02a900d86f8b0d63141bcce Mon Sep 17 00:00:00 2001 From: Osoitz Date: Fri, 12 Jan 2018 12:38:08 +0000 Subject: [PATCH 0090/1160] Translated using Weblate (Basque) Currently translated at 100.0% (980 of 980 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eu/ --- src/i18n/strings/eu.json | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index c50ba9ed77..5309a76148 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -968,5 +968,16 @@ "Quote": "Aipua", "The platform you're on": "Zauden plataforma", "The version of Riot.im": "Riot.im bertsioa", - "Your language of choice": "Zure aukerako hizkuntza" + "Your language of choice": "Zure aukerako hizkuntza", + "Show devices, mark devices known and send or cancel all.": "Erakutsi gailuak, markatu gailuak ezagun gisa eta bidali edo ezeztatu guztia.", + "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Pribatutasuna garrantzitsua da guretzat, beraz ez dugu datu pertsonalik edo identifikagarririk jasotzen gure estatistiketan.", + "Learn more about how we use analytics.": "Ikasi gehiago estatistikei ematen diegun erabileraz.", + "The information being sent to us to help make Riot.im better includes:": "Riot.im hobetzeko bidaltzen zaigun informazioan hau dago:", + "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "Aplikazioan erabiltzen duzun orri bakoitza jasotzen dugu (orain ), erabiltzaile-agentea () eta gailuaren bereizmena ().", + "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Orri honek informazio identifikagarria badu ere, esaterako gela, erabiltzailea edo talde ID-a, datu hauek ezabatu egiten dira zerbitzarira bidali aurretik.", + "Whether or not you're logged in (we don't record your user name)": "Saioa hasita dagoen ala ez (ez dugu erabiltzaile-izena gordetzen)", + "Which officially provided instance you are using, if any": "Erabiltzen ari zaren instantzia ofiziala, balego", + "Whether or not you're using the Richtext mode of the Rich Text Editor": "Testu editorean testu aberatsa modua erabiltzen duzun", + "Your homeserver's URL": "Zure hasiera zerbitzariaren URL-a", + "Your identity server's URL": "Zure identitate zerbitzariaren URL-a" } From 3cadb9b58736c5f27e42c74f80f0850ba2067024 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 12 Jan 2018 16:21:30 +0000 Subject: [PATCH 0091/1160] Fall back for missing i18n plurals Counterpart doesn't do fallback if there is a translation for the base string in the preferred language but not the required pluralisation. This meant that if someone added some plurals to a language or a string, but not all, you'd get completely empty strings in the interface. Work around this in the wrapper function. --- src/languageHandler.js | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/languageHandler.js b/src/languageHandler.js index e732927a75..2d1fbc2f85 100644 --- a/src/languageHandler.js +++ b/src/languageHandler.js @@ -40,7 +40,7 @@ export function _td(s) { // Wrapper for counterpart's translation function so that it handles nulls and undefineds properly // Takes the same arguments as counterpart.translate() -function safeCounterpartTranslate(...args) { +function safeCounterpartTranslate(text, options) { // Horrible hack to avoid https://github.com/vector-im/riot-web/issues/4191 // The interpolation library that counterpart uses does not support undefined/null // values and instead will throw an error. This is a problem since everywhere else @@ -48,19 +48,29 @@ function safeCounterpartTranslate(...args) { // valid ES6 template strings to i18n strings it's extremely easy to pass undefined/null // if there are no existing null guards. To avoid this making the app completely inoperable, // we'll check all the values for undefined/null and stringify them here. - if (args[1] && typeof args[1] === 'object') { - Object.keys(args[1]).forEach((k) => { - if (args[1][k] === undefined) { + let count; + + if (options && typeof options === 'object') { + count = options['count']; + Object.keys(options).forEach((k) => { + if (options[k] === undefined) { console.warn("safeCounterpartTranslate called with undefined interpolation name: " + k); - args[1][k] = 'undefined'; + options[k] = 'undefined'; } - if (args[1][k] === null) { + if (options[k] === null) { console.warn("safeCounterpartTranslate called with null interpolation name: " + k); - args[1][k] = 'null'; + options[k] = 'null'; } }); } - return counterpart.translate(...args); + let translated = counterpart.translate(text, options); + if (translated === undefined && count !== undefined) { + // counterpart does not do fallback if no pluralisation exists + // in the preferred language, so do it here + options.locale = 'en'; + translated = counterpart.translate(text, options); + } + return translated; } /* From a3c6dd36eff90f386b553af96b45166a30dc3dc6 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Fri, 12 Jan 2018 17:38:21 +0000 Subject: [PATCH 0092/1160] Stickers popover. --- src/components/views/rooms/MessageComposer.js | 129 +++++++++++------- 1 file changed, 79 insertions(+), 50 deletions(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 9f4a017689..b17694011c 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -23,7 +23,7 @@ import sdk from '../../../index'; import dis from '../../../dispatcher'; import Autocomplete from './Autocomplete'; import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore"; -import Popover from 'react-simple-popover'; +import Popover, {ArrowContainer} from 'react-tiny-popover'; import Widgets from '../../../utils/widgets'; import AppTile from '../elements/AppTile'; @@ -266,7 +266,13 @@ export default class MessageComposer extends React.Component { alt={e2eTitle} title={e2eTitle} />, ); - let callButton, videoCallButton, hangupButton, showStickersButton, hideStickersButton; + + let callButton; + let videoCallButton; + let hangupButton; + let stickersButton; + + // Call buttons if (this.props.callState && this.props.callState !== 'ended') { hangupButton =
@@ -284,63 +290,58 @@ export default class MessageComposer extends React.Component { } // Stickers - if (this.state.showStickers) { - const popoverWidth = '300px'; - const popoverHeight = '300px'; - const stickerpackWidget = Widgets.getStickerpackWidgets()[0]; - let stickersContent =

Click here to add your first sitckerpack

; - if (stickerpackWidget && stickerpackWidget.content && stickerpackWidget.content.url) { - stickersContent =
- -
; - } + }} + > + +
; + } else { + // Default content to show if stickerpack widget not added + this.state.stickersContent =

Click here to add your first sitckerpack

; + } - hideStickersButton = + + if (this.state.showStickers) { + // Show hide-stickers button + stickersButton =
-
; } else { - showStickersButton = + // Show show-stickers button + stickersButton =
; } - const stickersContainer =
- { showStickersButton } - { hideStickersButton } -
; + + const stickers = ( + +
+ { this.state.stickersContent } +
+
+ )} + > +
+ { stickersButton } +
+
; const canSendMessages = this.props.room.currentState.maySendMessage( MatrixClientPeg.get().credentials.userId); @@ -398,7 +427,7 @@ export default class MessageComposer extends React.Component { hangupButton, callButton, videoCallButton, - stickersContainer, + stickers, ); } else { controls.push( From e42bea6277175e94bcd9ed92ee32c384e283a500 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 12 Jan 2018 18:17:03 +0000 Subject: [PATCH 0093/1160] Don't paginate whilst decrypting events As comment hopefully explains. This meant loading the app on an e2e room would often be very slow as it tried to pull hundreds of events into the timeline. --- src/components/structures/TimelinePanel.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/components/structures/TimelinePanel.js b/src/components/structures/TimelinePanel.js index 3760bb37c5..4ade78af85 100644 --- a/src/components/structures/TimelinePanel.js +++ b/src/components/structures/TimelinePanel.js @@ -302,6 +302,8 @@ var TimelinePanel = React.createClass({ // set off a pagination request. onMessageListFillRequest: function(backwards) { + if (!this._shouldPaginate()) return Promise.resolve(false); + const dir = backwards ? EventTimeline.BACKWARDS : EventTimeline.FORWARDS; const canPaginateKey = backwards ? 'canBackPaginate' : 'canForwardPaginate'; const paginatingKey = backwards ? 'backPaginating' : 'forwardPaginating'; @@ -1091,6 +1093,17 @@ var TimelinePanel = React.createClass({ }, this.props.onReadMarkerUpdated); }, + _shouldPaginate: function() { + // don't try to paginate while events in the timeline are + // still being decrypted. We don't render events while they're + // being decrypted, so they don't take up space in the timeline. + // This means we can pull quite a lot of events into the timeline + // and end up trying to render a lot of events. + return !this.state.events.some((e) => { + return e.isBeingDecrypted(); + }); + }, + render: function() { const MessagePanel = sdk.getComponent("structures.MessagePanel"); const Loader = sdk.getComponent("elements.Spinner"); From ba5d92559b9b57bac455c0152cff379f0ce7eb5a Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Sat, 13 Jan 2018 12:58:50 +0000 Subject: [PATCH 0094/1160] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (980 of 980 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hant/ --- src/i18n/strings/zh_Hant.json | 293 +++++++++++++++++++++++++++++++++- 1 file changed, 292 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 611f6db7ff..40aa6b4905 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -687,5 +687,296 @@ "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s 小工具已被 %(senderName)s 修改", "Copied!": "已複製!", "Failed to copy": "複製失敗", - "Add rooms to this community": "新增聊天室到此社群" + "Add rooms to this community": "新增聊天室到此社群", + "Call Failed": "通話失敗", + "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "此聊天室有未知的裝置:若您想要不驗證它們而繼續,可能會有其他人竊聽您的通話。", + "Review Devices": "審閱裝置", + "Call Anyway": "無論如何都通話", + "Answer Anyway": "無論如何都回覆", + "Call": "通話", + "Answer": "回覆", + "Who would you like to add to this community?": "您想要把誰新增到此社群內?", + "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "警告:任何您新增到社群內的人都可以被任何知道社群 ID 的人公開看見", + "Invite new community members": "邀請新社群成員", + "Name or matrix ID": "名稱或 matrix ID", + "Invite to Community": "邀請到社群", + "Which rooms would you like to add to this community?": "您想要新增哪個聊天室到此社群?", + "Show these rooms to non-members on the community page and room list?": "在社群頁面與聊天室清單上顯示這些聊天室給非成員?", + "Add rooms to the community": "新增聊天室到社群", + "Room name or alias": "聊天室名稱或別名", + "Add to community": "新增到社群", + "Failed to invite the following users to %(groupId)s:": "邀請下列使用者到 %(groupId)s 失敗:", + "Failed to invite users to community": "邀請使用者到社群失敗", + "Failed to invite users to %(groupId)s": "邀請使用者到 %(groupId)s 失敗", + "Failed to add the following rooms to %(groupId)s:": "新增下列聊天室到 %(groupId)s 失敗:", + "Restricted": "限制", + "Ignored user": "已忽略的使用者", + "You are now ignoring %(userId)s": "您忽略了 %(userId)s", + "Unignored user": "未忽略的使用者", + "You are no longer ignoring %(userId)s": "您不再忽略 %(userId)s", + "%(senderName)s changed the pinned messages for the room.": "%(senderName)s 變更了聊天室的釘選訊息。", + "%(names)s and %(count)s others are typing|other": "%(names)s 與其他 %(count)s 個人正在輸入", + "%(names)s and %(count)s others are typing|one": "%(names)s 與另一個人正在輸入", + "Send": "傳送", + "Message Replies": "訊息回覆", + "Message Pinning": "訊息釘選", + "Presence Management": "出席管理", + "Tag Panel": "標籤面板", + "Disable Emoji suggestions while typing": "在輸入時停用繪文字建議", + "Hide avatar changes": "隱藏大頭貼變更", + "Hide display name changes": "隱藏顯示名稱變更", + "Disable big emoji in chat": "在聊天中停用大型繪文字", + "Mirror local video feed": "鏡射本機視訊 feed", + "Enable inline URL previews by default": "預設啟用內嵌 URL 預覽", + "Enable URL previews for this room (only affects you)": "對此聊天室啟用 URL 預覽(僅影響您)", + "Enable URL previews by default for participants in this room": "對此聊天室中的參與者預設啟用 URL 預覽", + "Delete %(count)s devices|other": "刪除 %(count)s 個裝置", + "Delete %(count)s devices|one": "刪除裝置", + "Select devices": "選取裝置", + "%(senderName)s sent an image": "%(senderName)s 傳送了一張圖片", + "%(senderName)s sent a video": "%(senderName)s 傳送了一則視訊", + "%(senderName)s uploaded a file": "%(senderName)s 上傳了一個檔案", + "Disinvite this user?": "取消邀請此使用者?", + "Kick this user?": "踢除此使用者?", + "Unban this user?": "取消阻擋此使用者?", + "Ban this user?": "阻擋此使用者?", + "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "如果您是聊天室中最後一位有特殊權限的使用者,您將無法復原此變更,因為無法再獲得特定權限。", + "Unignore": "取消忽略", + "Ignore": "忽略", + "Jump to read receipt": "跳到讀取回條", + "Mention": "提及", + "Invite": "邀請", + "User Options": "使用者選項", + "Send an encrypted reply…": "傳送加密的回覆……", + "Send a reply (unencrypted)…": "傳送回覆(未加密)……", + "Send an encrypted message…": "傳送加密的訊息……", + "Send a message (unencrypted)…": "傳送訊息(未加密)……", + "Unpin Message": "取消釘選訊息", + "Jump to message": "跳到訊息", + "No pinned messages.": "沒有已釘選的訊息。", + "Loading...": "正在載入……", + "Pinned Messages": "已釘選的訊息", + "%(duration)ss": "%(duration)s 秒", + "%(duration)sm": "%(duration)s 分鐘", + "%(duration)sh": "%(duration)s 小時", + "%(duration)sd": "%(duration)s 天", + "Online for %(duration)s": "已上線 %(duration)s", + "Idle for %(duration)s": "已閒置 %(duration)s", + "Offline for %(duration)s": "已離線 %(duration)s", + "Unknown for %(duration)s": "未知 %(duration)s", + "Unknown": "未知", + "Replying": "正在回覆", + "No rooms to show": "未顯示聊天室", + "Unnamed room": "未命名的聊天室", + "World readable": "所有人可讀", + "Guests can join": "訪客可加入", + "Remove avatar": "移除大頭貼", + "Drop here to favourite": "拖曳到這裡以加入到最愛", + "Drop here to tag direct chat": "拖曳到這裡以為聊天加上標籤", + "Drop here to restore": "拖曳到這裡以復原", + "Drop here to demote": "拖曳到這裡以降級", + "Community Invites": "社群邀請", + "You have been kicked from this room by %(userName)s.": "您已經被 %(userName)s 從此聊天室中踢除。", + "You have been banned from this room by %(userName)s.": "您已經被 %(userName)s 從此聊天室中阻擋。", + "You are trying to access a room.": "您正在嘗試存取聊天室。", + "To change the room's avatar, you must be a": "要變更聊天室的大頭貼,您必須是", + "To change the room's name, you must be a": "要變更聊天室的名稱,您必須是", + "To change the room's main address, you must be a": "要變更聊天室的主地址,您必須是", + "To change the room's history visibility, you must be a": "要變更聊天室的歷史紀錄可見度,您必須是", + "To change the permissions in the room, you must be a": "要變更聊天室中的權限,您必須是", + "To change the topic, you must be a": "要變更主題,您必須是", + "To modify widgets in the room, you must be a": "要修改聊天室中的小工具,您必須是", + "Banned by %(displayName)s": "被 %(displayName)s 阻擋", + "Members only (since the point in time of selecting this option)": "僅成員(自選取此選項開始)", + "Members only (since they were invited)": "僅成員(自他們被邀請開始)", + "Members only (since they joined)": "僅成員(自他們加入開始)", + "To send messages, you must be a": "要傳送訊息,您必須是", + "To invite users into the room, you must be a": "要邀請使用者到聊天室,您必須是", + "To configure the room, you must be a": "要設定聊天室,您必須是", + "To kick users, you must be a": "要踢除使用者,您必須是", + "To ban users, you must be a": "要阻擋使用者,您必須是", + "To remove other users' messages, you must be a": "要移除其他使用者的訊息,您必須是", + "To send events of type , you must be a": "要傳送 類型的活動,您必須是", + "Addresses": "地址", + "Invalid community ID": "無效的社群 ID", + "'%(groupId)s' is not a valid community ID": "「%(groupId)s」不是有效的社群 ID", + "Flair": "特色", + "Showing flair for these communities:": "為這些社群顯示特色", + "This room is not showing flair for any communities": "此聊天室並未對任何社群顯示特色", + "New community ID (e.g. +foo:%(localDomain)s)": "新社群 ID(例子:+foo:%(localDomain)s)", + "URL previews are enabled by default for participants in this room.": "此聊天室已預設對參與者啟用 URL 預覽。", + "URL previews are disabled by default for participants in this room.": "此聊天室已預設對參與者停用 URL 預覽。", + "Message removed by %(userId)s": "訊息已被 %(userId)s 移除", + "Message removed": "訊息已移除", + "An email has been sent to %(emailAddress)s": "電子郵件已傳送給 %(emailAddress)s", + "A text message has been sent to %(msisdn)s": "文字訊息已傳送給 %(msisdn)s", + "Username on %(hs)s": "在 %(hs)s 上的使用者名稱", + "%(serverName)s Matrix ID": "%(serverName)s Matrix ID", + "Remove from community": "從社群中移除", + "Disinvite this user from community?": "從社群取消邀請此使用者?", + "Remove this user from community?": "從社群移除此使用者?", + "Failed to withdraw invitation": "撤回邀請失敗", + "Failed to remove user from community": "從社群移除使用者失敗", + "Filter community members": "過濾社群成員", + "Flair will appear if enabled in room settings": "若在聊天室設定內啟用將會顯示特色", + "Flair will not appear": "不會顯示特色", + "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "您確定您想要從 %(groupId)s 移除「%(roomName)s」嗎?", + "Removing a room from the community will also remove it from the community page.": "從社群移除聊天室同時也會將其從社群頁面中移除。", + "Failed to remove room from community": "從社群中移除聊天室失敗", + "Failed to remove '%(roomName)s' from %(groupId)s": "從 %(groupId)s 移除「%(roomName)s」失敗", + "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "在 %(groupId)s 中的「%(roomName)s」能見度無法更新。", + "Visibility in Room List": "在聊天室清單中的能見度", + "Visible to everyone": "對所有人可見", + "Only visible to community members": "僅對社群成員可見", + "Filter community rooms": "過濾社群聊天室", + "Something went wrong when trying to get your communities.": "當嘗試取得您的社群時發生錯誤。", + "Display your community flair in rooms configured to show it.": "在設定了顯示特色的聊天室中顯示您的社群特色。", + "You're not currently a member of any communities.": "您目前不是任何社群的成員。", + "Delete Widget": "刪除小工具", + "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "刪除小工具會將它從此聊天室中所有使用者的收藏中移除。您確定您要刪除這個小工具嗎?", + "Minimize apps": "最小化應用程式", + "Communities": "社群", + "%(nameList)s %(transitionList)s": "%(nameList)s %(transitionList)s", + "%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)s 加入了 %(count)s 次", + "%(severalUsers)sjoined %(count)s times|one": "%(severalUsers)s 加入了", + "%(oneUser)sjoined %(count)s times|other": "%(oneUser)s 加入了 %(count)s 次", + "%(oneUser)sjoined %(count)s times|one": "%(oneUser)s 加入了", + "%(severalUsers)sleft %(count)s times|other": "%(severalUsers)s 離開了 %(count)s 次", + "%(severalUsers)sleft %(count)s times|one": "%(severalUsers)s 離開了", + "%(oneUser)sleft %(count)s times|other": "%(oneUser)s 離開了 %(count)s 次", + "%(oneUser)sleft %(count)s times|one": "%(oneUser)s 離開了", + "%(severalUsers)sjoined and left %(count)s times|other": "%(severalUsers)s 加入並離開了 %(count)s 次", + "%(severalUsers)sjoined and left %(count)s times|one": "%(severalUsers)s 加入並離開了", + "%(oneUser)sjoined and left %(count)s times|other": "%(oneUser)s 加入並離開了 %(count)s 次", + "%(oneUser)sjoined and left %(count)s times|one": "%(oneUser)s 加入並離開了", + "%(severalUsers)sleft and rejoined %(count)s times|other": "%(severalUsers)s 離開並重新加入了 %(count)s 次", + "%(severalUsers)sleft and rejoined %(count)s times|one": "%(severalUsers)s 離開並重新加入了", + "%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)s 離開並重新加入了 %(count)s 次", + "%(oneUser)sleft and rejoined %(count)s times|one": "%(oneUser)s 離開並重新加入了", + "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)s 回絕了他們的邀請 %(count)s 次", + "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)s 回絕了他們的邀請", + "%(oneUser)srejected their invitation %(count)s times|other": "%(oneUser)s 回絕了他們的邀請 %(count)s 次", + "%(oneUser)srejected their invitation %(count)s times|one": "%(oneUser)s 回絕了他們的邀請", + "%(severalUsers)shad their invitations withdrawn %(count)s times|other": "%(severalUsers)s 撤回了他們的邀請 %(count)s 次", + "%(severalUsers)shad their invitations withdrawn %(count)s times|one": "%(severalUsers)s 撤回了他們的邀請", + "%(oneUser)shad their invitation withdrawn %(count)s times|other": "%(oneUser)s 撤回了他們的邀請 %(count)s 次", + "%(oneUser)shad their invitation withdrawn %(count)s times|one": "%(oneUser)s 撤回了他們的邀請", + "were invited %(count)s times|other": "被邀請了 %(count)s 次", + "were invited %(count)s times|one": "被邀請了", + "was invited %(count)s times|other": "被邀請了 %(count)s 次", + "was invited %(count)s times|one": "被邀請了", + "were banned %(count)s times|other": "被阻擋了 %(count)s 次", + "were banned %(count)s times|one": "被阻擋了", + "was banned %(count)s times|other": "被阻擋了 %(count)s 次", + "was banned %(count)s times|one": "被阻擋了", + "were unbanned %(count)s times|other": "被取消阻擋了 %(count)s 次", + "were unbanned %(count)s times|one": "被取消阻擋了", + "was unbanned %(count)s times|other": "被取消阻擋了 %(count)s 次", + "was unbanned %(count)s times|one": "被取消阻擋了", + "were kicked %(count)s times|other": "被踢除了 %(count)s 次", + "were kicked %(count)s times|one": "被踢除了", + "was kicked %(count)s times|other": "被踢除了 %(count)s 次", + "was kicked %(count)s times|one": "被踢除了", + "%(severalUsers)schanged their name %(count)s times|other": "%(severalUsers)s 變更了他們的名稱 %(count)s 次", + "%(severalUsers)schanged their name %(count)s times|one": "%(severalUsers)s 變更了他們的名稱", + "%(oneUser)schanged their name %(count)s times|other": "%(oneUser)s 變更了他們的名稱 %(count)s 次", + "%(oneUser)schanged their name %(count)s times|one": "%(oneUser)s 變更了他們的名稱", + "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)s 變更了他們的大頭貼 %(count)s 次", + "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)s 變更了他們的大頭貼", + "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)s 變更了他們的大頭貼 %(count)s 次", + "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)s 變更了他們的大頭貼", + "%(items)s and %(count)s others|other": "%(items)s 與其他 %(count)s 個", + "%(items)s and %(count)s others|one": "%(items)s 與其他一個", + "collapse": "摺疊", + "expand": "展開", + "Custom of %(powerLevel)s": "自訂 %(powerLevel)s", + "Quote": "引用", + "And %(count)s more...|other": "與更多 %(count)s 個……", + "Matrix ID": "Matrix ID", + "Matrix Room ID": "Matrix 聊天室 ID", + "email address": "電子郵件地址", + "Try using one of the following valid address types: %(validTypesList)s.": "嘗試使用下列有效地地址格式中的其中一個:%(validTypesList)s。", + "You have entered an invalid address.": "您輸入了無效的地址。", + "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "社群 ID 只能包含 a-z, 0-9, or '=_-./' 等字元", + "Something went wrong whilst creating your community": "建立社群時發生問題", + "Create Community": "建立社群", + "Community Name": "社群名稱", + "Community ID": "社群 ID", + "example": "範例", + "Advanced options": "進階選項", + "Block users on other matrix homeservers from joining this room": "阻擋在其他 matrix 家伺服器的使用者加入此聊天室", + "This setting cannot be changed later!": "這個設定無法在之後變更!", + "

HTML for your community's page

\n

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

\n

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

\n": "

您社群頁面的 HTML

\n

\n 使用長描述來為社群的新成員簡介,或是散發\n 一些重要連結\n

\n

\n 您甚至可以使用 'img' 標籤\n

\n", + "Add rooms to the community summary": "新增聊天室到社群摘要中", + "Which rooms would you like to add to this summary?": "您想要新增哪個聊天室到此摘要中?", + "Add to summary": "新增到摘要", + "Failed to add the following rooms to the summary of %(groupId)s:": "新增以下聊天室到 %(groupId)s 的摘要中失敗:", + "Add a Room": "新增聊天室", + "Failed to remove the room from the summary of %(groupId)s": "從 %(groupId)s 的摘要中移除聊天室失敗", + "The room '%(roomName)s' could not be removed from the summary.": "聊天室「%(roomName)s」無法從摘要中移除。", + "Add users to the community summary": "新增使用者到社群摘要中", + "Who would you like to add to this summary?": "您想要新增誰到此摘要中?", + "Failed to add the following users to the summary of %(groupId)s:": "新增下列使用者到 %(groupId)s 的摘要中失敗:", + "Add a User": "新增使用者", + "Failed to remove a user from the summary of %(groupId)s": "從 %(groupId)s 的摘要中移除使用者失敗", + "The user '%(displayName)s' could not be removed from the summary.": "使用者「%(displayName)s」無法從摘要中移除。", + "Failed to update community": "更新社群失敗", + "Unable to accept invite": "無法接受邀請", + "Unable to reject invite": "無法回絕邀請", + "Leave Community": "離開社群", + "Leave %(groupName)s?": "離開 %(groupName)s?", + "Leave": "離開", + "Unable to leave room": "無法離開聊天室", + "Community Settings": "社群設定", + "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "這些聊天室在社群頁面上顯示給社群成員。社群成員可以透過點按它們來加入聊天室。", + "%(inviter)s has invited you to join this community": "%(inviter)s 已經邀請您加入此社群", + "You are an administrator of this community": "您是此社群的管理員", + "You are a member of this community": "您是此社群的成員", + "Your community hasn't got a Long Description, a HTML page to show to community members.
Click here to open settings and give it one!": "您的社群尚未有長描述,一個顯示給社群成員的 HTML 頁面。
點按這裡以開啟設並建立一個!", + "Long Description (HTML)": "長描述(HTML)", + "Description": "描述", + "Community %(groupId)s not found": "找不到社群 %(groupId)s", + "This Home server does not support communities": "這個家伺服器不支援社群", + "Failed to load %(groupId)s": "載入 %(groupId)s 失敗", + "Cryptography data migrated": "加密資料已遷移", + "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "加密資料的一次性遷移已經執行。若您回到舊版本的 Riot,端到端加密將不會運作。若您需要在舊版本上使用端到端加密,先登出 Riot。要保留訊息歷史,匯出再重新匯入您的金鑰。", + "Old cryptography data detected": "偵測到舊的加密資料", + "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "偵測到來自舊版 Riot 的資料。這將會造成舊版的端到端加密失敗。在此版本中使用最近在舊版本交換的金鑰可能無法解密訊息。這也會造成與此版本的訊息交換失敗。若您遇到問題,請登出並重新登入。要保留訊息歷史,請匯出並重新匯入您的金鑰。", + "Your Communities": "您的社群", + "Error whilst fetching joined communities": "擷取已加入的社群時發生錯誤", + "Create a new community": "建立新社群", + "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "建立社群以將使用者與聊天室湊成一組!建立自訂的首頁以在 Matrix 宇宙中標出您的空間。", + "Join an existing community": "加入既有的社群", + "To join an existing community you'll have to know its community identifier; this will look something like +example:matrix.org.": "要加入既有的社群,您必須知道它的社群標記符號;其看起來像是 +example:matrix.org.", + "Show devices, mark devices known and send or cancel all.": "顯示裝置標記裝置為已知並傳送取消全部.", + "%(count)s of your messages have not been sent.|one": "您的訊息尚未傳送。", + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "現在重新傳送全部取消全部。您也可以選取單一訊息以重新傳送或取消。", + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "現在重新傳送訊息取消訊息。", + "Warning": "警告", + "There's no one else here! Would you like to invite others or stop warning about the empty room?": "沒有其他人了!您想要邀請其他人停止關於空聊天室的警告嗎?", + "Light theme": "亮色主題", + "Dark theme": "暗色主題", + "Status.im theme": "Status.im 主題", + "Ignored Users": "已忽略的使用者", + "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "隱私對我們來說至關重要,所以我們不會收集任何私人或可辨識的資料供我們的分析使用。", + "Learn more about how we use analytics.": "得知更多關於我們如何使用分析資料的資訊。", + "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "電子郵件已傳送至 %(emailAddress)s。您必須跟隨其中包含了連結,點按下面的連結。", + "Please note you are logging into the %(hs)s server, not matrix.org.": "請注意,您正在登入 %(hs)s 伺服器,不是 matrix.org。", + "This homeserver doesn't offer any login flows which are supported by this client.": "這個家伺服器不提供任何此客戶端支援的登入流程。", + "Sign in to get started": "登入以開始", + "Ignores a user, hiding their messages from you": "忽略使用者,從您這裡隱藏他們的訊息", + "Stops ignoring a user, showing their messages going forward": "停止忽略使用者,顯示他們的訊息", + "Notify the whole room": "通知整個聊天室", + "Room Notification": "聊天室通知", + "The information being sent to us to help make Riot.im better includes:": "協助讓 Riot.im 變得更好的傳送給我們的資訊包含了:", + "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "我們也紀錄了每個您在應用程式中使用的頁面(目前 ),您的使用者代理()與您的裝置解析度()。", + "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "這個頁面包含了可識別的資訊,如聊天室、使用者或群組 ID,這些資料會在傳到伺服器前被刪除。", + "The platform you're on": "您使用的平臺是", + "The version of Riot.im": "Riot.im 的版本", + "Whether or not you're logged in (we don't record your user name)": "您是否登入(我們不會紀錄您的使用者名稱)", + "Your language of choice": "您選擇的語言", + "Which officially provided instance you are using, if any": "您正在使用的任何官方實體,如果有的話", + "Whether or not you're using the Richtext mode of the Rich Text Editor": "您是否正在使用豐富文字編輯器的豐富文字模式", + "Your homeserver's URL": "您的家伺服器 URL", + "Your identity server's URL": "您的驗證伺服器 URL" } From b526fc057cc79fc641b7c291a56e74fb8a0d87af Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 14 Jan 2018 18:32:17 +0000 Subject: [PATCH 0095/1160] Add formatFullDateNoTime to DateUtils and stop passing 12/24h to DateSep --- src/DateUtils.js | 11 +++++++++++ src/components/structures/MessagePanel.js | 4 ++-- src/i18n/strings/en_EN.json | 1 + 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/DateUtils.js b/src/DateUtils.js index 91df1e46d5..986525eec8 100644 --- a/src/DateUtils.js +++ b/src/DateUtils.js @@ -82,6 +82,17 @@ export function formatDate(date, showTwelveHour=false) { return formatFullDate(date, showTwelveHour); } +export function formatFullDateNoTime(date) { + const days = getDaysArray(); + const months = getMonthsArray(); + return _t('%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s', { + weekDayName: days[date.getDay()], + monthName: months[date.getMonth()], + day: date.getDate(), + fullYear: date.getFullYear(), + }); +} + export function formatFullDate(date, showTwelveHour=false) { const days = getDaysArray(); const months = getMonthsArray(); diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index 5523fc27a0..6a8c2e9c2e 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -325,7 +325,7 @@ module.exports = React.createClass({ const key = "membereventlistsummary-" + (prevEvent ? mxEv.getId() : "initial"); if (this._wantsDateSeparator(prevEvent, mxEv.getDate())) { - const dateSeparator =
  • ; + const dateSeparator =
  • ; ret.push(dateSeparator); } @@ -479,7 +479,7 @@ module.exports = React.createClass({ // do we need a date separator since the last event? if (this._wantsDateSeparator(prevEvent, eventDate)) { - const dateSeparator =
  • ; + const dateSeparator =
  • ; ret.push(dateSeparator); continuation = false; } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 0d686ad490..73e3f3a014 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -49,6 +49,7 @@ "AM": "AM", "%(weekDayName)s %(time)s": "%(weekDayName)s %(time)s", "%(weekDayName)s, %(monthName)s %(day)s %(time)s": "%(weekDayName)s, %(monthName)s %(day)s %(time)s", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s", "Who would you like to add to this community?": "Who would you like to add to this community?", "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID", From 351bbdfd4eba77a485e4315e48cd2dadff4f9b5c Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Mon, 15 Jan 2018 10:25:19 +0000 Subject: [PATCH 0096/1160] Styling --- src/components/views/rooms/MessageComposer.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index b17694011c..531dc7aff1 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -366,10 +366,10 @@ export default class MessageComposer extends React.Component {
    { this.state.stickersContent } From 0fab905a2e5e90077719ed22f9830c0bf2771a35 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Mon, 15 Jan 2018 11:16:07 +0000 Subject: [PATCH 0097/1160] Cleanup styles. --- src/components/views/rooms/MessageComposer.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 531dc7aff1..39c51ebe3a 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -366,9 +366,6 @@ export default class MessageComposer extends React.Component {
    From ab0c03369b72d28ba5353144c47a264d97e02540 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Sat, 13 Jan 2018 12:59:41 +0000 Subject: [PATCH 0098/1160] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (980 of 980 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hant/ --- src/i18n/strings/zh_Hant.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 40aa6b4905..60a90516a4 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -801,7 +801,7 @@ "Invalid community ID": "無效的社群 ID", "'%(groupId)s' is not a valid community ID": "「%(groupId)s」不是有效的社群 ID", "Flair": "特色", - "Showing flair for these communities:": "為這些社群顯示特色", + "Showing flair for these communities:": "為這些社群顯示特色:", "This room is not showing flair for any communities": "此聊天室並未對任何社群顯示特色", "New community ID (e.g. +foo:%(localDomain)s)": "新社群 ID(例子:+foo:%(localDomain)s)", "URL previews are enabled by default for participants in this room.": "此聊天室已預設對參與者啟用 URL 預覽。", From 7fadd0f4acbe1e1404ac41b5a9a1a03fee884e69 Mon Sep 17 00:00:00 2001 From: Andrey Date: Mon, 15 Jan 2018 14:02:13 +0000 Subject: [PATCH 0099/1160] Translated using Weblate (Russian) Currently translated at 100.0% (981 of 981 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 6e8bbdb7a4..8126f84799 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -977,5 +977,8 @@ "Whether or not you're logged in (we don't record your user name)": "Независимо от того, вошли вы или нет (мы не записываем ваше имя пользователя)", "Your language of choice": "Выбранный вами язык", "Your homeserver's URL": "URL-адрес домашнего сервера", - "Your identity server's URL": "URL-адрес вашего идентификационного сервера" + "Your identity server's URL": "URL-адрес вашего идентификационного сервера", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s", + "Which officially provided instance you are using, if any": "Какую официально выпущенную версию вы используете", + "Whether or not you're using the Richtext mode of the Rich Text Editor": "Независимо от того, используете ли вы режим Richtext в редакторе Rich Text Editor" } From 5e6da4d7583273c8f52dcea4fc2213ecd6e997ec Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Mon, 15 Jan 2018 14:22:41 +0000 Subject: [PATCH 0100/1160] * Fix key error * Remove redundant logging * Catch error --- src/components/views/elements/AppTile.js | 9 ++++++--- src/components/views/rooms/MessageComposer.js | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 60df6ade9b..1da344227e 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -41,7 +41,6 @@ export default class AppTile extends React.Component { constructor(props) { super(props); - console.warn('AppTile constructor', props); this.state = this._getNewState(props); this._onAction = this._onAction.bind(this); @@ -218,8 +217,12 @@ export default class AppTile extends React.Component { } componentWillUnmount() { - this.widgetMessaging.stopListening(); - this.widgetMessaging.removeEndpoint(this.props.id, this.props.url); + try { + this.widgetMessaging.stopListening(); + this.widgetMessaging.removeEndpoint(this.props.id, this.props.url); + } catch (e) { + console.error('Failed to stop listening for widgetMessaging events', e.message); + } dis.unregister(this._onAction); window.removeEventListener('message', this._onMessage); } diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 39c51ebe3a..f87ac02d05 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -354,6 +354,7 @@ export default class MessageComposer extends React.Component { isOpen={this.state.showStickers} position={'top'} padding={1} + key='stickersPopover' content={({ position, targetRect, popoverRect }) => ( Date: Mon, 15 Jan 2018 14:25:56 +0000 Subject: [PATCH 0101/1160] Remove arrow opacity. --- src/components/views/rooms/MessageComposer.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index f87ac02d05..3becd6e2fb 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -362,7 +362,6 @@ export default class MessageComposer extends React.Component { popoverRect={popoverRect} arrowColor={'#76CFA6'} arrowSize={20} - arrowStyle={{ opacity: 0.7 }} >
    Date: Mon, 15 Jan 2018 14:42:41 +0000 Subject: [PATCH 0102/1160] Only set selected tags state when updating rooms instead of every time we get an update from a GroupStore/otherwise. This was leading to many setStates and renders at startup when we receive many group /members /rooms etc. responses. Also, use the rate limited version of refreshRoomList. --- src/components/views/rooms/RoomList.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index d1e00bd302..d1ef6c2f2c 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -324,12 +324,7 @@ module.exports = React.createClass({ // Show all rooms this._visibleRooms = MatrixClientPeg.get().getRooms(); } - - this.setState({ - selectedTags, - }, () => { - this.refreshRoomList(); - }); + this._delayedRefreshRoomList(); }, refreshRoomList: function() { @@ -345,6 +340,9 @@ module.exports = React.createClass({ this.setState({ lists: this.getRoomLists(), totalRoomCount: totalRooms, + // Do this here so as to not render every time the selected tags + // themselves change. + selectedTags: TagOrderStore.getSelectedTags(), }); // this._lastRefreshRoomListTs = Date.now(); From e085632d8d6e3c27835dfd070019d21188bdf4d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Thu, 11 Jan 2018 11:20:03 +0000 Subject: [PATCH 0103/1160] Translated using Weblate (French) Currently translated at 100.0% (981 of 981 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index c62e564d46..109697d750 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -979,5 +979,6 @@ "Which officially provided instance you are using, if any": "Quelle instance officielle vous utilisez, si c'est le cas", "Whether or not you're using the Richtext mode of the Rich Text Editor": "Si vous utilisez le mode de texte enrichi de l'éditeur de texte enrichi", "Your homeserver's URL": "L'URL de votre serveur d'accueil", - "Your identity server's URL": "L'URL de votre serveur d'identité" + "Your identity server's URL": "L'URL de votre serveur d'identité", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s %(day)s %(monthName)s %(fullYear)s" } From 16c13fb07960a59894887acbceadffec9ff1e56d Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Mon, 15 Jan 2018 18:12:27 +0000 Subject: [PATCH 0104/1160] Replace TagPanel react-dnd with react-beautiful-dnd This new library handles the simple case of an ordered vertical (or horizontal) list of items that can be reordered. It provides animations, handles positioning of items mid-drag and exposes a much simpler API to react-dnd (with a slight loss of potential function, but we don't need this flexibility here anyway). Apart from this, TagOrderStore had to be changed in a highly coupled way, but arguably for the better. Instead of being updated incrementally every time an item is dragged over another and having a separate "commit" action, the asyncronous action `moveTag` is used to reposition the tag in the list and both dispatch an optimistic update and carry out the request as before. (The MatrixActions.accountData is still used to indicate a successful reordering of tags). The view is updated instantly, in an animated way, and this is handled at the layer "above" React by the DND library. --- package.json | 1 + src/actions/TagOrderActions.js | 20 +++-- src/actions/actionCreators.js | 11 ++- src/components/structures/TagPanel.js | 42 ++++++++-- src/components/views/elements/DNDTagTile.js | 88 ++++++--------------- src/stores/TagOrderStore.js | 23 ++---- 6 files changed, 85 insertions(+), 100 deletions(-) diff --git a/package.json b/package.json index eb2cabf854..dbc27b5a08 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,7 @@ "querystring": "^0.2.0", "react": "^15.4.0", "react-addons-css-transition-group": "15.3.2", + "react-beautiful-dnd": "^4.0.0", "react-dnd": "^2.1.4", "react-dnd-html5-backend": "^2.1.2", "react-dom": "^15.4.0", diff --git a/src/actions/TagOrderActions.js b/src/actions/TagOrderActions.js index 60946ea7f1..db9230e964 100644 --- a/src/actions/TagOrderActions.js +++ b/src/actions/TagOrderActions.js @@ -31,16 +31,22 @@ const TagOrderActions = {}; * indicating the status of the request. * @see asyncAction */ -TagOrderActions.commitTagOrdering = function(matrixClient) { - return asyncAction('TagOrderActions.commitTagOrdering', () => { - // Only commit tags if the state is ready, i.e. not null - const tags = TagOrderStore.getOrderedTags(); - if (!tags) { - return; - } +TagOrderActions.moveTag = function(matrixClient, tag, destinationIx) { + // Only commit tags if the state is ready, i.e. not null + let tags = TagOrderStore.getOrderedTags(); + if (!tags) { + return; + } + tags = tags.filter((t) => t !== tag); + tags = [...tags.slice(0, destinationIx), tag, ...tags.slice(destinationIx)]; + + return asyncAction('TagOrderActions.moveTag', () => { Analytics.trackEvent('TagOrderActions', 'commitTagOrdering'); return matrixClient.setAccountData('im.vector.web.tag_ordering', {tags}); + }, () => { + // For an optimistic update + return {tags}; }); }; diff --git a/src/actions/actionCreators.js b/src/actions/actionCreators.js index bddfbc7c63..0238eee8c0 100644 --- a/src/actions/actionCreators.js +++ b/src/actions/actionCreators.js @@ -22,6 +22,9 @@ limitations under the License. * suffix determining whether it is pending, successful or * a failure. * @param {function} fn a function that returns a Promise. + * @param {function?} pendingFn a function that returns an object to assign + * to the `request` key of the ${id}.pending + * payload. * @returns {function} an action thunk - a function that uses its single * argument as a dispatch function to dispatch the * following actions: @@ -29,9 +32,13 @@ limitations under the License. * `${id}.success` or * `${id}.failure`. */ -export function asyncAction(id, fn) { +export function asyncAction(id, fn, pendingFn) { return (dispatch) => { - dispatch({action: id + '.pending'}); + dispatch({ + action: id + '.pending', + request: + typeof pendingFn === 'function' ? pendingFn() : undefined, + }); fn().then((result) => { dispatch({action: id + '.success', result}); }).catch((err) => { diff --git a/src/components/structures/TagPanel.js b/src/components/structures/TagPanel.js index 531c247ea6..323528e1f1 100644 --- a/src/components/structures/TagPanel.js +++ b/src/components/structures/TagPanel.js @@ -25,6 +25,8 @@ import TagOrderActions from '../../actions/TagOrderActions'; import sdk from '../../index'; import dis from '../../dispatcher'; +import { DragDropContext, Droppable } from 'react-beautiful-dnd'; + const TagPanel = React.createClass({ displayName: 'TagPanel', @@ -69,7 +71,9 @@ const TagPanel = React.createClass({ dis.dispatch(GroupActions.fetchJoinedGroups(this.context.matrixClient)); }, - onClick() { + onClick(e) { + // Ignore clicks on children + if (e.target !== e.currentTarget) return; dis.dispatch({action: 'deselect_tags'}); }, @@ -78,8 +82,20 @@ const TagPanel = React.createClass({ dis.dispatch({action: 'view_create_group'}); }, - onTagTileEndDrag() { - dis.dispatch(TagOrderActions.commitTagOrdering(this.context.matrixClient)); + onTagTileEndDrag(result) { + // Dragged to an invalid destination, not onto a droppable + if (!result.destination) { + return; + } + + // Dispatch synchronously so that the TagPanel receives an + // optimistic update from TagOrderStore before the previous + // state is shown. + dis.dispatch(TagOrderActions.moveTag( + this.context.matrixClient, + result.draggableId, + result.destination.index, + ), true); }, render() { @@ -89,16 +105,26 @@ const TagPanel = React.createClass({ const tags = this.state.orderedTags.map((tag, index) => { return ; }); return
    -
    - { tags } -
    + + + { (provided, snapshot) => ( +
    + { tags } + { provided.placeholder } +
    + ) } +
    +
    diff --git a/src/components/views/elements/DNDTagTile.js b/src/components/views/elements/DNDTagTile.js index 539163d0dc..e17ea52976 100644 --- a/src/components/views/elements/DNDTagTile.js +++ b/src/components/views/elements/DNDTagTile.js @@ -15,71 +15,29 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { DragSource, DropTarget } from 'react-dnd'; - import TagTile from './TagTile'; -import dis from '../../../dispatcher'; -import { findDOMNode } from 'react-dom'; -const tagTileSource = { - canDrag: function(props, monitor) { - return true; - }, +import { Draggable } from 'react-beautiful-dnd'; - beginDrag: function(props) { - // Return the data describing the dragged item - return { - tag: props.tag, - }; - }, - - endDrag: function(props, monitor, component) { - const dropResult = monitor.getDropResult(); - if (!monitor.didDrop() || !dropResult) { - return; - } - props.onEndDrag(); - }, -}; - -const tagTileTarget = { - canDrop(props, monitor) { - return true; - }, - - hover(props, monitor, component) { - if (!monitor.canDrop()) return; - const draggedY = monitor.getClientOffset().y; - const {top, bottom} = findDOMNode(component).getBoundingClientRect(); - const targetY = (top + bottom) / 2; - dis.dispatch({ - action: 'order_tag', - tag: monitor.getItem().tag, - targetTag: props.tag, - // Note: we indicate that the tag should be after the target when - // it's being dragged over the top half of the target. - after: draggedY < targetY, - }); - }, - - drop(props) { - // Return the data to be returned by getDropResult - return { - tag: props.tag, - }; - }, -}; - -export default - DropTarget('TagTile', tagTileTarget, (connect, monitor) => ({ - connectDropTarget: connect.dropTarget(), - }))(DragSource('TagTile', tagTileSource, (connect, monitor) => ({ - connectDragSource: connect.dragSource(), - }))((props) => { - const { connectDropTarget, connectDragSource, ...otherProps } = props; - return connectDropTarget(connectDragSource( -
    - -
    , - )); - })); +export default function DNDTagTile(props) { + return
    + + { (provided, snapshot) => ( +
    +
    + +
    + { provided.placeholder } +
    + ) } +
    +
    ; +} diff --git a/src/stores/TagOrderStore.js b/src/stores/TagOrderStore.js index 9c9427284e..27ce6cbb73 100644 --- a/src/stores/TagOrderStore.js +++ b/src/stores/TagOrderStore.js @@ -78,24 +78,11 @@ class TagOrderStore extends Store { this._updateOrderedTags(); break; } - // Puts payload.tag at payload.targetTag, placing the targetTag before or after the tag - case 'order_tag': { - if (!this._state.orderedTags || - !payload.tag || - !payload.targetTag || - payload.tag === payload.targetTag - ) return; - - const tags = this._state.orderedTags; - - let orderedTags = tags.filter((t) => t !== payload.tag); - const newIndex = orderedTags.indexOf(payload.targetTag) + (payload.after ? 1 : 0); - orderedTags = [ - ...orderedTags.slice(0, newIndex), - payload.tag, - ...orderedTags.slice(newIndex), - ]; - this._setState({orderedTags}); + case 'TagOrderActions.moveTag.pending': { + // Optimistic update of a moved tag + this._setState({ + orderedTags: payload.request.tags, + }); break; } case 'select_tag': { From 82b9897986e2c471d78ca09a244d5a56cdd06134 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Mon, 15 Jan 2018 18:27:14 +0000 Subject: [PATCH 0105/1160] Select apropriate theme colour for popover. --- src/components/views/rooms/MessageComposer.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 3becd6e2fb..8b70b67a1e 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -350,6 +350,11 @@ export default class MessageComposer extends React.Component {
    ; } + // Fall back to default highlight color if we can't compute one from the DOM + const highlightColor = document.getElementById('mx_theme_accentColor') ? + window.getComputedStyle(document.getElementById('mx_theme_accentColor')).color : + '#76CFA6'; + const stickers =
    { this.state.stickersContent } From 732950594d00041a3263f742cb428d6c8460e5d7 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Thu, 11 Jan 2018 12:34:08 +0000 Subject: [PATCH 0106/1160] Translated using Weblate (Hungarian) Currently translated at 100.0% (981 of 981 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 6384644925..a341d47795 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -979,5 +979,6 @@ "Which officially provided instance you are using, if any": "Milyen hivatalosan nyújtott verziót használsz", "Whether or not you're using the Richtext mode of the Rich Text Editor": "Használod-e a Richtext módot a szerkesztőben vagy nem", "Your homeserver's URL": "Az egyedi szerver URL-t", - "Your identity server's URL": "Az azonosítási szerver URL-t" + "Your identity server's URL": "Az azonosítási szerver URL-t", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(fullYear)s. %(monthName)s %(day)s, %(weekDayName)s" } From bc2448fa7c5ee6e5548ed7ba8d3cc304b293b6ad Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Sat, 13 Jan 2018 12:59:41 +0000 Subject: [PATCH 0107/1160] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (981 of 981 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hant/ --- src/i18n/strings/zh_Hant.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 60a90516a4..f29debcf22 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -978,5 +978,6 @@ "Which officially provided instance you are using, if any": "您正在使用的任何官方實體,如果有的話", "Whether or not you're using the Richtext mode of the Rich Text Editor": "您是否正在使用豐富文字編輯器的豐富文字模式", "Your homeserver's URL": "您的家伺服器 URL", - "Your identity server's URL": "您的驗證伺服器 URL" + "Your identity server's URL": "您的驗證伺服器 URL", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s" } From f7e2e91df513c409c887f3ec893ef23c77f0bc94 Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Tue, 16 Jan 2018 09:38:16 +0000 Subject: [PATCH 0108/1160] Workaround for travis-ci/travis-ci#8836 --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4137d754bf..d2b5558b39 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,9 @@ dist: trusty # we don't need sudo, so can run in a container, which makes startup much # quicker. -sudo: false +# +# unfortunately we do require sudo as per https://github.com/travis-ci/travis-ci/issues/8836 +sudo: required language: node_js node_js: From d2e5b122715bf89c1596a56eaffb1a9d3b0988d1 Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Tue, 16 Jan 2018 09:46:48 +0000 Subject: [PATCH 0109/1160] Update jsdoc for moveTag --- src/actions/TagOrderActions.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/actions/TagOrderActions.js b/src/actions/TagOrderActions.js index db9230e964..608fd6c4c5 100644 --- a/src/actions/TagOrderActions.js +++ b/src/actions/TagOrderActions.js @@ -22,11 +22,12 @@ const TagOrderActions = {}; /** * Creates an action thunk that will do an asynchronous request to - * commit TagOrderStore.getOrderedTags() to account data and dispatch - * actions to indicate the status of the request. + * move a tag in TagOrderStore to destinationIx. * * @param {MatrixClient} matrixClient the matrix client to set the * account data on. + * @param {string} tag the tag to move. + * @param {number} destinationIx the new position of the tag. * @returns {function} an action thunk that will dispatch actions * indicating the status of the request. * @see asyncAction From f391375deac0534c9d89863e15c2ffd643b7a6de Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Tue, 16 Jan 2018 10:09:11 +0000 Subject: [PATCH 0110/1160] Alter comment on travis-ci#8836 workaround --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d2b5558b39..954f14a4da 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,8 @@ dist: trusty # we don't need sudo, so can run in a container, which makes startup much # quicker. # -# unfortunately we do require sudo as per https://github.com/travis-ci/travis-ci/issues/8836 +# unfortunately we do temporarily require sudo as a workaround for +# https://github.com/travis-ci/travis-ci/issues/8836 sudo: required language: node_js From bda2d6b0a66b4a50a1313e1aebd50c4f4555ec15 Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Tue, 16 Jan 2018 10:44:11 +0000 Subject: [PATCH 0111/1160] Work around atlassian/react-beautiful-dnd#273 For some reason, after dragging an item the parent draggable receives a mouse click. The workaround is to use onMouseDown for deselecting tags --- src/components/structures/TagPanel.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/structures/TagPanel.js b/src/components/structures/TagPanel.js index 323528e1f1..a0a0e2d6e3 100644 --- a/src/components/structures/TagPanel.js +++ b/src/components/structures/TagPanel.js @@ -111,13 +111,14 @@ const TagPanel = React.createClass({ selected={this.state.selectedTags.includes(tag)} />; }); - return
    + return
    { (provided, snapshot) => (
    { tags } { provided.placeholder } From f19dcd81149b6ae0f971c3b89098fa30c559b023 Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Tue, 16 Jan 2018 11:07:25 +0000 Subject: [PATCH 0112/1160] Comment workaround to atlassian/react-beautiful-dnd#273 --- src/components/structures/TagPanel.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/structures/TagPanel.js b/src/components/structures/TagPanel.js index a0a0e2d6e3..1cd3f04f9d 100644 --- a/src/components/structures/TagPanel.js +++ b/src/components/structures/TagPanel.js @@ -118,6 +118,10 @@ const TagPanel = React.createClass({
    { tags } From 1155c1c85c26a7c5a88f2e6ea4a50a9ef577fb70 Mon Sep 17 00:00:00 2001 From: Osoitz Date: Fri, 12 Jan 2018 12:38:21 +0000 Subject: [PATCH 0113/1160] Translated using Weblate (Basque) Currently translated at 100.0% (981 of 981 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eu/ --- src/i18n/strings/eu.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index 5309a76148..e8fe9b2f20 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -979,5 +979,6 @@ "Which officially provided instance you are using, if any": "Erabiltzen ari zaren instantzia ofiziala, balego", "Whether or not you're using the Richtext mode of the Rich Text Editor": "Testu editorean testu aberatsa modua erabiltzen duzun", "Your homeserver's URL": "Zure hasiera zerbitzariaren URL-a", - "Your identity server's URL": "Zure identitate zerbitzariaren URL-a" + "Your identity server's URL": "Zure identitate zerbitzariaren URL-a", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(fullYear)s(e)ko %(monthName)sk %(day)sa" } From 5de8cf270c0f61285adb9693ce720a41cd4943fc Mon Sep 17 00:00:00 2001 From: Xose M Date: Tue, 16 Jan 2018 11:01:01 +0000 Subject: [PATCH 0114/1160] Translated using Weblate (Galician) Currently translated at 35.9% (353 of 981 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/gl/ --- src/i18n/strings/gl.json | 120 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 119 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/gl.json b/src/i18n/strings/gl.json index 4800e9e34e..1807ce96d8 100644 --- a/src/i18n/strings/gl.json +++ b/src/i18n/strings/gl.json @@ -234,5 +234,123 @@ "Select devices": "Escolla dispositivos", "Failed to set display name": "Fallo ao establecer o nome público", "Disable Notifications": "Deshabilitar notificacións", - "Enable Notifications": "Habilitar notificacións" + "Enable Notifications": "Habilitar notificacións", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(day)s %(monthName)s %(fullYear)s", + "Message Replies": "Respostas a mensaxe", + "Mirror local video feed": "", + "Opt out of analytics": "Saírse de analytics", + "Cannot add any more widgets": "Non pode engadir máis widgets", + "The maximum permitted number of widgets have already been added to this room.": "Xa se engadeu o número máximo de widgets a esta sala.", + "Add a widget": "Engadir widget", + "Drop File Here": "Solte aquí o ficheiro", + "Drop file here to upload": "Solte aquí o ficheiro para subilo", + " (unsupported)": " (non soportado)", + "Join as voice or video.": "Únase como voz ou vídeo.", + "Ongoing conference call%(supportedText)s.": "Chamada de conferencia en curso%(supportedText)s.", + "%(senderName)s sent an image": "%(senderName)s enviou unha imaxe", + "%(senderName)s sent a video": "%(senderName)s enviou un vídeo", + "%(senderName)s uploaded a file": "%(senderName)s subeu un ficheiro", + "Options": "Axustes", + "Undecryptable": "Non descifrable", + "Encrypted by a verified device": "Cifrado por un dispositivo verificado", + "Encrypted by an unverified device": "Cifrado por un dispositivo non verificado", + "Unencrypted message": "Mensaxe non cifrada", + "Please select the destination room for this message": "Escolla por favor a sala de destino para esta mensaxe", + "Blacklisted": "Omitidos", + "Verified": "Verificados", + "Unverified": "Non verificados", + "device id: ": "id dispositivo: ", + "Disinvite": "Retirar convite", + "Kick": "Expulsar", + "Disinvite this user?": "Retirar convite a este usuario?", + "Kick this user?": "Expulsar este usuario?", + "Failed to kick": "Fallo ao expulsar", + "Unban": "Non bloquear", + "Ban": "Bloquear", + "Unban this user?": "Non bloquear este usuario?", + "Ban this user?": "Bloquear a este usuario?", + "Failed to ban user": "Fallo ao bloquear usuario", + "Failed to mute user": "Fallo ao acalar usuario", + "Failed to toggle moderator status": "Fallo ao mudar a estado de moderador", + "Failed to change power level": "Fallo ao cambiar o nivel de permisos", + "Are you sure?": "Está segura?", + "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Non poderá desfacer este cambio xa que está promovendo a usaria a ter o mesmo nivel de permisos que vostede.", + "No devices with registered encryption keys": "Sen dispositivos con chaves de cifrado rexistradas", + "Devices": "Dispositivos", + "Unignore": "Non ignorar", + "Ignore": "Ignorar", + "Jump to read receipt": "Ir ao resgardo de lectura", + "Mention": "Mención", + "Invite": "Convidar", + "User Options": "Axustes de usuaria", + "Direct chats": "Conversa directa", + "Unmute": "Non acalar", + "Mute": "Acalar", + "Revoke Moderator": "Quitar Moderador", + "Make Moderator": "Facer Moderador", + "Admin Tools": "Ferramentas de administración", + "Level:": "Nivel:", + "and %(count)s others...|other": "e %(count)s outras...", + "and %(count)s others...|one": "e outra máis...", + "Invited": "Convidada", + "Filter room members": "Filtrar membros da conversa", + "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (permiso %(powerLevelNumber)s)", + "Attachment": "Anexo", + "Upload Files": "Subir ficheiros", + "Are you sure you want to upload the following files?": "Está segura de que quere subir os seguintes ficheiros?", + "Encrypted room": "Sala cifrada", + "Unencrypted room": "Sala non cifrada", + "Hangup": "Quedada", + "Voice call": "Chamada de voz", + "Video call": "Chamada de vídeo", + "Hide Apps": "Agochar Apps", + "Show Apps": "Mostrar Apps", + "Upload file": "Subir ficheiro", + "Show Text Formatting Toolbar": "Mostrar barra de formato de texto", + "Send an encrypted reply…": "Enviar unha resposta cifrada…", + "Send a reply (unencrypted)…": "Enviar unha resposta (non cifrada)…", + "Send an encrypted message…": "Enviar unha mensaxe cifrada…", + "Send a message (unencrypted)…": "Enviar unha mensaxe (non cifrada)…", + "You do not have permission to post to this room": "Non ten permiso para comentar en esta sala", + "Turn Markdown on": "Habilitar Markdown", + "Turn Markdown off": "Deshabilitar Markdown", + "Hide Text Formatting Toolbar": "Agochar barra de formato de texto", + "Server error": "Fallo no servidor", + "Server unavailable, overloaded, or something else went wrong.": "Servidor non dispoñible, sobrecargado, ou outra cousa puido fallar.", + "Command error": "Erro na orde", + "bold": "remarcado", + "italic": "cursiva", + "strike": "raiado", + "underline": "subliñado", + "code": "código", + "quote": "cita", + "bullet": "lista", + "numbullet": "lista numerada", + "Markdown is disabled": "Markdown deshabilitado", + "Markdown is enabled": "Markdown habilitado", + "Unpin Message": "Desfixar mensaxe", + "Jump to message": "Ir a mensaxe", + "No pinned messages.": "Sen mensaxes fixadas.", + "Loading...": "Cargando...", + "Pinned Messages": "Mensaxes fixadas", + "%(duration)ss": "%(duration)ss", + "%(duration)sm": "%(duration)sm", + "%(duration)sh": "%(duration)sh", + "%(duration)sd": "%(duration)sd", + "Online for %(duration)s": "En liña desde %(duration)s", + "Idle for %(duration)s": "En pausa desde %(duration)s", + "Offline for %(duration)s": "Desconectado desde %(duration)s", + "Unknown for %(duration)s": "Descoñecido desde %(duration)s", + "Online": "En liña", + "Idle": "En pausa", + "Offline": "Fóra de liña", + "Unknown": "Descoñecido", + "Replying": "Respostando", + "Seen by %(userName)s at %(dateTime)s": "Visto por %(userName)s as %(dateTime)s", + "No rooms to show": "Sen salas que mostrar", + "Unnamed room": "Sala sen nome", + "World readable": "Visible por todos", + "Guests can join": "Convidados pódense unir", + "Failed to set avatar.": "Fallo ao establecer o avatar.", + "Save": "Gardar" } From 87d8ed5af84507f4cd54960f6cfd602123b3f6cd Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Tue, 16 Jan 2018 17:01:25 +0000 Subject: [PATCH 0115/1160] Add comment --- src/components/views/rooms/MessageComposer.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 8b70b67a1e..aa27dc4ae4 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -292,6 +292,8 @@ export default class MessageComposer extends React.Component { // Stickers const popoverWidth = '300px'; const popoverHeight = '300px'; + // TODO - Add support for stickerpacks from multiple app stores. + // Render content from multiple stickerpack sources, each within their own iframe, within the stickerpack UI element. const stickerpackWidget = Widgets.getStickerpackWidgets()[0]; // Load stickerpack content From 0557737f8dcc4ea4e00e535cf3e0d30812b47305 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 16 Jan 2018 17:45:29 +0000 Subject: [PATCH 0116/1160] Don't modify original options arg --- src/languageHandler.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/languageHandler.js b/src/languageHandler.js index 2d1fbc2f85..4e24c04d36 100644 --- a/src/languageHandler.js +++ b/src/languageHandler.js @@ -67,8 +67,7 @@ function safeCounterpartTranslate(text, options) { if (translated === undefined && count !== undefined) { // counterpart does not do fallback if no pluralisation exists // in the preferred language, so do it here - options.locale = 'en'; - translated = counterpart.translate(text, options); + translated = counterpart.translate(text, Object.assign({}, options, {locale: 'en'})); } return translated; } From cb7f25f4defa33e63d21808a8c9c184f89611a4b Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Tue, 16 Jan 2018 18:13:52 +0000 Subject: [PATCH 0117/1160] Remove rubbish lib. --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 36f35556fc..43a5ebfcfd 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,6 @@ "react-dom": "^15.4.0", "react-gemini-scrollbar": "matrix-org/react-gemini-scrollbar#5e97aef", "react-simple-popover": "matrix-org/react-popover", - "react-tiny-popover": "^3.2.5", "sanitize-html": "^1.14.1", "text-encoding-utf-8": "^1.0.1", "url": "^0.11.0", From 86542d86e97be93cff49bea52378a7db13334395 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Tue, 16 Jan 2018 18:14:32 +0000 Subject: [PATCH 0118/1160] Move stickers into stand-alone component. --- src/components/views/rooms/MessageComposer.js | 117 +-------------- src/components/views/rooms/Stickerpack.js | 139 ++++++++++++++++++ 2 files changed, 143 insertions(+), 113 deletions(-) create mode 100644 src/components/views/rooms/Stickerpack.js diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index aa27dc4ae4..7e001165c0 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -23,9 +23,7 @@ import sdk from '../../../index'; import dis from '../../../dispatcher'; import Autocomplete from './Autocomplete'; import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore"; -import Popover, {ArrowContainer} from 'react-tiny-popover'; -import Widgets from '../../../utils/widgets'; -import AppTile from '../elements/AppTile'; +import Stickerpack from './Stickerpack'; export default class MessageComposer extends React.Component { constructor(props, context) { @@ -33,8 +31,6 @@ export default class MessageComposer extends React.Component { this.onCallClick = this.onCallClick.bind(this); this.onHangupClick = this.onHangupClick.bind(this); this.onUploadClick = this.onUploadClick.bind(this); - this.onShowStickersClick = this.onShowStickersClick.bind(this); - this.onHideStickersClick = this.onHideStickersClick.bind(this); this.onUploadFileSelected = this.onUploadFileSelected.bind(this); this.uploadFiles = this.uploadFiles.bind(this); this.onVoiceCallClick = this.onVoiceCallClick.bind(this); @@ -46,6 +42,8 @@ export default class MessageComposer extends React.Component { this.onEvent = this.onEvent.bind(this); this.render = this.render.bind(this); + // + this.state = { autocompleteQuery: '', selection: null, @@ -56,7 +54,6 @@ export default class MessageComposer extends React.Component { wordCount: 0, }, showFormatting: SettingsStore.getValue('MessageComposer.showFormatting'), - showStickers: false, }; } @@ -193,14 +190,6 @@ export default class MessageComposer extends React.Component { // this._startCallApp(true); } - onShowStickersClick(ev) { - this.setState({showStickers: true}); - } - - onHideStickersClick(ev) { - this.setState({showStickers: false}); - } - onInputContentChanged(content: string, selection: {start: number, end: number}) { this.setState({ autocompleteQuery: content, @@ -270,7 +259,6 @@ export default class MessageComposer extends React.Component { let callButton; let videoCallButton; let hangupButton; - let stickersButton; // Call buttons if (this.props.callState && this.props.callState !== 'ended') { @@ -289,103 +277,6 @@ export default class MessageComposer extends React.Component {
    ; } - // Stickers - const popoverWidth = '300px'; - const popoverHeight = '300px'; - // TODO - Add support for stickerpacks from multiple app stores. - // Render content from multiple stickerpack sources, each within their own iframe, within the stickerpack UI element. - const stickerpackWidget = Widgets.getStickerpackWidgets()[0]; - - // Load stickerpack content - if (stickerpackWidget && stickerpackWidget.content && stickerpackWidget.content.url) { - this.state.stickersContent =
    - -
    ; - } else { - // Default content to show if stickerpack widget not added - this.state.stickersContent =

    Click here to add your first sitckerpack

    ; - } - - - if (this.state.showStickers) { - // Show hide-stickers button - stickersButton = -
    - -
    ; - } else { - // Show show-stickers button - stickersButton = -
    - -
    ; - } - - // Fall back to default highlight color if we can't compute one from the DOM - const highlightColor = document.getElementById('mx_theme_accentColor') ? - window.getComputedStyle(document.getElementById('mx_theme_accentColor')).color : - '#76CFA6'; - - const stickers = ( - -
    - { this.state.stickersContent } -
    -
    - )} - > -
    - { stickersButton } -
    -
    ; - const canSendMessages = this.props.room.currentState.maySendMessage( MatrixClientPeg.get().credentials.userId); @@ -431,7 +322,7 @@ export default class MessageComposer extends React.Component { hangupButton, callButton, videoCallButton, - stickers, + , ); } else { controls.push( diff --git a/src/components/views/rooms/Stickerpack.js b/src/components/views/rooms/Stickerpack.js new file mode 100644 index 0000000000..97b1aedb3c --- /dev/null +++ b/src/components/views/rooms/Stickerpack.js @@ -0,0 +1,139 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd +Copyright 2017 New Vector Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +import React from 'react'; +import { _t } from '../../../languageHandler'; +import Widgets from '../../../utils/widgets'; +import AppTile from '../elements/AppTile'; +import ContextualMenu from '../../structures/ContextualMenu'; +import MatrixClientPeg from '../../../MatrixClientPeg'; +import sdk from '../../../index'; + + +export default class Stickerpack extends React.Component { + constructor(props) { + super(props); + this.onShowStickersClick = this.onShowStickersClick.bind(this); + this.onHideStickersClick = this.onHideStickersClick.bind(this); + + this.defaultStickersContent = (
    +

    You don't currently have any stickerpacks enabled

    +

    Click here to add some!

    +
    ); + this.popoverWidth = 300; + this.popoverHeight = 300; + + this.state = { + stickersContent: this.defaultStickersContent, + showStickers: false, + }; + } + + onComponentDidMount() { + // Stickers + // TODO - Add support for stickerpacks from multiple app stores. + // Render content from multiple stickerpack sources, each within their own iframe, within the stickerpack UI element. + const stickerpackWidget = Widgets.getStickerpackWidgets()[0]; + let stickersContent; + + // Load stickerpack content + if (stickerpackWidget && stickerpackWidget.content && stickerpackWidget.content.url) { + stickersContent =
    + +
    ; + } else { + // Default content to show if stickerpack widget not added + stickersContent =

    Click here to add your first sitckerpack

    ; + } + this.setState({stickersContent}); + } + + onShowStickersClick(e) { + const GenericElementContextMenu = sdk.getComponent('context_menus.GenericElementContextMenu'); + const buttonRect = e.target.getBoundingClientRect(); + + // The window X and Y offsets are to adjust position when zoomed in to page + const x = buttonRect.right + window.pageXOffset - 40; + const y = (buttonRect.top + (buttonRect.height / 2) + window.pageYOffset) - 19; + // const self = this; + ContextualMenu.createMenu(GenericElementContextMenu, { + chevronOffset: 10, + chevronFace: 'bottom', + left: x, + top: y, + menuWidth: this.popoverWidth, + menuHeight: this.popoverHeight, + element: this.state.stickersContent, + }); + + + this.setState({showStickers: true}); + } + + onHideStickersClick(ev) { + this.setState({showStickers: false}); + } + + render() { + const TintableSvg = sdk.getComponent("elements.TintableSvg"); + let stickersButton; + if (this.state.showStickers) { + // Show hide-stickers button + stickersButton = +
    + +
    ; + } else { + // Show show-stickers button + stickersButton = +
    + +
    ; + } + return stickersButton; + } +} From 933928409083c48f54621bcfbcc275cf6fe8b871 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Tue, 16 Jan 2018 21:06:57 +0000 Subject: [PATCH 0119/1160] Stickerpack content placeholder. --- src/components/views/rooms/Stickerpack.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/components/views/rooms/Stickerpack.js b/src/components/views/rooms/Stickerpack.js index 97b1aedb3c..52cd32ba4f 100644 --- a/src/components/views/rooms/Stickerpack.js +++ b/src/components/views/rooms/Stickerpack.js @@ -29,10 +29,13 @@ export default class Stickerpack extends React.Component { this.onShowStickersClick = this.onShowStickersClick.bind(this); this.onHideStickersClick = this.onHideStickersClick.bind(this); - this.defaultStickersContent = (
    -

    You don't currently have any stickerpacks enabled

    -

    Click here to add some!

    -
    ); + this.defaultStickersContent = ( +
    +

    You don't currently have any stickerpacks enabled

    +

    Click here to add some!

    + Add a stickerpack +
    + ); this.popoverWidth = 300; this.popoverHeight = 300; @@ -86,7 +89,7 @@ export default class Stickerpack extends React.Component { const buttonRect = e.target.getBoundingClientRect(); // The window X and Y offsets are to adjust position when zoomed in to page - const x = buttonRect.right + window.pageXOffset - 40; + const x = buttonRect.right + window.pageXOffset - 37; const y = (buttonRect.top + (buttonRect.height / 2) + window.pageYOffset) - 19; // const self = this; ContextualMenu.createMenu(GenericElementContextMenu, { From 7676fc0c10110336279d1d27c361b4c34581fef6 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Tue, 16 Jan 2018 21:28:15 +0000 Subject: [PATCH 0120/1160] Handle stickerpack close. --- src/components/views/rooms/Stickerpack.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/views/rooms/Stickerpack.js b/src/components/views/rooms/Stickerpack.js index 52cd32ba4f..18ace9300c 100644 --- a/src/components/views/rooms/Stickerpack.js +++ b/src/components/views/rooms/Stickerpack.js @@ -28,6 +28,7 @@ export default class Stickerpack extends React.Component { super(props); this.onShowStickersClick = this.onShowStickersClick.bind(this); this.onHideStickersClick = this.onHideStickersClick.bind(this); + this.onFinished = this.onFinished.bind(this); this.defaultStickersContent = (
    @@ -100,6 +101,7 @@ export default class Stickerpack extends React.Component { menuWidth: this.popoverWidth, menuHeight: this.popoverHeight, element: this.state.stickersContent, + onFinished: this.onFinished, }); @@ -110,6 +112,10 @@ export default class Stickerpack extends React.Component { this.setState({showStickers: false}); } + onFinished() { + this.setState({showStickers: false}); + } + render() { const TintableSvg = sdk.getComponent("elements.TintableSvg"); let stickersButton; From 38ed01bebdc9334e43e55bc8f9641620efa7c92b Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Tue, 16 Jan 2018 21:35:25 +0000 Subject: [PATCH 0121/1160] Pass room to stickerpack --- src/components/views/rooms/MessageComposer.js | 2 +- src/components/views/rooms/Stickerpack.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 7e001165c0..9dbfb994c7 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -322,7 +322,7 @@ export default class MessageComposer extends React.Component { hangupButton, callButton, videoCallButton, - , + , ); } else { controls.push( diff --git a/src/components/views/rooms/Stickerpack.js b/src/components/views/rooms/Stickerpack.js index 18ace9300c..0553fbbdc6 100644 --- a/src/components/views/rooms/Stickerpack.js +++ b/src/components/views/rooms/Stickerpack.js @@ -46,11 +46,12 @@ export default class Stickerpack extends React.Component { }; } - onComponentDidMount() { + componentDidMount() { // Stickers // TODO - Add support for stickerpacks from multiple app stores. // Render content from multiple stickerpack sources, each within their own iframe, within the stickerpack UI element. const stickerpackWidget = Widgets.getStickerpackWidgets()[0]; + console.warn('Stickerpack widget', stickerpackWidget); let stickersContent; // Load stickerpack content From 86da20416972b38cb839a617bb25ca1e39705708 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Tue, 16 Jan 2018 23:25:07 +0000 Subject: [PATCH 0122/1160] Add manage stickerpacks link --- src/components/views/rooms/Stickerpack.js | 67 +++++++++++++++-------- 1 file changed, 44 insertions(+), 23 deletions(-) diff --git a/src/components/views/rooms/Stickerpack.js b/src/components/views/rooms/Stickerpack.js index 0553fbbdc6..a12f1f359d 100644 --- a/src/components/views/rooms/Stickerpack.js +++ b/src/components/views/rooms/Stickerpack.js @@ -56,29 +56,50 @@ export default class Stickerpack extends React.Component { // Load stickerpack content if (stickerpackWidget && stickerpackWidget.content && stickerpackWidget.content.url) { - stickersContent =
    - -
    ; + stickersContent = ( +
    +
    + +
    +
    + Add sticker packs +
    +
    + ); } else { // Default content to show if stickerpack widget not added stickersContent =

    Click here to add your first sitckerpack

    ; From 614a10c6d397c794c2f93fc27b96355c89174ea4 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Wed, 17 Jan 2018 00:04:06 +0000 Subject: [PATCH 0123/1160] Add manage integration link. --- src/components/views/rooms/Stickerpack.js | 36 ++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/components/views/rooms/Stickerpack.js b/src/components/views/rooms/Stickerpack.js index a12f1f359d..7afad74a4c 100644 --- a/src/components/views/rooms/Stickerpack.js +++ b/src/components/views/rooms/Stickerpack.js @@ -20,7 +20,10 @@ import Widgets from '../../../utils/widgets'; import AppTile from '../elements/AppTile'; import ContextualMenu from '../../structures/ContextualMenu'; import MatrixClientPeg from '../../../MatrixClientPeg'; +import Modal from '../../../Modal'; import sdk from '../../../index'; +import SdkConfig from '../../../SdkConfig'; +import ScalarAuthClient from '../../../ScalarAuthClient'; export default class Stickerpack extends React.Component { @@ -29,6 +32,7 @@ export default class Stickerpack extends React.Component { this.onShowStickersClick = this.onShowStickersClick.bind(this); this.onHideStickersClick = this.onHideStickersClick.bind(this); this.onFinished = this.onFinished.bind(this); + this._launchManageIntegrations = this._launchManageIntegrations.bind(this); this.defaultStickersContent = (
    @@ -47,6 +51,20 @@ export default class Stickerpack extends React.Component { } componentDidMount() { + this.scalarClient = null; + if (SdkConfig.get().integrations_ui_url && SdkConfig.get().integrations_rest_url) { + this.scalarClient = new ScalarAuthClient(); + this.scalarClient.connect().then(() => { + this.forceUpdate(); + }).catch((e) => { + console.log("Failed to connect to integrations server"); + // TODO -- Handle Scalar errors + // this.setState({ + // scalar_error: err, + // }); + }); + } + // Stickers // TODO - Add support for stickerpacks from multiple app stores. // Render content from multiple stickerpack sources, each within their own iframe, within the stickerpack UI element. @@ -56,6 +74,7 @@ export default class Stickerpack extends React.Component { // Load stickerpack content if (stickerpackWidget && stickerpackWidget.content && stickerpackWidget.content.url) { + this.widgetId = stickerpackWidget.id; stickersContent = (
    - Add sticker packs + Add sticker packs
    ); @@ -138,6 +157,21 @@ export default class Stickerpack extends React.Component { this.setState({showStickers: false}); } + _launchManageIntegrations() { + this.onFinished(); + const IntegrationsManager = sdk.getComponent("views.settings.IntegrationsManager"); + const src = (this.scalarClient !== null && this.scalarClient.hasCredentials()) ? + this.scalarClient.getScalarInterfaceUrlForRoom( + this.props.room.roomId, + 'add_integ', + // this.widgetId, + ) : + null; + Modal.createTrackedDialog('Integrations Manager', '', IntegrationsManager, { + src: src, + }, "mx_IntegrationsManager"); + } + render() { const TintableSvg = sdk.getComponent("elements.TintableSvg"); let stickersButton; From 2a1f8bd394a5d9fa300062017437f02f93af2f6a Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Wed, 17 Jan 2018 10:45:49 +0000 Subject: [PATCH 0124/1160] Ignore remote echos caused by this client by sending each tag_ordering with a _storeId and ignoring accout data that has a matching _storeId. This will tend to become out of sync with the server over time if requests continually fail, but subsequent successful requests will rectify any differences. --- src/actions/TagOrderActions.js | 7 ++++++- src/stores/TagOrderStore.js | 12 ++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/actions/TagOrderActions.js b/src/actions/TagOrderActions.js index 608fd6c4c5..dd4df6a9d4 100644 --- a/src/actions/TagOrderActions.js +++ b/src/actions/TagOrderActions.js @@ -42,9 +42,14 @@ TagOrderActions.moveTag = function(matrixClient, tag, destinationIx) { tags = tags.filter((t) => t !== tag); tags = [...tags.slice(0, destinationIx), tag, ...tags.slice(destinationIx)]; + const storeId = TagOrderStore.getStoreId(); + return asyncAction('TagOrderActions.moveTag', () => { Analytics.trackEvent('TagOrderActions', 'commitTagOrdering'); - return matrixClient.setAccountData('im.vector.web.tag_ordering', {tags}); + return matrixClient.setAccountData( + 'im.vector.web.tag_ordering', + {tags, _storeId: storeId}, + ); }, () => { // For an optimistic update return {tags}; diff --git a/src/stores/TagOrderStore.js b/src/stores/TagOrderStore.js index 27ce6cbb73..effd8287c7 100644 --- a/src/stores/TagOrderStore.js +++ b/src/stores/TagOrderStore.js @@ -63,6 +63,11 @@ class TagOrderStore extends Store { // Get ordering from account data case 'MatrixActions.accountData': { if (payload.event_type !== 'im.vector.web.tag_ordering') break; + + // Ignore remote echos caused by this store so as to avoid setting + // state back to old state. + if (payload.event_content._storeId === this.getStoreId()) break; + this._setState({ orderedTagsAccountData: payload.event_content ? payload.event_content.tags : null, }); @@ -176,6 +181,13 @@ class TagOrderStore extends Store { return this._state.orderedTags; } + getStoreId() { + // Generate a random ID to prevent this store from clobbering its + // state with redundant remote echos. + if (!this._id) this._id = Math.random().toString(16).slice(2, 10); + return this._id; + } + getSelectedTags() { return this._state.selectedTags; } From 621682a2dbadad22d40ad8a3702483e3235b54a7 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 17 Jan 2018 11:01:07 +0000 Subject: [PATCH 0125/1160] Retest please From 47f3e511b6dc9ce3b094d8b9c2ba92c40fd2aaae Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 17 Jan 2018 11:01:50 +0000 Subject: [PATCH 0126/1160] Retest please From 3331c8af273622c0c57e98ab56a51de1f504101f Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Wed, 17 Jan 2018 15:40:04 +0000 Subject: [PATCH 0127/1160] Use dispatcher ref for unregister call. --- src/components/views/elements/AppTile.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 1da344227e..fd88295122 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -43,7 +43,7 @@ export default class AppTile extends React.Component { super(props); this.state = this._getNewState(props); - this._onAction = this._onAction.bind(this); + this._onWidgetAction = this._onWidgetAction.bind(this); this._onMessage = this._onMessage.bind(this); this._onLoaded = this._onLoaded.bind(this); this._onEditClick = this._onEditClick.bind(this); @@ -161,7 +161,7 @@ export default class AppTile extends React.Component { window.addEventListener('message', this._onMessage, false); // General event handler - dis.register(this._onAction); + this.dispatcherRef = dis.register(this._onWidgetAction); } /** @@ -217,13 +217,19 @@ export default class AppTile extends React.Component { } componentWillUnmount() { + // Widget action listeners + dis.unregister(this.dispatcherRef); + + // Widget postMessage listeners try { - this.widgetMessaging.stopListening(); - this.widgetMessaging.removeEndpoint(this.props.id, this.props.url); + if (this.widgetMessaging) { + this.widgetMessaging.stopListening(); + this.widgetMessaging.removeEndpoint(this.props.id, this.props.url); + } } catch (e) { console.error('Failed to stop listening for widgetMessaging events', e.message); } - dis.unregister(this._onAction); + // Jitsi listener window.removeEventListener('message', this._onMessage); } @@ -342,7 +348,7 @@ export default class AppTile extends React.Component { this.setState({loading: false}); } - _onAction(payload) { + _onWidgetAction(payload) { if (payload.widgetId === this.props.id) { switch (payload.action) { case 'sticker_message': From 5a4271268b72c1e878c224b7290474ed70d787cd Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Wed, 17 Jan 2018 15:40:47 +0000 Subject: [PATCH 0128/1160] Keep reference to stickers menu --- src/components/views/rooms/Stickerpack.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/Stickerpack.js b/src/components/views/rooms/Stickerpack.js index 7afad74a4c..4bcb426a35 100644 --- a/src/components/views/rooms/Stickerpack.js +++ b/src/components/views/rooms/Stickerpack.js @@ -134,7 +134,7 @@ export default class Stickerpack extends React.Component { const x = buttonRect.right + window.pageXOffset - 37; const y = (buttonRect.top + (buttonRect.height / 2) + window.pageYOffset) - 19; // const self = this; - ContextualMenu.createMenu(GenericElementContextMenu, { + this.stickersMenu = ContextualMenu.createMenu(GenericElementContextMenu, { chevronOffset: 10, chevronFace: 'bottom', left: x, @@ -150,11 +150,12 @@ export default class Stickerpack extends React.Component { } onHideStickersClick(ev) { - this.setState({showStickers: false}); + this.stickersMenu.close(); } onFinished() { this.setState({showStickers: false}); + this.stickersMenu = null; } _launchManageIntegrations() { From fa336b7a99d1ae7564985dd05d47e21e92f32f9a Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Wed, 17 Jan 2018 15:41:15 +0000 Subject: [PATCH 0129/1160] Bring hide stickers icon to front when menu open. --- src/components/views/rooms/Stickerpack.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/rooms/Stickerpack.js b/src/components/views/rooms/Stickerpack.js index 4bcb426a35..84a7f4cbef 100644 --- a/src/components/views/rooms/Stickerpack.js +++ b/src/components/views/rooms/Stickerpack.js @@ -182,7 +182,7 @@ export default class Stickerpack extends React.Component {
    From aa524c339d290560d32f7c2804f5a6ed4ef10e30 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Wed, 17 Jan 2018 15:49:36 +0000 Subject: [PATCH 0130/1160] Update class names. --- src/components/views/rooms/Stickerpack.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/views/rooms/Stickerpack.js b/src/components/views/rooms/Stickerpack.js index 84a7f4cbef..3c4a8f6425 100644 --- a/src/components/views/rooms/Stickerpack.js +++ b/src/components/views/rooms/Stickerpack.js @@ -35,7 +35,7 @@ export default class Stickerpack extends React.Component { this._launchManageIntegrations = this._launchManageIntegrations.bind(this); this.defaultStickersContent = ( -
    +

    You don't currently have any stickerpacks enabled

    Click here to add some!

    Add a stickerpack @@ -84,7 +84,7 @@ export default class Stickerpack extends React.Component { >
    - Add sticker packs + Add sticker packs
    ); @@ -182,7 +182,7 @@ export default class Stickerpack extends React.Component {
    From b6f85fbf9251bb36e61335a23091b4534d353870 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Wed, 17 Jan 2018 16:52:10 +0000 Subject: [PATCH 0131/1160] Don't treat sticker messages as info messages. --- src/components/views/rooms/EventTile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 46dc0d19db..a6750ac792 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -440,7 +440,7 @@ module.exports = withMatrixClient(React.createClass({ const eventType = this.props.mxEvent.getType(); // Info messages are basically information about commands processed on a room - const isInfoMessage = (eventType !== 'm.room.message'); + const isInfoMessage = (eventType !== 'm.room.message' && eventType !== 'm.room.sticker'); const EventTileType = sdk.getComponent(getHandlerTile(this.props.mxEvent)); // This shouldn't happen: the caller should check we support this type From 3ebf278cf3dc11d04d8b1240341e3a3af0e2b5ec Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Wed, 17 Jan 2018 16:59:13 +0000 Subject: [PATCH 0132/1160] Refactor GroupStore based on existing STATE_KEY concept by factoring out a lot of repeated code. --- src/stores/GroupStore.js | 145 ++++++++++++++++++++------------------- 1 file changed, 75 insertions(+), 70 deletions(-) diff --git a/src/stores/GroupStore.js b/src/stores/GroupStore.js index 9dce15fb53..d0040528a8 100644 --- a/src/stores/GroupStore.js +++ b/src/stores/GroupStore.js @@ -19,6 +19,14 @@ import { groupMemberFromApiObject, groupRoomFromApiObject } from '../groups'; import FlairStore from './FlairStore'; import MatrixClientPeg from '../MatrixClientPeg'; +function parseMembersResponse(response) { + return response.chunk.map((apiMember) => groupMemberFromApiObject(apiMember)); +} + +function parseRoomsResponse(response) { + return response.chunk.map((apiRoom) => groupRoomFromApiObject(apiRoom)); +} + /** * Stores the group summary for a room and provides an API to change it and * other useful group APIs that may have an effect on the group summary. @@ -38,65 +46,57 @@ export default class GroupStore extends EventEmitter { throw new Error('GroupStore needs a valid groupId to be created'); } this.groupId = groupId; - this._summary = {}; - this._rooms = []; - this._members = []; - this._invitedMembers = []; + this._state = {}; + this._state[GroupStore.STATE_KEY.Summary] = {}; + this._state[GroupStore.STATE_KEY.GroupRooms] = []; + this._state[GroupStore.STATE_KEY.GroupMembers] = []; + this._state[GroupStore.STATE_KEY.GroupInvitedMembers] = []; this._ready = {}; + this._resourceFetcher = { + [GroupStore.STATE_KEY.Summary]: () => { + return MatrixClientPeg.get() + .getGroupSummary(this.groupId); + }, + [GroupStore.STATE_KEY.GroupRooms]: () => { + return MatrixClientPeg.get() + .getGroupRooms(this.groupId) + .then(parseRoomsResponse); + }, + [GroupStore.STATE_KEY.GroupMembers]: () => { + return MatrixClientPeg.get() + .getGroupUsers(this.groupId) + .then(parseMembersResponse); + }, + [GroupStore.STATE_KEY.GroupInvitedMembers]: () => { + return MatrixClientPeg.get() + .getGroupInvitedUsers(this.groupId) + .then(parseMembersResponse); + }, + }; + this.on('error', (err) => { console.error(`GroupStore for ${this.groupId} encountered error`, err); }); } - _fetchMembers() { - MatrixClientPeg.get().getGroupUsers(this.groupId).then((result) => { - this._members = result.chunk.map((apiMember) => { - return groupMemberFromApiObject(apiMember); - }); - this._ready[GroupStore.STATE_KEY.GroupMembers] = true; - this._notifyListeners(); - }).catch((err) => { - console.error("Failed to get group member list: " + err); - this.emit('error', err); - }); - - MatrixClientPeg.get().getGroupInvitedUsers(this.groupId).then((result) => { - this._invitedMembers = result.chunk.map((apiMember) => { - return groupMemberFromApiObject(apiMember); - }); - this._ready[GroupStore.STATE_KEY.GroupInvitedMembers] = true; + _fetchResource(stateKey) { + const clientPromise = this._resourceFetcher[stateKey](); + clientPromise.then((result) => { + this._state[stateKey] = result; + this._ready[stateKey] = true; this._notifyListeners(); }).catch((err) => { // Invited users not visible to non-members - if (err.httpStatus === 403) { + if (stateKey === GroupStore.STATE_KEY.GroupInvitedMembers && err.httpStatus === 403) { return; } - console.error("Failed to get group invited member list: " + err); - this.emit('error', err); - }); - } - _fetchSummary() { - MatrixClientPeg.get().getGroupSummary(this.groupId).then((resp) => { - this._summary = resp; - this._ready[GroupStore.STATE_KEY.Summary] = true; - this._notifyListeners(); - }).catch((err) => { + console.error("Failed to get resource " + stateKey + ":" + err); this.emit('error', err); }); - } - _fetchRooms() { - MatrixClientPeg.get().getGroupRooms(this.groupId).then((resp) => { - this._rooms = resp.chunk.map((apiRoom) => { - return groupRoomFromApiObject(apiRoom); - }); - this._ready[GroupStore.STATE_KEY.GroupRooms] = true; - this._notifyListeners(); - }).catch((err) => { - this.emit('error', err); - }); + return clientPromise; } _notifyListeners() { @@ -108,10 +108,9 @@ export default class GroupStore extends EventEmitter { * immediately triggers an update to send the current state of the * store (which could be the initial state). * - * XXX: This also causes a fetch of all group data, which effectively - * causes 4 separate HTTP requests. This is bad, we should at least - * deduplicate these in order to fix: - * https://github.com/vector-im/riot-web/issues/5901 + * This also causes a fetch of all group data, which might cause + * 4 separate HTTP requests, but only said requests aren't already + * ongoing. * * @param {function} fn the function to call when the store updates. * @return {Object} tok a registration "token" with a single @@ -123,9 +122,11 @@ export default class GroupStore extends EventEmitter { this.on('update', fn); // Call to set initial state (before fetching starts) this.emit('update'); - this._fetchSummary(); - this._fetchRooms(); - this._fetchMembers(); + + this._fetchResource(GroupStore.STATE_KEY.Summary); + this._fetchResource(GroupStore.STATE_KEY.GroupRooms); + this._fetchResource(GroupStore.STATE_KEY.GroupMembers); + this._fetchResource(GroupStore.STATE_KEY.GroupInvitedMembers); // Similar to the Store of flux/utils, we return a "token" that // can be used to unregister the listener. @@ -145,90 +146,94 @@ export default class GroupStore extends EventEmitter { } getSummary() { - return this._summary; + return this._state[GroupStore.STATE_KEY.Summary]; } getGroupRooms() { - return this._rooms; + return this._state[GroupStore.STATE_KEY.GroupRooms]; } - getGroupMembers( ) { - return this._members; + getGroupMembers() { + return this._state[GroupStore.STATE_KEY.GroupMembers]; } - getGroupInvitedMembers( ) { - return this._invitedMembers; + getGroupInvitedMembers() { + return this._state[GroupStore.STATE_KEY.GroupInvitedMembers]; } getGroupPublicity() { - return this._summary.user ? this._summary.user.is_publicised : null; + return this._state[GroupStore.STATE_KEY.Summary].user ? + this._state[GroupStore.STATE_KEY.Summary].user.is_publicised : null; } isUserPrivileged() { - return this._summary.user ? this._summary.user.is_privileged : null; + return this._state[GroupStore.STATE_KEY.Summary].user ? + this._state[GroupStore.STATE_KEY.Summary].user.is_privileged : null; } addRoomToGroup(roomId, isPublic) { return MatrixClientPeg.get() .addRoomToGroup(this.groupId, roomId, isPublic) - .then(this._fetchRooms.bind(this)); + .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupRooms)); } updateGroupRoomVisibility(roomId, isPublic) { return MatrixClientPeg.get() .updateGroupRoomVisibility(this.groupId, roomId, isPublic) - .then(this._fetchRooms.bind(this)); + .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupRooms)); } removeRoomFromGroup(roomId) { return MatrixClientPeg.get() .removeRoomFromGroup(this.groupId, roomId) // Room might be in the summary, refresh just in case - .then(this._fetchSummary.bind(this)) - .then(this._fetchRooms.bind(this)); + .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary)) + .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupRooms)); } inviteUserToGroup(userId) { return MatrixClientPeg.get().inviteUserToGroup(this.groupId, userId) - .then(this._fetchMembers.bind(this)); + .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupInvitedMembers)); } acceptGroupInvite() { return MatrixClientPeg.get().acceptGroupInvite(this.groupId) // The user might be able to see more rooms now - .then(this._fetchRooms.bind(this)) + .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupRooms)) // The user should now appear as a member - .then(this._fetchMembers.bind(this)); + .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupMembers)) + // The user should now not appear as an invited member + .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupInvitedMembers)); } addRoomToGroupSummary(roomId, categoryId) { return MatrixClientPeg.get() .addRoomToGroupSummary(this.groupId, roomId, categoryId) - .then(this._fetchSummary.bind(this)); + .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary)); } addUserToGroupSummary(userId, roleId) { return MatrixClientPeg.get() .addUserToGroupSummary(this.groupId, userId, roleId) - .then(this._fetchSummary.bind(this)); + .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary)); } removeRoomFromGroupSummary(roomId) { return MatrixClientPeg.get() .removeRoomFromGroupSummary(this.groupId, roomId) - .then(this._fetchSummary.bind(this)); + .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary)); } removeUserFromGroupSummary(userId) { return MatrixClientPeg.get() .removeUserFromGroupSummary(this.groupId, userId) - .then(this._fetchSummary.bind(this)); + .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary)); } setGroupPublicity(isPublished) { return MatrixClientPeg.get() .setGroupPublicity(this.groupId, isPublished) .then(() => { FlairStore.invalidatePublicisedGroups(MatrixClientPeg.get().credentials.userId); }) - .then(this._fetchSummary.bind(this)); + .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary)); } } From 5f413ddf8bd3cc376eedf2664067ae3ecca2bac3 Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Wed, 17 Jan 2018 17:01:42 +0000 Subject: [PATCH 0133/1160] Do not fetch GroupStore resources if already fetching --- src/stores/GroupStore.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/stores/GroupStore.js b/src/stores/GroupStore.js index d0040528a8..c3465b684c 100644 --- a/src/stores/GroupStore.js +++ b/src/stores/GroupStore.js @@ -53,6 +53,7 @@ export default class GroupStore extends EventEmitter { this._state[GroupStore.STATE_KEY.GroupInvitedMembers] = []; this._ready = {}; + this._fetchResourcePromise = {}; this._resourceFetcher = { [GroupStore.STATE_KEY.Summary]: () => { return MatrixClientPeg.get() @@ -81,7 +82,14 @@ export default class GroupStore extends EventEmitter { } _fetchResource(stateKey) { + // Ongoing request, ignore + if (this._fetchResourcePromise[stateKey]) return; + const clientPromise = this._resourceFetcher[stateKey](); + + // Indicate ongoing request + this._fetchResourcePromise[stateKey] = clientPromise; + clientPromise.then((result) => { this._state[stateKey] = result; this._ready[stateKey] = true; @@ -94,6 +102,9 @@ export default class GroupStore extends EventEmitter { console.error("Failed to get resource " + stateKey + ":" + err); this.emit('error', err); + }).finally(() => { + // Indicate finished request, allow for future fetches + delete this._fetchResourcePromise[stateKey]; }); return clientPromise; From f8d7ab10fab9c742f2351477e698d5f6b0e6a5d1 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Wed, 17 Jan 2018 17:19:20 +0000 Subject: [PATCH 0134/1160] Handle non-m.room.message event types. --- src/components/structures/MessagePanel.js | 2 +- src/components/views/rooms/EventTile.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index 53cc660a9b..30ded948a4 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -450,7 +450,7 @@ module.exports = React.createClass({ if (prevEvent !== null && prevEvent.sender && mxEv.sender && mxEv.sender.userId === prevEvent.sender.userId - && mxEv.getType() == prevEvent.getType()) { + && Boolean(mxEv.getContent().body) == Boolean(prevEvent.getContent().body)) { continuation = true; } diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index a6750ac792..3245cf1ac3 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -440,7 +440,8 @@ module.exports = withMatrixClient(React.createClass({ const eventType = this.props.mxEvent.getType(); // Info messages are basically information about commands processed on a room - const isInfoMessage = (eventType !== 'm.room.message' && eventType !== 'm.room.sticker'); + // For now assume that anything that doesn't have a content body is an isInfoMessage + const isInfoMessage = !content.body; // Boolean comparison of non-boolean content body const EventTileType = sdk.getComponent(getHandlerTile(this.props.mxEvent)); // This shouldn't happen: the caller should check we support this type From b90a98b5c1e46751dcd412ddd842d04c4d6d7171 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 17 Jan 2018 18:06:19 +0000 Subject: [PATCH 0135/1160] don't pass back {} when we have no `org.matrix.room.color_scheme` Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/settings/handlers/RoomAccountSettingsHandler.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/settings/handlers/RoomAccountSettingsHandler.js b/src/settings/handlers/RoomAccountSettingsHandler.js index e946581807..72355b43be 100644 --- a/src/settings/handlers/RoomAccountSettingsHandler.js +++ b/src/settings/handlers/RoomAccountSettingsHandler.js @@ -24,7 +24,7 @@ export default class RoomAccountSettingsHandler extends SettingsHandler { getValue(settingName, roomId) { // Special case URL previews if (settingName === "urlPreviewsEnabled") { - const content = this._getSettings(roomId, "org.matrix.room.preview_urls"); + const content = this._getSettings(roomId, "org.matrix.room.preview_urls") || {}; // Check to make sure that we actually got a boolean if (typeof(content['disable']) !== "boolean") return null; @@ -38,13 +38,14 @@ export default class RoomAccountSettingsHandler extends SettingsHandler { return this._getSettings(roomId, "org.matrix.room.color_scheme"); } - return this._getSettings(roomId)[settingName]; + const settings = this._getSettings(roomId) || {}; + return settings[settingName]; } setValue(settingName, roomId, newValue) { // Special case URL previews if (settingName === "urlPreviewsEnabled") { - const content = this._getSettings(roomId, "org.matrix.room.preview_urls"); + const content = this._getSettings(roomId, "org.matrix.room.preview_urls") || {}; content['disable'] = !newValue; return MatrixClientPeg.get().setRoomAccountData(roomId, "org.matrix.room.preview_urls", content); } @@ -55,7 +56,7 @@ export default class RoomAccountSettingsHandler extends SettingsHandler { return MatrixClientPeg.get().setRoomAccountData(roomId, "org.matrix.room.color_scheme", newValue); } - const content = this._getSettings(roomId); + const content = this._getSettings(roomId) || {}; content[settingName] = newValue; return MatrixClientPeg.get().setRoomAccountData(roomId, "im.vector.web.settings", content); } @@ -74,10 +75,10 @@ export default class RoomAccountSettingsHandler extends SettingsHandler { _getSettings(roomId, eventType = "im.vector.settings") { const room = MatrixClientPeg.get().getRoom(roomId); - if (!room) return {}; + if (!room) return null; const event = room.getAccountData(eventType); - if (!event || !event.getContent()) return {}; + if (!event || !event.getContent()) return null; return event.getContent(); } } From 43bb8c561d3e70e7b19682bde727338d520d2164 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 17 Jan 2018 18:10:19 +0000 Subject: [PATCH 0136/1160] add comment Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/settings/handlers/RoomAccountSettingsHandler.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/settings/handlers/RoomAccountSettingsHandler.js b/src/settings/handlers/RoomAccountSettingsHandler.js index 72355b43be..74dbf9eed0 100644 --- a/src/settings/handlers/RoomAccountSettingsHandler.js +++ b/src/settings/handlers/RoomAccountSettingsHandler.js @@ -35,6 +35,7 @@ export default class RoomAccountSettingsHandler extends SettingsHandler { if (settingName === "roomColor") { // The event content should already be in an appropriate format, we just need // to get the right value. + // don't fallback to {} because thats truthy and would imply there is an event specifying tint return this._getSettings(roomId, "org.matrix.room.color_scheme"); } From b7204e79a7479dc1f1a2d429e4e9c55da7485dc0 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 17 Jan 2018 18:17:26 +0000 Subject: [PATCH 0137/1160] fallback after receiving settings rather than {} because its truthy Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/settings/handlers/AccountSettingsHandler.js | 16 +++++++++------- src/settings/handlers/DeviceSettingsHandler.js | 7 ++++--- src/settings/handlers/RoomSettingsHandler.js | 14 ++++++++------ 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/settings/handlers/AccountSettingsHandler.js b/src/settings/handlers/AccountSettingsHandler.js index e50358a728..b822709573 100644 --- a/src/settings/handlers/AccountSettingsHandler.js +++ b/src/settings/handlers/AccountSettingsHandler.js @@ -25,19 +25,20 @@ export default class AccountSettingHandler extends SettingsHandler { getValue(settingName, roomId) { // Special case URL previews if (settingName === "urlPreviewsEnabled") { - const content = this._getSettings("org.matrix.preview_urls"); + const content = this._getSettings("org.matrix.preview_urls") || {}; // Check to make sure that we actually got a boolean if (typeof(content['disable']) !== "boolean") return null; return !content['disable']; } - let preferredValue = this._getSettings()[settingName]; + const settings = this._getSettings() || {}; + let preferredValue = settings[settingName]; if (preferredValue === null || preferredValue === undefined) { // Honour the old setting on read only if (settingName === "hideAvatarChanges" || settingName === "hideDisplaynameChanges") { - preferredValue = this._getSettings()["hideAvatarDisplaynameChanges"]; + preferredValue = settings["hideAvatarDisplaynameChanges"]; } } @@ -47,12 +48,12 @@ export default class AccountSettingHandler extends SettingsHandler { setValue(settingName, roomId, newValue) { // Special case URL previews if (settingName === "urlPreviewsEnabled") { - const content = this._getSettings("org.matrix.preview_urls"); + const content = this._getSettings("org.matrix.preview_urls") || {}; content['disable'] = !newValue; return MatrixClientPeg.get().setAccountData("org.matrix.preview_urls", content); } - const content = this._getSettings(); + const content = this._getSettings() || {}; content[settingName] = newValue; return MatrixClientPeg.get().setAccountData("im.vector.web.settings", content); } @@ -68,9 +69,10 @@ export default class AccountSettingHandler extends SettingsHandler { _getSettings(eventType = "im.vector.web.settings") { const cli = MatrixClientPeg.get(); - if (!cli) return {}; + if (!cli) return null; + const event = cli.getAccountData(eventType); - if (!event || !event.getContent()) return {}; + if (!event || !event.getContent()) return null; return event.getContent(); } } diff --git a/src/settings/handlers/DeviceSettingsHandler.js b/src/settings/handlers/DeviceSettingsHandler.js index 22f6140a80..13117f7498 100644 --- a/src/settings/handlers/DeviceSettingsHandler.js +++ b/src/settings/handlers/DeviceSettingsHandler.js @@ -53,7 +53,8 @@ export default class DeviceSettingsHandler extends SettingsHandler { return null; // wrong type or otherwise not set } - return this._getSettings()[settingName]; + const settings = this._getSettings() || {}; + return settings[settingName]; } setValue(settingName, roomId, newValue) { @@ -74,7 +75,7 @@ export default class DeviceSettingsHandler extends SettingsHandler { return Promise.resolve(); } - const settings = this._getSettings(); + const settings = this._getSettings() || {}; settings[settingName] = newValue; localStorage.setItem("mx_local_settings", JSON.stringify(settings)); @@ -91,7 +92,7 @@ export default class DeviceSettingsHandler extends SettingsHandler { _getSettings() { const value = localStorage.getItem("mx_local_settings"); - if (!value) return {}; + if (!value) return null; return JSON.parse(value); } diff --git a/src/settings/handlers/RoomSettingsHandler.js b/src/settings/handlers/RoomSettingsHandler.js index cb3e836c7f..71abff94f6 100644 --- a/src/settings/handlers/RoomSettingsHandler.js +++ b/src/settings/handlers/RoomSettingsHandler.js @@ -24,25 +24,26 @@ export default class RoomSettingsHandler extends SettingsHandler { getValue(settingName, roomId) { // Special case URL previews if (settingName === "urlPreviewsEnabled") { - const content = this._getSettings(roomId, "org.matrix.room.preview_urls"); + const content = this._getSettings(roomId, "org.matrix.room.preview_urls") || {}; // Check to make sure that we actually got a boolean if (typeof(content['disable']) !== "boolean") return null; return !content['disable']; } - return this._getSettings(roomId)[settingName]; + const settings = this._getSettings(roomId) || {}; + return settings[settingName]; } setValue(settingName, roomId, newValue) { // Special case URL previews if (settingName === "urlPreviewsEnabled") { - const content = this._getSettings(roomId, "org.matrix.room.preview_urls"); + const content = this._getSettings(roomId, "org.matrix.room.preview_urls") || {}; content['disable'] = !newValue; return MatrixClientPeg.get().sendStateEvent(roomId, "org.matrix.room.preview_urls", content); } - const content = this._getSettings(roomId); + const content = this._getSettings(roomId) || {}; content[settingName] = newValue; return MatrixClientPeg.get().sendStateEvent(roomId, "im.vector.web.settings", content, ""); } @@ -65,9 +66,10 @@ export default class RoomSettingsHandler extends SettingsHandler { _getSettings(roomId, eventType = "im.vector.web.settings") { const room = MatrixClientPeg.get().getRoom(roomId); - if (!room) return {}; + if (!room) return null; + const event = room.currentState.getStateEvents(eventType, ""); - if (!event || !event.getContent()) return {}; + if (!event || !event.getContent()) return null; return event.getContent(); } } From d3292d93887e6834056a6b922bb6ab9cbb0e43d7 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Wed, 17 Jan 2018 23:25:39 +0000 Subject: [PATCH 0138/1160] fix typos and NPE. fixes #5999 --- src/components/views/rooms/MemberInfo.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js index 33d59e0467..816246a2de 100644 --- a/src/components/views/rooms/MemberInfo.js +++ b/src/components/views/rooms/MemberInfo.js @@ -857,8 +857,8 @@ module.exports = withMatrixClient(React.createClass({ } const room = this.props.matrixClient.getRoom(this.props.member.roomId); - const poweLevelEvent = room ? room.currentState.getStateEvents("m.room.power_levels", "") : null; - const powerLevelUsersDefault = poweLevelEvent.getContent().users_default; + const powerLevelEvent = room ? room.currentState.getStateEvents("m.room.power_levels", "") : null; + const powerLevelUsersDefault = powerLevelEvent ? powerLevelEvent.getContent().users_default : 0; let roomMemberDetails = null; if (this.props.member.roomId) { // is in room From 80d3edfbb339ac5a90f5d6fd13a53b3f35aaa475 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Thu, 18 Jan 2018 09:57:29 +0000 Subject: [PATCH 0139/1160] simplify the 'send anyway' text, as 'mark devices known' is meaningless to users --- src/components/structures/RoomStatusBar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/RoomStatusBar.js b/src/components/structures/RoomStatusBar.js index 47da4096c0..8034923158 100644 --- a/src/components/structures/RoomStatusBar.js +++ b/src/components/structures/RoomStatusBar.js @@ -296,7 +296,7 @@ module.exports = React.createClass({ if (hasUDE) { title = _t("Message not sent due to unknown devices being present"); content = _t( - "Show devices, mark devices known and send or cancel all.", + "Show devices, send anyway or cancel.", {}, { 'showDevicesText': (sub) => { sub }, From 1293c53c4bbb4d5a95503ab65c0d952bd5387fbf Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 18 Jan 2018 12:02:45 +0000 Subject: [PATCH 0140/1160] Cleanup --- src/components/views/elements/AppTile.js | 39 +++++++++++++----------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index fd88295122..05ea8cfa0b 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -160,10 +160,30 @@ export default class AppTile extends React.Component { // postMessaging API window.addEventListener('message', this._onMessage, false); - // General event handler + // Widget action listeners this.dispatcherRef = dis.register(this._onWidgetAction); } + componentWillUnmount() { + // Widget action listeners + console.warn('Removing widget event listener', this.dispatcherRef); + dis.unregister(this.dispatcherRef); + + // Widget postMessage listeners + try { + if (this.widgetMessaging) { + this.widgetMessaging.stopListening(); + this.widgetMessaging.removeEndpoint(this.props.id, this.props.url); + } else { + console.warn('WidgetMessaging not initialised. Not stopping.'); + } + } catch (e) { + console.error('Failed to stop listening for widgetMessaging events', e.message); + } + // Jitsi listener + window.removeEventListener('message', this._onMessage); + } + /** * Adds a scalar token to the widget URL, if required * Component initialisation is only complete when this function has resolved @@ -216,23 +236,6 @@ export default class AppTile extends React.Component { }); } - componentWillUnmount() { - // Widget action listeners - dis.unregister(this.dispatcherRef); - - // Widget postMessage listeners - try { - if (this.widgetMessaging) { - this.widgetMessaging.stopListening(); - this.widgetMessaging.removeEndpoint(this.props.id, this.props.url); - } - } catch (e) { - console.error('Failed to stop listening for widgetMessaging events', e.message); - } - // Jitsi listener - window.removeEventListener('message', this._onMessage); - } - componentWillReceiveProps(nextProps) { if (nextProps.url !== this.props.url) { this._getNewState(nextProps); From 917d85d603d071764e2ce7151e8fdbb3f72fc287 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 18 Jan 2018 12:03:24 +0000 Subject: [PATCH 0141/1160] Refer rest parameters --- src/components/structures/ContextualMenu.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/structures/ContextualMenu.js b/src/components/structures/ContextualMenu.js index 3c2308e6a7..f3189c2e4b 100644 --- a/src/components/structures/ContextualMenu.js +++ b/src/components/structures/ContextualMenu.js @@ -51,11 +51,11 @@ module.exports = { createMenu: function(Element, props) { const self = this; - const closeMenu = function() { + const closeMenu = function(...args) { ReactDOM.unmountComponentAtNode(self.getOrCreateContainer()); if (props && props.onFinished) { - props.onFinished.apply(null, arguments); + props.onFinished.apply(null, args); } }; From 910623d287c131ec51ff3ec09091a91b5f85d6f2 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 18 Jan 2018 12:04:00 +0000 Subject: [PATCH 0142/1160] Close context menu on resize. --- src/components/structures/ContextualMenu.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/structures/ContextualMenu.js b/src/components/structures/ContextualMenu.js index f3189c2e4b..7ec078f739 100644 --- a/src/components/structures/ContextualMenu.js +++ b/src/components/structures/ContextualMenu.js @@ -59,6 +59,11 @@ module.exports = { } }; + // Close the menu on window resize + const windowResize = function() { + closeMenu(); + }; + const position = {}; let chevronFace = null; @@ -135,7 +140,7 @@ module.exports = {
    { chevron } - +
    From 23bef68a8f0a3f08ff3a5d22646c26c41a8dbffa Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 18 Jan 2018 13:16:06 +0000 Subject: [PATCH 0143/1160] Fix duplicate message listeners --- src/WidgetMessaging.js | 16 ++++++++++++---- src/components/views/elements/AppTile.js | 8 ++------ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/WidgetMessaging.js b/src/WidgetMessaging.js index cd1e4a0996..c1af402e4d 100644 --- a/src/WidgetMessaging.js +++ b/src/WidgetMessaging.js @@ -178,6 +178,10 @@ export default class WidgetMessaging extends MatrixPostMessageApi { constructor(widgetId, targetWindow) { super(targetWindow); this.widgetId = widgetId; + + this.startListening = this.startListening.bind(this); + this.stopListening = this.stopListening.bind(this); + this.onMessage = this.onMessage.bind(this); } exec(action) { @@ -206,9 +210,11 @@ export default class WidgetMessaging extends MatrixPostMessageApi { * Register widget message event listeners */ startListening() { - this.start(); if (global.mxWidgetMessagingListenerCount === 0) { - window.addEventListener("message", (evt) => this.onMessage(evt), false); + // Start postMessage API listener + this.start(); + // Start widget specific listener + window.addEventListener("message", this.onMessage, false); } global.mxWidgetMessagingListenerCount += 1; } @@ -217,10 +223,12 @@ export default class WidgetMessaging extends MatrixPostMessageApi { * De-register widget message event listeners */ stopListening() { - this.stop(); global.mxWidgetMessagingListenerCount -= 1; if (global.mxWidgetMessagingListenerCount === 0) { - window.removeEventListener("message", () => this.onMessage); + // Stop widget specific listener + window.removeEventListener("message", this.onMessage, false); + // Stop postMessage API listener + this.stop(); } if (global.mxWidgetMessagingListenerCount < 0) { // Make an error so we get a stack trace diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 05ea8cfa0b..582cc01a57 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -171,12 +171,8 @@ export default class AppTile extends React.Component { // Widget postMessage listeners try { - if (this.widgetMessaging) { - this.widgetMessaging.stopListening(); - this.widgetMessaging.removeEndpoint(this.props.id, this.props.url); - } else { - console.warn('WidgetMessaging not initialised. Not stopping.'); - } + this.widgetMessaging.stopListening(); + this.widgetMessaging.removeEndpoint(this.props.id, this.props.url); } catch (e) { console.error('Failed to stop listening for widgetMessaging events', e.message); } From dfecad181a1a086c391e1cedd67e53c50b9c2b54 Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Thu, 18 Jan 2018 17:52:50 +0000 Subject: [PATCH 0144/1160] Swap RoomList to react-beautiful-dnd --- src/components/views/rooms/RoomList.js | 97 ++++++++++++++++++++++++++ src/components/views/rooms/RoomTile.js | 43 ++++-------- 2 files changed, 109 insertions(+), 31 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index d1ef6c2f2c..898dfbef8c 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -18,6 +18,7 @@ limitations under the License. 'use strict'; const React = require("react"); const ReactDOM = require("react-dom"); +import { DragDropContext } from 'react-beautiful-dnd'; import PropTypes from 'prop-types'; import { _t } from '../../../languageHandler'; const GeminiScrollbar = require('react-gemini-scrollbar'); @@ -32,6 +33,8 @@ const Receipt = require('../../../utils/Receipt'); import TagOrderStore from '../../../stores/TagOrderStore'; import GroupStoreCache from '../../../stores/GroupStoreCache'; +import Modal from '../../../Modal'; + const HIDE_CONFERENCE_CHANS = true; function phraseForSection(section) { @@ -275,6 +278,98 @@ module.exports = React.createClass({ this.forceUpdate(); }, + onRoomTileEndDrag: function(result) { + if (!result.destination) return; + + let newTag = result.destination.droppableId.split('_')[1]; + let prevTag = result.source.droppableId.split('_')[1]; + if (newTag === 'undefined') newTag = undefined; + if (prevTag === 'undefined') prevTag = undefined; + + const roomId = result.draggableId.split('_')[1]; + const room = MatrixClientPeg.get().getRoom(roomId); + + const newIndex = result.destination.index; + + // Evil hack to get DMs behaving + if ((prevTag === undefined && newTag === 'im.vector.fake.direct') || + (prevTag === 'im.vector.fake.direct' && newTag === undefined) + ) { + Rooms.guessAndSetDMRoom( + room, newTag === 'im.vector.fake.direct', + ).catch((err) => { + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + console.error("Failed to set direct chat tag " + err); + Modal.createTrackedDialog('Failed to set direct chat tag', '', ErrorDialog, { + title: _t('Failed to set direct chat tag'), + description: ((err && err.message) ? err.message : _t('Operation failed')), + }); + }); + return; + } + + const hasChangedSubLists = result.source.droppableId !== result.destination.droppableId; + + const newOrder = {}; + + // Is the tag ordered manually? + if (!newTag.match(/^(m\.lowpriority|im\.vector\.fake\.(invite|recent|direct|archived))$/)) { + const newList = Object.assign({}, this.state.lists[newTag]); + + // If the room was moved "down" (increasing index) in the same list we + // need to use the orders of the tiles with indices shifted by +1 + const offset = ( + newTag === prevTag && result.source.index < result.destination.index + ) ? 1 : 0; + + const prevOrder = newIndex === 0 ? + 0 : newList[offset + newIndex - 1].tags[newTag].order; + const nextOrder = newIndex === newList.length ? + 1 : newList[offset + newIndex].tags[newTag].order; + + newOrder['order'] = (prevOrder + nextOrder) / 2.0; + } + + // More evilness: We will still be dealing with moving to favourites/low prio, + // but we avoid ever doing a request with 'im.vector.fake.direct`. + // + // if we moved lists, remove the old tag + if (prevTag && prevTag !== 'im.vector.fake.direct' && + hasChangedSubLists + ) { + // Optimistic update of what will happen to the room tags + delete room.tags[prevTag]; + + MatrixClientPeg.get().deleteRoomTag(roomId, prevTag).catch(function(err) { + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + console.error("Failed to remove tag " + prevTag + " from room: " + err); + Modal.createTrackedDialog('Failed to remove tag from room', '', ErrorDialog, { + title: _t('Failed to remove tag %(tagName)s from room', {tagName: prevTag}), + description: ((err && err.message) ? err.message : _t('Operation failed')), + }); + }); + } + + // if we moved lists or the ordering changed, add the new tag + if (newTag && newTag !== 'im.vector.fake.direct' && + (hasChangedSubLists || newOrder) + ) { + // Optimistic update of what will happen to the room tags + room.tags[newTag] = newOrder; + + MatrixClientPeg.get().setRoomTag(roomId, newTag, newOrder).catch(function(err) { + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + console.error("Failed to add tag " + newTag + " to room: " + err); + Modal.createTrackedDialog('Failed to add tag to room', '', ErrorDialog, { + title: _t('Failed to add tag %(tagName)s to room', {tagName: newTag}), + description: ((err && err.message) ? err.message : _t('Operation failed')), + }); + }); + } + + this.refreshRoomList(); + }, + _delayedRefreshRoomList: new rate_limited_func(function() { this.refreshRoomList(); }, 500), @@ -649,6 +744,7 @@ module.exports = React.createClass({ const self = this; return ( +
    @@ -757,6 +853,7 @@ module.exports = React.createClass({ onShowMoreRooms={self.onShowMoreRooms} />
    +
    ); }, }); diff --git a/src/components/views/rooms/RoomTile.js b/src/components/views/rooms/RoomTile.js index 30cc64ef7a..43bc69dea2 100644 --- a/src/components/views/rooms/RoomTile.js +++ b/src/components/views/rooms/RoomTile.js @@ -35,10 +35,7 @@ module.exports = React.createClass({ displayName: 'RoomTile', propTypes: { - connectDragSource: PropTypes.func, - connectDropTarget: PropTypes.func, onClick: PropTypes.func, - isDragging: PropTypes.bool, room: PropTypes.object.isRequired, collapsed: PropTypes.bool.isRequired, @@ -256,35 +253,19 @@ module.exports = React.createClass({ directMessageIndicator = dm; } - // These props are injected by React DnD, - // as defined by your `collect` function above: - const isDragging = this.props.isDragging; - const connectDragSource = this.props.connectDragSource; - const connectDropTarget = this.props.connectDropTarget; - - - let ret = ( -
    { /* Only native elements can be wrapped in a DnD object. */ } - -
    -
    - - { directMessageIndicator } -
    + return +
    +
    + + { directMessageIndicator }
    -
    - { label } - { badge } -
    - { /* { incomingCallBox } */ } - { tooltip } -
    - ); - - if (connectDropTarget) ret = connectDropTarget(ret); - if (connectDragSource) ret = connectDragSource(ret); - - return ret; +
    + { label } + { badge } +
    + { /* { incomingCallBox } */ } + { tooltip } +
    ; }, }); From 59f4661bfdd50360b6688e67eec4f19d244e7079 Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Thu, 18 Jan 2018 18:01:31 +0000 Subject: [PATCH 0145/1160] Add comment --- src/components/views/rooms/RoomList.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 898dfbef8c..6a7c86ab31 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -367,6 +367,9 @@ module.exports = React.createClass({ }); } + // Refresh to display the optimistic updates - this needs to be done in the + // same tick as the drag finishing otherwise the room will pop back to its + // previous position - hence no delayed refresh this.refreshRoomList(); }, From 6f0d7999129f1413f5f11d424811b85d0137cd88 Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Thu, 18 Jan 2018 18:15:34 +0000 Subject: [PATCH 0146/1160] Fix indentation --- src/components/views/rooms/RoomList.js | 202 ++++++++++++------------- 1 file changed, 101 insertions(+), 101 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 6a7c86ab31..9c66731b06 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -748,114 +748,114 @@ module.exports = React.createClass({ const self = this; return ( - -
    - + +
    + - + - + - + - + - { Object.keys(self.state.lists).map((tagName) => { - if (!tagName.match(/^(m\.(favourite|lowpriority)|im\.vector\.fake\.(invite|recent|direct|archived))$/)) { - return ; - } - }) } + { Object.keys(self.state.lists).map((tagName) => { + if (!tagName.match(/^(m\.(favourite|lowpriority)|im\.vector\.fake\.(invite|recent|direct|archived))$/)) { + return ; + } + }) } - + - -
    -
    + +
    +
    ); }, From 6c15bd859987b1d7698f55777fa90d0574e9ac04 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Fri, 19 Jan 2018 10:39:38 +0000 Subject: [PATCH 0147/1160] fix NPE when getGroupProfiles returns null --- src/components/views/elements/Flair.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/views/elements/Flair.js b/src/components/views/elements/Flair.js index a487395a87..009817a340 100644 --- a/src/components/views/elements/Flair.js +++ b/src/components/views/elements/Flair.js @@ -107,7 +107,11 @@ export default class Flair extends React.Component { } const profiles = await this._getGroupProfiles(groups); if (!this.unmounted) { - this.setState({profiles: profiles.filter((profile) => {return profile.avatarUrl;})}); + this.setState({ + profiles: profiles.filter((profile) => { + return profile ? profile.avatarUrl : false; + }) + }); } } From fba5d339237bdd9e0014befe83b32dbe25c9e98f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D1=80=D0=BA=D0=BE=20=D0=9C=2E=20=D0=9A=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D0=B8=D1=9B?= Date: Thu, 18 Jan 2018 21:15:59 +0000 Subject: [PATCH 0148/1160] Translated using Weblate (Serbian) Currently translated at 12.0% (118 of 981 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sr/ --- src/i18n/strings/sr.json | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index b43afe6116..8e3768dd4b 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -87,5 +87,34 @@ "Missing room_id in request": "Недостаје room_id у захтеву", "Must be viewing a room": "Морате гледати собу", "Room %(roomId)s not visible": "Соба %(roomId)s није видљива", - "Missing user_id in request": "Недостаје user_id у захтеву" + "Missing user_id in request": "Недостаје user_id у захтеву", + "Call Failed": "Позивање неуспешно", + "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "Постоје непознати уређаји у овој соби: уколико наставите без проверавања, можда ће неко прислушкивати ваш позив.", + "Review Devices": "Испрегледај уређаје", + "Call Anyway": "Ипак позови", + "Answer Anyway": "Ипак одговори", + "Call": "Позови", + "Answer": "Одговори", + "Call Timeout": "Прекорачено време позивања", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(day)s %(monthName)s %(fullYear)s", + "Failed to lookup current room": "Неуспех при потраживању тренутне собе", + "Usage": "Коришћење", + "/ddg is not a command": "/ddg није наредба", + "To use it, just wait for autocomplete results to load and tab through them.": "Да бисте је користили, само сачекајте да се исходи самодовршавања учитају и табом прођите кроз њих.", + "Unrecognised room alias:": "Непознати алијас собе:", + "Ignored user": "Занемарени корисник", + "You are now ignoring %(userId)s": "Сада занемарујете корисника %(userId)s", + "Unignored user": "Незанемарени корисник", + "You are no longer ignoring %(userId)s": "Више не занемарујете корисника %(userId)s", + "Unknown (user, device) pair:": "Непознати пар (корисника, уређаја):", + "Device already verified!": "Уређај је већ проверен!", + "WARNING: Device already verified, but keys do NOT MATCH!": "УПОЗОРЕЊЕ: Уређај је већ проверен али се кључеви НЕ ПОДУДАРАЈУ!", + "Verified key": "Проверени кључ", + "Unrecognised command:": "Непрепозната наредба:", + "Reason": "Разлог", + "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s је прихватио позивницу за %(displayName)s.", + "%(targetName)s accepted an invitation.": "%(targetName)s је прихватио позивницу.", + "%(senderName)s requested a VoIP conference.": "%(senderName)s је затражио VoIP конференцију.", + "%(senderName)s invited %(targetName)s.": "%(senderName)s је позвао %(targetName)s.", + "%(senderName)s banned %(targetName)s.": "%(senderName)s је бановао %(targetName)s." } From 00dc077271ef48d9275a690af1f41607d9a9bc7f Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Fri, 19 Jan 2018 13:34:56 +0000 Subject: [PATCH 0149/1160] Remove react-dnd, revert fa14bc9 as no longer needed --- package.json | 2 -- src/components/structures/LoggedInView.js | 4 +--- src/components/structures/MatrixChat.js | 4 ++-- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index dbc27b5a08..f81e72e556 100644 --- a/package.json +++ b/package.json @@ -78,8 +78,6 @@ "react": "^15.4.0", "react-addons-css-transition-group": "15.3.2", "react-beautiful-dnd": "^4.0.0", - "react-dnd": "^2.1.4", - "react-dnd-html5-backend": "^2.1.2", "react-dom": "^15.4.0", "react-gemini-scrollbar": "matrix-org/react-gemini-scrollbar#5e97aef", "sanitize-html": "^1.14.1", diff --git a/src/components/structures/LoggedInView.js b/src/components/structures/LoggedInView.js index bebc109806..e97d9dd0a1 100644 --- a/src/components/structures/LoggedInView.js +++ b/src/components/structures/LoggedInView.js @@ -19,8 +19,6 @@ limitations under the License. import * as Matrix from 'matrix-js-sdk'; import React from 'react'; import PropTypes from 'prop-types'; -import { DragDropContext } from 'react-dnd'; -import HTML5Backend from 'react-dnd-html5-backend'; import { KeyCode, isOnlyCtrlOrCmdKeyEvent } from '../../Keyboard'; import Notifier from '../../Notifier'; @@ -347,4 +345,4 @@ const LoggedInView = React.createClass({ }, }); -export default DragDropContext(HTML5Backend)(LoggedInView); +export default LoggedInView; diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 733007677b..a5181b55a7 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -1066,10 +1066,10 @@ export default React.createClass({ // this if we are not scrolled up in the view. To find out, delegate to // the timeline panel. If the timeline panel doesn't exist, then we assume // it is safe to reset the timeline. - if (!self._loggedInView) { + if (!self._loggedInView || !self._loggedInView.child) { return true; } - return self._loggedInView.getDecoratedComponentInstance().canResetTimelineInRoom(roomId); + return self._loggedInView.child.canResetTimelineInRoom(roomId); }); cli.on('sync', function(state, prevState) { From 75a19227314ced9de11d775a5f6c9b311f443996 Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Fri, 19 Jan 2018 14:07:13 +0000 Subject: [PATCH 0150/1160] Fix linting --- src/components/views/elements/Flair.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/elements/Flair.js b/src/components/views/elements/Flair.js index 009817a340..76566e8c4d 100644 --- a/src/components/views/elements/Flair.js +++ b/src/components/views/elements/Flair.js @@ -110,7 +110,7 @@ export default class Flair extends React.Component { this.setState({ profiles: profiles.filter((profile) => { return profile ? profile.avatarUrl : false; - }) + }), }); } } From 54f6d305d759c6911ba69e549a2cb55587951f64 Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Fri, 19 Jan 2018 14:11:05 +0000 Subject: [PATCH 0151/1160] Null-guard for newTag --- 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 9c66731b06..85b4b52380 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -313,7 +313,7 @@ module.exports = React.createClass({ const newOrder = {}; // Is the tag ordered manually? - if (!newTag.match(/^(m\.lowpriority|im\.vector\.fake\.(invite|recent|direct|archived))$/)) { + if (newTag && !newTag.match(/^(m\.lowpriority|im\.vector\.fake\.(invite|recent|direct|archived))$/)) { const newList = Object.assign({}, this.state.lists[newTag]); // If the room was moved "down" (increasing index) in the same list we From 6106b3ce44122fc858f44eeec5bbbfc141a59286 Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Fri, 19 Jan 2018 14:12:21 +0000 Subject: [PATCH 0152/1160] newOrder defaults `null`, allows check for `newOrder` on line 357 --- src/components/views/rooms/RoomList.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 85b4b52380..ca1fccd1f5 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -310,7 +310,7 @@ module.exports = React.createClass({ const hasChangedSubLists = result.source.droppableId !== result.destination.droppableId; - const newOrder = {}; + let newOrder = null; // Is the tag ordered manually? if (newTag && !newTag.match(/^(m\.lowpriority|im\.vector\.fake\.(invite|recent|direct|archived))$/)) { @@ -327,7 +327,9 @@ module.exports = React.createClass({ const nextOrder = newIndex === newList.length ? 1 : newList[offset + newIndex].tags[newTag].order; - newOrder['order'] = (prevOrder + nextOrder) / 2.0; + newOrder = { + order: (prevOrder + nextOrder) / 2.0, + }; } // More evilness: We will still be dealing with moving to favourites/low prio, From 86e833424809988d5ce9d145dbd86fe49a26087e Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 19 Jan 2018 18:04:42 +0000 Subject: [PATCH 0153/1160] Try upgrading eslint-plugin-react Because 7.4.0 does not seem to be picking up the same set of problems as 7.5.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f81e72e556..edf8ad03d4 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "eslint-config-google": "^0.7.1", "eslint-plugin-babel": "^4.0.1", "eslint-plugin-flowtype": "^2.30.0", - "eslint-plugin-react": "^7.4.0", + "eslint-plugin-react": "^7.5.1", "estree-walker": "^0.5.0", "expect": "^1.16.0", "flow-parser": "^0.57.3", From 5206c9d18b6d096ca4dc5dbfbd2363ac73b03a60 Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Fri, 19 Jan 2018 22:27:48 +0000 Subject: [PATCH 0154/1160] Show a warning if the user attempts to leave a room that is invite only --- src/components/structures/MatrixChat.js | 22 +++++++++++++++++++++- src/i18n/strings/en_EN.json | 3 ++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index a5181b55a7..d6d0b00c84 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -847,16 +847,36 @@ export default React.createClass({ }).close; }, + _leaveRoomWarnings: function(roomId) { + const roomToLeave = MatrixClientPeg.get().getRoom(roomId); + // Show a warning if there are additional complications. + const joinRules = roomToLeave.currentState.getStateEvents('m.room.join_rules', ''); + const warnings = []; + if (joinRules) { + const rule = joinRules.getContent().join_rule; + if (rule !== "public") { + warnings.push(( + + { _t("This room is not public. You will not be able to rejoin without an invite.") } + + )); + } + } + return warnings; + }, + _leaveRoom: function(roomId) { const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - const roomToLeave = MatrixClientPeg.get().getRoom(roomId); + const warnings = this._leaveRoomWarnings(roomId); + Modal.createTrackedDialog('Leave room', '', QuestionDialog, { title: _t("Leave room"), description: ( { _t("Are you sure you want to leave the room '%(roomName)s'?", {roomName: roomToLeave.name}) } + { warnings } ), onFinished: (shouldLeave) => { diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 73e3f3a014..7efc5ff38e 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -979,5 +979,6 @@ "Which officially provided instance you are using, if any": "Which officially provided instance you are using, if any", "Whether or not you're using the Richtext mode of the Rich Text Editor": "Whether or not you're using the Richtext mode of the Rich Text Editor", "Your homeserver's URL": "Your homeserver's URL", - "Your identity server's URL": "Your identity server's URL" + "Your identity server's URL": "Your identity server's URL", + "This room is not public. You will not be able to rejoin without an invite.": "This room is not public. You will not be able to rejoin without an invite." } From 67a4c6c487ee63830631d88dc5da5b0ce3fe9ca9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D1=80=D0=BA=D0=BE=20=D0=9C=2E=20=D0=9A=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D0=B8=D1=9B?= Date: Sat, 20 Jan 2018 11:44:16 +0000 Subject: [PATCH 0155/1160] Translated using Weblate (Serbian) Currently translated at 18.2% (179 of 981 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sr/ --- src/i18n/strings/sr.json | 63 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index 8e3768dd4b..e355c56b9d 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -116,5 +116,66 @@ "%(targetName)s accepted an invitation.": "%(targetName)s је прихватио позивницу.", "%(senderName)s requested a VoIP conference.": "%(senderName)s је затражио VoIP конференцију.", "%(senderName)s invited %(targetName)s.": "%(senderName)s је позвао %(targetName)s.", - "%(senderName)s banned %(targetName)s.": "%(senderName)s је бановао %(targetName)s." + "%(senderName)s banned %(targetName)s.": "%(senderName)s је бановао %(targetName)s.", + "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“. Ово можда значи да се ваши разговори прате!", + "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Кључ за потписивање који сте доставили се подудара са кључем за потписивање од корисника %(userId)s и уређаја %(deviceId)s. Уређај је означен као проверен.", + "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "Корисник %(senderName)s је променио приказно име из %(oldDisplayName)s у %(displayName)s.", + "%(senderName)s set their display name to %(displayName)s.": "Корисник %(senderName)s је себи поставио приказно име %(displayName)s.", + "%(senderName)s removed their display name (%(oldDisplayName)s).": "Корисник %(senderName)s је себи уклонио приказно име %(oldDisplayName)s.", + "%(senderName)s removed their profile picture.": "Корисник %(senderName)s је себи уклонио профилну слику.", + "%(senderName)s changed their profile picture.": "Корисник %(senderName)s је себи променио профилну слику.", + "%(senderName)s set a profile picture.": "Корисник %(senderName)s је себи поставио профилну слику.", + "VoIP conference started.": "VoIP конференција је започета.", + "%(targetName)s joined the room.": "Корисник %(targetName)s је ушао у собу.", + "VoIP conference finished.": "VoIP конференција је завршена.", + "%(targetName)s rejected the invitation.": "Корисник %(targetName)s је одбацио позивницу.", + "%(targetName)s left the room.": "Корисник %(targetName)s је напустио собу.", + "%(senderName)s unbanned %(targetName)s.": "Корисник %(senderName)s је скинуо забрану приступа са %(targetName)s.", + "%(senderName)s kicked %(targetName)s.": "Корисник %(senderName)s је избацио %(targetName)s.", + "%(senderName)s withdrew %(targetName)s's invitation.": "Пошиљалац %(senderName)s је повукао позивницу за %(targetName)s.", + "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "Корисник %(senderDisplayName)s је променио тему у „%(topic)s“.", + "%(senderDisplayName)s removed the room name.": "Корисник %(senderDisplayName)s је уклонио назив собе.", + "%(senderDisplayName)s changed the room name to %(roomName)s.": "Корисник %(senderDisplayName)s је променио назив собе у %(roomName)s.", + "%(senderDisplayName)s sent an image.": "Корисник %(senderDisplayName)s је послао слику.", + "Someone": "Неко", + "(not supported by this browser)": "(није подржано од стране овог прегледача)", + "%(senderName)s answered the call.": "Корисник %(senderName)s се јавио.", + "(could not connect media)": "(не могу да повежем медије)", + "(no answer)": "(нема одговора)", + "(unknown failure: %(reason)s)": "(непозната грешка: %(reason)s)", + "%(senderName)s ended the call.": "Корисник %(senderName)s је окончао позив.", + "%(senderName)s placed a %(callType)s call.": "Корисник %(senderName)s је направио %(callType)s позив.", + "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "Корисник %(senderName)s је послао позивницу за приступ соби ка %(targetDisplayName)s.", + "%(senderName)s made future room history visible to all room members, from the point they are invited.": "Корисник %(senderName)s је учинио будући историјат собе видљивим свим члановима собе, од тренутка позивања у собу.", + "%(senderName)s made future room history visible to all room members, from the point they joined.": "Корисник %(senderName)s је учинио будући историјат собе видљивим свим члановима собе, од тренутка приступања соби.", + "%(senderName)s made future room history visible to all room members.": "Корисник %(senderName)s је учинио будући историјат собе видљивим свим члановима собе.", + "%(senderName)s made future room history visible to anyone.": "Корисник %(senderName)s је учинио будући историјат собе видљивим свима.", + "%(senderName)s made future room history visible to unknown (%(visibility)s).": "Корисник %(senderName)s је учинио будући историјат собе непознатим (%(visibility)s).", + "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "Корисник %(senderName)s је укључио шифровање с краја на крај (алгоритам %(algorithm)s).", + "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s са %(fromPowerLevel)s на %(toPowerLevel)s", + "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "Корисник %(senderName)s је променио ниво моћи од %(powerLevelDiffText)s.", + "%(senderName)s changed the pinned messages for the room.": "Корисник %(senderName)s је променио закачене поруке у соби.", + "%(widgetName)s widget modified by %(senderName)s": "Корисник %(senderName)s је променио виџет %(widgetName)s", + "%(widgetName)s widget added by %(senderName)s": "Корисник %(senderName)s је додао виџет %(widgetName)s", + "%(widgetName)s widget removed by %(senderName)s": "Корисник %(senderName)s је уклонио виџет %(widgetName)s", + "%(displayName)s is typing": "%(displayName)s куца", + "%(names)s and %(count)s others are typing|other": "%(names)s и %(count)s корисник(а) куцају", + "%(names)s and %(count)s others are typing|one": "%(names)s и још један куцају", + "%(names)s and %(lastPerson)s are typing": "%(names)s и %(lastPerson)s куцају", + "Failure to create room": "Неуспех при прављењу собе", + "Server may be unavailable, overloaded, or you hit a bug.": "Сервер је можда недоступан, преоптерећен или сте нашли грешку.", + "Send anyway": "Ипак пошаљи", + "Send": "Пошаљи", + "Unnamed Room": "Неименована соба", + "Your browser does not support the required cryptography extensions": "Ваш прегледач не подржава потребна криптографска проширења", + "Not a valid Riot keyfile": "Није исправана Riot кључ-датотека", + "Authentication check failed: incorrect password?": "Провера идентитета није успела: нетачна лозинка?", + "Failed to join room": "Нисам успео да уђем у собу", + "Message Replies": "Одговори", + "Message Pinning": "Закачене поруке", + "Presence Management": "Управљање присутношћу", + "Tag Panel": "Означи површ", + "Disable Emoji suggestions while typing": "Онемогући предлагање емоџија приликом куцања", + "Use compact timeline layout": "Користи збијени распоред временске линије", + "Hide removed messages": "Сакриј уклоњене поруке" } From 2705397bf695988feebf6dedb720be49a1b67be2 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 20 Jan 2018 13:16:33 +0000 Subject: [PATCH 0156/1160] Add local GID==='' check, because Synapse says Group rather than Community Reset createError when doing check because it is now stale Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/dialogs/CreateGroupDialog.js | 6 +++++- src/i18n/strings/en_EN.json | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/views/dialogs/CreateGroupDialog.js b/src/components/views/dialogs/CreateGroupDialog.js index d811dde09e..86a2b2498c 100644 --- a/src/components/views/dialogs/CreateGroupDialog.js +++ b/src/components/views/dialogs/CreateGroupDialog.js @@ -55,11 +55,15 @@ export default React.createClass({ _checkGroupId: function(e) { let error = null; - if (!/^[a-z0-9=_\-\.\/]*$/.test(this.state.groupId)) { + if (!this.state.groupId) { + error = _t("Community IDs cannot not be empty."); + } else if (!/^[a-z0-9=_\-\.\/]*$/.test(this.state.groupId)) { error = _t("Community IDs may only contain characters a-z, 0-9, or '=_-./'"); } this.setState({ groupIdError: error, + // Reset createError to get rid of now stale error message + createError: null, }); return error; }, diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 73e3f3a014..f8526fe6f3 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -653,6 +653,7 @@ "Confirm Removal": "Confirm Removal", "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.", "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "Community IDs may only contain characters a-z, 0-9, or '=_-./'", + "Community IDs cannot not be empty.": "Community IDs cannot not be empty.", "Something went wrong whilst creating your community": "Something went wrong whilst creating your community", "Create Community": "Create Community", "Community Name": "Community Name", From 38c58f3b23a731e34d4023630a24015b2fb9c476 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Mon, 15 Jan 2018 19:01:37 +0000 Subject: [PATCH 0157/1160] Translated using Weblate (Hungarian) Currently translated at 100.0% (982 of 982 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index a341d47795..663fbe9f92 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -980,5 +980,6 @@ "Whether or not you're using the Richtext mode of the Rich Text Editor": "Használod-e a Richtext módot a szerkesztőben vagy nem", "Your homeserver's URL": "Az egyedi szerver URL-t", "Your identity server's URL": "Az azonosítási szerver URL-t", - "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(fullYear)s. %(monthName)s %(day)s, %(weekDayName)s" + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(fullYear)s. %(monthName)s %(day)s, %(weekDayName)s", + "This room is not public. You will not be able to rejoin without an invite.": "Ez a szoba nem nyilvános. Kilépés után csak újabb meghívóval tudsz újra belépni a szobába." } From 1356e6dfd2a674d9203e3885c75a81da3911b7b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Mon, 15 Jan 2018 16:08:31 +0000 Subject: [PATCH 0158/1160] Translated using Weblate (French) Currently translated at 100.0% (982 of 982 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 109697d750..846cf7a32f 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -980,5 +980,6 @@ "Whether or not you're using the Richtext mode of the Rich Text Editor": "Si vous utilisez le mode de texte enrichi de l'éditeur de texte enrichi", "Your homeserver's URL": "L'URL de votre serveur d'accueil", "Your identity server's URL": "L'URL de votre serveur d'identité", - "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s %(day)s %(monthName)s %(fullYear)s" + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s %(day)s %(monthName)s %(fullYear)s", + "This room is not public. You will not be able to rejoin without an invite.": "Ce salon n'est pas public. Vous ne pourrez pas y revenir sans invitation." } From a0ba25806c347facc5794a9fbee0371f86e8e23d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Sat, 20 Jan 2018 15:12:54 +0000 Subject: [PATCH 0159/1160] Translated using Weblate (Slovak) Currently translated at 100.0% (982 of 982 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sk/ --- src/i18n/strings/sk.json | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index 0126299f9f..aca0fabbe4 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -953,5 +953,33 @@ "This room is not showing flair for any communities": "V tejto miestnosti nie je zobrazená príslušnosť k žiadnym komunitám", "Flair will appear if enabled in room settings": "Príslušnosť ku komunite sa zobrazí ak je to povolené v nastaveniach miestnosti", "Flair will not appear": "Príslušnosť ku komunite nebude zobrazená", - "Display your community flair in rooms configured to show it.": "Zobrazovať vašu príslušnosť ku komunite v miestnostiach, ktoré sú nastavené na zobrazovanie tejto príslušnosti." + "Display your community flair in rooms configured to show it.": "Zobrazovať vašu príslušnosť ku komunite v miestnostiach, ktoré sú nastavené na zobrazovanie tejto príslušnosti.", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(day)s %(monthName)s %(fullYear)s", + "Message Replies": "Odpovede na správy", + "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Túto zmenu nebudete môcť vrátiť späť pretože znižujete vašu vlastnú úroveň moci. Ak ste jediný poverený používateľ v miestnosti, nebudete môcť znovu získať úroveň, akú máte teraz.", + "Send an encrypted reply…": "Odoslať šifrovanú odpoveď…", + "Send a reply (unencrypted)…": "Odoslať odpoveď (nešifrovanú)…", + "Send an encrypted message…": "Odoslať šifrovanú správu…", + "Send a message (unencrypted)…": "Odoslať správu (nešifrovanú)…", + "Replying": "Odpoveď", + "Minimize apps": "Minimalizovať aplikácie", + "Quote": "Citácia", + "Show devices, mark devices known and send or cancel all.": "Zobraziť zariadenia, Považovať zariadenia za známe a odoslať alebo zrušiť všetko.", + "%(count)s of your messages have not been sent.|one": "Vaša správa nebola odoslaná.", + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "Znovu poslať všetky alebo zrušiť všetky teraz. Vybratím môžete tiež znovu odoslať alebo zrušiť jednotlivé správy.", + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Znovu odoslať správu alebo zrušiť správu teraz.", + "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Vaše súkromie je pre nás dôležité, preto nezhromažďujeme žiadne osobné údaje alebo údaje, na základe ktorých je možné vás identifikovať.", + "Learn more about how we use analytics.": "Zistite viac o tom, ako spracúvame analytické údaje.", + "The information being sent to us to help make Riot.im better includes:": "S cieľom vylepšovať aplikáciu Riot.im zbierame nasledujúce údaje:", + "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "Zaznamenávame tiež každú stránku aplikácie Riot.im, ktorú otvoríte (momentálne ), reťazec user agent () a rozlíšenie obrazovky vašeho zariadenia ().", + "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Ak sa na stránke vyskytujú identifikujúce údaje, akými sú napríklad názov miestnosti, ID používateľa, miestnosti alebo skupiny, tieto sú pred odoslaním na server odstránené.", + "The platform you're on": "Vami používaná platforma", + "The version of Riot.im": "Verzia Riot.im", + "Whether or not you're logged in (we don't record your user name)": "Stav vašeho prihlásenia - prihlásený / neprihlásený (nezaznamenávame vaše používateľské meno)", + "Your language of choice": "Váš uprednostňovaný jazyk", + "Which officially provided instance you are using, if any": "Cez ktorú oficiálne podporovanú inštanciu Riot.im ste pripojení (ak nehostujete Riot sami)", + "Whether or not you're using the Richtext mode of the Rich Text Editor": "Či pri písaní správ používate rozbalenú lištu formátovania textu", + "Your homeserver's URL": "URL adresa vami používaného domovského servera", + "Your identity server's URL": "URL adresa vami používaného servera totožností", + "This room is not public. You will not be able to rejoin without an invite.": "Toto nie je verejne dostupná miestnosť. Bez pozvánky nebudete do nej môcť vstúpiť znovu." } From 2111271bdad6ae482c150548c2cd71144f63361a Mon Sep 17 00:00:00 2001 From: Andrey Date: Mon, 15 Jan 2018 14:02:58 +0000 Subject: [PATCH 0160/1160] Translated using Weblate (Russian) Currently translated at 100.0% (982 of 982 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 8126f84799..4fc55e5e23 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -980,5 +980,6 @@ "Your identity server's URL": "URL-адрес вашего идентификационного сервера", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s", "Which officially provided instance you are using, if any": "Какую официально выпущенную версию вы используете", - "Whether or not you're using the Richtext mode of the Rich Text Editor": "Независимо от того, используете ли вы режим Richtext в редакторе Rich Text Editor" + "Whether or not you're using the Richtext mode of the Rich Text Editor": "Независимо от того, используете ли вы режим Richtext в редакторе Rich Text Editor", + "This room is not public. You will not be able to rejoin without an invite.": "Эта комната не является публичной. Вы не сможете войти без приглашения." } From fd2ef3e54db84385e3a2a751b0bb894afcd87a05 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Tue, 16 Jan 2018 02:33:06 +0000 Subject: [PATCH 0161/1160] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (982 of 982 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hant/ --- src/i18n/strings/zh_Hant.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index f29debcf22..c6b37bf2bc 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -979,5 +979,6 @@ "Whether or not you're using the Richtext mode of the Rich Text Editor": "您是否正在使用豐富文字編輯器的豐富文字模式", "Your homeserver's URL": "您的家伺服器 URL", "Your identity server's URL": "您的驗證伺服器 URL", - "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s" + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s", + "This room is not public. You will not be able to rejoin without an invite.": "這個聊天室並未公開。您在沒有邀請的情況下將無法重新加入。" } From fb9930ad2c3b7d0c2c543f543751120a7678af26 Mon Sep 17 00:00:00 2001 From: Osoitz Date: Tue, 16 Jan 2018 11:21:32 +0000 Subject: [PATCH 0162/1160] Translated using Weblate (Basque) Currently translated at 100.0% (982 of 982 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eu/ --- src/i18n/strings/eu.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index e8fe9b2f20..2dfb197f46 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -980,5 +980,6 @@ "Whether or not you're using the Richtext mode of the Rich Text Editor": "Testu editorean testu aberatsa modua erabiltzen duzun", "Your homeserver's URL": "Zure hasiera zerbitzariaren URL-a", "Your identity server's URL": "Zure identitate zerbitzariaren URL-a", - "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(fullYear)s(e)ko %(monthName)sk %(day)sa" + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(fullYear)s(e)ko %(monthName)sk %(day)sa", + "This room is not public. You will not be able to rejoin without an invite.": "Gela hau ez da publikoa. Ezin izango zara berriro elkartu gonbidapenik gabe." } From 02824cfacf06f7a4eb22607476a6c3090022a120 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 22 Jan 2018 12:16:11 +0100 Subject: [PATCH 0163/1160] fix i18n for show devices prompt --- src/i18n/strings/en_EN.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 7efc5ff38e..6543f96508 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -781,7 +781,7 @@ "You have no visible notifications": "You have no visible notifications", "Scroll to bottom of page": "Scroll to bottom of page", "Message not sent due to unknown devices being present": "Message not sent due to unknown devices being present", - "Show devices, mark devices known and send or cancel all.": "Show devices, mark devices known and send or cancel all.", + "Show devices, send anyway or cancel.": "Show devices, send anyway or cancel.", "%(count)s of your messages have not been sent.|other": "Some of your messages have not been sent.", "%(count)s of your messages have not been sent.|one": "Your message was not sent.", "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "Resend all or cancel all now. You can also select individual messages to resend or cancel.", From 755ead7c1d26b823baf0a68dd2b327089499b47f Mon Sep 17 00:00:00 2001 From: Szimszon Date: Sat, 20 Jan 2018 13:41:07 +0000 Subject: [PATCH 0164/1160] Translated using Weblate (Hungarian) Currently translated at 100.0% (982 of 982 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 663fbe9f92..e630a3949c 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -903,7 +903,7 @@ "Room Notification": "Szoba értesítések", "Show these rooms to non-members on the community page and room list?": "Mutassuk meg ezeket a szobákat kívülállóknak a közösségi oldalon és a szobák listájában?", "Sign in to get started": "Az induláshoz jelentkezz be", - "Status.im theme": "Állapot.im téma", + "Status.im theme": "Állapot téma", "Please note you are logging into the %(hs)s server, not matrix.org.": "Figyelem, a %(hs)s szerverre jelentkezel be és nem a matrix.org szerverre.", "Username on %(hs)s": "Felhasználónév a %(hs)s szerveren", "Restricted": "Korlátozott", From 2326ee2586d3879cbdbedad891587419008407bf Mon Sep 17 00:00:00 2001 From: "A.G" Date: Sat, 20 Jan 2018 23:00:56 +0000 Subject: [PATCH 0165/1160] Translated using Weblate (Italian) Currently translated at 9.1% (90 of 982 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/it/ --- src/i18n/strings/it.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/it.json b/src/i18n/strings/it.json index 0da7cf704b..369db6f123 100644 --- a/src/i18n/strings/it.json +++ b/src/i18n/strings/it.json @@ -85,5 +85,9 @@ "Unable to capture screen": "Impossibile acquisire lo schermo", "Call": "Chiama", "Answer": "Rispondi", - "Invite to Community": "Invita alla community" + "Invite to Community": "Invita alla community", + "Unpin Message": "Sblocca messaggio", + "Add rooms to this community": "Aggiungi stanze a questa community", + "Warning": "Attenzione", + "Unnamed room": "Stanza senza nome" } From 1d43ccde23f18ac1c38af136516237713b0a28e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D1=80=D0=BA=D0=BE=20=D0=9C=2E=20=D0=9A=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D0=B8=D1=9B?= Date: Sun, 21 Jan 2018 16:59:48 +0000 Subject: [PATCH 0166/1160] Translated using Weblate (Serbian) Currently translated at 28.0% (275 of 982 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sr/ --- src/i18n/strings/sr.json | 98 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index e355c56b9d..ab2a4a529b 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -177,5 +177,101 @@ "Tag Panel": "Означи површ", "Disable Emoji suggestions while typing": "Онемогући предлагање емоџија приликом куцања", "Use compact timeline layout": "Користи збијени распоред временске линије", - "Hide removed messages": "Сакриј уклоњене поруке" + "Hide removed messages": "Сакриј уклоњене поруке", + "Hide join/leave messages (invites/kicks/bans unaffected)": "Сакриј поруке приступања и напуштања (позивнице, избацивања и забране нису захваћене)", + "Hide avatar changes": "Сакриј промене аватара", + "Hide display name changes": "Сакриј промене приказног имена", + "Hide read receipts": "Сакриј потврде прочитаности", + "Show timestamps in 12 hour format (e.g. 2:30pm)": "Прикажи временске жигове у 12-сатном облику (нпр.: 2:30 ПоП)", + "Always show message timestamps": "Увек прикажи временске жигове", + "Autoplay GIFs and videos": "Самостално пуштај GIF-ове и видео записе", + "Enable automatic language detection for syntax highlighting": "Омогући самостално препознавање језика за истицање синтаксе", + "Hide avatars in user and room mentions": "Сакриј аватаре у спомињањима корисника и соба", + "Disable big emoji in chat": "Онемогући велике емоџије у ћаскању", + "Don't send typing notifications": "Не шаљи обавештења о куцању", + "Automatically replace plain text Emoji": "Самостално замени емоџије писане обичним текстом", + "Mirror local video feed": "Копирај довод локалног видеа", + "Disable Peer-to-Peer for 1:1 calls": "Онемогући парњаке за 1 на 1 позиве", + "Opt out of analytics": "Не учествуј у аналитици", + "Never send encrypted messages to unverified devices from this device": "Никада не шаљи шифроване поруке са овог уређаја ка непровереним уређајима", + "Never send encrypted messages to unverified devices in this room from this device": "Никада не шаљи шифроване поруке са овог уређаја ка непровереним уређајима у овој соби", + "Enable inline URL previews by default": "Подразумевано омогући претпрегледе адреса унутар линије", + "Enable URL previews for this room (only affects you)": "Омогући претпрегледе адреса у овој соби (утиче само на вас)", + "Enable URL previews by default for participants in this room": "Подразумевано омогући прегледе адреса за чланове ове собе", + "Room Colour": "Боја собе", + "Active call (%(roomName)s)": "Активни позив (%(roomName)s)", + "unknown caller": "непознати позивалац", + "Incoming voice call from %(name)s": "Долазни гласовни позив од корисника %(name)s", + "Incoming video call from %(name)s": "Долазни видео позив од корисника %(name)s", + "Incoming call from %(name)s": "Долазни позив од корисника %(name)s", + "Decline": "Одбиј", + "Accept": "Прихвати", + "Error": "Грешка", + "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Текстуална порука је послата на %(msisdn)s. Унесите потврдни код из те поруке", + "Incorrect verification code": "Нетачни потврдни код", + "Enter Code": "Унесите код", + "Submit": "Пошаљи", + "Phone": "Телефон", + "Add phone number": "Додај телефонски број", + "Add": "Додај", + "Failed to upload profile picture!": "Нисам успео да отпремим профилну слику!", + "Upload new:": "Отпреми нову:", + "No display name": "Нема приказног имена", + "New passwords don't match": "Нове лозинке се не подударају", + "Passwords can't be empty": "Лозинке не могу бити празне", + "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Промена лозинке ће тренутно ресетовати све кључеве за шифровање с краја на крај, на свим уређајима и тиме учинити шифровани историјат ћаскања нечитљивим осим ако прво не извезете кључеве ваше собе па их поново увезете после. Ово ће бити побољшано у будућности.", + "Continue": "Настави", + "Export E2E room keys": "Извези E2E кључеве собе", + "Do you want to set an email address?": "Да ли желите да поставите мејл адресу?", + "Current password": "Тренутна лозинка", + "Password": "Лозинка", + "New Password": "Нова лозинка", + "Confirm password": "Потврди лозинку", + "Change Password": "Промени лозинку", + "Your home server does not support device management.": "Ваш кућни сервер не подржава управљање уређајима.", + "Unable to load device list": "Нисам могао да учитам списак уређаја", + "Authentication": "Идентификација", + "Delete %(count)s devices|other": "Обриши %(count)s уређај(а)", + "Delete %(count)s devices|one": "Обриши уређај", + "Device ID": "ИБ уређаја", + "Device Name": "Назив уређаја", + "Last seen": "Последњи пут виђен", + "Select devices": "Изабери уређаје", + "Failed to set display name": "Нисам успео да поставим приказно име", + "Disable Notifications": "Онемогући обавештења", + "Enable Notifications": "Омогући обавештења", + "Cannot add any more widgets": "Не могу да додам још виџета", + "The maximum permitted number of widgets have already been added to this room.": "Највећи број дозвољених додатих виџета је прекорачен у овој соби.", + "Add a widget": "Додај виџет", + "Drop File Here": "Превуци датотеку овде", + "Drop file here to upload": "Превуци датотеку овде да би је отпремио", + " (unsupported)": " (неподржано)", + "Join as voice or video.": "Приступи преко гласа или видеа.", + "Ongoing conference call%(supportedText)s.": "Текући конференцијски позив %(supportedText)s.", + "%(senderName)s sent an image": "Корисник %(senderName)s је послао слику", + "%(senderName)s sent a video": "Корисник %(senderName)s је послао видео", + "%(senderName)s uploaded a file": "Корисник %(senderName)s је отпремио датотеку", + "Options": "Опције", + "Undecryptable": "Немогуће дешифровати", + "Encrypted by a verified device": "Шифровано на провереном уређају", + "Encrypted by an unverified device": "Шифровано на непровереном уређају", + "Unencrypted message": "Нешифрована порука", + "Please select the destination room for this message": "Изаберите одредишну собу за ову поруку", + "Blacklisted": "На црном списку", + "Verified": "Проверени", + "Unverified": "Непроверени", + "device id: ": "иб уређаја: ", + "Disinvite": "Откажи позивницу", + "Kick": "Избаци", + "Disinvite this user?": "Отказати позивницу за овог корисника?", + "Kick this user?": "Избацити овог корисника?", + "Failed to kick": "Неуспех при избацивању", + "Unban": "Скини забрану", + "Ban": "Забрани приступ", + "Unban this user?": "Скинути забрану за овог корисника?", + "Ban this user?": "Забранити приступ овом кориснику?", + "Failed to ban user": "Неуспех при забрањивању приступа кориснику", + "Failed to mute user": "Неуспех при пригушивању корисника", + "Failed to toggle moderator status": "Неуспех при промени стања модератора", + "Failed to change power level": "Неуспех при промени нивоа моћи" } From 8496c947c87f53355710ad7d6719beed9d8c142e Mon Sep 17 00:00:00 2001 From: pebles Date: Sat, 20 Jan 2018 16:17:34 +0000 Subject: [PATCH 0167/1160] Translated using Weblate (Spanish) Currently translated at 58.3% (573 of 982 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/es/ --- src/i18n/strings/es.json | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/es.json b/src/i18n/strings/es.json index ff28d339d0..53e0a3cc9f 100644 --- a/src/i18n/strings/es.json +++ b/src/i18n/strings/es.json @@ -429,7 +429,7 @@ "Changes colour scheme of current room": "Cambia el esquema de colores de esta sala", "Delete widget": "Eliminar widget", "Define the power level of a user": "Definir el nivel de poder de los usuarios", - "Edit": "Edita", + "Edit": "Editar", "Enable automatic language detection for syntax highlighting": "Activar la detección automática del lenguaje para resaltar la sintaxis", "Hide Apps": "Ocultar aplicaciones", "Hide join/leave messages (invites/kicks/bans unaffected)": "Ocultar mensajes de entrada/salida (no afecta invitaciones/kicks/bans)", @@ -560,7 +560,7 @@ "Jun": "Jun", "Jul": "Jul", "Aug": "August", - "Add rooms to this community": "Agrega salas a esta comunidad", + "Add rooms to this community": "Agregar salas a esta comunidad", "Call Failed": "La llamada falló", "Review Devices": "Revisar Dispositivos", "Call Anyway": "Llamar de todas formas", @@ -570,5 +570,7 @@ "Sep": "Sep", "Oct": "Oct", "Nov": "Nov", - "Dec": "Dic" + "Dec": "Dic", + "Warning": "Advertencia", + "Unpin Message": "Desmarcar Mensaje" } From 37dcb33b15e9f3848f6badbdb4125c7dbf105c82 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 22 Jan 2018 14:45:04 +0000 Subject: [PATCH 0168/1160] Reset quotingEvent on Room Change because inideal UX Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/stores/RoomViewStore.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/stores/RoomViewStore.js b/src/stores/RoomViewStore.js index cf895d2190..4c010f4e8e 100644 --- a/src/stores/RoomViewStore.js +++ b/src/stores/RoomViewStore.js @@ -132,6 +132,8 @@ class RoomViewStore extends Store { shouldPeek: payload.should_peek === undefined ? true : payload.should_peek, // have we sent a join request for this room and are waiting for a response? joining: payload.joining || false, + // Reset quotingEvent because we don't want cross-room because bad UX + quotingEvent: null, }; if (this._state.forwardingEvent) { From 0441487e97573dde03578efd8b621ab5394ff0a0 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Mon, 22 Jan 2018 17:00:50 +0100 Subject: [PATCH 0169/1160] Manage sticker packs link and add comments --- src/components/views/rooms/Stickerpack.js | 21 ++++++++++++++++++--- src/i18n/strings/en_EN.json | 1 + 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/components/views/rooms/Stickerpack.js b/src/components/views/rooms/Stickerpack.js index 3c4a8f6425..cb2a19eae7 100644 --- a/src/components/views/rooms/Stickerpack.js +++ b/src/components/views/rooms/Stickerpack.js @@ -115,7 +115,7 @@ export default class Stickerpack extends React.Component { padding: '5px', borderTop: '1px solid #999', }}> - Add sticker packs + { _t("Manage sticker packs") }
    ); @@ -126,6 +126,11 @@ export default class Stickerpack extends React.Component { this.setState({stickersContent}); } + /** + * Show the sticker picker overlay + * If no stickerpacks have been added, show a link to the integration manager add sticker packs page. + * @param {Event} e Event that triggered the function + */ onShowStickersClick(e) { const GenericElementContextMenu = sdk.getComponent('context_menus.GenericElementContextMenu'); const buttonRect = e.target.getBoundingClientRect(); @@ -149,23 +154,33 @@ export default class Stickerpack extends React.Component { this.setState({showStickers: true}); } + /** + * Trigger hiding of the sticker picker overlay + * @param {Event} ev Event that triggered the function call + */ onHideStickersClick(ev) { this.stickersMenu.close(); } + /** + * The stickers picker was hidden + */ onFinished() { this.setState({showStickers: false}); this.stickersMenu = null; } + /** + * Launch the integrations manager on the stickers integration page + */ _launchManageIntegrations() { this.onFinished(); const IntegrationsManager = sdk.getComponent("views.settings.IntegrationsManager"); const src = (this.scalarClient !== null && this.scalarClient.hasCredentials()) ? this.scalarClient.getScalarInterfaceUrlForRoom( this.props.room.roomId, - 'add_integ', - // this.widgetId, + 'type_stickerpack', + this.widgetId, ) : null; Modal.createTrackedDialog('Integrations Manager', '', IntegrationsManager, { diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 41f1b75e43..a4152ef94a 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -555,6 +555,7 @@ "NOTE: Apps are not end-to-end encrypted": "NOTE: Apps are not end-to-end encrypted", "Do you want to load widget from URL:": "Do you want to load widget from URL:", "Allow": "Allow", + "Manage sticker packs": "Manage sticker packs", "Delete Widget": "Delete Widget", "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?", "Delete widget": "Delete widget", From 34b9db2033200f95c977bacdffc9f71b68571895 Mon Sep 17 00:00:00 2001 From: Andrey Date: Sat, 20 Jan 2018 15:41:41 +0000 Subject: [PATCH 0170/1160] Translated using Weblate (Russian) Currently translated at 100.0% (982 of 982 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 4fc55e5e23..c89afb5ba6 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -981,5 +981,6 @@ "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s", "Which officially provided instance you are using, if any": "Какую официально выпущенную версию вы используете", "Whether or not you're using the Richtext mode of the Rich Text Editor": "Независимо от того, используете ли вы режим Richtext в редакторе Rich Text Editor", - "This room is not public. You will not be able to rejoin without an invite.": "Эта комната не является публичной. Вы не сможете войти без приглашения." + "This room is not public. You will not be able to rejoin without an invite.": "Эта комната не является публичной. Вы не сможете войти без приглашения.", + "Show devices, send anyway or cancel.": "Показать устройства, отправить в любом случае или отменить." } From 33995b053eb00baab5e8e80c37000326dc2e2cc8 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 22 Jan 2018 16:34:14 +0000 Subject: [PATCH 0171/1160] Add class to EventTile Line's that are quotes Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/EventTile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 937826b4fd..4e0ff2c6d6 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -592,7 +592,7 @@ module.exports = withMatrixClient(React.createClass({
    { avatar } { sender } -
    +
    { timestamp } From 3b1d69edbb01ff534ca53c8a58a3c79a08816cec Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 22 Jan 2018 16:34:47 +0000 Subject: [PATCH 0172/1160] Change Quotes to be linearly rendered rather than recursively nested Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Quote.js | 146 ++++++++++++------- src/components/views/messages/TextualBody.js | 24 +-- src/i18n/strings/en_EN.json | 3 +- 3 files changed, 109 insertions(+), 64 deletions(-) diff --git a/src/components/views/elements/Quote.js b/src/components/views/elements/Quote.js index bceba0f536..55b59a5789 100644 --- a/src/components/views/elements/Quote.js +++ b/src/components/views/elements/Quote.js @@ -20,10 +20,11 @@ import PropTypes from 'prop-types'; import MatrixClientPeg from '../../../MatrixClientPeg'; import {wantsDateSeparator} from '../../../DateUtils'; import {MatrixEvent} from 'matrix-js-sdk'; +import {makeUserPermalink} from "../../../matrix-to"; // For URLs of matrix.to links in the timeline which have been reformatted by // HttpUtils transformTags to relative links. This excludes event URLs (with `[^\/]*`) -const REGEX_LOCAL_MATRIXTO = /^#\/room\/(([\#\!])[^\/]*)\/(\$[^\/]*)$/; +const REGEX_LOCAL_MATRIXTO = /^#\/room\/([\#\!][^\/]*)\/(\$[^\/]*)$/; export default class Quote extends React.Component { static isMessageUrl(url) { @@ -32,111 +33,148 @@ export default class Quote extends React.Component { static childContextTypes = { matrixClient: PropTypes.object, + addRichQuote: PropTypes.func, }; static propTypes = { // The matrix.to url of the event url: PropTypes.string, + // The original node that was rendered + node: PropTypes.instanceOf(Element), // The parent event parentEv: PropTypes.instanceOf(MatrixEvent), - // Whether this isn't the first Quote, and we're being nested - isNested: PropTypes.bool, }; constructor(props, context) { super(props, context); this.state = { - // The event related to this quote - event: null, - show: !this.props.isNested, + // The event related to this quote and their nested rich quotes + events: [], + // Whether the top (oldest) event should be shown or spoilered + show: true, + // Whether an error was encountered fetching another older event, show if it does + err: null, }; this.onQuoteClick = this.onQuoteClick.bind(this); + this.addRichQuote = this.addRichQuote.bind(this); } getChildContext() { return { matrixClient: MatrixClientPeg.get(), + addRichQuote: this.addRichQuote, }; } + parseUrl(url) { + if (!url) return; + + // Default to the empty array if no match for simplicity + // resource and prefix will be undefined instead of throwing + const matrixToMatch = REGEX_LOCAL_MATRIXTO.exec(url) || []; + + const [, roomIdentifier, eventId] = matrixToMatch; + return {roomIdentifier, eventId}; + } + componentWillReceiveProps(nextProps) { - let roomId; - let prefix; - let eventId; + const {roomIdentifier, eventId} = this.parseUrl(nextProps.url); + if (!roomIdentifier || !eventId) return; - if (nextProps.url) { - // Default to the empty array if no match for simplicity - // resource and prefix will be undefined instead of throwing - const matrixToMatch = REGEX_LOCAL_MATRIXTO.exec(nextProps.url) || []; - - roomId = matrixToMatch[1]; // The room ID - prefix = matrixToMatch[2]; // The first character of prefix - eventId = matrixToMatch[3]; // The event ID - } - - const room = prefix === '#' ? - MatrixClientPeg.get().getRooms().find((r) => { - return r.getAliases().includes(roomId); - }) : MatrixClientPeg.get().getRoom(roomId); + const room = this.getRoom(roomIdentifier); + if (!room) return; // Only try and load the event if we know about the room // otherwise we just leave a `Quote` anchor which can be used to navigate/join the room manually. - if (room) this.getEvent(room, eventId); + this.setState({ events: [] }); + if (room) this.getEvent(room, eventId, true); } componentWillMount() { this.componentWillReceiveProps(this.props); } - async getEvent(room, eventId) { - let event = room.findEventById(eventId); + getRoom(id) { + const cli = MatrixClientPeg.get(); + if (id[0] === '!') return cli.getRoom(id); + + return cli.getRooms().find((r) => { + return r.getAliases().includes(id); + }); + } + + async getEvent(room, eventId, show) { + const event = room.findEventById(eventId); if (event) { - this.setState({room, event}); + this.addEvent(event, show); return; } await MatrixClientPeg.get().getEventTimeline(room.getUnfilteredTimelineSet(), eventId); - event = room.findEventById(eventId); - this.setState({room, event}); + this.addEvent(room.findEventById(eventId), show); + } + + addEvent(event, show) { + const events = [event].concat(this.state.events); + this.setState({events, show}); + } + + // addRichQuote(roomId, eventId) { + addRichQuote(href) { + const {roomIdentifier, eventId} = this.parseUrl(href); + if (!roomIdentifier || !eventId) return; + + const room = this.getRoom(roomIdentifier); + if (!room) return; + + this.getEvent(room, eventId, false); } onQuoteClick() { - this.setState({ - show: true, - }); + this.setState({ show: true }); } render() { - const ev = this.state.event; - if (ev) { - if (this.state.show) { - const EventTile = sdk.getComponent('views.rooms.EventTile'); - let dateSep = null; + const events = this.state.events.slice(); + if (events.length) { + const evTiles = []; - const evDate = ev.getDate(); - if (wantsDateSeparator(this.props.parentEv.getDate(), evDate)) { - const DateSeparator = sdk.getComponent('messages.DateSeparator'); - dateSep = ; - } + if (!this.state.show) { + const oldestEv = events.shift(); + const Pill = sdk.getComponent('elements.Pill'); + const room = MatrixClientPeg.get().getRoom(oldestEv.getRoomId()); - return
    - { dateSep } - -
    ; + evTiles.push(
    + { + _t('In reply to ', {}, { + 'a': (sub) => { sub }, + 'pill': , + }) + } +
    ); } - return ; + const EventTile = sdk.getComponent('views.rooms.EventTile'); + const DateSeparator = sdk.getComponent('messages.DateSeparator'); + events.forEach((ev) => { + let dateSep = null; + + if (wantsDateSeparator(this.props.parentEv.getDate(), ev.getDate())) { + dateSep = ; + } + + evTiles.push(
    + { dateSep } + +
    ); + }); + + return
    { evTiles }
    ; } // Deliberately render nothing if the URL isn't recognised - return ; + return this.props.node; } } diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index 4f34a635dc..31c1df7b44 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -61,6 +61,10 @@ module.exports = React.createClass({ tileShape: PropTypes.string, }, + contextTypes: { + addRichQuote: PropTypes.func, + }, + getInitialState: function() { return { // the URLs (if any) to be previewed with a LinkPreviewWidget @@ -202,18 +206,20 @@ module.exports = React.createClass({ // update the current node with one that's now taken its place node = pillContainer; } else if (SettingsStore.isFeatureEnabled("feature_rich_quoting") && Quote.isMessageUrl(href)) { - // only allow this branch if we're not already in a quote, as fun as infinite nesting is. - const quoteContainer = document.createElement('span'); + if (this.context.addRichQuote) { // We're already a Rich Quote so just append the next one above + this.context.addRichQuote(href); + node.remove(); + } else { // We're the first in the chain + const quoteContainer = document.createElement('span'); - const quote = - ; - - ReactDOM.render(quote, quoteContainer); - node.parentNode.replaceChild(quoteContainer, node); + const quote = + ; + ReactDOM.render(quote, quoteContainer); + node.parentNode.replaceChild(quoteContainer, node); + node = quoteContainer; + } pillified = true; - - node = quoteContainer; } } else if (node.nodeType == Node.TEXT_NODE) { const Pill = sdk.getComponent('elements.Pill'); diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 73e3f3a014..52cb8f0991 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -979,5 +979,6 @@ "Which officially provided instance you are using, if any": "Which officially provided instance you are using, if any", "Whether or not you're using the Richtext mode of the Rich Text Editor": "Whether or not you're using the Richtext mode of the Rich Text Editor", "Your homeserver's URL": "Your homeserver's URL", - "Your identity server's URL": "Your identity server's URL" + "Your identity server's URL": "Your identity server's URL", + "In reply to ": "In reply to " } From a6cefb83f86f4fe0050e1af18e81d5c631b97024 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 22 Jan 2018 16:41:32 +0000 Subject: [PATCH 0173/1160] basic error handling for malformed quotes Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Quote.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/components/views/elements/Quote.js b/src/components/views/elements/Quote.js index 55b59a5789..0a186b3ca6 100644 --- a/src/components/views/elements/Quote.js +++ b/src/components/views/elements/Quote.js @@ -53,8 +53,8 @@ export default class Quote extends React.Component { events: [], // Whether the top (oldest) event should be shown or spoilered show: true, - // Whether an error was encountered fetching another older event, show if it does - err: null, + // Whether an error was encountered fetching nested older event, show node if it does + err: false, }; this.onQuoteClick = this.onQuoteClick.bind(this); @@ -124,10 +124,16 @@ export default class Quote extends React.Component { // addRichQuote(roomId, eventId) { addRichQuote(href) { const {roomIdentifier, eventId} = this.parseUrl(href); - if (!roomIdentifier || !eventId) return; + if (!roomIdentifier || !eventId) { + this.setState({ err: true }); + return; + } const room = this.getRoom(roomIdentifier); - if (!room) return; + if (!room) { + this.setState({ err: true }); + return; + } this.getEvent(room, eventId, false); } From e3e3535072bb053eb5c41a3c0aca89920b984fd5 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 22 Jan 2018 17:02:20 +0000 Subject: [PATCH 0174/1160] delint Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Quote.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/views/elements/Quote.js b/src/components/views/elements/Quote.js index 0a186b3ca6..0c0078978d 100644 --- a/src/components/views/elements/Quote.js +++ b/src/components/views/elements/Quote.js @@ -156,7 +156,8 @@ export default class Quote extends React.Component { { _t('In reply to ', {}, { 'a': (sub) => { sub }, - 'pill': , + 'pill': , }) } ); From 294a5db20eedb6610d6e34f36c216c0acf1d0820 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Sat, 20 Jan 2018 13:41:07 +0000 Subject: [PATCH 0175/1160] Translated using Weblate (Hungarian) Currently translated at 100.0% (982 of 982 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index e630a3949c..6e03659c8a 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -981,5 +981,6 @@ "Your homeserver's URL": "Az egyedi szerver URL-t", "Your identity server's URL": "Az azonosítási szerver URL-t", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(fullYear)s. %(monthName)s %(day)s, %(weekDayName)s", - "This room is not public. You will not be able to rejoin without an invite.": "Ez a szoba nem nyilvános. Kilépés után csak újabb meghívóval tudsz újra belépni a szobába." + "This room is not public. You will not be able to rejoin without an invite.": "Ez a szoba nem nyilvános. Kilépés után csak újabb meghívóval tudsz újra belépni a szobába.", + "Show devices, send anyway or cancel.": "Eszközök listája, mindenképpen küld vagy szakítsd meg." } From e19435d39d942bdc1fda9e1b8ac583be3df95515 Mon Sep 17 00:00:00 2001 From: Andrey Date: Mon, 22 Jan 2018 16:03:49 +0000 Subject: [PATCH 0176/1160] Translated using Weblate (Russian) Currently translated at 100.0% (983 of 983 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index c89afb5ba6..6ddc92b928 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -982,5 +982,6 @@ "Which officially provided instance you are using, if any": "Какую официально выпущенную версию вы используете", "Whether or not you're using the Richtext mode of the Rich Text Editor": "Независимо от того, используете ли вы режим Richtext в редакторе Rich Text Editor", "This room is not public. You will not be able to rejoin without an invite.": "Эта комната не является публичной. Вы не сможете войти без приглашения.", - "Show devices, send anyway or cancel.": "Показать устройства, отправить в любом случае или отменить." + "Show devices, send anyway or cancel.": "Показать устройства, отправить в любом случае или отменить.", + "Community IDs cannot not be empty.": "ID сообществ не могут быть пустыми." } From 88443af8fac56e2fbcf3262df1af9599fc74d38b Mon Sep 17 00:00:00 2001 From: Osoitz Date: Mon, 22 Jan 2018 19:23:20 +0000 Subject: [PATCH 0177/1160] Translated using Weblate (Basque) Currently translated at 100.0% (983 of 983 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eu/ --- src/i18n/strings/eu.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index 2dfb197f46..f1db7376e9 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -981,5 +981,7 @@ "Your homeserver's URL": "Zure hasiera zerbitzariaren URL-a", "Your identity server's URL": "Zure identitate zerbitzariaren URL-a", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(fullYear)s(e)ko %(monthName)sk %(day)sa", - "This room is not public. You will not be able to rejoin without an invite.": "Gela hau ez da publikoa. Ezin izango zara berriro elkartu gonbidapenik gabe." + "This room is not public. You will not be able to rejoin without an invite.": "Gela hau ez da publikoa. Ezin izango zara berriro elkartu gonbidapenik gabe.", + "Community IDs cannot not be empty.": "Komunitate ID-ak ezin dira hutsik egon.", + "Show devices, send anyway or cancel.": "Erakutsi gailuak, bidali hala ere edo ezeztatu." } From ace7b84987d6e4375819c371416bfb5b2f65c0fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Mon, 22 Jan 2018 20:42:32 +0000 Subject: [PATCH 0178/1160] Translated using Weblate (French) Currently translated at 100.0% (983 of 983 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 846cf7a32f..cff37c3d70 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -981,5 +981,7 @@ "Your homeserver's URL": "L'URL de votre serveur d'accueil", "Your identity server's URL": "L'URL de votre serveur d'identité", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s %(day)s %(monthName)s %(fullYear)s", - "This room is not public. You will not be able to rejoin without an invite.": "Ce salon n'est pas public. Vous ne pourrez pas y revenir sans invitation." + "This room is not public. You will not be able to rejoin without an invite.": "Ce salon n'est pas public. Vous ne pourrez pas y revenir sans invitation.", + "Community IDs cannot not be empty.": "Les identifiants de communauté ne peuvent pas être vides.", + "Show devices, send anyway or cancel.": "Afficher les appareils, envoyer quand même ou annuler." } From e5f5091505572147c233a6a1884fcd2747aa615a Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Tue, 23 Jan 2018 05:15:27 +0000 Subject: [PATCH 0179/1160] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (983 of 983 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hant/ --- src/i18n/strings/zh_Hant.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index c6b37bf2bc..bae5c33be9 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -980,5 +980,7 @@ "Your homeserver's URL": "您的家伺服器 URL", "Your identity server's URL": "您的驗證伺服器 URL", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s", - "This room is not public. You will not be able to rejoin without an invite.": "這個聊天室並未公開。您在沒有邀請的情況下將無法重新加入。" + "This room is not public. You will not be able to rejoin without an invite.": "這個聊天室並未公開。您在沒有邀請的情況下將無法重新加入。", + "Community IDs cannot not be empty.": "社群 ID 不能為空。", + "Show devices, send anyway or cancel.": "顯示裝置無論如何都要傳送取消。" } From 71ecc5d7c595409a7b2d7c6439777a943ea8dbd6 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Mon, 22 Jan 2018 17:24:43 +0000 Subject: [PATCH 0180/1160] Translated using Weblate (Hungarian) Currently translated at 100.0% (983 of 983 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 6e03659c8a..da9de87695 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -982,5 +982,6 @@ "Your identity server's URL": "Az azonosítási szerver URL-t", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(fullYear)s. %(monthName)s %(day)s, %(weekDayName)s", "This room is not public. You will not be able to rejoin without an invite.": "Ez a szoba nem nyilvános. Kilépés után csak újabb meghívóval tudsz újra belépni a szobába.", - "Show devices, send anyway or cancel.": "Eszközök listája, mindenképpen küld vagy szakítsd meg." + "Show devices, send anyway or cancel.": "Eszközök listája, mindenképpen küld vagy szakítsd meg.", + "Community IDs cannot not be empty.": "A közösségi azonosító nem lehet üres." } From f45ad264237ff1aa57f3a355d9acf59b7bd7f346 Mon Sep 17 00:00:00 2001 From: d1d4c Date: Wed, 24 Jan 2018 02:57:44 +0000 Subject: [PATCH 0181/1160] Translated using Weblate (Catalan) Currently translated at 24.3% (239 of 983 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ca/ --- src/i18n/strings/ca.json | 209 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 208 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ca.json b/src/i18n/strings/ca.json index 6af10bf907..c8d5991c49 100644 --- a/src/i18n/strings/ca.json +++ b/src/i18n/strings/ca.json @@ -30,5 +30,212 @@ "Remove": "Elimina", "unknown error code": "codi d'error desconegut", "OK": "D'acord", - "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "S'ha enviat un missatge de text a +%(msisdn)s. Entreu si us plau el codi de verificació que conté" + "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "S'ha enviat un missatge de text a +%(msisdn)s. Entreu si us plau el codi de verificació que conté", + "Operation failed": "No s'ha pogut realitzar l'operació", + "Search": "Cerca", + "powered by Matrix": "amb tecnologia de Matrix", + "Edit": "Editeu", + "Unpin Message": "Desenganxa el missatge", + "Quote": "Cita", + "Register": "Registre", + "Rooms": "Sales", + "Add rooms to this community": "Afegeix sales a aquesta comunitat", + "World readable": "Llegible al món", + "Guests can join": "Els convidats s'hi poden unir", + "This email address is already in use": "Aquesta adreça de correu electrònic ja està en ús", + "This phone number is already in use": "Aquest número de telèfon ja està en ús", + "Failed to verify email address: make sure you clicked the link in the email": "No s'ha pogut verificar l'adreça de correu electrònic. Assegureu-vos de fer clic a l'enllaç del correu electrònic de verificació", + "Call Failed": "No s'ha pogut realitzar la trucada", + "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "Hi ha dispositius desconeguts a aquesta sala. Si continueu sense verificar-los, és possible que algú escolti la vostra trucada.", + "Review Devices": "Revisió de dispositius", + "Call Anyway": "Truca de totes maneres", + "Answer Anyway": "Contesta en tot cas", + "Call": "Truca", + "Answer": "Contesta", + "The remote side failed to pick up": "El costat remot no s'ha pogut recuperar", + "Unable to capture screen": "No s'ha pogut capturar la pantalla", + "Existing Call": "Trucades existents", + "You are already in a call.": "Ja sou a una trucada.", + "VoIP is unsupported": "El VoIP no és compatible aquí", + "You cannot place VoIP calls in this browser.": "No es poden fer trucades VoIP amb aquest navegador.", + "You cannot place a call with yourself.": "No és possible trucar-se a un mateix.", + "Conference calls are not supported in this client": "Aquest client no és compatible amb les trucades de conferència", + "Conference calls are not supported in encrypted rooms": "Les trucades de conferència no es poden fer dins les sales encriptades", + "Warning!": "Avís!", + "Conference calling is in development and may not be reliable.": "Les conferències estan en desenvolupament i podrien no ser fiables.", + "Failed to set up conference call": "No s'ha pogut realitzar la trucada de conferència", + "Conference call failed.": "No s´ha pogut realitzar la trucada de conferència.", + "The file '%(fileName)s' failed to upload": "No s'ha pogut pujar el fitxer '%(fileName)s'", + "The file '%(fileName)s' exceeds this home server's size limit for uploads": "El fitxer '%(fileName)s' supera el límit de mida per a les càrregues d'aquest servidor", + "Upload Failed": "No s'ha pogut realitzar la pujada", + "Sun": "dg.", + "Mon": "dl.", + "Tue": "dt.", + "Wed": "dc.", + "Thu": "dj.", + "Fri": "dv.", + "Sat": "ds.", + "Jan": "gen.", + "Feb": "febr.", + "Mar": "març", + "Apr": "abr.", + "May": "maig", + "Jun": "juny", + "Jul": "jul.", + "Aug": "ag.", + "Sep": "set.", + "Oct": "oct.", + "Nov": "nov.", + "Dec": "des.", + "PM": "PM", + "AM": "AM", + "%(weekDayName)s %(time)s": "%(weekDayName)s%(time)s", + "%(weekDayName)s, %(monthName)s %(day)s %(time)s": "%(weekDayName)s%(day)s%(monthName)s%(time)s", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s%(day)s%(monthName)s%(fullYear)s", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s": "%(weekDayName)s%(day)s%(monthName)s%(fullYear)s%(time)s", + "Who would you like to add to this community?": "A qui voleu afegir a aquesta comunitat?", + "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Avís: les persones que afegiu a aquesta comunitat seran visibles públicament per a qualsevol que conegui l'ID de la comunitat", + "Invite new community members": "Convida a unir-se a la comunitat a nous membres", + "Name or matrix ID": "Nom o ID de Matrix", + "Invite to Community": "Convida a la comunitat", + "Which rooms would you like to add to this community?": "Quines sales voleu afegir a aquesta comunitat?", + "Show these rooms to non-members on the community page and room list?": "Voleu mostrar a la llista de sales i a la pàgina de la comunitat, aquestes sales, als qui no en siguin membres?", + "Add rooms to the community": "Afegeix sales a la comunitat", + "Room name or alias": "Nom de la sala o alies", + "Add to community": "Afegeix a la comunitat", + "Failed to invite the following users to %(groupId)s:": "No s'ha pogut convidar al grup %(groupId)s els següents usuaris:", + "Failed to invite users to community": "No s'ha pogut convidar als usuaris a la comunitat", + "Failed to invite users to %(groupId)s": "No s'ha pogut convidar als usuaris al grup %(groupId)s", + "Failed to add the following rooms to %(groupId)s:": "No s'ha pogut afegir al grup %(groupId)s les següents sales:", + "Riot does not have permission to send you notifications - please check your browser settings": "Riot no té permís per enviar-vos notificacions. Comproveu la configuració del vostre navegador", + "Riot was not given permission to send notifications - please try again": "Riot no ha rebut cap permís per enviar notificacions. Torneu-ho a provar", + "Unable to enable Notifications": "No s'ha pogut activar les notificacions", + "This email address was not found": "Aquesta adreça de correu electrònic no s'ha trobat", + "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "La vostra adreça de correu electrònic no sembla que estigui associada amb un identificador de Matrix d'aquest servidor.", + "Default": "Per defecte", + "Restricted": "Restringit", + "Moderator": "Moderador", + "Admin": "Admin", + "Start a chat": "Comença un xat", + "Who would you like to communicate with?": "Amb qui es vol comunicar?", + "Email, name or matrix ID": "Correu electrònic, nom o ID de Matrix", + "Start Chat": "Comença un xat", + "Invite new room members": "Convida a nous membres a la sala", + "Who would you like to add to this room?": "A qui vol afegir a aquesta sala?", + "Send Invites": "Envia invitacions", + "Failed to invite user": "No s'ha pogut convidar al usuari", + "Failed to invite": "No s'ha pogut tramitar la invitació", + "Failed to invite the following users to the %(roomName)s room:": "No s'ha pogut convidar a la sala %(roomName)s els següents usuaris:", + "You need to be logged in.": "És necessari estar autenticat.", + "You need to be able to invite users to do that.": "Per poder fer això, heu de poder convidar a altres usuaris.", + "Unable to create widget.": "No s'ha pogut crear el giny.", + "Failed to send request.": "No s'ha pogut enviar la sol·licitud.", + "This room is not recognised.": "No es reconeix aquesta sala.", + "Power level must be positive integer.": "El nivell de potència ha de ser un enter positiu.", + "You are not in this room.": "No heu entrat a aquesta sala.", + "You do not have permission to do that in this room.": "No teniu el permís per realitzar aquesta acció en aquesta sala.", + "Missing room_id in request": "Falta l'ID de la sala en la vostra sol·licitud", + "Must be viewing a room": "Hauríeu de veure una sala", + "Room %(roomId)s not visible": "La sala %(roomId)s no és visible", + "Missing user_id in request": "Falta l'ID d'usuari a la vostre sol·licitud", + "Failed to lookup current room": "No s'ha pogut buscar la sala actual", + "Usage": "Ús", + "/ddg is not a command": "/ddg no és un comandament", + "To use it, just wait for autocomplete results to load and tab through them.": "Per utilitzar-lo, simplement espereu que es completin els resultats automàticament i seleccioneu-ne el desitjat.", + "Unrecognised room alias:": "Alies de sala no reconeguts:", + "Ignored user": "Usuari ignorat", + "You are now ignoring %(userId)s": "S'està ignorant l'usuari %(userId)s", + "Unignored user": "Usuari no ignorat", + "You are no longer ignoring %(userId)s": "Ja no s'està ignorant al usuari %(userId)s", + "Device already verified!": "El dispositiu ja estava verificat!", + "WARNING: Device already verified, but keys do NOT MATCH!": "AVÍS: El dispositiu ja estava verificat, però les claus NO COINCIDIEN!", + "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!": "AVÍS: NO S'HA POGUT VERIFICAR! La firma de la clau de l'usuari %(userId)s i el dispositiu %(deviceId)s és \"%(fprint)s\", però no coincideix amb la clau \"%(fingerprint)s\". Això pot significar que les vostres comunicacions estan sent interceptades!", + "Verified key": "Claus verificades", + "Call Timeout": "La trucada ha esgotat el temps d'espera", + "Unknown (user, device) pair:": "Parell desconegut (usuari, dispositiu):", + "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "La clau de signatura que heu proporcionat coincideix amb la clau de signatura que heu rebut del dispositiu %(deviceId)s de l'usuari %(userId)s. S'ha marcat el dispositiu com a dispositiu verificat.", + "Unrecognised command:": "Ordre no reconegut:", + "Reason": "Raó", + "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s ha acceptat la invitació de %(displayName)s.", + "%(targetName)s accepted an invitation.": "%(targetName)s ha acceptat una invitació.", + "%(senderName)s requested a VoIP conference.": "%(senderName)s ha sol·licitat una conferència VoIP.", + "%(senderName)s invited %(targetName)s.": "%(senderName)s ha convidat a %(targetName)s.", + "%(senderName)s banned %(targetName)s.": "%(senderName)s ha expulsat a %(targetName)s.", + "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s ha canviat el seu nom visible %(oldDisplayName)s a %(displayName)s.", + "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s ha establert %(displayName)s com el seu nom visible.", + "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s ha retirat el seu nom visible %(oldDisplayName)s.", + "%(senderName)s removed their profile picture.": "%(senderName)s ha retirat la seva foto de perfil.", + "%(senderName)s changed their profile picture.": "%(senderName)s ha canviat la seva foto de perfil.", + "%(senderName)s set a profile picture.": "%(senderName)s ha establert una foto de perfil.", + "VoIP conference started.": "S'ha iniciat la conferència VoIP.", + "%(targetName)s joined the room.": "%(targetName)s ha entrat a la sala.", + "VoIP conference finished.": "S'ha finalitzat la conferència VoIP.", + "%(targetName)s rejected the invitation.": "%(targetName)s ha rebutjat la invitació.", + "%(targetName)s left the room.": "%(targetName)s ha sortir de la sala.", + "%(senderName)s unbanned %(targetName)s.": "%(senderName)s ha readmès a %(targetName)s.", + "%(senderName)s kicked %(targetName)s.": "%(senderName)s ha fet fora a %(targetName)s.", + "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s ha retirat la invitació per a %(targetName)s.", + "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s ha canviat el tema a \"%(topic)s\".", + "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s ha eliminat el nom de la sala.", + "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s ha canviat el nom de la sala a %(roomName)s.", + "%(senderDisplayName)s sent an image.": "%(senderDisplayName)s ha enviat una imatge.", + "Someone": "Algú", + "(not supported by this browser)": "(no és compatible amb aquest navegador)", + "%(senderName)s answered the call.": "%(senderName)s ha contestat la trucada.", + "(could not connect media)": "(no s'ha pogut connectar el medi)", + "(no answer)": "(sense resposta)", + "(unknown failure: %(reason)s)": "(error desconegut: %(reason)s)", + "%(senderName)s ended the call.": "%(senderName)s ha penjat.", + "%(senderName)s placed a %(callType)s call.": "%(senderName)s ha col·locat una trucada de %(callType)s.", + "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s ha enviat una invitació a %(targetDisplayName)s a entrar a aquesta sala.", + "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s ha fet visible l'històric futur de la sala per a tots els membres, a partir de que són convidats.", + "%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s ha fet visible l'històric futur de la sala a tots els membres, des de que entren a la sala.", + "%(senderName)s made future room history visible to all room members.": "%(senderName)s ha fet visible l'històric futur de la sala a tots els membres de la sala.", + "%(senderName)s made future room history visible to anyone.": "%(senderName)s ha fet visible l´historial de la sala per a tothom.", + "%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s ha fet visible l'històric de la sala per a desconeguts (%(visibility)s).", + "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s ha activat l'encriptació d'extrem a extrem (algoritme %(algorithm)s).", + "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s de %(fromPowerLevel)s fins %(toPowerLevel)s", + "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s ha canviat el nivell de potència de %(powerLevelDiffText)s.", + "%(senderName)s changed the pinned messages for the room.": "%(senderName)s ha canviat els missatges fixats de la sala.", + "%(widgetName)s widget modified by %(senderName)s": "%(senderName)s ha modificat el giny %(widgetName)s", + "%(widgetName)s widget added by %(senderName)s": "%(senderName)s ha afegit el giny %(widgetName)s", + "%(widgetName)s widget removed by %(senderName)s": "%(senderName)s ha eliminat el giny %(widgetName)s", + "%(displayName)s is typing": "%(displayName)s està escrivint", + "%(names)s and %(count)s others are typing|other": "%(names)s i %(count)s més estan escrivint", + "%(names)s and %(count)s others are typing|one": "%(names)s i algú altre està escrivint", + "%(names)s and %(lastPerson)s are typing": "%(names)s i %(lastPerson)s estan escrivint", + "Failure to create room": "No s'ha pogut crear la sala", + "Server may be unavailable, overloaded, or you hit a bug.": "És possible que el servidor no estigui disponible, amb sobrecàrrega o que s'hagi trobat un error.", + "Send anyway": "Envia de totes maneres", + "Send": "Envia", + "Unnamed Room": "Sala sense nom", + "Your browser does not support the required cryptography extensions": "El vostre navegador no és compatible amb els complements criptogràfics necessaris", + "Not a valid Riot keyfile": "El fitxer no és un fitxer de claus de Riot valid", + "Authentication check failed: incorrect password?": "Ha fallat l'autenticació: heu introduït correctament la contrasenya?", + "Failed to join room": "No s'ha pogut entrar a la sala", + "Message Replies": "Respostes del missatge", + "Message Pinning": "Fixació de missatges", + "Presence Management": "Gestió de presència", + "Tag Panel": "Tauler d'etiquetes", + "Disable Emoji suggestions while typing": "Desactiva els suggeriments d'Emoji mentre s'escriu", + "Use compact timeline layout": "Utilitza el disseny compacte de la línia de temps", + "Hide join/leave messages (invites/kicks/bans unaffected)": "Amaga els missatges de entrada i sortida (no afecta a invitacions, expulsions o prohibicions)", + "Hide avatar changes": "Amaga els canvis de foto de perfil", + "Hide display name changes": "Amaga els canvis de nom visible", + "Hide read receipts": "Amaga els rebuts llegits", + "Show timestamps in 12 hour format (e.g. 2:30pm)": "Mostra les marques de temps en format de 12 hores (per exemple, 2:30pm)", + "Autoplay GIFs and videos": "Reprodueix de forma automàtica els GIF i vídeos", + "Enable automatic language detection for syntax highlighting": "Activa la detecció automàtica d'idiomes per al ressaltat de sintaxi", + "Disable big emoji in chat": "Desactiva els grans emoji al xat", + "Don't send typing notifications": "No enviïs notificacions d'escriptura", + "Automatically replace plain text Emoji": "Substitueix automàticament Emoji de text pla", + "Disable Peer-to-Peer for 1:1 calls": "Desactiva el Peer-to-Peer per a trucades entre dos", + "Never send encrypted messages to unverified devices in this room from this device": "Des d´aquest dispositiu no enviïs mai a aquesta sala missatges encriptats a dispositius sense verificar", + "Enable inline URL previews by default": "Activa per defecte les visualitzacions prèvies d'URL en línia", + "Enable URL previews for this room (only affects you)": "Activa les visualitzacions prèvies d'URL d'aquesta sala (no afecta a altres usuaris)", + "Enable URL previews by default for participants in this room": "Activa per defecte les visualitzacions prèvies d'URL per als participants d'aquesta sala", + "Room Colour": "Color de la sala", + "Active call (%(roomName)s)": "Trucada activa (%(roomName)s)", + "unknown caller": "trucada desconeguda", + "Incoming voice call from %(name)s": "Trucada de veu entrant de %(name)s" } From 18d9de61fa1f9d2fa102037cbc5820c285475140 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sim=C3=B3=20Albert=20i=20Beltran?= Date: Wed, 24 Jan 2018 07:59:40 +0000 Subject: [PATCH 0182/1160] Translated using Weblate (Catalan) Currently translated at 24.3% (239 of 983 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ca/ --- src/i18n/strings/ca.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/i18n/strings/ca.json b/src/i18n/strings/ca.json index c8d5991c49..c40336f2d1 100644 --- a/src/i18n/strings/ca.json +++ b/src/i18n/strings/ca.json @@ -230,12 +230,12 @@ "Don't send typing notifications": "No enviïs notificacions d'escriptura", "Automatically replace plain text Emoji": "Substitueix automàticament Emoji de text pla", "Disable Peer-to-Peer for 1:1 calls": "Desactiva el Peer-to-Peer per a trucades entre dos", - "Never send encrypted messages to unverified devices in this room from this device": "Des d´aquest dispositiu no enviïs mai a aquesta sala missatges encriptats a dispositius sense verificar", - "Enable inline URL previews by default": "Activa per defecte les visualitzacions prèvies d'URL en línia", - "Enable URL previews for this room (only affects you)": "Activa les visualitzacions prèvies d'URL d'aquesta sala (no afecta a altres usuaris)", - "Enable URL previews by default for participants in this room": "Activa per defecte les visualitzacions prèvies d'URL per als participants d'aquesta sala", + "Never send encrypted messages to unverified devices in this room from this device": "Des d'aquest dispositiu no enviïs mai a aquesta sala missatges encriptats a dispositius sense verificar", + "Enable inline URL previews by default": "Activa per defecte la vista prèvia d'URLs en línia", + "Enable URL previews for this room (only affects you)": "Activa la vista prèvia d'URLs d'aquesta sala (no afecta a altres usuaris)", + "Enable URL previews by default for participants in this room": "Activa per defecte la vista prèvia d'URLs per als participants d'aquesta sala", "Room Colour": "Color de la sala", "Active call (%(roomName)s)": "Trucada activa (%(roomName)s)", - "unknown caller": "trucada desconeguda", + "unknown caller": "trucada d'un desconegut", "Incoming voice call from %(name)s": "Trucada de veu entrant de %(name)s" } From d3100f9bc99c465b94d3cbd35bfd5bc3d917bb40 Mon Sep 17 00:00:00 2001 From: d1d4c Date: Wed, 24 Jan 2018 17:53:21 +0000 Subject: [PATCH 0183/1160] Translated using Weblate (Catalan) Currently translated at 54.3% (534 of 983 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ca/ --- src/i18n/strings/ca.json | 305 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 300 insertions(+), 5 deletions(-) diff --git a/src/i18n/strings/ca.json b/src/i18n/strings/ca.json index c40336f2d1..342996513a 100644 --- a/src/i18n/strings/ca.json +++ b/src/i18n/strings/ca.json @@ -41,7 +41,7 @@ "Rooms": "Sales", "Add rooms to this community": "Afegeix sales a aquesta comunitat", "World readable": "Llegible al món", - "Guests can join": "Els convidats s'hi poden unir", + "Guests can join": "Els usuaris d'altres xarxes s'hi poden unir", "This email address is already in use": "Aquesta adreça de correu electrònic ja està en ús", "This phone number is already in use": "Aquest número de telèfon ja està en ús", "Failed to verify email address: make sure you clicked the link in the email": "No s'ha pogut verificar l'adreça de correu electrònic. Assegureu-vos de fer clic a l'enllaç del correu electrònic de verificació", @@ -101,7 +101,7 @@ "Which rooms would you like to add to this community?": "Quines sales voleu afegir a aquesta comunitat?", "Show these rooms to non-members on the community page and room list?": "Voleu mostrar a la llista de sales i a la pàgina de la comunitat, aquestes sales, als qui no en siguin membres?", "Add rooms to the community": "Afegeix sales a la comunitat", - "Room name or alias": "Nom de la sala o alies", + "Room name or alias": "Nom de la sala o àlies", "Add to community": "Afegeix a la comunitat", "Failed to invite the following users to %(groupId)s:": "No s'ha pogut convidar al grup %(groupId)s els següents usuaris:", "Failed to invite users to community": "No s'ha pogut convidar als usuaris a la comunitat", @@ -142,7 +142,7 @@ "Usage": "Ús", "/ddg is not a command": "/ddg no és un comandament", "To use it, just wait for autocomplete results to load and tab through them.": "Per utilitzar-lo, simplement espereu que es completin els resultats automàticament i seleccioneu-ne el desitjat.", - "Unrecognised room alias:": "Alies de sala no reconeguts:", + "Unrecognised room alias:": "Àlies de sala no reconeguts:", "Ignored user": "Usuari ignorat", "You are now ignoring %(userId)s": "S'està ignorant l'usuari %(userId)s", "Unignored user": "Usuari no ignorat", @@ -188,7 +188,7 @@ "%(senderName)s ended the call.": "%(senderName)s ha penjat.", "%(senderName)s placed a %(callType)s call.": "%(senderName)s ha col·locat una trucada de %(callType)s.", "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s ha enviat una invitació a %(targetDisplayName)s a entrar a aquesta sala.", - "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s ha fet visible l'històric futur de la sala per a tots els membres, a partir de que són convidats.", + "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s ha fet visible l'històric futur de la sala per a tots els membres, a partir de que hi són convidats.", "%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s ha fet visible l'històric futur de la sala a tots els membres, des de que entren a la sala.", "%(senderName)s made future room history visible to all room members.": "%(senderName)s ha fet visible l'històric futur de la sala a tots els membres de la sala.", "%(senderName)s made future room history visible to anyone.": "%(senderName)s ha fet visible l´historial de la sala per a tothom.", @@ -237,5 +237,300 @@ "Room Colour": "Color de la sala", "Active call (%(roomName)s)": "Trucada activa (%(roomName)s)", "unknown caller": "trucada d'un desconegut", - "Incoming voice call from %(name)s": "Trucada de veu entrant de %(name)s" + "Incoming voice call from %(name)s": "Trucada de veu entrant de %(name)s", + "Hide avatars in user and room mentions": "Amaga els avatars a les mencions de l'usuari i de la sala", + "Never send encrypted messages to unverified devices from this device": "No enviïs mai des de aquest dispositiu missatges encriptats a dispositius no verificats", + "Incoming video call from %(name)s": "Trucada de vídeo entrant de %(name)s", + "Incoming call from %(name)s": "Trucada entrant de %(name)s", + "Decline": "Declina", + "Accept": "Accepta", + "Incorrect verification code": "El codi de verificació és incorrecte", + "Enter Code": "Introduïu el codi", + "Submit": "Envia", + "Phone": "Telèfon", + "Add phone number": "Afegiu un número de telèfon", + "Add": "Afegeix", + "Failed to upload profile picture!": "No s'ha pogut pujar la imatge!", + "Upload new:": "Puja un nou:", + "No display name": "Sense nom visible", + "New passwords don't match": "Les noves contrasenyes no coincideixen", + "Passwords can't be empty": "Les contrasenyes no poden estar buides", + "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Si canvieu la contrasenya es reiniciaran totes les actuals claus de xifratge d'extrem per a tots els dispositius, fent que l'historial encriptat no sigui llegible, tret que primer exporteu les claus de la vostra sala i les torneu a importar després. En un futur això serà millorat.", + "Export E2E room keys": "Exporta les claus E2E de la sala", + "Do you want to set an email address?": "Voleu establir una adreça de correu electrònic?", + "Current password": "Contrasenya actual", + "Password": "Contrasenya", + "New Password": "Nova contrasenya", + "Confirm password": "Confirma la contrasenya", + "Change Password": "Canvia la contrasenya", + "Your home server does not support device management.": "El seu servidor amfitrió no és compatible amb la gestió de dispositius.", + "Unable to load device list": "No s'ha pogut carregar la llista de dispositius", + "Authentication": "Autenticació", + "Delete %(count)s devices|other": "Suprimeix %(count)s dispositius", + "Delete %(count)s devices|one": "Suprimeix el dispositiu", + "Device ID": "ID del dispositiu", + "Device Name": "Nom del dispositiu", + "Last seen": "Vist per últim cop", + "Select devices": "Selecciona els dispositius", + "Failed to set display name": "No s'ha pogut establir el nom visible", + "Disable Notifications": "Desactiva les notificacions", + "Enable Notifications": "Activa les notificacions", + "Cannot add any more widgets": "No s'ha pogut afegir cap més giny", + "The maximum permitted number of widgets have already been added to this room.": "Ja s'han afegit el màxim de ginys permesos en aquesta sala.", + "Drop File Here": "Deixeu anar un fitxer aquí", + "Drop file here to upload": "Deixeu anar un arxiu aquí per pujar-lo", + " (unsupported)": " (incompatible)", + "Join as voice or video.": "Uneix-te com voice o video.", + "Ongoing conference call%(supportedText)s.": "Trucada de conferència en curs %(supportedText)s.", + "%(senderName)s sent an image": "%(senderName)s ha enviat una imatge", + "%(senderName)s sent a video": "%(senderName)s ha enviat un vídeo", + "%(senderName)s uploaded a file": "%(senderName)s ha pujat un fitxer", + "Options": "Opcions", + "Undecryptable": "Indesxifrable", + "Encrypted by a verified device": "Encriptat per un dispositiu verificat", + "Encrypted by an unverified device": "Encriptat per un dispositiu no verificat", + "Unencrypted message": "Missatge no encriptat", + "Please select the destination room for this message": "Si us plau, seleccioneu la sala destinatària per a aquest missatge", + "Blacklisted": "Llista negre", + "Verified": "Verificat", + "Unverified": "No verificat", + "device id: ": "ID del dispositiu: ", + "Disinvite": "Descarta la invitació", + "Kick": "Fes fora", + "Disinvite this user?": "Descartar la invitació per a aquest usuari?", + "Kick this user?": "Voleu fer fora a aquest usuari?", + "Failed to kick": "No s'ha pogut fer fora", + "Unban": "Retira l'expulsió", + "Ban": "Expulsa", + "Unban this user?": "Voleu retirar l'expulsió de aquest usuari?", + "This room is not public. You will not be able to rejoin without an invite.": "Aquesta sala no és pública. No podreu tronar a entrar sense invitació.", + "Ban this user?": "Voleu expulsar a aquest usuari?", + "Failed to ban user": "No s'ha pogut expulsar l'usuari", + "Failed to mute user": "No s'ha pogut silenciar l'usuari", + "Failed to toggle moderator status": "No s'ha pogut canviar l'estat del moderador", + "Failed to change power level": "No s'ha pogut canviar el nivell de potència", + "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "No podreu desfer aquest canvi ja que estareu baixant de grau de privilegis. Només un altre usuari amb més privilegis podrà fer que els recupereu.", + "Are you sure?": "Esteu segur?", + "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "No podreu desfer aquesta acció ja que esteu donant al usuari el mateix nivell de privilegi que el vostre.", + "No devices with registered encryption keys": "No hi ha cap dispositiu amb les claus d'encriptació registrades", + "Devices": "Dispositius", + "Unignore": "Deixa de ignorar", + "Ignore": "Ignora", + "Jump to read receipt": "Salta a els rebuts llegits", + "Mention": "Menció", + "Invite": "Convida", + "User Options": "Opcions d'usuari", + "Direct chats": "Xats directes", + "Unmute": "No silenciïs", + "Revoke Moderator": "Revoca el moderador", + "Make Moderator": "Fes-lo moderador", + "Admin Tools": "Eines d'administració", + "Level:": "Nivell:", + "and %(count)s others...|other": "i %(count)s altres...", + "and %(count)s others...|one": "i un altre...", + "Invited": "Convidat", + "Filter room members": "Filtre de membres de sala", + "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (poder %(powerLevelNumber)s)", + "Attachment": "Adjunt", + "Upload Files": "Puja fitxers", + "Are you sure you want to upload the following files?": "Confirmeu que voleu pujar els següents fitxers?", + "Encrypted room": "Sala encriptada", + "Unencrypted room": "Sala no encriptada", + "Hangup": "Penja", + "Voice call": "Trucada de veu", + "Video call": "Trucada de vídeo", + "Hide Apps": "Amaga les aplicacions", + "Show Apps": "Mostra les aplicacions", + "Upload file": "Puja el fitxer", + "Show Text Formatting Toolbar": "Mostra la barra d'eines de format de text", + "Send an encrypted reply…": "Envia una resposta encriptada…", + "Send a reply (unencrypted)…": "Envia una resposta (sense encriptar)…", + "Send an encrypted message…": "Envia un missatge encriptat…", + "Send a message (unencrypted)…": "Envia un missatge (sense encriptar)…", + "You do not have permission to post to this room": "No teniu el permís per escriure en aquesta sala", + "Turn Markdown on": "Activa el Markdown", + "Turn Markdown off": "Desactiva el Markdown", + "Hide Text Formatting Toolbar": "Amaga la barra d'eines de format de text", + "Server error": "S'ha produït un error al servidor", + "Mirror local video feed": "Mostra el vídeo local com un mirall", + "Opt out of analytics": "Opcions fora d'anàlisi", + "Server unavailable, overloaded, or something else went wrong.": "El servidor no està disponible, està sobrecarregat o alguna altra cosa no ha funcionat correctament.", + "Command error": "S'ha produït un error en l'ordre", + "bold": "negreta", + "italic": "cursiva", + "strike": "tatxat", + "underline": "subratllat", + "code": "codi", + "quote": "cita", + "bullet": "pic", + "numbullet": "pic numerat", + "Markdown is disabled": "El Markdown està desactivat", + "Markdown is enabled": "El Markdown està activat", + "Jump to message": "Salta al missatge", + "No pinned messages.": "No hi ha cap missatge fixat.", + "Loading...": "S'està carregant...", + "Pinned Messages": "Missatges fixats", + "%(duration)ss": "%(duration)ss", + "%(duration)sm": "%(duration)sm", + "%(duration)sh": "%(duration)sh", + "%(duration)sd": "%(duration)sd", + "Online for %(duration)s": "En línia durant %(duration)s", + "Idle for %(duration)s": "Inactiu durant %(duration)s", + "Offline for %(duration)s": "Desconnectat durant %(duration)s", + "Unknown for %(duration)s": "Desconegut durant %(duration)s", + "Online": "En línia", + "Idle": "Inactiu", + "Offline": "Desconnectat", + "Unknown": "Desconegut", + "Replying": "S'està contestant", + "Seen by %(userName)s at %(dateTime)s": "Vist per %(userName)s el %(dateTime)s", + "No rooms to show": "No hi ha cap sala per a mostrar", + "Unnamed room": "Sala sense nom", + "Failed to set avatar.": "No s'ha pogut establir l'avatar.", + "Save": "Desa", + "(~%(count)s results)|other": "(~%(count)s resultats)", + "(~%(count)s results)|one": "(~%(count)s resultat)", + "Join Room": "Entra a la sala", + "Upload avatar": "Puja l'avatar", + "Remove avatar": "Elimina l'avatar", + "Forget room": "Oblida la sala", + "Show panel": "Mostra el plafó", + "Drop here to favourite": "Deixa-ho anar aquí per a marcar-ho com a favorit", + "Drop here to tag direct chat": "Deixa'l anar aquí per posar-li la etiqueta de xat directe", + "Drop here to restore": "Deixa'l anar aquí per a restaurar-lo", + "Drop here to demote": "Deixa'l anar aquí per a baixar-lo de grau", + "Drop here to tag %(section)s": "Deixa´l anar aquí per posar-li la etiqueta de %(section)s", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Encara no ha entrat a cap sala. Premeu per crear una sala o bé per fullejar el directori", + "Community Invites": "Invitacions de les comunitats", + "Invites": "Invitacions", + "Favourites": "Preferits", + "Low priority": "Baixa prioritat", + "Historical": "Històric", + "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "No s'ha pogut determinar que s'hagi enviat la invitació des de una adreça associada al vostre compte.", + "This invitation was sent to an email address which is not associated with this account:": "Aquesta invitació s'ha enviat a una adreça de correu electrònic que no està associada a aquest compte:", + "Press to start a chat with someone": "Premeu per a iniciar un xat amb algú", + "You may wish to login with a different account, or add this email to this account.": "És possible que vulgueu iniciar la sessió amb un altre compte o bé afegir aquest correu electrònic a aquest compte.", + "You have been invited to join this room by %(inviterName)s": "Heu sigut convidat a aquesta sala per %(inviterName)s", + "Would you like to accept or decline this invitation?": "Voleu accept o bé declineText>decline aquesta invitació?", + "Reason: %(reasonText)s": "Raó: %(reasonText)s", + "Rejoin": "Trona a entrar", + "You have been kicked from %(roomName)s by %(userName)s.": "%(userName)s us ha fet fora de la sala %(roomName)s.", + "You have been kicked from this room by %(userName)s.": "%(userName)s vos ha fet fora de la sala.", + "You have been banned from %(roomName)s by %(userName)s.": "%(userName)s vos ha expulsat de la sala %(roomName)s.", + "You have been banned from this room by %(userName)s.": "Heu sigut expulsat d'aquesta sala per %(userName)s.", + "This room": "Aquesta sala", + "%(roomName)s does not exist.": "La sala %(roomName)s no existeix.", + "%(roomName)s is not accessible at this time.": "La sala %(roomName)s no és accessible en aquest moment.", + "You are trying to access %(roomName)s.": "Esteu intentant accedir a la sala %(roomName)s.", + "You are trying to access a room.": "Esteu intentant accedir a una sala.", + "Click here to join the discussion!": "Click here per a entrar al debat!", + "This is a preview of this room. Room interactions have been disabled": "Aquesta és una vista prèvia de la sala. No s'hi pot interactuar des de aquí", + "To change the room's avatar, you must be a": "Per canviar l'avatar de la sala, heu de ser", + "To change the room's name, you must be a": "Per canviar el nom de la sala, heu de ser", + "To change the room's main address, you must be a": "Per canviar l'adreça principal de la sala, heu de ser", + "To change the room's history visibility, you must be a": "Per canviar la visibilitat de l'historial de la sala, heu de ser", + "To change the permissions in the room, you must be a": "Per canviar els permisos a la sala, heu de ser", + "To change the topic, you must be a": "Per canviar el tema, heu de ser", + "To modify widgets in the room, you must be a": "Per modificar els ginys de la sala, has de ser", + "Failed to unban": "No s'ha pogut expulsar", + "Banned by %(displayName)s": "Expulsat per %(displayName)s", + "Privacy warning": "Avís de privadesa", + "Changes to who can read history will only apply to future messages in this room": "Els canvis de qui pot llegir l'historial només s'aplicaran als missatges futurs d'aquesta sala", + "The visibility of existing history will be unchanged": "La visibilitat de l'historial existent no es modificarà", + "End-to-end encryption is in beta and may not be reliable": "L'encriptació d'extrem a extrem està en fase beta i pot ser que no sigui fiable", + "You should not yet trust it to secure data": "Encara no hi heu de confiar per a comunicacions segures", + "Devices will not yet be able to decrypt history from before they joined the room": "Els dispositius encara no podran desencriptar l'historial d'abans d'entrar a la sala", + "Once encryption is enabled for a room it cannot be turned off again (for now)": "Quan s'activa la encriptació en una sala, no es pot desactivar posteriorment (per ara)", + "Encrypted messages will not be visible on clients that do not yet implement encryption": "Els missatges encriptats no es podran veure en els clients que encara no tenguin implementada la encriptació", + "Enable encryption": "L'encriptació està activada", + "(warning: cannot be disabled again!)": "(avís: no es pot desactivar de nou!)", + "Encryption is enabled in this room": "L'encriptació està activada en aquesta sala", + "Encryption is not enabled in this room": "L'encriptació no està activada en aquesta sala", + "Privileged Users": "Usuaris amb privilegis", + "%(user)s is a": "L'usuari %(user)s és", + "No users have specific privileges in this room": "Cap usuari té privilegis específics en aquesta sala", + "Banned users": "Usuaris expulsats", + "This room is not accessible by remote Matrix servers": "Aquesta sala no és accessible per a servidors de Matrix remots", + "Leave room": "Surt de la sala", + "Tagged as: ": "Etiquetats com: ", + "To link to a room it must have an address.": "Per poder fer un enllaç a una sala aquesta ha de tenir an address.", + "Guests cannot join this room even if explicitly invited.": "Els usuaris d'altres xarxes no poden entrar a la sala d'aquest esdeveniment, encara que hi hagin sigut convidats de forma explícita.", + "Click here to fix": "Feu clic aquí per corregir-ho", + "Who can access this room?": "Qui pot entrar a aquesta sala?", + "Only people who have been invited": "Només les persones que hi hagin sigut convidades", + "Anyone who knows the room's link, apart from guests": "Qualsevol que conegui l'enllaç de la sala, excepte els usuaris d'altres xarxes", + "Publish this room to the public in %(domain)s's room directory?": "Voleu que es publiqui aquesta sala al directori de sales públiques de %(domain)s?", + "Who can read history?": "Qui pot llegir l'historial?", + "Anyone": "Qualsevol", + "Members only (since the point in time of selecting this option)": "Només els membres (a partir del punt en què seleccioneu aquesta opció)", + "Members only (since they were invited)": "Només els membres (a partir del punt en què hi són convidats)", + "Members only (since they joined)": "Només els membres (a partir del punt en què entrin a la sala)", + "Permissions": "Permisos", + "The default role for new room members is": "El rol per defecte dels nous membres de la sala és", + "To send messages, you must be a": "Per poder enviar missatges, heu de ser", + "To invite users into the room, you must be a": "Per poder convidar a usuaris a aquesta sala, heu de ser", + "To configure the room, you must be a": "Per poder configurar aquesta sala, heu de ser", + "To kick users, you must be a": "Per poder fer fora a usuaris, heu de ser", + "To ban users, you must be a": "Per expulsar a usuaris, heu de ser", + "To remove other users' messages, you must be a": "Per eliminar missatges d'altres usuaris, heu de ser", + "To send events of type , you must be a": "Per poder enviar esdeveniments de tipus , heu de ser", + "This room's internal ID is": "L'ID d'aquesta sala és", + "Add a topic": "Afegeix un tema", + "Scroll to unread messages": "Desplaça't fins els missatges no llegits", + "Jump to first unread message.": "Salta al primer missatge no llegit.", + "Invalid alias format": "El format de l'àlies no és vàlid", + "'%(alias)s' is not a valid format for an alias": "'%(alias)s' no és un format d'àlies vàlid", + "Invalid address format": "L'adreça no té un format vàlid", + "Anyone who knows the room's link, including guests": "Qualsevol que conegui l'enllaç, inclosos els usuaris d'altres xarxes", + "'%(alias)s' is not a valid format for an address": "'%(alias)s' no és un format vàlid per a una adreça", + "not specified": "sense especificar", + "not set": "sense definir", + "Remote addresses for this room:": "Adreces remotes per a aquesta sala:", + "Addresses": "Adreces", + "The main address for this room is": "L'adreça principal d'aquesta sala és", + "Local addresses for this room:": "Adreces locals d'aquesta sala:", + "This room has no local addresses": "Aquesta sala no té adreces locals", + "New address (e.g. #foo:%(localDomain)s)": "Nova adreça (per exemple #foo:%(localDomain)s)", + "Invalid community ID": "L'ID de la comunitat no és vàlid", + "'%(groupId)s' is not a valid community ID": "'%(groupId)s' no és un ID de comunitat vàlid", + "New community ID (e.g. +foo:%(localDomain)s)": "Nou ID de comunitat (per exemple +foo:%(localDomain)s)", + "You have enabled URL previews by default.": "Heu enabled les previsualitzacions per defecte de les URL.", + "You have disabled URL previews by default.": "Heu disabled les previsualitzacions per defecte de les URL.", + "URL previews are enabled by default for participants in this room.": "Les previsualitzacions de les URL estan activades per defecte per als membres d'aquesta sala.", + "URL previews are disabled by default for participants in this room.": "Les previsualitzacions de les URL estan per defecte desactivades per als membres d'aquesta sala.", + "URL Previews": "Previsualitzacions de les URL", + "Error decrypting audio": "S'ha produït un error mentre es desencriptava l'audio", + "Error decrypting attachment": "S'ha produït un error en desencriptar el fitxer adjunt", + "Decrypt %(text)s": "Desencripta %(text)s", + "Download %(text)s": "Baixa %(text)s", + "Invalid file%(extra)s": "Fitxer invàlid%(extra)s", + "Error decrypting image": "S'ha produït un error en desencriptar la imatge", + "Image '%(Body)s' cannot be displayed.": "La imatge '%(Body)s' no es pot mostrar.", + "This image cannot be displayed.": "Aquesta imatge no es pot mostrar.", + "Error decrypting video": "S'ha produït un error en desencriptar el vídeo", + "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s ha canviat el seu avatar per a la sala %(roomName)s", + "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s ha eliminat l'avatar de la sala.", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s ha canviat l'avatar de la sala per aquest ", + "Copied!": "Copiat!", + "Failed to copy": "No s'ha pogut copiar", + "Add an Integration": "Afegeix una integració", + "Removed or unknown message type": "El tipus de missatge ha sigut eliminat o és desconegut", + "Message removed by %(userId)s": "El missatge ha sigut eliminat per l'usuari %(userId)s", + "Message removed": "S'ha eliminat el missatge", + "Robot check is currently unavailable on desktop - please use a web browser": "Actualment, la verificació del robot no està disponible a l'escriptori: utilitzeu un web browser", + "Sign in with CAS": "Inicieu sessió amb CAS", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "Podeu utilitzar les opcions de servidor personalitzades per a iniciar sessió en altres servidors Matrix, especificant una altre URL de servidor principal.", + "This allows you to use this app with an existing Matrix account on a different home server.": "Això us permet utilitzar aquesta aplicació amb un compte de Matrix existent en un altre servidor.", + "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "També podeu establir un servidor d'identitat personalitzat, però normalment això evitarà la interacció basada en l'adreça de correu electrònic amb altres usuaris.", + "To continue, please enter your password.": "Per poder continuar, si us plau, introduïu una contrasenya.", + "Password:": "Contrasenya:", + "An email has been sent to %(emailAddress)s": "S'ha enviat un correu electrònic a %(emailAddress)s", + "Please check your email to continue registration.": "Reviseu el vostre correu electrònic per a poder continuar amb el registre.", + "Token incorrect": "El testimoni és incorrecte", + "A text message has been sent to %(msisdn)s": "S'ha enviat un missatge de text a %(msisdn)s", + "Please enter the code it contains:": "Introduïu el codi que conté:", + "Start authentication": "Inicia l'autenticació", + "Username on %(hs)s": "Nom d'usuari a %(hs)s", + "User name": "Nom d'usuari", + "Mobile phone number": "Número de telèfon mòbil" } From b7c32ee1b5731ca8efc1c6005227b4bbf19bdec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D1=80=D0=BA=D0=BE=20=D0=9C=2E=20=D0=9A=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D0=B8=D1=9B?= Date: Tue, 23 Jan 2018 20:59:39 +0000 Subject: [PATCH 0184/1160] Translated using Weblate (Serbian) Currently translated at 38.9% (383 of 983 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sr/ --- src/i18n/strings/sr.json | 110 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 109 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index ab2a4a529b..87c8aea100 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -273,5 +273,113 @@ "Failed to ban user": "Неуспех при забрањивању приступа кориснику", "Failed to mute user": "Неуспех при пригушивању корисника", "Failed to toggle moderator status": "Неуспех при промени стања модератора", - "Failed to change power level": "Неуспех при промени нивоа моћи" + "Failed to change power level": "Неуспех при промени нивоа моћи", + "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Нећете моћи да опозовете ове промене зато што снижавате себе, ако сте последњи овлашћени корисник у соби, немогуће је да поново добијете овлашћења.", + "Are you sure?": "Да ли сте сигурни?", + "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Нећете моћи да опозовете ову измену јер унапређујете корисника тако да има исти ниво моћи као и ви.", + "No devices with registered encryption keys": "Нема уређаја са регистрованим кључевима за шифровање", + "Devices": "Уређаји", + "Unignore": "Не занемаруј више", + "Ignore": "Занемари", + "Jump to read receipt": "Скочи на потврду о прочитаности", + "Mention": "Спомени", + "Invite": "Позови", + "User Options": "Корисничке опције", + "Direct chats": "Директна ћаскања", + "Unmute": "Појачај", + "Mute": "Утишај", + "Revoke Moderator": "Опозови модератора", + "Make Moderator": "Учини модератором", + "Admin Tools": "Админ алатке", + "Level:": "Ниво:", + "and %(count)s others...|other": "и %(count)s других...", + "and %(count)s others...|one": "и још један други...", + "Invited": "Позван", + "Filter room members": "Филтрирај чланове собе", + "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (моћ %(powerLevelNumber)s)", + "Attachment": "Прилог", + "Upload Files": "Отпреми датотеке", + "Are you sure you want to upload the following files?": "Да ли сте сигурни да желите да отпремите следеће датотеке?", + "Encrypted room": "Шифрована соба", + "Unencrypted room": "Нешифрована соба", + "Hangup": "Спусти слушалицу", + "Voice call": "Гласовни позив", + "Video call": "Видео позив", + "Hide Apps": "Сакриј апликације", + "Show Apps": "Прикажи апликације", + "Upload file": "Отпреми датотеку", + "Show Text Formatting Toolbar": "Прикажи алатницу за форматирање текста", + "Send an encrypted reply…": "Пошаљи шифровани одговор…", + "Send a reply (unencrypted)…": "Пошаљи одговор (нешифровани)…", + "Send an encrypted message…": "Пошаљи шифровану поруку…", + "Send a message (unencrypted)…": "Пошаљи поруку (нешифровану)…", + "You do not have permission to post to this room": "Немате овлашћење за писање у овој соби", + "Turn Markdown on": "Укључи Маркдаун", + "Turn Markdown off": "Искључи Маркдаун", + "Hide Text Formatting Toolbar": "Сакриј алатницу за форматирање текста", + "Server error": "Грешка на серверу", + "Server unavailable, overloaded, or something else went wrong.": "Сервер није доступан или је преоптерећен или је нешто пошло наопако.", + "Command error": "Грешка у наредби", + "bold": "подебљано", + "italic": "искошено", + "strike": "прецртано", + "underline": "подвучено", + "code": "код", + "quote": "цитат", + "bullet": "списак", + "numbullet": "бројевни_списак", + "Markdown is disabled": "Маркдаун је искључен", + "Markdown is enabled": "Маркдаун је укључен", + "Unpin Message": "Откачи поруку", + "Jump to message": "Скочи на поруку", + "No pinned messages.": "Нема закачених порука.", + "Loading...": "Учитавам...", + "Pinned Messages": "Закачене поруке", + "%(duration)ss": "%(duration)sс", + "%(duration)sm": "%(duration)sм", + "%(duration)sh": "%(duration)sч", + "%(duration)sd": "%(duration)sд", + "Online for %(duration)s": "На мрежи %(duration)s", + "Idle for %(duration)s": "У мировању %(duration)s", + "Offline for %(duration)s": "Ван мреже %(duration)s", + "Unknown for %(duration)s": "Непознато већ %(duration)s", + "Online": "На мрежи", + "Idle": "У мировању", + "Offline": "Ван мреже", + "Unknown": "Непознато", + "Replying": "Одговара", + "Seen by %(userName)s at %(dateTime)s": "Видео корисник %(userName)s у %(dateTime)s", + "No rooms to show": "Нема соба за приказ", + "Unnamed room": "Неименована соба", + "World readable": "Читљиво за све", + "Guests can join": "Гости могу приступити", + "Failed to set avatar.": "Нисам успео да поставим аватар.", + "Save": "Сачувај", + "(~%(count)s results)|other": "(~%(count)s резултата)", + "(~%(count)s results)|one": "(~%(count)s резултат)", + "Join Room": "Приступи соби", + "Upload avatar": "Отпреми аватара", + "Remove avatar": "Уклони аватара", + "Settings": "Подешавања", + "Forget room": "Заборави собу", + "Search": "Претрага", + "Show panel": "Прикажи површ", + "Drop here to favourite": "Пусти овде да учиниш омиљеним", + "Drop here to tag direct chat": "Пусти овде да означиш директно ћаскање", + "Drop here to restore": "Пусти овде да опоравиш", + "Drop here to demote": "Пусти овде да унизиш", + "Drop here to tag %(section)s": "Пусти овде да означиш %(section)s", + "Press to start a chat with someone": "Притисни за започињање ћаскања са неким", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Још нисте у било којој соби! Притисните да бисте направили собу или да бисте погледали фасциклу", + "Community Invites": "Позивнице заједнице", + "Invites": "Позивнице", + "Favourites": "Омиљено", + "People": "Особе", + "Rooms": "Собе", + "Low priority": "Ниска важност", + "Historical": "Историјско", + "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Не могу да утврдим да ли се адреса на овој позивници поклапа са оном која је повезана са вашим налогом.", + "This invitation was sent to an email address which is not associated with this account:": "Ова позивница је послата на мејл адресу која није повезана са вашим налогом:", + "You may wish to login with a different account, or add this email to this account.": "Можда бисте желели да се пријавите са другим налогом или да додате овај мејл у ваш налог.", + "You have been invited to join this room by %(inviterName)s": "Позвани сте да приступите овој соби од стране корисника %(inviterName)s" } From 899192b0197a50279bbbe831496c8a2f45873a32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Mon, 22 Jan 2018 20:43:11 +0000 Subject: [PATCH 0185/1160] Translated using Weblate (French) Currently translated at 100.0% (984 of 984 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index cff37c3d70..b9d2ef7d89 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -983,5 +983,6 @@ "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s %(day)s %(monthName)s %(fullYear)s", "This room is not public. You will not be able to rejoin without an invite.": "Ce salon n'est pas public. Vous ne pourrez pas y revenir sans invitation.", "Community IDs cannot not be empty.": "Les identifiants de communauté ne peuvent pas être vides.", - "Show devices, send anyway or cancel.": "Afficher les appareils, envoyer quand même ou annuler." + "Show devices, send anyway or cancel.": "Afficher les appareils, envoyer quand même ou annuler.", + "In reply to ": "En réponse à " } From 00f52edf4ca1e7f0cce69b8d75410ae7a1954ab2 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Tue, 23 Jan 2018 05:16:28 +0000 Subject: [PATCH 0186/1160] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (984 of 984 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hant/ --- src/i18n/strings/zh_Hant.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index bae5c33be9..8333ce746c 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -982,5 +982,6 @@ "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s", "This room is not public. You will not be able to rejoin without an invite.": "這個聊天室並未公開。您在沒有邀請的情況下將無法重新加入。", "Community IDs cannot not be empty.": "社群 ID 不能為空。", - "Show devices, send anyway or cancel.": "顯示裝置無論如何都要傳送取消。" + "Show devices, send anyway or cancel.": "顯示裝置無論如何都要傳送取消。", + "In reply to ": "回覆給 " } From dd4cef4c3e2c2f7a5444cf6eddee1b3fea8e851c Mon Sep 17 00:00:00 2001 From: Andrey Date: Mon, 22 Jan 2018 18:31:43 +0000 Subject: [PATCH 0187/1160] Translated using Weblate (Russian) Currently translated at 100.0% (984 of 984 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 6ddc92b928..9ea84961c8 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -983,5 +983,6 @@ "Whether or not you're using the Richtext mode of the Rich Text Editor": "Независимо от того, используете ли вы режим Richtext в редакторе Rich Text Editor", "This room is not public. You will not be able to rejoin without an invite.": "Эта комната не является публичной. Вы не сможете войти без приглашения.", "Show devices, send anyway or cancel.": "Показать устройства, отправить в любом случае или отменить.", - "Community IDs cannot not be empty.": "ID сообществ не могут быть пустыми." + "Community IDs cannot not be empty.": "ID сообществ не могут быть пустыми.", + "In reply to ": "В ответ на " } From 3060ec10535e1be1850b809c24c18d97eea24b9b Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 25 Jan 2018 09:54:31 +0000 Subject: [PATCH 0188/1160] Use invite_3pid prop of createRoom instead of manual invite after create Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/RoomInvite.js | 13 ++++++++++--- src/createRoom.js | 13 ++++++++++++- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/RoomInvite.js b/src/RoomInvite.js index 1979c6d111..31541148d9 100644 --- a/src/RoomInvite.js +++ b/src/RoomInvite.js @@ -85,9 +85,7 @@ function _onStartChatFinished(shouldInvite, addrs) { if (rooms.length > 0) { // A Direct Message room already exists for this user, so select a // room from a list that is similar to the one in MemberInfo panel - const ChatCreateOrReuseDialog = sdk.getComponent( - "views.dialogs.ChatCreateOrReuseDialog", - ); + const ChatCreateOrReuseDialog = sdk.getComponent("views.dialogs.ChatCreateOrReuseDialog"); const close = Modal.createTrackedDialog('Create or Reuse', '', ChatCreateOrReuseDialog, { userId: addrTexts[0], onNewDMClick: () => { @@ -115,6 +113,15 @@ function _onStartChatFinished(shouldInvite, addrs) { }); }); } + } else if (addrTexts.length === 1) { + // Start a new DM chat + createRoom({dmUserId: addrTexts[0]}).catch((err) => { + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + Modal.createTrackedDialog('Failed to invite user', '', ErrorDialog, { + title: _t("Failed to invite user"), + description: ((err && err.message) ? err.message : _t("Operation failed")), + }); + }); } else { // Start multi user chat let room; diff --git a/src/createRoom.js b/src/createRoom.js index ffe3a85c4e..a767d09288 100644 --- a/src/createRoom.js +++ b/src/createRoom.js @@ -22,6 +22,7 @@ import dis from "./dispatcher"; import * as Rooms from "./Rooms"; import Promise from 'bluebird'; +import {getAddressType} from "./UserAddress"; /** * Create a new room, and switch to it. @@ -52,7 +53,17 @@ function createRoom(opts) { createOpts.preset = createOpts.preset || defaultPreset; createOpts.visibility = createOpts.visibility || 'private'; if (opts.dmUserId && createOpts.invite === undefined) { - createOpts.invite = [opts.dmUserId]; + switch (getAddressType(opts.dmUserId)) { + case 'mx-user-id': + createOpts.invite = [opts.dmUserId]; + break; + case 'email': + createOpts.invite_3pid = [{ + id_server: MatrixClientPeg.get().getIdentityServerUrl(true), + medium: 'email', + address: opts.dmUserId, + }]; + } } if (opts.dmUserId && createOpts.is_direct === undefined) { createOpts.is_direct = true; From c86c12de40f2c522f16856d610ff4cda92d1e04e Mon Sep 17 00:00:00 2001 From: Osoitz Date: Mon, 22 Jan 2018 19:23:52 +0000 Subject: [PATCH 0189/1160] Translated using Weblate (Basque) Currently translated at 100.0% (984 of 984 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eu/ --- src/i18n/strings/eu.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index f1db7376e9..15c5e43d97 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -983,5 +983,6 @@ "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(fullYear)s(e)ko %(monthName)sk %(day)sa", "This room is not public. You will not be able to rejoin without an invite.": "Gela hau ez da publikoa. Ezin izango zara berriro elkartu gonbidapenik gabe.", "Community IDs cannot not be empty.": "Komunitate ID-ak ezin dira hutsik egon.", - "Show devices, send anyway or cancel.": "Erakutsi gailuak, bidali hala ere edo ezeztatu." + "Show devices, send anyway or cancel.": "Erakutsi gailuak, bidali hala ere edo ezeztatu.", + "In reply to ": "honi erantzunez: " } From 56bd4b7d06949a0d3cb11e2e15acd7c2edd00e19 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 25 Jan 2018 12:18:02 +0000 Subject: [PATCH 0190/1160] Fix not showing Invited section if all invites are 3PID Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/MemberList.js | 56 +++++++++++++----------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/src/components/views/rooms/MemberList.js b/src/components/views/rooms/MemberList.js index 04b6089559..1c5eba7fbc 100644 --- a/src/components/views/rooms/MemberList.js +++ b/src/components/views/rooms/MemberList.js @@ -315,6 +315,30 @@ module.exports = React.createClass({ }); }, + _getPending3PidInvites: function() { + // include 3pid invites (m.room.third_party_invite) state events. + // The HS may have already converted these into m.room.member invites so + // we shouldn't add them if the 3pid invite state key (token) is in the + // member invite (content.third_party_invite.signed.token) + const room = MatrixClientPeg.get().getRoom(this.props.roomId); + + if (room) { + return room.currentState.getStateEvents("m.room.third_party_invite").filter(function(e) { + // any events without these keys are not valid 3pid invites, so we ignore them + const requiredKeys = ['key_validity_url', 'public_key', 'display_name']; + for (let i = 0; i < requiredKeys.length; ++i) { + if (e.getContent()[requiredKeys[i]] === undefined) return false; + } + + // discard all invites which have a m.room.member event since we've + // already added them. + const memberEvent = room.currentState.getInviteForThreePidToken(e.getStateKey()); + if (memberEvent) return false; + return true; + }); + } + }, + _makeMemberTiles: function(members, membership) { const MemberTile = sdk.getComponent("rooms.MemberTile"); @@ -329,33 +353,13 @@ module.exports = React.createClass({ // Double XXX: Now it's really, really not the right home for this logic: // we shouldn't even be passing in the 'membership' param to this function. // Ew, ew, and ew. + // Triple XXX: This violates the size constraint, the output is expected/desired + // to be the same length as the members input array. if (membership === "invite") { - // include 3pid invites (m.room.third_party_invite) state events. - // The HS may have already converted these into m.room.member invites so - // we shouldn't add them if the 3pid invite state key (token) is in the - // member invite (content.third_party_invite.signed.token) - const room = MatrixClientPeg.get().getRoom(this.props.roomId); const EntityTile = sdk.getComponent("rooms.EntityTile"); - if (room) { - room.currentState.getStateEvents("m.room.third_party_invite").forEach( - function(e) { - // any events without these keys are not valid 3pid invites, so we ignore them - const required_keys = ['key_validity_url', 'public_key', 'display_name']; - for (let i = 0; i < required_keys.length; ++i) { - if (e.getContent()[required_keys[i]] === undefined) return; - } - - // discard all invites which have a m.room.member event since we've - // already added them. - const memberEvent = room.currentState.getInviteForThreePidToken(e.getStateKey()); - if (memberEvent) { - return; - } - memberList.push( - , - ); - }); - } + memberList.push(...this._getPending3PidInvites().map((e) => { + return ; + })); } return memberList; @@ -374,7 +378,7 @@ module.exports = React.createClass({ }, _getChildCountInvited: function() { - return this.state.filteredInvitedMembers.length; + return this.state.filteredInvitedMembers.length + (this._getPending3PidInvites() || []).length; }, render: function() { From e78659642e64997d969258fb79ece05e1e2e6401 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Tue, 23 Jan 2018 07:09:24 +0000 Subject: [PATCH 0191/1160] Translated using Weblate (Hungarian) Currently translated at 100.0% (984 of 984 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index da9de87695..f2aa17c764 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -983,5 +983,6 @@ "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(fullYear)s. %(monthName)s %(day)s, %(weekDayName)s", "This room is not public. You will not be able to rejoin without an invite.": "Ez a szoba nem nyilvános. Kilépés után csak újabb meghívóval tudsz újra belépni a szobába.", "Show devices, send anyway or cancel.": "Eszközök listája, mindenképpen küld vagy szakítsd meg.", - "Community IDs cannot not be empty.": "A közösségi azonosító nem lehet üres." + "Community IDs cannot not be empty.": "A közösségi azonosító nem lehet üres.", + "In reply to ": "Válaszolva neki " } From 9223a5db9eb24dae8f1066a29ded8d021cff26d0 Mon Sep 17 00:00:00 2001 From: d1d4c Date: Thu, 25 Jan 2018 16:13:04 +0000 Subject: [PATCH 0192/1160] Translated using Weblate (Catalan) Currently translated at 83.6% (823 of 984 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ca/ --- src/i18n/strings/ca.json | 309 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 299 insertions(+), 10 deletions(-) diff --git a/src/i18n/strings/ca.json b/src/i18n/strings/ca.json index 342996513a..b5bca7d912 100644 --- a/src/i18n/strings/ca.json +++ b/src/i18n/strings/ca.json @@ -105,7 +105,7 @@ "Add to community": "Afegeix a la comunitat", "Failed to invite the following users to %(groupId)s:": "No s'ha pogut convidar al grup %(groupId)s els següents usuaris:", "Failed to invite users to community": "No s'ha pogut convidar als usuaris a la comunitat", - "Failed to invite users to %(groupId)s": "No s'ha pogut convidar als usuaris al grup %(groupId)s", + "Failed to invite users to %(groupId)s": "No s'ha pogut convidar els usuaris al grup %(groupId)s", "Failed to add the following rooms to %(groupId)s:": "No s'ha pogut afegir al grup %(groupId)s les següents sales:", "Riot does not have permission to send you notifications - please check your browser settings": "Riot no té permís per enviar-vos notificacions. Comproveu la configuració del vostre navegador", "Riot was not given permission to send notifications - please try again": "Riot no ha rebut cap permís per enviar notificacions. Torneu-ho a provar", @@ -151,7 +151,7 @@ "WARNING: Device already verified, but keys do NOT MATCH!": "AVÍS: El dispositiu ja estava verificat, però les claus NO COINCIDIEN!", "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!": "AVÍS: NO S'HA POGUT VERIFICAR! La firma de la clau de l'usuari %(userId)s i el dispositiu %(deviceId)s és \"%(fprint)s\", però no coincideix amb la clau \"%(fingerprint)s\". Això pot significar que les vostres comunicacions estan sent interceptades!", "Verified key": "Claus verificades", - "Call Timeout": "La trucada ha esgotat el temps d'espera", + "Call Timeout": "Temps d'espera de les trucades", "Unknown (user, device) pair:": "Parell desconegut (usuari, dispositiu):", "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "La clau de signatura que heu proporcionat coincideix amb la clau de signatura que heu rebut del dispositiu %(deviceId)s de l'usuari %(userId)s. S'ha marcat el dispositiu com a dispositiu verificat.", "Unrecognised command:": "Ordre no reconegut:", @@ -219,7 +219,7 @@ "Tag Panel": "Tauler d'etiquetes", "Disable Emoji suggestions while typing": "Desactiva els suggeriments d'Emoji mentre s'escriu", "Use compact timeline layout": "Utilitza el disseny compacte de la línia de temps", - "Hide join/leave messages (invites/kicks/bans unaffected)": "Amaga els missatges de entrada i sortida (no afecta a invitacions, expulsions o prohibicions)", + "Hide join/leave messages (invites/kicks/bans unaffected)": "Amaga els missatges d'entrada i sortida (no afecta a les invitacions, expulsions o prohibicions)", "Hide avatar changes": "Amaga els canvis de foto de perfil", "Hide display name changes": "Amaga els canvis de nom visible", "Hide read receipts": "Amaga els rebuts llegits", @@ -329,7 +329,7 @@ "and %(count)s others...|other": "i %(count)s altres...", "and %(count)s others...|one": "i un altre...", "Invited": "Convidat", - "Filter room members": "Filtre de membres de sala", + "Filter room members": "Filtra membres de sala", "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (poder %(powerLevelNumber)s)", "Attachment": "Adjunt", "Upload Files": "Puja fitxers", @@ -353,7 +353,7 @@ "Hide Text Formatting Toolbar": "Amaga la barra d'eines de format de text", "Server error": "S'ha produït un error al servidor", "Mirror local video feed": "Mostra el vídeo local com un mirall", - "Opt out of analytics": "Opcions fora d'anàlisi", + "Opt out of analytics": "No acceptis analítiques", "Server unavailable, overloaded, or something else went wrong.": "El servidor no està disponible, està sobrecarregat o alguna altra cosa no ha funcionat correctament.", "Command error": "S'ha produït un error en l'ordre", "bold": "negreta", @@ -408,7 +408,7 @@ "Historical": "Històric", "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "No s'ha pogut determinar que s'hagi enviat la invitació des de una adreça associada al vostre compte.", "This invitation was sent to an email address which is not associated with this account:": "Aquesta invitació s'ha enviat a una adreça de correu electrònic que no està associada a aquest compte:", - "Press to start a chat with someone": "Premeu per a iniciar un xat amb algú", + "Press to start a chat with someone": "Prem per a començar un xat amb algú", "You may wish to login with a different account, or add this email to this account.": "És possible que vulgueu iniciar la sessió amb un altre compte o bé afegir aquest correu electrònic a aquest compte.", "You have been invited to join this room by %(inviterName)s": "Heu sigut convidat a aquesta sala per %(inviterName)s", "Would you like to accept or decline this invitation?": "Voleu accept o bé declineText>decline aquesta invitació?", @@ -454,11 +454,11 @@ "Leave room": "Surt de la sala", "Tagged as: ": "Etiquetats com: ", "To link to a room it must have an address.": "Per poder fer un enllaç a una sala aquesta ha de tenir an address.", - "Guests cannot join this room even if explicitly invited.": "Els usuaris d'altres xarxes no poden entrar a la sala d'aquest esdeveniment, encara que hi hagin sigut convidats de forma explícita.", + "Guests cannot join this room even if explicitly invited.": "Els usuaris d'altres xarxes no poden entrar a la sala d'aquest esdeveniment encara que hi hagin sigut convidats de forma explícita.", "Click here to fix": "Feu clic aquí per corregir-ho", "Who can access this room?": "Qui pot entrar a aquesta sala?", "Only people who have been invited": "Només les persones que hi hagin sigut convidades", - "Anyone who knows the room's link, apart from guests": "Qualsevol que conegui l'enllaç de la sala, excepte els usuaris d'altres xarxes", + "Anyone who knows the room's link, apart from guests": "Qualsevol que conegui l'enllaç de la sala, excepte usuaris d'altres xarxes", "Publish this room to the public in %(domain)s's room directory?": "Voleu que es publiqui aquesta sala al directori de sales públiques de %(domain)s?", "Who can read history?": "Qui pot llegir l'historial?", "Anyone": "Qualsevol", @@ -481,7 +481,7 @@ "Invalid alias format": "El format de l'àlies no és vàlid", "'%(alias)s' is not a valid format for an alias": "'%(alias)s' no és un format d'àlies vàlid", "Invalid address format": "L'adreça no té un format vàlid", - "Anyone who knows the room's link, including guests": "Qualsevol que conegui l'enllaç, inclosos els usuaris d'altres xarxes", + "Anyone who knows the room's link, including guests": "Qualsevol que conegui l'enllaç de la sala, inclosos els usuaris d'altres xarxes", "'%(alias)s' is not a valid format for an address": "'%(alias)s' no és un format vàlid per a una adreça", "not specified": "sense especificar", "not set": "sense definir", @@ -532,5 +532,294 @@ "Start authentication": "Inicia l'autenticació", "Username on %(hs)s": "Nom d'usuari a %(hs)s", "User name": "Nom d'usuari", - "Mobile phone number": "Número de telèfon mòbil" + "Mobile phone number": "Número de telèfon mòbil", + "Forgot your password?": "Heu oblidat la vostra contrasenya?", + "%(serverName)s Matrix ID": "ID de Matrix de %(serverName)s", + "Sign in with": "Inicieu sessió amb", + "Email address": "Correu electrònic", + "Sign in": "Inicia sessió", + "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Si no especifiqueu una adreça de correu electrònic, no podreu restablir la vostra contrasenya. N'esteu segur?", + "Email address (optional)": "Correu electrònic (opcional)", + "You are registering with %(SelectedTeamName)s": "Esteu registrant-vos amb %(SelectedTeamName)s", + "Mobile phone number (optional)": "Número de telèfon mòbil (opcional)", + "Default server": "Servidor per defecte", + "Custom server": "Servidor personalitzat", + "Identity server URL": "URL del servidor d'identitat", + "What does this mean?": "Què vol dir això?", + "Remove from community": "Elimina de la comunitat", + "Disinvite this user from community?": "Voleu retirar la invitació de aquest usuari a la comunitat?", + "Remove this user from community?": "Voleu eliminar de la comunitat a aquest usuari?", + "Failed to withdraw invitation": "No s'ha pogut retirar la invitació", + "Failed to remove user from community": "No s'ha pogut treure l'usuari de la comunitat", + "Filter community members": "Filtra membres de comunitat", + "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Esteu segur que voleu treure l'usuari '%(roomName)s' del grup %(groupId)s?", + "Home server URL": "URL del servidor d'origen", + "In reply to ": "In reply to ", + "Removing a room from the community will also remove it from the community page.": "L'eliminació d'una sala de la comunitat també l'eliminarà de la pàgina de la comunitat.", + "Failed to remove room from community": "No s'ha pogut eliminar la sala de la comunitat", + "Failed to remove '%(roomName)s' from %(groupId)s": "No s'ha pogut treure la sala '%(roomName)s' de la comunitat %(groupId)s", + "Something went wrong!": "Alguna cosa ha anat malament!", + "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "No s'ha pogut actualitzar la visibilitat de la sala '%(roomName)s' de la comunitat %(groupId)s.", + "Visibility in Room List": "Visibilitat a la llista de les sales", + "Visible to everyone": "Visible per a tothom", + "Only visible to community members": "Només visible per als membres de la comunitat", + "Filter community rooms": "Filtra sales de comunitats", + "Something went wrong when trying to get your communities.": "S'ha produït un error en intentar obtenir les vostres comunitats.", + "You're not currently a member of any communities.": "Actualment no sou membre de cap comunitat.", + "Unknown Address": "Adreça desconeguda", + "NOTE: Apps are not end-to-end encrypted": "NOTA: Les aplicacions no estan encriptades d'extrem a extrem", + "Do you want to load widget from URL:": "Carregar ginys des de l'URL:", + "Allow": "Permetre", + "Delete Widget": "Suprimeix el giny", + "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "La supressió d'un giny l'elimina per a tots els usuaris d'aquesta sala. Esteu segur que voleu eliminar aquest giny?", + "Delete widget": "Suprimeix el giny", + "Revoke widget access": "Revoca l'accés del giny", + "Minimize apps": "Minimitza les aplicacions", + "Blacklist": "Llista negre", + "Unverify": "Sense verificar", + "Verify...": "S'està verificant...", + "No results": "Sense resultats", + "Delete": "Esborra", + "Communities": "Comunitats", + "Home": "Inici", + "Integrations Error": "S'ha produït un error d'integració", + "Could not connect to the integration server": "No s'ha pogut connectar amb el servidor de l'integració", + "Manage Integrations": "Gestiona les integracions", + "%(nameList)s %(transitionList)s": "%(transitionList)s%(nameList)s", + "%(severalUsers)sjoined %(count)s times|one": "%(severalUsers)s han entrat", + "Guest access is disabled on this Home Server.": "L'accés a usuaris d'altres xarxes no està permès en aquest servidor.", + "Login as guest": "Inicia sessió com a convidat", + "Unblacklist": "Treure de la llista negre", + "%(oneUser)sjoined %(count)s times|one": "%(oneUser)s s'ha unit", + "%(severalUsers)sleft %(count)s times|one": "%(severalUsers)s han sortit", + "%(oneUser)sleft %(count)s times|one": "%(oneUser)s ha sortit", + "%(severalUsers)sjoined and left %(count)s times|other": "%(severalUsers)s s'han unit i han sortit %(count)s vegades", + "%(severalUsers)sjoined and left %(count)s times|one": "%(severalUsers)s s'han unit i han sortit", + "%(oneUser)sjoined and left %(count)s times|other": "%(oneUser)s ha entrat i ha sortit %(count)s vegades", + "%(oneUser)sjoined and left %(count)s times|one": "%(oneUser)s ha entrat i ha sortit", + "%(severalUsers)sleft and rejoined %(count)s times|other": "%(severalUsers)s han sortit i han tornat a entrar %(count)s vegades", + "%(severalUsers)sleft and rejoined %(count)s times|one": "%(severalUsers)s han sortit i han tornat a entrar", + "%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)s ha sortit i ha tornat a entrar %(count)s vegades", + "%(oneUser)sleft and rejoined %(count)s times|one": "%(oneUser)s ha sortit i ha tornat a entrar", + "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)s han rebutjat les seves invitacions %(count)s vegades", + "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)s han rebutjat les seves invitacions", + "%(oneUser)srejected their invitation %(count)s times|other": "%(oneUser)s ha rebutjat la seva invitació %(count)s vegades", + "%(oneUser)srejected their invitation %(count)s times|one": "%(oneUser)s ha rebutjat la seva invitació", + "%(severalUsers)shad their invitations withdrawn %(count)s times|other": "a %(severalUsers)s els hi han retirat les seves invitacions %(count)s vegades", + "%(severalUsers)shad their invitations withdrawn %(count)s times|one": "a %(severalUsers)s els hi han retirat les seves invitacions", + "%(oneUser)shad their invitation withdrawn %(count)s times|other": "a %(oneUser)s li han retirat la seva invitació %(count)s vegades", + "%(oneUser)shad their invitation withdrawn %(count)s times|one": "a %(oneUser)s li han retirat la seva invitació", + "were invited %(count)s times|other": "a sigut invitat %(count)s vegades", + "were invited %(count)s times|one": "han sigut convidats", + "was invited %(count)s times|other": "ha sigut convidat %(count)s vegades", + "was invited %(count)s times|one": "ha sigut convidat", + "were banned %(count)s times|other": "han sigut expulsats %(count)s vegades", + "were banned %(count)s times|one": "ha sigut expulsat", + "was banned %(count)s times|other": "ha sigut expulsat %(count)s vegades", + "was banned %(count)s times|one": "ha sigut expulsat", + "were unbanned %(count)s times|other": "han sigut readmesos %(count)s vegades", + "were unbanned %(count)s times|one": "han sigut readmesos", + "was unbanned %(count)s times|other": "ha sigut readmès %(count)s vegades", + "was unbanned %(count)s times|one": "ha sigut readmès", + "were kicked %(count)s times|other": "els han fet fora %(count)s vegades", + "were kicked %(count)s times|one": "els han fet fora", + "was kicked %(count)s times|other": "l'han fet fora %(count)s vegades", + "was kicked %(count)s times|one": "l'han fet fora", + "%(severalUsers)schanged their name %(count)s times|other": "%(severalUsers)s han canviat el seu nom %(count)s vegades", + "%(severalUsers)schanged their name %(count)s times|one": "%(severalUsers)s han canviat el seu nom", + "%(oneUser)schanged their name %(count)s times|other": "%(oneUser)s han canviat el seu nom %(count)s vegades", + "%(oneUser)schanged their name %(count)s times|one": "%(oneUser)s ha canviat el seu nom", + "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)s han canviat el seu avatar %(count)s vegades", + "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)s han canviat el seu avatar", + "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)s han canviat el seu avatar %(count)s vegades", + "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)s ha canviat el seu avatar", + "%(items)s and %(count)s others|other": "%(items)s i %(count)s altres", + "%(items)s and %(count)s others|one": "%(items)s i un altre", + "%(items)s and %(lastItem)s": "%(items)s i %(lastItem)s", + "collapse": "col·lapsa", + "expand": "expandeix", + "Custom of %(powerLevel)s": "Personalitzat de %(powerLevel)s", + "Custom level": "Nivell personalitzat", + "And %(count)s more...|other": "I %(count)s més...", + "ex. @bob:example.com": "per exemple @carles:exemple.cat", + "Add User": "Afegeix un usuari", + "Matrix ID": "ID de Matrix", + "Matrix Room ID": "ID de sala de Matrix", + "email address": "correu electrònic", + "Try using one of the following valid address types: %(validTypesList)s.": "Proveu d'utilitzar un dels següents tipus d'adreça vàlids: %(validTypesList)s.", + "You have entered an invalid address.": "No heu introduït una adreça vàlida.", + "Create a new chat or reuse an existing one": "Creeu un xat nou o feu-ne servit un d'existent", + "Start new chat": "Inicia un nou xat", + "You already have existing direct chats with this user:": "Ja teniu xats directes amb aquest usuari:", + "Start chatting": "Comença a xerrar", + "Click on the button below to start chatting!": "Feu clic al botó de sota per començar a xerrar!", + "Start Chatting": "Comenceu a xatejar", + "Confirm Removal": "Confirmeu l'eliminació", + "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Esteu segur que voleu eliminar (suprimir) aquest esdeveniment? Tingueu en compte que si suprimiu un nom sala o si feu un canvi de tema, desfaria el canvi.", + "This room is not showing flair for any communities": "Aquesta sala no mostra talent per a cap comunitat", + "Flair": "Talents", + "Showing flair for these communities:": "Mostra els talents d'aquestes comunitats:", + "Flair will appear if enabled in room settings": "Els talents es mostraran si són activats a la configuració de la sala", + "Flair will not appear": "Els talents no es mostraran", + "Display your community flair in rooms configured to show it.": "Mostra els talents de la vostra comunitat dins les sales configurades per a mostrar-los.", + "This Home Server would like to make sure you are not a robot": "Aquest servidor amfitrió es vol assegurar que no sou un robot", + "%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)s han entrat %(count)s vegades", + "%(oneUser)sjoined %(count)s times|other": "%(oneUser)s ha entrat %(count)s vegades", + "%(severalUsers)sleft %(count)s times|other": "%(severalUsers)s han sortit %(count)s vegades", + "%(oneUser)sleft %(count)s times|other": "%(oneUser)s ha sortit %(count)s vegades", + "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "Les ID de les comunitats només poden contendre caràcters a-z, 0-9, o '=_-./'", + "Community IDs cannot not be empty.": "Les ID de les comunitats no poden estar buides.", + "Something went wrong whilst creating your community": "S'ha produït un error al crear la vostra comunitat", + "Create Community": "Crea una comunitat", + "Community Name": "Nom de la comunitat", + "Example": "Exemple", + "Community ID": "ID de la comunitat", + "example": "exemple", + "Create": "Crea", + "Create Room": "Crea una sala", + "Room name (optional)": "Nom de la sala (opcional)", + "Advanced options": "Opcions avançades", + "This setting cannot be changed later!": "Aquests paràmetres no es poden canviar després!", + "Unknown error": "S'ha produït un error desconegut", + "Incorrect password": "Contrasenya incorrecta", + "Deactivate Account": "Desactivar el compte", + "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Això farà que el vostre compte no es pugui utilitzar mai més. No podreu tornar a registrar la mateixa identificació d'usuari.", + "This action is irreversible.": "Aquesta acció és irreversible.", + "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Per verificar que es pot confiar en aquest dispositiu, poseu-vos en contacte amb el propietari mitjançant altres mitjans (per exemple, en persona o amb una trucada telefònica) i pregunteu-li si la clau que veuen a la configuració del seu usuari, aquest dispositiu coincideix amb la següent clau:", + "Device name": "Nom del dispositiu", + "Device key": "Clau del dispositiu", + "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Si coincideix, premeu el botó de verificació de sota. Si no coincideix, algú més està interceptant aquest dispositiu i probablement voleu prémer el botó de llista negra.", + "In future this verification process will be more sophisticated.": "En un futur, aquest procés de verificació serà més sofisticat.", + "Verify device": "Verifica el dispositiu", + "I verify that the keys match": "Verifico que les claus coincideixen", + "An error has occurred.": "S'ha produït un error.", + "You added a new device '%(displayName)s', which is requesting encryption keys.": "Heu afegit el nou dispositiu '%(displayName)s', que està demanant les claus d'encriptació.", + "Your unverified device '%(displayName)s' is requesting encryption keys.": "El dispositiu no verificat '%(displayName)s' està demanat les claus d'encriptació.", + "Start verification": "Inicia la verificació", + "Share without verifying": "Comparteix sense verificar", + "Ignore request": "Ignora la sol·licitud", + "Loading device info...": "S'està carregant la informació del dispositiu...", + "Encryption key request": "Sol·licitud de claus", + "Otherwise, click here to send a bug report.": "D'una altra manera, click here per a enviar un informe d'error.", + "Unable to restore session": "No s'ha pogut restaurar la sessió", + "Continue anyway": "Continua de totes maneres", + "Invalid Email Address": "El correu electrònic no és vàlid", + "This doesn't appear to be a valid email address": "Aquest no sembla ser un correu electrònic vàlid", + "Verification Pending": "Verificació pendent", + "Please check your email and click on the link it contains. Once this is done, click continue.": "Reviseu el vostre correu electrònic i feu clic a l'enllaç que conté. Un cop fet això, feu clic a Continua.", + "Unable to add email address": "No s'ha pogut afegir el correu electrònic", + "Unable to verify email address.": "No s'ha pogut verificar el correu electrònic.", + "This will allow you to reset your password and receive notifications.": "Això us permetrà restablir la vostra contrasenya i rebre notificacions.", + "Skip": "Omet", + "User names may only contain letters, numbers, dots, hyphens and underscores.": "Els noms d'usuari només poden contenir lletres, números, punts, guionets i guionets baixos.", + "Username not available": "Aquest nom d'usuari no està disponible", + "Username invalid: %(errMessage)s": "El nom d'usuari és invàlid: %(errMessage)s", + "An error occurred: %(error_string)s": "S'ha produït un error: %(error_string)s", + "Username available": "Aquest nom d'usuari està disponible", + "To get started, please pick a username!": "Per començar, seleccioneu un nom d'usuari!", + "This will be your account name on the homeserver, or you can pick a different server.": "Aquest serà el nom del seu compte al servidor amfitrió, o bé trieu-ne un altre different server.", + "If you already have a Matrix account you can log in instead.": "Si ja teniu un compte a Matrix, podeu log in.", + "Block users on other matrix homeservers from joining this room": "Impedeix als usuaris d'altres servidors de Matrix d'entrar a aquesta sala", + "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Hem trobat un error en intentar restaurar la vostra sessió anterior. Si continueu, haureu d'iniciar la sessió de nou i l'historial de xat encriptat serà il·legible.", + "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Si anteriorment heu utilitzat un versió de Riot més recent, la vostra sessió podría ser incompatible amb aquesta versió. Tanqueu aquesta finestra i torneu a la versió més recent.", + "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Actualment teniu a la llista negre els dispositius no verificats; per enviar missatges a aquests dispositius, els heu de verificar abans.", + "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Recomanem que dugueu a terme el procès de verificació per a cada dispositiu per tal de confirmar que són del legítim propietari, però podeu enviar el missatge sense verificar-ho si ho preferiu.", + "Room contains unknown devices": "Hi ha dispositius desconeguts a la sala", + "\"%(RoomName)s\" contains devices that you haven't seen before.": "A la sala \"%(RoomName)s\" hi ha dispositius que no havíeu vist abans.", + "Unknown devices": "Dispositius desconeguts", + "Private Chat": "Xat privat", + "Public Chat": "Xat públic", + "Custom": "Personalitzat", + "Name": "Nom", + "Topic": "Tema", + "Make this room private": "Fes que aquesta sala sigui privada", + "Share message history with new users": "Comparteix l'historial dels missatges amb els nous usuaris", + "Encrypt room": "Sala encriptada", + "You must register to use this functionality": "Heu de register per utilitzar aquesta funcionalitat", + "You must join the room to see its files": "Heu d'entrar a la sala per poder-ne veure els fitxers", + "There are no visible files in this room": "No hi ha fitxers visibles en aquesta sala", + "

    HTML for your community's page

    \n

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

    \n

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

    \n": "

    Aquest és l'HTML per a la pàgina de la vostra comunitat

    \n

    \n Utilitzeu la descripció llarga per a presentar la comunitat a nous membres,\n o per afegir-hi enlaços d'interès. \n

    \n

    \n També podeu utilitzar etiquetes 'img'.\n

    \n", + "Add rooms to the community summary": "Afegiu sales al resum de la comunitat", + "Which rooms would you like to add to this summary?": "Quines sales voleu afegir a aquest resum?", + "Add to summary": "Afegeix-ho al resum", + "Failed to add the following rooms to the summary of %(groupId)s:": "No s'ha pogut afegir al resum de la comunitat %(groupId)s les següents sales:", + "Add a Room": "Afegeix una sala", + "Failed to remove the room from the summary of %(groupId)s": "No s'ha pogut eliminar la sala del resum de la comunitat %(groupId)s", + "The room '%(roomName)s' could not be removed from the summary.": "La sala '%(roomName)s' no s'ha pogut eliminar del resum.", + "Add users to the community summary": "Afegeix usuaris al resum de la comunitat", + "Who would you like to add to this summary?": "A qui vol afegir a aquest resum?", + "Failed to add the following users to the summary of %(groupId)s:": "No s'ha pogut afegir al resum de la comunitat %(groupId)s, els següents usuaris:", + "Add a User": "Afegeix un usuari", + "Failed to remove a user from the summary of %(groupId)s": "No s'ha pogut eliminar l'usuari del resum de la comunitat %(groupId)s", + "The user '%(displayName)s' could not be removed from the summary.": "L'usuari '%(displayName)s' no s'ha pogut eliminar del resum.", + "Failed to upload image": "No s'ha pogut pujar la imatge", + "Failed to update community": "No s'ha pogut actualitzar la comunitat", + "Unable to accept invite": "No s'ha pogut acceptar la invitació", + "Unable to reject invite": "No s'ha pogut rebutjar la invitació", + "Leave Community": "Abandona la comunitat", + "Leave %(groupName)s?": "Voleu sortir de la comunitat %(groupName)s?", + "Leave": "Surt", + "Unable to leave room": "No s'ha pogut sortir de la sala", + "Community Settings": "Paràmetres de la comunitat", + "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Aquestes sales es mostren a la pàgina de la comunitat als seus membres i poden entrar-hi fent clic sobre elles.", + "Featured Rooms:": "Sales destacades:", + "Featured Users:": "Usuaris destacats:", + "%(inviter)s has invited you to join this community": "%(inviter)s vos convida a unir-vos a aquesta comunitat", + "You are an administrator of this community": "Sou un administrador d'aquesta comunitat", + "You are a member of this community": "Sou un membre d'aquesta comunitat", + "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?": "Esteu a punt de ser portat a un lloc de tercers perquè pugui autenticar-se amb el vostre compte per utilitzar-lo amb %(integrationsUrl)s. Voleu continuar?", + "Your community hasn't got a Long Description, a HTML page to show to community members.
    Click here to open settings and give it one!": "La vostra comunitat no té una descripció llarga, una pàgina HTML per mostrar als membres de la comunitat.
    Feu clic aquí per obrir la configuració i donar-ne una!", + "Long Description (HTML)": "Descripció llarga (HTML)", + "Description": "Descripció", + "Community %(groupId)s not found": "No s'ha pogut trobar la comunitat %(groupId)s", + "This Home server does not support communities": "Aquest servidor amfitrió no admet comunitats", + "Failed to load %(groupId)s": "No s'ha pogut carregar la comunitat %(groupId)s", + "Reject invitation": "Rebutja la invitació", + "Are you sure you want to reject the invitation?": "Esteu segur que voleu rebutjar la invitació?", + "Failed to reject invitation": "No s'ha pogut rebutjar la invitació", + "Are you sure you want to leave the room '%(roomName)s'?": "Esteu segur que voleu sortir de la sala '%(roomName)s'?", + "Failed to leave room": "No s'ha pogut sortir de la sala", + "For security, this session has been signed out. Please sign in again.": "Per seguretat, aquesta sessió s'ha tancat. Torna a iniciar la sessió.", + "Cryptography data migrated": "S'han migrat les dades criptogràfiques", + "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "S'ha realitzat una migració puntual de les dades criptogràfiques. L'encriptació d'extrem a extrem no funcionarà si torneu a una versió anterior de Riot. Si necessiteu utilitzar l'encriptació d'extrem a extrem en una versió anterior, primer sortiu de Riot. Per poder llegir l'historial dels missatges encriptats, exporteu i torneu a importar les vostres claus.", + "Old cryptography data detected": "S'han detectat dades de criptografia antigues", + "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "S'han detectat dades d'una versió antiga de Riot. Això pot provocar que l'encriptació d'extrem a extrem no funcioni correctament a la versió anterior. Els missatges encriptats d'extrem a extrem que s'han intercanviat recentment mentre s'utilitzava la versió anterior no es poden desencriptar en aquesta versió. També pot provocar que els missatges intercanviats amb aquesta versió fallin. Si teniu problemes, tanqueu-lo i torneu-ho a engegar. Per poder llegir l'historial dels missatges encriptats, exporteu i torneu a importar les vostres claus.", + "Logout": "Surt", + "Your Communities": "Les teves comunitats", + "Error whilst fetching joined communities": "S'ha produït un error en buscar comunitats unides", + "Create a new community": "Crea una nova comunitat", + "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Crea una comunitat per agrupar usuaris i sales! Creeu una pàgina d'inici personalitzada per definir el vostre espai a l'univers Matrix.", + "Join an existing community": "Uneix-te a una comunitat existent", + "To join an existing community you'll have to know its community identifier; this will look something like +example:matrix.org.": "Per unir-se a una comunitat existent, haureu de conèixer l'identificador de la comunitat; això es veurà com +exemple:matrix.org.", + "You have no visible notifications": "No teniu cap notificació visible", + "Scroll to bottom of page": "Desplaça't fins a la part inferior de la pàgina", + "Message not sent due to unknown devices being present": "El missatge no s'ha enviat perquè hi ha dispositius desconeguts presents", + "%(count)s of your messages have not been sent.|other": "Alguns dels vostres missatges no s'han enviat.", + "%(count)s of your messages have not been sent.|one": "El vostre missatge no s'ha enviat.", + "Warning": "Avís", + "Connectivity to the server has been lost.": "S'ha perdut la connectivitat amb el servidor.", + "Sent messages will be stored until your connection has returned.": "Els missatges enviats s'emmagatzemaran fins que la vostra connexió hagi tornat.", + "%(count)s new messages|other": "%(count)s nous missatges", + "%(count)s new messages|one": "%(count)s nou missatge", + "Active call": "Trucada activa", + "You seem to be uploading files, are you sure you want to quit?": "Sembla que s'està pujant fitxers, esteu segur que voleu sortir?", + "You seem to be in a call, are you sure you want to quit?": "Sembla que està en una trucada, estàs segur que vols sortir?", + "Failed to upload file": "No s'ha pogut pujar el fitxer", + "Server may be unavailable, overloaded, or the file too big": "El servidor pot estar no disponible, sobrecarregat o el fitxer és massa gran", + "Search failed": "No s'ha pogut cercar", + "Server may be unavailable, overloaded, or search timed out :(": "Pot ser que el servidor no estigui disponible, que estigui sobrecarregat o que s'ha esgotat el temps de cerca :(", + "No more results": "No hi ha més resultats", + "Unknown room %(roomId)s": "La sala %(roomId)s és desconeguda", + "Room": "Sala", + "Failed to save settings": "No s'ha pogut desar la configuració", + "Failed to reject invite": "No s'ha pogut rebutjar la invitació", + "Fill screen": "Emplena la pantalla", + "Click to unmute video": "Feu clic per activar el so de vídeo", + "Click to mute video": "Feu clic per desactivar el so de vídeo", + "Click to unmute audio": "Feu clic per activar el so", + "Click to mute audio": "Feu clic per desactivar el so", + "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "S'ha intentat carregar un punt específic dins la línia de temps d'aquesta sala, però no teniu permís per veure el missatge en qüestió.", + "Tried to load a specific point in this room's timeline, but was unable to find it.": "S'ha intentat carregar un punt específic de la línia de temps d'aquesta sala, però no s'ha pogut trobar.", + "Failed to load timeline position": "No s'ha pogut carregar aquesta posició de la línia de temps", + "Show devices, send anyway or cancel.": "Mostra els dispositius, envia de totes maneres o cancel·la." } From 38de8a129bdf5359714f5721ebcfa38195cdcda4 Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Thu, 25 Jan 2018 21:45:15 +0100 Subject: [PATCH 0193/1160] Add transaction capability to asyncActions for relating pending/success/failure actions. Particularly useful for mapping a failure to a pending action to roll back any optimistic updates. --- src/actions/actionCreators.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/actions/actionCreators.js b/src/actions/actionCreators.js index 0238eee8c0..697930414c 100644 --- a/src/actions/actionCreators.js +++ b/src/actions/actionCreators.js @@ -31,18 +31,30 @@ limitations under the License. * `${id}.pending` and either * `${id}.success` or * `${id}.failure`. + * + * The shape of each are: + * { action: '${id}.pending', request, asyncId } + * { action: '${id}.success', result, asyncId } + * { action: '${id}.failure', err, asyncId } + * + * where `request` is returned by `pendingFn`, result + * is the result of the promise returned by `fn` and + * `asyncId` is a unique ID for each dispatch of the + * asynchronous action. */ export function asyncAction(id, fn, pendingFn) { return (dispatch) => { + const asyncId = Math.random().toString(16).slice(2, 10); dispatch({ action: id + '.pending', request: typeof pendingFn === 'function' ? pendingFn() : undefined, + asyncId, }); fn().then((result) => { - dispatch({action: id + '.success', result}); + dispatch({action: id + '.success', result, asyncId}); }).catch((err) => { - dispatch({action: id + '.failure', err}); + dispatch({action: id + '.failure', err, asyncId}); }); }; } From 815f52587bd532bb916113fe205b3bbf2df6140b Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Thu, 25 Jan 2018 21:53:34 +0100 Subject: [PATCH 0194/1160] Move TagPanel out of LoggedInView (...and into LeftPanel in riot-web. Can we merge the projects yet?) --- src/components/structures/LoggedInView.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/structures/LoggedInView.js b/src/components/structures/LoggedInView.js index e97d9dd0a1..d7fe699156 100644 --- a/src/components/structures/LoggedInView.js +++ b/src/components/structures/LoggedInView.js @@ -208,7 +208,6 @@ const LoggedInView = React.createClass({ }, render: function() { - const TagPanel = sdk.getComponent('structures.TagPanel'); const LeftPanel = sdk.getComponent('structures.LeftPanel'); const RightPanel = sdk.getComponent('structures.RightPanel'); const RoomView = sdk.getComponent('structures.RoomView'); @@ -330,7 +329,6 @@ const LoggedInView = React.createClass({
    { topBar }
    - { SettingsStore.isFeatureEnabled("feature_tag_panel") ? :
    } Date: Thu, 25 Jan 2018 21:58:35 +0100 Subject: [PATCH 0195/1160] Remove DragDropContext from TagPanel and RoomList So that we can have one context that can handle DND between the TagPanel and RoomList. --- src/components/structures/TagPanel.js | 53 ++--- src/components/views/rooms/RoomList.js | 304 ++++++++----------------- 2 files changed, 118 insertions(+), 239 deletions(-) diff --git a/src/components/structures/TagPanel.js b/src/components/structures/TagPanel.js index 1cd3f04f9d..8c790edc03 100644 --- a/src/components/structures/TagPanel.js +++ b/src/components/structures/TagPanel.js @@ -20,12 +20,11 @@ import { MatrixClient } from 'matrix-js-sdk'; import TagOrderStore from '../../stores/TagOrderStore'; import GroupActions from '../../actions/GroupActions'; -import TagOrderActions from '../../actions/TagOrderActions'; import sdk from '../../index'; import dis from '../../dispatcher'; -import { DragDropContext, Droppable } from 'react-beautiful-dnd'; +import { Droppable } from 'react-beautiful-dnd'; const TagPanel = React.createClass({ displayName: 'TagPanel', @@ -82,22 +81,6 @@ const TagPanel = React.createClass({ dis.dispatch({action: 'view_create_group'}); }, - onTagTileEndDrag(result) { - // Dragged to an invalid destination, not onto a droppable - if (!result.destination) { - return; - } - - // Dispatch synchronously so that the TagPanel receives an - // optimistic update from TagOrderStore before the previous - // state is shown. - dis.dispatch(TagOrderActions.moveTag( - this.context.matrixClient, - result.draggableId, - result.destination.index, - ), true); - }, - render() { const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); const TintableSvg = sdk.getComponent('elements.TintableSvg'); @@ -112,24 +95,22 @@ const TagPanel = React.createClass({ />; }); return
    - - - { (provided, snapshot) => ( -
    - { tags } - { provided.placeholder } -
    - ) } -
    -
    + + { (provided, snapshot) => ( +
    + { tags } + { provided.placeholder } +
    + ) } +
    diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index ca1fccd1f5..d1ef6c2f2c 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -18,7 +18,6 @@ limitations under the License. 'use strict'; const React = require("react"); const ReactDOM = require("react-dom"); -import { DragDropContext } from 'react-beautiful-dnd'; import PropTypes from 'prop-types'; import { _t } from '../../../languageHandler'; const GeminiScrollbar = require('react-gemini-scrollbar'); @@ -33,8 +32,6 @@ const Receipt = require('../../../utils/Receipt'); import TagOrderStore from '../../../stores/TagOrderStore'; import GroupStoreCache from '../../../stores/GroupStoreCache'; -import Modal from '../../../Modal'; - const HIDE_CONFERENCE_CHANS = true; function phraseForSection(section) { @@ -278,103 +275,6 @@ module.exports = React.createClass({ this.forceUpdate(); }, - onRoomTileEndDrag: function(result) { - if (!result.destination) return; - - let newTag = result.destination.droppableId.split('_')[1]; - let prevTag = result.source.droppableId.split('_')[1]; - if (newTag === 'undefined') newTag = undefined; - if (prevTag === 'undefined') prevTag = undefined; - - const roomId = result.draggableId.split('_')[1]; - const room = MatrixClientPeg.get().getRoom(roomId); - - const newIndex = result.destination.index; - - // Evil hack to get DMs behaving - if ((prevTag === undefined && newTag === 'im.vector.fake.direct') || - (prevTag === 'im.vector.fake.direct' && newTag === undefined) - ) { - Rooms.guessAndSetDMRoom( - room, newTag === 'im.vector.fake.direct', - ).catch((err) => { - const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - console.error("Failed to set direct chat tag " + err); - Modal.createTrackedDialog('Failed to set direct chat tag', '', ErrorDialog, { - title: _t('Failed to set direct chat tag'), - description: ((err && err.message) ? err.message : _t('Operation failed')), - }); - }); - return; - } - - const hasChangedSubLists = result.source.droppableId !== result.destination.droppableId; - - let newOrder = null; - - // Is the tag ordered manually? - if (newTag && !newTag.match(/^(m\.lowpriority|im\.vector\.fake\.(invite|recent|direct|archived))$/)) { - const newList = Object.assign({}, this.state.lists[newTag]); - - // If the room was moved "down" (increasing index) in the same list we - // need to use the orders of the tiles with indices shifted by +1 - const offset = ( - newTag === prevTag && result.source.index < result.destination.index - ) ? 1 : 0; - - const prevOrder = newIndex === 0 ? - 0 : newList[offset + newIndex - 1].tags[newTag].order; - const nextOrder = newIndex === newList.length ? - 1 : newList[offset + newIndex].tags[newTag].order; - - newOrder = { - order: (prevOrder + nextOrder) / 2.0, - }; - } - - // More evilness: We will still be dealing with moving to favourites/low prio, - // but we avoid ever doing a request with 'im.vector.fake.direct`. - // - // if we moved lists, remove the old tag - if (prevTag && prevTag !== 'im.vector.fake.direct' && - hasChangedSubLists - ) { - // Optimistic update of what will happen to the room tags - delete room.tags[prevTag]; - - MatrixClientPeg.get().deleteRoomTag(roomId, prevTag).catch(function(err) { - const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - console.error("Failed to remove tag " + prevTag + " from room: " + err); - Modal.createTrackedDialog('Failed to remove tag from room', '', ErrorDialog, { - title: _t('Failed to remove tag %(tagName)s from room', {tagName: prevTag}), - description: ((err && err.message) ? err.message : _t('Operation failed')), - }); - }); - } - - // if we moved lists or the ordering changed, add the new tag - if (newTag && newTag !== 'im.vector.fake.direct' && - (hasChangedSubLists || newOrder) - ) { - // Optimistic update of what will happen to the room tags - room.tags[newTag] = newOrder; - - MatrixClientPeg.get().setRoomTag(roomId, newTag, newOrder).catch(function(err) { - const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - console.error("Failed to add tag " + newTag + " to room: " + err); - Modal.createTrackedDialog('Failed to add tag to room', '', ErrorDialog, { - title: _t('Failed to add tag %(tagName)s to room', {tagName: newTag}), - description: ((err && err.message) ? err.message : _t('Operation failed')), - }); - }); - } - - // Refresh to display the optimistic updates - this needs to be done in the - // same tick as the drag finishing otherwise the room will pop back to its - // previous position - hence no delayed refresh - this.refreshRoomList(); - }, - _delayedRefreshRoomList: new rate_limited_func(function() { this.refreshRoomList(); }, 500), @@ -749,116 +649,114 @@ module.exports = React.createClass({ const self = this; return ( - - -
    - + +
    + - + - + - + - + - { Object.keys(self.state.lists).map((tagName) => { - if (!tagName.match(/^(m\.(favourite|lowpriority)|im\.vector\.fake\.(invite|recent|direct|archived))$/)) { - return ; - } - }) } + { Object.keys(self.state.lists).map((tagName) => { + if (!tagName.match(/^(m\.(favourite|lowpriority)|im\.vector\.fake\.(invite|recent|direct|archived))$/)) { + return ; + } + }) } - + - -
    -
    - + +
    +
    ); }, }); From 701abb6a219cb278dc992c4761ef58d366e29743 Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Thu, 25 Jan 2018 22:16:03 +0100 Subject: [PATCH 0196/1160] Move management of room lists to RoomListStore this is part maintenance to make RoomList clearer and part allowing room list state to be modified via a dispatch. --- src/actions/MatrixActionCreators.js | 5 + src/actions/RoomListActions.js | 142 +++++++++++++++++ src/components/views/rooms/RoomList.js | 91 +++-------- src/stores/RoomListStore.js | 212 +++++++++++++++++++++++++ 4 files changed, 383 insertions(+), 67 deletions(-) create mode 100644 src/actions/RoomListActions.js create mode 100644 src/stores/RoomListStore.js diff --git a/src/actions/MatrixActionCreators.js b/src/actions/MatrixActionCreators.js index 33bdb53799..d9309d7c1c 100644 --- a/src/actions/MatrixActionCreators.js +++ b/src/actions/MatrixActionCreators.js @@ -62,6 +62,10 @@ function createAccountDataAction(matrixClient, accountDataEvent) { }; } +function createRoomTagsAction(matrixClient, roomTagsEvent, room) { + return { action: 'MatrixActions.Room.tags', room }; +} + /** * This object is responsible for dispatching actions when certain events are emitted by * the given MatrixClient. @@ -78,6 +82,7 @@ export default { start(matrixClient) { this._addMatrixClientListener(matrixClient, 'sync', createSyncAction); this._addMatrixClientListener(matrixClient, 'accountData', createAccountDataAction); + this._addMatrixClientListener(matrixClient, 'Room.tags', createRoomTagsAction); }, /** diff --git a/src/actions/RoomListActions.js b/src/actions/RoomListActions.js new file mode 100644 index 0000000000..3e0ea53a33 --- /dev/null +++ b/src/actions/RoomListActions.js @@ -0,0 +1,142 @@ +/* +Copyright 2018 New Vector Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +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 { asyncAction } from './actionCreators'; +import RoomListStore from '../stores/RoomListStore'; + +import Modal from '../Modal'; +import Rooms from '../Rooms'; +import { _t } from '../languageHandler'; +import sdk from '../index'; + +const RoomListActions = {}; + +/** + * Creates an action thunk that will do an asynchronous request to + * tag room. + * + * @param {MatrixClient} matrixClient the matrix client to set the + * account data on. + * @param {Room} room the room to tag. + * @param {string} oldTag the tag to remove (unless oldTag ==== newTag) + * @param {string} newTag the tag with which to tag the room. + * @param {?number} oldIndex the previous position of the room in the + * list of rooms. + * @param {?number} newIndex the new position of the room in the list + * of rooms. + * @returns {function} an action thunk. + * @see asyncAction + */ +RoomListActions.tagRoom = function(matrixClient, room, oldTag, newTag, oldIndex, newIndex) { + let metaData = null; + + // Is the tag ordered manually? + if (newTag && !newTag.match(/^(m\.lowpriority|im\.vector\.fake\.(invite|recent|direct|archived))$/)) { + const lists = RoomListStore.getRoomLists(); + const newList = [...lists[newTag]]; + + newList.sort((a, b) => a.tags[newTag].order - b.tags[newTag].order); + + // If the room was moved "down" (increasing index) in the same list we + // need to use the orders of the tiles with indices shifted by +1 + const offset = ( + newTag === oldTag && oldIndex < newIndex + ) ? 1 : 0; + + const prevOrder = newIndex === 0 ? + 0 : newList[offset + newIndex - 1].tags[newTag].order; + const nextOrder = newIndex === newList.length ? + 1 : newList[offset + newIndex].tags[newTag].order; + + metaData = { + order: (prevOrder + nextOrder) / 2.0, + }; + } + + return asyncAction('RoomListActions.tagRoom', () => { + const promises = []; + const roomId = room.roomId; + + // Evil hack to get DMs behaving + if ((oldTag === undefined && newTag === 'im.vector.fake.direct') || + (oldTag === 'im.vector.fake.direct' && newTag === undefined) + ) { + return Rooms.guessAndSetDMRoom( + room, newTag === 'im.vector.fake.direct', + ).catch((err) => { + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + console.error("Failed to set direct chat tag " + err); + Modal.createTrackedDialog('Failed to set direct chat tag', '', ErrorDialog, { + title: _t('Failed to set direct chat tag'), + description: ((err && err.message) ? err.message : _t('Operation failed')), + }); + }); + } + + const hasChangedSubLists = oldTag !== newTag; + + // More evilness: We will still be dealing with moving to favourites/low prio, + // but we avoid ever doing a request with 'im.vector.fake.direct`. + // + // if we moved lists, remove the old tag + if (oldTag && oldTag !== 'im.vector.fake.direct' && + hasChangedSubLists + ) { + const promiseToDelete = matrixClient.deleteRoomTag( + roomId, oldTag, + ).catch(function(err) { + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + console.error("Failed to remove tag " + oldTag + " from room: " + err); + Modal.createTrackedDialog('Failed to remove tag from room', '', ErrorDialog, { + title: _t('Failed to remove tag %(tagName)s from room', {tagName: oldTag}), + description: ((err && err.message) ? err.message : _t('Operation failed')), + }); + }); + + promises.push(promiseToDelete); + } + + // if we moved lists or the ordering changed, add the new tag + if (newTag && newTag !== 'im.vector.fake.direct' && + (hasChangedSubLists || metaData) + ) { + // Optimistic update of what will happen to the room tags + room.tags[newTag] = metaData; + + const promiseToAdd = matrixClient.setRoomTag(roomId, newTag, metaData).catch(function(err) { + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + console.error("Failed to add tag " + newTag + " to room: " + err); + Modal.createTrackedDialog('Failed to add tag to room', '', ErrorDialog, { + title: _t('Failed to add tag %(tagName)s to room', {tagName: newTag}), + description: ((err && err.message) ? err.message : _t('Operation failed')), + }); + + throw err; + }); + + promises.push(promiseToAdd); + } + + return Promise.all(promises); + }, () => { + // For an optimistic update + return { + room, oldTag, newTag, metaData, + }; + }); +}; + +export default RoomListActions; diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index d1ef6c2f2c..ad85beac12 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -26,10 +26,11 @@ const CallHandler = require('../../../CallHandler'); const dis = require("../../../dispatcher"); const sdk = require('../../../index'); const rate_limited_func = require('../../../ratelimitedfunc'); -const Rooms = require('../../../Rooms'); +import * as Rooms from '../../../Rooms'; import DMRoomMap from '../../../utils/DMRoomMap'; const Receipt = require('../../../utils/Receipt'); import TagOrderStore from '../../../stores/TagOrderStore'; +import RoomListStore from '../../../stores/RoomListStore'; import GroupStoreCache from '../../../stores/GroupStoreCache'; const HIDE_CONFERENCE_CHANS = true; @@ -77,7 +78,6 @@ module.exports = React.createClass({ cli.on("deleteRoom", this.onDeleteRoom); cli.on("Room.timeline", this.onRoomTimeline); cli.on("Room.name", this.onRoomName); - cli.on("Room.tags", this.onRoomTags); cli.on("Room.receipt", this.onRoomReceipt); cli.on("RoomState.events", this.onRoomStateEvents); cli.on("RoomMember.name", this.onRoomMemberName); @@ -115,6 +115,10 @@ module.exports = React.createClass({ this.updateVisibleRooms(); }); + this._roomListStoreToken = RoomListStore.addListener(() => { + this._delayedRefreshRoomList(); + }); + this.refreshRoomList(); // order of the sublists @@ -175,7 +179,6 @@ module.exports = React.createClass({ MatrixClientPeg.get().removeListener("deleteRoom", this.onDeleteRoom); MatrixClientPeg.get().removeListener("Room.timeline", this.onRoomTimeline); MatrixClientPeg.get().removeListener("Room.name", this.onRoomName); - MatrixClientPeg.get().removeListener("Room.tags", this.onRoomTags); MatrixClientPeg.get().removeListener("Room.receipt", this.onRoomReceipt); MatrixClientPeg.get().removeListener("RoomState.events", this.onRoomStateEvents); MatrixClientPeg.get().removeListener("RoomMember.name", this.onRoomMemberName); @@ -248,10 +251,6 @@ module.exports = React.createClass({ this._delayedRefreshRoomList(); }, - onRoomTags: function(event, room) { - this._delayedRefreshRoomList(); - }, - onRoomStateEvents: function(ev, state) { this._delayedRefreshRoomList(); }, @@ -338,7 +337,7 @@ module.exports = React.createClass({ totalRooms += l.length; } this.setState({ - lists: this.getRoomLists(), + lists, totalRoomCount: totalRooms, // Do this here so as to not render every time the selected tags // themselves change. @@ -349,70 +348,28 @@ module.exports = React.createClass({ }, getRoomLists: function() { - const lists = {}; - lists["im.vector.fake.invite"] = []; - lists["m.favourite"] = []; - lists["im.vector.fake.recent"] = []; - lists["im.vector.fake.direct"] = []; - lists["m.lowpriority"] = []; - lists["im.vector.fake.archived"] = []; + const lists = RoomListStore.getRoomLists(); - const dmRoomMap = DMRoomMap.shared(); + const filteredLists = {}; - this._visibleRooms.forEach((room, index) => { - const me = room.getMember(MatrixClientPeg.get().credentials.userId); - if (!me) return; - - // console.log("room = " + room.name + ", me.membership = " + me.membership + - // ", sender = " + me.events.member.getSender() + - // ", target = " + me.events.member.getStateKey() + - // ", prevMembership = " + me.events.member.getPrevContent().membership); - - if (me.membership == "invite") { - lists["im.vector.fake.invite"].push(room); - } else if (HIDE_CONFERENCE_CHANS && Rooms.isConfCallRoom(room, me, this.props.ConferenceHandler)) { - // skip past this room & don't put it in any lists - } else if (me.membership == "join" || me.membership === "ban" || - (me.membership === "leave" && me.events.member.getSender() !== me.events.member.getStateKey())) { - // Used to split rooms via tags - const tagNames = Object.keys(room.tags); - if (tagNames.length) { - for (let i = 0; i < tagNames.length; i++) { - const tagName = tagNames[i]; - lists[tagName] = lists[tagName] || []; - lists[tagName].push(room); - } - } else if (dmRoomMap.getUserIdForRoomId(room.roomId)) { - // "Direct Message" rooms (that we're still in and that aren't otherwise tagged) - lists["im.vector.fake.direct"].push(room); - } else { - lists["im.vector.fake.recent"].push(room); + Object.keys(lists).forEach((tagName) => { + filteredLists[tagName] = lists[tagName].filter((taggedRoom) => { + // Somewhat impossible, but guard against it anyway + if (!taggedRoom) { + return; } - } else if (me.membership === "leave") { - lists["im.vector.fake.archived"].push(room); - } else { - console.error("unrecognised membership: " + me.membership + " - this should never happen"); - } + const me = taggedRoom.getMember(MatrixClientPeg.get().credentials.userId); + if (HIDE_CONFERENCE_CHANS && Rooms.isConfCallRoom(taggedRoom, me, this.props.ConferenceHandler)) { + return; + } + + return this._visibleRooms.some((visibleRoom) => { + return visibleRoom.roomId === taggedRoom.roomId; + }); + }); }); - // we actually apply the sorting to this when receiving the prop in RoomSubLists. - - // we'll need this when we get to iterating through lists programatically - e.g. ctrl-shift-up/down -/* - this.listOrder = [ - "im.vector.fake.invite", - "m.favourite", - "im.vector.fake.recent", - "im.vector.fake.direct", - Object.keys(otherTagNames).filter(tagName=>{ - return (!tagName.match(/^m\.(favourite|lowpriority)$/)); - }).sort(), - "m.lowpriority", - "im.vector.fake.archived" - ]; -*/ - - return lists; + return filteredLists; }, _getScrollNode: function() { diff --git a/src/stores/RoomListStore.js b/src/stores/RoomListStore.js new file mode 100644 index 0000000000..16902ef471 --- /dev/null +++ b/src/stores/RoomListStore.js @@ -0,0 +1,212 @@ +/* +Copyright 2018 New Vector Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +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 {Store} from 'flux/utils'; +import dis from '../dispatcher'; +import DMRoomMap from '../utils/DMRoomMap'; + +/** + * A class for storing application state for categorising rooms in + * the RoomList. + */ +class RoomListStore extends Store { + constructor() { + super(dis); + + this._init(); + this._actionHistory = []; + } + + _init() { + // Initialise state + this._state = { + lists: { + "im.vector.fake.invite": [], + "m.favourite": [], + "im.vector.fake.recent": [], + "im.vector.fake.direct": [], + "m.lowpriority": [], + "im.vector.fake.archived": [], + }, + ready: false, + }; + } + + _setState(newState) { + this._state = Object.assign(this._state, newState); + console.info(this._state); + this.__emitChange(); + } + + __onDispatch(payload) { + switch (payload.action) { + // Initialise state after initial sync + case 'MatrixActions.sync': { + if (!(payload.prevState !== 'PREPARED' && payload.state === 'PREPARED')) { + break; + } + + this._generateRoomLists(payload.matrixClient); + this._actionHistory.unshift(payload); + } + break; + case 'MatrixActions.Room.tags': { + if (!this._state.ready) break; + this._updateRoomLists(payload.room); + this._actionHistory.unshift(payload); + } + break; + case 'RoomListActions.tagRoom.pending': { + this._updateRoomListsOptimistic( + payload.request.room, + payload.request.oldTag, + payload.request.newTag, + payload.request.metaData, + ); + this._actionHistory.unshift(payload); + } + break; + case 'RoomListActions.tagRoom.failure': { + this._actionHistory = this._actionHistory.filter((action) => { + return action.asyncId !== payload.asyncId; + }); + + // don't duplicate history + const history = this._actionHistory.slice(0); + this._actionHistory = []; + this._reloadFromHistory(history); + } + break; + case 'on_logged_out': { + // Reset state without pushing an update to the view, which generally assumes that + // the matrix client isn't `null` and so causing a re-render will cause NPEs. + this._init(); + this._actionHistory.unshift(payload); + } + break; + } + } + + _reloadFromHistory(history) { + this._init(); + history.forEach((action) => this.__onDispatch(action)); + } + + _updateRoomListsOptimistic(updatedRoom, oldTag, newTag, metaData) { + const newLists = {}; + + // Remove room from oldTag + Object.keys(this._state.lists).forEach((tagName) => { + if (tagName === oldTag) { + newLists[tagName] = this._state.lists[tagName].filter((room) => { + return room.roomId !== updatedRoom.roomId; + }); + } else { + newLists[tagName] = this._state.lists[tagName]; + } + }); + + /// XXX: RoomSubList sorts by data on the room object. We + /// should sort in advance and incrementally insert new rooms + /// instead of resorting every time. + if (metaData) { + updatedRoom.tags[newTag] = metaData; + } + + newLists[newTag].push(updatedRoom); + + this._setState({ + lists: newLists, + }); + } + + _updateRoomLists(updatedRoom) { + const roomTags = Object.keys(updatedRoom.tags); + + const newLists = {}; + + // Removal of the updatedRoom from tags it no longer has + Object.keys(this._state.lists).forEach((tagName) => { + newLists[tagName] = this._state.lists[tagName].filter((room) => { + return room.roomId !== updatedRoom.roomId || roomTags.includes(tagName); + }); + }); + + roomTags.forEach((tagName) => { + if (newLists[tagName].includes(updatedRoom)) return; + newLists[tagName].push(updatedRoom); + }); + + this._setState({ + lists: newLists, + }); + } + + _generateRoomLists(matrixClient) { + const lists = { + "im.vector.fake.invite": [], + "m.favourite": [], + "im.vector.fake.recent": [], + "im.vector.fake.direct": [], + "m.lowpriority": [], + "im.vector.fake.archived": [], + }; + + const dmRoomMap = DMRoomMap.shared(); + + matrixClient.getRooms().forEach((room, index) => { + const me = room.getMember(matrixClient.credentials.userId); + if (!me) return; + + if (me.membership == "invite") { + lists["im.vector.fake.invite"].push(room); + } else if (me.membership == "join" || me.membership === "ban" || + (me.membership === "leave" && me.events.member.getSender() !== me.events.member.getStateKey())) { + // Used to split rooms via tags + const tagNames = Object.keys(room.tags); + if (tagNames.length) { + for (let i = 0; i < tagNames.length; i++) { + const tagName = tagNames[i]; + lists[tagName] = lists[tagName] || []; + lists[tagName].push(room); + } + } else if (dmRoomMap.getUserIdForRoomId(room.roomId)) { + // "Direct Message" rooms (that we're still in and that aren't otherwise tagged) + lists["im.vector.fake.direct"].push(room); + } else { + lists["im.vector.fake.recent"].push(room); + } + } else if (me.membership === "leave") { + lists["im.vector.fake.archived"].push(room); + } else { + console.error("unrecognised membership: " + me.membership + " - this should never happen"); + } + }); + + this._setState({ + lists, + ready: true, // Ready to receive updates via Room.tags events + }); + } + + getRoomLists() { + return this._state.lists; + } +} + +if (global.singletonRoomListStore === undefined) { + global.singletonRoomListStore = new RoomListStore(); +} +export default global.singletonRoomListStore; From 73e3a594ac20dece69ff3f9b3aa644153703dca4 Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Thu, 25 Jan 2018 22:52:19 +0100 Subject: [PATCH 0197/1160] Prevent TagTiles from being dragged into other droppables for the time being at least. --- src/components/structures/TagPanel.js | 5 ++++- src/components/views/elements/DNDTagTile.js | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/structures/TagPanel.js b/src/components/structures/TagPanel.js index 8c790edc03..c843c08ce9 100644 --- a/src/components/structures/TagPanel.js +++ b/src/components/structures/TagPanel.js @@ -95,7 +95,10 @@ const TagPanel = React.createClass({ />; }); return
    - + { (provided, snapshot) => (
    { (provided, snapshot) => (
    From 18bf9ef5987f2082a0b78d963449cb199a681c80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sim=C3=B3=20Albert=20i=20Beltran?= Date: Thu, 25 Jan 2018 22:23:58 +0000 Subject: [PATCH 0198/1160] Translated using Weblate (Catalan) Currently translated at 88.5% (871 of 984 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ca/ --- src/i18n/strings/ca.json | 50 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ca.json b/src/i18n/strings/ca.json index b5bca7d912..b28593861f 100644 --- a/src/i18n/strings/ca.json +++ b/src/i18n/strings/ca.json @@ -821,5 +821,53 @@ "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "S'ha intentat carregar un punt específic dins la línia de temps d'aquesta sala, però no teniu permís per veure el missatge en qüestió.", "Tried to load a specific point in this room's timeline, but was unable to find it.": "S'ha intentat carregar un punt específic de la línia de temps d'aquesta sala, però no s'ha pogut trobar.", "Failed to load timeline position": "No s'ha pogut carregar aquesta posició de la línia de temps", - "Show devices, send anyway or cancel.": "Mostra els dispositius, envia de totes maneres o cancel·la." + "Show devices, send anyway or cancel.": "Mostra els dispositius, envia de totes maneres o cancel·la.", + "Signed Out": "Sessió tancada", + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "Reenviar tot o cancel·lar tot ara. També pots seleccionar missatges individualment per reenviar o cancel·lar.", + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Reenviar missarge o cancel·lar missatge ara.", + "There's no one else here! Would you like to invite others or stop warning about the empty room?": "No hi ha ningú més aquí! T'agradaria convidar algú o no avisar més que la sala està buida?", + "Uploading %(filename)s and %(count)s others|other": "Pujant %(filename)s i %(count)s més", + "Uploading %(filename)s and %(count)s others|zero": "Pujant %(filename)s", + "Light theme": "Tema clar", + "Dark theme": "Tema fosc", + "Status.im theme": "Tema d'Status.im", + "Sign out": "Tancar sessió", + "Remove %(threePid)s?": "Esborrar %(threePid)s?", + "Interface Language": "Idioma de l'interfície", + "User Interface": "Interfície d'usuari", + "Import E2E room keys": "Importar claus E2E de la sala", + "Cryptography": "Criptografia", + "Device ID:": "ID del dispositiu:", + "Device key:": "Clau del dispositiu:", + "Ignored Users": "Usuaris ignorats", + "Labs": "Laboraroris", + "Use with caution": "Utilitzar amb precaució", + "Deactivate my account": "Desactivar la meva compte", + "Updates": "Actualitzacions", + "matrix-react-sdk version:": "Versió de matrix-react-sdk:", + "riot-web version:": "Versió de riot-web:", + "olm version:": "Versió d'olm:", + "Your password has been reset": "La teva contrasenya s'ha reiniciat", + "New password": "Nova contrasenya", + "Confirm your new password": "Confirma la teva nova contrasenya", + "Incorrect username and/or password.": "Usuari i/o contrasenya incorrectes.", + "The phone number entered looks invalid": "El número de telèfon introduït sembla erroni", + "none": "cap", + "Curve25519 identity key": "Clau de la identitat Curve25519", + "Claimed Ed25519 fingerprint key": "Empremta digital Ed25519 reclamada", + "Session ID": "ID de la sessió", + "End-to-end encryption information": "Informació de l'encriptació d'extrem a extrem", + "Event information": "Informació d'esdeveniment", + "User ID": "ID de l'usuari", + "Decryption error": "Error de desencriptació", + "Sender device information": "Informació del dispositiu remitent", + "Export room keys": "Exporta les claus de la sala", + "Upload an avatar:": "Pujar un avatar:", + "Confirm passphrase": "Introduïu una contrasenya", + "Export": "Exporta", + "Import room keys": "Importa les claus de la sala", + "Import": "Importa", + "The version of Riot.im": "La versió de Riot.im", + "Email": "Correu electrònic", + "Add email address": "Afegeix correu electrònic" } From 4820a195ab1d75f318030c4313309ab319d23a29 Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Fri, 26 Jan 2018 09:15:03 +0100 Subject: [PATCH 0199/1160] Remove logging --- src/stores/RoomListStore.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/stores/RoomListStore.js b/src/stores/RoomListStore.js index 16902ef471..69d957f074 100644 --- a/src/stores/RoomListStore.js +++ b/src/stores/RoomListStore.js @@ -46,7 +46,6 @@ class RoomListStore extends Store { _setState(newState) { this._state = Object.assign(this._state, newState); - console.info(this._state); this.__emitChange(); } From 6fa217742ffa2df5b5a3c9368e74b77f2df2661c Mon Sep 17 00:00:00 2001 From: d1d4c Date: Fri, 26 Jan 2018 02:45:24 +0000 Subject: [PATCH 0200/1160] Translated using Weblate (Catalan) Currently translated at 88.5% (871 of 984 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ca/ --- src/i18n/strings/ca.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/ca.json b/src/i18n/strings/ca.json index b28593861f..15d64cd9e1 100644 --- a/src/i18n/strings/ca.json +++ b/src/i18n/strings/ca.json @@ -34,7 +34,7 @@ "Operation failed": "No s'ha pogut realitzar l'operació", "Search": "Cerca", "powered by Matrix": "amb tecnologia de Matrix", - "Edit": "Editeu", + "Edit": "Edita", "Unpin Message": "Desenganxa el missatge", "Quote": "Cita", "Register": "Registre", From 40907ecf2925a9907d2f4a2e83875537dc438751 Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Fri, 26 Jan 2018 19:39:06 +0100 Subject: [PATCH 0201/1160] Use correct condition for getting account data after first sync so that we can get tags sooner. --- src/stores/TagOrderStore.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stores/TagOrderStore.js b/src/stores/TagOrderStore.js index effd8287c7..69b22797fb 100644 --- a/src/stores/TagOrderStore.js +++ b/src/stores/TagOrderStore.js @@ -48,7 +48,7 @@ class TagOrderStore extends Store { switch (payload.action) { // Initialise state after initial sync case 'MatrixActions.sync': { - if (!(payload.prevState === 'PREPARED' && payload.state === 'SYNCING')) { + if (!(payload.prevState !== 'PREPARED' && payload.state === 'PREPARED')) { break; } const tagOrderingEvent = payload.matrixClient.getAccountData('im.vector.web.tag_ordering'); From 56927b23e675b2a5d984aa6b2fd288dd08a63c3b Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 28 Jan 2018 22:12:34 +0000 Subject: [PATCH 0202/1160] pass onWidgetLoad (which is required for SOME EventTileTypes) XXX: they should follow an interface, this is somewhat nasty Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/EventTile.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 4e0ff2c6d6..1d8df4c7a6 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -602,6 +602,7 @@ module.exports = withMatrixClient(React.createClass({ mxEvent={this.props.mxEvent} highlights={this.props.highlights} highlightLink={this.props.highlightLink} + onWidgetLoad={this.props.onWidgetLoad} showUrlPreview={false} />
    From 5764280588de9071f5a136e5d35e306ed5b71d43 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 29 Jan 2018 09:08:11 +0000 Subject: [PATCH 0203/1160] Persist contentState when sending SlashCommand via MessageComposerInput Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/MessageComposerInput.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 932ccf3446..c142d97b28 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -723,6 +723,7 @@ export default class MessageComposerInput extends React.Component { const cmd = SlashCommands.processInput(this.props.room.roomId, commandText); if (cmd) { if (!cmd.error) { + this.historyManager.save(contentState, this.state.isRichtextEnabled ? 'html' : 'markdown'); this.setState({ editorState: this.createEditorState(), }); From 6dd63ae6444835ae7b50948fa1c5a32eb4e62903 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 29 Jan 2018 19:17:46 +0000 Subject: [PATCH 0204/1160] Null guard against falsey (non-null) props.node, to make react happy Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Quote.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/views/elements/Quote.js b/src/components/views/elements/Quote.js index 0c0078978d..761f7aa151 100644 --- a/src/components/views/elements/Quote.js +++ b/src/components/views/elements/Quote.js @@ -182,6 +182,7 @@ export default class Quote extends React.Component { } // Deliberately render nothing if the URL isn't recognised - return this.props.node; + // in case we get an undefined/falsey node, replace it with null to make React happy + return this.props.node || null; } } From c5a3a02e1d8d19ccb1c9b58fdd8ce4a6bc98fa4c Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Tue, 30 Jan 2018 10:14:05 +0000 Subject: [PATCH 0205/1160] Fix order calculation logic when reordering a room --- src/components/views/rooms/RoomList.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index ca1fccd1f5..0c0f7366eb 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -314,7 +314,7 @@ module.exports = React.createClass({ // Is the tag ordered manually? if (newTag && !newTag.match(/^(m\.lowpriority|im\.vector\.fake\.(invite|recent|direct|archived))$/)) { - const newList = Object.assign({}, this.state.lists[newTag]); + const newList = this.state.lists[newTag]; // If the room was moved "down" (increasing index) in the same list we // need to use the orders of the tiles with indices shifted by +1 @@ -322,10 +322,13 @@ module.exports = React.createClass({ newTag === prevTag && result.source.index < result.destination.index ) ? 1 : 0; - const prevOrder = newIndex === 0 ? - 0 : newList[offset + newIndex - 1].tags[newTag].order; - const nextOrder = newIndex === newList.length ? - 1 : newList[offset + newIndex].tags[newTag].order; + const indexBefore = offset + newIndex - 1; + const indexAfter = offset + newIndex; + + const prevOrder = indexBefore < 0 ? + 0 : newList[indexBefore].tags[newTag].order; + const nextOrder = indexAfter >= newList.length ? + 1 : newList[indexAfter].tags[newTag].order; newOrder = { order: (prevOrder + nextOrder) / 2.0, From 819dd93d1fc111fc6ce3593daf801fb96eb26295 Mon Sep 17 00:00:00 2001 From: Osoitz Date: Mon, 29 Jan 2018 18:08:49 +0000 Subject: [PATCH 0206/1160] Translated using Weblate (Basque) Currently translated at 100.0% (984 of 984 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eu/ --- src/i18n/strings/eu.json | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index 15c5e43d97..2613ebf4ce 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -63,7 +63,7 @@ "Ban": "Debekatu", "Unban": "Debekua kendu", "Connectivity to the server has been lost.": "Zerbitzariarekin konexioa galdu da.", - "You do not have permission to post to this room": "Ez duzu gela honetan idazteko baimena", + "You do not have permission to post to this room": "Ez duzu gela honetara mezuak bidaltzeko baimenik", "Logout": "Amaitu saioa", "Filter room members": "Iragazi gelako kideak", "Email": "E-mail", @@ -73,7 +73,7 @@ "Advanced": "Aurreratua", "Cryptography": "Kriptografia", "Devices": "Gailuak", - "Hide read receipts": "Ezkutatu irakurtze-agiria", + "Hide read receipts": "Ezkutatu irakurragiriak", "Don't send typing notifications": "Ez bidali idatzi bitarteko jakinarazpenak", "Always show message timestamps": "Erakutsi beti mezuen denbora-zigilua", "Name": "Izena", @@ -90,7 +90,7 @@ "none": "bat ere ez", "Who can read history?": "Nork irakurri dezake historiala?", "Who can access this room?": "Nor sartu daiteke gelara?", - "Anyone": "Edonor", + "Anyone": "Edonork", "Only people who have been invited": "Gonbidatua izan den jendea besterik ez", "Anyone who knows the room's link, apart from guests": "Gelaren esteka dakien edonor, bisitariak ezik", "Anyone who knows the room's link, including guests": "Gelaren esteka dakien edonor, bisitariak barne", @@ -173,7 +173,7 @@ "Bans user with given id": "Debekatu ID zehatz bat duen erabiltzailea", "Call Timeout": "Deiaren denbora-muga", "Change Password": "Aldatu pasahitza", - "Changes your display nickname": "Zure pantaila izena aldatzen du", + "Changes your display nickname": "Zure pantaila-izena aldatzen du", "Clear Cache": "Garbitu cachea", "Click here to join the discussion!": "Elkartu elkarrizketara!", "Click here to fix": "Egin klik hemen konpontzeko", @@ -209,7 +209,7 @@ "Device key:": "Gailuaren gakoa:", "Direct chats": "Txat zuzenak", "Disable Notifications": "Desgaitu jakinarazpenak", - "Display name": "Pantaila izena", + "Display name": "Pantaila-izena", "Displays action": "Ekintza bistaratzen du", "Drop File Here": "Jaregin fitxategia hona", "%(items)s and %(lastItem)s": "%(items)s eta %(lastItem)s", @@ -253,7 +253,7 @@ "Failed to send email": "Huts egin du e-maila bidaltzean", "Failed to send request.": "Huts egin du eskaera bidaltzean.", "Failed to set avatar.": "Huts egin du abatarra ezartzean.", - "Failed to set display name": "Huts egin du pantaila izena ezartzean", + "Failed to set display name": "Huts egin du pantaila-izena ezartzean", "Failed to set up conference call": "Huts egin du konferentzia deia ezartzean", "Failed to toggle moderator status": "Huts egin du moderatzaile rola aldatzean", "Failed to unban": "Huts egin du debekua kentzean", @@ -272,9 +272,9 @@ "Bulk Options": "Aukera masiboak", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Ezin da hasiera zerbitzarira konektatu, egiaztatu zure konexioa, ziurtatu zure hasiera zerbitzariaren SSL ziurtagiria fidagarritzat jotzen duela zure gailuak, eta nabigatzailearen pluginen batek ez dituela eskaerak blokeatzen.", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Ezin zara hasiera zerbitzarira HTTP bidez konektatu zure nabigatzailearen barran dagoen URLa HTTS bada. Erabili HTTPS edo gaitu script ez seguruak.", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s erabiltzaileak bere pantaila izena aldatu du, %(oldDisplayName)s izatetik %(displayName)s izatera.", + "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s erabiltzaileak bere pantaila-izena aldatu du, %(oldDisplayName)s izatetik %(displayName)s izatera.", "%(senderName)s changed their profile picture.": "%(senderName)s erabiltzaileak bere profileko argazkia aldatu du.", - "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s erabiltzaileak %(powerLevelDiffText)s erabiltzailearen botere maila aldatu du.", + "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s erabiltzaileak botere mailaz aldatu du %(powerLevelDiffText)s.", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s erabiltzaileak gelaren izena aldatu du, orain %(roomName)s da.", "Drop here to tag %(section)s": "Jaregin hona %(section)s atalari etiketa jartzeko", "Incoming voice call from %(name)s": "%(name)s erabiltzailearen deia jasotzen", @@ -354,7 +354,7 @@ "Rejoin": "Berriro elkartu", "Remote addresses for this room:": "Gela honen urruneko helbideak:", "Remove Contact Information?": "Kendu kontaktuaren informazioa?", - "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s erabiltzaileak bere pantaila izena kendu du (%(oldDisplayName)s).", + "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s erabiltzaileak bere pantaila-izena kendu du (%(oldDisplayName)s).", "%(senderName)s removed their profile picture.": "%(senderName)s erabiltzaileak bere profileko argazkia kendu du.", "Remove %(threePid)s?": "Kendu %(threePid)s?", "%(senderName)s requested a VoIP conference.": "%(senderName)s erabiltzaileak VoIP konferentzia bat eskatu du.", @@ -790,9 +790,9 @@ "To change the permissions in the room, you must be a": "Gelaren baimenak aldatzeko, hau izan behar zara:", "To change the topic, you must be a": "Mintzagaia aldatzeko, hau izan behar zara:", "To modify widgets in the room, you must be a": "Gelaren trepetak aldatzeko, hau izan behar zara:", - "Members only (since the point in time of selecting this option)": "Kideak besterik ez (aukera hau hautatzen den unetik)", - "Members only (since they were invited)": "Kideak besterik ez (gonbidatu zaienetik)", - "Members only (since they joined)": "Kideak besterik ez (elkartu zirenetik)", + "Members only (since the point in time of selecting this option)": "Kideek besterik ez (aukera hau hautatzen den unetik)", + "Members only (since they were invited)": "Kideek besterik ez (gonbidatu zaienetik)", + "Members only (since they joined)": "Kideek besterik ez (elkartu zirenetik)", "To send events of type , you must be a": " motako gertaerak bidaltzeko, hau izan behar zara:", "Addresses": "Helbideak", "Invalid community ID": "Komunitate ID baliogabea", From 5c7bdcec4f8ece9c8c92345fc05a9c9336cab696 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sim=C3=B3=20Albert=20i=20Beltran?= Date: Mon, 29 Jan 2018 20:47:05 +0000 Subject: [PATCH 0207/1160] Translated using Weblate (Catalan) Currently translated at 88.5% (871 of 984 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ca/ --- src/i18n/strings/ca.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/ca.json b/src/i18n/strings/ca.json index 15d64cd9e1..eb4ac76d05 100644 --- a/src/i18n/strings/ca.json +++ b/src/i18n/strings/ca.json @@ -18,7 +18,7 @@ "Error": "Error", "Failed to forget room %(errCode)s": "No s'ha pogut oblidar la sala %(errCode)s", "Favourite": "Favorit", - "Mute": "Silenciat", + "Mute": "Silencia", "Room directory": "Directori de sales", "Settings": "Paràmetres", "Start chat": "Inicia un xat", @@ -316,7 +316,7 @@ "Devices": "Dispositius", "Unignore": "Deixa de ignorar", "Ignore": "Ignora", - "Jump to read receipt": "Salta a els rebuts llegits", + "Jump to read receipt": "Vés a l'últim missatge llegit", "Mention": "Menció", "Invite": "Convida", "User Options": "Opcions d'usuari", @@ -577,7 +577,7 @@ "Minimize apps": "Minimitza les aplicacions", "Blacklist": "Llista negre", "Unverify": "Sense verificar", - "Verify...": "S'està verificant...", + "Verify...": "Verificar...", "No results": "Sense resultats", "Delete": "Esborra", "Communities": "Comunitats", From 4afdefb926193160987018b57ec44286e79ca3ff Mon Sep 17 00:00:00 2001 From: Nathan van Beelen Date: Sun, 28 Jan 2018 21:52:17 +0000 Subject: [PATCH 0208/1160] Translated using Weblate (Dutch) Currently translated at 73.9% (728 of 984 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/nl/ --- src/i18n/strings/nl.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index f440e128cb..492d9d596c 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -722,5 +722,10 @@ "%(names)s and %(count)s others are typing|other": "%(names)s en %(count)s andere gebruikers zijn aan het typen", "%(names)s and %(count)s others are typing|one": "%(names)s en iemand anders is aan het typen", "Send": "Verstuur", - "Message Pinning": "Boodschap vastpinnen" + "Message Pinning": "Boodschap vastpinnen", + "Message Replies": "Antwoorden op bericht", + "Presence Management": "Presentie Beheer", + "Tag Panel": "Label Paneel", + "Disable Emoji suggestions while typing": "Emoji suggesties tijdens het typen uitzetten", + "Hide avatar changes": "Avatar veranderingen verbergen" } From 8d902010f8b8c82104f9ea96c6e97298153cc64d Mon Sep 17 00:00:00 2001 From: Xose M Date: Tue, 30 Jan 2018 06:36:34 +0000 Subject: [PATCH 0209/1160] Translated using Weblate (Galician) Currently translated at 99.1% (976 of 984 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/gl/ --- src/i18n/strings/gl.json | 625 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 624 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/gl.json b/src/i18n/strings/gl.json index 1807ce96d8..3fbaf2591b 100644 --- a/src/i18n/strings/gl.json +++ b/src/i18n/strings/gl.json @@ -352,5 +352,628 @@ "World readable": "Visible por todos", "Guests can join": "Convidados pódense unir", "Failed to set avatar.": "Fallo ao establecer o avatar.", - "Save": "Gardar" + "Save": "Gardar", + "(~%(count)s results)|other": "(~%(count)s resultados)", + "(~%(count)s results)|one": "(~%(count)s resultado)", + "Join Room": "Unirse a sala", + "Upload avatar": "Subir avatar", + "Remove avatar": "Quitar avatar", + "Settings": "Axustes", + "Forget room": "Esquecer sala", + "Search": "Busca", + "Show panel": "Mostra panel", + "Drop here to favourite": "Solte aqui para favorito", + "Drop here to tag direct chat": "Solte aquí para etiquetar chat directo", + "Drop here to restore": "Solte aquí para restablecer", + "Drop here to tag %(section)s": "Solte aquí para etiquetar %(section)s", + "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Non poderá desfacer este cambio xa que está a diminuír a súa autoridade, si vostede é a única usuaria con autorización na sala será imposible voltar a obter privilexios.", + "Drop here to demote": "Arrastre aquí para degradar", + "Press to start a chat with someone": "Pulse para iniciar a conversa con alguén", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Aínda non está en ningunha sala! Pulse para crear unha sala ou para buscar no directorio", + "Community Invites": "Convites da comunidade", + "Invites": "Convites", + "Favourites": "Favoritas", + "People": "Xente", + "Rooms": "Salas", + "Low priority": "Baixa prioridade", + "Historical": "Historial", + "This invitation was sent to an email address which is not associated with this account:": "Este convite foi enviado a un enderezo de correo que non está asociado con esta conta:", + "You may wish to login with a different account, or add this email to this account.": "Pode que desexe conectarse con outra conta, ou engadir este enderezo a súa conta.", + "You have been invited to join this room by %(inviterName)s": "Foi convidada por %(inviterName)s a unirse a esta sala", + "Would you like to accept or decline this invitation?": "Quere aceptar ou rexeitar este convite?", + "Reason: %(reasonText)s": "Razón: %(reasonText)s", + "Rejoin": "Voltar a unirse", + "You have been kicked from %(roomName)s by %(userName)s.": "Foi expulsada de %(roomName)s por %(userName)s.", + "You have been kicked from this room by %(userName)s.": "Foi expulsada de esta sala por %(userName)s.", + "You have been banned from %(roomName)s by %(userName)s.": "Non se lle permite acceder a %(roomName)s por %(userName)s.", + "You have been banned from this room by %(userName)s.": "Non se lle permite o acceso a esta sala por %(userName)s.", + "This room": "Esta sala", + "%(roomName)s does not exist.": "%(roomName)s non existe.", + "%(roomName)s is not accessible at this time.": "%(roomName)s non está accesible en este momento.", + "You are trying to access %(roomName)s.": "Está intentando acceder a %(roomName)s.", + "You are trying to access a room.": "Está intentando acceder a unha sala.", + "Click here to join the discussion!": "Pulse aquí para unirse a conversa!", + "This is a preview of this room. Room interactions have been disabled": "Esta é unha vista previa de esta sala. Desactiváronse as interaccións coa sala", + "To change the room's avatar, you must be a": "Para cambiar o avatar da sala, debe ser", + "To change the room's name, you must be a": "Para cambiar o nome da sala, debe ser", + "To change the room's main address, you must be a": "Para cambiar o enderezo principal da sala, debe ser", + "To change the room's history visibility, you must be a": "Para cambiar a visibilidade do histórico da sala, debe ser", + "To change the permissions in the room, you must be a": "Para cambiar os permisos na sala, debe ser", + "To change the topic, you must be a": "Para cambiar o asunto, debe ser", + "To modify widgets in the room, you must be a": "Para modificar os widgets da sala, debe ser", + "Failed to unban": "Fallou eliminar a prohibición", + "Banned by %(displayName)s": "Non aceptado por %(displayName)s", + "Privacy warning": "Aviso de intimidade", + "Changes to who can read history will only apply to future messages in this room": "Os cambios sobre quen pode ler o histórico serán de aplicación a futuras mensaxes en esta sala", + "The visibility of existing history will be unchanged": "A visibilidade do histórico existente non cambiará", + "unknown error code": "código de fallo descoñecido", + "Failed to forget room %(errCode)s": "Fallo ao esquecer sala %(errCode)s", + "End-to-end encryption is in beta and may not be reliable": "O cifrado de extremo-a-extremo está en beta e podería non ser fiable", + "You should not yet trust it to secure data": "Polo de agora non debería confiarlle datos seguros", + "Devices will not yet be able to decrypt history from before they joined the room": "Os dispositivos non poderán descifrar o histórico anterior a que se uniron a sala", + "Once encryption is enabled for a room it cannot be turned off again (for now)": "Unha vez habilitado o cifrado para unha sala non se poderá desactivar (por agora)", + "Encrypted messages will not be visible on clients that do not yet implement encryption": "As mensaxes cifradas non será visibles en clientes que non aínda non teñan implementado o cifrado", + "Enable encryption": "Habilitar cifrado", + "(warning: cannot be disabled again!)": "(aviso: non se pode deshabilitar!)", + "Encryption is enabled in this room": "O cifrado está habilitado en esta sala", + "Encryption is not enabled in this room": "O cifrado non se habilitou para esta sala", + "Privileged Users": "Usuarios con privilexios", + "%(user)s is a": "%(user)s é un", + "No users have specific privileges in this room": "Non hai usuarias con privilexios específicos en esta sala", + "Banned users": "Usuarias non permitidas", + "This room is not accessible by remote Matrix servers": "Esta sala non é accesible por servidores Matrix remotos", + "Leave room": "Deixar a sala", + "Favourite": "Favorita", + "Tagged as: ": "Etiquetada como: ", + "To link to a room it must have an address.": "Para ligar a unha sala deberá ter un enderezo.", + "Guests cannot join this room even if explicitly invited.": "As convidadas non se poden unir a esta sala incluso se foro explicitamente convidadas.", + "Click here to fix": "Pulse aquí para solución", + "Who can access this room?": "Quén pode acceder a esta sala?", + "Only people who have been invited": "Só persoas que foron convidadas", + "Anyone who knows the room's link, apart from guests": "Calquera que coñeza o enderezo da sala, aparte das convidadas", + "Anyone who knows the room's link, including guests": "Calquera que coñeza a ligazón a sala, incluíndo as convidadas", + "Publish this room to the public in %(domain)s's room directory?": "Publicar esta sala no directorio público de salas de %(domain)s?", + "Who can read history?": "Quén pode ler o histórico?", + "Anyone": "Calquera", + "Members only (since the point in time of selecting this option)": "Só membros (desde o momento en que se selecciona esta opción)", + "Members only (since they were invited)": "Só membros (desde que foron convidados)", + "Members only (since they joined)": "Só membros (desde que se uniron)", + "Permissions": "Permisos", + "The default role for new room members is": "Por omisión o rol na sala para novos membros é", + "To send messages, you must be a": "Para enviar mensaxes, deberá ser", + "To invite users into the room, you must be a": "Para convidar a usuarias a esta sala, debe ser", + "To configure the room, you must be a": "Para configurar a sala, debe ser", + "To kick users, you must be a": "Para expulsar usuarias, debe ser", + "To ban users, you must be a": "Para prohibir usuarias, debe ser", + "To remove other users' messages, you must be a": "Para eliminar mensaxes de outras usuarias, debe ser", + "To send events of type , you must be a": "Para enviar eventos de tipo , debe ser", + "Advanced": "Avanzado", + "This room's internal ID is": "O ID interno de esta sala é", + "Add a topic": "Engadir asunto", + "Cancel": "Cancelar", + "Scroll to unread messages": "Desplace ate mensaxes non lidas", + "Jump to first unread message.": "Ir a primeira mensaxe non lida.", + "Close": "Pechar", + "Invalid alias format": "Formato de alias non válido", + "'%(alias)s' is not a valid format for an alias": "'%(alias)s' non é un formato válido para un alias", + "Invalid address format": "Formato de enderezo non válido", + "'%(alias)s' is not a valid format for an address": "'%(alias)s' non é un formato válido par un enderezo", + "not specified": "non indicado", + "not set": "non establecido", + "Remote addresses for this room:": "Enderezos remotos para esta sala:", + "Addresses": "Enderezos", + "The main address for this room is": "O enderezo principal para esta sala é", + "Local addresses for this room:": "O enderezo local para esta sala:", + "This room has no local addresses": "Esta sala non ten enderezos locais", + "New address (e.g. #foo:%(localDomain)s)": "Novos enderezos (ex. #foo:%(localDomain)s)", + "Invalid community ID": "ID da comunidade non válido", + "'%(groupId)s' is not a valid community ID": "'%(groupId)s' non é un ID de comunidade válido", + "New community ID (e.g. +foo:%(localDomain)s)": "Novo ID da comunidade (ex. +foo:%(localDomain)s)", + "You have enabled URL previews by default.": "Vostede habilitou a vista previa de URL por omisión.", + "You have disabled URL previews by default.": "Vostede desactivou a vista previa de URL por omisión.", + "URL previews are enabled by default for participants in this room.": "As vistas previas de URL están habilitadas por omisión para os participantes de esta sala.", + "URL previews are disabled by default for participants in this room.": "As vistas previas de URL están desactivadas por omisión para os participantes de esta sala.", + "URL Previews": "Vista previa de URL", + "Error decrypting audio": "Fallo ao descifrar audio", + "Error decrypting attachment": "Fallo descifrando o anexo", + "Decrypt %(text)s": "Descifrar %(text)s", + "Download %(text)s": "Baixar %(text)s", + "Invalid file%(extra)s": "Ficheiro non válido %(extra)s", + "Error decrypting image": "Fallo ao descifrar a imaxe", + "Image '%(Body)s' cannot be displayed.": "Imaxe '%(Body)s' non pode ser mostrada.", + "This image cannot be displayed.": "Esta imaxe non se pode ser mostrada.", + "Error decrypting video": "Fallo descifrando vídeo", + "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s cambiou o avatar para %(roomName)s", + "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s eliminou o avatar da sala.", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s cambiou o avatar da sala a ", + "Copied!": "Copiado!", + "Failed to copy": "Fallo ao copiar", + "Add an Integration": "Engadir unha integración", + "You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "Vai ser redirixido a unha web de terceiros para poder autenticar a súa conta e así utilizar %(integrationsUrl)s. Quere continuar?", + "Removed or unknown message type": "Tipo de mensaxe descoñecida ou eliminada", + "Message removed by %(userId)s": "Mensaxe eliminada por %(userId)s", + "Message removed": "Mensaxe eliminada", + "Robot check is currently unavailable on desktop - please use a web browser": "Comprobación por Robot non está dispoñible en escritorio - por favor utilice un navegador web", + "This Home Server would like to make sure you are not a robot": "Este Servidor quere asegurarse de que vostede non é un robot", + "Sign in with CAS": "Conectarse con CAS", + "Custom Server Options": "Opcións personalizadas do servidor", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "Pode utilizar as opcións personalizadas do servidor para conectarse a outros servidores Matrix indicando un URL de servidor de inicio diferente.", + "This allows you to use this app with an existing Matrix account on a different home server.": "Así pode utilizar este aplicativo con unha conta Matrix existente en un servidor de incio diferente.", + "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "Tamén pode establecer un servidor de identidade personalizado pero esto normalmente dificulta a interacción con usuarias basándose non enderezo de correo.", + "Dismiss": "Rexeitar", + "To continue, please enter your password.": "Para continuar, por favor introduza o seu contrasinal.", + "Password:": "Contrasinal:", + "An email has been sent to %(emailAddress)s": "Enviouse un correo a %(emailAddress)s", + "Please check your email to continue registration.": "Por favor comprobe o seu correo para continuar co rexistro.", + "Token incorrect": "Testemuño incorrecto", + "A text message has been sent to %(msisdn)s": "Enviouse unha mensaxe de texto a %(msisdn)s", + "Please enter the code it contains:": "Por favor introduza o código que contén:", + "Start authentication": "Inicie a autenticación", + "powered by Matrix": "funciona grazas a Matrix", + "Username on %(hs)s": "Nome de usuaria en %(hs)s", + "User name": "Nome de usuaria", + "Mobile phone number": "Número de teléfono móbil", + "Forgot your password?": "Esqueceu o contrasinal?", + "%(serverName)s Matrix ID": "Matrix ID en %(serverName)s", + "Sign in with": "Conectarse con", + "Email address": "Enderezo de correo", + "Sign in": "Conectar", + "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Si non indica un enderezo de correo non poderá restablecer o contrasinal, está segura?", + "Email address (optional)": "Enderezo de correo (opcional)", + "You are registering with %(SelectedTeamName)s": "Estase a rexistrar con %(SelectedTeamName)s", + "Mobile phone number (optional)": "Número de teléfono móbil (opcional)", + "Register": "Rexistar", + "Default server": "Servidor por omisión", + "Custom server": "Servidor personalizado", + "Home server URL": "URL do servidor de inicio", + "Identity server URL": "URL do servidor de identidade", + "What does this mean?": "Qué significa esto?", + "Remove from community": "Eliminar da comunidade", + "Disinvite this user from community?": "Retirar o convite a comunidade a esta usuaria?", + "Remove this user from community?": "Quitar a esta usuaria da comunidade?", + "Failed to withdraw invitation": "Fallo ao retirar o convite", + "Failed to remove user from community": "Fallo ao quitar a usuaria da comunidade", + "Filter community members": "Filtrar membros da comunidade", + "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Está segura de que quere eliminar '%(roomName)s' de %(groupId)s?", + "Removing a room from the community will also remove it from the community page.": "Eliminar unha sala da comunidade tamén a quitará da páxina da comunidade.", + "Remove": "Eliminar", + "Failed to remove room from community": "Fallo ao quitar a sala da comunidade", + "Failed to remove '%(roomName)s' from %(groupId)s": "Fallo ao quitar '%(roomName)s' de %(groupId)s", + "Something went wrong!": "Algo fallou!", + "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "A visibilidade de '%(roomName)s' en %(groupId)s non se puido actualizar.", + "Visibility in Room List": "Visibilidade na Lista de Salas", + "Visible to everyone": "Visible para todo o mundo", + "Only visible to community members": "Só visible para membros da comunidade", + "Filter community rooms": "Filtrar salas da comunidade", + "Something went wrong when trying to get your communities.": "Algo fallou ao intentar obter as súas comunidades.", + "You're not currently a member of any communities.": "Ate o momento non é membro de ningunha comunidade.", + "Unknown Address": "Enderezo descoñecido", + "NOTE: Apps are not end-to-end encrypted": "NOTA: As Apps non están cifradas de extremo-a-extremo", + "Do you want to load widget from URL:": "Quere cargar o widget da URL:", + "Allow": "Permitir", + "Delete Widget": "Eliminar Widget", + "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Quitando un widget eliminao para todas as usuarias de esta sala. Está segura de querer eliminar este widget?", + "Delete widget": "Eliminar widget", + "Revoke widget access": "Retirar acceso ao widget", + "Minimize apps": "Minimizar apps", + "Edit": "Editar", + "Create new room": "Crear unha nova sala", + "Unblacklist": "Quitar da lista negra", + "Blacklist": "Por na lista negra", + "Unverify": "Retirar verificación", + "Verify...": "Verificar...", + "No results": "Sen resultados", + "Delete": "Eliminar", + "Communities": "Comunidades", + "Home": "Inicio", + "Integrations Error": "Fallo nas integracións", + "Could not connect to the integration server": "Non se puido conectar ao servidor de integración", + "Manage Integrations": "Xestionar integracións", + "%(nameList)s %(transitionList)s": "%(nameList)s %(transitionList)s", + "%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)s uníronse %(count)s veces", + "%(severalUsers)sjoined %(count)s times|one": "%(severalUsers)s uníronse", + "%(oneUser)sjoined %(count)s times|other": "%(oneUser)s uniuse %(count)s veces", + "%(oneUser)sjoined %(count)s times|one": "%(oneUser)s uníuse", + "%(severalUsers)sleft %(count)s times|other": "%(severalUsers)s saíron %(count)s veces", + "%(severalUsers)sleft %(count)s times|one": "%(severalUsers)s saíron", + "%(oneUser)sleft %(count)s times|other": "%(oneUser)s saiu %(count)s veces", + "%(oneUser)sleft %(count)s times|one": "%(oneUser)s saiu", + "%(severalUsers)sjoined and left %(count)s times|other": "%(severalUsers)s uníronse e saíron %(count)s veces", + "%(severalUsers)sjoined and left %(count)s times|one": "%(severalUsers)s uníronse e saíron", + "%(oneUser)sjoined and left %(count)s times|other": "%(oneUser)s uniuse e saiu %(count)s veces", + "%(oneUser)sjoined and left %(count)s times|one": "%(oneUser)s uníuse e saiu", + "%(severalUsers)sleft and rejoined %(count)s times|other": "%(severalUsers)s saíron e voltaron %(count)s veces", + "%(severalUsers)sleft and rejoined %(count)s times|one": "%(severalUsers)s saíron e voltaron", + "%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)s saiu e voltou %(count)s veces", + "%(oneUser)sleft and rejoined %(count)s times|one": "%(oneUser)s saiu e voltou", + "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)s rexeitaron convites %(count)s veces", + "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)s rexeitaron os seus convites", + "%(oneUser)srejected their invitation %(count)s times|other": "%(oneUser)s rexeitou o seu convite %(count)s veces", + "%(oneUser)srejected their invitation %(count)s times|one": "%(oneUser)s rexeitou o seu convite", + "%(severalUsers)shad their invitations withdrawn %(count)s times|other": "retiróuselle o convite a %(severalUsers)s %(count)s veces", + "%(severalUsers)shad their invitations withdrawn %(count)s times|one": "retirouselle o convite a %(severalUsers)s", + "%(oneUser)shad their invitation withdrawn %(count)s times|other": "retiróuselle o convite a %(oneUser)s %(count)s veces", + "%(oneUser)shad their invitation withdrawn %(count)s times|one": "retiróuselle o convite a %(oneUser)s", + "were invited %(count)s times|other": "foron convidados %(count)s veces", + "were invited %(count)s times|one": "foron convidados", + "was invited %(count)s times|other": "foi convidada %(count)s veces", + "was invited %(count)s times|one": "foi convidada", + "were banned %(count)s times|other": "foron prohibidas %(count)s veces", + "were banned %(count)s times|one": "foron prohibidas", + "was banned %(count)s times|other": "foi prohibida %(count)s veces", + "was banned %(count)s times|one": "foi prohibida", + "were unbanned %(count)s times|other": "retirouselle a prohibición %(count)s veces", + "were unbanned %(count)s times|one": "retirouselle a prohibición", + "was unbanned %(count)s times|other": "retirouselle a prohibición %(count)s veces", + "was unbanned %(count)s times|one": "retiróuselle a prohibición", + "were kicked %(count)s times|other": "foron expulsadas %(count)s veces", + "were kicked %(count)s times|one": "foron expulsadas", + "was kicked %(count)s times|other": "foi expulsada %(count)s veces", + "was kicked %(count)s times|one": "foi expulsada", + "%(severalUsers)schanged their name %(count)s times|other": "%(severalUsers)s cambiaron o seu nome %(count)s veces", + "%(severalUsers)schanged their name %(count)s times|one": "%(severalUsers)s cambiaron o seu nome", + "%(oneUser)schanged their name %(count)s times|other": "%(oneUser)s cambiou o seu nome %(count)s veces", + "%(oneUser)schanged their name %(count)s times|one": "%(oneUser)s cambiou o seu nome", + "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)s cambiaron o seu avatar %(count)s veces", + "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)s cambiaron o seu avatar", + "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)s cambiou o seu avatar %(count)s veces", + "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)s cambiou o seu avatar", + "%(items)s and %(count)s others|other": "%(items)s e %(count)s outras", + "%(items)s and %(count)s others|one": "%(items)s e outra máis", + "%(items)s and %(lastItem)s": "%(items)s e %(lastItem)s", + "collapse": "comprimir", + "expand": "expandir", + "Custom of %(powerLevel)s": "Personalización de %(powerLevel)s", + "Custom level": "Nivel personalizado", + "Quote": "Cita", + "Room directory": "Directorio de salas", + "Start chat": "Iniciar conversa", + "And %(count)s more...|other": "E %(count)s máis...", + "ex. @bob:example.com": "ex. @pepe:exemplo.com", + "Add User": "Engadir usuaria", + "Matrix ID": "ID Matrix", + "Matrix Room ID": "ID sala Matrix", + "email address": "enderezo de correo", + "Try using one of the following valid address types: %(validTypesList)s.": "Intentar utilizar algún dos seguintes tipos de enderezo válidos: %(validTypesList)s.", + "You have entered an invalid address.": "Introduxo un enderezo non válido.", + "Create a new chat or reuse an existing one": "Crear un novo chat ou reutilizar un xa existente", + "Start new chat": "Iniciar un novo chat", + "You already have existing direct chats with this user:": "Xa ten unha conversa directa con esta usuaria:", + "Start chatting": "Iniciar a conversar", + "Click on the button below to start chatting!": "Pulse non botón inferior para iniciar a conversar!", + "Start Chatting": "Iniciar a conversa", + "Confirm Removal": "Confirme a retirada", + "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Está certa de que quere quitar (eliminar) este evento? Sepa que si elimina un nome de sala ou cambia o asunto, podería desfacer o cambio.", + "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "Os ID de comunidade só poden conter caracteres a-z, 0-9, or '=_-./'", + "Community IDs cannot not be empty.": "O ID de comunidade non pode quedar baldeiro.", + "Something went wrong whilst creating your community": "Algo fallou mentras se creaba a súa comunidade", + "Create Community": "Crear comunidade", + "Community Name": "Nome da comunidade", + "Example": "Exemplo", + "Community ID": "ID da comunidade", + "example": "exemplo", + "Create": "Crear", + "Create Room": "Crear sala", + "Room name (optional)": "Nome da sala (opcional)", + "Advanced options": "Axustes avanzados", + "Block users on other matrix homeservers from joining this room": "Evitar que usuarias de outros servidores matrix se unan a esta sala", + "This setting cannot be changed later!": "Esta preferencia non se pode cambiar máis tarde!", + "Unknown error": "Fallo descoñecido", + "Incorrect password": "Contrasinal incorrecto", + "Deactivate Account": "Desactivar conta", + "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Esto inutilizará a súa conta de xeito permanente. Non poderá voltar a rexistrarse co mesmo ID de usuaria.", + "This action is irreversible.": "Esta acción e irreversible.", + "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Non se pode determinar si o enderezo ao que foi enviado este convite coincide con un dos asociados a súa conta.", + "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Para verificar que se pode confiar en este dispositivo, contacte co seu dono utilizando algún outro medio (ex. en persoa ou chamada de teléfono) e pregúntelle si a chave que ven nos Axustes de Usuaria do se dispositivo coincide coa chave inferior:", + "Device name": "Nome do dispositivo", + "Device key": "Chave do dispositivo", + "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Si concorda, pulse o botón verificar. Si non, entón alguén está interceptando este dispositivo e probablemente vostede desexe pulsar o botón lista negra.", + "In future this verification process will be more sophisticated.": "No futuro este proceso de verificación será máis sofisticado.", + "Verify device": "Verificar dispositivo", + "I verify that the keys match": "Certifico que coinciden as chaves", + "An error has occurred.": "Algo fallou.", + "OK": "OK", + "You added a new device '%(displayName)s', which is requesting encryption keys.": "Engadeu un novo dispositivo '%(displayName)s', que está a solicitar as chaves de cifrado.", + "Your unverified device '%(displayName)s' is requesting encryption keys.": "O seu dispositivo non verificado '%(displayName)s' está solicitando chaves de cifrado.", + "Start verification": "Iniciar verificación", + "Share without verifying": "Compartir sin verificar", + "Ignore request": "Ignorar petición", + "Loading device info...": "Cargando información do dispositivo...", + "Encryption key request": "Petición de chave de cifrado", + "Otherwise, click here to send a bug report.": "Se non, pulse aquí para enviar un informe de fallo.", + "Unable to restore session": "Non se puido restaurar a sesión", + "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Atopamos un erro intentando restablecer a sesión anterior. Si continúa, deberá conectarse de novo, e a parte cifrada do chat non será lexible.", + "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Si anteriormente utilizou unha versión máis recente de Riot, a súa sesión podería non ser compatible con esta versión. Peche esta ventá e volte a versión máis recente.", + "Continue anyway": "Continuar igualmente", + "Invalid Email Address": "Enderezo de email non válido", + "This doesn't appear to be a valid email address": "Este non semella ser un enderezo de email válido", + "Verification Pending": "Verificación pendente", + "Please check your email and click on the link it contains. Once this is done, click continue.": "Por favor comprobe o seu email e pulse na ligazón que contén. Unha vez feito, pulse continuar.", + "Unable to add email address": "Non se puido engadir enderezo de email", + "Unable to verify email address.": "Non se puido verificar enderezo de email.", + "This will allow you to reset your password and receive notifications.": "Esto permitiralle restablecer o seu contrasinal e recibir notificacións.", + "Skip": "Saltar", + "User names may only contain letters, numbers, dots, hyphens and underscores.": "Os nomes de usuaria só poden conter letras, números, puntos e guión alto e baixo.", + "Username not available": "Nome de usuaria non dispoñible", + "Username invalid: %(errMessage)s": "Nome de usuaria non válido: %(errMessage)s", + "An error occurred: %(error_string)s": "Algo fallou: %(error_string)s", + "Username available": "Nome de usuaria dispoñible", + "To get started, please pick a username!": "Para comezar, escolla un nome de usuaria!", + "This will be your account name on the homeserver, or you can pick a different server.": "Este será o nome da súa conta no servidor, ou pode escoller un servidor diferente.", + "If you already have a Matrix account you can log in instead.": "Si xa ten unha conta Matrix entón pode conectarse.", + "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "En este momento está por na lista negra os dispositivos non verificados; para enviar mensaxes a eses dispositivos debe verificalos.", + "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Recomendámoslle que vaia ao proceso de verificación para cada dispositivo para confirmar que pertencen ao seu dono lexítimos, pero se o prefire pode enviar a mensaxe sen ter verificado.", + "Room contains unknown devices": "A sala contén dispositivos descoñecidos", + "\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" contén dispositivos que vostede non vira antes.", + "Unknown devices": "Dispositivos descoñecidos", + "Private Chat": "Conversa privada", + "Public Chat": "Conversa pública", + "Custom": "Personalizada", + "Alias (optional)": "Alias (opcional)", + "Name": "Nome", + "Topic": "Asunto", + "Make this room private": "Facer que esta sala sexa privada", + "Share message history with new users": "Compartir o histórico de mensaxes coas novas usuarias", + "Encrypt room": "Cifrar sala", + "You must register to use this functionality": "Debe rexistrarse para utilizar esta función", + "You must join the room to see its files": "Debe unirse a sala para ver os seus ficheiros", + "There are no visible files in this room": "Non hai ficheiros visibles en esta sala", + "

    HTML for your community's page

    \n

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

    \n

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

    \n": "

    HTML para a páxina da súa comunidade

    \n

    \n Utilice a descrición longa para presentar novos membros a comunidade, ou publicar algunha ligazón importante\n \n

    \n

    \n Tamén pode utilizar etiquetas 'img'\n

    \n", + "Add rooms to the community summary": "Engadir salas ao resumo da comunidade", + "Which rooms would you like to add to this summary?": "Qué salas desexa engadir a este resumo?", + "Add to summary": "Engadir ao resumo", + "Failed to add the following rooms to the summary of %(groupId)s:": "Algo fallou ao engadir estas salas ao resumo de %(groupId)s:", + "Add a Room": "Engadir unha sala", + "Failed to remove the room from the summary of %(groupId)s": "Algo fallou ao quitar a sala do resumo de %(groupId)s", + "The room '%(roomName)s' could not be removed from the summary.": "A sala '%(roomName)s' non se puido eliminar do resumo.", + "Add users to the community summary": "Engadir usuarias ao resumo da comunidade", + "Who would you like to add to this summary?": "A quén desexa engadir a este resumo?", + "Failed to add the following users to the summary of %(groupId)s:": "Algo fallou ao engadir as seguintes usuarias ao resumo de %(groupId)s:", + "Add a User": "Engadir unha usuaria", + "Failed to remove a user from the summary of %(groupId)s": "Algo fallou ao eliminar a usuaria do resumo de %(groupId)s", + "The user '%(displayName)s' could not be removed from the summary.": "A usuaria '%(displayName)s' non se puido eliminar do resumo.", + "Failed to upload image": "Fallo ao subir a páxina", + "Failed to update community": "Fallo ao actualizar a comunidade", + "Unable to accept invite": "Non puido aceptar o convite", + "Unable to reject invite": "Non puido rexeitar o convite", + "Leave Community": "Deixar a comunidade", + "Leave %(groupName)s?": "Deixar %(groupName)s?", + "Leave": "Saír", + "Unable to leave room": "Non puido deixar a sala", + "Community Settings": "Axustes da comunidade", + "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Estas salas son mostradas aos membros da comunidade na páxina da comunidade. Os membros da comunidade poden unirse as salas pulsando en elas.", + "Add rooms to this community": "Engadir salas a esta comunidade", + "Featured Rooms:": "Salas destacadas:", + "Featured Users:": "Usuarias destacadas:", + "%(inviter)s has invited you to join this community": "%(inviter)s convidouna a unirse a esta comunidade", + "You are an administrator of this community": "Vostede administra esta comunidade", + "You are a member of this community": "Vostede é membro de esta comunidade", + "Your community hasn't got a Long Description, a HTML page to show to community members.
    Click here to open settings and give it one!": "A súa comunidade non ten unha Descrición Longa, unha páxina HTML para mostrar aos membros.
    Pulse aquí para abrir os axustes e publicar unha!", + "Long Description (HTML)": "Descrición longa (HTML)", + "Description": "Descrición", + "Community %(groupId)s not found": "Non se atopou a comunidade %(groupId)s", + "This Home server does not support communities": "Este servidor non soporta comunidades", + "Failed to load %(groupId)s": "Fallo ao cargar %(groupId)s", + "Reject invitation": "Rexeitar convite", + "Are you sure you want to reject the invitation?": "Seguro que desexa rexeitar o convite?", + "Failed to reject invitation": "Fallo ao rexeitar o convite", + "Are you sure you want to leave the room '%(roomName)s'?": "Seguro que desexa saír da sala '%(roomName)s'?", + "Failed to leave room": "Algo fallou ao saír da sala", + "Signed Out": "Desconectada", + "For security, this session has been signed out. Please sign in again.": "Por seguridade, pechouse a sesión. Por favor, conéctese de novo.", + "Cryptography data migrated": "Migráronse os datos de cifrado", + "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "Levouse a fin a mudanza de datos criptográficos. O cifrado extremo-a-extremo si volta a unha versión máis antiga de Riot. Si precisa utilizar criptografía de extremo-a-extremo en unha versión anterior, primeiro desconéctese de Riot. Para manter o histórico de mensaxes, exporte e volte a importar as súas chaves.", + "Old cryptography data detected": "Detectouse o uso de criptografía sobre datos antigos", + "Logout": "Desconectar", + "Your Communities": "As súas Comunidades", + "Error whilst fetching joined communities": "Fallo mentras se obtiñas as comunidades unidas", + "Create a new community": "Crear unha nova comunidade", + "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Crear unha comunidade para agrupar usuarias e salas! Poña unha páxina de inicio personalizada para destacar o seu lugar no universo Matrix.", + "Join an existing community": "Unirse a unha comunidade existente", + "To join an existing community you'll have to know its community identifier; this will look something like +example:matrix.org.": "Para unirse a unha comunidade existente deberá coñecer o identificador de esa comunidade; terá un aspecto como +exemplo:matrix.org", + "You have no visible notifications": "Non ten notificacións visibles", + "Scroll to bottom of page": "Desplácese ate o final da páxina", + "Message not sent due to unknown devices being present": "Non se enviou a mensaxe porque hai dispositivos non coñecidos", + "Show devices, send anyway or cancel.": "Mostrar dispositivos, enviar igualmente ou cancelar.", + "%(count)s of your messages have not been sent.|other": "Algunha das súas mensaxes non foron enviadas.", + "%(count)s of your messages have not been sent.|one": "A súa mensaxe non foi enviada.", + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "Reenviar todo ou bencancelar todo. Tamén pode seleccionar mensaxes individuais para reenviar ou cancelar.", + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Reenviar mensaxe ou cancelar mensaxe agora.", + "Warning": "Aviso", + "Connectivity to the server has been lost.": "Perdeuse a conexión ao servidor.", + "Sent messages will be stored until your connection has returned.": "As mensaxes enviadas gardaránse ate que retome a conexión.", + "%(count)s new messages|other": "%(count)s novas mensaxes", + "%(count)s new messages|one": "%(count)s nova mensaxe", + "Active call": "Chamada activa", + "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Non hai ninguén por aquí! Desexa convidar a outras ou deixar de informar sobre a sala baldeira?", + "You seem to be uploading files, are you sure you want to quit?": "Semella estar a subir ficheiros, seguro que desexa deixalo?", + "You seem to be in a call, are you sure you want to quit?": "Semella estar en unha chamada, seguro que quere saír?", + "Failed to upload file": "Fallo ao subir ficheiro", + "Server may be unavailable, overloaded, or the file too big": "O servidor podería non estar dispoñible, sobrecargado ou o ficheiro ser demasiado grande", + "Search failed": "Fallou a busca", + "Server may be unavailable, overloaded, or search timed out :(": "O servidor podería non estar dispoñible, sobrecargado, ou caducou a busca :(", + "No more results": "Sen máis resultados", + "Unknown room %(roomId)s": "Sala descoñecida %(roomId)s", + "Room": "Sala", + "Failed to save settings": "Fallo ao gardar os axustes", + "Failed to reject invite": "Fallo ao rexeitar o convite", + "Fill screen": "Encher pantalla", + "Click to unmute video": "Pulse para escoitar vídeo", + "Click to mute video": "Pulse para acalar video", + "Click to unmute audio": "Pulse para escoitar audio", + "Click to mute audio": "Pulse para acalar audio", + "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Intentouse cargar un punto concreto do historial de esta sala, pero vostede non ten permiso para ver a mensaxe en cuestión.", + "Tried to load a specific point in this room's timeline, but was unable to find it.": "Intentouse cargar un punto específico do historial de esta sala, pero non se puido atopar.", + "Failed to load timeline position": "Fallo ao cargar posición da liña temporal", + "Uploading %(filename)s and %(count)s others|other": "Subindo %(filename)s e %(count)s máis", + "Uploading %(filename)s and %(count)s others|zero": "Subindo %(filename)s", + "Uploading %(filename)s and %(count)s others|one": "Subindo %(filename)s e %(count)s máis", + "Light theme": "Decorado claro", + "Dark theme": "Decorado oscuro", + "Status.im theme": "Decorado Status.im", + "Can't load user settings": "Non se puideron cargar os axustes de usuaria", + "Server may be unavailable or overloaded": "O servidor podería non está dispoñible ou sobrecargado", + "Sign out": "Desconectar", + "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Por seguridade, ao desconectarse borrará todas as chaves de cifrado extremo-a-extremo en este navegador. Si quere poder descifrar o historial da conversa en futuras sesións en Riot, por favor exporte as chaves da sala e gárdeas en lugar seguro.", + "Failed to change password. Is your password correct?": "Fallo ao cambiar o contrasinal. É correcto o contrasinal?", + "Success": "Parabéns", + "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "O seu contrasinal cambiouse correctamente. Non recibirá notificacións tipo push en outros dispositivos ate que se conecte novamente en eles", + "Remove Contact Information?": "Eliminar información do contacto?", + "Remove %(threePid)s?": "Eliminar %(threePid)s?", + "Unable to remove contact information": "Non se puido eliminar a información do contacto", + "Refer a friend to Riot:": "Convide a un amigo a Riot:", + "Interface Language": "Idioma da Interface", + "User Interface": "Interface de usuaria", + "Autocomplete Delay (ms):": "Retraso no autocompletado (ms):", + "": "", + "Import E2E room keys": "Importar chaves E2E da sala", + "Cryptography": "Criptografía", + "Device ID:": "ID de dispositivo:", + "Device key:": "Chave do dispositivo:", + "Ignored Users": "Usuarias ignoradas", + "Bug Report": "Informe de fallo", + "Found a bug?": "Atopou un fallo?", + "Report it": "Informe", + "Analytics": "Analytics", + "Riot collects anonymous analytics to allow us to improve the application.": "Riot recolle información analítica anónima para permitirnos mellorar o aplicativo.", + "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "A intimidade impórtanos, así que non recollemos información personal ou identificable nos datos dos nosos análises.", + "Learn more about how we use analytics.": "Saber máis sobre cómo utilizamos analytics.", + "Labs": "Labs", + "These are experimental features that may break in unexpected ways": "Estas son características experimentais que poderían dar lugar a fallos non agardados", + "Use with caution": "Utilice con precaución", + "Deactivate my account": "Desactivar a miña conta", + "Clear Cache": "Limpar caché", + "Clear Cache and Reload": "Limpar caché e recargar", + "Updates": "Actualizacións", + "Check for update": "Comprobar actualización", + "Reject all %(invitedRooms)s invites": "Rexeitar todos os %(invitedRooms)s convites", + "Bulk Options": "Opcións en bloque", + "Desktop specific": "Específicas de escritorio", + "Start automatically after system login": "Iniciar automáticamente despóis de iniciar sesión", + "No media permissions": "Sen permisos de medios", + "You may need to manually permit Riot to access your microphone/webcam": "Igual ten que permitir manualmente a Riot acceder ao seus micrófono e cámara", + "Missing Media Permissions, click here to request.": "Faltan permisos de medios, pulse aquí para solicitalos.", + "No Microphones detected": "Non se detectaron micrófonos", + "No Webcams detected": "Non se detectaron cámaras", + "Default Device": "Dispositivo por omisión", + "Microphone": "Micrófono", + "Camera": "Cámara", + "VoIP": "VoIP", + "Email": "Correo-e", + "Add email address": "Engadir enderezo correo-e", + "Notifications": "Notificacións", + "Profile": "Perfil", + "Display name": "Nome mostrado", + "Account": "Conta", + "To return to your account in future you need to set a password": "Estableza un contrasinal para voltar a súa conta con posterioridade", + "Logged in as:": "Conectada como:", + "Access Token:": "Testemuño de acceso:", + "click to reveal": "pulse para revelar", + "Homeserver is": "O servidor de inicio é", + "Identity Server is": "O servidor de identidade é", + "matrix-react-sdk version:": "versión matrix-react-sdk:", + "riot-web version:": "versión riot-web:", + "olm version:": "versión olm:", + "Failed to send email": "Fallo ao enviar correo-e", + "The email address linked to your account must be entered.": "Debe introducir o correo-e ligado a súa conta.", + "A new password must be entered.": "Debe introducir un novo contrasinal.", + "New passwords must match each other.": "Os novos contrasinais deben ser coincidentes.", + "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Detectáronse datos de una versión anterior de Riot. Esto causará un mal funcionamento da criptografía extremo-a-extremo na versión antiga. As mensaxes cifradas extremo-a-extremo intercambiadas mentras utilizaba a versión anterior poderían non ser descifrables en esta versión. Esto tamén podería causar que mensaxes intercambiadas con esta versión tampouco funcionasen. Si ten problemas, desconéctese e conéctese de novo. Para manter o historial de mensaxes, exporte e reimporte as súas chaves.", + "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.": "O restablecemento do contrasinal restablecerá tamén as chaves de cifrado extremo-a-extremo en todos os dispositivos, facendo o historial de chat cifrado non lexible, a menos que primeiro exporte as chaves da sala e as reimporte posteriormente. No futuro melloraremos esto.", + "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "Enviouse un email a %(emailAddress)s. Unha vez siga a ligazón que contén, pulse abaixo.", + "I have verified my email address": "Validei o meu enderezo de correo-e", + "Your password has been reset": "Restableceuse o seu contrasinal", + "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": "Foi desconectado de todos os seus dispositivos e xa non recibirá notificacións push. Para reactivar as notificacións, conéctese de novo en cada dispositivo", + "Return to login screen": "Voltar a pantalla de conexión", + "To reset your password, enter the email address linked to your account": "Para restablecer o seu contrasinal, introduza o enderezo de correo electrónico ligado a súa conta", + "New password": "Novo contrasinal", + "Confirm your new password": "Confirme o seu novo contrasinal", + "Send Reset Email": "Enviar correo-e de restablecemento", + "Create an account": "Crear unha conta", + "This Home Server does not support login using email address.": "Este servidor non soporta a conexión utilizando un enderezo de correo-e.", + "Incorrect username and/or password.": "Nome de usuaria ou contrasinal non válidos.", + "Please note you are logging into the %(hs)s server, not matrix.org.": "Teña en conta que se está a conectar ao servidor %(hs)s, non a matrix.org.", + "Guest access is disabled on this Home Server.": "O acceso de convidados está deshabilitado en este servidor de inicio.", + "The phone number entered looks invalid": "O número de teléfono introducido non semella ser válido", + "This homeserver doesn't offer any login flows which are supported by this client.": "Este servidor non ofrece ningún sistema de conexión que soporte este cliente.", + "Error: Problem communicating with the given homeserver.": "Fallo: problema ao comunicarse con servidor proporcionado.", + "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Non se pode conectar ao servidor vía HTTP cando na barra de enderezos do navegador está HTTPS. Utilice HTTPS ou active scripts non seguros.", + "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Non se conectou ao servidor - por favor comprobe a conexión, asegúrese de o certificado SSL do servidor é de confianza, e que ningún engadido do navegador está bloqueando as peticións.", + "Login as guest": "Conexión como convidado", + "Sign in to get started": "Conéctese para iniciar", + "Failed to fetch avatar URL": "Fallo ao obter o URL do avatar", + "Set a display name:": "Establecer nome público:", + "Upload an avatar:": "Suba un avatar:", + "This server does not support authentication with a phone number.": "O servidor non soporta a autenticación con número de teléfono.", + "Missing password.": "Falta contrasinal.", + "Passwords don't match.": "Non coinciden os contrasinais.", + "Password too short (min %(MIN_PASSWORD_LENGTH)s).": "Contrasinal demasiado curto (min %(MIN_PASSWORD_LENGTH)s).", + "This doesn't look like a valid email address.": "Non semella ser un enderezo de correo-e válido.", + "This doesn't look like a valid phone number.": "Non semella ser un número de teléfono válido.", + "You need to enter a user name.": "É preciso que introduza un nome de usuaria.", + "An unknown error occurred.": "Aconteceu un erro descoñecido.", + "I already have an account": "Xa teño unha conta", + "Displays action": "Mostra acción", + "Bans user with given id": "Prohibe a usuaria co ID indicado", + "Unbans user with given id": "Permite de novo a usuaria co ID proporcionado", + "Define the power level of a user": "Define o nivel de permisos de unha usuaria", + "Invites user with given id to current room": "Convida a usuaria co id proporcionado a sala actual", + "Joins room with given alias": "Únese a sala co alias proporcionado", + "Sets the room topic": "Establece o asunto da sala", + "Kicks user with given id": "Expulsa usuaria co id proporcionado", + "Changes your display nickname": "Cambia o alcume mostrado", + "Searches DuckDuckGo for results": "Buscar en DuckDuckGo por resultados", + "Changes colour scheme of current room": "Cambia o esquema de cores da sala actual", + "Verifies a user, device, and pubkey tuple": "Valida o conxunto de usuaria, dispositivo e chave pública", + "Ignores a user, hiding their messages from you": "Ignora unha usuaria, agochándolle as súas mensaxes", + "Stops ignoring a user, showing their messages going forward": "Deixa de ignorar unha usuaria, mostrándolles as súas mensaxes a partir de agora", + "Commands": "Comandos", + "Results from DuckDuckGo": "Resultados desde DuckDuckGo", + "Emoji": "Emoji", + "Notify the whole room": "Notificar a toda a sala", + "Room Notification": "Notificación da Sala", + "Users": "Usuarias", + "unknown device": "dispositivo descoñecido", + "NOT verified": "Non validado", + "verified": "validado", + "Verification": "Validación", + "Ed25519 fingerprint": "pegada Ed25519", + "User ID": "ID de usuaria", + "Curve25519 identity key": "Chave de identidade Curve25519", + "none": "nada", + "Claimed Ed25519 fingerprint key": "Chave de pegada pedida Ed25519", + "Algorithm": "Algoritmo", + "unencrypted": "non cifrado", + "Decryption error": "Fallo ao descifrar", + "Session ID": "ID de sesión", + "End-to-end encryption information": "Información do cifrado extremo-a-extremo", + "Event information": "Información do evento", + "Sender device information": "Información do dispositivo do remitente", + "Passphrases must match": "As frases de paso deben coincidir", + "Passphrase must not be empty": "A frase de paso non pode quedar baldeira", + "Export room keys": "Exportar chaves da sala", + "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Este proceso permítelle exportar a un ficheiro local as chaves para as mensaxes que recibeu en salas cifradas. Posteriormente permitiralle importar as chaves en outro cliente Matrix no futuro, así o cliente poderá descifrar esas mensaxes.", + "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "O ficheiro exportado permitiralle a calquera que poida lelo descifrar e cifrar mensaxes que vostede ve, así que debería ter coidado e gardalo de xeito seguro. Para axudarlle, debe introducir unha frase de paso aquí abaixo que será utilizada para cifrar os datos exportados. Só será posible importar os datos utilizando a misma frase de paso.", + "Enter passphrase": "Introduza a frase de paso", + "Confirm passphrase": "Confirme a frase de paso", + "Export": "Exportar", + "Import room keys": "Importar chaves de sala", + "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Este proceso permítelle importar chaves de cifrado que vostede exportou de outro cliente Matrix. Así poderá descifrar calquer mensaxe que o outro cliente puidese cifrar.", + "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "O ficheiro exportado estará protexido con unha frase de paso. Debe introducir aquí esa frase de paso para descifrar o ficheiro.", + "File to import": "Ficheiro a importar", + "Import": "Importar", + "The information being sent to us to help make Riot.im better includes:": "A información enviada a Riot.im para axudarnos a mellorar inclúe:", + "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "Tamén rexistramos cada páxina que vostede utiliza no aplicativo (actualmente ), o User Agent () e a resolución do dispositivo ().", + "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Si esta páxina inclúe información identificable como ID de grupo, usuario ou sala, estes datos son eliminados antes de ser enviados ao servidor.", + "The platform you're on": "A plataforma na que está", + "The version of Riot.im": "A versión de Riot.im", + "Whether or not you're logged in (we don't record your user name)": "Si está ou non conectada (non gardamos o nome de usuaria)", + "Your language of choice": "A súa preferencia de idioma", + "Which officially provided instance you are using, if any": "Qué instancia oficial está a utilizar, si algunha", + "Whether or not you're using the Richtext mode of the Rich Text Editor": "Si utiliza o modo Richtext ou non do Editor Rich Text", + "Your homeserver's URL": "O URL do seu servidor de inicio", + "Your identity server's URL": "O URL da súa identidade no servidor", + "In reply to ": "En resposta a ", + "This room is not public. You will not be able to rejoin without an invite.": "Esta sala non é pública. Non poderá voltar a ela sin un convite.", + "This room is not showing flair for any communities": "Esta sala non mostra popularidade para as comunidades" } From 5e34c8043f9026ec21c6e8cd8e055473d7e9611c Mon Sep 17 00:00:00 2001 From: Walter Date: Mon, 29 Jan 2018 17:04:22 +0000 Subject: [PATCH 0210/1160] Translated using Weblate (German) Currently translated at 98.9% (974 of 984 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index f60b4e582d..d0c193bfa9 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -972,5 +972,7 @@ "Your language of choice": "Deine ausgewählte Sprache", "Whether or not you're using the Richtext mode of the Rich Text Editor": "Ob du den Richtext-Modus des Editors benutzt oder nicht", "Your homeserver's URL": "Die URL deines Homeservers", - "Your identity server's URL": "Die URL deines Identitätsservers" + "Your identity server's URL": "Die URL deines Identitätsservers", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s", + "Tag Panel": "Beschriftungsfeld" } From fd4fc883c16579b0dc644bf75a5ff2279b4d2594 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Thu, 25 Jan 2018 15:24:21 +0000 Subject: [PATCH 0211/1160] Translated using Weblate (Hungarian) Currently translated at 100.0% (984 of 984 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index f2aa17c764..f2e48905d5 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -912,7 +912,7 @@ "Hide avatar changes": "Avatar változások elrejtése", "Hide display name changes": "Név változások elrejtése", "Enable inline URL previews by default": "Beágyazott URL előnézetek alapértelmezett engedélyezése", - "Enable URL previews for this room (only affects you)": "URL előnézet engedélyezése ebben a szobában (csak téged érint)", + "Enable URL previews for this room (only affects you)": "URL előnézet ebben a szobában (csak téged érint)", "Enable URL previews by default for participants in this room": "URL előnézet alapértelmezett engedélyezése a szoba tagságának", "URL previews are enabled by default for participants in this room.": "Az URL előnézetek alapértelmezetten engedélyezve vannak a szobában jelenlévőknek.", "URL previews are disabled by default for participants in this room.": "Az URL előnézet alapértelmezetten tiltva van a szobában jelenlévőknek.", From 977dec40a30dacefe4e58a2d7bf3649a45e82150 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D1=80=D0=BA=D0=BE=20=D0=9C=2E=20=D0=9A=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D0=B8=D1=9B?= Date: Fri, 26 Jan 2018 20:50:25 +0000 Subject: [PATCH 0212/1160] Translated using Weblate (Serbian) Currently translated at 60.8% (599 of 984 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sr/ --- src/i18n/strings/sr.json | 218 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 217 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index 87c8aea100..6396455f9d 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -381,5 +381,221 @@ "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Не могу да утврдим да ли се адреса на овој позивници поклапа са оном која је повезана са вашим налогом.", "This invitation was sent to an email address which is not associated with this account:": "Ова позивница је послата на мејл адресу која није повезана са вашим налогом:", "You may wish to login with a different account, or add this email to this account.": "Можда бисте желели да се пријавите са другим налогом или да додате овај мејл у ваш налог.", - "You have been invited to join this room by %(inviterName)s": "Позвани сте да приступите овој соби од стране корисника %(inviterName)s" + "You have been invited to join this room by %(inviterName)s": "Позвани сте да приступите овој соби од стране корисника %(inviterName)s", + "Would you like to accept or decline this invitation?": "Да ли желите да прихватите или одбијете ову позивницу?", + "Reason: %(reasonText)s": "Разлог: %(reasonText)s", + "Rejoin": "Поново приступи", + "You have been kicked from %(roomName)s by %(userName)s.": "Корисник %(userName)s вас је избацио из собе %(roomName)s.", + "You have been kicked from this room by %(userName)s.": "Корисник %(userName)s вас је избацио из ове собе.", + "You have been banned from %(roomName)s by %(userName)s.": "Корисник %(userName)s је вама забранио приступ соби %(roomName)s.", + "You have been banned from this room by %(userName)s.": "Корисник %(userName)s је вама забранио приступ овој соби.", + "This room": "Ова соба", + "%(roomName)s does not exist.": "Соба %(roomName)s не постоји.", + "%(roomName)s is not accessible at this time.": "Соба %(roomName)s није доступна у овом тренутку.", + "You are trying to access %(roomName)s.": "Покушавате да приступите соби %(roomName)s.", + "You are trying to access a room.": "Покушавате да приступите соби.", + "Click here to join the discussion!": "Кликните овде да бисте се придружили разговору!", + "This is a preview of this room. Room interactions have been disabled": "Ово је претпреглед ове собе. Интеракције у соби су онемогућене", + "To change the room's avatar, you must be a": "Да бисте променили аватар собе, морате бити", + "To change the room's name, you must be a": "Да бисте променили назив собе, морате бити", + "To change the room's main address, you must be a": "Да бисте променили главну адресу собе, морате бити", + "To change the room's history visibility, you must be a": "Да бисте променили видљивост историјата собе, морате бити", + "To change the permissions in the room, you must be a": "Да бисте променили овлашћења у соби, морате бити", + "To change the topic, you must be a": "Да бисте променили тему, морате бити", + "To modify widgets in the room, you must be a": "Да бисте изменили виџете у соби, морате бити", + "Failed to unban": "Нисам успео да скинем забрану", + "Banned by %(displayName)s": "Приступ забранио %(displayName)s", + "Privacy warning": "Упозорење о приватности", + "Changes to who can read history will only apply to future messages in this room": "Измене права читања историјата биће примењене на будуће поруке у овој соби", + "The visibility of existing history will be unchanged": "Видљивост постојећег историјата неће бити промењена", + "unknown error code": "непознати код грешке", + "Failed to forget room %(errCode)s": "Нисам успео да заборавим собу %(errCode)s", + "End-to-end encryption is in beta and may not be reliable": "Шифровање с краја на крај је у бета фази и може бити непоуздано", + "You should not yet trust it to secure data": "Не бисте требали да му још верујете за обезбеђивање података", + "Devices will not yet be able to decrypt history from before they joined the room": "Уређаји још не могу да дешифрују историјат настао пре приступања соби", + "Once encryption is enabled for a room it cannot be turned off again (for now)": "Када се шифровање омогући за собу, не може се поново искључити (за сада)", + "Encrypted messages will not be visible on clients that do not yet implement encryption": "Шифроване поруке неће бити видљиве на клијентима који још не подржавају шифровање", + "Enable encryption": "Омогући шифровање", + "(warning: cannot be disabled again!)": "(упозорење: не може се поново искључити!)", + "Encryption is enabled in this room": "Шифровање је омогућено у овој соби", + "Encryption is not enabled in this room": "Шифровање није омогућено у овој соби", + "Privileged Users": "Овлашћени корисници", + "%(user)s is a": "%(user)s је", + "No users have specific privileges in this room": "Нема корисника са посебним овлашћењима у овој соби", + "Banned users": "Корисници са забраном приступа", + "This room is not accessible by remote Matrix servers": "Овој соби не могу приступити удаљени Матрикс сервери", + "Leave room": "Напусти собу", + "Favourite": "Омиљено", + "Tagged as: ": "Означено као: ", + "To link to a room it must have an address.": "Да бисте слали везу собе, она мора имати адресу.", + "Guests cannot join this room even if explicitly invited.": "Гости не могу приступити овој соби чак и ако су експлицитно позвани.", + "Click here to fix": "Кликните овде да бисте поправили", + "Who can access this room?": "Ко може приступити овој соби?", + "Only people who have been invited": "Само особе које су позване", + "Anyone who knows the room's link, apart from guests": "Било ко ко зна везу ка соби, осим гостију", + "Anyone who knows the room's link, including guests": "Било ко ко зна везу ка соби, укључујући и госте", + "Publish this room to the public in %(domain)s's room directory?": "Објавити ову собу у јавној фасцикли соба на домену %(domain)s?", + "Who can read history?": "Ко може читати историјат?", + "Anyone": "Било ко", + "Members only (since the point in time of selecting this option)": "Само чланови (од тренутка бирања ове опције)", + "Members only (since they were invited)": "Само чланови (од тренутка позивања)", + "Members only (since they joined)": "Само чланови (од приступања)", + "Permissions": "Овлашћења", + "The default role for new room members is": "Подразумевана улога за нове чланове у соби је", + "To send messages, you must be a": "Да бисте слали поруке, морате бити", + "To invite users into the room, you must be a": "Да бисте позивали кориснике у собу, морате бити", + "To configure the room, you must be a": "Да бисте подешавали собу, морате бити", + "To kick users, you must be a": "Да бисте избацивали кориснике, морате бити", + "To ban users, you must be a": "Да бисте забрањивали приступ корисницима, морате бити", + "To remove other users' messages, you must be a": "Да бисте уклањали поруке других корисника, морате бити", + "To send events of type , you must be a": "Да бисте слали догађаје врсте , морате бити", + "Advanced": "Напредно", + "This room's internal ID is": "Унутрашњи ИБ ове собе је", + "Add a topic": "Додај тему", + "Cancel": "Откажи", + "Scroll to unread messages": "Превуци на непрочитане поруке", + "Jump to first unread message.": "Скочи на прву непрочитану поруку.", + "Close": "Затвори", + "Invalid alias format": "Неисправан облик алијаса", + "'%(alias)s' is not a valid format for an alias": "„%(alias)s 1“ није исправан облик алијаса", + "Invalid address format": "Неисправан облик адресе", + "'%(alias)s' is not a valid format for an address": "„%(alias)s“ није исправан облик адресе", + "not specified": "није наведено", + "not set": "није постављено", + "Remote addresses for this room:": "Удаљене адресе за ову собу:", + "Addresses": "Адресе", + "The main address for this room is": "Главна адреса ове собе је", + "Local addresses for this room:": "Локална адреса ове собе:", + "This room has no local addresses": "Ова соба нема локалних адреса", + "New address (e.g. #foo:%(localDomain)s)": "Нова адреса (нпр.: #soba:%(localDomain)s)", + "Invalid community ID": "Неисправан ИБ заједнице", + "'%(groupId)s' is not a valid community ID": "„%(groupId)s“ није исправан ИБ заједнице", + "Flair": "Беџ", + "Showing flair for these communities:": "Приказујем беџ за ове заједнице:", + "This room is not showing flair for any communities": "Ова соба не приказује беџеве било које заједнице", + "New community ID (e.g. +foo:%(localDomain)s)": "Нови ИБ заједнице (нпр.: +zajednica:%(localDomain)s)", + "You have enabled URL previews by default.": "Омогућили сте подразумеване претпрегледе адреса.", + "You have disabled URL previews by default.": "Онемогућили сте подразумеване претпрегледе адреса.", + "URL previews are enabled by default for participants in this room.": "Претпрегледи адреса су подразумевано омогућени за све чланове ове собе.", + "URL previews are disabled by default for participants in this room.": "Претпрегледи адреса су подразумевано онемогућени за све чланове ове собе.", + "URL Previews": "Претпрегледи адреса", + "Error decrypting audio": "Грешка при дешифровању звука", + "Error decrypting attachment": "Грешка при дешифровању прилога", + "Decrypt %(text)s": "Дешифруј %(text)s", + "Download %(text)s": "Преузми %(text)s", + "Invalid file%(extra)s": "Неисправна датотека %(extra)s", + "Error decrypting image": "Грешка при дешифровању слике", + "Image '%(Body)s' cannot be displayed.": "Слика „%(Body)s“ се не може приказати.", + "This image cannot be displayed.": "Ова слика се не може приказати.", + "Error decrypting video": "Грешка при дешифровању видеа", + "%(senderDisplayName)s changed the avatar for %(roomName)s": "Корисник %(senderDisplayName)s је променио аватара собе %(roomName)s", + "%(senderDisplayName)s removed the room avatar.": "Корисник %(senderDisplayName)s је уклонио аватара собе.", + "%(senderDisplayName)s changed the room avatar to ": "Корисник %(senderDisplayName)s је променио аватара собе у ", + "Copied!": "Копирано!", + "Failed to copy": "Нисам успео да ископирам", + "Add an Integration": "Додај уградњу", + "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?": "Бићете пребачени на сајт треће стране да бисте се идентификовали са својим налогом зарад коришћења уградње %(integrationsUrl)s. Да ли желите да наставите?", + "Removed or unknown message type": "Уклоњена порука или порука непознатог типа", + "Message removed by %(userId)s": "Поруку је уклонио корисник %(userId)s", + "Message removed": "Порука је уклоњена", + "Robot check is currently unavailable on desktop - please use a web browser": "Роботска провера тренутно није доступна у стоним програмима, користите веб прегледач", + "This Home Server would like to make sure you are not a robot": "Овај кућни сервер жели да се увери да нисте робот", + "Sign in with CAS": "Пријавите се уз CAS", + "Custom Server Options": "Прилагођене опције сервера", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "Можете користити прилагођене опције сервера да бисте се пријавили на друге Матрикс сервере тако што ћете навести другачију адресу кућног сервера.", + "This allows you to use this app with an existing Matrix account on a different home server.": "Ово омогућава коришћење ове апликације са постојећим Матрикс налогом на другом кућном серверу.", + "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "Можете такође поставити прилагођени сервер идентитета али ово уобичајено спречава радње са другим корисницима које користе мејл адресе.", + "Dismiss": "Одбаци", + "To continue, please enter your password.": "Да бисте наставили, унесите вашу лозинку.", + "Password:": "Лозинка:", + "An email has been sent to %(emailAddress)s": "Мејл је послат на адресу %(emailAddress)s", + "Please check your email to continue registration.": "Проверите ваше сандуче да бисте наставили регистровање.", + "Token incorrect": "Жетон је нетачан", + "A text message has been sent to %(msisdn)s": "Текстуална порука је послата на %(msisdn)s", + "Please enter the code it contains:": "Унесите код који се налази у њој:", + "Start authentication": "Започните идентификацију", + "powered by Matrix": "покреће Матрикс", + "Username on %(hs)s": "Корисничко на %(hs)s", + "User name": "Корисничко име", + "Mobile phone number": "Мобилни број телефона", + "Forgot your password?": "Заборавили сте лозинку?", + "%(serverName)s Matrix ID": "%(serverName)s Матрикс ИБ", + "Sign in with": "Пријавите се преко", + "Email address": "Мејл адреса", + "Sign in": "Пријави се", + "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Ако не наведете мејл адресу, нећете моћи да опоравите вашу лозинку. Да ли сте сигурни?", + "Email address (optional)": "Мејл адреса (изборно)", + "You are registering with %(SelectedTeamName)s": "Региструјете се уз %(SelectedTeamName)s", + "Mobile phone number (optional)": "Број мобилног телефона (изборно)", + "Register": "Регистровање", + "Default server": "Подразумевани сервер", + "Custom server": "Прилагођени сервер", + "Home server URL": "Адреса кућног сервера", + "Identity server URL": "Адреса сервера идентитета", + "What does this mean?": "Шта ово значи?", + "Remove from community": "Уклони из заједнице", + "Disinvite this user from community?": "Отказати позивницу у заједницу овом кориснику?", + "Remove this user from community?": "Уклонити овог корисника из заједнице?", + "Failed to withdraw invitation": "Нисам успео да повучем позивницу", + "Failed to remove user from community": "Нисам успео да уклоним кориснике из заједнице", + "Filter community members": "Филтрирај чланове заједнице", + "Flair will appear if enabled in room settings": "Беџ ће се приказати ако се омогући у подешавањима собе", + "Flair will not appear": "Беџ се неће приказати", + "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Да ли сте сигурни да желите да уклоните собу „%(roomName)s“ из %(groupId)s?", + "Removing a room from the community will also remove it from the community page.": "Уклањање собе из заједнице је такође уклања и са странице заједнице.", + "Remove": "Уклони", + "Failed to remove room from community": "Нисам успео да уклоним собу из заједнице", + "Failed to remove '%(roomName)s' from %(groupId)s": "Нисам успео да уклоним собу „%(roomName)s“ из %(groupId)s", + "Something went wrong!": "Нешто је пошло наопако!", + "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "Видљивост собе „%(roomName)s“ у %(groupId)s није могла бити измењена.", + "Visibility in Room List": "Видљивост у списку соба", + "Visible to everyone": "Видљиво свима", + "Only visible to community members": "Видљиво само члановима заједнице", + "Filter community rooms": "Филтрирај собе заједнице", + "Something went wrong when trying to get your communities.": "Нешто је пошло наопако приликом добављања ваших заједница.", + "Display your community flair in rooms configured to show it.": "Приказује ваш беџ заједнице у собама које су подешене за то.", + "You're not currently a member of any communities.": "Тренутно нисте члан било које заједнице.", + "Unknown Address": "Непозната адреса", + "NOTE: Apps are not end-to-end encrypted": "НАПОМЕНА: Апликације не користе шифровање с краја на крај", + "Do you want to load widget from URL:": "Да ли желите да учитате виџет са адресе:", + "Allow": "Дозволи", + "Delete Widget": "Обриши виџет", + "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Брисање виџета уклања виџет за све чланове ове собе. Да ли сте сигурни да желите обрисати овај виџет?", + "Delete widget": "Обриши виџет", + "Revoke widget access": "Опозови приступ виџету", + "Minimize apps": "Умањи апликације", + "Edit": "Уреди", + "Create new room": "Направи нову собу", + "Unblacklist": "Скини са црног списка", + "Blacklist": "Стави на црни списак", + "Unverify": "Скини потврду", + "Verify...": "Потврди...", + "No results": "Нема резултата", + "Delete": "Обриши", + "Communities": "Заједнице", + "Home": "Почетна", + "Integrations Error": "Грешка са уградњама", + "Could not connect to the integration server": "Не могу да се повежем на сервер за уградње", + "Manage Integrations": "Управљај уградњама", + "%(nameList)s %(transitionList)s": "%(nameList)s %(transitionList)s", + "%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)s су ушли %(count)s пута", + "%(severalUsers)sjoined %(count)s times|one": "%(severalUsers)s је ушло", + "%(oneUser)sjoined %(count)s times|other": "Корисник %(oneUser)s је ушао %(count)s пута", + "%(oneUser)sjoined %(count)s times|one": "Корисник %(oneUser)s је ушао", + "%(severalUsers)sleft %(count)s times|other": "%(severalUsers)s је изашло %(count)s пута", + "%(severalUsers)sleft %(count)s times|one": "%(severalUsers)s је изашло", + "%(oneUser)sleft %(count)s times|other": "Корисник %(oneUser)s је изашло %(count)s пута", + "%(oneUser)sleft %(count)s times|one": "Корисник %(oneUser)s је изашао", + "%(severalUsers)sjoined and left %(count)s times|other": "%(severalUsers)s је ушло и изашло %(count)s пута", + "%(severalUsers)sjoined and left %(count)s times|one": "%(severalUsers)s је ушло и изашло", + "%(oneUser)sjoined and left %(count)s times|other": "%(oneUser)s је ушао и изашао %(count)s пута", + "%(oneUser)sjoined and left %(count)s times|one": "%(oneUser)s је ушао и изашао", + "%(severalUsers)sleft and rejoined %(count)s times|other": "%(severalUsers)s је изашло и поново ушло %(count)s пута", + "%(severalUsers)sleft and rejoined %(count)s times|one": "%(severalUsers)s је изашло и поново ушло", + "%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)s је изашао и поново ушао %(count)s пута", + "%(oneUser)sleft and rejoined %(count)s times|one": "%(oneUser)s је изашао и поново ушао", + "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)s је одбило њихове позивнице %(count)s пута", + "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)s је одбило њихове позивнице", + "%(oneUser)srejected their invitation %(count)s times|other": "%(oneUser)s је одбио позивницу %(count)s пута", + "%(oneUser)srejected their invitation %(count)s times|one": "%(oneUser)s је одбио позивницу" } From 8a6727ea98ea8034bbe79d29d6e6bc6585dbff43 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 30 Jan 2018 10:55:23 +0000 Subject: [PATCH 0213/1160] This is actually MFileBody not MImageBody, change classname Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/messages/MFileBody.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/views/messages/MFileBody.js b/src/components/views/messages/MFileBody.js index d106d7368e..c324c291e7 100644 --- a/src/components/views/messages/MFileBody.js +++ b/src/components/views/messages/MFileBody.js @@ -295,7 +295,7 @@ module.exports = React.createClass({ return ( -
    +
    { _t("Decrypt %(text)s", { text: text }) } @@ -327,7 +327,7 @@ module.exports = React.createClass({ } return ( -
    +
    { /* * Add dummy copy of the "a" tag @@ -347,7 +347,7 @@ module.exports = React.createClass({ if (this.props.tileShape === "file_grid") { return ( -
    +
    { fileName } @@ -360,7 +360,7 @@ module.exports = React.createClass({ } else { return ( -
    +
    { _t("Download %(text)s", { text: text }) } From 3a33eea5e9569b54094b99ae7b729a7cb5e6cdab Mon Sep 17 00:00:00 2001 From: Nathan van Beelen Date: Tue, 30 Jan 2018 20:29:30 +0000 Subject: [PATCH 0214/1160] Translated using Weblate (Dutch) Currently translated at 75.5% (743 of 984 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/nl/ --- src/i18n/strings/nl.json | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index 492d9d596c..9ad7c6d5bb 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -727,5 +727,20 @@ "Presence Management": "Presentie Beheer", "Tag Panel": "Label Paneel", "Disable Emoji suggestions while typing": "Emoji suggesties tijdens het typen uitzetten", - "Hide avatar changes": "Avatar veranderingen verbergen" + "Hide avatar changes": "Avatar veranderingen verbergen", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(day)s %(monthName)s %(fullYear)s", + "Hide display name changes": "Weergavenaam wijzigingen verbergen", + "Enable inline URL previews by default": "Inline URL voorvertoning standaard aanzetten", + "Enable URL previews for this room (only affects you)": "URL voorvertoning in deze ruimte aanzetten (geldt alleen voor jou)", + "Enable URL previews by default for participants in this room": "URL voorvertoning standaard voor de gebruikers in deze ruimte aanzetten", + "Delete %(count)s devices|other": "Verwijder %(count)s apparaten", + "Delete %(count)s devices|one": "Verwijder apparaat", + "Select devices": "Apparaten selecteren", + "%(senderName)s sent an image": "%(senderName)s heeft een afbeelding gestuurd", + "%(senderName)s sent a video": "%(senderName)s heeft een video gestuurd", + "%(senderName)s uploaded a file": "%(senderName)s heeft een bestand geüpload", + "Disinvite this user?": "Uitnodiging van deze gebruiker intrekken?", + "Kick this user?": "Deze gebruiker er uit zetten?", + "Unban this user?": "Deze gebruiker ontbannen?", + "Ban this user?": "Deze gebruiker bannen?" } From 497cf21c8669f6f17c3498714b880c01f1209c85 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 1 Feb 2018 10:31:44 +0000 Subject: [PATCH 0215/1160] Translated using Weblate (Hungarian) Currently translated at 100.0% (984 of 984 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index f2e48905d5..7bfadfc96e 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -903,7 +903,7 @@ "Room Notification": "Szoba értesítések", "Show these rooms to non-members on the community page and room list?": "Mutassuk meg ezeket a szobákat kívülállóknak a közösségi oldalon és a szobák listájában?", "Sign in to get started": "Az induláshoz jelentkezz be", - "Status.im theme": "Állapot téma", + "Status.im theme": "Status.im téma", "Please note you are logging into the %(hs)s server, not matrix.org.": "Figyelem, a %(hs)s szerverre jelentkezel be és nem a matrix.org szerverre.", "Username on %(hs)s": "Felhasználónév a %(hs)s szerveren", "Restricted": "Korlátozott", From 41c9cb1c27112ea024605a46bb62a72f773545bc Mon Sep 17 00:00:00 2001 From: Krombel Date: Thu, 1 Feb 2018 15:11:44 +0000 Subject: [PATCH 0216/1160] Translated using Weblate (German) Currently translated at 100.0% (984 of 984 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index d0c193bfa9..dd5ed801a3 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -974,5 +974,15 @@ "Your homeserver's URL": "Die URL deines Homeservers", "Your identity server's URL": "Die URL deines Identitätsservers", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s", - "Tag Panel": "Beschriftungsfeld" + "Tag Panel": "Beschriftungsfeld", + "Message Replies": "Antworten auf Nachrichten", + "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Du wirst nicht in der Lage sein, die Änderung zurückzusetzen, da du dich degradierst. Wenn du der letze Nutzer mit Berechtigungen bist, wird es unmöglich sein die Privilegien zurückzubekommen.", + "Community IDs cannot not be empty.": "Community-IDs können nicht leer sein.", + "Show devices, send anyway or cancel.": "Geräte anzeigen, trotzdem senden oder abbrechen.", + "Learn more about how we use analytics.": "Lerne mehr darüber, wie wir die Analysedaten nutzen.", + "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Wenn diese Seite identifizierbare Informationen sowie Raum, Nutzer oder Gruppen-ID enthalten, werden diese Daten entfernt bevor sie an den Server gesendet werden.", + "Whether or not you're logged in (we don't record your user name)": "Ob oder ob du nicht angemeldet bist (wir zeichnen deinen Benutzernamen nicht auf)", + "Which officially provided instance you are using, if any": "Welche offiziell angebotene Instanz du nutzt, wenn es der Fall ist", + "In reply to ": "Antwort zu ", + "This room is not public. You will not be able to rejoin without an invite.": "Dies ist kein öffentlicher Raum. Du wirst diesen nicht ohne Einladung wieder beitreten können." } From d1a24ac87b56d5fb7a1b2f28ea6189bcfc508227 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 2 Feb 2018 08:12:56 +0000 Subject: [PATCH 0217/1160] guard against m.room.aliases events with no keys (redaction?) Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/room_settings/AliasSettings.js | 4 ++-- src/components/views/rooms/RoomSettings.js | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/views/room_settings/AliasSettings.js b/src/components/views/room_settings/AliasSettings.js index 2915a061de..bd92d75dd9 100644 --- a/src/components/views/room_settings/AliasSettings.js +++ b/src/components/views/room_settings/AliasSettings.js @@ -58,8 +58,8 @@ module.exports = React.createClass({ state.domainToAliases = this.aliasEventsToDictionary(aliasEvents); - state.remoteDomains = Object.keys(state.domainToAliases).filter((alias) => { - return alias !== localDomain; + state.remoteDomains = Object.keys(state.domainToAliases).filter((domain) => { + return domain !== localDomain && state.domainToAliases[domain].length > 0; }); if (canonicalAliasEvent) { diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index 0bbf33478d..ea4a29615e 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -774,7 +774,8 @@ module.exports = React.createClass({ const aliasEvents = this.props.room.currentState.getStateEvents('m.room.aliases') || []; let aliasCount = 0; aliasEvents.forEach((event) => { - aliasCount += event.getContent().aliases.length; + const aliases = event.getContent().aliases || []; + aliasCount += aliases.length; }); if (this.state.join_rule === "public" && aliasCount == 0) { From d884596a1f2b770fac9bb940042ade0a1d945dff Mon Sep 17 00:00:00 2001 From: Nathan van Beelen Date: Sun, 4 Feb 2018 14:22:56 +0000 Subject: [PATCH 0218/1160] Translated using Weblate (Dutch) Currently translated at 100.0% (984 of 984 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/nl/ --- src/i18n/strings/nl.json | 248 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 244 insertions(+), 4 deletions(-) diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index 9ad7c6d5bb..b3dcfb3a8b 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -42,7 +42,7 @@ "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s heeft het onderwerp gewijzigd naar \"%(topic)s\".", "Changes to who can read history will only apply to future messages in this room": "Veranderingen aan wie de geschiedenis kan lezen worden alleen maar toegepast op toekomstige berichten in deze ruimte", "Changes your display nickname": "Verandert jouw weergavenaam", - "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Het veranderen van het wachtwoord zal op het moment alle eind-tot-eind encryptie sleutels resetten, wat alle versleutelde chat geschiedenis onleesbaar zou maken, behalve als je eerst je ruimtesleutels exporteert en achteraf opnieuw importeert. Dit zal worden verbeterd in de toekomst.", + "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Het veranderen van het wachtwoord zal op het moment alle eind-tot-eind encryptie sleutels resetten, wat alle versleutelde gespreksgeschiedenis onleesbaar zou maken, behalve als je eerst je ruimtesleutels exporteert en achteraf opnieuw importeert. Dit zal worden verbeterd in de toekomst.", "Clear Cache and Reload": "Legen cache en herlaad", "Clear Cache": "Legen cache", "Click here to fix": "Klik hier om op te lossen", @@ -178,7 +178,7 @@ "Cryptography": "Cryptografie", "Current password": "Huidig wachtwoord", "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s heeft de naam van de ruimte verwijderd.", - "Create a new chat or reuse an existing one": "Maak een nieuwe chat aan of ga verder met een bestaande", + "Create a new chat or reuse an existing one": "Maak een nieuw gesprek aan of hergebruik een al bestaand gesprek", "Create Room": "Maak een ruimte aan", "Curve25519 identity key": "Curve25519-identiteitssleutel", "/ddg is not a command": "/ddg is geen commando", @@ -556,7 +556,7 @@ "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Het te exporteren bestand zal beveiligd zijn met een wachtzin. Je moet hier een wachtzin invoeren om het bestand te ontsleutelen.", "You must join the room to see its files": "Je moet tot een ruimte toetreden om de bestanden te zien", "Reject all %(invitedRooms)s invites": "Alle %(invitedRooms)s uitnodigingen afslaan", - "Start new chat": "Nieuwe chat starten", + "Start new chat": "Nieuw gesprek starten", "Failed to invite": "Niet gelukt om uit te nodigen", "Failed to invite user": "Niet gelukt om de gebruiker uit te nodigen", "Failed to invite the following users to the %(roomName)s room:": "Niet gelukt om de volgende gebruikers voor de %(roomName)s ruimte uit te nodigen:", @@ -742,5 +742,245 @@ "Disinvite this user?": "Uitnodiging van deze gebruiker intrekken?", "Kick this user?": "Deze gebruiker er uit zetten?", "Unban this user?": "Deze gebruiker ontbannen?", - "Ban this user?": "Deze gebruiker bannen?" + "Ban this user?": "Deze gebruiker bannen?", + "Disable big emoji in chat": "Grote emoji in gesprekken uitzetten", + "Mirror local video feed": "Lokale video aanvoering ook op andere locaties (Mirrors) opslaan", + "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Je kan deze actie niet ongedaan maken omdat je jezelf degradeert. Als je het laatste persoon met rechten bent, is het onmogelijk om de rechten terug te krijgen.", + "Unignore": "Niet meer negeren", + "Ignore": "Negeren", + "Jump to read receipt": "Naar het laatst gelezen bericht gaan", + "Mention": "Vermelden", + "Invite": "Uitnodigen", + "User Options": "Gebruikersopties", + "Send an encrypted reply…": "Verstuur een versleuteld antwoord…", + "Send a reply (unencrypted)…": "Verstuur een antwoord (onversleuteld)…", + "Send an encrypted message…": "Verstuur een versleuteld bericht…", + "Send a message (unencrypted)…": "Verstuur een bericht (onversleuteld)…", + "Jump to message": "Naar bericht gaan", + "No pinned messages.": "Geen gepinde berichten.", + "Loading...": "Laden...", + "Pinned Messages": "Gepinde Berichten", + "%(duration)ss": "%(duration)ss", + "%(duration)sm": "%(duration)sm", + "%(duration)sh": "%(duration)su", + "%(duration)sd": "%(duration)sd", + "Online for %(duration)s": "Online voor %(duration)s", + "Idle for %(duration)s": "Inactief voor %(duration)s", + "Offline for %(duration)s": "Offline voor %(duration)s", + "Unknown for %(duration)s": "Onbekend voor %(duration)s", + "Unknown": "Onbekend", + "Replying": "Aan het beantwoorden", + "No rooms to show": "Geen ruimtes om weer te geven", + "Unnamed room": "Ruimte zonder naam", + "World readable": "Leesbaar voor iedereen", + "Guests can join": "Gasten kunnen toetreden", + "Remove avatar": "Avatar verwijderen", + "To change the room's avatar, you must be a": "Om de avatar van de ruimte te verwijderen, moet het volgende zijn:", + "Drop here to favourite": "Hier laten vallen om aan favorieten toe te voegen", + "Drop here to tag direct chat": "Hier laten vallen om als privégesprek te markeren", + "Drop here to restore": "Hier laten vallen om te herstellen", + "Drop here to demote": "Hier laten vallen om te degraderen", + "Community Invites": "Gemeenschapsuitnodigingen", + "You have been kicked from this room by %(userName)s.": "Je bent uit deze ruimte gezet door %(userName)s.", + "You have been banned from this room by %(userName)s.": "Je bent uit deze ruimte verbannen door %(userName)s.", + "You are trying to access a room.": "Je probeert een ruimte te betreden.", + "To change the room's name, you must be a": "Om de ruimtenaam te veranderen moet je het volgende zijn:", + "To change the room's main address, you must be a": "Om het hoofdadres van deze ruimte te wijzigen moet je het volgende zijn:", + "To change the room's history visibility, you must be a": "Om de zichtbaarheid van de geschiedenis van de ruimte te veranderen moet je het volgende zijn:", + "To change the permissions in the room, you must be a": "Om de permissies in de ruimte te veranderen moet je het volgende zijn:", + "To change the topic, you must be a": "Om het onderwerp te veranderen moet je het volgende zijn:", + "To modify widgets in the room, you must be a": "Om een widget in de ruimte aan te passen moet je het volgende zijn:", + "Banned by %(displayName)s": "Verbannen door %(displayName)s", + "Members only (since the point in time of selecting this option)": "Alleen gebruikers (vanaf het moment dat deze optie wordt geselecteerd)", + "Members only (since they were invited)": "Alleen gebruikers (vanaf het moment dat ze uitgenodigd zijn)", + "Members only (since they joined)": "Alleen gebruikers (vanaf het moment dat ze toegetreden zijn)", + "To send messages, you must be a": "Om berichten te versturen moet je het volgende zijn:", + "To invite users into the room, you must be a": "Om gebruikers in de ruimte uit te nodigen moet je het volgende zijn:", + "To configure the room, you must be a": "Om de ruimte te configureren moet je het volgende zijn:", + "To kick users, you must be a": "Om gebruikers er uit te zetten moet je het volgende zijn:", + "To ban users, you must be a": "Om gebruikers te verbannen moet je het volgende zijn:", + "To remove other users' messages, you must be a": "Om de berichten van andere gebruikers te verwijderen moet je het volgende zijn:", + "To send events of type , you must be a": "Om gebeurtenissen van het type te versturen, moet je het volgende zijn:", + "Addresses": "Adressen", + "Invalid community ID": "Ongeldig gemeenschaps-ID", + "'%(groupId)s' is not a valid community ID": "'%(groupId)s' is niet een geldig gemeenschaps-ID", + "Flair": "Badge", + "Showing flair for these communities:": "Badges voor deze gemeenschappen weergeven:", + "This room is not showing flair for any communities": "Deze ruimte geeft geen badges voor gemeenschappen weer", + "New community ID (e.g. +foo:%(localDomain)s)": "Nieuw gemeenschaps-ID (bv. +foo:%(localDomain)s)", + "URL previews are enabled by default for participants in this room.": "URL voorvertoning staat standaard aan voor deelnemers in deze ruimte.", + "URL previews are disabled by default for participants in this room.": "URL voorvertoning staat standaard uit voor deelnemers in deze ruimte.", + "Message removed by %(userId)s": "Bericht verwijderd door %(userId)s", + "Message removed": "Bericht verwijderd", + "An email has been sent to %(emailAddress)s": "Een e-mail is naar %(emailAddress)s verstuurd", + "A text message has been sent to %(msisdn)s": "Een tekstbericht is naar %(msisdn)s versuurd", + "Username on %(hs)s": "Gebruikersnaam op %(hs)s", + "Remove from community": "Verwijder van gemeenschap", + "Disinvite this user from community?": "Uitnodiging van de gemeenschap voor deze gebruiker intrekken?", + "Remove this user from community?": "Deze gebruiker van de gemeenschap verwijderen?", + "Failed to withdraw invitation": "Niet gelukt om de uitnodiging in te trekken", + "Failed to remove user from community": "Niet gelukt om de gebruiker van de gemeenschap te verwijderen", + "Filter community members": "Filter gemeenschapsleden", + "Flair will appear if enabled in room settings": "Badge zal worden weergeven als het aangezet is in de ruimte-instellingen", + "Flair will not appear": "Badge zal niet weergeven worden", + "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Weet je zeker dat je '%(roomName)s' van %(groupId)s wilt verwijderen?", + "Removing a room from the community will also remove it from the community page.": "Het verwijderen van de ruimte van de gemeenschap zal de ruimte ook van de gemeenschapspagina verwijderen.", + "Failed to remove room from community": "Niet gelukt om de ruimte van de gemeenschap te verwijderen", + "Failed to remove '%(roomName)s' from %(groupId)s": "Niet gelijkt om '%(roomName)s' van %(groupId)s te verwijderen", + "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "De zichtbaarheid van '%(roomName)s' in %(groupId)s kon niet geüpdatet worden.", + "Visibility in Room List": "Zichtbaarheid in Ruimte Lijst", + "Visible to everyone": "Zichtbaar voor iedereen", + "Only visible to community members": "Alleen zichtbaar voor gemeenschapsleden", + "Filter community rooms": "Gemeenschapsruimtes filteren", + "Something went wrong when trying to get your communities.": "Iets ging verkeerd tijdens het ophalen van je gemeenschappen.", + "Display your community flair in rooms configured to show it.": "Geef je gemeenschapsbadge weer in ruimtes die geconfigureerd zijn om het te weergeven.", + "You're not currently a member of any communities.": "Je bent momenteel niet een lid van een gemeenschap.", + "Minimize apps": "Applicaties minimaliseren", + "Communities": "Gemeenschappen", + "%(nameList)s %(transitionList)s": "%(nameList)s%(transitionList)s", + "%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)s traden %(count)s keer toe", + "%(severalUsers)sjoined %(count)s times|one": "%(severalUsers)s zijn toegetreden", + "%(oneUser)sjoined %(count)s times|other": "%(oneUser)s trad %(count)s keer toe", + "%(oneUser)sjoined %(count)s times|one": "%(oneUser)s is toegetreden", + "%(severalUsers)sleft %(count)s times|other": "%(severalUsers)s gingen %(count)s keer weg", + "%(severalUsers)sleft %(count)s times|one": "%(severalUsers)s gingen weg", + "%(oneUser)sleft %(count)s times|other": "%(oneUser)s ging %(count)s keer weg", + "%(oneUser)sleft %(count)s times|one": "%(oneUser)s ging weg", + "%(severalUsers)sjoined and left %(count)s times|other": "%(severalUsers)s traden toe en gingen weer weg voor %(count)s keer", + "%(severalUsers)sjoined and left %(count)s times|one": "%(severalUsers)s traden toe en gingen weer weg", + "%(oneUser)sjoined and left %(count)s times|other": "%(oneUser)s trad toe en ging weer weg voor %(count)s keer", + "%(oneUser)sjoined and left %(count)s times|one": "%(oneUser)s trad toe en ging weer weg", + "%(severalUsers)sleft and rejoined %(count)s times|other": "%(severalUsers)s ging weg en trad weer toe voor %(count)s keer", + "%(severalUsers)sleft and rejoined %(count)s times|one": "%(severalUsers)s gingen weg en kwamen weer terug", + "%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)s ging weg en kwam weer terug voor %(count)s keer", + "%(oneUser)sleft and rejoined %(count)s times|one": "%(oneUser)s ging weg en kwam weer terug", + "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)s wezen hun uitnodiging af voor %(count)s keer", + "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)s wezen hun uitnodiging af", + "%(oneUser)srejected their invitation %(count)s times|other": "%(oneUser)s wees %(count)s keer zijn of haar uitnodiging af", + "%(oneUser)srejected their invitation %(count)s times|one": "%(oneUser)s wees zijn of haar uitnodiging af", + "%(severalUsers)shad their invitations withdrawn %(count)s times|other": "De uitnodigingen naar %(severalUsers)s zijn %(count)s keer ingetrokken", + "%(severalUsers)shad their invitations withdrawn %(count)s times|one": "De uitnodigingen voor %(severalUsers)s zijn ingetrokken", + "%(oneUser)shad their invitation withdrawn %(count)s times|other": "De uitnodiging van %(oneUser)s is %(count)s keer ingetrokken", + "%(oneUser)shad their invitation withdrawn %(count)s times|one": "De uitnodiging van %(oneUser)s is ingetrokken", + "were invited %(count)s times|other": "was %(count)s keer uitgenodigd", + "were invited %(count)s times|one": "was uitgenodigd", + "was invited %(count)s times|other": "was %(count)s keer uitgenodigd", + "was invited %(count)s times|one": "was uitgenodigd", + "were banned %(count)s times|other": "was %(count)s keer verbannen", + "were banned %(count)s times|one": "was verbannen", + "was banned %(count)s times|other": "was %(count)s keer verbannen", + "was banned %(count)s times|one": "was verbannen", + "were unbanned %(count)s times|other": "zijn voor %(count)s keer ontbannen", + "was unbanned %(count)s times|other": "was %(count)s keer ontbannen", + "was unbanned %(count)s times|one": "was ontbannen", + "were kicked %(count)s times|other": "werden er %(count)s keer uitgezet", + "were kicked %(count)s times|one": "werden er uit gezet", + "was kicked %(count)s times|other": "was er %(count)s keer uitgezet", + "was kicked %(count)s times|one": "was er uit gezet", + "%(severalUsers)schanged their name %(count)s times|other": "%(severalUsers)s veranderden hun naam %(count)s keer", + "%(severalUsers)schanged their name %(count)s times|one": "%(severalUsers)s veranderden hun naam", + "%(oneUser)schanged their name %(count)s times|other": "%(oneUser)s veranderde zijn of haar naam %(count)s keer", + "%(oneUser)schanged their name %(count)s times|one": "%(oneUser)s veranderde zijn of haar naam", + "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)s veranderden hun avatar %(count)s keer", + "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)s veranderden hun avatar", + "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)s veranderde zijn of haar avatar %(count)s keer", + "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)s veranderde zijn of haar avatar", + "%(items)s and %(count)s others|other": "%(items)s en %(count)s anderen", + "%(items)s and %(count)s others|one": "%(items)s en één andere", + "collapse": "inklappen", + "expand": "openklappen", + "Custom of %(powerLevel)s": "Aangepast rank van %(powerLevel)s", + "Quote": "Citeren", + "And %(count)s more...|other": "En %(count)s meer...", + "Matrix ID": "Matrix ID", + "Matrix Room ID": "Matrix Ruimte ID", + "email address": "e-mailadres", + "Try using one of the following valid address types: %(validTypesList)s.": "Probeer één van de volgende geldige adrestypes: %(validTypesList)s.", + "You have entered an invalid address.": "Je hebt een ongeldig adres ingevoerd.", + "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "Een gemeenschaps-ID mag alleen de karakters a-z, 0-9, of '=_-./' bevatten.", + "Community IDs cannot not be empty.": "Een gemeenschaps-ID kan niet leeg zijn.", + "Something went wrong whilst creating your community": "Er is iets fout gegaan tijdens het aanmaken van je gemeenschap", + "Create Community": "Gemeenschap Aanmaken", + "Community Name": "Gemeenschapsnaam", + "Community ID": "Gemeenschap-ID", + "example": "voorbeeld", + "Advanced options": "Geavanceerde opties", + "Block users on other matrix homeservers from joining this room": "Gebruikers van andere matrix thuisservers niet toestaan om tot deze ruimte toe te treden", + "This setting cannot be changed later!": "Deze instelling kan niet later veranderd worden!", + "

    HTML for your community's page

    \n

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

    \n

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

    \n": "

    HTML voor je gemeenschapspagina

    \n

    \n Gebruik de lange beschrijving om nieuwe leden in de gemeenschap te introduceren of om belangrijke links te verspreiden\n

    \n

    \n Je kan zelfs 'img' tags gebruiken\n

    \n", + "Add rooms to the community summary": "Voeg ruimtes aan de gemeenschapssamenvatting toe", + "Which rooms would you like to add to this summary?": "Welke ruimtes zou je aan deze samenvatting willen toevoegen?", + "Add to summary": "Voeg aan samenvatting toe", + "Failed to add the following rooms to the summary of %(groupId)s:": "Het is niet gelukt om de volgende ruimtes aan de samenvatting van %(groupId)s toe te voegen:", + "Add a Room": "Voeg een ruimte toe", + "Failed to remove the room from the summary of %(groupId)s": "Het is niet gelukt om de ruimte van de samenvatting van %(groupId)s te verwijderen", + "The room '%(roomName)s' could not be removed from the summary.": "De ruimte '%(roomName)s' kan niet van de samenvatting verwijderd worden.", + "Add users to the community summary": "Voeg gebruikers aan de gemeenschapssamenvatting toe", + "Who would you like to add to this summary?": "Wie zou je aan de samenvatting toe willen voegen?", + "Failed to add the following users to the summary of %(groupId)s:": "Het is niet gelukt om de volgende gebruikers aan de samenvatting van %(groupId)s toe te voegen:", + "Add a User": "Voeg een Gebruiker toe", + "Failed to remove a user from the summary of %(groupId)s": "Het is niet gelukt om een gebruiker van de samenvatting van %(groupId)s te verwijderen", + "The user '%(displayName)s' could not be removed from the summary.": "De gebruiker '%(displayName)s' kon niet van de samenvatting verwijderd worden.", + "Failed to update community": "Het is niet gelukt om de gemeenschap te updaten", + "Unable to accept invite": "De uitnodiging kon niet geaccepteerd worden", + "Unable to reject invite": "De uitnodiging kon niet afgewezen worden", + "Leave Community": "Gemeenschap Verlaten", + "Leave %(groupName)s?": "%(groupName)s verlaten?", + "Leave": "Verlaten", + "Unable to leave room": "De ruimte kon niet verlaten worden", + "Community Settings": "Gemeenschapsinstellingen", + "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Deze ruimtes worden aan gemeenschapsleden getoond op de gemeenschapspagina. Gemeenschapsleden kunnen tot de ruimtes toetreden door er op te klikken.", + "%(inviter)s has invited you to join this community": "%(inviter)s heeft jou uitgenodigd om tot deze gemeenschap toe te treden", + "You are an administrator of this community": "Je bent een administrator van deze gemeenschap", + "You are a member of this community": "Je bent lid van deze gemeenschap", + "Your community hasn't got a Long Description, a HTML page to show to community members.
    Click here to open settings and give it one!": "Jouw gemeenschap heeft geen Lange Beschrijving (een HTML pagina dat aan de gemeenschapsleden wordt weergeven).
    Klik hier om de instellingen te openen en een Lange Beschrijving te maken!", + "Long Description (HTML)": "Lange Beschrijving (HTML)", + "Description": "Beschrijving", + "Community %(groupId)s not found": "Gemeenschap %(groupId)s is niet gevonden", + "This Home server does not support communities": "Deze Thuisserver ondersteunt geen gemeenschappen", + "Failed to load %(groupId)s": "Het is niet gelukt om %(groupId)s te laden", + "Cryptography data migrated": "Cryptografie gegevens zijn gemigreerd", + "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "Een eenmalige migratie van cryptografie gegevens heeft plaatsgevonden. Eind-tot-eind versleuteling zal niet werken als je terug gaat naar een oudere versie van Riot. Log eerst uit op Riot als je eind-tot-eind versleuteling wil gebruiken op een oudere versie. Exporteer je sleutels en importeer ze achteraf weer als je de berichtgeschiedenis wilt behouden.", + "Old cryptography data detected": "Oude cryptografie gegevens gedetecteerd", + "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Er zijn gegevens van een oudere versie van Riot gedetecteerd. Dit zal eind-tot-eind versleuteling laten storen in de oudere versie. Eind-tot-eind berichten dat recent zijn uitgewisseld zal misschien niet ontsleutelbaar zijn in deze versie. Dit zou er misschien ook voor kunnen zorgen dat berichten die zijn uitgewisseld in deze versie falen. Indien je problemen ervaart, log opnieuw in. Om de berichtgeschiedenis te behouden, exporteer de sleutels en importeer ze achteraf weer.", + "Your Communities": "Jouw Gemeenschappen", + "Error whilst fetching joined communities": "Er is een fout opgetreden tijdens het ophalen van de gemeenschappen waar je lid van bent", + "Create a new community": "Maak een nieuwe gemeenschap aan", + "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Maak een gemeenschap aan om gebruikers en ruimtes samen te groeperen! Bouw een aangepaste homepagina om je eigen plek in het Matrix universum te maken.", + "Join an existing community": "Treed tot een bestaande gemeenschap toe", + "To join an existing community you'll have to know its community identifier; this will look something like +example:matrix.org.": "Je moet het gemeenschaps-ID weten om tot de gemeenschap toe te treden; dit zal er uitzien zoals +voorbeeld:matrix.org.", + "Show devices, send anyway or cancel.": "Toon apparaten, Toch versturen of annuleren.", + "%(count)s of your messages have not been sent.|one": "Je bericht was niet verstuurd.", + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "Nu alles opnieuw versturen of annuleren. Je kan ook individuele berichten selecteren om opnieuw te versturen of te annuleren.", + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Nu bericht opnieuw versturen of bericht annuleren.", + "Warning": "Waarschuwing", + "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Er is niemand anders hier! Wil je anderen uitnodigen of de waarschuwing over de lege ruimte stoppen?", + "Light theme": "Licht thema", + "Dark theme": "Donker thema", + "Status.im theme": "Status.im thema", + "Ignored Users": "Genegeerde Gebruikers", + "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Privacy is belangrijk voor ons, dus we collecteren geen persoonlijke of identificeerbare gegevens voor onze gegevensanalyse.", + "Learn more about how we use analytics.": "Leer meer over hoe we gegevensanalyse gebruiken.", + "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "Een e-mail is naar %(emailAddress)s verstuurd. Klik hieronder zodra je de link hebt gevolgd.", + "Please note you are logging into the %(hs)s server, not matrix.org.": "Merk op dat je aan het inloggen bent in de %(hs)s server, niet matrix.org.", + "This homeserver doesn't offer any login flows which are supported by this client.": "Deze thuisserver heeft geen inlogmethodes die bij deze client ondersteunt worden.", + "Sign in to get started": "Log in om te beginnen", + "Ignores a user, hiding their messages from you": "Negeert een gebruiker, waardoor de berichten van de gebruiker onzichtbaar voor je worden", + "Stops ignoring a user, showing their messages going forward": "Stopt het negeren van een gebruiker, hierdoor worden de berichten van de gebruiker vanaf nu weer zichtbaar", + "Notify the whole room": "Notificeer de gehele ruimte", + "Room Notification": "Ruimte Notificatie", + "The information being sent to us to help make Riot.im better includes:": "De informatie dat naar ons wordt verstuurd om Riot.im beter te maken betrekt:", + "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "We nemen ook elke pagina die je in de applicatie gebruikt (momenteel ), je User Agent () en de resolutie van je apparaat () op.", + "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Waar deze pagina identificeerbare informatie bevat, zoals een ruimte, gebruiker of groep ID, zal deze data verwijderd worden voordat het naar de server gestuurd wordt.", + "The platform you're on": "Het platform waar je je op bevindt", + "The version of Riot.im": "De versie van Riot.im", + "Whether or not you're logged in (we don't record your user name)": "Of je wel of niet ingelogd bent (we nemen niet je gebruikersnaam op)", + "Your language of choice": "De taal waarin de applicatie wordt weergeven", + "Which officially provided instance you are using, if any": "Welke officieel verschafte instantie je gebruikt, in dat het geval is", + "Whether or not you're using the Richtext mode of the Rich Text Editor": "Of je wel of niet gebruik maakt van de Richttext modus of de Rich Text Editor", + "Your homeserver's URL": "De URL van je thuisserver", + "Your identity server's URL": "De URL van je thuisserver", + "In reply to ": "Als antwoord op ", + "This room is not public. You will not be able to rejoin without an invite.": "Deze ruimte is niet publiekelijk. Je zal niet opnieuw kunnen toetreden zonder een uitnodiging.", + "were unbanned %(count)s times|one": "waren ontbant" } From 03b137d42555781b62baeb88d55f3e18bbc03470 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sim=C3=B3=20Albert=20i=20Beltran?= Date: Sat, 3 Feb 2018 15:38:29 +0000 Subject: [PATCH 0219/1160] Translated using Weblate (Catalan) Currently translated at 88.5% (871 of 984 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ca/ --- src/i18n/strings/ca.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/ca.json b/src/i18n/strings/ca.json index eb4ac76d05..49c2c6ed9b 100644 --- a/src/i18n/strings/ca.json +++ b/src/i18n/strings/ca.json @@ -317,7 +317,7 @@ "Unignore": "Deixa de ignorar", "Ignore": "Ignora", "Jump to read receipt": "Vés a l'últim missatge llegit", - "Mention": "Menció", + "Mention": "Menciona", "Invite": "Convida", "User Options": "Opcions d'usuari", "Direct chats": "Xats directes", From 41338013909f130fd5071b979220a2b63c862e80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D1=80=D0=BA=D0=BE=20=D0=9C=2E=20=D0=9A=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D0=B8=D1=9B?= Date: Sat, 3 Feb 2018 11:51:18 +0000 Subject: [PATCH 0220/1160] Translated using Weblate (Serbian) Currently translated at 78.4% (772 of 984 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sr/ --- src/i18n/strings/sr.json | 179 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 176 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index 6396455f9d..5d31879b2e 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -1,7 +1,7 @@ { "This email address is already in use": "Ова мејл адреса се већ користи", "This phone number is already in use": "Овај број телефона се већ користи", - "Failed to verify email address: make sure you clicked the link in the email": "Нисам успео да потврдим мејл адресу, постарајте се да сте кликнули на везу у мејлу", + "Failed to verify email address: make sure you clicked the link in the email": "Нисам успео да проверим мејл адресу, постарајте се да сте кликнули на везу у мејлу", "The remote side failed to pick up": "Друга страна није подигла слушалицу", "Unable to capture screen": "Не могу да ухватим садржај екрана", "Existing Call": "Постојећи позив", @@ -569,7 +569,7 @@ "Unblacklist": "Скини са црног списка", "Blacklist": "Стави на црни списак", "Unverify": "Скини потврду", - "Verify...": "Потврди...", + "Verify...": "Провери...", "No results": "Нема резултата", "Delete": "Обриши", "Communities": "Заједнице", @@ -597,5 +597,178 @@ "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)s је одбило њихове позивнице %(count)s пута", "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)s је одбило њихове позивнице", "%(oneUser)srejected their invitation %(count)s times|other": "%(oneUser)s је одбио позивницу %(count)s пута", - "%(oneUser)srejected their invitation %(count)s times|one": "%(oneUser)s је одбио позивницу" + "%(oneUser)srejected their invitation %(count)s times|one": "%(oneUser)s је одбио позивницу", + "%(severalUsers)shad their invitations withdrawn %(count)s times|other": "Корисницима %(severalUsers)s су позивнице повучене %(count)s пута", + "%(severalUsers)shad their invitations withdrawn %(count)s times|one": "Корисницима %(severalUsers)s су позивнице повучене", + "%(oneUser)shad their invitation withdrawn %(count)s times|other": "Кориснику %(oneUser)s је позивница повучена %(count)s пута", + "%(oneUser)shad their invitation withdrawn %(count)s times|one": "Кориснику %(oneUser)s је позивница повучена", + "were invited %(count)s times|other": "су позвани %(count)s пута", + "were invited %(count)s times|one": "су позвани", + "was invited %(count)s times|other": "је позван %(count)s пута", + "was invited %(count)s times|one": "је позван", + "were banned %(count)s times|other": "забрањен приступ %(count)s пута", + "were banned %(count)s times|one": "забрањен приступ", + "was banned %(count)s times|other": "забрањен приступ %(count)s пута", + "was banned %(count)s times|one": "забрањен приступ", + "were unbanned %(count)s times|other": "дозвољен приступ %(count)s пута", + "were unbanned %(count)s times|one": "дозвољен приступ", + "was unbanned %(count)s times|other": "дозвољен приступ %(count)s пута", + "was unbanned %(count)s times|one": "дозвољен приступ", + "were kicked %(count)s times|other": "избачен %(count)s пута", + "were kicked %(count)s times|one": "избачен", + "was kicked %(count)s times|other": "избачен %(count)s пута", + "was kicked %(count)s times|one": "избачен", + "%(severalUsers)schanged their name %(count)s times|other": "%(severalUsers)s је променило своје име %(count)s пута", + "%(severalUsers)schanged their name %(count)s times|one": "%(severalUsers)s је променило своје име", + "%(oneUser)schanged their name %(count)s times|other": "%(oneUser)s је променило своје име %(count)s пута", + "%(oneUser)schanged their name %(count)s times|one": "%(oneUser)s је променило своје име", + "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)s је променило свој аватар %(count)s пута", + "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)s је променило свој аватар", + "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)s је променило свој аватар %(count)s пута", + "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)s је променило свој аватар", + "%(items)s and %(count)s others|other": "%(items)s и %(count)s других", + "%(items)s and %(count)s others|one": "%(items)s и још један", + "%(items)s and %(lastItem)s": "%(items)s и %(lastItem)s", + "collapse": "скупи", + "expand": "рашири", + "Custom of %(powerLevel)s": "Прилагођени ниво %(powerLevel)s", + "Custom level": "Прилагођени ниво", + "Quote": "Цитат", + "Room directory": "Фасцикла са собама", + "Start chat": "Започни ћаскање", + "And %(count)s more...|other": "И %(count)s других...", + "ex. @bob:example.com": "нпр.: @pera:domen.rs", + "Add User": "Додај корисника", + "Matrix ID": "Матрикс ИБ", + "Matrix Room ID": "ИБ Матрикс собе", + "email address": "мејл адреса", + "Try using one of the following valid address types: %(validTypesList)s.": "Пробајте са једним од следећих исправних типова адреса: %(validTypesList)s.", + "You have entered an invalid address.": "Унели сте неисправну адресу.", + "Create a new chat or reuse an existing one": "Започните ново ћаскање или искористите постојеће", + "Start new chat": "Започни ново ћаскање", + "You already have existing direct chats with this user:": "Већ имате постојећа директна ћаскања са овим корисником:", + "Start chatting": "Започни ћаскање", + "Click on the button below to start chatting!": "Кликните на дугме испод да бисте започели ћаскање!", + "Start Chatting": "Започни ћаскање", + "Confirm Removal": "Потврди уклањање", + "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Да ли сте сигурни да желите уклонити (обрисати) овај догађај? Знајте да брисање назива собе или мењање теме може опозвати измену.", + "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "ИБ-јеви заједнице могу садржати само знакове a-z, 0-9, или '=_-./'", + "Community IDs cannot not be empty.": "ИБ-јеви заједнице не могу бити празни.", + "Something went wrong whilst creating your community": "Нешто је пошло наопако приликом стварања ваше заједнице", + "Create Community": "Направи заједницу", + "Community Name": "Назив заједнице", + "Example": "Пример", + "Community ID": "ИБ заједнице", + "example": "пример", + "Create": "Направи", + "Create Room": "Направи собу", + "Room name (optional)": "Назив собе (изборно)", + "Advanced options": "Напредне опције", + "Block users on other matrix homeservers from joining this room": "Блокирај приступ соби корисницима са других матрикс кућних сервера", + "This setting cannot be changed later!": "Ово подешавање се не може променити касније!", + "Unknown error": "Непозната грешка", + "Incorrect password": "Нетачна лозинка", + "Deactivate Account": "Угаси налог", + "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Ово ће учинити ваш налог трајно неупотребљивим. Нећете моћи да се поново региструјете са истим корисничким ИБ-јем.", + "This action is irreversible.": "Ова радња се не може поништити.", + "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Да бисте проверили да се овом уређају може веровати, контактирајте власника користећи друге начине (нпр.: лично или преко телефонског позива) и питајте га да ли се кључ који види у корисничким подешавањима подудара са кључем испод:", + "Device name": "Назив уређаја", + "Device key": "Кључ уређаја", + "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Ако се подудара, притисните дугме за потврду провере испод. Ако се не подудара, неко други прислушкује овај уређај и вероватно желите да притиснете дугме за стављање на црни списак.", + "In future this verification process will be more sophisticated.": "У будућности ће овај поступак потврђивања бити напреднији.", + "Verify device": "Провери уређај", + "I verify that the keys match": "Потврђујем да се кључеви подударају", + "An error has occurred.": "Догодила се грешка.", + "OK": "У реду", + "You added a new device '%(displayName)s', which is requesting encryption keys.": "Додали сте нови уређај „%(displayName)s“ који захтева кључеве за шифровање.", + "Your unverified device '%(displayName)s' is requesting encryption keys.": "Ваш непотврђени уређај „%(displayName)s“ захтева кључеве за шифровање.", + "Start verification": "Започни потврђивање", + "Share without verifying": "Подели без потврђивања", + "Ignore request": "Занемари захтев", + "Loading device info...": "Учитавам податке о уређају...", + "Encryption key request": "Захтев за кључ шифровања", + "Otherwise, click here to send a bug report.": "У супротном, кликните овде да бисте послали извештај о грешци.", + "Unable to restore session": "Не могу да повратим сесију", + "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Наишли смо на грешку приликом опоравка ваше претходне сесије. Ако наставите, мораћете да се пријавите поново и ваш шифровани историјат ћаскања неће бити читљив.", + "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Ако сте претходно користили новије издање Riot-а, ваша сесија може бити некомпатибилна са овим издањем. Затворите овај прозор и вратите се на новије издање.", + "Continue anyway": "Ипак настави", + "Invalid Email Address": "Неисправна мејл адреса", + "This doesn't appear to be a valid email address": "Изгледа да ово није исправна мејл адреса", + "Verification Pending": "Чека се на потврду", + "Please check your email and click on the link it contains. Once this is done, click continue.": "Проверите ваш мејл и кликните на везу унутар њега. Када ово урадите, кликните на дугме „настави“.", + "Unable to add email address": "Не могу да додам мејл адресу", + "Unable to verify email address.": "Не могу да проверим мејл адресу.", + "This will allow you to reset your password and receive notifications.": "Ово омогућава поновно постављање лозинке и примање обавештења.", + "Skip": "Прескочи", + "User names may only contain letters, numbers, dots, hyphens and underscores.": "Корисничка имена могу садржати само слова, бројеве, тачке, повлаке и доње црте.", + "Username not available": "Корисничко име није доступно", + "Username invalid: %(errMessage)s": "Корисничко име није исправно: %(errMessage)s", + "An error occurred: %(error_string)s": "Догодила се грешка: %(error_string)s", + "Username available": "Корисничко име је доступно", + "To get started, please pick a username!": "Да бисте кренули, изаберите корисничко име!", + "This will be your account name on the homeserver, or you can pick a different server.": "Ово ће бити назив вашег налога на кућном серверу, или можете изабрати други сервер.", + "If you already have a Matrix account you can log in instead.": "Ако већ имате Матрикс налог, можете се већ пријавити.", + "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Тренутно убацујете непроверене уређаје на црни списак. Да бисте им слали поруке, морате их проверити.", + "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Предлажемо да прођете кроз поступак провере сваког уређаја да бисте потврдили да они припадају њиховим стварним власницима али можете поново послати поруку без провере, ако то желите.", + "Room contains unknown devices": "Соба садржи непознате уређаје", + "\"%(RoomName)s\" contains devices that you haven't seen before.": "Соба „%(RoomName)s“ садржи уређаје које нисте видели пре.", + "Unknown devices": "Непознати уређаји", + "Private Chat": "Приватно ћаскање", + "Public Chat": "Јавно ћаскање", + "Custom": "Прилагођено", + "Alias (optional)": "Алијас (изборно)", + "Name": "Име", + "Topic": "Тема", + "Make this room private": "Учини ову собу приватном", + "Share message history with new users": "Подели историјат порука са новим корисницима", + "Encrypt room": "Шифруј собу", + "You must register to use this functionality": "Морате се регистровати да бисте користили ову могућност", + "You must join the room to see its files": "Морате приступити соби да бисте видели њене датотеке", + "There are no visible files in this room": "Нема видљивих датотека у овој соби", + "

    HTML for your community's page

    \n

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

    \n

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

    \n": "

    HTML за страницу ваше заједнице

    \n

    \n Користите дужи опис да бисте упознали нове чланове са заједницом, или поделили\n неке важне везе\n

    \n

    \n Можете чак користити \"img\" ознаке\n

    \n", + "Add rooms to the community summary": "Додај собе у кратак опис заједнице", + "Which rooms would you like to add to this summary?": "Које собе желите додати у овај кратак опис?", + "Add to summary": "Додај у кратак опис", + "Failed to add the following rooms to the summary of %(groupId)s:": "Нисам успео да додам следеће собе у кратак опис групе %(groupId)s:", + "Add a Room": "Додај собу", + "Failed to remove the room from the summary of %(groupId)s": "Нисам успео да уклоним собу из кратког описа групе %(groupId)s", + "The room '%(roomName)s' could not be removed from the summary.": "Соба „%(roomName)s“ се не може уклонити из кратког описа.", + "Add users to the community summary": "Додај кориснике у кратак опис заједнице", + "Who would you like to add to this summary?": "Да ли желите да додате у овај кратак опис?", + "Failed to add the following users to the summary of %(groupId)s:": "Нисам успео да додам следеће кориснике у кратак опис групе %(groupId)s:", + "Add a User": "Додај корисника", + "Failed to remove a user from the summary of %(groupId)s": "Нисам успео да уклоним корисника из кратког описа групе %(groupId)s", + "The user '%(displayName)s' could not be removed from the summary.": "Корисник „%(displayName)s“ се не може уклонити из кратког описа.", + "Failed to upload image": "Нисам успео да отпремим слику", + "Failed to update community": "Нисам успео да ажурирам заједницу", + "Unable to accept invite": "Не могу да прихватим позивницу", + "Unable to reject invite": "Не могу да одбијем позивницу", + "Leave Community": "Напусти заједницу", + "Leave %(groupName)s?": "Напустити %(groupName)s?", + "Leave": "Напусти", + "Unable to leave room": "Не могу да напустим собу", + "Community Settings": "Подешавања заједнице", + "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Ове собе су приказане члановима заједнице на страници заједнице. Чланови заједнице могу приступити собама кликом на њих.", + "Add rooms to this community": "Додај собе у ову заједницу", + "Featured Rooms:": "Издвојене собе:", + "Featured Users:": "Издвојени корисници:", + "%(inviter)s has invited you to join this community": "Корисник %(inviter)s вас је позвао у ову заједницу", + "You are an administrator of this community": "Ви сте администратор ове заједнице", + "You are a member of this community": "Ви сте члан ове заједнице", + "Your community hasn't got a Long Description, a HTML page to show to community members.
    Click here to open settings and give it one!": "Ваша заједница нема дуги опис, HTML страницу на којој су приказани чланови заједнице.
    Кликните овде да бисте отворили подешавања и направили страницу!", + "Long Description (HTML)": "Дуги опис (HTML)", + "Description": "Опис", + "Community %(groupId)s not found": "Заједница %(groupId)s није нађена", + "This Home server does not support communities": "Овај кућни сервер не подржава заједнице", + "Failed to load %(groupId)s": "Нисам успео да учитам %(groupId)s", + "Reject invitation": "Одбиј позивницу", + "Are you sure you want to reject the invitation?": "Да ли сте сигурни да желите одбити позивницу?", + "Failed to reject invitation": "Нисам успео да одбијем позивницу", + "Are you sure you want to leave the room '%(roomName)s'?": "Да ли сте сигурни да желите напустити собу „%(roomName)s“?", + "Failed to leave room": "Нисам успео да напустим собу", + "Signed Out": "Одјављен", + "For security, this session has been signed out. Please sign in again.": "Зарад безбедности, одјављени сте из ове сесије. Пријавите се поново.", + "Cryptography data migrated": "Криптографски подаци су пренесени", + "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "Једноструко преношење криптографских података је обављено. Шифровање с краја на крај неће радити ако се вратите на старије издање Riot-а. Ако вам треба шифровање с краја на крај на старијем издању, прво се одјавите из Riot-а. Да бисте задржали историјат порука, извезите па поново увезите ваше кључеве.", + "Old cryptography data detected": "Нађени су стари криптографски подаци" } From 29962ed89d1f4716a46e41877a17b4f5425d4672 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Mon, 5 Feb 2018 11:48:48 +0000 Subject: [PATCH 0221/1160] Add stickerpack strings. --- src/i18n/strings/en_EN.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index a4152ef94a..4458fefbf1 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -241,6 +241,11 @@ "Cannot add any more widgets": "Cannot add any more widgets", "The maximum permitted number of widgets have already been added to this room.": "The maximum permitted number of widgets have already been added to this room.", "Add a widget": "Add a widget", + "You don't currently have any stickerpacks enabled": "You don't currently have any stickerpacks enabled", + "Click": "Click", + "here": "here", + "to add some!": "to add some!", + "Add a stickerpack": "Add a stickerpack", "Drop File Here": "Drop File Here", "Drop file here to upload": "Drop file here to upload", " (unsupported)": " (unsupported)", From 34de3729fe12c61f263f102131e2a3bf61761259 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Mon, 5 Feb 2018 11:49:26 +0000 Subject: [PATCH 0222/1160] Add method to remove all stickerpacks. --- src/utils/widgets.js | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/utils/widgets.js b/src/utils/widgets.js index 4e26fa6ceb..806906f072 100644 --- a/src/utils/widgets.js +++ b/src/utils/widgets.js @@ -45,12 +45,33 @@ function getUserWidgets() { * @return {[object]} Array containing current / active stickerpack widgets */ function getStickerpackWidgets() { - return getUserWidgets().filter((widget) => widget.type='stickerpack'); + const stickerpackWidgets = getUserWidgets().filter((widget) => widget.type='stickerpack'); + console.warn('Stickerpack widgets', stickerpackWidgets); + return stickerpackWidgets; } +/** + * Remove all stickerpack widgets (stickerpacks are user widgets by nature) + */ +function removeStickerpackWidgets() { + const client = MatrixClientPeg.get(); + if (!client) { + throw new Error('User not logged in'); + } + const userWidgets = client.getAccountData('m.widgets').getContent() || {}; + Object.entries(userWidgets).forEach(([key, widget]) => { + if (widget.type === 'stickerpack') { + delete userWidgets[key]; + } + }); + client.setAccountData('m.widgets', userWidgets); +} + + export default { getWidgets, getRoomWidgets, getUserWidgets, getStickerpackWidgets, + removeStickerpackWidgets, }; From 992c4771f4d78ee349e05a2e1d05ca9d88b19b1c Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Mon, 5 Feb 2018 11:49:44 +0000 Subject: [PATCH 0223/1160] Add button to remove all stickerpacks --- src/components/views/rooms/Stickerpack.js | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/components/views/rooms/Stickerpack.js b/src/components/views/rooms/Stickerpack.js index cb2a19eae7..77e188198a 100644 --- a/src/components/views/rooms/Stickerpack.js +++ b/src/components/views/rooms/Stickerpack.js @@ -33,12 +33,13 @@ export default class Stickerpack extends React.Component { this.onHideStickersClick = this.onHideStickersClick.bind(this); this.onFinished = this.onFinished.bind(this); this._launchManageIntegrations = this._launchManageIntegrations.bind(this); + this._removeStickerpackWidgets = this._removeStickerpackWidgets.bind(this); this.defaultStickersContent = (
    -

    You don't currently have any stickerpacks enabled

    -

    Click here to add some!

    - Add a stickerpack +

    {_t("You don't currently have any stickerpacks enabled")}

    +

    {_t("Click")} { _t("here") } {_t("to add some!")}

    + {_t('Add
    ); this.popoverWidth = 300; @@ -50,6 +51,11 @@ export default class Stickerpack extends React.Component { }; } + _removeStickerpackWidgets() { + console.warn('Removing stickerpack widgets'); + Widgets.removeStickerpackWidgets() + } + componentDidMount() { this.scalarClient = null; if (SdkConfig.get().integrations_ui_url && SdkConfig.get().integrations_rest_url) { @@ -91,6 +97,14 @@ export default class Stickerpack extends React.Component { width: this.popoverWidth, }} > +
    X
    Click here to add your first sitckerpack

    ; + stickersContent = this.defaultStickersContent; } this.setState({stickersContent}); } From e508f0676547732b9905839fe37418392cdc82e3 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Mon, 5 Feb 2018 11:50:25 +0000 Subject: [PATCH 0224/1160] Add asset add / remove messaging clauses. --- src/ScalarMessaging.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index 9a57ab5bce..0fa342e69f 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -624,6 +624,12 @@ const onMessage = function(event) { } else if (event.data.action === "set_widget") { setWidget(event, roomId); return; + } else if (event.data.action === "add_widget_asset") { + addWidgetAsset(event, roomId); + return; + } else if (event.data.action === "remove_widget_asset") { + removeWidgetAsset(event, roomId); + return; } if (!roomId) { From 330ce0f02e31a7be7195624718fb3caf5ad1d11a Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Mon, 5 Feb 2018 17:29:22 +0000 Subject: [PATCH 0225/1160] On failure, regenerate state from sdk Instead of using history, which could be unpredictable --- src/stores/RoomListStore.js | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/src/stores/RoomListStore.js b/src/stores/RoomListStore.js index 69d957f074..e48eacaa6a 100644 --- a/src/stores/RoomListStore.js +++ b/src/stores/RoomListStore.js @@ -26,7 +26,6 @@ class RoomListStore extends Store { super(dis); this._init(); - this._actionHistory = []; } _init() { @@ -57,14 +56,13 @@ class RoomListStore extends Store { break; } - this._generateRoomLists(payload.matrixClient); - this._actionHistory.unshift(payload); + this._matrixClient = payload.matrixClient; + this._generateRoomLists(); } break; case 'MatrixActions.Room.tags': { if (!this._state.ready) break; this._updateRoomLists(payload.room); - this._actionHistory.unshift(payload); } break; case 'RoomListActions.tagRoom.pending': { @@ -74,35 +72,22 @@ class RoomListStore extends Store { payload.request.newTag, payload.request.metaData, ); - this._actionHistory.unshift(payload); } break; case 'RoomListActions.tagRoom.failure': { - this._actionHistory = this._actionHistory.filter((action) => { - return action.asyncId !== payload.asyncId; - }); - - // don't duplicate history - const history = this._actionHistory.slice(0); - this._actionHistory = []; - this._reloadFromHistory(history); + // Reset state according to js-sdk + this._generateRoomLists(); } break; case 'on_logged_out': { // Reset state without pushing an update to the view, which generally assumes that // the matrix client isn't `null` and so causing a re-render will cause NPEs. this._init(); - this._actionHistory.unshift(payload); } break; } } - _reloadFromHistory(history) { - this._init(); - history.forEach((action) => this.__onDispatch(action)); - } - _updateRoomListsOptimistic(updatedRoom, oldTag, newTag, metaData) { const newLists = {}; @@ -153,7 +138,7 @@ class RoomListStore extends Store { }); } - _generateRoomLists(matrixClient) { + _generateRoomLists() { const lists = { "im.vector.fake.invite": [], "m.favourite": [], @@ -163,10 +148,14 @@ class RoomListStore extends Store { "im.vector.fake.archived": [], }; + const dmRoomMap = DMRoomMap.shared(); - matrixClient.getRooms().forEach((room, index) => { - const me = room.getMember(matrixClient.credentials.userId); + // If somehow we dispatched a RoomListActions.tagRoom.failure before a MatrixActions.sync + if (!this._matrixClient) return; + + this._matrixClient.getRooms().forEach((room, index) => { + const me = room.getMember(this._matrixClient.credentials.userId); if (!me) return; if (me.membership == "invite") { From 9982efbd8f61b75c4d4c688ce0124b47fb6c9deb Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Mon, 5 Feb 2018 18:06:29 +0000 Subject: [PATCH 0226/1160] Regenerate room lists when we get m.direct --- src/stores/RoomListStore.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/stores/RoomListStore.js b/src/stores/RoomListStore.js index e48eacaa6a..6a9217eab4 100644 --- a/src/stores/RoomListStore.js +++ b/src/stores/RoomListStore.js @@ -65,6 +65,11 @@ class RoomListStore extends Store { this._updateRoomLists(payload.room); } break; + case 'MatrixActions.accountData': { + if (payload.event_type !== 'm.direct') break; + this._generateRoomLists(); + } + break; case 'RoomListActions.tagRoom.pending': { this._updateRoomListsOptimistic( payload.request.room, From c665c1170b419ec8b6e6b4b5fe7e7e06a792d0bd Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Mon, 5 Feb 2018 18:27:50 +0000 Subject: [PATCH 0227/1160] Regenerate room lists when we get RoomMember.membership --- src/actions/MatrixActionCreators.js | 5 +++++ src/stores/RoomListStore.js | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/actions/MatrixActionCreators.js b/src/actions/MatrixActionCreators.js index d9309d7c1c..f4d6c34ff5 100644 --- a/src/actions/MatrixActionCreators.js +++ b/src/actions/MatrixActionCreators.js @@ -66,6 +66,10 @@ function createRoomTagsAction(matrixClient, roomTagsEvent, room) { return { action: 'MatrixActions.Room.tags', room }; } +function createRoomMembershipAction(matrixClient, membershipEvent, member, oldMembership) { + return { action: 'MatrixActions.RoomMember.membership', member }; +} + /** * This object is responsible for dispatching actions when certain events are emitted by * the given MatrixClient. @@ -83,6 +87,7 @@ export default { this._addMatrixClientListener(matrixClient, 'sync', createSyncAction); this._addMatrixClientListener(matrixClient, 'accountData', createAccountDataAction); this._addMatrixClientListener(matrixClient, 'Room.tags', createRoomTagsAction); + this._addMatrixClientListener(matrixClient, 'RoomMember.membership', createRoomMembershipAction); }, /** diff --git a/src/stores/RoomListStore.js b/src/stores/RoomListStore.js index 6a9217eab4..28ffee99d2 100644 --- a/src/stores/RoomListStore.js +++ b/src/stores/RoomListStore.js @@ -70,6 +70,11 @@ class RoomListStore extends Store { this._generateRoomLists(); } break; + case 'MatrixActions.RoomMember.membership': { + if (!this._matrixClient || payload.member.userId !== this._matrixClient.credentials.userId) break; + this._generateRoomLists(); + } + break; case 'RoomListActions.tagRoom.pending': { this._updateRoomListsOptimistic( payload.request.room, From 0f2ca3bd95ea68401482152c36291bfa1553802d Mon Sep 17 00:00:00 2001 From: "Robert A. Viana" Date: Tue, 6 Feb 2018 09:07:38 +0000 Subject: [PATCH 0228/1160] Translated using Weblate (Portuguese (Brazil)) Currently translated at 66.9% (659 of 984 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/pt_BR/ --- src/i18n/strings/pt_BR.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/pt_BR.json b/src/i18n/strings/pt_BR.json index 817d094422..5a9c4d7d65 100644 --- a/src/i18n/strings/pt_BR.json +++ b/src/i18n/strings/pt_BR.json @@ -656,5 +656,7 @@ "You are not in this room.": "Você não está nesta sala.", "You do not have permission to do that in this room.": "Você não tem permissão para fazer isto nesta sala.", "Ignored user": "Usuário ignorado", - "You are no longer ignoring %(userId)s": "Você parou de ignorar %(userId)s" + "You are no longer ignoring %(userId)s": "Você parou de ignorar %(userId)s", + "Edit": "Editar", + "Unpin Message": "Desafixar Mensagem" } From feca1707f119bab11c836a810ec9566df7de6498 Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Tue, 6 Feb 2018 09:55:58 +0000 Subject: [PATCH 0229/1160] Remove a factor n complexity during room visibility calc --- src/components/views/rooms/RoomList.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index ad85beac12..269f04c963 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -352,6 +352,14 @@ module.exports = React.createClass({ const filteredLists = {}; + const isRoomVisible = { + // $roomId: true, + }; + + this._visibleRooms.forEach((r) => { + isRoomVisible[r.roomId] = true; + }); + Object.keys(lists).forEach((tagName) => { filteredLists[tagName] = lists[tagName].filter((taggedRoom) => { // Somewhat impossible, but guard against it anyway @@ -363,9 +371,7 @@ module.exports = React.createClass({ return; } - return this._visibleRooms.some((visibleRoom) => { - return visibleRoom.roomId === taggedRoom.roomId; - }); + return isRoomVisible[taggedRoom.roomId]; }); }); From 8458023bbca4c805a9d8fdeeece501f843645c02 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 6 Feb 2018 10:24:38 +0000 Subject: [PATCH 0230/1160] Fix display name change message (i18n file fixes coming separately for ease of review) Fixes https://github.com/vector-im/riot-web/issues/5171 --- src/TextForEvent.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/TextForEvent.js b/src/TextForEvent.js index 1bdf5ad90c..e60bde4094 100644 --- a/src/TextForEvent.js +++ b/src/TextForEvent.js @@ -52,8 +52,7 @@ function textForMemberEvent(ev) { case 'join': if (prevContent && prevContent.membership === 'join') { if (prevContent.displayname && content.displayname && prevContent.displayname !== content.displayname) { - return _t('%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.', { - senderName, + return _t('%(oldDisplayName)s changed their display name to %(displayName)s.', { oldDisplayName: prevContent.displayname, displayName: content.displayname, }); From f1eb899cadf3822b066ab90db58d4f1de0c76a71 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 6 Feb 2018 10:26:37 +0000 Subject: [PATCH 0231/1160] Re-run i18n script & prune --- src/i18n/strings/ca.json | 2 -- src/i18n/strings/cs.json | 2 -- src/i18n/strings/da.json | 1 - src/i18n/strings/de_DE.json | 4 ---- src/i18n/strings/el.json | 1 - src/i18n/strings/en_EN.json | 38 ++++++++++++++++++----------------- src/i18n/strings/en_US.json | 1 - src/i18n/strings/eo.json | 2 -- src/i18n/strings/es.json | 1 - src/i18n/strings/eu.json | 4 ---- src/i18n/strings/fi.json | 1 - src/i18n/strings/fr.json | 4 ---- src/i18n/strings/gl.json | 2 -- src/i18n/strings/hu.json | 4 ---- src/i18n/strings/id.json | 1 - src/i18n/strings/ko.json | 1 - src/i18n/strings/lv.json | 1 - src/i18n/strings/nl.json | 1 - src/i18n/strings/pl.json | 1 - src/i18n/strings/pt.json | 1 - src/i18n/strings/pt_BR.json | 1 - src/i18n/strings/ru.json | 4 ---- src/i18n/strings/sk.json | 4 ---- src/i18n/strings/sr.json | 1 - src/i18n/strings/sv.json | 1 - src/i18n/strings/th.json | 1 - src/i18n/strings/tr.json | 1 - src/i18n/strings/uk.json | 1 - src/i18n/strings/zh_Hans.json | 1 - src/i18n/strings/zh_Hant.json | 3 --- 30 files changed, 20 insertions(+), 71 deletions(-) diff --git a/src/i18n/strings/ca.json b/src/i18n/strings/ca.json index eb4ac76d05..0aba649fde 100644 --- a/src/i18n/strings/ca.json +++ b/src/i18n/strings/ca.json @@ -36,7 +36,6 @@ "powered by Matrix": "amb tecnologia de Matrix", "Edit": "Edita", "Unpin Message": "Desenganxa el missatge", - "Quote": "Cita", "Register": "Registre", "Rooms": "Sales", "Add rooms to this community": "Afegeix sales a aquesta comunitat", @@ -161,7 +160,6 @@ "%(senderName)s requested a VoIP conference.": "%(senderName)s ha sol·licitat una conferència VoIP.", "%(senderName)s invited %(targetName)s.": "%(senderName)s ha convidat a %(targetName)s.", "%(senderName)s banned %(targetName)s.": "%(senderName)s ha expulsat a %(targetName)s.", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s ha canviat el seu nom visible %(oldDisplayName)s a %(displayName)s.", "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s ha establert %(displayName)s com el seu nom visible.", "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s ha retirat el seu nom visible %(oldDisplayName)s.", "%(senderName)s removed their profile picture.": "%(senderName)s ha retirat la seva foto de perfil.", diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index b6b1aa8255..fe2c9bd249 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -359,7 +359,6 @@ "Active call (%(roomName)s)": "Probíhající hovor (%(roomName)s)", "%(senderName)s banned %(targetName)s.": "%(senderName)s vykázal/a %(targetName)s.", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Nelze se připojit k domovskému serveru přes HTTP, pokud je v adresním řádku HTTPS. Buď použijte HTTPS, nebo povolte nebezpečné scripty.", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s změnil/a své zobrazované jméno z %(oldDisplayName)s na %(displayName)s.", "Click here to fix": "Klikněte zde pro opravu", "Click to mute video": "Klikněte pro zakázání videa", "click to reveal": "klikněte pro odhalení", @@ -952,6 +951,5 @@ "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "Jednorázová migrace šifrovaných údajů dokončena. E2E šifrovaní vám nebude fungovat jakmile se vrátíte ke starší verzi programu Riot. Pokud plánujete používat šifrovaní ve starší verzi Riot, doporučujeme vám se nejdříve odhlásit. Aby jste si zachovali historii šifrovaných konverzací, exportujte a znovu importujte klíče místností.", "Old cryptography data detected": "Nalezeny starší šifrované datové zprávy", "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Nalezeny datové zprávy ze starší verze Riot. Důsledkem bude, že E2E šifrování nebude ve starší verzi Riot správně fungovat. Šifrované zprávy ze starší verze nemusí být čitelné v nové verzi. Může dojít i k selhání zasílaní zpráv s touto verzí Riot. Pokud zaznamenáte některý z uvedených problému, odhlaste se a přihlaste znovu. Pro zachování historie zpráv exportujte a znovu importujte vaše klíče.", - "Show devices or cancel all.": "Zobrazit zařízení anebo Zrušit vše.", "Warning": "Upozornění" } diff --git a/src/i18n/strings/da.json b/src/i18n/strings/da.json index 67f00cdefb..dbcc9fbb2c 100644 --- a/src/i18n/strings/da.json +++ b/src/i18n/strings/da.json @@ -218,7 +218,6 @@ "%(senderName)s requested a VoIP conference.": "%(senderName)s forespurgte en VoIP konference.", "%(senderName)s invited %(targetName)s.": "%(senderName)s inviterede %(targetName)s.", "%(senderName)s banned %(targetName)s.": "%(senderName)s bannede %(targetName)s.", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s ændrede deres viste navn fra %(oldDisplayName)s til %(displayName)s.", "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s satte deres viste navn til %(displayName)s.", "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s fjernede deres viste navn (%(oldDisplayName)s).", "%(senderName)s removed their profile picture.": "%(senderName)s fjernede deres profilbillede.", diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index d0c193bfa9..d118d50d56 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -246,7 +246,6 @@ "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s hat die Einladung für %(displayName)s akzeptiert.", "%(senderName)s answered the call.": "%(senderName)s hat den Anruf angenommen.", "%(senderName)s banned %(targetName)s.": "%(senderName)s hat %(targetName)s verbannt.", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s hat den Anzeigenamen von %(oldDisplayName)s auf %(displayName)s geändert.", "%(senderName)s changed their profile picture.": "%(senderName)s hat das Profilbild geändert.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s hat das Berechtigungslevel von %(powerLevelDiffText)s geändert.", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s hat den Raumnamen geändert zu %(roomName)s.", @@ -949,7 +948,6 @@ "expand": "Erweitern", "Cryptography data migrated": "Kryptographie-Schlüssel wurden übertragen", "Old cryptography data detected": "Alte Kryptografiedaten erkannt", - "Show devices or cancel all.": "Geräte anzeigen oder alle abbrechen.", "Warning": "Warnung", "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "Eine tiefgreifende Migration im Kontext der Verschlüsselungsdaten wurde durchgeführt. Ende-zu-Ende-Verschlüsselung wird nicht mehr funktionieren, wenn du zu einer älteren Version von Riot zurückkehrst. Wenn du Ende-zu-Ende-Verschlüssung bei einer älteren Version von Riot brauchst, melde dich bitte vorher ab. Um die Historie zu behalten, ex- und reimportiere deine Schlüssel.", "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Es wurden Daten von einer älteren Version von Riot entdeckt. Dies wird zu Fehlern in der Ende-zu-Ende-Verschlüsselung der älteren Version geführt haben. Ende-zu-Ende verschlüsselte Nachrichten, die ausgetauscht wruden, während die ältere Version genutzt wurde, werden in dieser Version nicht entschlüsselbar sein. Es kann auch zu Fehlern mit Nachrichten führen, die mit dieser Version versendet werden. Wenn du Probleme feststellst, melde dich ab und wieder an. Um die Historie zu behalten, ex- und reimportiere deine Schlüssel.", @@ -959,8 +957,6 @@ "Send a message (unencrypted)…": "Nachricht senden (unverschlüsselt)…", "Replying": "Antwortet", "Minimize apps": "Apps minimieren", - "Quote": "Zitat", - "Show devices, mark devices known and send or cancel all.": "Geräte anzeigen, Geräte als bekannt markieren und senden oder alles abbrechen.", "%(count)s of your messages have not been sent.|one": "Deine Nachricht wurde nicht gesendet.", "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "Jetzt alle erneut senden oder alle abbrechen. Du kannst auch einzelne Nachrichten auswählen und erneut senden oder abbrechen.", "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Nachricht jetzt erneut senden oder senden abbrechen now.", diff --git a/src/i18n/strings/el.json b/src/i18n/strings/el.json index 4974268999..c17c49eb7c 100644 --- a/src/i18n/strings/el.json +++ b/src/i18n/strings/el.json @@ -49,7 +49,6 @@ "Blacklisted": "Στη μαύρη λίστα", "Can't load user settings": "Δεν είναι δυνατή η φόρτωση των ρυθμίσεων χρήστη", "Change Password": "Αλλαγή κωδικού πρόσβασης", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "Ο %(senderName)s άλλαξε το όνομά του από %(oldDisplayName)s σε %(displayName)s.", "%(senderName)s changed their profile picture.": "Ο %(senderName)s άλλαξε τη φωτογραφία του προφίλ του.", "%(senderDisplayName)s changed the room name to %(roomName)s.": "Ο %(senderDisplayName)s άλλαξε το όνομα του δωματίου σε %(roomName)s.", "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "Ο %(senderDisplayName)s άλλαξε το θέμα σε \"%(topic)s\".", diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 93af7aa47c..6139ac2a91 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2,6 +2,18 @@ "This email address is already in use": "This email address is already in use", "This phone number is already in use": "This phone number is already in use", "Failed to verify email address: make sure you clicked the link in the email": "Failed to verify email address: make sure you clicked the link in the email", + "The platform you're on": "The platform you're on", + "The version of Riot.im": "The version of Riot.im", + "Whether or not you're logged in (we don't record your user name)": "Whether or not you're logged in (we don't record your user name)", + "Your language of choice": "Your language of choice", + "Which officially provided instance you are using, if any": "Which officially provided instance you are using, if any", + "Whether or not you're using the Richtext mode of the Rich Text Editor": "Whether or not you're using the Richtext mode of the Rich Text Editor", + "Your homeserver's URL": "Your homeserver's URL", + "Your identity server's URL": "Your identity server's URL", + "Analytics": "Analytics", + "The information being sent to us to help make Riot.im better includes:": "The information being sent to us to help make Riot.im better includes:", + "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().", + "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.", "Call Failed": "Call Failed", "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.", "Review Devices": "Review Devices", @@ -119,7 +131,7 @@ "%(senderName)s requested a VoIP conference.": "%(senderName)s requested a VoIP conference.", "%(senderName)s invited %(targetName)s.": "%(senderName)s invited %(targetName)s.", "%(senderName)s banned %(targetName)s.": "%(senderName)s banned %(targetName)s.", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s changed their display name to %(displayName)s.", "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s set their display name to %(displayName)s.", "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s removed their display name (%(oldDisplayName)s).", "%(senderName)s removed their profile picture.": "%(senderName)s removed their profile picture.", @@ -369,6 +381,9 @@ "Drop here to restore": "Drop here to restore", "Drop here to demote": "Drop here to demote", "Drop here to tag %(section)s": "Drop here to tag %(section)s", + "Failed to set direct chat tag": "Failed to set direct chat tag", + "Failed to remove tag %(tagName)s from room": "Failed to remove tag %(tagName)s from room", + "Failed to add tag %(tagName)s to room": "Failed to add tag %(tagName)s to room", "Press to start a chat with someone": "Press to start a chat with someone", "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", "Community Invites": "Community Invites", @@ -633,7 +648,7 @@ "expand": "expand", "Custom of %(powerLevel)s": "Custom of %(powerLevel)s", "Custom level": "Custom level", - "Quote": "Quote", + "In reply to ": "In reply to ", "Room directory": "Room directory", "Start chat": "Start chat", "And %(count)s more...|other": "And %(count)s more...", @@ -652,8 +667,8 @@ "Start Chatting": "Start Chatting", "Confirm Removal": "Confirm Removal", "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.", - "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "Community IDs may only contain characters a-z, 0-9, or '=_-./'", "Community IDs cannot not be empty.": "Community IDs cannot not be empty.", + "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "Community IDs may only contain characters a-z, 0-9, or '=_-./'", "Something went wrong whilst creating your community": "Something went wrong whilst creating your community", "Create Community": "Create Community", "Community Name": "Community Name", @@ -764,6 +779,7 @@ "Reject invitation": "Reject invitation", "Are you sure you want to reject the invitation?": "Are you sure you want to reject the invitation?", "Failed to reject invitation": "Failed to reject invitation", + "This room is not public. You will not be able to rejoin without an invite.": "This room is not public. You will not be able to rejoin without an invite.", "Are you sure you want to leave the room '%(roomName)s'?": "Are you sure you want to leave the room '%(roomName)s'?", "Failed to leave room": "Failed to leave room", "Signed Out": "Signed Out", @@ -842,7 +858,6 @@ "Bug Report": "Bug Report", "Found a bug?": "Found a bug?", "Report it": "Report it", - "Analytics": "Analytics", "Riot collects anonymous analytics to allow us to improve the application.": "Riot collects anonymous analytics to allow us to improve the application.", "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.", "Learn more about how we use analytics.": "Learn more about how we use analytics.", @@ -969,18 +984,5 @@ "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.", "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.", "File to import": "File to import", - "Import": "Import", - "The information being sent to us to help make Riot.im better includes:": "The information being sent to us to help make Riot.im better includes:", - "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().", - "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.", - "The platform you're on": "The platform you're on", - "The version of Riot.im": "The version of Riot.im", - "Whether or not you're logged in (we don't record your user name)": "Whether or not you're logged in (we don't record your user name)", - "Your language of choice": "Your language of choice", - "Which officially provided instance you are using, if any": "Which officially provided instance you are using, if any", - "Whether or not you're using the Richtext mode of the Rich Text Editor": "Whether or not you're using the Richtext mode of the Rich Text Editor", - "Your homeserver's URL": "Your homeserver's URL", - "Your identity server's URL": "Your identity server's URL", - "In reply to ": "In reply to ", - "This room is not public. You will not be able to rejoin without an invite.": "This room is not public. You will not be able to rejoin without an invite." + "Import": "Import" } diff --git a/src/i18n/strings/en_US.json b/src/i18n/strings/en_US.json index ce606d3907..2375e6ad2e 100644 --- a/src/i18n/strings/en_US.json +++ b/src/i18n/strings/en_US.json @@ -52,7 +52,6 @@ "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.", "Can't load user settings": "Can't load user settings", "Change Password": "Change Password", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.", "%(senderName)s changed their profile picture.": "%(senderName)s changed their profile picture.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s changed the power level of %(powerLevelDiffText)s.", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s changed the room name to %(roomName)s.", diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index 409c2054cb..a50d16a2b3 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -115,7 +115,6 @@ "%(senderName)s requested a VoIP conference.": "%(senderName)s petis rettelefonan vokon.", "%(senderName)s invited %(targetName)s.": "%(senderName)s invitis uzanton %(targetName)s.", "%(senderName)s banned %(targetName)s.": "%(senderName)s forbaris uzanton %(targetName)s.", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s ŝanĝis sian vidigan nomon de %(oldDisplayName)s al %(displayName)s.", "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s agordis sian vidigan nomon al %(displayName)s.", "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s forigis sian vidigan nomon (%(oldDisplayName)s).", "%(senderName)s removed their profile picture.": "%(senderName)s forigis sian profilbildon.", @@ -767,7 +766,6 @@ "You have no visible notifications": "Neniuj videblaj sciigoj", "Scroll to bottom of page": "Rulumi al susbo de la paĝo", "Message not sent due to unknown devices being present": "Mesaĝoj ne sendiĝis pro ĉeesto de nekonataj aparatoj", - "Show devices or cancel all.": "Montri aparatojnnuligi ĉiujn.", "Connectivity to the server has been lost.": "Konekto al la servilo perdiĝis.", "Sent messages will be stored until your connection has returned.": "Senditaj mesaĝoj konserviĝos ĝis via konekto refunkcios.", "%(count)s new messages|other": "%(count)s novaj mesaĝoj", diff --git a/src/i18n/strings/es.json b/src/i18n/strings/es.json index 53e0a3cc9f..1b513cc51f 100644 --- a/src/i18n/strings/es.json +++ b/src/i18n/strings/es.json @@ -35,7 +35,6 @@ "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "No se puede conectar al servidor via HTTP, cuando es necesario un enlace HTTPS en la barra de direcciones de tu navegador. Ya sea usando HTTPS o habilitando los scripts inseguros.", "Can't load user settings": "No se puede cargar las configuraciones del usuario", "Change Password": "Cambiar clave", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s ha cambiado su nombre de %(oldDisplayName)s a %(displayName)s.", "%(senderName)s changed their profile picture.": "%(senderName)s ha cambiado su foto de perfil.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s ha cambiado el nivel de acceso de %(powerLevelDiffText)s.", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s ha cambiado el nombre de la sala a %(roomName)s.", diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index 2613ebf4ce..8ec181d879 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -272,7 +272,6 @@ "Bulk Options": "Aukera masiboak", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Ezin da hasiera zerbitzarira konektatu, egiaztatu zure konexioa, ziurtatu zure hasiera zerbitzariaren SSL ziurtagiria fidagarritzat jotzen duela zure gailuak, eta nabigatzailearen pluginen batek ez dituela eskaerak blokeatzen.", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Ezin zara hasiera zerbitzarira HTTP bidez konektatu zure nabigatzailearen barran dagoen URLa HTTS bada. Erabili HTTPS edo gaitu script ez seguruak.", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s erabiltzaileak bere pantaila-izena aldatu du, %(oldDisplayName)s izatetik %(displayName)s izatera.", "%(senderName)s changed their profile picture.": "%(senderName)s erabiltzaileak bere profileko argazkia aldatu du.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s erabiltzaileak botere mailaz aldatu du %(powerLevelDiffText)s.", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s erabiltzaileak gelaren izena aldatu du, orain %(roomName)s da.", @@ -947,7 +946,6 @@ "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Riot bertsio zahar batek datuak antzeman dira. Honek bertsio zaharrean muturretik muturrerako zifratzea ez funtzionatzea eragingo du. Azkenaldian bertsio zaharrean bidali edo jasotako zifratutako mezuak agian ezin izango dira deszifratu bertsio honetan. Honek ere Bertsio honekin egindako mezu trukeak huts egitea ekar dezake. Arazoak badituzu, amaitu saioa eta hasi berriro saioa. Mezuen historiala gordetzeko, esportatu eta berriro inportatu zure gakoak.", "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Sortu komunitate bat erabiltzaileak eta gelak biltzeko! Sortu zure hasiera orria eta markatu zure espazioa Matrix unibertsoan.", "To join an existing community you'll have to know its community identifier; this will look something like +example:matrix.org.": "Bdagoen komunitate batera elkartzeko, komunitatearen identifikatzailea jakin behar duzu; honen antza izango du +adibidea:matrix.org.", - "Show devices or cancel all.": "Erakutsi gailuak edo baztertu guztia.", "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Ez dago beste inor hemen! Beste batzuk gonbidatu nahi dituzu edo gela hutsik dagoela abisatzeari utzi?", "Light theme": "Itxura argia", "Dark theme": "Itxura iluna", @@ -965,11 +963,9 @@ "Send a message (unencrypted)…": "Bidali mezu bat (zifratu gabea)…", "Replying": "Erantzuten", "Minimize apps": "Minimizatu aplikazioak", - "Quote": "Aipua", "The platform you're on": "Zauden plataforma", "The version of Riot.im": "Riot.im bertsioa", "Your language of choice": "Zure aukerako hizkuntza", - "Show devices, mark devices known and send or cancel all.": "Erakutsi gailuak, markatu gailuak ezagun gisa eta bidali edo ezeztatu guztia.", "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Pribatutasuna garrantzitsua da guretzat, beraz ez dugu datu pertsonalik edo identifikagarririk jasotzen gure estatistiketan.", "Learn more about how we use analytics.": "Ikasi gehiago estatistikei ematen diegun erabileraz.", "The information being sent to us to help make Riot.im better includes:": "Riot.im hobetzeko bidaltzen zaigun informazioan hau dago:", diff --git a/src/i18n/strings/fi.json b/src/i18n/strings/fi.json index 0ae3379ed7..fc7eac51a7 100644 --- a/src/i18n/strings/fi.json +++ b/src/i18n/strings/fi.json @@ -62,7 +62,6 @@ "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Yhdistäminen kotipalveluun HTTP:n avulla ei ole mahdollista kun selaimen osoitepalkissa on HTTPS URL. Käytä joko HTTPS tai salli turvattomat skriptit.", "Can't load user settings": "Käyttäjäasetusten lataaminen epäonnistui", "Change Password": "Muuta salasana", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s muutti näyttönimensä %(oldDisplayName)s -> %(displayName)s.", "%(senderName)s changed their profile picture.": "%(senderName)s muutti profiilikuvansa.", "%(targetName)s accepted an invitation.": "%(targetName)s hyväksyi kutsun.", "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s hyväksyi kutsun käyttäjän %(displayName)s puolesta.", diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index b9d2ef7d89..36620c2894 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -62,7 +62,6 @@ "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Impossible de se connecter au serveur d'accueil en HTTP si l'URL dans la barre de votre explorateur est en HTTPS. Utilisez HTTPS ou activez le support des scripts non-vérifiés.", "Can't load user settings": "Impossible de charger les paramètres de l'utilisateur", "Change Password": "Changer le mot de passe", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s a changé son nom affiché de %(oldDisplayName)s en %(displayName)s.", "%(senderName)s changed their profile picture.": "%(senderName)s a changé son image de profil.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s a changé le rang de %(powerLevelDiffText)s.", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s a changé le nom du salon en %(roomName)s.", @@ -952,7 +951,6 @@ "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "Une migration unique des données de chiffrement a été effectuée. Le chiffrement de bout-en-bout ne fonctionnera pas si vous revenez sur une version antérieure de Riot. Si vous avez besoin d'utiliser le chiffrement de bout-en-bout sur une ancienne version, déconnectez-vous de Riot. Pour conserver l'historique des messages, exportez et réimportez vos clés de chiffrement.", "Old cryptography data detected": "Anciennes données de chiffrement détectées", "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Nous avons détecté des données d'une ancienne version de Riot. Le chiffrement de bout-en-bout n'aura pas fonctionné correctement sur l'ancienne version. Les messages chiffrés échangés récemment dans l'ancienne version ne sont peut-être pas déchiffrables dans cette version. Les échanges de message avec cette version peuvent aussi échouer. Si vous rencontrez des problèmes, déconnectez-vous puis reconnectez-vous. Pour conserver l'historique des messages, exportez puis réimportez vos clés de chiffrement.", - "Show devices or cancel all.": "Afficher les appareils ou tout annuler.", "Warning": "Attention", "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Vous ne pourrez pas annuler cette modification car vous vous destituez. Si vous êtes le dernier utilisateur privilégié de ce salon, il sera impossible de récupérer les privilèges.", "%(count)s of your messages have not been sent.|one": "Votre message n'a pas été envoyé.", @@ -965,8 +963,6 @@ "Send a message (unencrypted)…": "Envoyer un message (non chiffré)…", "Replying": "Répond", "Minimize apps": "Minimiser les applications", - "Quote": "Citer", - "Show devices, mark devices known and send or cancel all.": "Afficher les appareils, marquer les appareils comme connus et envoyer ou tout annuler.", "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Le respect de votre vie privée est important pour nous, donc nous ne collectons aucune donnée personnelle ou permettant de vous identifier pour nos statistiques.", "Learn more about how we use analytics.": "En savoir plus sur notre utilisation des statistiques.", "The information being sent to us to help make Riot.im better includes:": "Les informations qui nous sont envoyées pour nous aider à améliorer Riot.im comprennent :", diff --git a/src/i18n/strings/gl.json b/src/i18n/strings/gl.json index 3fbaf2591b..7a1fd567ee 100644 --- a/src/i18n/strings/gl.json +++ b/src/i18n/strings/gl.json @@ -117,7 +117,6 @@ "%(senderName)s requested a VoIP conference.": "%(senderName)s solicitou unha conferencia VoIP.", "%(senderName)s invited %(targetName)s.": "%(senderName)s convidou a %(targetName)s.", "%(senderName)s banned %(targetName)s.": "%(senderName)s bloqueou a %(targetName)s.", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s mudou o seu nome público de %(oldDisplayName)s a %(displayName)s.", "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s estableceu o seu nome público a %(displayName)s.", "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s eliminou o seu nome público (%(oldDisplayName)s).", "%(senderName)s removed their profile picture.": "%(senderName)s eliminou a súa imaxe de perfil.", @@ -625,7 +624,6 @@ "expand": "expandir", "Custom of %(powerLevel)s": "Personalización de %(powerLevel)s", "Custom level": "Nivel personalizado", - "Quote": "Cita", "Room directory": "Directorio de salas", "Start chat": "Iniciar conversa", "And %(count)s more...|other": "E %(count)s máis...", diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 7bfadfc96e..29067f0bb4 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -76,7 +76,6 @@ "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Nem lehet csatlakozni a saját szerverhez HTTP-n keresztül ha HTTPS van a böngésző címsorában. Vagy használj HTTPS-t vagy engedélyezd a nem biztonságos script-et.", "Can't load user settings": "A felhasználói beállítások nem tölthetők be", "Change Password": "Jelszó megváltoztatása", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s megváltoztatta a nevét erről: %(oldDisplayName)s erre: %(displayName)s.", "%(senderName)s changed their profile picture.": "%(senderName)s megváltoztatta a profil képét.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s megváltoztatta a hozzáférési szintjét erre: %(powerLevelDiffText)s.", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s megváltoztatta a szoba nevét erre: %(roomName)s.", @@ -952,7 +951,6 @@ "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "A titkosítási adatok egyszeri migrációja megtörtént. Ha egy régebbi Riot verzióra állsz vissza a végponttól-végpontig titkosítás nem fog működni. Ha régi verzióval szeretnéd használni a végponttól-végpontig titkosítást először jelentkezz ki a Riotból. A régi üzenetek későbbi eléréséhez először mentsd ki a kulcsokat majd töltsd be újra.", "Old cryptography data detected": "Régi titkosítási adatot találhatók", "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Régebbi Riot verzióból származó adatok találhatók. Ezek hibás működéshez vezethettek a végponttól-végpontig titkosításban régebbi verzióknál. A nemrég küldött/fogadott titkosított üzenetek ha a régi adatokat használták lehetséges hogy nem lesznek visszafejthetők ebben a verzióban. Ha problémákba ütközöl jelentkezz ki és vissza. A régi üzenetek elérésének biztosításához mentsd ki a kulcsokat és töltsd be újra.", - "Show devices or cancel all.": "Eszközök megmutatása vagy mind elutasítása.", "Warning": "Figyelmeztetés", "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Ahogy lefokozod magad a változás visszafordíthatatlan, ha te vagy az utolsó jogosultságokkal bíró felhasználó a szobában a jogok már nem szerezhetők vissza.", "%(count)s of your messages have not been sent.|one": "Az üzeneted nem lett elküldve.", @@ -965,8 +963,6 @@ "Send a message (unencrypted)…": "Üzenet küldése (titkosítás nélkül)…", "Replying": "Válaszolni", "Minimize apps": "Alkalmazás összecsukása", - "Quote": "Idézet", - "Show devices, mark devices known and send or cancel all.": "Eszközök megjelenítése, eszközök ismertnek jelölése és küldés vagy mindent megszakít.", "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "A személyes adatok védelme fontos számunkra, így mi nem gyűjtünk személyes és személyhez köthető adatokat az analitikánkhoz.", "Learn more about how we use analytics.": "Tudj meg többet arról hogyan használjuk az analitikai adatokat.", "The information being sent to us to help make Riot.im better includes:": "Az adatok amiket a Riot.im javításához felhasználunk az alábbiak:", diff --git a/src/i18n/strings/id.json b/src/i18n/strings/id.json index 2c45314a6e..e95f3b13af 100644 --- a/src/i18n/strings/id.json +++ b/src/i18n/strings/id.json @@ -178,7 +178,6 @@ "Banned users": "Pengguna yang diblokir", "Bulk Options": "Opsi Massal", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Tidak dapat terhubung ke server Home - harap cek koneksi anda, pastikan sertifikat SSL server Home Anda terpercaya, dan ekstensi dari browser tidak memblokir permintaan.", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s mengubah tampilan namanya dari %(oldDisplayName)s menjadi %(displayName)s.", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Tidak dapat terhubung ke server Home melalui HTTP ketika URL di browser berupa HTTPS. Pilih gunakan HTTPS atau aktifkan skrip yang tidak aman.", "%(senderName)s changed their profile picture.": "%(senderName)s telah mengubah foto profilnya.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s telah mengubah tingkat kekuatan dari %(powerLevelDiffText)s.", diff --git a/src/i18n/strings/ko.json b/src/i18n/strings/ko.json index 8a92e0f496..82174ad5d0 100644 --- a/src/i18n/strings/ko.json +++ b/src/i18n/strings/ko.json @@ -96,7 +96,6 @@ "Call Timeout": "전화 대기 시간 초과", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "홈 서버에 연결할 수 없어요 - 연결을 확인해주시고, 홈 서버의 SSL 인증서가 믿을 수 있는지 확인하시고, 브라우저 확장기능이 요청을 차단하고 있는지 확인해주세요.", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "주소창에 HTTPS URL이 있을 때는 HTTP로 홈 서버를 연결할 수 없어요. HTTPS를 쓰거나 안전하지 않은 스크립트를 허용해주세요.", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s님이 별명을 %(oldDisplayName)s에서 %(displayName)s로 바꾸셨어요.", "%(senderName)s changed their profile picture.": "%(senderName)s님이 자기 소개 사진을 바꾸셨어요.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s님이 %(powerLevelDiffText)s의 권한 등급을 바꾸셨어요.", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s님이 방 이름을 %(roomName)s로 바꾸셨어요.", diff --git a/src/i18n/strings/lv.json b/src/i18n/strings/lv.json index 71cfdc5110..ae290d4d5f 100644 --- a/src/i18n/strings/lv.json +++ b/src/i18n/strings/lv.json @@ -53,7 +53,6 @@ "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Neizdevās savienoties ar serveri izmantojot HTTP protokolu, kad tava pārlūka adreses laukā ir HTTPS saite. Tā vietā izmanto HTTPS savienojumu vai iespējo nedrošos skriptus.", "Can't load user settings": "Neizdevās ielādēt lietotāja uzstādījumus", "Change Password": "Paroles maiņa", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s nomainīja redzamo vārdu no %(oldDisplayName)s uz %(displayName)s.", "%(senderName)s changed their profile picture.": "%(senderName)s nomainīja profila attēlu.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s nomainīja statusa līmeni %(powerLevelDiffText)s.", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s nomainīja istabas nosaukumu uz %(roomName)s.", diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index 9ad7c6d5bb..bb1e45c730 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -35,7 +35,6 @@ "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Kan niet met de thuisserver verbinden via HTTP wanneer er een HTTPS-URL in je browser balk staat. Gebruik HTTPS of activeer onveilige scripts.", "Can't load user settings": "Kan de gebruikersinstellingen niet laden", "Change Password": "Wachtwoord veranderen", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s heeft zijn of haar weergavenaam veranderd van %(oldDisplayName)s naar %(displayName)s.", "%(senderName)s changed their profile picture.": "%(senderName)s heeft zijn of haar profielfoto veranderd.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s heeft het machtsniveau van %(powerLevelDiffText)s gewijzigd.", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s heeft de kamernaam van %(roomName)s gewijzigd.", diff --git a/src/i18n/strings/pl.json b/src/i18n/strings/pl.json index 2ddbf47ce6..0933b77dee 100644 --- a/src/i18n/strings/pl.json +++ b/src/i18n/strings/pl.json @@ -145,7 +145,6 @@ "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Nie można nawiązać połączenia z serwerem przy użyciu HTTP podczas korzystania z HTTPS dla bieżącej strony. Użyj HTTPS lub włącz niebezpieczne skrypty.", "Can't load user settings": "Nie można załadować ustawień użytkownika", "Cannot add any more widgets": "Nie można dodać już więcej widżetów", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s zmienił swoją nazwę z %(oldDisplayName)s na %(displayName)s.", "%(senderName)s changed their profile picture.": "%(senderName)s zmienił swoje zdjęcie profilowe.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s zmienił poziom mocy %(powerLevelDiffText)s.", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s zmienił nazwę pokoju na %(roomName)s.", diff --git a/src/i18n/strings/pt.json b/src/i18n/strings/pt.json index 5c55b1eddb..a91a66bdbd 100644 --- a/src/i18n/strings/pt.json +++ b/src/i18n/strings/pt.json @@ -207,7 +207,6 @@ "%(senderName)s answered the call.": "%(senderName)s atendeu à chamada.", "%(senderName)s banned %(targetName)s.": "%(senderName)s removeu %(targetName)s da sala.", "Call Timeout": "Tempo esgotado. Chamada encerrada", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s mudou seu nome público de %(oldDisplayName)s para %(displayName)s.", "%(senderName)s changed their profile picture.": "%(senderName)s alterou sua imagem de perfil.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s alterou o nível de permissões de %(powerLevelDiffText)s.", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s alterou o nome da sala para %(roomName)s.", diff --git a/src/i18n/strings/pt_BR.json b/src/i18n/strings/pt_BR.json index 817d094422..d58a78160b 100644 --- a/src/i18n/strings/pt_BR.json +++ b/src/i18n/strings/pt_BR.json @@ -207,7 +207,6 @@ "%(senderName)s answered the call.": "%(senderName)s atendeu à chamada.", "%(senderName)s banned %(targetName)s.": "%(senderName)s removeu %(targetName)s da sala.", "Call Timeout": "Tempo esgotado. Chamada encerrada", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s mudou seu nome público de %(oldDisplayName)s para %(displayName)s.", "%(senderName)s changed their profile picture.": "%(senderName)s alterou sua imagem de perfil.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s alterou o nível de permissões de %(powerLevelDiffText)s.", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s alterou o nome da sala para %(roomName)s.", diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 9ea84961c8..5f82177a2f 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -146,7 +146,6 @@ "%(senderName)s answered the call.": "%(senderName)s ответил на звонок.", "%(senderName)s banned %(targetName)s.": "%(senderName)s заблокировал(а) %(targetName)s.", "Call Timeout": "Время ожидания вызова", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s изменено с %(oldDisplayName)s на %(displayName)s.", "%(senderName)s changed their profile picture.": "%(senderName)s изменил изображение профиля.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s изменил(а) уровень доступа для %(powerLevelDiffText)s.", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s изменил(а) название комнаты на %(roomName)s.", @@ -946,7 +945,6 @@ "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "Выполнена одноразовая миграция данных криптографии. Сквозное шифрование не будет работать, если вы вернетесь к старой версии Riot. Если требуется использовать сквозную криптографию для более старой версии, сначала выйдите из Riot. Чтобы сохранить журнал сообщений, экспортируйте и повторно импортируйте ключи.", "Old cryptography data detected": "Обнаружены старые криптографические данные", "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Обнаружены данные из более старой версии Riot. Это приведет к сбою криптографии в более ранней версии. В этой версии не могут быть расшифрованы сообщения, которые использовались недавно при использовании старой версии. Это также может привести к сбою обмена сообщениями с этой версией. Если возникают неполадки, выйдите и снова войдите в систему. Чтобы сохранить журнал сообщений, экспортируйте и повторно импортируйте ключи.", - "Show devices or cancel all.": "Показать устройства или отменить все.", "Warning": "Предупреждение", "Showing flair for these communities:": "Показ таланта в следующих сообществах:", "This room is not showing flair for any communities": "В этой комнате не отображается талант для любых сообществ", @@ -965,8 +963,6 @@ "Send a message (unencrypted)…": "Отправить сообщение (незашифрованное)…", "Replying": "Отвечая", "Minimize apps": "Свернуть приложения", - "Quote": "Цитата", - "Show devices, mark devices known and send or cancel all.": "Показать устройства, отметить известные устройства и отправить или отменить все.", "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Конфиденциальность важна для нас, поэтому мы не собираем никаких личных или идентифицируемых данных для нашей аналитики.", "Learn more about how we use analytics.": "Подробнее о том, как мы используем аналитику.", "The information being sent to us to help make Riot.im better includes:": "Информация направляемая нам, чтобы помочь сделать Riot.im лучше включает в себя:", diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index aca0fabbe4..fa118beca4 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -109,7 +109,6 @@ "%(senderName)s requested a VoIP conference.": "%(senderName)s požiadal o VoIP konferenciu.", "%(senderName)s invited %(targetName)s.": "%(senderName)s pozval %(targetName)s.", "%(senderName)s banned %(targetName)s.": "%(senderName)s zakázal vstup %(targetName)s.", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s si zmenil zobrazované meno z %(oldDisplayName)s na %(displayName)s.", "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s si nastavil zobrazované meno %(displayName)s.", "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s odstránil svoje zobrazované meno (%(oldDisplayName)s).", "%(senderName)s removed their profile picture.": "%(senderName)s si z profilu odstránil obrázok.", @@ -945,7 +944,6 @@ "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "Práve bola vykonaná jednorázová migrácia kryptografických údajov. E2E šifrovanie vám nebude fungovať, ak sa vrátite k staršej verzii programu Riot. Ak plánujete použiť šifrovanie v staršej verzii Riot, mali by ste sa pred tým odhlásiť. Aby ste si zachovali históriu šifrovaných konverzácií, exportujte a znovu importujte kľúče miestností.", "Old cryptography data detected": "Nájdené zastaralé kryptografické údaje", "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Boli nájdené údaje zo staršej verzie Riot. Toto spôsobí, že E2E šifrovanie nebude v staršej verzii Riot fungovať. Zašifrované správy prijaté a odoslané v poslednom čase cez staršiu verziu Riot nemusia byť čitateľné v tejto verzii Riot. Môže to tiež spôsobiť, že šifrované konverzácie nebudú s touto verziou Riot čitateľné. Ak spozorujete niektoré s týchto problémov, odhláste sa a opätovne sa prihláste prosím. Históriu šifrovaných konverzácií zachováte tak, že si exportujete a znovu importujete kľúče miestností.", - "Show devices or cancel all.": "Zobraziť zariadenia alebo Zrušiť všetko.", "Warning": "Upozornenie", "This homeserver doesn't offer any login flows which are supported by this client.": "Tento domovský server neponúka žiadny prihlasovací mechanizmus podporovaný vašim klientom.", "Flair": "Príslušnosť ku komunitám", @@ -963,8 +961,6 @@ "Send a message (unencrypted)…": "Odoslať správu (nešifrovanú)…", "Replying": "Odpoveď", "Minimize apps": "Minimalizovať aplikácie", - "Quote": "Citácia", - "Show devices, mark devices known and send or cancel all.": "Zobraziť zariadenia, Považovať zariadenia za známe a odoslať alebo zrušiť všetko.", "%(count)s of your messages have not been sent.|one": "Vaša správa nebola odoslaná.", "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "Znovu poslať všetky alebo zrušiť všetky teraz. Vybratím môžete tiež znovu odoslať alebo zrušiť jednotlivé správy.", "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Znovu odoslať správu alebo zrušiť správu teraz.", diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index 6396455f9d..efac9b9e84 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -119,7 +119,6 @@ "%(senderName)s banned %(targetName)s.": "%(senderName)s је бановао %(targetName)s.", "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“. Ово можда значи да се ваши разговори прате!", "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Кључ за потписивање који сте доставили се подудара са кључем за потписивање од корисника %(userId)s и уређаја %(deviceId)s. Уређај је означен као проверен.", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "Корисник %(senderName)s је променио приказно име из %(oldDisplayName)s у %(displayName)s.", "%(senderName)s set their display name to %(displayName)s.": "Корисник %(senderName)s је себи поставио приказно име %(displayName)s.", "%(senderName)s removed their display name (%(oldDisplayName)s).": "Корисник %(senderName)s је себи уклонио приказно име %(oldDisplayName)s.", "%(senderName)s removed their profile picture.": "Корисник %(senderName)s је себи уклонио профилну слику.", diff --git a/src/i18n/strings/sv.json b/src/i18n/strings/sv.json index 59e9d2a899..ac0c9503f3 100644 --- a/src/i18n/strings/sv.json +++ b/src/i18n/strings/sv.json @@ -48,7 +48,6 @@ "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Det går inte att ansluta till en hemserver via HTTP då adressen i webbläsaren är HTTPS. Använd HTTPS, eller sätt på osäkra skript.", "Can't load user settings": "Det gick inte att ladda användarinställningar", "Change Password": "Byt lösenord", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s bytte namn från %(oldDisplayName)s till %(displayName)s.", "%(senderName)s changed their profile picture.": "%(senderName)s bytte sin profilbild.", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s bytte rummets namn till %(roomName)s.", "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s tog bort rummets namn.", diff --git a/src/i18n/strings/th.json b/src/i18n/strings/th.json index 9e9e606826..adb351f1c2 100644 --- a/src/i18n/strings/th.json +++ b/src/i18n/strings/th.json @@ -84,7 +84,6 @@ "Bans user with given id": "ผู้ใช้และ id ที่ถูกแบน", "Blacklisted": "ขึ้นบัญชีดำ", "Can't load user settings": "ไม่สามารถโหลดการตั้งค่าผู้ใช้ได้", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s เปลี่ยนชื่อที่แสดงของเขาจาก %(oldDisplayName)s ไปเป็น %(displayName)s", "%(senderName)s changed their profile picture.": "%(senderName)s เปลี่ยนรูปโปรไฟล์ของเขา", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s เปลี่ยนชื่อห้องไปเป็น %(roomName)s", "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s ลบชื่อห้อง", diff --git a/src/i18n/strings/tr.json b/src/i18n/strings/tr.json index 4067de767e..51c7a44dd4 100644 --- a/src/i18n/strings/tr.json +++ b/src/i18n/strings/tr.json @@ -55,7 +55,6 @@ "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Tarayıcı çubuğunuzda bir HTTPS URL'si olduğunda Ana Sunusuna HTTP üzerinden bağlanılamıyor . Ya HTTPS kullanın veya güvensiz komut dosyalarını etkinleştirin.", "Can't load user settings": "Kullanıcı ayarları yüklenemiyor", "Change Password": "Şifre Değiştir", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s görüntülenen ismini %(oldDisplayName)s dan %(displayName)s 'a değiştirdi.", "%(senderName)s changed their profile picture.": "%(senderName)s profil resmini değiştirdi.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s %(powerLevelDiffText)s'nin güç düzeyini değiştirdi.", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s odanın ismini %(roomName)s olarak değiştirdi.", diff --git a/src/i18n/strings/uk.json b/src/i18n/strings/uk.json index 7d292a4bbe..2ff04fec65 100644 --- a/src/i18n/strings/uk.json +++ b/src/i18n/strings/uk.json @@ -80,7 +80,6 @@ "Can't load user settings": "Неможливо завантажити настройки користувача", "Cannot add any more widgets": "Неможливо додати більше віджетів", "Change Password": "Поміняти пароль", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s змінено з %(oldDisplayName)s на %(displayName)s.", "%(senderName)s changed their profile picture.": "%(senderName)s змінив зображення профіля.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s змінив(ла) рівень доступу для %(powerLevelDiffText)s.", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s змінив(ла) назву кімнати на %(roomName)s.", diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index 1885cf58f0..14e5a0712f 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -191,7 +191,6 @@ "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "当浏览器地址栏里有 HTTPS 的 URL 时,不能使用 HTTP 连接主服务器。请使用 HTTPS 或者允许不安全的脚本。", "Can't load user settings": "无法加载用户设置", "Change Password": "修改密码", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s 将昵称从 %(oldDisplayName)s 改为了 %(displayName)s。", "%(senderName)s changed their profile picture.": "%(senderName)s 修改了头像。", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s 将聊天室名称改为 %(roomName)s。", "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s 移除了聊天室名称。", diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 8333ce746c..93a324aba0 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -255,7 +255,6 @@ "Are you sure you want to leave the room '%(roomName)s'?": "您確定您要想要離開房間 '%(roomName)s' 嗎?", "Bans user with given id": "禁止有指定 ID 的使用者", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "無法連線到家伺服器 - 請檢查您的連線,確保您的家伺服器的 SSL 憑證可被信任,而瀏覽器擴充套件也沒有阻擋請求。", - "%(senderName)s changed their display name from %(oldDisplayName)s to %(displayName)s.": "%(senderName)s 已經變更他們的名稱,從 %(oldDisplayName)s 到 %(displayName)s。", "%(senderName)s changed their profile picture.": "%(senderName)s 已經變更了他們的基本資料圖片。", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s 變更了 %(powerLevelDiffText)s 權限等級。", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s 將房間名稱變更為 %(roomName)s。", @@ -890,7 +889,6 @@ "collapse": "摺疊", "expand": "展開", "Custom of %(powerLevel)s": "自訂 %(powerLevel)s", - "Quote": "引用", "And %(count)s more...|other": "與更多 %(count)s 個……", "Matrix ID": "Matrix ID", "Matrix Room ID": "Matrix 聊天室 ID", @@ -948,7 +946,6 @@ "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "建立社群以將使用者與聊天室湊成一組!建立自訂的首頁以在 Matrix 宇宙中標出您的空間。", "Join an existing community": "加入既有的社群", "To join an existing community you'll have to know its community identifier; this will look something like +example:matrix.org.": "要加入既有的社群,您必須知道它的社群標記符號;其看起來像是 +example:matrix.org.", - "Show devices, mark devices known and send or cancel all.": "顯示裝置標記裝置為已知並傳送取消全部.", "%(count)s of your messages have not been sent.|one": "您的訊息尚未傳送。", "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "現在重新傳送全部取消全部。您也可以選取單一訊息以重新傳送或取消。", "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "現在重新傳送訊息取消訊息。", From 3398c29aa5989312776d90a15ff72b646e40117e Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 6 Feb 2018 10:31:37 +0000 Subject: [PATCH 0232/1160] Revert unintentional package.josn change --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index edf8ad03d4..f81e72e556 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "eslint-config-google": "^0.7.1", "eslint-plugin-babel": "^4.0.1", "eslint-plugin-flowtype": "^2.30.0", - "eslint-plugin-react": "^7.5.1", + "eslint-plugin-react": "^7.4.0", "estree-walker": "^0.5.0", "expect": "^1.16.0", "flow-parser": "^0.57.3", From 623cc10ab073a0d90254b00b5de02616460e979a Mon Sep 17 00:00:00 2001 From: "Robert A. Viana" Date: Tue, 6 Feb 2018 09:15:50 +0000 Subject: [PATCH 0233/1160] Translated using Weblate (Portuguese (Brazil)) Currently translated at 67.0% (660 of 984 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/pt_BR/ --- src/i18n/strings/pt_BR.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/pt_BR.json b/src/i18n/strings/pt_BR.json index 5a9c4d7d65..f2bd95185e 100644 --- a/src/i18n/strings/pt_BR.json +++ b/src/i18n/strings/pt_BR.json @@ -658,5 +658,6 @@ "Ignored user": "Usuário ignorado", "You are no longer ignoring %(userId)s": "Você parou de ignorar %(userId)s", "Edit": "Editar", - "Unpin Message": "Desafixar Mensagem" + "Unpin Message": "Desafixar Mensagem", + "Add rooms to this community": "Adicionar salas na comunidade" } From b744dbaab7d7feb3008f144a369d7f7cb4309eea Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Tue, 6 Feb 2018 11:56:55 +0000 Subject: [PATCH 0234/1160] Handle setting a newTag without metaData metaData is actually the request body for the PUT that adds the tag so we need to send {} for e.g. m.lowpriority, which is not manually ordered. --- src/actions/RoomListActions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/actions/RoomListActions.js b/src/actions/RoomListActions.js index 3e0ea53a33..5802dbcaed 100644 --- a/src/actions/RoomListActions.js +++ b/src/actions/RoomListActions.js @@ -114,7 +114,7 @@ RoomListActions.tagRoom = function(matrixClient, room, oldTag, newTag, oldIndex, (hasChangedSubLists || metaData) ) { // Optimistic update of what will happen to the room tags - room.tags[newTag] = metaData; + room.tags[newTag] = metaData || {}; const promiseToAdd = matrixClient.setRoomTag(roomId, newTag, metaData).catch(function(err) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); From 8d0d0b43ffa6440bf98577c2246d6ec78fa3ab76 Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Tue, 6 Feb 2018 12:00:06 +0000 Subject: [PATCH 0235/1160] Handle first tag added/last tag removed This is a special case because untagged rooms should appear in im.vector.fake.recent and tagged rooms should not. --- src/stores/RoomListStore.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/stores/RoomListStore.js b/src/stores/RoomListStore.js index 28ffee99d2..32aab47009 100644 --- a/src/stores/RoomListStore.js +++ b/src/stores/RoomListStore.js @@ -101,6 +101,16 @@ class RoomListStore extends Store { _updateRoomListsOptimistic(updatedRoom, oldTag, newTag, metaData) { const newLists = {}; + // Adding a tag to an untagged room - need to remove it from recents + if (newTag && Object.keys(updatedRoom.tags).length === 0) { + oldTag = 'im.vector.fake.recent'; + } + + // Removing a tag from a room with one tag left - need to add it to recents + if (oldTag && Object.keys(updatedRoom.tags).length === 1) { + newTag = 'im.vector.fake.recent'; + } + // Remove room from oldTag Object.keys(this._state.lists).forEach((tagName) => { if (tagName === oldTag) { From dd0e981d728e9cb9974ed49d0cc46b48f1dea7ae Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Tue, 6 Feb 2018 12:00:23 +0000 Subject: [PATCH 0236/1160] Handle indication from server that a room has no more tags --- src/stores/RoomListStore.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/stores/RoomListStore.js b/src/stores/RoomListStore.js index 32aab47009..42c77d5237 100644 --- a/src/stores/RoomListStore.js +++ b/src/stores/RoomListStore.js @@ -153,6 +153,10 @@ class RoomListStore extends Store { newLists[tagName].push(updatedRoom); }); + if (roomTags.length === 0) { + newLists['im.vector.fake.recent'].unshift(updatedRoom); + } + this._setState({ lists: newLists, }); From 6a858863fcf8b49382b6a442dffca7bb53c0ec74 Mon Sep 17 00:00:00 2001 From: Andrey Date: Tue, 6 Feb 2018 12:41:13 +0000 Subject: [PATCH 0237/1160] Translated using Weblate (Russian) Currently translated at 100.0% (986 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 5f82177a2f..e7cc2f2319 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -980,5 +980,9 @@ "This room is not public. You will not be able to rejoin without an invite.": "Эта комната не является публичной. Вы не сможете войти без приглашения.", "Show devices, send anyway or cancel.": "Показать устройства, отправить в любом случае или отменить.", "Community IDs cannot not be empty.": "ID сообществ не могут быть пустыми.", - "In reply to ": "В ответ на " + "In reply to ": "В ответ на ", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s изменил отображаемое имя на %(displayName)s.", + "Failed to set direct chat tag": "Не удалось установить тег прямого чата", + "Failed to remove tag %(tagName)s from room": "Не удалось удалить тег %(tagName)s из комнаты", + "Failed to add tag %(tagName)s to room": "Не удалось добавить тег %(tagName)s в комнату" } From 1ea6301ecaf7154acc4b862f2d7f7639ea32e711 Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Tue, 6 Feb 2018 14:25:33 +0000 Subject: [PATCH 0238/1160] Add index fix again This was changed on /develop to fix an issue where the incorrect index was being used in a condition to handle literal edge cases of dragging room tiles to start or end of an ordered sublist. --- src/actions/RoomListActions.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/actions/RoomListActions.js b/src/actions/RoomListActions.js index 5802dbcaed..f59e9953ee 100644 --- a/src/actions/RoomListActions.js +++ b/src/actions/RoomListActions.js @@ -56,10 +56,13 @@ RoomListActions.tagRoom = function(matrixClient, room, oldTag, newTag, oldIndex, newTag === oldTag && oldIndex < newIndex ) ? 1 : 0; - const prevOrder = newIndex === 0 ? - 0 : newList[offset + newIndex - 1].tags[newTag].order; - const nextOrder = newIndex === newList.length ? - 1 : newList[offset + newIndex].tags[newTag].order; + const indexBefore = offset + newIndex - 1; + const indexAfter = offset + newIndex; + + const prevOrder = indexBefore <= 0 ? + 0 : newList[indexBefore].tags[newTag].order; + const nextOrder = indexAfter >= newList.length ? + 1 : newList[indexAfter].tags[newTag].order; metaData = { order: (prevOrder + nextOrder) / 2.0, From aab57d091d7fea357bd26af63cde458df5ada304 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 6 Feb 2018 14:39:13 +0000 Subject: [PATCH 0239/1160] Make ratelimitedfunc time from the function's end Otherwise any function tghat takes longer than the delay to execute will become eligible for execution again immediately after finishing and therefore be able to spin. This should help with https://github.com/vector-im/riot-web/issues/6060 (at least in the respect that it makes ratelimitedfunc do its job) even if it's not the reason Riot started getting wedged. --- src/ratelimitedfunc.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/ratelimitedfunc.js b/src/ratelimitedfunc.js index d8c30f5d03..20f6db79b8 100644 --- a/src/ratelimitedfunc.js +++ b/src/ratelimitedfunc.js @@ -35,13 +35,17 @@ module.exports = function(f, minIntervalMs) { if (self.lastCall < now - minIntervalMs) { f.apply(this); - self.lastCall = now; + // get the time again now the function has finished, so if it + // took longer than the delay time to execute, it doesn't + // immediately become eligible to run again. + self.lastCall = Date.now(); } else if (self.scheduledCall === undefined) { self.scheduledCall = setTimeout( () => { self.scheduledCall = undefined; f.apply(this); - self.lastCall = now; + // get time again as per above + self.lastCall = Date.now(); }, (self.lastCall + minIntervalMs) - now, ); From 6162c0b3605c284fe053e9de94adbae8daaec6ca Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 6 Feb 2018 15:01:14 +0000 Subject: [PATCH 0240/1160] Fix key bindings in address picker dialog Another regression from https://github.com/matrix-org/matrix-react-sdk/pull/1674 Fixes https://github.com/vector-im/riot-web/issues/5994 --- src/components/views/dialogs/BaseDialog.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index 8e6f944df3..e879808dc2 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -37,6 +37,9 @@ export default React.createClass({ // callback to call when Enter is pressed onEnterPressed: PropTypes.func, + // called when a key is pressed + onKeyDown: PropTypes.func, + // CSS class to apply to dialog div className: PropTypes.string, @@ -49,6 +52,9 @@ export default React.createClass({ }, _onKeyDown: function(e) { + if (this.props.onKeyDown) { + this.props.onKeyDown(e); + } if (e.keyCode === KeyCode.ESCAPE) { e.stopPropagation(); e.preventDefault(); From cf4ae681f49be20c9d9eb17c267efb9e115f5868 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 6 Feb 2018 17:50:53 +0000 Subject: [PATCH 0241/1160] Offline mode (#1723) * Allow the client to run without connection to HS (i.e. using indexeddb) Allows running without having pushRules (it's safe not to have these when running from indexeddb sync.) This means rooms will be displayed with "unknown" notifcation state. This assumes anything that uses the push rules will get pushRule state again when the client starts syncing again. For recovering from being disconnected, * If an avatar has fallen back, try again on reconnection * If a thumbnail image failed to load, retry on reconnect * Load joined groups when reconnecting Update tests to give MELS a context.matrixClient --- src/RoomNotifs.js | 14 +++++- src/components/structures/TagPanel.js | 12 +++++ src/components/views/avatars/BaseAvatar.js | 32 +++++++++++++ src/components/views/elements/Pill.js | 14 +++++- src/components/views/messages/MImageBody.js | 46 +++++++++++++++++-- .../elements/MemberEventListSummary-test.js | 19 ++++---- test/test-utils.js | 26 ++++++++++- 7 files changed, 148 insertions(+), 15 deletions(-) diff --git a/src/RoomNotifs.js b/src/RoomNotifs.js index 5cc078dc59..91e49fe09b 100644 --- a/src/RoomNotifs.js +++ b/src/RoomNotifs.js @@ -34,7 +34,14 @@ export function getRoomNotifsState(roomId) { } // for everything else, look at the room rule. - const roomRule = MatrixClientPeg.get().getRoomPushRule('global', roomId); + let roomRule = null; + try { + roomRule = MatrixClientPeg.get().getRoomPushRule('global', roomId); + } catch (err) { + // Possible that the client doesn't have pushRules yet. If so, it + // hasn't started eiher, so indicate that this room is not notifying. + return null; + } // XXX: We have to assume the default is to notify for all messages // (in particular this will be 'wrong' for one to one rooms because @@ -130,6 +137,11 @@ function setRoomNotifsStateUnmuted(roomId, newState) { } function findOverrideMuteRule(roomId) { + if (!MatrixClientPeg.get().pushRules || + !MatrixClientPeg.get().pushRules['global'] || + !MatrixClientPeg.get().pushRules['global'].override) { + return null; + } for (const rule of MatrixClientPeg.get().pushRules['global'].override) { if (isRuleForRoom(roomId, rule)) { if (isMuteRule(rule) && rule.enabled) { diff --git a/src/components/structures/TagPanel.js b/src/components/structures/TagPanel.js index 1cd3f04f9d..49a7a4020a 100644 --- a/src/components/structures/TagPanel.js +++ b/src/components/structures/TagPanel.js @@ -44,6 +44,7 @@ const TagPanel = React.createClass({ componentWillMount: function() { this.unmounted = false; this.context.matrixClient.on("Group.myMembership", this._onGroupMyMembership); + this.context.matrixClient.on("sync", this.onClientSync); this._tagOrderStoreToken = TagOrderStore.addListener(() => { if (this.unmounted) { @@ -61,6 +62,7 @@ const TagPanel = React.createClass({ componentWillUnmount() { this.unmounted = true; this.context.matrixClient.removeListener("Group.myMembership", this._onGroupMyMembership); + this.context.matrixClient.removeListener("sync", this.onClientSync); if (this._filterStoreToken) { this._filterStoreToken.remove(); } @@ -71,6 +73,16 @@ const TagPanel = React.createClass({ dis.dispatch(GroupActions.fetchJoinedGroups(this.context.matrixClient)); }, + onClientSync(syncState, prevState) { + // Consider the client reconnected if there is no error with syncing. + // This means the state could be RECONNECTING, SYNCING or PREPARED. + const reconnected = syncState !== "ERROR" && prevState !== syncState; + if (reconnected) { + // Load joined groups + dis.dispatch(GroupActions.fetchJoinedGroups(this.context.matrixClient)); + } + }, + onClick(e) { // Ignore clicks on children if (e.target !== e.currentTarget) return; diff --git a/src/components/views/avatars/BaseAvatar.js b/src/components/views/avatars/BaseAvatar.js index 47c217eb96..5735a99125 100644 --- a/src/components/views/avatars/BaseAvatar.js +++ b/src/components/views/avatars/BaseAvatar.js @@ -16,6 +16,7 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; +import { MatrixClient } from 'matrix-js-sdk'; import AvatarLogic from '../../../Avatar'; import sdk from '../../../index'; import AccessibleButton from '../elements/AccessibleButton'; @@ -36,6 +37,10 @@ module.exports = React.createClass({ defaultToInitialLetter: PropTypes.bool, // true to add default url }, + contextTypes: { + matrixClient: PropTypes.instanceOf(MatrixClient), + }, + getDefaultProps: function() { return { width: 40, @@ -49,6 +54,16 @@ module.exports = React.createClass({ return this._getState(this.props); }, + componentWillMount() { + this.unmounted = false; + this.context.matrixClient.on('sync', this.onClientSync); + }, + + componentWillUnmount() { + this.unmounted = true; + this.context.matrixClient.removeListener('sync', this.onClientSync); + }, + componentWillReceiveProps: function(nextProps) { // work out if we need to call setState (if the image URLs array has changed) const newState = this._getState(nextProps); @@ -67,6 +82,23 @@ module.exports = React.createClass({ } }, + onClientSync(syncState, prevState) { + if (this.unmounted) return; + + // Consider the client reconnected if there is no error with syncing. + // This means the state could be RECONNECTING, SYNCING or PREPARED. + const reconnected = syncState !== "ERROR" && prevState !== syncState; + if (reconnected && + // Did we fall back? + this.state.urlsIndex > 0 + ) { + // Start from the highest priority URL again + this.setState({ + urlsIndex: 0, + }); + } + }, + _getState: function(props) { // work out the full set of urls to try to load. This is formed like so: // imageUrls: [ props.url, props.urls, default image ] diff --git a/src/components/views/elements/Pill.js b/src/components/views/elements/Pill.js index a85f83d78c..067c377eaa 100644 --- a/src/components/views/elements/Pill.js +++ b/src/components/views/elements/Pill.js @@ -17,7 +17,7 @@ import React from 'react'; import sdk from '../../../index'; import dis from '../../../dispatcher'; import classNames from 'classnames'; -import { Room, RoomMember } from 'matrix-js-sdk'; +import { Room, RoomMember, MatrixClient } from 'matrix-js-sdk'; import PropTypes from 'prop-types'; import MatrixClientPeg from '../../../MatrixClientPeg'; import { MATRIXTO_URL_PATTERN } from '../../../linkify-matrix'; @@ -61,6 +61,17 @@ const Pill = React.createClass({ shouldShowPillAvatar: PropTypes.bool, }, + + childContextTypes: { + matrixClient: PropTypes.instanceOf(MatrixClient), + }, + + getChildContext() { + return { + matrixClient: this._matrixClient, + }; + }, + getInitialState() { return { // ID/alias of the room/user @@ -135,6 +146,7 @@ const Pill = React.createClass({ componentWillMount() { this._unmounted = false; + this._matrixClient = MatrixClientPeg.get(); this.componentWillReceiveProps(this.props); }, diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index 608f48112e..f5515fad90 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -18,8 +18,9 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; +import { MatrixClient } from 'matrix-js-sdk'; + import MFileBody from './MFileBody'; -import MatrixClientPeg from '../../../MatrixClientPeg'; import ImageUtils from '../../../ImageUtils'; import Modal from '../../../Modal'; import sdk from '../../../index'; @@ -40,15 +41,37 @@ module.exports = React.createClass({ onWidgetLoad: PropTypes.func.isRequired, }, + contextTypes: { + matrixClient: PropTypes.instanceOf(MatrixClient), + }, + getInitialState: function() { return { decryptedUrl: null, decryptedThumbnailUrl: null, decryptedBlob: null, error: null, + imgError: false, }; }, + componentWillMount() { + this.unmounted = false; + this.context.matrixClient.on('sync', this.onClientSync); + }, + + onClientSync(syncState, prevState) { + if (this.unmounted) return; + // Consider the client reconnected if there is no error with syncing. + // This means the state could be RECONNECTING, SYNCING or PREPARED. + const reconnected = syncState !== "ERROR" && prevState !== syncState; + if (reconnected && this.state.imgError) { + // Load the image again + this.setState({ + imgError: false, + }); + } + }, onClick: function onClick(ev) { if (ev.button == 0 && !ev.metaKey) { @@ -97,12 +120,18 @@ module.exports = React.createClass({ imgElement.src = this._getThumbUrl(); }, + onImageError: function() { + this.setState({ + imgError: true, + }); + }, + _getContentUrl: function() { const content = this.props.mxEvent.getContent(); if (content.file !== undefined) { return this.state.decryptedUrl; } else { - return MatrixClientPeg.get().mxcUrlToHttp(content.url); + return this.context.matrixClient.mxcUrlToHttp(content.url); } }, @@ -115,7 +144,7 @@ module.exports = React.createClass({ } return this.state.decryptedUrl; } else { - return MatrixClientPeg.get().mxcUrlToHttp(content.url, 800, 600); + return this.context.matrixClient.mxcUrlToHttp(content.url, 800, 600); } }, @@ -156,7 +185,9 @@ module.exports = React.createClass({ }, componentWillUnmount: function() { + this.unmounted = true; dis.unregister(this.dispatcherRef); + this.context.matrixClient.removeListener('sync', this.onClientSync); }, onAction: function(payload) { @@ -217,6 +248,14 @@ module.exports = React.createClass({ ); } + if (this.state.imgError) { + return ( + + { _t("This image cannot be displayed.") } + + ); + } + const contentUrl = this._getContentUrl(); let thumbUrl; if (this._isGif() && SettingsStore.getValue("autoplayGifsAndVideos")) { @@ -231,6 +270,7 @@ module.exports = React.createClass({ {content.body} diff --git a/test/components/views/elements/MemberEventListSummary-test.js b/test/components/views/elements/MemberEventListSummary-test.js index 436133c717..b593923ef9 100644 --- a/test/components/views/elements/MemberEventListSummary-test.js +++ b/test/components/views/elements/MemberEventListSummary-test.js @@ -1,12 +1,15 @@ -const expect = require('expect'); -const React = require('react'); -const ReactDOM = require("react-dom"); -const ReactTestUtils = require('react-addons-test-utils'); -const sdk = require('matrix-react-sdk'); -const MemberEventListSummary = sdk.getComponent('views.elements.MemberEventListSummary'); +import expect from 'expect'; +import React from 'react'; +import ReactTestUtils from 'react-addons-test-utils'; +import sdk from 'matrix-react-sdk'; import * as languageHandler from '../../../../src/languageHandler'; +import * as testUtils from '../../../test-utils'; + +// Give MELS a matrixClient in its child context +const MemberEventListSummary = testUtils.wrapInMatrixClientContext( + sdk.getComponent('views.elements.MemberEventListSummary'), +); -const testUtils = require('../../../test-utils'); describe('MemberEventListSummary', function() { let sandbox; @@ -113,7 +116,6 @@ describe('MemberEventListSummary', function() { renderer.render(); const result = renderer.getRenderOutput(); - expect(result.type).toBe('div'); expect(result.props.children).toEqual([
    Expanded membership
    , ]); @@ -136,7 +138,6 @@ describe('MemberEventListSummary', function() { renderer.render(); const result = renderer.getRenderOutput(); - expect(result.type).toBe('div'); expect(result.props.children).toEqual([
    Expanded membership
    ,
    Expanded membership
    , diff --git a/test/test-utils.js b/test/test-utils.js index 0b536f5766..5753c02665 100644 --- a/test/test-utils.js +++ b/test/test-utils.js @@ -2,7 +2,8 @@ import sinon from 'sinon'; import Promise from 'bluebird'; - +import React from 'react'; +import PropTypes from 'prop-types'; import peg from '../src/MatrixClientPeg'; import dis from '../src/dispatcher'; import jssdk from 'matrix-js-sdk'; @@ -265,3 +266,26 @@ export function getDispatchForStore(store) { dis._isDispatching = false; }; } + +export function wrapInMatrixClientContext(WrappedComponent) { + class Wrapper extends React.Component { + static childContextTypes = { + matrixClient: PropTypes.object, + } + + getChildContext() { + return { + matrixClient: this._matrixClient, + }; + } + + componentWillMount() { + this._matrixClient = peg.get(); + } + + render() { + return ; + } + } + return Wrapper; +} From 424c367ecc7c2b7f607d5d973056365591a7aac6 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 6 Feb 2018 18:45:43 +0000 Subject: [PATCH 0242/1160] Fix the reject/accept call buttons in canary (mk2) Fixes https://github.com/vector-im/riot-web/issues/6081 by making the accept/reject buttons AccessibleButtons which they should be anyway (presumably the role=button makes chrome do the right thing with the events). Also swallow the onClick event otherwise that propagates out to the room header and causes it to expand/collapse. --- src/components/views/voip/IncomingCallBox.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/components/views/voip/IncomingCallBox.js b/src/components/views/voip/IncomingCallBox.js index 8d75029baa..c0dff4e8a3 100644 --- a/src/components/views/voip/IncomingCallBox.js +++ b/src/components/views/voip/IncomingCallBox.js @@ -1,5 +1,6 @@ /* Copyright 2015, 2016 OpenMarket Ltd +Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -18,6 +19,7 @@ import PropTypes from 'prop-types'; import MatrixClientPeg from '../../../MatrixClientPeg'; import dis from '../../../dispatcher'; import { _t } from '../../../languageHandler'; +import AccessibleButton from '../elements/AccessibleButton'; module.exports = React.createClass({ displayName: 'IncomingCallBox', @@ -26,14 +28,16 @@ module.exports = React.createClass({ incomingCall: PropTypes.object, }, - onAnswerClick: function() { + onAnswerClick: function(e) { + e.stopPropagation(); dis.dispatch({ action: 'answer', room_id: this.props.incomingCall.roomId, }); }, - onRejectClick: function() { + onRejectClick: function(e) { + e.stopPropagation(); dis.dispatch({ action: 'hangup', room_id: this.props.incomingCall.roomId, @@ -67,14 +71,14 @@ module.exports = React.createClass({
    -
    + { _t("Decline") } -
    +
    -
    + { _t("Accept") } -
    +
    From ab88c1cf58b4d9b08362b1eca2cdb892bffc3338 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Tue, 6 Feb 2018 19:11:22 +0000 Subject: [PATCH 0243/1160] Translated using Weblate (French) Currently translated at 100.0% (986 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 36620c2894..f0f9b2dae9 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -980,5 +980,9 @@ "This room is not public. You will not be able to rejoin without an invite.": "Ce salon n'est pas public. Vous ne pourrez pas y revenir sans invitation.", "Community IDs cannot not be empty.": "Les identifiants de communauté ne peuvent pas être vides.", "Show devices, send anyway or cancel.": "Afficher les appareils, envoyer quand même ou annuler.", - "In reply to ": "En réponse à " + "In reply to ": "En réponse à ", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s a changé son nom affiché en %(displayName)s.", + "Failed to set direct chat tag": "Échec de l'ajout de l'étiquette discussion directe", + "Failed to remove tag %(tagName)s from room": "Échec de la suppression de l'étiquette %(tagName)s du salon", + "Failed to add tag %(tagName)s to room": "Échec de l'ajout de l'étiquette %(tagName)s au salon" } From 1b196655fa0767391f59383e699b86cc9a82e3c8 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Tue, 6 Feb 2018 21:11:17 +0000 Subject: [PATCH 0244/1160] Translated using Weblate (Hungarian) Currently translated at 100.0% (986 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 29067f0bb4..4f06bbfc4e 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -980,5 +980,9 @@ "This room is not public. You will not be able to rejoin without an invite.": "Ez a szoba nem nyilvános. Kilépés után csak újabb meghívóval tudsz újra belépni a szobába.", "Show devices, send anyway or cancel.": "Eszközök listája, mindenképpen küld vagy szakítsd meg.", "Community IDs cannot not be empty.": "A közösségi azonosító nem lehet üres.", - "In reply to ": "Válaszolva neki " + "In reply to ": "Válaszolva neki ", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s megváltoztatta a nevét erre: %(displayName)s.", + "Failed to set direct chat tag": "Nem sikerült a közvetlen beszélgetés jelzést beállítani", + "Failed to remove tag %(tagName)s from room": "Nem sikerült a szobáról eltávolítani ezt: %(tagName)s", + "Failed to add tag %(tagName)s to room": "Nem sikerült hozzáadni a szobához ezt: %(tagName)s" } From 054849bc18c304b042ad1a0e5e8ecbea9268a207 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Wed, 7 Feb 2018 08:52:37 +0000 Subject: [PATCH 0245/1160] Translated using Weblate (Slovak) Currently translated at 100.0% (986 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sk/ --- src/i18n/strings/sk.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index fa118beca4..959a18270a 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -977,5 +977,12 @@ "Whether or not you're using the Richtext mode of the Rich Text Editor": "Či pri písaní správ používate rozbalenú lištu formátovania textu", "Your homeserver's URL": "URL adresa vami používaného domovského servera", "Your identity server's URL": "URL adresa vami používaného servera totožností", - "This room is not public. You will not be able to rejoin without an invite.": "Toto nie je verejne dostupná miestnosť. Bez pozvánky nebudete do nej môcť vstúpiť znovu." + "This room is not public. You will not be able to rejoin without an invite.": "Toto nie je verejne dostupná miestnosť. Bez pozvánky nebudete do nej môcť vstúpiť znovu.", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s si zmenil zobrazované meno na %(displayName)s.", + "Failed to set direct chat tag": "Nepodarilo sa nastaviť značku priama konverzácia", + "Failed to remove tag %(tagName)s from room": "Z miestnosti sa nepodarilo odstrániť značku %(tagName)s", + "Failed to add tag %(tagName)s to room": "Miestnosti sa nepodarilo pridať značku %(tagName)s", + "In reply to ": "Odpoveď na ", + "Community IDs cannot not be empty.": "ID komunity nemôže ostať prázdne.", + "Show devices, send anyway or cancel.": "Zobraziť zariadenia, napriek tomu odoslať alebo zrušiť." } From 393236ba3438707da047debbca7464912b61a01f Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Wed, 7 Feb 2018 09:23:00 +0000 Subject: [PATCH 0246/1160] Update / remove stickerpacks --- src/ScalarMessaging.js | 2 + src/components/views/rooms/Stickerpack.js | 45 +++++++++++++++++++---- src/utils/widgets.js | 4 +- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index 0fa342e69f..3d585108dd 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -362,6 +362,8 @@ function setWidget(event, roomId) { sendResponse(event, { success: true, }); + + dis.dispatch({ action: "user_widget_updated" }); } else { // Room widget if (!roomId) { sendError(event, _t('Missing roomId.'), null); diff --git a/src/components/views/rooms/Stickerpack.js b/src/components/views/rooms/Stickerpack.js index 77e188198a..a61ca84fbd 100644 --- a/src/components/views/rooms/Stickerpack.js +++ b/src/components/views/rooms/Stickerpack.js @@ -24,7 +24,7 @@ import Modal from '../../../Modal'; import sdk from '../../../index'; import SdkConfig from '../../../SdkConfig'; import ScalarAuthClient from '../../../ScalarAuthClient'; - +import dis from '../../../dispatcher'; export default class Stickerpack extends React.Component { constructor(props) { @@ -34,11 +34,12 @@ export default class Stickerpack extends React.Component { this.onFinished = this.onFinished.bind(this); this._launchManageIntegrations = this._launchManageIntegrations.bind(this); this._removeStickerpackWidgets = this._removeStickerpackWidgets.bind(this); + this._onWidgetAction = this._onWidgetAction.bind(this); this.defaultStickersContent = (
    -

    {_t("You don't currently have any stickerpacks enabled")}

    -

    {_t("Click")} { _t("here") } {_t("to add some!")}

    +

    { _t("You don't currently have any stickerpacks enabled") }

    +

    { _t("Click") } { _t("here") } { _t("to add some!") }

    {_t('Add
    ); @@ -53,7 +54,9 @@ export default class Stickerpack extends React.Component { _removeStickerpackWidgets() { console.warn('Removing stickerpack widgets'); - Widgets.removeStickerpackWidgets() + Widgets.removeStickerpackWidgets(); + this._getStickerPickerWidget(); + this.onFinished(); } componentDidMount() { @@ -70,16 +73,36 @@ export default class Stickerpack extends React.Component { // }); }); } + this._getStickerPickerWidget(); + this.dispatcherRef = dis.register(this._onWidgetAction); + } + componentWillUnmount() { + dis.unregister(this.dispatcherRef); + } + + _onWidgetAction(payload) { + if (payload.action === "user_widget_updated") { + console.warn("user widget updated"); + this._getStickerPickerWidget(); + return; + } + console.error("Unhandled widget action"); + } + + _getStickerPickerWidget() { // Stickers // TODO - Add support for stickerpacks from multiple app stores. // Render content from multiple stickerpack sources, each within their own iframe, within the stickerpack UI element. + console.warn("Checking for sticker picker widgets"); const stickerpackWidget = Widgets.getStickerpackWidgets()[0]; - console.warn('Stickerpack widget', stickerpackWidget); let stickersContent; // Load stickerpack content if (stickerpackWidget && stickerpackWidget.content && stickerpackWidget.content.url) { + // Set default name + stickerpackWidget.content.name = stickerpackWidget.name || "Stickerpack"; + console.warn('Stickerpack widget', stickerpackWidget); this.widgetId = stickerpackWidget.id; stickersContent = (
    X
    widget.type='stickerpack'); + const widgets = getUserWidgets(); + console.warn("widgets", widgets); + const stickerpackWidgets = widgets.filter((widget) => widget.type='stickerpack'); console.warn('Stickerpack widgets', stickerpackWidgets); return stickerpackWidgets; } From ae094bebe576a58b8c0b6ca893b2e4c650a0d87a Mon Sep 17 00:00:00 2001 From: Krombel Date: Wed, 7 Feb 2018 09:40:21 +0000 Subject: [PATCH 0247/1160] Translated using Weblate (German) Currently translated at 100.0% (986 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 05745932b9..a1687858d1 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -980,5 +980,9 @@ "Whether or not you're logged in (we don't record your user name)": "Ob oder ob du nicht angemeldet bist (wir zeichnen deinen Benutzernamen nicht auf)", "Which officially provided instance you are using, if any": "Welche offiziell angebotene Instanz du nutzt, wenn es der Fall ist", "In reply to ": "Antwort zu ", - "This room is not public. You will not be able to rejoin without an invite.": "Dies ist kein öffentlicher Raum. Du wirst diesen nicht ohne Einladung wieder beitreten können." + "This room is not public. You will not be able to rejoin without an invite.": "Dies ist kein öffentlicher Raum. Du wirst diesen nicht ohne Einladung wieder beitreten können.", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s änderte den Anzeigenamen auf %(displayName)s.", + "Failed to set direct chat tag": "Fehler beim Setzen der Direkt-Chat-Markierung", + "Failed to remove tag %(tagName)s from room": "Fehler beim Entfernen des \"%(tagName)s\"-Tags von dem Raum", + "Failed to add tag %(tagName)s to room": "Fehler beim Hinzufügen des \"%(tagName)s\"-Tags von dem Raum" } From c1649d1b754777d665301c5b319cbba5ee5075eb Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Wed, 7 Feb 2018 09:45:36 +0000 Subject: [PATCH 0248/1160] Give dialogs a matrixClient context Dialogs are mounted outside of the main react tree of MatrixChat, so they won't have its child context. --- src/components/views/dialogs/BaseDialog.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index e879808dc2..66e5fcb0c0 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -17,9 +17,12 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; +import { MatrixClient } from 'matrix-js-sdk'; + import { KeyCode } from '../../../Keyboard'; import AccessibleButton from '../elements/AccessibleButton'; import sdk from '../../../index'; +import MatrixClientPeg from '../../../MatrixClientPeg'; /** * Basic container for modal dialogs. @@ -51,6 +54,20 @@ export default React.createClass({ children: PropTypes.node, }, + childContextTypes: { + matrixClient: PropTypes.instanceOf(MatrixClient), + }, + + getChildContext: function() { + return { + matrixClient: this._matrixClient, + }; + }, + + componentWillMount() { + this._matrixClient = MatrixClientPeg.get(); + }, + _onKeyDown: function(e) { if (this.props.onKeyDown) { this.props.onKeyDown(e); From 74a28a749661e2e742bac2085f2b517081ae8397 Mon Sep 17 00:00:00 2001 From: Krombel Date: Wed, 7 Feb 2018 09:41:35 +0000 Subject: [PATCH 0249/1160] Translated using Weblate (German) Currently translated at 100.0% (986 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index a1687858d1..f92b7b479a 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -984,5 +984,5 @@ "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s änderte den Anzeigenamen auf %(displayName)s.", "Failed to set direct chat tag": "Fehler beim Setzen der Direkt-Chat-Markierung", "Failed to remove tag %(tagName)s from room": "Fehler beim Entfernen des \"%(tagName)s\"-Tags von dem Raum", - "Failed to add tag %(tagName)s to room": "Fehler beim Hinzufügen des \"%(tagName)s\"-Tags von dem Raum" + "Failed to add tag %(tagName)s to room": "Fehler beim Hinzufügen des \"%(tagName)s\"-Tags an dem Raum" } From 443c19c6e149aa7667f8f4b162911eabe34eb006 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Tue, 6 Feb 2018 21:13:13 +0000 Subject: [PATCH 0250/1160] Translated using Weblate (Hungarian) Currently translated at 100.0% (986 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 4f06bbfc4e..48132200a3 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -890,7 +890,7 @@ "%(items)s and %(count)s others|other": "%(items)s és még %(count)s másik", "%(items)s and %(count)s others|one": "%(items)s és még egy másik", "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "Az e-mail leküldésre került ide: %(emailAddress)s. Ha követte a levélben lévő linket kattints alább.", - "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "%(roomName)s szoba láthatóságát nem lehet frissíteni ebben a közösségben: %(groupId)s", + "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "%(roomName)s szoba láthatóságát nem lehet frissíteni ebben a közösségben: %(groupId)s.", "Visibility in Room List": "Láthatóság a szoba listában", "Visible to everyone": "Mindenki számára látható", "Only visible to community members": "Csak a közösség számára látható", From b65e80fa53b49ae2f5802a2521be868b219ac965 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D1=80=D0=BA=D0=BE=20=D0=9C=2E=20=D0=9A=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D0=B8=D1=9B?= Date: Tue, 6 Feb 2018 21:40:24 +0000 Subject: [PATCH 0251/1160] Translated using Weblate (Serbian) Currently translated at 80.4% (793 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sr/ --- src/i18n/strings/sr.json | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index 1a6da54baa..9d5c08046a 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -769,5 +769,28 @@ "For security, this session has been signed out. Please sign in again.": "Зарад безбедности, одјављени сте из ове сесије. Пријавите се поново.", "Cryptography data migrated": "Криптографски подаци су пренесени", "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "Једноструко преношење криптографских података је обављено. Шифровање с краја на крај неће радити ако се вратите на старије издање Riot-а. Ако вам треба шифровање с краја на крај на старијем издању, прво се одјавите из Riot-а. Да бисте задржали историјат порука, извезите па поново увезите ваше кључеве.", - "Old cryptography data detected": "Нађени су стари криптографски подаци" + "Old cryptography data detected": "Нађени су стари криптографски подаци", + "The platform you're on": "Платформа коју користите", + "The version of Riot.im": "Riot.im издање", + "Whether or not you're logged in (we don't record your user name)": "Стање ваше пријављености (не памтимо ваше корисничко име)", + "Your language of choice": "Ваш жељени језик", + "Which officially provided instance you are using, if any": "Коју званичну инстанцу користите, ако користите", + "Whether or not you're using the Richtext mode of the Rich Text Editor": "Да ли користите режим богатог текста у уређивачу богатог текста", + "Your homeserver's URL": "Адреса вашег кућног сервера", + "Your identity server's URL": "Адреса вашег идентитеског сервера", + "Analytics": "Аналитика", + "The information being sent to us to help make Riot.im better includes:": "У податке које нам шаљете зарад побољшавања Riot.im-а спадају:", + "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "Такође бележимо сваку страницу коју користите у апликацији (тренутно ), ваш кориснички агент () и резолуцију вашег уређаја ().", + "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Ако страница садржи поверљиве податке (као што је назив собе, корисника или ИБ-ја групе), ти подаци се уклањају пре слања на сервер.", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "Корисник %(oldDisplayName)s је променио приказно име у %(displayName)s.", + "Failed to set direct chat tag": "Нисам успео да поставим ознаку директног ћаскања", + "Failed to remove tag %(tagName)s from room": "Нисам успео да скинем ознаку %(tagName)s са собе", + "Failed to add tag %(tagName)s to room": "Нисам успео да додам ознаку %(tagName)s на собу", + "In reply to ": "Као одговор за ", + "This room is not public. You will not be able to rejoin without an invite.": "Ова соба није јавна. Нећете моћи да поново приступите без позивнице.", + "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Подаци из старијег издања Riot-а су нађени. Ово ће узроковати лош рад шифровања с краја на крај у старијем издању. Размењене поруке које су шифроване с краја на крај у старијем издању је можда немогуће дешифровати у овом издању. Такође, ово може узроковати неуспешно размењивање порука са овим издањем. Ако доживите проблеме, одјавите се и пријавите се поново. Да бисте задржали историјат поруке, извезите па поново увезите ваше кључеве.", + "Logout": "Одјава", + "Your Communities": "Ваше заједнице", + "Error whilst fetching joined communities": "Грешка приликом добављања списка са приступљеним заједницама", + "Create a new community": "Направи нову заједницу" } From f3943bef51e9551634b42ffad6daef72fc9879c8 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Wed, 7 Feb 2018 10:05:50 +0000 Subject: [PATCH 0252/1160] Check for empty user widgets. --- src/components/views/rooms/Stickerpack.js | 1 - src/utils/widgets.js | 8 ++++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/components/views/rooms/Stickerpack.js b/src/components/views/rooms/Stickerpack.js index a61ca84fbd..3722818bf6 100644 --- a/src/components/views/rooms/Stickerpack.js +++ b/src/components/views/rooms/Stickerpack.js @@ -87,7 +87,6 @@ export default class Stickerpack extends React.Component { this._getStickerPickerWidget(); return; } - console.error("Unhandled widget action"); } _getStickerPickerWidget() { diff --git a/src/utils/widgets.js b/src/utils/widgets.js index 081815fed9..2c7901a18f 100644 --- a/src/utils/widgets.js +++ b/src/utils/widgets.js @@ -36,8 +36,12 @@ function getUserWidgets() { if (!client) { throw new Error('User not logged in'); } - const userWidgets = client.getAccountData('m.widgets').getContent() || {}; - return Object.keys(userWidgets).map((key) => userWidgets[key]); + const userWidgets = client.getAccountData('m.widgets'); + let userWidgetContent = {}; + if (userWidgets && userWidgets.getContent()) { + userWidgetContent = userWidgets.getContent(); + } + return Object.keys(userWidgetContent).map((key) => userWidgetContent[key]); } /** From 0a5bf079139dedb3cc3b897ea68513a7ab146487 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Feb 2018 10:13:19 +0000 Subject: [PATCH 0253/1160] Use getComponent --- src/components/views/voip/IncomingCallBox.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/voip/IncomingCallBox.js b/src/components/views/voip/IncomingCallBox.js index c0dff4e8a3..a04cf4421e 100644 --- a/src/components/views/voip/IncomingCallBox.js +++ b/src/components/views/voip/IncomingCallBox.js @@ -19,7 +19,6 @@ import PropTypes from 'prop-types'; import MatrixClientPeg from '../../../MatrixClientPeg'; import dis from '../../../dispatcher'; import { _t } from '../../../languageHandler'; -import AccessibleButton from '../elements/AccessibleButton'; module.exports = React.createClass({ displayName: 'IncomingCallBox', @@ -63,6 +62,7 @@ module.exports = React.createClass({ } } + const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); return (
    From 2a68e3ea392f84ef11b1efb0b5d58a2dd837bc92 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Feb 2018 11:42:50 +0000 Subject: [PATCH 0254/1160] import sdk --- src/components/views/voip/IncomingCallBox.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/views/voip/IncomingCallBox.js b/src/components/views/voip/IncomingCallBox.js index a04cf4421e..ae003ff6f3 100644 --- a/src/components/views/voip/IncomingCallBox.js +++ b/src/components/views/voip/IncomingCallBox.js @@ -19,6 +19,7 @@ import PropTypes from 'prop-types'; import MatrixClientPeg from '../../../MatrixClientPeg'; import dis from '../../../dispatcher'; import { _t } from '../../../languageHandler'; +import sdk from '../../../index' module.exports = React.createClass({ displayName: 'IncomingCallBox', From 8eb4137ec315293b546a0ec305e76774c16e0ae3 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Feb 2018 11:51:41 +0000 Subject: [PATCH 0255/1160] missing semicolon --- src/components/views/voip/IncomingCallBox.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/voip/IncomingCallBox.js b/src/components/views/voip/IncomingCallBox.js index ae003ff6f3..6cbaabe602 100644 --- a/src/components/views/voip/IncomingCallBox.js +++ b/src/components/views/voip/IncomingCallBox.js @@ -19,7 +19,7 @@ import PropTypes from 'prop-types'; import MatrixClientPeg from '../../../MatrixClientPeg'; import dis from '../../../dispatcher'; import { _t } from '../../../languageHandler'; -import sdk from '../../../index' +import sdk from '../../../index'; module.exports = React.createClass({ displayName: 'IncomingCallBox', From 8d21803df5c9b36b93d06fcc996db552bc819a2d Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Wed, 7 Feb 2018 11:57:06 +0000 Subject: [PATCH 0256/1160] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (986 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hant/ --- src/i18n/strings/zh_Hant.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 93a324aba0..8ea32cf99c 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -980,5 +980,9 @@ "This room is not public. You will not be able to rejoin without an invite.": "這個聊天室並未公開。您在沒有邀請的情況下將無法重新加入。", "Community IDs cannot not be empty.": "社群 ID 不能為空。", "Show devices, send anyway or cancel.": "顯示裝置無論如何都要傳送取消。", - "In reply to ": "回覆給 " + "In reply to ": "回覆給 ", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s 變更了他們的顯示名稱為 %(displayName)s 。", + "Failed to set direct chat tag": "設定直接聊天標籤失敗", + "Failed to remove tag %(tagName)s from room": "從聊天室移除標籤 %(tagName)s 失敗", + "Failed to add tag %(tagName)s to room": "新增標籤 %(tagName)s 到聊天室失敗" } From 34eae0fbde1b59b8a1a37feadd7658694b72ccbe Mon Sep 17 00:00:00 2001 From: "Robert A. Viana" Date: Wed, 7 Feb 2018 11:19:03 +0000 Subject: [PATCH 0257/1160] Translated using Weblate (Portuguese (Brazil)) Currently translated at 67.0% (661 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/pt_BR/ --- src/i18n/strings/pt_BR.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/pt_BR.json b/src/i18n/strings/pt_BR.json index 023294db22..8c7b6ffbd6 100644 --- a/src/i18n/strings/pt_BR.json +++ b/src/i18n/strings/pt_BR.json @@ -658,5 +658,7 @@ "You are no longer ignoring %(userId)s": "Você parou de ignorar %(userId)s", "Edit": "Editar", "Unpin Message": "Desafixar Mensagem", - "Add rooms to this community": "Adicionar salas na comunidade" + "Add rooms to this community": "Adicionar salas na comunidade", + "The version of Riot.im": "A Versão do Riot.im", + "Whether or not you're logged in (we don't record your user name)": "Se você está ou não conectado (Nos não Gravaremos seu nome de usuário)" } From 7b75dbbd15d621df14fb292716d0c499b8ac198e Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Wed, 7 Feb 2018 14:44:01 +0000 Subject: [PATCH 0258/1160] Use default AppTile menu bar. --- src/components/views/elements/AppTile.js | 109 ++++++++++++++-------- src/components/views/rooms/Stickerpack.js | 31 ++---- 2 files changed, 79 insertions(+), 61 deletions(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 582cc01a57..c96ce9f775 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -274,12 +274,16 @@ export default class AppTile extends React.Component { _onEditClick(e) { console.log("Edit widget ID ", this.props.id); - const IntegrationsManager = sdk.getComponent("views.settings.IntegrationsManager"); - const src = this._scalarClient.getScalarInterfaceUrlForRoom( - this.props.room.roomId, 'type_' + this.props.type, this.props.id); - Modal.createTrackedDialog('Integrations Manager', '', IntegrationsManager, { - src: src, - }, "mx_IntegrationsManager"); + if (this.props.onEditClick) { + this.props.onEditClick(); + } else { + const IntegrationsManager = sdk.getComponent("views.settings.IntegrationsManager"); + const src = this._scalarClient.getScalarInterfaceUrlForRoom( + this.props.room.roomId, 'type_' + this.props.type, this.props.id); + Modal.createTrackedDialog('Integrations Manager', '', IntegrationsManager, { + src: src, + }, "mx_IntegrationsManager"); + } } _onSnapshotClick(e) { @@ -298,34 +302,38 @@ export default class AppTile extends React.Component { * otherwise revoke access for the widget to load in the user's browser */ _onDeleteClick() { - if (this._canUserModify()) { - // Show delete confirmation dialog - const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - Modal.createTrackedDialog('Delete Widget', '', QuestionDialog, { - title: _t("Delete Widget"), - description: _t( - "Deleting a widget removes it for all users in this room." + - " Are you sure you want to delete this widget?"), - button: _t("Delete widget"), - onFinished: (confirmed) => { - if (!confirmed) { - return; - } - this.setState({deleting: true}); - MatrixClientPeg.get().sendStateEvent( - this.props.room.roomId, - 'im.vector.modular.widgets', - {}, // empty content - this.props.id, - ).catch((e) => { - console.error('Failed to delete widget', e); - this.setState({deleting: false}); - }); - }, - }); + if (this.props.onDeleteClick) { + this.props.onDeleteClick(); } else { - console.log("Revoke widget permissions - %s", this.props.id); - this._revokeWidgetPermission(); + if (this._canUserModify()) { + // Show delete confirmation dialog + const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); + Modal.createTrackedDialog('Delete Widget', '', QuestionDialog, { + title: _t("Delete Widget"), + description: _t( + "Deleting a widget removes it for all users in this room." + + " Are you sure you want to delete this widget?"), + button: _t("Delete widget"), + onFinished: (confirmed) => { + if (!confirmed) { + return; + } + this.setState({deleting: true}); + MatrixClientPeg.get().sendStateEvent( + this.props.room.roomId, + 'im.vector.modular.widgets', + {}, // empty content + this.props.id, + ).catch((e) => { + console.error('Failed to delete widget', e); + this.setState({deleting: false}); + }); + }, + }); + } else { + console.log("Revoke widget permissions - %s", this.props.id); + this._revokeWidgetPermission(); + } } } @@ -429,6 +437,22 @@ export default class AppTile extends React.Component { return safeWidgetUrl; } + _getTileTitle() { + const name = this.formatAppTileName(); + const titleSpacer =  - ; + let title = ''; + if (this.state.widgetPageTitle && this.state.widgetPageTitle != this.formatAppTileName()) { + title = this.state.widgetPageTitle; + } + + return ( + + { name } + { title ? titleSpacer : '' }{ title } + + ); + } + render() { let appTileBody; @@ -508,17 +532,14 @@ export default class AppTile extends React.Component { { this.props.showMenubar &&
    - - { this.formatAppTileName() } - { this.state.widgetPageTitle && this.state.widgetPageTitle != this.formatAppTileName() && ( -  - { this.state.widgetPageTitle } - ) } + /> } + { this.props.showTitle && this._getTileTitle() } { /* Snapshot widget */ } @@ -575,10 +596,20 @@ AppTile.propTypes = { showMenubar: React.PropTypes.bool, // Should the AppTile render itself show: React.PropTypes.bool, + // Optional onEditClickHandler (overrides default behaviour) + onEditClick: React.PropTypes.func, + // Optional onDeleteClickHandler (overrides default behaviour) + onDeleteClick: React.PropTypes.func, + // Optionally hide the tile title + showTitle: React.PropTypes.bool, + // Optionally hide the tile minimise icon + showMinimise: React.PropTypes.bool, }; AppTile.defaultProps = { url: "", waitForIframeLoad: true, showMenubar: true, + showTitle: true, + showMinimise: true, }; diff --git a/src/components/views/rooms/Stickerpack.js b/src/components/views/rooms/Stickerpack.js index 3722818bf6..6a61618b2c 100644 --- a/src/components/views/rooms/Stickerpack.js +++ b/src/components/views/rooms/Stickerpack.js @@ -25,6 +25,8 @@ import sdk from '../../../index'; import SdkConfig from '../../../SdkConfig'; import ScalarAuthClient from '../../../ScalarAuthClient'; import dis from '../../../dispatcher'; +import TintableSvgButton from '../elements/TintableSvgButton'; + export default class Stickerpack extends React.Component { constructor(props) { @@ -103,6 +105,7 @@ export default class Stickerpack extends React.Component { stickerpackWidget.content.name = stickerpackWidget.name || "Stickerpack"; console.warn('Stickerpack widget', stickerpackWidget); this.widgetId = stickerpackWidget.id; + stickersContent = (
    -
    X
    -
    - { _t("Manage sticker packs") } -
    ); } else { From 5e30468a0080b02f175222e96f29ba53dda6a347 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Wed, 7 Feb 2018 14:48:43 +0000 Subject: [PATCH 0259/1160] Linting --- src/components/views/elements/AppTile.js | 4 ++-- src/components/views/rooms/Stickerpack.js | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index c96ce9f775..9d76e3410e 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -37,8 +37,6 @@ import dis from '../../../dispatcher'; const ALLOWED_APP_URL_SCHEMES = ['https:', 'http:']; export default class AppTile extends React.Component { - static displayName ='AppTile'; - constructor(props) { super(props); this.state = this._getNewState(props); @@ -579,6 +577,8 @@ export default class AppTile extends React.Component { } } +AppTile.displayName ='AppTile'; + AppTile.propTypes = { id: React.PropTypes.string.isRequired, url: React.PropTypes.string.isRequired, diff --git a/src/components/views/rooms/Stickerpack.js b/src/components/views/rooms/Stickerpack.js index 6a61618b2c..e04098a06b 100644 --- a/src/components/views/rooms/Stickerpack.js +++ b/src/components/views/rooms/Stickerpack.js @@ -25,8 +25,6 @@ import sdk from '../../../index'; import SdkConfig from '../../../SdkConfig'; import ScalarAuthClient from '../../../ScalarAuthClient'; import dis from '../../../dispatcher'; -import TintableSvgButton from '../elements/TintableSvgButton'; - export default class Stickerpack extends React.Component { constructor(props) { From 45ad46b4687242f296a12a9c937ddf46577d2574 Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Wed, 7 Feb 2018 15:51:03 +0000 Subject: [PATCH 0260/1160] Fix HS/IS URL reset when switching to Registration --- src/components/structures/MatrixChat.js | 43 ++++++++++++++----- src/components/structures/login/Login.js | 3 ++ .../structures/login/Registration.js | 2 + 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index d6d0b00c84..b37da0144f 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -618,18 +618,26 @@ export default React.createClass({ }, _startRegistration: function(params) { - this.setStateForNewView({ + const newState = { view: VIEWS.REGISTER, - // these params may be undefined, but if they are, - // unset them from our state: we don't want to - // resume a previous registration session if the - // user just clicked 'register' - register_client_secret: params.client_secret, - register_session_id: params.session_id, - register_hs_url: params.hs_url, - register_is_url: params.is_url, - register_id_sid: params.sid, - }); + }; + + // Only honour params if they are all present, otherwise we reset + // HS and IS URLs when switching to registration. + if (params.client_secret && + params.session_id && + params.hs_url && + params.is_url && + params.sid + ) { + newState.register_client_secret = params.client_secret; + newState.register_session_id = params.session_id; + newState.register_hs_url = params.hs_url; + newState.register_is_url = params.is_url; + newState.register_id_sid = params.sid; + } + + this.setStateForNewView(newState); this.notifyNewScreen('register'); }, @@ -1501,6 +1509,17 @@ export default React.createClass({ } }, + onServerConfigChange(config) { + const newState = {}; + if (config.hsUrl) { + newState.register_hs_url = config.hsUrl; + } + if (config.isUrl) { + newState.register_is_url = config.isUrl; + } + this.setState(newState); + }, + _makeRegistrationUrl: function(params) { if (this.props.startingFragmentQueryParams.referrer) { params.referrer = this.props.startingFragmentQueryParams.referrer; @@ -1589,6 +1608,7 @@ export default React.createClass({ onLoginClick={this.onLoginClick} onRegisterClick={this.onRegisterClick} onCancelClick={MatrixClientPeg.get() ? this.onReturnToAppClick : null} + onServerConfigChange={this.onServerConfigChange} /> ); } @@ -1623,6 +1643,7 @@ export default React.createClass({ onForgotPasswordClick={this.onForgotPasswordClick} enableGuest={this.props.enableGuest} onCancelClick={MatrixClientPeg.get() ? this.onReturnToAppClick : null} + onServerConfigChange={this.onServerConfigChange} /> ); } diff --git a/src/components/structures/login/Login.js b/src/components/structures/login/Login.js index f4c08e8362..5042ca1fd0 100644 --- a/src/components/structures/login/Login.js +++ b/src/components/structures/login/Login.js @@ -58,6 +58,7 @@ module.exports = React.createClass({ // login shouldn't care how password recovery is done. onForgotPasswordClick: PropTypes.func, onCancelClick: PropTypes.func, + onServerConfigChange: PropTypes.func.isRequired, }, getInitialState: function() { @@ -218,6 +219,8 @@ module.exports = React.createClass({ if (config.isUrl !== undefined) { newState.enteredIdentityServerUrl = config.isUrl; } + + this.props.onServerConfigChange(config); this.setState(newState, function() { self._initLoginLogic(config.hsUrl || null, config.isUrl); }); diff --git a/src/components/structures/login/Registration.js b/src/components/structures/login/Registration.js index b8a85c5f82..62a3ee4f68 100644 --- a/src/components/structures/login/Registration.js +++ b/src/components/structures/login/Registration.js @@ -61,6 +61,7 @@ module.exports = React.createClass({ // registration shouldn't know or care how login is done. onLoginClick: PropTypes.func.isRequired, onCancelClick: PropTypes.func, + onServerConfigChange: PropTypes.func.isRequired, }, getInitialState: function() { @@ -131,6 +132,7 @@ module.exports = React.createClass({ if (config.isUrl !== undefined) { newState.isUrl = config.isUrl; } + this.props.onServerConfigChange(config); this.setState(newState, function() { this._replaceClient(); }); From 2549b44768a525e0ca46778573fcd99132b864a7 Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Wed, 7 Feb 2018 18:57:32 +0000 Subject: [PATCH 0261/1160] Linting --- src/components/views/avatars/RoomAvatar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/avatars/RoomAvatar.js b/src/components/views/avatars/RoomAvatar.js index 37e7abe05e..e71a3c929b 100644 --- a/src/components/views/avatars/RoomAvatar.js +++ b/src/components/views/avatars/RoomAvatar.js @@ -122,7 +122,7 @@ module.exports = React.createClass({ return mlist[leftUserIds[0]].getAvatarUrl( MatrixClientPeg.get().getHomeserverUrl(), props.width, props.height, props.resizeMethod, - false + false, ); } return mlist[userIds[0]].getAvatarUrl( From 5823b32ab14c52be42ffac359b8f18d3ef2f10f7 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 8 Feb 2018 10:01:24 +0000 Subject: [PATCH 0262/1160] RoomView: guard against unmounting during peeking it's possible for the user to change room before the peek operation completes. Check if we've been unmounted before setting state. --- src/components/structures/RoomView.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 27a70fdb10..5304f38901 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -264,12 +264,19 @@ module.exports = React.createClass({ isPeeking: true, // this will change to false if peeking fails }); MatrixClientPeg.get().peekInRoom(roomId).then((room) => { + if (this.unmounted) { + return; + } this.setState({ room: room, peekLoading: false, }); this._onRoomLoaded(room); }, (err) => { + if (this.unmounted) { + return; + } + // Stop peeking if anything went wrong this.setState({ isPeeking: false, @@ -286,7 +293,7 @@ module.exports = React.createClass({ } else { throw err; } - }).done(); + }); } } else if (room) { // Stop peeking because we have joined this room previously From 5cf3d3176fd7b31eeb197982fe41e7852ee096b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D1=80=D0=BA=D0=BE=20=D0=9C=2E=20=D0=9A=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D0=B8=D1=9B?= Date: Wed, 7 Feb 2018 20:35:20 +0000 Subject: [PATCH 0263/1160] Translated using Weblate (Serbian) Currently translated at 91.1% (899 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sr/ --- src/i18n/strings/sr.json | 108 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index 9d5c08046a..9a38d6fac8 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -792,5 +792,111 @@ "Logout": "Одјава", "Your Communities": "Ваше заједнице", "Error whilst fetching joined communities": "Грешка приликом добављања списка са приступљеним заједницама", - "Create a new community": "Направи нову заједницу" + "Create a new community": "Направи нову заједницу", + "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Направите заједницу да бисте спојили кориснике и собе! Направите прилагођену почетну страницу да бисте означили ваш кутак у Матрикс универзуму.", + "Join an existing community": "Приступи већ постојећој заједници", + "To join an existing community you'll have to know its community identifier; this will look something like +example:matrix.org.": "Да бисте приступили већ постојећој заједници, морате знати њен идентификатор заједнице. Ово изгледа нешто као +primer:matrix.org.", + "You have no visible notifications": "Немате видљивих обавештења", + "Scroll to bottom of page": "Превуци на дно странице", + "Message not sent due to unknown devices being present": "Порука се неће послати због присутности непознатих уређаја", + "Show devices, send anyway or cancel.": "Прикажи уређаје, ипак пошаљи или откажи.", + "%(count)s of your messages have not been sent.|other": "Неке ваше поруке нису послате.", + "%(count)s of your messages have not been sent.|one": "Ваша порука није послата.", + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "Пошаљи поново или откажи све сада. Такође можете изабрати појединачне поруке за поновно слање или отказивање.", + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Поново пошаљи поруку или откажи поруку сада.", + "Warning": "Упозорење", + "Connectivity to the server has been lost.": "Веза ка серверу је прекинута.", + "Sent messages will be stored until your connection has returned.": "Послате поруке биће сачуване док се веза не успостави поново.", + "%(count)s new messages|other": "%(count)s нових порука", + "%(count)s new messages|one": "%(count)s нова порука", + "Active call": "Текући позив", + "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Нема других чланова! Да ли желите да позовете друге или да склоните упозорење о празној соби?", + "You seem to be uploading files, are you sure you want to quit?": "Изгледа да отпремате датотеке. Да ли сте сигурни да желите изаћи?", + "You seem to be in a call, are you sure you want to quit?": "Изгледа да сте у позиву. Да ли сте сигурни да желите изаћи?", + "Failed to upload file": "Нисам успео да отпремим датотеку", + "Server may be unavailable, overloaded, or the file too big": "Сервер је можда недоступан, преоптерећен или је датотека сувише велика", + "Search failed": "Претрага је неуспешна", + "Server may be unavailable, overloaded, or search timed out :(": "Сервер је можда недоступан, преоптерећен или је истекло време претраживања :(", + "No more results": "Нема више резултата", + "Unknown room %(roomId)s": "Непозната соба %(roomId)s", + "Room": "Соба", + "Failed to save settings": "Нисам успео да сачувам подешавања", + "Failed to reject invite": "Нисам успео да одбацим позивницу", + "Fill screen": "Испуни екран", + "Click to unmute video": "Кликни да појачаш видео", + "Click to mute video": "Кликни да утишаш видео", + "Click to unmute audio": "Кликни да појачаш звук", + "Click to mute audio": "Кликни да утишаш звук", + "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Покушао сам да учитам одређену тачку у временској линији ове собе али ви немате овлашћења за преглед наведене поруке.", + "Tried to load a specific point in this room's timeline, but was unable to find it.": "Покушао сам да учитам одређену тачку у временској линији ове собе али нисам могао да је нађем.", + "Failed to load timeline position": "Нисам могао да учитам позицију у временској линији", + "Uploading %(filename)s and %(count)s others|other": "Отпремам датотеку %(filename)s и још %(count)s других", + "Uploading %(filename)s and %(count)s others|zero": "Отпремам датотеку %(filename)s", + "Uploading %(filename)s and %(count)s others|one": "Отпремам датотеку %(filename)s и %(count)s других датотека", + "Light theme": "Светла тема", + "Dark theme": "Тамна тема", + "Status.im theme": "Status.im тема", + "Can't load user settings": "Не могу да учитам корисничка подешавања", + "Server may be unavailable or overloaded": "Сервер је недоступан или је преоптерећен", + "Sign out": "Одјави ме", + "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Зарад безбедности, одјава ће обрисати све кључеве за шифровање с краја на крај, на овом прегледачу. Ако желите да дешифрујете историјат вашег ћаскања из будућих Riot сесија, извезите ваше кључеве и чувајте их.", + "Failed to change password. Is your password correct?": "Нисам успео да променим лозинку. Да ли је ваша лозинка тачна?", + "Success": "Успех", + "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Ваша лозинка је успешно промењена. Нећете добијати пуш обавештења на вашим другим уређајима док се поново не пријавите на њима", + "Remove Contact Information?": "Уклонити контакт податке?", + "Remove %(threePid)s?": "Уклонити %(threePid)s?", + "Unable to remove contact information": "Не могу да уклоним контакт податке", + "Refer a friend to Riot:": "Кажите пријатељу за Riot:", + "Interface Language": "Језик интерфејса", + "User Interface": "Кориснички интерфејс", + "Autocomplete Delay (ms):": "Застој самодопуњавања (мс):", + "": "<није подржано>", + "Import E2E room keys": "Увези E2E кључеве собе", + "Cryptography": "Криптографија", + "Device ID:": "ИБ уређаја:", + "Device key:": "Кључ уређаја:", + "Ignored Users": "Занемарени корисници", + "Bug Report": "Извештај о грешци", + "Found a bug?": "Нашли сте грешку?", + "Report it": "Пријавите је", + "Riot collects anonymous analytics to allow us to improve the application.": "Riot прикупља анонимне податке о коришћењу да бисмо побољшали апликацију.", + "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Приватност је веома важна нама те не сакупљамо било какве податке личне природе у нашој аналитици.", + "Learn more about how we use analytics.": "Сазнајте више о нашем начину употребе аналитике.", + "Labs": "Лабораторије", + "These are experimental features that may break in unexpected ways": "Ово су пробне могућности које се могу поломити на непредвидљиве начине", + "Use with caution": "Опрезно користите", + "Deactivate my account": "Деактивирај мој налог", + "Clear Cache": "Очисти кеш", + "Clear Cache and Reload": "Очисти кеш и поново учитај", + "Updates": "Ажурирања", + "Check for update": "Провери да ли има ажурирања", + "Reject all %(invitedRooms)s invites": "Одбиј све позивнице за собе %(invitedRooms)s", + "Bulk Options": "Вишеструке опције", + "Desktop specific": "Само за стоне уређаје", + "Start automatically after system login": "Самостално покрећи након пријаве на систем", + "No media permissions": "Нема овлашћења за медије", + "You may need to manually permit Riot to access your microphone/webcam": "Можда ћете морати да ручно доделите овлашћења Riot-у за приступ микрофону/веб камери", + "Missing Media Permissions, click here to request.": "Недостају овлашћења за медије, кликните овде да затражите.", + "No Microphones detected": "Нема уочених микрофона", + "No Webcams detected": "Нема уочених веб камера", + "Default Device": "Подразумевани уређај", + "Microphone": "Микрофон", + "Camera": "Камера", + "VoIP": "VoIP", + "Email": "Мејл", + "Add email address": "Додај мејл адресу", + "Notifications": "Обавештења", + "Profile": "Профил", + "Display name": "Приказно име", + "Account": "Налог", + "To return to your account in future you need to set a password": "Да бисте се вратили у ваш налог у будућности, морате поставити лозинку", + "Logged in as:": "Пријављени као:", + "Access Token:": "Приступни жетон:", + "click to reveal": "кликни за приказ", + "Homeserver is": "Кућни сервер је", + "Identity Server is": "Идентитетски сервер је", + "matrix-react-sdk version:": "matrix-react-sdk издање:", + "riot-web version:": "riot-web издање:", + "olm version:": "olm издање:", + "Failed to send email": "Нисам успео да пошаљем мејл" } From 7a594ce08dbcb1b0248ecfe39acab5b8ce60a607 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 8 Feb 2018 17:58:53 +0200 Subject: [PATCH 0264/1160] Add seconds to formatFullDate() Fixes vector-im/riot-web#6055 Signed-off-by: Tulir Asokan --- src/DateUtils.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/DateUtils.js b/src/DateUtils.js index 986525eec8..108697238c 100644 --- a/src/DateUtils.js +++ b/src/DateUtils.js @@ -50,11 +50,15 @@ function pad(n) { return (n < 10 ? '0' : '') + n; } -function twelveHourTime(date) { +function twelveHourTime(date, showSeconds=false) { let hours = date.getHours() % 12; const minutes = pad(date.getMinutes()); const ampm = date.getHours() >= 12 ? _t('PM') : _t('AM'); hours = hours ? hours : 12; // convert 0 -> 12 + if (showSeconds) { + const seconds = pad(date.getSeconds()); + return `${hours}:${minutes}:${seconds}${ampm}`; + } return `${hours}:${minutes}${ampm}`; } @@ -101,10 +105,17 @@ export function formatFullDate(date, showTwelveHour=false) { monthName: months[date.getMonth()], day: date.getDate(), fullYear: date.getFullYear(), - time: formatTime(date, showTwelveHour), + time: formatFullTime(date, showTwelveHour), }); } +export function formatFullTime(date, showTwelveHour=false) { + if (showTwelveHour) { + return twelveHourTime(date, true); + } + return pad(date.getHours()) + ':' + pad(date.getMinutes()) + ':' + pad(date.getSeconds()); +} + export function formatTime(date, showTwelveHour=false) { if (showTwelveHour) { return twelveHourTime(date); From 21d70125e4e21d40320c793186527d96c9b9358c Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 8 Feb 2018 14:48:29 +0000 Subject: [PATCH 0265/1160] Dispatch MatrixActions synchronously Otherwise we risk blocking the dispatches on other work, and they do not need to be done asynchronously. This emerged as a bug where the room list appeared empty until MatrixActions.sync dispatches all occured in one big lump, well after the sync events being emitted by the js-sdk. --- src/actions/MatrixActionCreators.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/actions/MatrixActionCreators.js b/src/actions/MatrixActionCreators.js index f4d6c34ff5..dbfe910533 100644 --- a/src/actions/MatrixActionCreators.js +++ b/src/actions/MatrixActionCreators.js @@ -101,7 +101,7 @@ export default { */ _addMatrixClientListener(matrixClient, eventName, actionCreator) { const listener = (...args) => { - dis.dispatch(actionCreator(matrixClient, ...args)); + dis.dispatch(actionCreator(matrixClient, ...args), true); }; matrixClient.on(eventName, listener); this._matrixClientListenersStop.push(() => { From 9b0df1914953223cbbf31b33231585d1ba6f5afb Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Tue, 6 Feb 2018 15:15:47 +0000 Subject: [PATCH 0266/1160] Make RoomListStore aware of sub list orderings so that it can do optimistic updates of ordered lists. --- src/actions/RoomListActions.js | 5 +- src/stores/RoomListStore.js | 173 +++++++++++++++++++-------------- 2 files changed, 103 insertions(+), 75 deletions(-) diff --git a/src/actions/RoomListActions.js b/src/actions/RoomListActions.js index f59e9953ee..a92bd1ebaf 100644 --- a/src/actions/RoomListActions.js +++ b/src/actions/RoomListActions.js @@ -116,8 +116,9 @@ RoomListActions.tagRoom = function(matrixClient, room, oldTag, newTag, oldIndex, if (newTag && newTag !== 'im.vector.fake.direct' && (hasChangedSubLists || metaData) ) { - // Optimistic update of what will happen to the room tags - room.tags[newTag] = metaData || {}; + // metaData is the body of the PUT to set the tag, so it must + // at least be an empty object. + metaData = metaData || {}; const promiseToAdd = matrixClient.setRoomTag(roomId, newTag, metaData).catch(function(err) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); diff --git a/src/stores/RoomListStore.js b/src/stores/RoomListStore.js index 42c77d5237..193784811c 100644 --- a/src/stores/RoomListStore.js +++ b/src/stores/RoomListStore.js @@ -16,6 +16,7 @@ limitations under the License. import {Store} from 'flux/utils'; import dis from '../dispatcher'; import DMRoomMap from '../utils/DMRoomMap'; +import Unread from '../Unread'; /** * A class for storing application state for categorising rooms in @@ -26,6 +27,8 @@ class RoomListStore extends Store { super(dis); this._init(); + this._getManualComparator = this._getManualComparator.bind(this); + this._recentsComparator = this._recentsComparator.bind(this); } _init() { @@ -62,7 +65,7 @@ class RoomListStore extends Store { break; case 'MatrixActions.Room.tags': { if (!this._state.ready) break; - this._updateRoomLists(payload.room); + this._generateRoomLists(); } break; case 'MatrixActions.accountData': { @@ -76,12 +79,7 @@ class RoomListStore extends Store { } break; case 'RoomListActions.tagRoom.pending': { - this._updateRoomListsOptimistic( - payload.request.room, - payload.request.oldTag, - payload.request.newTag, - payload.request.metaData, - ); + this._generateRoomLists(payload.request); } break; case 'RoomListActions.tagRoom.failure': { @@ -93,76 +91,13 @@ class RoomListStore extends Store { // Reset state without pushing an update to the view, which generally assumes that // the matrix client isn't `null` and so causing a re-render will cause NPEs. this._init(); + this._matrixClient = null; } break; } } - _updateRoomListsOptimistic(updatedRoom, oldTag, newTag, metaData) { - const newLists = {}; - - // Adding a tag to an untagged room - need to remove it from recents - if (newTag && Object.keys(updatedRoom.tags).length === 0) { - oldTag = 'im.vector.fake.recent'; - } - - // Removing a tag from a room with one tag left - need to add it to recents - if (oldTag && Object.keys(updatedRoom.tags).length === 1) { - newTag = 'im.vector.fake.recent'; - } - - // Remove room from oldTag - Object.keys(this._state.lists).forEach((tagName) => { - if (tagName === oldTag) { - newLists[tagName] = this._state.lists[tagName].filter((room) => { - return room.roomId !== updatedRoom.roomId; - }); - } else { - newLists[tagName] = this._state.lists[tagName]; - } - }); - - /// XXX: RoomSubList sorts by data on the room object. We - /// should sort in advance and incrementally insert new rooms - /// instead of resorting every time. - if (metaData) { - updatedRoom.tags[newTag] = metaData; - } - - newLists[newTag].push(updatedRoom); - - this._setState({ - lists: newLists, - }); - } - - _updateRoomLists(updatedRoom) { - const roomTags = Object.keys(updatedRoom.tags); - - const newLists = {}; - - // Removal of the updatedRoom from tags it no longer has - Object.keys(this._state.lists).forEach((tagName) => { - newLists[tagName] = this._state.lists[tagName].filter((room) => { - return room.roomId !== updatedRoom.roomId || roomTags.includes(tagName); - }); - }); - - roomTags.forEach((tagName) => { - if (newLists[tagName].includes(updatedRoom)) return; - newLists[tagName].push(updatedRoom); - }); - - if (roomTags.length === 0) { - newLists['im.vector.fake.recent'].unshift(updatedRoom); - } - - this._setState({ - lists: newLists, - }); - } - - _generateRoomLists() { + _generateRoomLists(optimisticRequest) { const lists = { "im.vector.fake.invite": [], "m.favourite": [], @@ -187,7 +122,19 @@ class RoomListStore extends Store { } else if (me.membership == "join" || me.membership === "ban" || (me.membership === "leave" && me.events.member.getSender() !== me.events.member.getStateKey())) { // Used to split rooms via tags - const tagNames = Object.keys(room.tags); + let tagNames = Object.keys(room.tags); + + if (optimisticRequest && optimisticRequest.room === room) { + // Remove old tag + tagNames = tagNames.filter((tagName) => tagName !== optimisticRequest.oldTag); + // Add new tag + if (optimisticRequest.newTag && + !tagNames.includes(optimisticRequest.newTag) + ) { + tagNames.push(optimisticRequest.newTag); + } + } + if (tagNames.length) { for (let i = 0; i < tagNames.length; i++) { const tagName = tagNames[i]; @@ -207,12 +154,92 @@ class RoomListStore extends Store { } }); + const listOrders = { + "manual": [ + "m.favourite", + ], + "recent": [ + "im.vector.fake.invite", + "im.vector.fake.recent", + "im.vector.fake.direct", + "m.lowpriority", + "im.vector.fake.archived", + ], + }; + + Object.keys(listOrders).forEach((order) => { + listOrders[order].forEach((listKey) => { + let comparator; + switch (order) { + case "manual": + comparator = this._getManualComparator(listKey, optimisticRequest); + break; + case "recent": + comparator = this._recentsComparator; + break; + } + lists[listKey].sort(comparator); + }); + }); + this._setState({ lists, ready: true, // Ready to receive updates via Room.tags events }); } + _tsOfNewestEvent(room) { + for (let i = room.timeline.length - 1; i >= 0; --i) { + const ev = room.timeline[i]; + if (ev.getTs() && + (Unread.eventTriggersUnreadCount(ev) || + (ev.getSender() === this._matrixClient.credentials.userId)) + ) { + return ev.getTs(); + } + } + + // we might only have events that don't trigger the unread indicator, + // in which case use the oldest event even if normally it wouldn't count. + // This is better than just assuming the last event was forever ago. + if (room.timeline.length && room.timeline[0].getTs()) { + return room.timeline[0].getTs(); + } else { + return Number.MAX_SAFE_INTEGER; + } + } + + _recentsComparator(roomA, roomB) { + return this._tsOfNewestEvent(roomB) - this._tsOfNewestEvent(roomA); + } + + _lexicographicalComparator(roomA, roomB) { + return roomA.name > roomB.name ? 1 : -1; + } + + _getManualComparator(tagName, optimisticRequest) { + return (roomA, roomB) => { + let metaA = roomA.tags[tagName]; + let metaB = roomB.tags[tagName]; + + if (optimisticRequest && roomA === optimisticRequest.room) metaA = optimisticRequest.metaData; + if (optimisticRequest && roomB === optimisticRequest.room) metaB = optimisticRequest.metaData; + + // Make sure the room tag has an order element, if not set it to be the bottom + const a = metaA.order; + const b = metaB.order; + + // Order undefined room tag orders to the bottom + if (a === undefined && b !== undefined) { + return 1; + } else if (a !== undefined && b === undefined) { + return -1; + } + + return a == b ? this._lexicographicalComparator(roomA, roomB) : ( a > b ? 1 : -1); + }; + } + getRoomLists() { return this._state.lists; } From c5da1015fe95a5d30971cd05164e1fd89a3898d8 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 8 Feb 2018 17:47:36 +0000 Subject: [PATCH 0267/1160] Do not truncate autocompleted users in composer so that disambiguation is possible at a glance. Fixes https://github.com/vector-im/riot-web/issues/6024 --- src/autocomplete/UserProvider.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/autocomplete/UserProvider.js b/src/autocomplete/UserProvider.js index fefe77f6cd..bceec3f144 100644 --- a/src/autocomplete/UserProvider.js +++ b/src/autocomplete/UserProvider.js @@ -158,7 +158,7 @@ export default class UserProvider extends AutocompleteProvider { } renderCompletions(completions: [React.Component]): ?React.Component { - return
    + return
    { completions }
    ; } From 234ca8b062f088f23a2f50d508d2a20056a73c79 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 8 Feb 2018 17:50:30 +0000 Subject: [PATCH 0268/1160] Remove top padding from app tile. --- src/ScalarMessaging.js | 1 - src/components/structures/ContextualMenu.js | 4 ++++ src/components/views/rooms/Stickerpack.js | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index 3d585108dd..ac68d1a2d2 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -336,7 +336,6 @@ function setWidget(event, roomId) { if (userWidget) { console.warn('Adding user widget'); const client = MatrixClientPeg.get(); - // client.setAccountData('m.widgets', {}); const userWidgets = client.getAccountData('m.widgets').getContent() || {}; // Delete existing widget with ID diff --git a/src/components/structures/ContextualMenu.js b/src/components/structures/ContextualMenu.js index 7ec078f739..3c23e0ceae 100644 --- a/src/components/structures/ContextualMenu.js +++ b/src/components/structures/ContextualMenu.js @@ -134,6 +134,10 @@ module.exports = { menuStyle["backgroundColor"] = props.menuColour; } + if (!isNaN(Number(props.menuPaddingTop))) { + menuStyle["paddingTop"] = props.menuPaddingTop; + } + // FIXME: If a menu uses getDefaultProps it clobbers the onFinished // property set here so you can't close the menu from a button click! const menu = ( diff --git a/src/components/views/rooms/Stickerpack.js b/src/components/views/rooms/Stickerpack.js index e04098a06b..24bd44c3d3 100644 --- a/src/components/views/rooms/Stickerpack.js +++ b/src/components/views/rooms/Stickerpack.js @@ -175,6 +175,7 @@ export default class Stickerpack extends React.Component { menuHeight: this.popoverHeight, element: this.state.stickersContent, onFinished: this.onFinished, + menuPaddingTop: 0, }); From 015477278914b38d559e6bd77cabea16c8aee2bb Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 8 Feb 2018 18:18:57 +0000 Subject: [PATCH 0269/1160] Change wording of debug log submission Fixes https://github.com/vector-im/riot-web/issues/5985 --- src/components/structures/UserSettings.js | 6 +++--- src/i18n/strings/en_EN.json | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index b1eedd1a90..4237cd78eb 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -794,11 +794,11 @@ module.exports = React.createClass({ } return (
    -

    { _t("Bug Report") }

    +

    { _t("Debug Logs Submission") }

    -

    { _t("Found a bug?") }

    +

    { _t("Want to send logs?") }

    diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 6139ac2a91..d51f20dbd0 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -500,8 +500,8 @@ "Download %(text)s": "Download %(text)s", "Invalid file%(extra)s": "Invalid file%(extra)s", "Error decrypting image": "Error decrypting image", - "Image '%(Body)s' cannot be displayed.": "Image '%(Body)s' cannot be displayed.", "This image cannot be displayed.": "This image cannot be displayed.", + "Image '%(Body)s' cannot be displayed.": "Image '%(Body)s' cannot be displayed.", "Error decrypting video": "Error decrypting video", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s changed the avatar for %(roomName)s", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s removed the room avatar.", @@ -855,9 +855,9 @@ "Device ID:": "Device ID:", "Device key:": "Device key:", "Ignored Users": "Ignored Users", - "Bug Report": "Bug Report", - "Found a bug?": "Found a bug?", - "Report it": "Report it", + "Debug Logs Submission": "Debug Logs Submission", + "Want to send logs?": "Want to send logs?", + "Submit debug logs": "Submit debug logs", "Riot collects anonymous analytics to allow us to improve the application.": "Riot collects anonymous analytics to allow us to improve the application.", "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.", "Learn more about how we use analytics.": "Learn more about how we use analytics.", From 8f97e9479d3be395d9855f17fb093629b1cd4ad6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Thu, 8 Feb 2018 21:16:57 +0100 Subject: [PATCH 0270/1160] Ooops, restore a bit of RoomCreateDialog content I have accidentally removed while trying to solve merge conflicts (thx @dbkr) --- src/components/views/dialogs/CreateRoomDialog.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/components/views/dialogs/CreateRoomDialog.js b/src/components/views/dialogs/CreateRoomDialog.js index 7a8852bc00..51693a19c9 100644 --- a/src/components/views/dialogs/CreateRoomDialog.js +++ b/src/components/views/dialogs/CreateRoomDialog.js @@ -55,6 +55,19 @@ export default React.createClass({
    +
    + +
    + { _t('Advanced options') } +
    + + +
    +
    Date: Thu, 8 Feb 2018 21:16:25 +0000 Subject: [PATCH 0271/1160] Translated using Weblate (Serbian) Currently translated at 100.0% (986 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sr/ --- src/i18n/strings/sr.json | 89 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index 9a38d6fac8..39a1f1cf20 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -898,5 +898,92 @@ "matrix-react-sdk version:": "matrix-react-sdk издање:", "riot-web version:": "riot-web издање:", "olm version:": "olm издање:", - "Failed to send email": "Нисам успео да пошаљем мејл" + "Failed to send email": "Нисам успео да пошаљем мејл", + "The email address linked to your account must be entered.": "Морате унети мејл адресу која је везана за ваш налог.", + "A new password must be entered.": "Морате унети нову лозинку.", + "New passwords must match each other.": "Нове лозинке се морају подударати.", + "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.": "Опоравак ваше лозинке ће тренутно поново поставити кључеве за шифровање с краја на крај, на свим вашим уређајима. Ово ће учинити шифровани историјат ћаскања нечитљивим осим ако прво не извезете ваше кључеве собе па их онда увезете касније. Ово ће бити побољшано у будућности.", + "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "Мејл је послат на адресу %(emailAddress)s. Када будете испратили везу у њему, кликните испод.", + "I have verified my email address": "Потврдио сам своју мејл адресу", + "Your password has been reset": "Ваша лозинка је опорављена", + "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": "Одјављени сте са свих ваших уређаја и више нећете примати пуш обавештења. Да бисте поново омогућили обавештења, одјавите се и пријавите поново на сваком вашем уређају", + "Return to login screen": "Врати ме на екран за пријаву", + "To reset your password, enter the email address linked to your account": "Да бисте опоравили вашу лозинку, унесите мејл адресу повезану са вашим налогом", + "New password": "Нова лозинка", + "Confirm your new password": "Потврдите вашу нову лозинку", + "Send Reset Email": "Пошаљи мејл за опоравак", + "Create an account": "Направи налог", + "This Home Server does not support login using email address.": "Овај кућни сервер не подржава пријављивање преко мејл адресе.", + "Incorrect username and/or password.": "Нетачно корисничко име и/или лозинка.", + "Please note you are logging into the %(hs)s server, not matrix.org.": "Знајте да се пријављујете на сервер %(hs)s, не на matrix.org.", + "Guest access is disabled on this Home Server.": "Гостински приступ је онемогућен на овом кућном серверу.", + "The phone number entered looks invalid": "Унети број телефона не изгледа исправно", + "This homeserver doesn't offer any login flows which are supported by this client.": "Овај кућни сервер не пружа било који начин пријаве унутар овог клијента.", + "Error: Problem communicating with the given homeserver.": "Грешка: проблем у комуницирању са датим кућним сервером.", + "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 или омогућите небезбедне скрипте.", + "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Не могу да се повежем на кућни сервер. Проверите вашу интернет везу, постарајте се да верујете SSL сертификату кућног сервера и да проширење прегледача не блокира захтеве.", + "Login as guest": "Пријави се као гост", + "Sign in to get started": "Пријави се да почнеш", + "Failed to fetch avatar URL": "Нисам успео да добавим адресу аватара", + "Set a display name:": "Постави приказно име:", + "Upload an avatar:": "Отпреми аватар:", + "This server does not support authentication with a phone number.": "Овај сервер не подржава идентификацију преко броја мобилног.", + "Missing password.": "Недостаје лозинка.", + "Passwords don't match.": "Лозинке се не подударају.", + "Password too short (min %(MIN_PASSWORD_LENGTH)s).": "Лозинка је сувише кратка (најмање %(MIN_PASSWORD_LENGTH)s).", + "This doesn't look like a valid email address.": "Мејл адреса не изгледа исправно.", + "This doesn't look like a valid phone number.": "Број телефона не изгледа исправно.", + "You need to enter a user name.": "Морате унети корисничко име.", + "An unknown error occurred.": "Непозната грешка се догодила.", + "I already have an account": "Већ имам налог", + "Displays action": "Приказује радњу", + "Bans user with given id": "Забрањује приступ кориснику са датим иб-јем", + "Unbans user with given id": "Скида забрану приступа кориснику са датим иб-јем", + "Define the power level of a user": "Дефинише ниво моћи корисника", + "Deops user with given id": "Укида админа за корисника са датим иб-јем", + "Invites user with given id to current room": "Позива корисника са датим иб-јем у тренутну собу", + "Joins room with given alias": "Приступа соби са датим алијасем", + "Sets the room topic": "Поставља тему собе", + "Kicks user with given id": "Избацује корисника са датим иб-јем", + "Changes your display nickname": "Мења ваш приказни надимак", + "Searches DuckDuckGo for results": "Претражује DuckDuckGo за резултате", + "Changes colour scheme of current room": "Мења шему боје у тренутној соби", + "Verifies a user, device, and pubkey tuple": "Проверава корисника, уређај и торку јавног кључа", + "Ignores a user, hiding their messages from you": "Занемарује корисника и тиме скрива њихове поруке од вас", + "Stops ignoring a user, showing their messages going forward": "Престаје са занемаривањем корисника и тиме приказује њихове поруке одсад", + "Commands": "Наредбе", + "Results from DuckDuckGo": "Резултати са DuckDuckGo-а", + "Emoji": "Емоџи", + "Notify the whole room": "Обавести све у соби", + "Room Notification": "Собно обавештење", + "Users": "Корисници", + "unknown device": "непознати уређај", + "NOT verified": "НИЈЕ проверен", + "verified": "проверен", + "Verification": "Провера", + "Ed25519 fingerprint": "Ed25519 отисак прста", + "User ID": "Кориснички ИБ", + "Curve25519 identity key": "Curve25519 идентитески кључ", + "none": "ништа", + "Claimed Ed25519 fingerprint key": "Наводни Ed25519 кључ отиска прста", + "Algorithm": "Алгоритам", + "unencrypted": "нешифрован", + "Decryption error": "Грешка дешифровања", + "Session ID": "ИБ сесије", + "End-to-end encryption information": "Подаци о шифровању с краја на крај", + "Event information": "Подаци о догађају", + "Sender device information": "Подаци о уређају пошиљаоца", + "Passphrases must match": "Фразе се морају подударати", + "Passphrase must not be empty": "Фразе не смеју бити празне", + "Export room keys": "Извези кључеве собе", + "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Ова радња вам омогућава да извезете кључеве за примљене поруке у шифрованим собама у локалну датотеку. Онда ћете моћи да увезете датотеку у други Матрикс клијент, у будућности, тако да ће тај клијент моћи да дешифрује ове поруке.", + "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Извезена датотека ће дозволити свима који је могу прочитати да дешифрују било које шифроване поруке које можете видети те бисте требали да будете пажљиви и да је осигурате. Да бисмо вам помогли са тиме, требало би да унесете фразу испод са којом ће извезени подаци бити шифровани. Поновни увоз података ће бити могућ само уз коришћење исте фразе.", + "Enter passphrase": "Унеси фразу", + "Confirm passphrase": "Потврди фразу", + "Export": "Извези", + "Import room keys": "Увези кључеве собе", + "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Ова радња вам омогућава да увезете кључеве за шифровање које сте претходно извезли из другог Матрикс клијента. Након тога ћете моћи да дешифрујете било коју поруку коју је други клијент могао да дешифрује.", + "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Извезена датотека ће бити заштићена са фразом. Требало би да унесете фразу овде, да бисте дешифровали датотеку.", + "File to import": "Датотека за увоз", + "Import": "Увези" } From 410570936a6e301b2eff5591f99bf75a6f838337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Thu, 8 Feb 2018 22:51:07 +0100 Subject: [PATCH 0272/1160] Reimplement setting aria-hidden on the main app node by dispatching actions rather than assuming we can find and manipulate the node directly --- src/Modal.js | 25 +++++++++++------------ src/components/structures/LoggedInView.js | 2 +- src/components/structures/MatrixChat.js | 14 +++++++++++++ 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/Modal.js b/src/Modal.js index 8e3b394f87..2565d5c73b 100644 --- a/src/Modal.js +++ b/src/Modal.js @@ -22,6 +22,7 @@ const ReactDOM = require('react-dom'); import PropTypes from 'prop-types'; import Analytics from './Analytics'; import sdk from './index'; +import dis from './dispatcher'; const DIALOG_CONTAINER_ID = "mx_Dialog_Container"; @@ -187,24 +188,22 @@ class ModalManager { } _reRender() { - // Retrieve the root node of the Riot application outside the modal - let applicationNode = document.getElementById('matrixchat'); if (this._modals.length == 0) { - if (applicationNode) { - // If there is no modal to render, make all of Riot available - // to screen reader users again - applicationNode.setAttribute('aria-hidden', 'false'); - } + // If there is no modal to render, make all of Riot available + // to screen reader users again + dis.dispatch({ + action: 'aria_unhide_main_app', + }); ReactDOM.unmountComponentAtNode(this.getOrCreateContainer()); return; } - if (applicationNode) { - // Hide the content outside the modal to screen reader users - // so they won't be able to navigate into it and act on it using - // screen reader specific features - applicationNode.setAttribute('aria-hidden', 'true'); - } + // Hide the content outside the modal to screen reader users + // so they won't be able to navigate into it and act on it using + // screen reader specific features + dis.dispatch({ + action: 'aria_hide_main_app', + }); const modal = this._modals[0]; const dialog = ( diff --git a/src/components/structures/LoggedInView.js b/src/components/structures/LoggedInView.js index e97d9dd0a1..211340f5a8 100644 --- a/src/components/structures/LoggedInView.js +++ b/src/components/structures/LoggedInView.js @@ -327,7 +327,7 @@ const LoggedInView = React.createClass({ } return ( -
    +
    { topBar }
    { SettingsStore.isFeatureEnabled("feature_tag_panel") ? :
    } diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index d6d0b00c84..380cc697e1 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -171,6 +171,10 @@ export default React.createClass({ register_hs_url: null, register_is_url: null, register_id_sid: null, + + // When showing Modal dialogs we need to set aria-hidden on the root app element + // and disable it when there are no dialogs + hideToSRUsers: false, }; return s; }, @@ -608,6 +612,16 @@ export default React.createClass({ case 'send_event': this.onSendEvent(payload.room_id, payload.event); break; + case 'aria_hide_main_app': + this.setState({ + hideToSRUsers: true, + }); + break; + case 'aria_unhide_main_app': + this.setState({ + hideToSRUsers: false, + }); + break; } }, From cf0d45a65bd0082bc3ce0b9890b61a08a78bfa68 Mon Sep 17 00:00:00 2001 From: Osoitz Date: Fri, 9 Feb 2018 10:28:32 +0000 Subject: [PATCH 0273/1160] Translated using Weblate (Basque) Currently translated at 100.0% (986 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eu/ --- src/i18n/strings/eu.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index 8ec181d879..7592eb0708 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -980,5 +980,9 @@ "This room is not public. You will not be able to rejoin without an invite.": "Gela hau ez da publikoa. Ezin izango zara berriro elkartu gonbidapenik gabe.", "Community IDs cannot not be empty.": "Komunitate ID-ak ezin dira hutsik egon.", "Show devices, send anyway or cancel.": "Erakutsi gailuak, bidali hala ere edo ezeztatu.", - "In reply to ": "honi erantzunez: " + "In reply to ": "honi erantzunez: ", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s erabiltzaileak bere pantaila izena aldatu du %(displayName)s izatera.", + "Failed to set direct chat tag": "Huts egin du txat zuzenarenaren etiketa jartzean", + "Failed to remove tag %(tagName)s from room": "Huts egin du %(tagName)s etiketa gelatik kentzean", + "Failed to add tag %(tagName)s to room": "Huts egin du %(tagName)s etiketa gelara gehitzean" } From 9e3c1fbc7ac6a7e1da09e9a82406497ec388d2af Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Fri, 9 Feb 2018 11:44:27 +0000 Subject: [PATCH 0274/1160] Pass room name. --- src/ScalarAuthClient.js | 5 ++++- src/components/views/elements/AppTile.js | 2 +- src/components/views/elements/ManageIntegsButton.js | 4 ++-- src/components/views/rooms/AppsDrawer.js | 2 +- src/components/views/rooms/RoomHeader.js | 2 +- src/components/views/rooms/Stickerpack.js | 2 +- 6 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/ScalarAuthClient.js b/src/ScalarAuthClient.js index 3e775a94ab..756965d41e 100644 --- a/src/ScalarAuthClient.js +++ b/src/ScalarAuthClient.js @@ -105,10 +105,13 @@ class ScalarAuthClient { return defer.promise; } - getScalarInterfaceUrlForRoom(roomId, screen, id) { + getScalarInterfaceUrlForRoom(room, screen, id) { + const roomId = room.roomId; + const roomName = room.name; let url = SdkConfig.get().integrations_ui_url; url += "?scalar_token=" + encodeURIComponent(this.scalarToken); url += "&room_id=" + encodeURIComponent(roomId); + url += "&room_name=" + encodeURIComponent(roomName); if (id) { url += '&integ_id=' + encodeURIComponent(id); } diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 9d76e3410e..cc11a8542a 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -277,7 +277,7 @@ export default class AppTile extends React.Component { } else { const IntegrationsManager = sdk.getComponent("views.settings.IntegrationsManager"); const src = this._scalarClient.getScalarInterfaceUrlForRoom( - this.props.room.roomId, 'type_' + this.props.type, this.props.id); + this.props.room, 'type_' + this.props.type, this.props.id); Modal.createTrackedDialog('Integrations Manager', '', IntegrationsManager, { src: src, }, "mx_IntegrationsManager"); diff --git a/src/components/views/elements/ManageIntegsButton.js b/src/components/views/elements/ManageIntegsButton.js index 17dbbeee62..024c5feda5 100644 --- a/src/components/views/elements/ManageIntegsButton.js +++ b/src/components/views/elements/ManageIntegsButton.js @@ -64,7 +64,7 @@ export default class ManageIntegsButton extends React.Component { const IntegrationsManager = sdk.getComponent("views.settings.IntegrationsManager"); Modal.createDialog(IntegrationsManager, { src: (this.scalarClient !== null && this.scalarClient.hasCredentials()) ? - this.scalarClient.getScalarInterfaceUrlForRoom(this.props.roomId) : + this.scalarClient.getScalarInterfaceUrlForRoom(this.props.room) : null, }, "mx_IntegrationsManager"); } @@ -103,5 +103,5 @@ export default class ManageIntegsButton extends React.Component { } ManageIntegsButton.propTypes = { - roomId: PropTypes.string.isRequired, + room: PropTypes.object.isRequired, }; diff --git a/src/components/views/rooms/AppsDrawer.js b/src/components/views/rooms/AppsDrawer.js index 78677e138b..7541b304a2 100644 --- a/src/components/views/rooms/AppsDrawer.js +++ b/src/components/views/rooms/AppsDrawer.js @@ -189,7 +189,7 @@ module.exports = React.createClass({ _launchManageIntegrations: function() { const IntegrationsManager = sdk.getComponent("views.settings.IntegrationsManager"); const src = (this.scalarClient !== null && this.scalarClient.hasCredentials()) ? - this.scalarClient.getScalarInterfaceUrlForRoom(this.props.room.roomId, 'add_integ') : + this.scalarClient.getScalarInterfaceUrlForRoom(this.props.room, 'add_integ') : null; Modal.createTrackedDialog('Integrations Manager', '', IntegrationsManager, { src: src, diff --git a/src/components/views/rooms/RoomHeader.js b/src/components/views/rooms/RoomHeader.js index aee229c5da..67ede1a011 100644 --- a/src/components/views/rooms/RoomHeader.js +++ b/src/components/views/rooms/RoomHeader.js @@ -391,7 +391,7 @@ module.exports = React.createClass({ let manageIntegsButton; if (this.props.room && this.props.room.roomId && this.props.inRoom) { manageIntegsButton = ; } diff --git a/src/components/views/rooms/Stickerpack.js b/src/components/views/rooms/Stickerpack.js index 24bd44c3d3..983a357d86 100644 --- a/src/components/views/rooms/Stickerpack.js +++ b/src/components/views/rooms/Stickerpack.js @@ -208,7 +208,7 @@ export default class Stickerpack extends React.Component { const IntegrationsManager = sdk.getComponent("views.settings.IntegrationsManager"); const src = (this.scalarClient !== null && this.scalarClient.hasCredentials()) ? this.scalarClient.getScalarInterfaceUrlForRoom( - this.props.room.roomId, + this.props.room, 'type_stickerpack', this.widgetId, ) : From 3e4175f3e0e32db28f39935d1a3f45212104328e Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 9 Feb 2018 12:20:05 +0000 Subject: [PATCH 0275/1160] Add isUrlPermitted function --- src/HtmlUtils.js | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index 0c262fe89a..5c6cbd6c1b 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -1,6 +1,6 @@ /* Copyright 2015, 2016 OpenMarket Ltd -Copyright 2017 New Vector Ltd +Copyright 2017, 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ import escape from 'lodash/escape'; import emojione from 'emojione'; import classNames from 'classnames'; import MatrixClientPeg from './MatrixClientPeg'; +import url from 'url'; emojione.imagePathSVG = 'emojione/svg/'; // Store PNG path for displaying many flags at once (for increased performance over SVG) @@ -44,6 +45,8 @@ const SYMBOL_PATTERN = /([\u2100-\u2bff])/; const EMOJI_REGEX = new RegExp(emojione.unicodeRegexp+"+", "gi"); const COLOR_REGEX = /^#[0-9a-fA-F]{6}$/; +const PERMITTED_URL_SCHEMES = ['http', 'https', 'ftp', 'mailto', 'magnet']; + /* * Return true if the given string contains emoji * Uses a much, much simpler regex than emojione's so will give false @@ -152,6 +155,25 @@ export function sanitizedHtmlNode(insaneHtml) { return
    ; } +/** + * Tests if a URL from an untrusted source may be safely put into the DOM + * The biggest threat here is javascript: URIs. + * Note that the HTML sanitiser library has its own internal logic for + * doing this, to which we pass the same list of schemes. This is used in + * other places we need to sanitise URLs. + * @return true if permitted, otherwise false + */ +export function isUrlPermitted(inputUrl) { + try { + const parsed = url.parse(inputUrl); + if (!parsed.protocol) return false; + // URL parser protocol includes the trailing colon + return PERMITTED_URL_SCHEMES.includes(parsed.protocol.slice(0, -1)); + } catch (e) { + return false; + } +} + const sanitizeHtmlParams = { allowedTags: [ 'font', // custom to matrix for IRC-style font coloring @@ -172,7 +194,7 @@ const sanitizeHtmlParams = { // Lots of these won't come up by default because we don't allow them selfClosing: ['img', 'br', 'hr', 'area', 'base', 'basefont', 'input', 'link', 'meta'], // URL schemes we permit - allowedSchemes: ['http', 'https', 'ftp', 'mailto', 'magnet'], + allowedSchemes: PERMITTED_URL_SCHEMES, allowProtocolRelative: false, From 52181fde9550192e88a548cbb257ae2c2f631651 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sim=C3=B3=20Albert=20i=20Beltran?= Date: Thu, 8 Feb 2018 19:20:09 +0000 Subject: [PATCH 0276/1160] Translated using Weblate (Catalan) Currently translated at 88.3% (871 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ca/ --- src/i18n/strings/ca.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ca.json b/src/i18n/strings/ca.json index 691da985f2..1ff3e7f8e9 100644 --- a/src/i18n/strings/ca.json +++ b/src/i18n/strings/ca.json @@ -867,5 +867,7 @@ "Import": "Importa", "The version of Riot.im": "La versió de Riot.im", "Email": "Correu electrònic", - "Add email address": "Afegeix correu electrònic" + "Add email address": "Afegeix correu electrònic", + "I have verified my email address": "He verificat l'adreça de correu electrònic", + "Send Reset Email": "Envia email de reinici" } From 22aedb6075259cf1e58745dc7825c6aca9d78533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D1=80=D0=BA=D0=BE=20=D0=9C=2E=20=D0=9A=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D0=B8=D1=9B?= Date: Thu, 8 Feb 2018 21:19:42 +0000 Subject: [PATCH 0277/1160] Translated using Weblate (Serbian) Currently translated at 100.0% (986 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sr/ --- src/i18n/strings/sr.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index 39a1f1cf20..6f1958094a 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -117,7 +117,7 @@ "%(senderName)s requested a VoIP conference.": "%(senderName)s је затражио VoIP конференцију.", "%(senderName)s invited %(targetName)s.": "%(senderName)s је позвао %(targetName)s.", "%(senderName)s banned %(targetName)s.": "%(senderName)s је бановао %(targetName)s.", - "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“. Ово можда значи да се ваши разговори прате!", + "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“. Ово можда значи да се ваши разговори прате!", "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Кључ за потписивање који сте доставили се подудара са кључем за потписивање од корисника %(userId)s и уређаја %(deviceId)s. Уређај је означен као проверен.", "%(senderName)s set their display name to %(displayName)s.": "Корисник %(senderName)s је себи поставио приказно име %(displayName)s.", "%(senderName)s removed their display name (%(oldDisplayName)s).": "Корисник %(senderName)s је себи уклонио приказно име %(oldDisplayName)s.", @@ -567,7 +567,7 @@ "Create new room": "Направи нову собу", "Unblacklist": "Скини са црног списка", "Blacklist": "Стави на црни списак", - "Unverify": "Скини потврду", + "Unverify": "Означи непровереним", "Verify...": "Провери...", "No results": "Нема резултата", "Delete": "Обриши", @@ -674,15 +674,15 @@ "Device name": "Назив уређаја", "Device key": "Кључ уређаја", "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Ако се подудара, притисните дугме за потврду провере испод. Ако се не подудара, неко други прислушкује овај уређај и вероватно желите да притиснете дугме за стављање на црни списак.", - "In future this verification process will be more sophisticated.": "У будућности ће овај поступак потврђивања бити напреднији.", + "In future this verification process will be more sophisticated.": "У будућности ће овај поступак провере бити напреднији.", "Verify device": "Провери уређај", "I verify that the keys match": "Потврђујем да се кључеви подударају", "An error has occurred.": "Догодила се грешка.", "OK": "У реду", "You added a new device '%(displayName)s', which is requesting encryption keys.": "Додали сте нови уређај „%(displayName)s“ који захтева кључеве за шифровање.", - "Your unverified device '%(displayName)s' is requesting encryption keys.": "Ваш непотврђени уређај „%(displayName)s“ захтева кључеве за шифровање.", - "Start verification": "Започни потврђивање", - "Share without verifying": "Подели без потврђивања", + "Your unverified device '%(displayName)s' is requesting encryption keys.": "Ваш непроверени уређај „%(displayName)s“ захтева кључеве за шифровање.", + "Start verification": "Започни проверу", + "Share without verifying": "Подели без провере", "Ignore request": "Занемари захтев", "Loading device info...": "Учитавам податке о уређају...", "Encryption key request": "Захтев за кључ шифровања", @@ -693,7 +693,7 @@ "Continue anyway": "Ипак настави", "Invalid Email Address": "Неисправна мејл адреса", "This doesn't appear to be a valid email address": "Изгледа да ово није исправна мејл адреса", - "Verification Pending": "Чека се на потврду", + "Verification Pending": "Чека се на проверу", "Please check your email and click on the link it contains. Once this is done, click continue.": "Проверите ваш мејл и кликните на везу унутар њега. Када ово урадите, кликните на дугме „настави“.", "Unable to add email address": "Не могу да додам мејл адресу", "Unable to verify email address.": "Не могу да проверим мејл адресу.", From e9e0d65401c3ff6b840b2df66a92fab269e76df3 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 9 Feb 2018 12:33:59 +0000 Subject: [PATCH 0278/1160] Prepare changelog for v0.11.4 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87459882c9..055e25b805 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +Changes in [0.11.4](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.11.4) (2018-02-09) +===================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.11.3...v0.11.4) + + * Add isUrlPermitted function to sanity check URLs + Changes in [0.11.3](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.11.3) (2017-12-04) ===================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.11.2...v0.11.3) From 4bf5e44b2043bbe95faa66943878acad23dfb823 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 9 Feb 2018 12:34:00 +0000 Subject: [PATCH 0279/1160] v0.11.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5c81db2153..36f137e4f4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.11.3", + "version": "0.11.4", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From 9dba4ab569e050dd28492ba633889f392546c0b7 Mon Sep 17 00:00:00 2001 From: Tirifto Date: Fri, 9 Feb 2018 12:30:53 +0000 Subject: [PATCH 0280/1160] Translated using Weblate (Esperanto) Currently translated at 97.1% (958 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eo/ --- src/i18n/strings/eo.json | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index a50d16a2b3..c6a4b81740 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -944,5 +944,17 @@ "Import": "Enporti", "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Forigo de fenestraĵo efektiviĝos por ĉiuj uzantoj en ĉi tiu ĉambro. Ĉu vi certe volas ĝin forigi?", "Unblacklist": "Repermesi legadon de ĉifritaj mesaĝoj", - "none": "neniu" + "none": "neniu", + "The version of Riot.im": "Tiu ĉi versio de Riot.im", + "Whether or not you're logged in (we don't record your user name)": "Ĉu vi salutis aŭ ne (ni ne registras vian salutnomon)", + "Your language of choice": "Via preferata lingvo", + "The information being sent to us to help make Riot.im better includes:": "Informoj sendataj al ni por plibonigi la servon Riot.im inkluzivas:", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s ŝanĝis sian vidigan nomon al %(displayName)s.", + "Send an encrypted reply…": "Sendi ĉifritan respondon…", + "Send a reply (unencrypted)…": "Sendi respondon (neĉifritan)…", + "Send an encrypted message…": "Sendi ĉifritan mesaĝon…", + "Send a message (unencrypted)…": "Sendi mesaĝon (neĉifritan)…", + "Replying": "Respondanta", + "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Privato gravas al ni, tial ni ne kolektas personajn aŭ spureblajn datumojn por nia analizo.", + "Learn more about how we use analytics.": "Lernu pli pri nia uzo de analiziloj." } From 55593416fa71c9c2a77382da8053457c6a5d4d39 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Fri, 9 Feb 2018 13:23:34 +0000 Subject: [PATCH 0281/1160] Hide apps drawer when viewining room settings. --- src/components/structures/RoomView.js | 3 +- src/components/views/rooms/AppsDrawer.js | 40 ++++++++++++++---------- src/components/views/rooms/AuxPanel.js | 9 +++++- 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 60987fe26e..4873bbc961 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -1605,7 +1605,8 @@ module.exports = React.createClass({ displayConfCallNotification={this.state.displayConfCallNotification} maxHeight={this.state.auxPanelMaxHeight} onResize={this.onChildResize} - showApps={this.state.showApps && !this.state.editingRoomSettings} > + showApps={this.state.showApps} + hideAppsDrawer={this.state.editingRoomSettings} > { aux } ); diff --git a/src/components/views/rooms/AppsDrawer.js b/src/components/views/rooms/AppsDrawer.js index 7541b304a2..a8336edfc3 100644 --- a/src/components/views/rooms/AppsDrawer.js +++ b/src/components/views/rooms/AppsDrawer.js @@ -35,7 +35,15 @@ module.exports = React.createClass({ displayName: 'AppsDrawer', propTypes: { + userId: React.PropTypes.string.isRequired, room: React.PropTypes.object.isRequired, + showApps: React.PropTypes.bool, // Should apps be rendered + hide: React.PropTypes.bool, // If rendered, should apps drawer be visible + }, + + defaultProps: { + showApps: true, + hide: false, }, getInitialState: function() { @@ -46,7 +54,7 @@ module.exports = React.createClass({ componentWillMount: function() { ScalarMessaging.startListening(); - MatrixClientPeg.get().on("RoomState.events", this.onRoomStateEvents); + MatrixClientPeg.get().on('RoomState.events', this.onRoomStateEvents); }, componentDidMount: function() { @@ -56,7 +64,7 @@ module.exports = React.createClass({ this.scalarClient.connect().then(() => { this.forceUpdate(); }).catch((e) => { - console.log("Failed to connect to integrations server"); + console.log('Failed to connect to integrations server'); // TODO -- Handle Scalar errors // this.setState({ // scalar_error: err, @@ -70,7 +78,7 @@ module.exports = React.createClass({ componentWillUnmount: function() { ScalarMessaging.stopListening(); if (MatrixClientPeg.get()) { - MatrixClientPeg.get().removeListener("RoomState.events", this.onRoomStateEvents); + MatrixClientPeg.get().removeListener('RoomState.events', this.onRoomStateEvents); } dis.unregister(this.dispatcherRef); }, @@ -81,7 +89,7 @@ module.exports = React.createClass({ }, onAction: function(action) { - const hideWidgetKey = this.props.room.roomId + "_hide_widget_drawer"; + const hideWidgetKey = this.props.room.roomId + '_hide_widget_drawer'; switch (action.action) { case 'appsDrawer': // When opening the app drawer when there aren't any apps, @@ -109,7 +117,7 @@ module.exports = React.createClass({ * passed through encodeURIComponent. * @param {string} pathTemplate The path with template variables e.g. '/foo/$bar'. * @param {Object} variables The key/value pairs to replace the template - * variables with. E.g. { "$bar": "baz" }. + * variables with. E.g. { '$bar': 'baz' }. * @return {string} The result of replacing all template variables e.g. '/foo/baz'. */ encodeUri: function(pathTemplate, variables) { @@ -187,13 +195,13 @@ module.exports = React.createClass({ }, _launchManageIntegrations: function() { - const IntegrationsManager = sdk.getComponent("views.settings.IntegrationsManager"); + const IntegrationsManager = sdk.getComponent('views.settings.IntegrationsManager'); const src = (this.scalarClient !== null && this.scalarClient.hasCredentials()) ? this.scalarClient.getScalarInterfaceUrlForRoom(this.props.room, 'add_integ') : null; Modal.createTrackedDialog('Integrations Manager', '', IntegrationsManager, { src: src, - }, "mx_IntegrationsManager"); + }, 'mx_IntegrationsManager'); }, onClickAddWidget: function(e) { @@ -201,12 +209,12 @@ module.exports = React.createClass({ // Display a warning dialog if the max number of widgets have already been added to the room const apps = this._getApps(); if (apps && apps.length >= MAX_WIDGETS) { - const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog'); const errorMsg = `The maximum number of ${MAX_WIDGETS} widgets have already been added to this room.`; console.error(errorMsg); Modal.createDialog(ErrorDialog, { - title: _t("Cannot add any more widgets"), - description: _t("The maximum permitted number of widgets have already been added to this room."), + title: _t('Cannot add any more widgets'), + description: _t('The maximum permitted number of widgets have already been added to this room.'), }); return; } @@ -238,11 +246,11 @@ module.exports = React.createClass({ ) { addWidget =
    [+] { _t('Add a widget') } @@ -250,8 +258,8 @@ module.exports = React.createClass({ } return ( -
    -
    +
    +
    { apps }
    { this._canUserModify() && addWidget } diff --git a/src/components/views/rooms/AuxPanel.js b/src/components/views/rooms/AuxPanel.js index c0857d9691..749026d5c6 100644 --- a/src/components/views/rooms/AuxPanel.js +++ b/src/components/views/rooms/AuxPanel.js @@ -31,7 +31,8 @@ module.exports = React.createClass({ // js-sdk room object room: React.PropTypes.object.isRequired, userId: React.PropTypes.string.isRequired, - showApps: React.PropTypes.bool, + showApps: React.PropTypes.bool, // Render apps + hideAppsDrawer: React.PropTypes.bool, // Do not display apps drawer and content (may still be rendered) // Conference Handler implementation conferenceHandler: React.PropTypes.object, @@ -51,6 +52,11 @@ module.exports = React.createClass({ onResize: React.PropTypes.func, }, + defaultProps: { + showApps: true, + hideAppsDrawer: false, + }, + shouldComponentUpdate: function(nextProps, nextState) { return (!ObjectUtils.shallowEqual(this.props, nextProps) || !ObjectUtils.shallowEqual(this.state, nextState)); @@ -133,6 +139,7 @@ module.exports = React.createClass({ userId={this.props.userId} maxHeight={this.props.maxHeight} showApps={this.props.showApps} + hide={this.props.hideAppsDrawer} />; return ( From 1c3d8cbe6e27781b568753a39fd1a73c15d306f2 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 10 Feb 2018 11:19:43 +0000 Subject: [PATCH 0282/1160] initial refactor of Replies to use `B` explicit over-the-wire format Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Quote.js | 230 +++++++++--------- src/components/views/messages/TextualBody.js | 19 -- src/components/views/rooms/EventTile.js | 6 +- .../views/rooms/MessageComposerInput.js | 54 ++-- src/components/views/rooms/QuotePreview.js | 4 +- 5 files changed, 140 insertions(+), 173 deletions(-) diff --git a/src/components/views/elements/Quote.js b/src/components/views/elements/Quote.js index 761f7aa151..fa571aa063 100644 --- a/src/components/views/elements/Quote.js +++ b/src/components/views/elements/Quote.js @@ -21,33 +21,20 @@ import MatrixClientPeg from '../../../MatrixClientPeg'; import {wantsDateSeparator} from '../../../DateUtils'; import {MatrixEvent} from 'matrix-js-sdk'; import {makeUserPermalink} from "../../../matrix-to"; - -// For URLs of matrix.to links in the timeline which have been reformatted by -// HttpUtils transformTags to relative links. This excludes event URLs (with `[^\/]*`) -const REGEX_LOCAL_MATRIXTO = /^#\/room\/([\#\!][^\/]*)\/(\$[^\/]*)$/; +import SettingsStore from "../../../settings/SettingsStore"; export default class Quote extends React.Component { - static isMessageUrl(url) { - return !!REGEX_LOCAL_MATRIXTO.exec(url); - } - - static childContextTypes = { - matrixClient: PropTypes.object, - addRichQuote: PropTypes.func, - }; - static propTypes = { - // The matrix.to url of the event - url: PropTypes.string, - // The original node that was rendered - node: PropTypes.instanceOf(Element), // The parent event parentEv: PropTypes.instanceOf(MatrixEvent), + + onWidgetLoad: PropTypes.func.isRequired, }; constructor(props, context) { super(props, context); + /* this.state = { // The event related to this quote and their nested rich quotes events: [], @@ -55,45 +42,54 @@ export default class Quote extends React.Component { show: true, // Whether an error was encountered fetching nested older event, show node if it does err: false, + loading: true, + };*/ + + this.state = { + // The loaded events to be rendered as linear-replies + events: [], + + // The latest loaded event which has not yet been shown + loadedEv: null, + // Whether the component is still loading more events + loading: true, + + // Whether as error was encountered fetching a replied to event. + err: null, }; this.onQuoteClick = this.onQuoteClick.bind(this); - this.addRichQuote = this.addRichQuote.bind(this); - } - - getChildContext() { - return { - matrixClient: MatrixClientPeg.get(), - addRichQuote: this.addRichQuote, - }; - } - - parseUrl(url) { - if (!url) return; - - // Default to the empty array if no match for simplicity - // resource and prefix will be undefined instead of throwing - const matrixToMatch = REGEX_LOCAL_MATRIXTO.exec(url) || []; - - const [, roomIdentifier, eventId] = matrixToMatch; - return {roomIdentifier, eventId}; - } - - componentWillReceiveProps(nextProps) { - const {roomIdentifier, eventId} = this.parseUrl(nextProps.url); - if (!roomIdentifier || !eventId) return; - - const room = this.getRoom(roomIdentifier); - if (!room) return; - - // Only try and load the event if we know about the room - // otherwise we just leave a `Quote` anchor which can be used to navigate/join the room manually. - this.setState({ events: [] }); - if (room) this.getEvent(room, eventId, true); } componentWillMount() { - this.componentWillReceiveProps(this.props); + this.room = this.getRoom(this.props.parentEv.getRoomId()); + this.initialize(); + } + + async initialize() { + const {parentEv} = this.props; + const inReplyTo = Quote.getInReplyTo(parentEv); + + const ev = await this.getEvent(this.room, inReplyTo['event_id']); + this.setState({ + events: [ev], + }, this.loadNextEvent); + } + + async loadNextEvent() { + this.props.onWidgetLoad(); + const ev = this.state.events[0]; + const inReplyTo = Quote.getInReplyTo(ev); + + if (!inReplyTo) { + this.setState({ + loading: false, + }); + return; + } + + const loadedEv = await this.getEvent(this.room, inReplyTo['event_id']); + this.setState({loadedEv}); } getRoom(id) { @@ -105,84 +101,84 @@ export default class Quote extends React.Component { }); } - async getEvent(room, eventId, show) { + async getEvent(room, eventId) { const event = room.findEventById(eventId); - if (event) { - this.addEvent(event, show); - return; - } + if (event) return event; await MatrixClientPeg.get().getEventTimeline(room.getUnfilteredTimelineSet(), eventId); - this.addEvent(room.findEventById(eventId), show); - } - - addEvent(event, show) { - const events = [event].concat(this.state.events); - this.setState({events, show}); - } - - // addRichQuote(roomId, eventId) { - addRichQuote(href) { - const {roomIdentifier, eventId} = this.parseUrl(href); - if (!roomIdentifier || !eventId) { - this.setState({ err: true }); - return; - } - - const room = this.getRoom(roomIdentifier); - if (!room) { - this.setState({ err: true }); - return; - } - - this.getEvent(room, eventId, false); + return room.findEventById(eventId); } onQuoteClick() { - this.setState({ show: true }); + const events = [this.state.loadedEv].concat(this.state.events); + + this.setState({ + loadedEv: null, + events, + }, this.loadNextEvent); + } + + static getInReplyTo(ev) { + if (ev.isRedacted()) return; + + const {'m.relates_to': mRelatesTo} = ev.getContent(); + if (mRelatesTo) { + return mRelatesTo['m.in_reply_to']; + } + } + + static getRelationship(ev) { + return { + 'm.relates_to': { + 'm.in_reply_to': { + 'event_id': ev.getId(), + }, + }, + }; + } + + static getQuote(parentEv, onWidgetLoad) { + if (!SettingsStore.isFeatureEnabled("feature_rich_quoting") || !Quote.getInReplyTo(parentEv)) return null; + return ; } render() { - const events = this.state.events.slice(); - if (events.length) { - const evTiles = []; - - if (!this.state.show) { - const oldestEv = events.shift(); - const Pill = sdk.getComponent('elements.Pill'); - const room = MatrixClientPeg.get().getRoom(oldestEv.getRoomId()); - - evTiles.push(
    - { - _t('In reply to ', {}, { - 'a': (sub) => { sub }, - 'pill': , - }) - } -
    ); - } - - const EventTile = sdk.getComponent('views.rooms.EventTile'); - const DateSeparator = sdk.getComponent('messages.DateSeparator'); - events.forEach((ev) => { - let dateSep = null; - - if (wantsDateSeparator(this.props.parentEv.getDate(), ev.getDate())) { - dateSep = ; + let header = null; + if (this.state.loadedEv) { + const ev = this.state.loadedEv; + const Pill = sdk.getComponent('elements.Pill'); + const room = MatrixClientPeg.get().getRoom(ev.getRoomId()); + header =
    + { + _t('In reply to ', {}, { + 'a': (sub) => { sub }, + 'pill': , + }) } - - evTiles.push(
    - { dateSep } - -
    ); - }); - - return
    { evTiles }
    ; +
    ; + } else if (this.state.loading) { + header =
    LOADING...
    ; } - // Deliberately render nothing if the URL isn't recognised - // in case we get an undefined/falsey node, replace it with null to make React happy - return this.props.node || null; + const EventTile = sdk.getComponent('views.rooms.EventTile'); + const DateSeparator = sdk.getComponent('messages.DateSeparator'); + const evTiles = this.state.events.map((ev) => { + let dateSep = null; + + if (wantsDateSeparator(this.props.parentEv.getDate(), ev.getDate())) { + dateSep = ; + } + + return
    + { dateSep } + +
    ; + }); + + return
    +
    { header }
    +
    { evTiles }
    +
    ; } } diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index 31c1df7b44..7da4dd8644 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -61,10 +61,6 @@ module.exports = React.createClass({ tileShape: PropTypes.string, }, - contextTypes: { - addRichQuote: PropTypes.func, - }, - getInitialState: function() { return { // the URLs (if any) to be previewed with a LinkPreviewWidget @@ -205,21 +201,6 @@ module.exports = React.createClass({ // update the current node with one that's now taken its place node = pillContainer; - } else if (SettingsStore.isFeatureEnabled("feature_rich_quoting") && Quote.isMessageUrl(href)) { - if (this.context.addRichQuote) { // We're already a Rich Quote so just append the next one above - this.context.addRichQuote(href); - node.remove(); - } else { // We're the first in the chain - const quoteContainer = document.createElement('span'); - - const quote = - ; - - ReactDOM.render(quote, quoteContainer); - node.parentNode.replaceChild(quoteContainer, node); - node = quoteContainer; - } - pillified = true; } } else if (node.nodeType == Node.TEXT_NODE) { const Pill = sdk.getComponent('elements.Pill'); diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 1d8df4c7a6..7e9a7a75f1 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -18,6 +18,8 @@ limitations under the License. 'use strict'; +import Quote from "../elements/Quote"; + const React = require('react'); import PropTypes from 'prop-types'; const classNames = require("classnames"); @@ -517,7 +519,7 @@ module.exports = withMatrixClient(React.createClass({ if (needsSenderProfile) { let text = null; - if (!this.props.tileShape || this.props.tileShape === 'quote') { + if (!this.props.tileShape) { if (msgtype === 'm.image') text = _td('%(senderName)s sent an image'); else if (msgtype === 'm.video') text = _td('%(senderName)s sent a video'); else if (msgtype === 'm.file') text = _td('%(senderName)s uploaded a file'); @@ -598,7 +600,6 @@ module.exports = withMatrixClient(React.createClass({ { this._renderE2EPadlock() } { this._renderE2EPadlock() } + { Quote.getQuote(this.props.mxEvent, this.props.onWidgetLoad) } block.getType() !== 'unstyled')) { shouldSendHTML = true; @@ -820,15 +815,15 @@ export default class MessageComposerInput extends React.Component { const md = new Markdown(pt); // if contains no HTML and we're not quoting (needing HTML) - if (md.isPlainText() && !quotingEv) { + if (md.isPlainText()) { contentText = md.toPlaintext(); } else { contentHTML = md.toHTML(); } } - let sendHtmlFn = this.client.sendHtmlMessage; - let sendTextFn = this.client.sendTextMessage; + let sendHtmlFn = ContentHelpers.makeHtmlMessage; + let sendTextFn = ContentHelpers.makeTextMessage; this.historyManager.save( contentState, @@ -839,35 +834,26 @@ export default class MessageComposerInput extends React.Component { contentText = contentText.substring(4); // bit of a hack, but the alternative would be quite complicated if (contentHTML) contentHTML = contentHTML.replace(/\/me ?/, ''); - sendHtmlFn = this.client.sendHtmlEmote; - sendTextFn = this.client.sendEmoteMessage; + sendHtmlFn = ContentHelpers.makeHtmlEmote; + sendTextFn = ContentHelpers.makeEmoteMessage; } - if (quotingEv) { - const cli = MatrixClientPeg.get(); - const room = cli.getRoom(quotingEv.getRoomId()); - const sender = room.currentState.getMember(quotingEv.getSender()); - - const {body/*, formatted_body*/} = quotingEv.getContent(); - - const perma = makeEventPermalink(quotingEv.getRoomId(), quotingEv.getId()); - contentText = `${sender.name}:\n> ${body}\n\n${contentText}`; - contentHTML = `Quote
    ${contentHTML}`; - - // we have finished quoting, clear the quotingEvent - dis.dispatch({ - action: 'quote_event', - event: null, - }); - } + const quotingEv = RoomViewStore.getQuotingEvent(); + const content = quotingEv ? Quote.getRelationship(quotingEv) : {}; + // we have finished quoting, clear the quotingEvent + // TODO maybe delay this until the event actually sends? + dis.dispatch({ + action: 'quote_event', + event: null, + }); let sendMessagePromise; if (contentHTML) { - sendMessagePromise = sendHtmlFn.call( - this.client, this.props.room.roomId, contentText, contentHTML, - ); + Object.assign(content, sendHtmlFn(contentText, contentHTML)); + sendMessagePromise = this.client.sendMessage(this.props.room.roomId, content); } else { - sendMessagePromise = sendTextFn.call(this.client, this.props.room.roomId, contentText); + Object.assign(content, sendTextFn(contentText)); + sendMessagePromise = this.client.sendMessage(this.props.room.roomId, content); } sendMessagePromise.done((res) => { diff --git a/src/components/views/rooms/QuotePreview.js b/src/components/views/rooms/QuotePreview.js index 614d51dada..590ee21b8f 100644 --- a/src/components/views/rooms/QuotePreview.js +++ b/src/components/views/rooms/QuotePreview.js @@ -71,8 +71,10 @@ export default class QuotePreview extends React.Component { onClick={cancelQuoting} />
    - +
    ; } } + +function dummyOnWidgetLoad() {} From 18145460b2764e0fbc637ce23832ca98100ca7ee Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 10 Feb 2018 12:31:22 +0000 Subject: [PATCH 0283/1160] fix Replies for e2e Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Quote.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/views/elements/Quote.js b/src/components/views/elements/Quote.js index fa571aa063..33819d522a 100644 --- a/src/components/views/elements/Quote.js +++ b/src/components/views/elements/Quote.js @@ -121,9 +121,10 @@ export default class Quote extends React.Component { static getInReplyTo(ev) { if (ev.isRedacted()) return; - const {'m.relates_to': mRelatesTo} = ev.getContent(); + const mRelatesTo = ev.getWireContent()['m.relates_to']; if (mRelatesTo) { - return mRelatesTo['m.in_reply_to']; + const mInReplyTo = mRelatesTo['m.in_reply_to']; + if ('event_id' in mInReplyTo) return mInReplyTo; } } From fbb950e06433fd3aa4166b398ab3a2940538ebc2 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 10 Feb 2018 12:38:25 +0000 Subject: [PATCH 0284/1160] mass s/Quote/Reply Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- .../views/elements/{Quote.js => Reply.js} | 18 +++++++++--------- src/components/views/messages/TextualBody.js | 1 - src/components/views/rooms/EventTile.js | 8 ++++---- .../views/rooms/MessageComposerInput.js | 8 ++++---- .../rooms/{QuotePreview.js => ReplyPreview.js} | 14 +++++++------- 5 files changed, 24 insertions(+), 25 deletions(-) rename src/components/views/elements/{Quote.js => Reply.js} (91%) rename src/components/views/rooms/{QuotePreview.js => ReplyPreview.js} (83%) diff --git a/src/components/views/elements/Quote.js b/src/components/views/elements/Reply.js similarity index 91% rename from src/components/views/elements/Quote.js rename to src/components/views/elements/Reply.js index 33819d522a..6d456cf6b4 100644 --- a/src/components/views/elements/Quote.js +++ b/src/components/views/elements/Reply.js @@ -23,7 +23,7 @@ import {MatrixEvent} from 'matrix-js-sdk'; import {makeUserPermalink} from "../../../matrix-to"; import SettingsStore from "../../../settings/SettingsStore"; -export default class Quote extends React.Component { +export default class Reply extends React.Component { static propTypes = { // The parent event parentEv: PropTypes.instanceOf(MatrixEvent), @@ -68,7 +68,7 @@ export default class Quote extends React.Component { async initialize() { const {parentEv} = this.props; - const inReplyTo = Quote.getInReplyTo(parentEv); + const inReplyTo = Reply.getInReplyTo(parentEv); const ev = await this.getEvent(this.room, inReplyTo['event_id']); this.setState({ @@ -79,7 +79,7 @@ export default class Quote extends React.Component { async loadNextEvent() { this.props.onWidgetLoad(); const ev = this.state.events[0]; - const inReplyTo = Quote.getInReplyTo(ev); + const inReplyTo = Reply.getInReplyTo(ev); if (!inReplyTo) { this.setState({ @@ -139,8 +139,8 @@ export default class Quote extends React.Component { } static getQuote(parentEv, onWidgetLoad) { - if (!SettingsStore.isFeatureEnabled("feature_rich_quoting") || !Quote.getInReplyTo(parentEv)) return null; - return ; + if (!SettingsStore.isFeatureEnabled("feature_rich_quoting") || !Reply.getInReplyTo(parentEv)) return null; + return ; } render() { @@ -149,10 +149,10 @@ export default class Quote extends React.Component { const ev = this.state.loadedEv; const Pill = sdk.getComponent('elements.Pill'); const room = MatrixClientPeg.get().getRoom(ev.getRoomId()); - header =
    + header =
    { _t('In reply to ', {}, { - 'a': (sub) => { sub }, + 'a': (sub) => { sub }, 'pill': , }) @@ -171,9 +171,9 @@ export default class Quote extends React.Component { dateSep = ; } - return
    + return
    { dateSep } - +
    ; }); diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index 7da4dd8644..c91178d9b5 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -182,7 +182,6 @@ module.exports = React.createClass({ // If the link is a (localised) matrix.to link, replace it with a pill const Pill = sdk.getComponent('elements.Pill'); - const Quote = sdk.getComponent('elements.Quote'); if (Pill.isMessagePillUrl(href)) { const pillContainer = document.createElement('span'); diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 7e9a7a75f1..3b72525fbd 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -18,7 +18,7 @@ limitations under the License. 'use strict'; -import Quote from "../elements/Quote"; +import Reply from "../elements/Reply"; const React = require('react'); import PropTypes from 'prop-types'; @@ -589,12 +589,12 @@ module.exports = withMatrixClient(React.createClass({
    ); } - case 'quote': { + case 'reply': { return (
    { avatar } { sender } -
    +
    { timestamp } @@ -622,7 +622,7 @@ module.exports = withMatrixClient(React.createClass({ { timestamp } { this._renderE2EPadlock() } - { Quote.getQuote(this.props.mxEvent, this.props.onWidgetLoad) } + { Reply.getQuote(this.props.mxEvent, this.props.onWidgetLoad) }
    - { SettingsStore.isFeatureEnabled("feature_rich_quoting") && } + { SettingsStore.isFeatureEnabled("feature_rich_quoting") && } this.autocomplete = e} room={this.props.room} diff --git a/src/components/views/rooms/QuotePreview.js b/src/components/views/rooms/ReplyPreview.js similarity index 83% rename from src/components/views/rooms/QuotePreview.js rename to src/components/views/rooms/ReplyPreview.js index 590ee21b8f..045c3da9b3 100644 --- a/src/components/views/rooms/QuotePreview.js +++ b/src/components/views/rooms/ReplyPreview.js @@ -27,7 +27,7 @@ function cancelQuoting() { }); } -export default class QuotePreview extends React.Component { +export default class ReplyPreview extends React.Component { constructor(props, context) { super(props, context); @@ -61,17 +61,17 @@ export default class QuotePreview extends React.Component { const EventTile = sdk.getComponent('rooms.EventTile'); const EmojiText = sdk.getComponent('views.elements.EmojiText'); - return
    -
    - + return
    +
    + { '💬 ' + _t('Replying') } -
    +
    -
    - +
    +
    ; } From 23c0daa83ab2789b996f14cf20172d1656dfd9b5 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 10 Feb 2018 12:41:31 +0000 Subject: [PATCH 0285/1160] pass onWidgetLoad to fix console err for e2e Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Reply.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/elements/Reply.js b/src/components/views/elements/Reply.js index 6d456cf6b4..3ab7af6ced 100644 --- a/src/components/views/elements/Reply.js +++ b/src/components/views/elements/Reply.js @@ -173,7 +173,7 @@ export default class Reply extends React.Component { return
    { dateSep } - +
    ; }); From 7425d01b212e7707482ac1e54365b60acf65c398 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 10 Feb 2018 15:45:42 +0000 Subject: [PATCH 0286/1160] tidy, improve error handling and improve Replies, run gen-i18n Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Reply.js | 51 ++++++++++++++++---------- src/i18n/strings/en_EN.json | 5 ++- 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/src/components/views/elements/Reply.js b/src/components/views/elements/Reply.js index 3ab7af6ced..ff2a6fc36a 100644 --- a/src/components/views/elements/Reply.js +++ b/src/components/views/elements/Reply.js @@ -23,6 +23,9 @@ import {MatrixEvent} from 'matrix-js-sdk'; import {makeUserPermalink} from "../../../matrix-to"; import SettingsStore from "../../../settings/SettingsStore"; +// This component does no cycle detection, simply because the only way to make such a cycle +// would be to craft event_id's, using a custom homeserver; even then the impact would be low +// as each event being loaded (after the first) is triggered by an explicit user action. export default class Reply extends React.Component { static propTypes = { // The parent event @@ -34,17 +37,6 @@ export default class Reply extends React.Component { constructor(props, context) { super(props, context); - /* - this.state = { - // The event related to this quote and their nested rich quotes - events: [], - // Whether the top (oldest) event should be shown or spoilered - show: true, - // Whether an error was encountered fetching nested older event, show node if it does - err: false, - loading: true, - };*/ - this.state = { // The loaded events to be rendered as linear-replies events: [], @@ -55,7 +47,7 @@ export default class Reply extends React.Component { loading: true, // Whether as error was encountered fetching a replied to event. - err: null, + err: false, }; this.onQuoteClick = this.onQuoteClick.bind(this); @@ -71,9 +63,13 @@ export default class Reply extends React.Component { const inReplyTo = Reply.getInReplyTo(parentEv); const ev = await this.getEvent(this.room, inReplyTo['event_id']); - this.setState({ - events: [ev], - }, this.loadNextEvent); + if (ev) { + this.setState({ + events: [ev], + }, this.loadNextEvent); + } else { + this.setState({err: true}); + } } async loadNextEvent() { @@ -89,7 +85,11 @@ export default class Reply extends React.Component { } const loadedEv = await this.getEvent(this.room, inReplyTo['event_id']); - this.setState({loadedEv}); + if (loadedEv) { + this.setState({loadedEv}); + } else { + this.setState({err: true}); + } } getRoom(id) { @@ -105,7 +105,11 @@ export default class Reply extends React.Component { const event = room.findEventById(eventId); if (event) return event; - await MatrixClientPeg.get().getEventTimeline(room.getUnfilteredTimelineSet(), eventId); + try { + await MatrixClientPeg.get().getEventTimeline(room.getUnfilteredTimelineSet(), eventId); + } catch (e) { + return; + } return room.findEventById(eventId); } @@ -145,7 +149,15 @@ export default class Reply extends React.Component { render() { let header = null; - if (this.state.loadedEv) { + + if (this.state.err) { + header =
    + { + _t('Unable to load event that was replied to, ' + + 'it either does not exist or you do not have permission to view it.') + } +
    ; + } else if (this.state.loadedEv) { const ev = this.state.loadedEv; const Pill = sdk.getComponent('elements.Pill'); const room = MatrixClientPeg.get().getRoom(ev.getRoomId()); @@ -159,7 +171,8 @@ export default class Reply extends React.Component { } ; } else if (this.state.loading) { - header =
    LOADING...
    ; + const Spinner = sdk.getComponent("elements.Spinner"); + header = ; } const EventTile = sdk.getComponent('views.rooms.EventTile'); diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 6139ac2a91..5bde93f46c 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -359,8 +359,8 @@ "Idle": "Idle", "Offline": "Offline", "Unknown": "Unknown", - "Replying": "Replying", "Seen by %(userName)s at %(dateTime)s": "Seen by %(userName)s at %(dateTime)s", + "Replying": "Replying", "No rooms to show": "No rooms to show", "Unnamed room": "Unnamed room", "World readable": "World readable", @@ -500,8 +500,8 @@ "Download %(text)s": "Download %(text)s", "Invalid file%(extra)s": "Invalid file%(extra)s", "Error decrypting image": "Error decrypting image", - "Image '%(Body)s' cannot be displayed.": "Image '%(Body)s' cannot be displayed.", "This image cannot be displayed.": "This image cannot be displayed.", + "Image '%(Body)s' cannot be displayed.": "Image '%(Body)s' cannot be displayed.", "Error decrypting video": "Error decrypting video", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s changed the avatar for %(roomName)s", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s removed the room avatar.", @@ -648,6 +648,7 @@ "expand": "expand", "Custom of %(powerLevel)s": "Custom of %(powerLevel)s", "Custom level": "Custom level", + "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.", "In reply to ": "In reply to ", "Room directory": "Room directory", "Start chat": "Start chat", From 25bc9cfbe7469db03a40d9f5672dd513774f9c4b Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 10 Feb 2018 15:47:32 +0000 Subject: [PATCH 0287/1160] make spinner size more appropriate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Reply.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/elements/Reply.js b/src/components/views/elements/Reply.js index ff2a6fc36a..c513535e85 100644 --- a/src/components/views/elements/Reply.js +++ b/src/components/views/elements/Reply.js @@ -172,7 +172,7 @@ export default class Reply extends React.Component { ; } else if (this.state.loading) { const Spinner = sdk.getComponent("elements.Spinner"); - header = ; + header = ; } const EventTile = sdk.getComponent('views.rooms.EventTile'); From 7bf05b071533a9cf407637f00daa71bd9508c2fa Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 10 Feb 2018 16:01:19 +0000 Subject: [PATCH 0288/1160] add unmounted guard Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Reply.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/components/views/elements/Reply.js b/src/components/views/elements/Reply.js index c513535e85..31e94e1d4a 100644 --- a/src/components/views/elements/Reply.js +++ b/src/components/views/elements/Reply.js @@ -51,6 +51,8 @@ export default class Reply extends React.Component { }; this.onQuoteClick = this.onQuoteClick.bind(this); + + this.unmounted = false; } componentWillMount() { @@ -58,11 +60,17 @@ export default class Reply extends React.Component { this.initialize(); } + componentWillUnmount() { + this.unmounted = true; + } + async initialize() { const {parentEv} = this.props; const inReplyTo = Reply.getInReplyTo(parentEv); const ev = await this.getEvent(this.room, inReplyTo['event_id']); + if (this.unmounted) return; + if (ev) { this.setState({ events: [ev], @@ -78,6 +86,7 @@ export default class Reply extends React.Component { const inReplyTo = Reply.getInReplyTo(ev); if (!inReplyTo) { + if (this.unmounted) return; this.setState({ loading: false, }); @@ -85,6 +94,8 @@ export default class Reply extends React.Component { } const loadedEv = await this.getEvent(this.room, inReplyTo['event_id']); + if (this.unmounted) return; + if (loadedEv) { this.setState({loadedEv}); } else { From e1410755600b4a3f94400cace45aae3ea2c84406 Mon Sep 17 00:00:00 2001 From: Oskars Date: Sat, 10 Feb 2018 16:38:14 +0000 Subject: [PATCH 0289/1160] Translated using Weblate (Latvian) Currently translated at 90.3% (891 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/lv/ --- src/i18n/strings/lv.json | 296 +++++++++++++++++++++++++++++++++------ 1 file changed, 251 insertions(+), 45 deletions(-) diff --git a/src/i18n/strings/lv.json b/src/i18n/strings/lv.json index ae290d4d5f..50416f0318 100644 --- a/src/i18n/strings/lv.json +++ b/src/i18n/strings/lv.json @@ -21,7 +21,7 @@ "Default Device": "Noklusējuma ierīce", "Microphone": "Mikrofons", "Camera": "Kamera", - "Advanced": "Īpašie", + "Advanced": "Papildus", "Algorithm": "Algoritms", "Hide removed messages": "Slēpt dzēstos ziņojumus", "Always show message timestamps": "Vienmēr rādīt ziņojumu laika zīmogu", @@ -35,7 +35,7 @@ "Anyone": "Ikviens", "Anyone who knows the room's link, apart from guests": "Ikviens, kurš zina adreses saiti uz istabu, izņemot viesus", "Anyone who knows the room's link, including guests": "Ikviens, kurš zina adreses saiti uz istabu, tai skaitā arī viesi", - "Are you sure?": "Esi pārliecināts/a?", + "Are you sure?": "Vai tiešām to vēlies?", "Are you sure you want to leave the room '%(roomName)s'?": "Vai tiešām vēlies pamest istabas: '%(roomName)s'?", "Are you sure you want to reject the invitation?": "Vai tiešām vēlies noraidīt šo uzaicinājumu?", "Are you sure you want to upload the following files?": "Vai tiešām vēlies augšuplādēt sekojošos failus?", @@ -48,7 +48,7 @@ "Blacklisted": "Melnajā sarakstā iekļautie", "Bug Report": "Paziņojums par kļūdu", "Bulk Options": "Lielapjoma darbības", - "Call Timeout": "Zvana noilgums", + "Call Timeout": "Zvana gaidīšanas noilgums", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Neizdevās savienoties ar serveri. Lūdzu pārbaudi savu tīkla savienējumu un pārliecinies, ka tava servera SSL sertifikāts ir uzticams, kā arī pārlūkā instalētie paplašinājumi nebloķē pieprasījumus.", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Neizdevās savienoties ar serveri izmantojot HTTP protokolu, kad tava pārlūka adreses laukā ir HTTPS saite. Tā vietā izmanto HTTPS savienojumu vai iespējo nedrošos skriptus.", "Can't load user settings": "Neizdevās ielādēt lietotāja uzstādījumus", @@ -77,21 +77,21 @@ "Conference call failed.": "Konferences zvans neizdevās.", "Conference calling is in development and may not be reliable.": "Konferences zvans šobrīd atrodas izstrādes stadijā un var būt nestabils.", "Conference calls are not supported in encrypted rooms": "Konferences zvani nav iespējami istabās, kurās tiek izmantota šifrēšana", - "Conference calls are not supported in this client": "Konferences zvani netiek atbalstīti šajā programmā", + "Conference calls are not supported in this client": "Konferences zvani šajā klienta programmā netiek atbalstīti", "Confirm password": "Apstiprini paroli", "Confirm your new password": "Apstiprini jauno paroli", "Continue": "Turpināt", "Could not connect to the integration server": "Neizdevās savienoties ar integrācijas serveri", "%(count)s new messages|one": "jaunu ziņu skaits: %(count)s", "%(count)s new messages|other": "%(count)s jaunas ziņas", - "Create a new chat or reuse an existing one": "Izveidot jaunu čatu vai izmantot eksistējošu", + "Create a new chat or reuse an existing one": "Izveidot jaunu čalu vai izmantot jau esošu", "Create an account": "Reģistrēt kontu", "Create Room": "Izveidot istabu", "Cryptography": "Kriptogrāfija", "Current password": "Pašreizējā parole", "Curve25519 identity key": "Curve25519 identifikācijas atslēga", "Custom": "Pielāgots", - "Custom level": "Speciāls līmenis", + "Custom level": "Īpašais līmenis", "/ddg is not a command": "/ddg nav komanda", "Deactivate Account": "Deaktivizēt kontu", "Deactivate my account": "Deaktivizēt manu kontu", @@ -116,7 +116,7 @@ "Don't send typing notifications": "Nesūtīt paziņojumus", "Download %(text)s": "Lejupielādēt tekstu: %(text)s", "Drop File Here": "Ievelc failu šeit", - "Drop here to tag %(section)s": "Ievelc šeit uz birkas %(section)s", + "Drop here to tag %(section)s": "Nomest šeit, lai birkotu %(section)s", "Ed25519 fingerprint": "Ed25519 identificējošā zīmju virkne", "Email": "Epasts", "Email address": "Epasta adrese", @@ -140,11 +140,11 @@ "Error decrypting attachment": "Kļūda atšifrējot pielikumu", "Error: Problem communicating with the given homeserver.": "Kļūda: Radās komunikācijas problēma ar norādīto serveri.", "Event information": "Notikuma informācija", - "Existing Call": "Eksistējošs zvans", + "Existing Call": "Pašreizējā saruna (zvans)", "Export": "Eksportēt", "Export E2E room keys": "Eksportēt E2E istabas atslēgas", - "Failed to ban user": "Neizdevās liegt pieeju lietotājam", - "Failed to change password. Is your password correct?": "Neizdevās mainīt paroli. Vai tava parole ir pareiza?", + "Failed to ban user": "Neizdevās bloķēt (liegt pieeju) lietotāju", + "Failed to change password. Is your password correct?": "Neizdevās nomainīt paroli. Vai tā ir pareiza?", "Failed to change power level": "Neizdevās mainīt statusa līmeni", "Power level must be positive integer.": "Statusa līmenim ir jābūt pozitīvam skaitlim.", "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Tu nevarēsi atcelt šo darbību, jo šim lietotājam piešķir tādu pašu statusa līmeni, kāds ir Tev.", @@ -170,12 +170,12 @@ "Failed to upload profile picture!": "Neizdevās augšuplādēt profila attēlu!", "Failed to verify email address: make sure you clicked the link in the email": "Neizdevās apstiprināt epasta adresi. Pārbaudi, vai Tu esi noklikšķinājis/usi saiti epasta ziņā", "Failure to create room": "Neizdevās izveidot istabu", - "Favourite": "Favorīts", + "Favourite": "Tava izlase (favorīti)", "Favourites": "Favorīti", "Fill screen": "Aizpildīt ekrānu", "Filter room members": "Filtrēt istabas biedrus", "Forget room": "\"Aizmirst\" istabu", - "Forgot your password?": "Aizmirsi savu paroli?", + "Forgot your password?": "Aizmirsi paroli?", "For security, this session has been signed out. Please sign in again.": "Drošības nolūkos, šī sesija ir beigusies. Lūdzu, pieraksties par jaunu.", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Drošības nolūkos, izrakstīšanās dzēsīs jebkādas ierīce-ierīce šifrēšanas atslēgas no šī pārlūka. Ja Tu vēlies saglabāt iespēju atšifrēt tavu saziņas vēsturi no Riot nākotnes sesijām, lūdzu eksportē tavas istabas atslēgas, saglabājot tās drošā vietā.", "Found a bug?": "Pamanīji kļūdu?", @@ -198,7 +198,7 @@ "Incorrect username and/or password.": "Nepareizs lietotājvārds un/vai parole.", "Incorrect verification code": "Nepareizs verifikācijas kods", "Interface Language": "Saskarnes valoda", - "Invalid alias format": "Nepareizs aizstājējvārda formāts", + "Invalid alias format": "Nepareizs aizstājējvārda (aliases) formāts", "Invalid address format": "Nepareizs adreses formāts", "Invalid Email Address": "Nepareiza epasta adrese", "Invalid file%(extra)s": "Nepareizs faila %(extra)s", @@ -215,7 +215,7 @@ "Join Room": "Pievienoties istabai", "%(targetName)s joined the room.": "%(targetName)s pievienojās istabai.", "Joins room with given alias": "Pievieno istabai ar uzdoto aizstājējvārdu", - "Jump to first unread message.": "Pārlekt uz pirmo neizlasīto ziņu.", + "Jump to first unread message.": "Pāriet uz pirmo neizlasīto ziņu.", "%(senderName)s kicked %(targetName)s.": "%(senderName)s iespēra (kick) %(targetName)s.", "Kick": "Iespert (kick)", "Kicks user with given id": "Iesper (kick) lietotājam pēc norādītā id", @@ -240,7 +240,7 @@ "Turn Markdown off": "Izslēgt formatēšanas iespēju", "Turn Markdown on": "Ieslēgt formatēšanas iespēju", "matrix-react-sdk version:": "matrix-react-sdk versija:", - "The default role for new room members is": "Noklusējuma loma jaunam istabas biedram ir", + "The default role for new room members is": "Jauna istabas biedra statuss pēc noklusējuma ir", "Message not sent due to unknown devices being present": "Ziņa nav nosūtīta, jo tika konstatēta nezināmu ierīču klātbūtne", "Missing room_id in request": "Iztrūkstošs room_id pieprasījumā", "Missing user_id in request": "Iztrūkstošs user_id pieprasījumā", @@ -248,7 +248,7 @@ "Mobile phone number (optional)": "Mobilā telefona numurs (nav obligāts)", "Moderator": "Moderators", "Must be viewing a room": "Jāapskata istaba", - "Mute": "Apklusināt", + "Mute": "Kluss (noklusināt)", "%(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", @@ -269,7 +269,7 @@ "No more results": "Nav tālāko rezultātu", "No results": "Nav rezultātu", "No users have specific privileges in this room": "Nav lietotāju ar īpašām privilēģijām šajā istabā", - "OK": "LABI", + "OK": "Labs ir", "olm version:": "olm versija:", "Once encryption is enabled for a room it cannot be turned off again (for now)": "Tiklīdz istabai tiks iespējota šifrēšana, tā vairs nebūs atslēdzama (pašlaik)", "Only people who have been invited": "Vienīgi personas, kuras ir tikušas uzaicinātas", @@ -283,7 +283,7 @@ "Phone": "Telefons", "%(senderName)s placed a %(callType)s call.": "%(senderName)s nolika %(callType)s zvanu.", "Please check your email and click on the link it contains. Once this is done, click continue.": "Lūdzu pārbaudi savu epastu un noklikšķini tajā esošo saiti. Tiklīdz tas ir izdarīts, klikšķini \"turpināt\".", - "Press to start a chat with someone": "Nospied , lai uzsāktu čatu ar kādu", + "Press to start a chat with someone": "Nospied , lai ar kādu uzsāktu čalošanu", "Privacy warning": "Privātuma brīdinājums", "Private Chat": "Privātais čats", "Privileged Users": "Priviliģētie lietotāji", @@ -308,8 +308,8 @@ "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.": "Paroles atiestatīšana atiestatīs visas ierīce-ierīce šifrēšanas atslēgas visās ierīcēs, padarot čata šifrēto ziņu vēsturi nelasāmu, ja vien Tu pirms tam neesi eksportējis savas istabas atslēgas un atkārtoti importējis tās atpakaļ. Nākotnē šo ir plānots uzlabot.", "Results from DuckDuckGo": "Rezultāti no DuckDuckGo", "Return to login screen": "Atgriezties uz pierakstīšanās lapu", - "Riot does not have permission to send you notifications - please check your browser settings": "Riot nav atļauts nosūtīt Tev paziņojumus. Lūdzu pārbaudi sava pārlūka uzstādījumus", - "Riot was not given permission to send notifications - please try again": "Riot nav atļauts nosūtīt paziņojumus. Lūdzu mēģini vēlreiz.", + "Riot does not have permission to send you notifications - please check your browser settings": "Riot nav atļauts nosūtīt Tev paziņojumus. Lūdzu pārbaudi sava pārlūka iestatījumus", + "Riot was not given permission to send notifications - please try again": "Riot nav piešķirta atļauja nosūtīt paziņojumus. Lūdzu mēģini vēlreiz", "riot-web version:": "riot-web versija:", "Unable to enable Notifications": "Nav iespējams iespējot paziņojumus", "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": "Tu izrakstījies no visām ierīcēm un vairs nesaņemsi pašpiegādes (push) paziņojumus. Lai iespējotu paziņojumus, pieraksties atkārtoti katrā no ierīcēm", @@ -319,14 +319,14 @@ "Room %(roomId)s not visible": "Istaba %(roomId)s nav redzama", "%(roomName)s does not exist.": "%(roomName)s neeksistē.", "%(roomName)s is not accessible at this time.": "%(roomName)s šobrīd nav pieejama.", - "Seen by %(userName)s at %(dateTime)s": "Redzams %(userName)s %(dateTime)s", + "Seen by %(userName)s at %(dateTime)s": "Redzējis %(userName)s %(dateTime)s", "%(senderDisplayName)s sent an image.": "%(senderDisplayName)s nosūtīja attēlu.", "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s nosūtīja uzaicinājumu %(targetDisplayName)s pievienoties istabai.", "%(senderName)s set a profile picture.": "%(senderName)s uzstādīja profila attēlu.", "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s uzstādīja redzamo vārdu uz: %(displayName)s.", "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Tevis uzdotā pierakstīšanās atslēga sakrīt ar atslēgu, kuru Tu saņēmi no %(userId)s ierīces %(deviceId)s. Ierīce tika atzīmēta kā verificēta.", "The file '%(fileName)s' exceeds this home server's size limit for uploads": "Faila '%(fileName)s' izmērs pārsniedz šī mājas servera augšupielādes lieluma ierobežojumu", - "The file '%(fileName)s' failed to upload": "Failu '%(fileName)s' neizdevās augšuplādēt", + "The file '%(fileName)s' failed to upload": "Failu '%(fileName)s' neizdevās nosūtīt (augšuplādēt)", "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s ieslēdza ierīce-ierīce šifrēšanu (algorithm %(algorithm)s).", "%(senderName)s unbanned %(targetName)s.": "%(senderName)s atcēla pieejas ierobežojumu (atbanoja) %(targetName)s.", "Unknown room %(roomId)s": "Nezināma istaba %(roomId)s", @@ -402,7 +402,7 @@ "This email address is already in use": "Šī epasta adrese jau tiek izmantota", "This email address was not found": "Šāda epasta adrese nav atrasta", "The email address linked to your account must be entered.": "Ir jāievada tavam kontam piesaistītā epasta adrese.", - "The remote side failed to pick up": "Neizdevās uzņemt attālināto pusi", + "The remote side failed to pick up": "Zvana adresāts neatbild", "This Home Server does not support login using email address.": "Šis serveris neatbalsta pierakstīšanos ar epasta adresi.", "This invitation was sent to an email address which is not associated with this account:": "Šis uzaicinājums tika nosūtīts uz epasta adresi, kura nav piesaistīta šim kontam:", "This room has no local addresses": "Šai istabai nav lokālo adrešu", @@ -425,7 +425,7 @@ "Unable to verify email address.": "Nav iespējams apstiprināt epasta adresi.", "Unban": "Atbanot", "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Nav iespējams pārliecināties, ka šis uzaicinājums tika nosūtīts uz to pašu adresi, kura ir piesaistīta tavam kontam.", - "Unable to capture screen": "Nav iespējams uzņemt ekrānattēlu", + "Unable to capture screen": "Neizdevās uzņemt ekrānattēlu", "Unable to load device list": "Nav iespējams ielādēt ierīču sarakstu", "Undecryptable": "Neatšifrējams", "Unencrypted room": "Nešifrēta istaba", @@ -439,14 +439,14 @@ "Unnamed Room": "Istaba bez nosaukuma", "Cancel": "Atcelt", "Create new room": "Izveidot jaunu istabu", - "Custom Server Options": "Īpaši servera uzstādījumi", - "Dismiss": "Noņemt", + "Custom Server Options": "Iestatāmie servera uzstādījumi", + "Dismiss": "Atteikums", "You have enabled URL previews by default.": "Tev ir pēc noklusējuma iespējots URL adrešu priekšskatījums.", "Unrecognised command:": "Neatpazīta komanda:", "Unrecognised room alias:": "Neatpazīts istabas aizstājējvārds:", "Unverified": "Neverificēts", "Upload avatar": "Augšuplādē profila attēlu", - "Upload Failed": "Augšupielāde neizdevās", + "Upload Failed": "Nosūtīšana (augšupielāde) neizdevās", "Upload Files": "Augšuplādē failus", "Upload file": "Augšuplādē failu", "Upload new:": "Augšuplādē jaunu:", @@ -481,11 +481,11 @@ "Who would you like to add to this room?": "Kuru vēlies pievienot šai istabai?", "Who would you like to communicate with?": "Ar kuru vēlies komunicēt?", "Would you like to accept or decline this invitation?": "Vai vēlies apstiprināt vai noraidīt šo uzaicinājumu?", - "You already have existing direct chats with this user:": "Tev jau ir eksistējošs tiešais čats ar šo lietotāju:", - "You are already in a call.": "Tu jau šobrīd atrodies zvanā.", + "You already have existing direct chats with this user:": "Tev jau ir viens tiešais čats ar šo lietotāju:", + "You are already in a call.": "Tu jau šobrīd esi sarunā.", "You're not in any rooms yet! Press to make a room or to browse the directory": "Šobrīd Tu vēl neatrodies nevienā istabā! Klikšķini lai izveidotu istabu, vai , lai skatītu istabu katalogu", - "You cannot place a call with yourself.": "Tu nevari veikt zvanu sev.", - "You cannot place VoIP calls in this browser.": "Tu nevari veikt VoIP zvanus šajā pārlūkā.", + "You cannot place a call with yourself.": "Nav iespējams piezvanīt sev.", + "You cannot place VoIP calls in this browser.": "VoIP zvani šajā pārlūkā netiek atbalstīti.", "You do not have permission to post to this room": "Tev nav vajadzīgās atļaujas pievienot ziņas šajā istabā", "You have disabled URL previews by default.": "URL priekšskatījums pēc noklusējuma Tev ir atspējots.", "You may wish to login with a different account, or add this email to this account.": "Tu varētu, iespējams, vēlēties pierakstīties no cita konta vai piesaistīt šo epastu šim kontam.", @@ -531,7 +531,7 @@ "An unknown error occurred.": "Notikusi neparedzēta kļūda.", "I already have an account": "Man jau ir konts", "Topic": "Tēma", - "Make Moderator": "Piešķirt moderatora līmeni", + "Make Moderator": "Piešķirt moderatora statusu", "Make this room private": "Padarīt šo istabu privātu", "Share message history with new users": "Kopīgot ziņu vēsturi ar jauniem lietotājiem", "Encrypt room": "Šifrēt istabu", @@ -550,7 +550,7 @@ "numbullet": "lode ar numuru", "Please select the destination room for this message": "Lūdzu izvēlies šīs ziņas mērķa istabu", "Room directory": "Istabu katalogs", - "Start chat": "Uzsākt čatu", + "Start chat": "Uzsākt čalošanu", "New Password": "Jauna parole", "Start automatically after system login": "Uzsākt automātiski pēc pierakstīšanās sistēmā", "Desktop specific": "Darbvirsmai specifiski", @@ -569,7 +569,7 @@ "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Šis process ļauj Tev importēt tās šifrēšanas atslēgas, kuras Tu iepriekš eksportēji no citas Matrix klienta aplikācijas. Importētās atslēgas ļaus vajadzīgajā klienta aplikācijā lasīt atšifrētās ziņas.", "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Eksporta fails būs aizsargāts ar paroles frāzi. Tā ir jāievada šeit, lai atšifrētu failu.", "You must join the room to see its files": "Tev ir jāpievienojas istabai, lai redzētu tās failus", - "Start new chat": "Uzsākt jaunu čatu", + "Start new chat": "Uzsākt jaunu čalu", "Failed to invite": "Neizdevās uzaicināt", "Failed to invite user": "Neizdevās uzaicināt lietotāju", "Confirm Removal": "Apstiprini dzēšanu", @@ -596,7 +596,7 @@ "Blacklist": "Melnais saraksts", "Unverify": "Atverificēt", "Verify...": "Verificē...", - "ex. @bob:example.com": "piemēram, @janis:majaslapa.lv", + "ex. @bob:example.com": "piemēram, @valters:smaidu.lv", "Add User": "Pievienot lietotāju", "This Home Server would like to make sure you are not a robot": "Šis mājas serveris vēlas pārliecināties, ka Tu neesi robots", "Sign in with CAS": "Pierakstīties ar CAS", @@ -606,7 +606,7 @@ "Please check your email to continue registration.": "Lūdzu pārbaudi savu epastu lai turpinātu reģistrāciju.", "Token incorrect": "Nepareizs autentifikācijas kods", "Please enter the code it contains:": "Lūdzu ievadi tajā ietverto kodu:", - "powered by Matrix": "spēcināts ar Matrix", + "powered by Matrix": "Tiek darbināts ar Matrix", "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Ja Tu nenorādīsi epasta adresi, tev nebūs iespējams izmantot paroles atiestatīšanu. Vai esi pārliecināts/a?", "Default server": "Noklusējuma serveris", "Custom server": "Īpašs serveris", @@ -617,18 +617,18 @@ "Error decrypting image": "Kļūda atšifrējot attēlu", "Error decrypting video": "Kļūda atšifrējot video", "Add an Integration": "Pievienot integrāciju", - "Removed or unknown message type": "Dzēsts vai nezināms ziņas veids", + "Removed or unknown message type": "Dzēsts vai nezināms ziņas tips", "URL Previews": "URL adrešu priekšskatījumi", "Drop file here to upload": "Ievelc failu šeit lai augšuplādētu", " (unsupported)": " (netiek atbalstīts)", - "Online": "Tiešsaistē", + "Online": "Tiešsaistē (pieslēgumā)", "Idle": "Dīkstāve", - "Offline": "Nav tiešsaistē", + "Offline": "Atsaistē (ārpus tīkla)", "Updates": "Atjauninājumi", "Check for update": "Pārbaudīt, vai ir atjauninājumi", - "Start chatting": "Sākt čatošanu", - "Start Chatting": "Sākt čatošanu", - "Click on the button below to start chatting!": "Klikšķini uz zemāk esošās pogas, lai uzsāktu čatošanu!", + "Start chatting": "Sākt čalošanu", + "Start Chatting": "Sākt čalošanu", + "Click on the button below to start chatting!": "Klikšķini uz zemāk esošās pogas, lai uzsāktu čalošanu!", "Username available": "Lietotājvārds ir pieejams", "Username not available": "Lietotājvārds nav pieejams", "Something went wrong!": "Kaut kas nogāja greizi!", @@ -653,14 +653,14 @@ "Delete widget": "Dzēst widžetu", "Define the power level of a user": "Definēt lietotāja pakāpes līmeni", "Do you want to load widget from URL:": "Vai vēlies ielādēt widžetu no URL:", - "Edit": "Labot", + "Edit": "Rediģēt", "Enable automatic language detection for syntax highlighting": "Iespējot automātisko valodas noteikšanu sintakses iezīmējumiem", "Hide Apps": "Slēpt aplikācijas", "Hide join/leave messages (invites/kicks/bans unaffected)": "Slēpt pievienoties/pamest ziņas (tas neietekmē uzaicinājumus, vai kick/bana darbības)", "Integrations Error": "Integrācijas kļūda", "Publish this room to the public in %(domain)s's room directory?": "Publicēt šo istabu publiskajā %(domain)s katalogā?", "AM": "AM", - "PM": "PZ", + "PM": "PM", "NOTE: Apps are not end-to-end encrypted": "PIEZĪME: Aplikācijās nav ierīce-ierīce šifrēšanas", "Sets the room topic": "Uzstāda istabas tēmas nosaukumu", "Show Apps": "Rādīt aplikācijas", @@ -683,5 +683,211 @@ "%(widgetName)s widget added by %(senderName)s": "%(senderName)s pievienoja %(widgetName)s vidžetu", "%(widgetName)s widget removed by %(senderName)s": "%(senderName)s dzēsa vidžetu %(widgetName)s", "Robot check is currently unavailable on desktop - please use a web browser": "Robotu pārbaude šobrīd nav pieejama darbvirsmas versijā. Lūdzu izmanto web pārlūku", - "Revoke widget access": "Atsaukt vidžeta piekļuvi" + "Revoke widget access": "Atsaukt vidžeta piekļuvi", + "Unpin Message": "Atkabināt ziņu", + "Add rooms to this community": "Pievienot istabas šai komūnai", + "Failed to set direct chat tag": "Neizdevās tiešajam čatam uzstādīt birku", + "Warning": "Brīdinājums", + "Send": "Sūtīt", + "Leave": "Pamest", + "Unnamed room": "Nenosaukta istaba", + "Guests can join": "Var pievienoties viesi", + "The platform you're on": "Izmantotā operētājsistēma", + "The version of Riot.im": "Riot.im versija", + "Whether or not you're logged in (we don't record your user name)": "Neatkarīgi no tā, vai esi vai neesi iegājis sistēmā (netiek fiksēts Tavs lietotājvārds)", + "Your language of choice": "Izvēlētā valoda", + "Which officially provided instance you are using, if any": "Kuru oficiāli izlaisto versiju izmantojat (ja to darat)", + "Whether or not you're using the Richtext mode of the Rich Text Editor": "Neatkarīgi no tā, vai izmantojat Richtext režīmu redaktorā Rich Text Editor", + "Your homeserver's URL": "Mājasservera URL adrese", + "Your identity server's URL": "Tava identitātes servera URL adrese", + "The information being sent to us to help make Riot.im better includes:": "Informācija, kura mums tiek nosūtīta, lai ļautu padarīt Riot.im labāku, ietver:", + "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "Mēs arī fiksējam katru lapu, kuru tu izmanto programmā (currently ), Tavu lietotāja aģentu () un Tavas ierīces ekrāna izšķirtspēju ().", + "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Ja šī lapa ietver identificējamu informāciju, tādu kā istaba, lietotājs, grupas ID, šie dati tiek noņemti pirms nosūtīšanas uz serveri.", + "Call Failed": "Zvans neizdevās", + "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "Šajā istabā ir nepazīstamas ierīces: ja Tu turpināsi bez to pārbaudes, ir iespējams, ka kāda nepiederoša persona var noklausīties Tavas sarunas.", + "Review Devices": "Ierīču pārskats", + "Call Anyway": "Vienalga zvanīt", + "Answer Anyway": "Vienalga atbildēt", + "Call": "Zvans", + "Answer": "Atbildēt", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s", + "Who would you like to add to this community?": "Kurus cilvēkus Tu vēlētos pievienot šai komūnai?", + "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Brīdinājums: ikviens, kurš tiek pievienots komūnai būs publiski redzams visiem, kuri zin komūnas ID", + "Invite new community members": "Uzaicināt jaunus komūnas biedrus", + "Name or matrix ID": "Vārds vai Matrix ID", + "Invite to Community": "Uzaicināt komūnā", + "Which rooms would you like to add to this community?": "Kuras istabas vēlies pievienot šai komūnai?", + "Show these rooms to non-members on the community page and room list?": "Vai ne-biedriem rādīt komūnas lapā un istabu sarakstā šīs istabas?", + "Add rooms to the community": "Istabu pievienošana komūnai", + "Room name or alias": "Istabas nosaukums vai aliase", + "Add to community": "Pievienot komūnai", + "Failed to invite the following users to %(groupId)s:": "Neizdevās uzaicināt sekojošus lietotājus grupā %(groupId)s:", + "Failed to invite users to community": "Neizdevās uzaicināt lietotājus komūnā", + "Failed to invite users to %(groupId)s": "Neizdevās uzaicināt lietotājus grupā %(groupId)s:", + "Failed to add the following rooms to %(groupId)s:": "Neizdevās pievienot sekojošas istabas grupai %(groupId)s:", + "Restricted": "Ierobežots", + "Ignored user": "Ignorējams lietotājs", + "You are now ignoring %(userId)s": "Tagad Tu ignorē %(userId)s", + "Unignored user": "Neignorējams lietotājs", + "You are no longer ignoring %(userId)s": "Tu vairāk neignorē %(userId)s", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s nomainīja savu attēlojamo vārdu uz %(displayName)s.", + "%(senderName)s changed the pinned messages for the room.": "%(senderName)s šai istabai nomainīja piekabinātās ziņas.", + "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s vidžets, kuru mainīja %(senderName)s", + "%(names)s and %(count)s others are typing|other": "%(names)s un %(count)s citi raksta", + "%(names)s and %(count)s others are typing|one": "%(names)s un vēl kāds raksta", + "Message Replies": "Atbildes uz ziņām", + "Message Pinning": "Ziņu piekabināšana", + "Presence Management": "Klātbūtnes vadība", + "Tag Panel": "Birku panelis", + "Disable Emoji suggestions while typing": "Atspējot Emoji ieteikumus teksta rakstīšanas laikā", + "Hide avatar changes": "Slēpt avatara izmaiņas", + "Hide display name changes": "Slēpt attēlojamā vārda izmaiņas", + "Disable big emoji in chat": "Atspējot čatā lielos emoji", + "Mirror local video feed": "Spoguļots vietējā video attēlojums", + "Enable inline URL previews by default": "Ieslēgt URL adrešu priekšskatījumu pēc noklusējuma", + "Enable URL previews for this room (only affects you)": "Ieslēgt URL adrešu priekšskatījumus šai istabai (ietekmē tikai Tevi pašu)", + "Enable URL previews by default for participants in this room": "Ieslēgt URL adrešu priekšskatījumus pēc noklusējuma visiem šīs istabas dalībniekiem", + "Delete %(count)s devices|other": "Dzēst %(count)s ierīces", + "Delete %(count)s devices|one": "Dzēst ierīci", + "Select devices": "Izvēlēties ierīces", + "%(senderName)s sent an image": "%(senderName)s nosūtīja bildi", + "%(senderName)s sent a video": "%(senderName)s nosūtīja video", + "%(senderName)s uploaded a file": "%(senderName)s augšupielādēja failu", + "Disinvite this user?": "Atcelt ielūgumu šim lietotājam?", + "Kick this user?": "Padzīt šo lietotāju?", + "Unban this user?": "Atbloķēt šo lietotāju (atcelt liegumu šim lietotājam)?", + "Ban this user?": "Bloķēt šo lietotāju (uzlikt liegumu šim lietotājam)?", + "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Jūs nevarēsiet atcelt šīs izmaiņas pēc sava statusa pazemināšanas. Gadījumā, ja esat pēdējais priviliģētais lietotājs istabā, būs neiespējami atgūt šīs privilēģijas.", + "Unignore": "Atcelt ignorēšanu", + "Ignore": "Ignorēt", + "Jump to read receipt": "Pāriet uz izlasīšanas apstiprinājumu", + "Mention": "Atsauce (pieminējums)", + "Invite": "Uzaicināt", + "User Options": "Lietotāja uzstādījumi", + "Send an encrypted reply…": "Sūtīt šifrētu atbildi…", + "Send a reply (unencrypted)…": "Sūtīt nešifrētu atbildi…", + "Send an encrypted message…": "Sūtīt šifrētu ziņu…", + "Send a message (unencrypted)…": "Sūtīt NEšifrētu ziņu…", + "Jump to message": "Pāriet uz ziņu", + "No pinned messages.": "Nav piestiprinātu ziņu.", + "Loading...": "Ielāde...", + "Pinned Messages": "Piestiprinātās ziņas", + "%(duration)ss": "%(duration)s sek", + "%(duration)sm": "%(duration)smin", + "%(duration)sh": "%(duration)sstundas", + "%(duration)sd": "%(duration)sdienas", + "Online for %(duration)s": "Pieslēgumā %(duration)s", + "Idle for %(duration)s": "Dīkstāvē (neaktīvs) %(duration)s", + "Offline for %(duration)s": "Atslēgumā %(duration)s", + "Unknown for %(duration)s": "Neskaidrā statusā %(duration)s", + "Unknown": "Neskaidrs statuss", + "Replying": "Atbildot uz", + "No rooms to show": "Nav istabu, kuras parādīt", + "World readable": "Pieejams ikvienam no visurienes", + "Remove avatar": "Dzēst avataru", + "Drop here to favourite": "Nomest šeit (atvilt uz šejieni), lai iekļautu izlasē (favorītos)", + "Drop here to tag direct chat": "Nomest šeit, lai pievienotu atzīmi \"Tiešais čats\"", + "Drop here to restore": "Nomest šeit, lai atgrieztu", + "Drop here to demote": "Nomest šeit, lai pazeminātu", + "Failed to remove tag %(tagName)s from room": "Neizdevās istabai noņemt birku %(tagName)s", + "Failed to add tag %(tagName)s to room": "Neizdevās istabai pievienot birku %(tagName)s", + "Community Invites": "Uzaicinājums uz komūnu", + "You have been kicked from this room by %(userName)s.": "%(userName)s padzina Tevi no šīs istabas.", + "You have been banned from this room by %(userName)s.": "%(userName)s nobloķēja Tevi (liedza piekļuvi) šajā istabā.", + "You are trying to access a room.": "Tu centies gūt piekļuvi istabai.", + "To change the room's avatar, you must be a": "Lai izmainītu istabas avatāru, Tev jābūt", + "To change the room's name, you must be a": "Lai izmainītu istabas nosaukumu, Tev jābūt", + "To change the room's main address, you must be a": "Lai izmainītu istabas pamatadresi, Tev jābūt", + "To change the room's history visibility, you must be a": "Lai izmainītu istabas vēstures redzamību, Tev jābūt", + "To change the permissions in the room, you must be a": "Lai istabā izmainītu atļaujas, Tev jābūt", + "To change the topic, you must be a": "Lai izmainītu tematu, Tev jābūt", + "To modify widgets in the room, you must be a": "Lai istabā izmainītu vidžetus, Tev jābūt", + "Banned by %(displayName)s": "Nobloķējis (liedzis piekļuvi) %(displayName)s", + "Members only (since the point in time of selecting this option)": "Tikai biedri (no šī parametra iestatīšanas brīža)", + "Members only (since they were invited)": "Tikai biedri (no to uzaicināšanas brīža)", + "Members only (since they joined)": "Tikai biedri (kopš pievienošanās)", + "To send messages, you must be a": "Lai sūtītu ziņas, Tev jābūt", + "To invite users into the room, you must be a": "Lai aicinātu istabā lietotājus, ir jābūt", + "To configure the room, you must be a": "Lai konfigurētu istabu, ir jābūt", + "To kick users, you must be a": "Lai padzītu lietotājus, ir jābūt", + "To ban users, you must be a": "Lai bloķētu (liegtu pieeju) lietotājiem, ir jābūt", + "To remove other users' messages, you must be a": "Lai dzēstu citu lietotāju ziņas, ir jābūt", + "To send events of type , you must be a": "Lai sūtītu tipa notikumus, ir jābūt", + "Addresses": "Adreses", + "Invalid community ID": "Nederīgs komūnas ID", + "'%(groupId)s' is not a valid community ID": "'%(groupId)s' nav derīgs komūnas ID", + "Flair": "Gaidas (nojauta)", + "Showing flair for these communities:": "Parādīt Tavas gaidas šajās komūnās:", + "This room is not showing flair for any communities": "Šajā istabā neparādās gaidas, kas uzstādītas komūnās", + "New community ID (e.g. +foo:%(localDomain)s)": "Jaunās komūnas ID (piem. +foo:%(localDomain)s)", + "URL previews are enabled by default for participants in this room.": "URL adrešu priekšskats šīs istabas dalībniekiem ir iespējots pēc noklusējuma.", + "URL previews are disabled by default for participants in this room.": "ULR adrešu priešskats šīs istabas dalībniekiem pēc noklusējuma ir atspējots.", + "Copied!": "Nokopēts!", + "Failed to copy": "Nokopēt neizdevās", + "Message removed by %(userId)s": "Ziņu dzēsis %(userId)s", + "Message removed": "Ziņa dzēsta", + "An email has been sent to %(emailAddress)s": "Vēstule tika nosūtīta uz %(emailAddress)s", + "A text message has been sent to %(msisdn)s": "Teksta ziņa tika nosūtīts uz %(msisdn)s", + "Username on %(hs)s": "Lietotājvārds uz %(hs)s", + "Remove from community": "Izdzēst no komūnas", + "Disinvite this user from community?": "Atcelt šim lietotājam nosūtīto uzaicinājumu pievienoties komūnai?", + "Remove this user from community?": "Izdzēst šo lietotāju no kopienas?", + "Failed to withdraw invitation": "Neizdevās atcelt uzaicinājumu", + "Failed to remove user from community": "Neizdevās izdzēst lietotāju no kopienas", + "Filter community members": "Kopienas biedru filtrs", + "Flair will appear if enabled in room settings": "Gaidas parādīsies, ja tās iespējotas istabas iestatījumos", + "Flair will not appear": "Gaidas neparādīsies", + "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Vai tiešām vēlies izdzēst '%(roomName)s' no %(groupId)s?", + "Removing a room from the community will also remove it from the community page.": "Dzēšot istabu no kopienas tā tiks dzēsta arī no kopienas lapas.", + "Failed to remove room from community": "Neizdevās dzēst istabu no kopienas", + "Failed to remove '%(roomName)s' from %(groupId)s": "Neizdevās dzēst '%(roomName)s' no %(groupId)s", + "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "Istabas '%(roomName)s' redzamību %(groupId)s nebija iespējams atjaunot.", + "Visibility in Room List": "Redzamība istabu sarakstā", + "Visible to everyone": "Redzama visiem", + "Only visible to community members": "Tikai komūnas dalībniekiem", + "Filter community rooms": "Kopienas istabu filtrs", + "Something went wrong when trying to get your communities.": "Kaut kas nogāja greizi, kad tika mēģināts attēlot Tavas kopienas.", + "Display your community flair in rooms configured to show it.": "Parādīt Tavas gaidas istabās, kurās to parādīšana iespējota.", + "You're not currently a member of any communities.": "Pašreiz Tu neesi neesi nevienas komūnas piederīgais.", + "Delete Widget": "Dzēst vidžetu", + "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Vidžeta dzēšana to dzēš visiem šīs istabas lietotājiem. Vai tiešām vēlies dzēst šo vidžetu?", + "Minimize apps": "Minimizēt lietotājprogrammas", + "Communities": "Kopienas", + "%(nameList)s %(transitionList)s": "%(nameList)s %(transitionList)s", + "%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)spievienojās %(count)s reizes", + "%(severalUsers)sjoined %(count)s times|one": "%(severalUsers)spievienojās", + "%(oneUser)sjoined %(count)s times|other": "%(oneUser)spievienojās %(count)s reizes", + "%(oneUser)sjoined %(count)s times|one": "%(oneUser)s pievienojās", + "%(severalUsers)sleft %(count)s times|other": "%(severalUsers)s izgāja %(count)s reizes", + "%(severalUsers)sleft %(count)s times|one": "%(severalUsers)s izgāja (atvienojās)", + "%(oneUser)sleft %(count)s times|other": "%(oneUser)s izgāja (atvienojās) %(count)s reizes", + "%(oneUser)sleft %(count)s times|one": "%(oneUser)s izgāja", + "%(severalUsers)sjoined and left %(count)s times|other": "%(severalUsers)s pievienojās un izgāja %(count)s reizes", + "%(severalUsers)sjoined and left %(count)s times|one": "%(severalUsers)s pievienojās un izgāja", + "%(oneUser)sjoined and left %(count)s times|other": "%(oneUser)s pievienojās un izgāja %(count)s reizes", + "%(oneUser)sjoined and left %(count)s times|one": "%(oneUser)s pievienojās un izgāja", + "%(severalUsers)sleft and rejoined %(count)s times|other": "%(severalUsers)s izgāja un atkalpievienojās %(count)s reizes", + "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)s noraidīja uzaicinājumus %(count)s reizes", + "%(severalUsers)shad their invitations withdrawn %(count)s times|other": "%(severalUsers)s atsauca izsniegtos uzaicinājumus %(count)s reizes", + "were banned %(count)s times|other": "tika bloķēti (liegta piekļuve) %(count)s reizes", + "was banned %(count)s times|other": "tika bloķēts (liegta piekļuve) %(count)s reizes", + "were unbanned %(count)s times|other": "tika atbloķēti (atgriezta pieeja) %(count)s reizes", + "were kicked %(count)s times|other": "tika padzīti %(count)s reizes", + "collapse": "sakļaut", + "expand": "izvērst", + "Custom of %(powerLevel)s": "Lietotāja līmenis %(powerLevel)s", + "In reply to ": "Atbildē uz ", + "And %(count)s more...|other": "Un par %(count)s vairāk...", + "Matrix ID": "Matrix ID", + "Matrix Room ID": "Matrix istabas ID", + "email address": "e-pasta adrese", + "Try using one of the following valid address types: %(validTypesList)s.": "Mēģiniet izmantot vienu no sekojošiem pieļautajiem adrešu tipiem: %(validTypesList)s.", + "You have entered an invalid address.": "Ievadīta nederīga adrese.", + "Community IDs cannot not be empty.": "Kopienas IDs nevar būt tukšs.", + "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "Kopienas IDs var saturēt tikai simbolus a-z, 0-9, or '=_-./'", + "Something went wrong whilst creating your community": "Radot Tavu kopienu kaut kas nogāja greizi", + "Create Community": "Radīt kopienu", + "Community Name": "Kopienas nosaukums", + "Community ID": "Kopienas ID", + "example": "piemērs" } From 97ce84c8e36eaf20c0306242a4700c03e9419ef6 Mon Sep 17 00:00:00 2001 From: Aidan Gauland Date: Sun, 11 Feb 2018 16:14:17 +1300 Subject: [PATCH 0290/1160] Add display name to the read receipt view Show the user's display name (aka nick) in the ReadReceiptMarker title (mouseover text), and then the user ID in parentheses. --- src/components/views/rooms/ReadReceiptMarker.js | 6 ++++-- src/i18n/strings/en_EN.json | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/views/rooms/ReadReceiptMarker.js b/src/components/views/rooms/ReadReceiptMarker.js index 5dd62ff6b7..d5436efc76 100644 --- a/src/components/views/rooms/ReadReceiptMarker.js +++ b/src/components/views/rooms/ReadReceiptMarker.js @@ -186,8 +186,10 @@ module.exports = React.createClass({ let title; if (this.props.timestamp) { title = _t( - "Seen by %(userName)s at %(dateTime)s", - {userName: this.props.member.userId, dateTime: formatDate(new Date(this.props.timestamp), this.props.showTwelveHour)}, + "Seen by %(displayName)s (%(userName)s) at %(dateTime)s", + {displayName: this.props.member.name, + userName: this.props.member.userId, + dateTime: formatDate(new Date(this.props.timestamp), this.props.showTwelveHour)}, ); } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 6139ac2a91..2be4bf2e48 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -360,7 +360,7 @@ "Offline": "Offline", "Unknown": "Unknown", "Replying": "Replying", - "Seen by %(userName)s at %(dateTime)s": "Seen by %(userName)s at %(dateTime)s", + "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Seen by %(displayName)s (%(userName)s) at %(dateTime)s", "No rooms to show": "No rooms to show", "Unnamed room": "Unnamed room", "World readable": "World readable", From 0fd9b3e9b2d89965bb3966839d8f55700e17e7b9 Mon Sep 17 00:00:00 2001 From: Aidan Gauland Date: Sun, 11 Feb 2018 16:27:07 +1300 Subject: [PATCH 0291/1160] Avoid doubling up username in read receipt view In the ReadReceiptMarker title, use the RoomMember.rawDisplayName because RoomMember.name may already include the username, which we are going to add ourselves. --- src/components/views/rooms/ReadReceiptMarker.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/rooms/ReadReceiptMarker.js b/src/components/views/rooms/ReadReceiptMarker.js index d5436efc76..8dc3c0f7d0 100644 --- a/src/components/views/rooms/ReadReceiptMarker.js +++ b/src/components/views/rooms/ReadReceiptMarker.js @@ -187,7 +187,7 @@ module.exports = React.createClass({ if (this.props.timestamp) { title = _t( "Seen by %(displayName)s (%(userName)s) at %(dateTime)s", - {displayName: this.props.member.name, + {displayName: this.props.member.rawDisplayName, userName: this.props.member.userId, dateTime: formatDate(new Date(this.props.timestamp), this.props.showTwelveHour)}, ); From aeedf48d841b89ab75736d4b3cd4f5e65ea0822e Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 11 Feb 2018 11:45:13 +0000 Subject: [PATCH 0292/1160] fix weird `in` op behaviour with null Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Reply.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/elements/Reply.js b/src/components/views/elements/Reply.js index 31e94e1d4a..944d90cdbd 100644 --- a/src/components/views/elements/Reply.js +++ b/src/components/views/elements/Reply.js @@ -137,9 +137,9 @@ export default class Reply extends React.Component { if (ev.isRedacted()) return; const mRelatesTo = ev.getWireContent()['m.relates_to']; - if (mRelatesTo) { + if (mRelatesTo && mRelatesTo['m.in_reply_to']) { const mInReplyTo = mRelatesTo['m.in_reply_to']; - if ('event_id' in mInReplyTo) return mInReplyTo; + if (mInReplyTo['event_id']) return mInReplyTo; } } From 0f5dc5a7e4fa9eff05d59732389085e504225d67 Mon Sep 17 00:00:00 2001 From: Oskars Date: Mon, 12 Feb 2018 00:54:12 +0000 Subject: [PATCH 0293/1160] Translated using Weblate (Latvian) Currently translated at 96.5% (952 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/lv/ --- src/i18n/strings/lv.json | 177 ++++++++++++++++++++++++++------------- 1 file changed, 119 insertions(+), 58 deletions(-) diff --git a/src/i18n/strings/lv.json b/src/i18n/strings/lv.json index 50416f0318..b888050e29 100644 --- a/src/i18n/strings/lv.json +++ b/src/i18n/strings/lv.json @@ -4,19 +4,19 @@ "%(targetName)s accepted an invitation.": "%(targetName)s apstiprināja uzaicinājumu.", "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s apstiprināja uzaicinājumu no %(displayName)s.", "Account": "Konts", - "Access Token:": "Pieejas atslēga:", + "Access Token:": "Pieejas tokens:", "Active call (%(roomName)s)": "Aktīvs zvans (%(roomName)s)", "Add": "Pievienot", "Add a topic": "Pievieno tematu", - "Add email address": "Pievieno Epasta adresi", + "Add email address": "Pievieno epasta adresi", "Add phone number": "Pievieno tālruņa numuru", "Admin": "Administrators", "Admin Tools": "Administratora rīki", "VoIP": "VoIP", - "Missing Media Permissions, click here to request.": "Nav pieejas medija saturam. Klikšķini šeit, lai pieprasītu.", - "No Microphones detected": "Mikrofoni nav atrasti", - "No Webcams detected": "Webkameras nav atrastas", - "No media permissions": "Nav pieejas mediju saturam", + "Missing Media Permissions, click here to request.": "Nav atļauju piekļūt ierīcei. Klikšķini šeit, lai tās pieprasītu.", + "No Microphones detected": "Nav mikrofonu", + "No Webcams detected": "Nav webkameru", + "No media permissions": "Nav datu nesēju, kuriem atļauta piekļuve", "You may need to manually permit Riot to access your microphone/webcam": "Tev varētu būt nepieciešams manuāli atļaut Riot pieslēgties tavam mikrofonam/webkamerai", "Default Device": "Noklusējuma ierīce", "Microphone": "Mikrofons", @@ -44,14 +44,14 @@ "%(senderName)s banned %(targetName)s.": "%(senderName)s liedza pieeju %(targetName)s.", "Ban": "Liegt pieeju (Bans)", "Banned users": "Lietotāji, kuriem ir liegta pieeja (banotie)", - "Bans user with given id": "Liedz pieeju lietotājam pēc uzdotā ID (Bans)", + "Bans user with given id": "Bloķē (liedz pieeju) lietotāju pēc uzdotā ID (nobano)", "Blacklisted": "Melnajā sarakstā iekļautie", "Bug Report": "Paziņojums par kļūdu", - "Bulk Options": "Lielapjoma darbības", + "Bulk Options": "Grupveida darbību parametri", "Call Timeout": "Zvana gaidīšanas noilgums", - "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Neizdevās savienoties ar serveri. Lūdzu pārbaudi savu tīkla savienējumu un pārliecinies, ka tava servera SSL sertifikāts ir uzticams, kā arī pārlūkā instalētie paplašinājumi nebloķē pieprasījumus.", - "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Neizdevās savienoties ar serveri izmantojot HTTP protokolu, kad tava pārlūka adreses laukā ir HTTPS saite. Tā vietā izmanto HTTPS savienojumu vai iespējo nedrošos skriptus.", - "Can't load user settings": "Neizdevās ielādēt lietotāja uzstādījumus", + "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Neizdodas savienoties ar bāzes serveri. Pārbaudi tīkla savienojumu un pārliecinies, ka bāzes servera SSL sertifikāts ir uzticams, kā arī pārlūkā instalētie paplašinājumi nebloķē pieprasījumus.", + "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Neizdodas savienoties ar bāzes serveri izmantojot HTTP protokolu, kad Tava pārlūka adreses laukā norādīts HTTPS protokols. Tā vietā izmanto HTTPS vai iespējo nedrošos skriptus.", + "Can't load user settings": "Neizdevās ielādēt lietotāja iestatījumus", "Change Password": "Paroles maiņa", "%(senderName)s changed their profile picture.": "%(senderName)s nomainīja profila attēlu.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s nomainīja statusa līmeni %(powerLevelDiffText)s.", @@ -59,18 +59,18 @@ "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s dzēsa istabas nosaukumu.", "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s nomainīja tēmas nosaukumu uz \"%(topic)s\".", "Changes to who can read history will only apply to future messages in this room": "Izmaiņas attiecībā uz to, kurš varēs lasīt vēstures ziņas, stāsies spēkā tikai uz ziņām,kuras vēl tiks pievienotas šajā istabā", - "Changes your display nickname": "Nomaina tavu publisko segvārdu (niku)", + "Changes your display nickname": "Nomaina Tavu publisko segvārdu (niku)", "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Paroles maiņa dzēsīs pašreizējās šifrēšanas atslēgas visās savstarpēji saistītajās ierīcēs, padarot čata vēsturi neizlasāmu, ja vien vien istabas atslēgas nav tikušas iepriekš eksportētas un no jauna importētas atpakaļ. Nākotnē to plānojam uzlabot.", - "Claimed Ed25519 fingerprint key": "Norādīta Ed25519 identificējošās zīmju virknes atslēga", + "Claimed Ed25519 fingerprint key": "Ed25519 pieprasītā nospieduma (fingerprint) atslēga", "Clear Cache and Reload": "Iztīri kešatmiņu un pārlādē", "Clear Cache": "Iztīri kešatmiņu", "Click here to join the discussion!": "Klikšķini šeit lai pievienotos diskusijai!", "Click here to fix": "Klikšķini šeit, lai izlabotu", - "Click to mute audio": "Klikšķini, lai izslēgtu skaņu", - "Click to mute video": "Klikšķini, lai izslēgtu video skaņu", - "click to reveal": "Klikšķini, lai atvērtu", - "Click to unmute video": "Klikšķini, lai ieslēgtu video skaņu", - "Click to unmute audio": "Klikšķini, lai ieslēgtu audio skaņu", + "Click to mute audio": "Klikšķini, lai audio skaņu izslēgtu", + "Click to mute video": "Klikšķini, lai video skaņu izslēgtu", + "click to reveal": "Klikšķini, lai atsegtu", + "Click to unmute video": "Klikšķini, lai video skaņu ieslēgtu", + "Click to unmute audio": "Klikšķini, lai audio skaņu ieslēgtu", "Close": "Aizvērt", "Command error": "Komandas kļūda", "Commands": "Komandas", @@ -93,13 +93,13 @@ "Custom": "Pielāgots", "Custom level": "Īpašais līmenis", "/ddg is not a command": "/ddg nav komanda", - "Deactivate Account": "Deaktivizēt kontu", - "Deactivate my account": "Deaktivizēt manu kontu", + "Deactivate Account": "Deaktivēt kontu", + "Deactivate my account": "Deaktivēt manu kontu", "Decline": "Noraidīt", "Decrypt %(text)s": "Atšifrēt %(text)s", "Decryption error": "Atšifrēšanas kļūda", "Delete": "Dzēst", - "Deops user with given id": "Noņemt operatora statusu lietotājam ar norādīto id", + "Deops user with given id": "Atceļ operatora statusu lietotājam ar norādīto ID", "Default": "Noklusējuma", "Device already verified!": "Ierīce ir jau verificēta!", "Device ID": "Ierīces ID", @@ -111,13 +111,13 @@ "Direct chats": "Tiešie čati", "Disable Notifications": "Atslēgt paziņojumus", "Disinvite": "Atsaukt", - "Display name": "Redzamais vārds", + "Display name": "Attēlojamais vārds", "Displays action": "Parāda darbību", "Don't send typing notifications": "Nesūtīt paziņojumus", "Download %(text)s": "Lejupielādēt tekstu: %(text)s", "Drop File Here": "Ievelc failu šeit", "Drop here to tag %(section)s": "Nomest šeit, lai birkotu %(section)s", - "Ed25519 fingerprint": "Ed25519 identificējošā zīmju virkne", + "Ed25519 fingerprint": "Ed25519 nospiedums (fingerprint), zīmju virkne", "Email": "Epasts", "Email address": "Epasta adrese", "Email address (optional)": "Epasta adrese (neobligāta)", @@ -138,7 +138,7 @@ "Enter passphrase": "Ievadi paroles frāzi", "Error": "Kļūda", "Error decrypting attachment": "Kļūda atšifrējot pielikumu", - "Error: Problem communicating with the given homeserver.": "Kļūda: Radās komunikācijas problēma ar norādīto serveri.", + "Error: Problem communicating with the given homeserver.": "Kļūda: Saziņas problēma ar norādīto bāzes serveri.", "Event information": "Notikuma informācija", "Existing Call": "Pašreizējā saruna (zvans)", "Export": "Eksportēt", @@ -166,7 +166,7 @@ "Failed to set up conference call": "Neizdevās iestatīt konferences zvanu", "Failed to toggle moderator status": "Neizdevās pārslēgt moderatora statusu", "Failed to unban": "Neizdevās atcelt pieejas liegumu (atbanot)", - "Failed to upload file": "Neizdevās augšuplādēt failu", + "Failed to upload file": "Neizdevās augšupielādēt failu", "Failed to upload profile picture!": "Neizdevās augšuplādēt profila attēlu!", "Failed to verify email address: make sure you clicked the link in the email": "Neizdevās apstiprināt epasta adresi. Pārbaudi, vai Tu esi noklikšķinājis/usi saiti epasta ziņā", "Failure to create room": "Neizdevās izveidot istabu", @@ -180,14 +180,14 @@ "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Drošības nolūkos, izrakstīšanās dzēsīs jebkādas ierīce-ierīce šifrēšanas atslēgas no šī pārlūka. Ja Tu vēlies saglabāt iespēju atšifrēt tavu saziņas vēsturi no Riot nākotnes sesijām, lūdzu eksportē tavas istabas atslēgas, saglabājot tās drošā vietā.", "Found a bug?": "Pamanīji kļūdu?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s no %(fromPowerLevel)s uz %(toPowerLevel)s", - "Guest access is disabled on this Home Server.": "Šajā serverī viesu pierakstīšanās nav iespējama.", + "Guest access is disabled on this Home Server.": "Šajā bāzes serverī viesu pierakstīšanās nav iespējama.", "Guests cannot join this room even if explicitly invited.": "Viesi nevar pievienoties šai istabai pat ja ir uzaicināti.", "Hangup": "Aizturēt", "Hide read receipts": "Slēpt izlasītās receptes", "Hide Text Formatting Toolbar": "Slēpt teksta formatēšanas rīkjoslu", "Historical": "Vēsturiskais", "Home": "Mājup", - "Homeserver is": "Serveris ir", + "Homeserver is": "Bāzes serveris ir", "Identity Server is": "Indentifikācijas serveris ir", "I have verified my email address": "Mana epasta adrese ir verificēta", "Import": "Importēt", @@ -214,11 +214,11 @@ "Join as voice or video.": "Pievienoties kā balss vai video.", "Join Room": "Pievienoties istabai", "%(targetName)s joined the room.": "%(targetName)s pievienojās istabai.", - "Joins room with given alias": "Pievieno istabai ar uzdoto aizstājējvārdu", + "Joins room with given alias": "Pievienojas istabai ar minēto aliasi (pseidonīmu)", "Jump to first unread message.": "Pāriet uz pirmo neizlasīto ziņu.", "%(senderName)s kicked %(targetName)s.": "%(senderName)s iespēra (kick) %(targetName)s.", "Kick": "Iespert (kick)", - "Kicks user with given id": "Iesper (kick) lietotājam pēc norādītā id", + "Kicks user with given id": "Padzen (kick) lietotāju ar norādīto ID", "Labs": "Laboratorija", "Last seen": "Pēdējo reizi redzēts/a", "Leave room": "Pamest istabu", @@ -226,7 +226,7 @@ "Level:": "Līmenis:", "Local addresses for this room:": "Šīs istabas lokālās adreses:", "Logged in as:": "Pierakstījās kā:", - "Login as guest": "Pierakstīties kā viesis", + "Login as guest": "Pierakstīties kā viesim", "Logout": "Izrakstīties", "Low priority": "Zema prioritāte", "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s uzstādīja nākotnes istabas ziņu vēsturi redzamu visi istabas biedri secībā, kādā tika uzaicināti.", @@ -257,7 +257,7 @@ "New password": "Jauna parole", "New passwords don't match": "Jaunās paroles nesakrīt", "New passwords must match each other.": "Jaunajām parolēm ir jāsakrīt vienai ar otru.", - "none": "nekāds", + "none": "neviens", "not set": "nav iestatījuma", "not specified": "nav noteikts", "Notifications": "Paziņojumi", @@ -292,7 +292,7 @@ "Reason": "Iemesls", "Reason: %(reasonText)s": "Iemesls: %(reasonText)s", "Revoke Moderator": "Atcelt moderatoru", - "Refer a friend to Riot:": "Nosūtīt draugu uz Riot:", + "Refer a friend to Riot:": "Rekomendēt draugam Riot:", "Register": "Reģistrēties", "%(targetName)s rejected the invitation.": "%(targetName)s noraidīja uzaicinājumu.", "Reject invitation": "Noraidīt uzaicinājumu", @@ -370,14 +370,14 @@ "Scroll to unread messages": "Aizritināt uz nelasītajām ziņām", "Search": "Meklēt", "Search failed": "Meklēšana neizdevās", - "Searches DuckDuckGo for results": "Meklē DuckDuckGo rezultātus", + "Searches DuckDuckGo for results": "Meklēšanai izmanto DuckDuckGo", "Send anyway": "Nosūtīt jebkurā gadījumā", "Sender device information": "Nosūtītāja ierīces informācija", "Send Invites": "Nosūtīt uzaicinājumus", "Send Reset Email": "Nosūtīt atiestatīšanas epastu", "Server error": "Servera kļūda", "Server may be unavailable or overloaded": "Serveris var nebūt pieejams vai ir pārslogots", - "Server may be unavailable, overloaded, or search timed out :(": "Serveris var nebūt pieejams, ir pārslogots, vai arī meklēšana beidzās ar savienojuma noilgumu :(", + "Server may be unavailable, overloaded, or search timed out :(": "Serveris izskatās nepieejams, ir pārslogots, vai arī meklēšana beidzās ar savienojuma noildzi :(", "Server may be unavailable, overloaded, or the file too big": "Serveris var nebūt pieejams, ir pārslogots, vai arī faila izmērs ir par lielu", "Server may be unavailable, overloaded, or you hit a bug.": "Serveris var nebūt pieejams, ir pārslogots, vai arī sastapi neparedzētu kļūdu.", "Server unavailable, overloaded, or something else went wrong.": "Serveris nav pieejams, ir pārslogots, vai arī ir notikusi cita, neparedzēta, kļūda.", @@ -395,19 +395,19 @@ "Start authentication": "Sākt autentifikāciju", "Start Chat": "Sākt čatu", "Submit": "Iesniegt", - "Success": "Veiksmīgi", + "Success": "Izdevās", "Tagged as: ": "Atzīmēts,kā: ", "The main address for this room is": "Galvenā šīs istabas adrese ir", "The phone number entered looks invalid": "Ievadītais telefona numurs izskatās nepareizs", "This email address is already in use": "Šī epasta adrese jau tiek izmantota", "This email address was not found": "Šāda epasta adrese nav atrasta", - "The email address linked to your account must be entered.": "Ir jāievada tavam kontam piesaistītā epasta adrese.", + "The email address linked to your account must be entered.": "Ir jāievada Tavam kontam piesaistītā epasta adrese.", "The remote side failed to pick up": "Zvana adresāts neatbild", - "This Home Server does not support login using email address.": "Šis serveris neatbalsta pierakstīšanos ar epasta adresi.", + "This Home Server does not support login using email address.": "Šis bāzes serveris neatbalsta pierakstīšanos ar epasta adresi.", "This invitation was sent to an email address which is not associated with this account:": "Šis uzaicinājums tika nosūtīts uz epasta adresi, kura nav piesaistīta šim kontam:", "This room has no local addresses": "Šai istabai nav lokālo adrešu", "This room is not recognised.": "Šī istaba netika atpazīta.", - "These are experimental features that may break in unexpected ways": "Šīs ir eksperimentālās iespējas, kuras var būt dažādos veidos nestrādājošas", + "These are experimental features that may break in unexpected ways": "Šīs ir eksperimentālas funkcijas, kuras reizēm var novest pie negaidītiem rezultātiem", "The visibility of existing history will be unchanged": "Esošās ziņu vēstures redzamība paliks nemainīga", "This doesn't appear to be a valid email address": "Šī neizskatās pēc derīgas epasta adreses", "This is a preview of this room. Room interactions have been disabled": "Šis ir esošās istabas priekšskatījums. Istabas mijiedarbība ir atspējota", @@ -416,10 +416,10 @@ "This room is not accessible by remote Matrix servers": "Šī istaba nav pieejama no attālinātajiem Matrix serveriem", "This room's internal ID is": "Šīs istabas iekšējais ID ir", "To link to a room it must have an address.": "Lai ieliktu saiti uz istabu, tai ir jābūt piešķirtai adresei.", - "To reset your password, enter the email address linked to your account": "Lai atiestatītu savu paroli, ievadi tavam kontam piesaistīto epasta adresi", + "To reset your password, enter the email address linked to your account": "Lai atiestatītu savu paroli, ievadi savam kontam piesaistīto epasta adresi", "To use it, just wait for autocomplete results to load and tab through them.": "Lai to izmantotu, vienkārši gaidi, kamēr ielādējas automātiski ieteiktie rezultāti, un pārvietojies caur tiem.", "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Notika mēģinājums ielādēt šīs istabas specifisku laikpaziņojumu sadaļu, bet Tev nav atļaujas skatīt šo ziņu.", - "Tried to load a specific point in this room's timeline, but was unable to find it.": "Notika mēģinājums ielādēt šīs istabas specifisku laikpaziņojumu sadaļu, bet tā netika atrasta.", + "Tried to load a specific point in this room's timeline, but was unable to find it.": "Mēģinājums ielādēt šīs istabas čata vēstures izvēlēto posmu neizdevās, jo tas netika atrasts.", "Unable to add email address": "Nav iespējams pievienot epasta adresi", "Unable to remove contact information": "Nav iespējams dzēst kontaktinformāciju", "Unable to verify email address.": "Nav iespējams apstiprināt epasta adresi.", @@ -518,10 +518,10 @@ "Oct": "Okt.", "Nov": "Nov.", "Dec": "Dec.", - "Set a display name:": "Iestatīt redzamo vārdu:", + "Set a display name:": "Iestatīt attēloto vārdu:", "This image cannot be displayed.": "Šo attēlu nav iespējams parādīt.", "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s nomainīja istabas attēlu uz ", - "Upload an avatar:": "Augšuplādē profila attēlu:", + "Upload an avatar:": "Augšuplādē avataru (profila attēlu):", "This server does not support authentication with a phone number.": "Šis serveris neatbalsta autentifikāciju pēc telefona numura.", "Missing password.": "Trūkst parole.", "Passwords don't match.": "Paroles nesakrīt.", @@ -530,14 +530,14 @@ "User names may only contain letters, numbers, dots, hyphens and underscores.": "Lietotājvārdi drīkst saturēt vienīgi alfabēta burtus, skaitļus, punktus, defises un apakšsvītras.", "An unknown error occurred.": "Notikusi neparedzēta kļūda.", "I already have an account": "Man jau ir konts", - "Topic": "Tēma", + "Topic": "Temats", "Make Moderator": "Piešķirt moderatora statusu", "Make this room private": "Padarīt šo istabu privātu", "Share message history with new users": "Kopīgot ziņu vēsturi ar jauniem lietotājiem", "Encrypt room": "Šifrēt istabu", "There are no visible files in this room": "Nav redzamu failu šajā istabā", "Room": "Istaba", - "Connectivity to the server has been lost.": "Savienojums ar serveri tika zaudēts.", + "Connectivity to the server has been lost.": "Savienojums ar serveri pārtrūka.", "Sent messages will be stored until your connection has returned.": "Nosūtītās ziņas tiks saglabātas tiklīdz savienojums tiks atjaunots.", "Active call": "Aktīvs zvans", "bold": "trekns", @@ -552,8 +552,8 @@ "Room directory": "Istabu katalogs", "Start chat": "Uzsākt čalošanu", "New Password": "Jauna parole", - "Start automatically after system login": "Uzsākt automātiski pēc pierakstīšanās sistēmā", - "Desktop specific": "Darbvirsmai specifiski", + "Start automatically after system login": "Palaist programmu automātiski pie sistēmas ielādes", + "Desktop specific": "Darbvirsmai specifiskie", "Analytics": "Analītika", "Opt out of analytics": "Atteikties no analītikas", "Options": "Iespējas", @@ -564,9 +564,9 @@ "Confirm passphrase": "Apstiprināt paroles frāzi", "Import room keys": "Importēt istabas atslēgas", "File to import": "Importējamais fails", - "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Šī darbība atļauj Tev eksportēt lokālā failā atslēgas tām ziņām, kuras Tu saņēmi šifrētās istabās. Pēc tam nākotnē Tu varēsi importēt šo failu citā Matrix klienta aplikācijā, lai tajā būtu iespējams atšifrēt šīs ziņas.", - "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Eksportētais fails atļaus ikvienam, kurš to ir nolasījis, atšifrēt jebkuras tev redzamās šifrētās ziņas, tāpēc ievēro piesardzību, un glabā šo failu drošā vietā. Lai palīdzētu to nodrošināt, Tev ir jāievada paroles frāze, kura tiks izmantota eksportēto datu šifrēšanai. Datu importēšana būs iespējama tikai izmantojot šo pašu paroles frāzi.", - "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Šis process ļauj Tev importēt tās šifrēšanas atslēgas, kuras Tu iepriekš eksportēji no citas Matrix klienta aplikācijas. Importētās atslēgas ļaus vajadzīgajā klienta aplikācijā lasīt atšifrētās ziņas.", + "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Šī darbība ļauj Tev uz lokālo failu eksportēt atslēgas priekš tām ziņām, kuras Tu saņēmi šifrētās istabās. Tu varēsi importēt šo failu citā Matrix klientā, lai tajā būtu iespējams lasīt šīs ziņas atšifrētas.", + "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Eksportētais fails ļaus ikvienam, kurš to spēj lasīt, atšifrēt jebkuras Tavas šifrētās ziņas, tāpēc ievēro piesardzību, un glabā šo failu drošā vietā. Lai palīdzētu to nodrošināt, Tev jāievada paroles frāze, kura tiks izmantota eksportēto datu šifrēšanai. Datu importēšana būs iespējama tikai izmantojot šo pašu paroles frāzi.", + "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Šis process ļaus Tev importēt šifrēšanas atslēgas, kuras Tu iepriekš eksportēji no cita Matrix klienta. Tas ļaus Tev atšifrēt čata vēsturi.", "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Eksporta fails būs aizsargāts ar paroles frāzi. Tā ir jāievada šeit, lai atšifrētu failu.", "You must join the room to see its files": "Tev ir jāpievienojas istabai, lai redzētu tās failus", "Start new chat": "Uzsākt jaunu čalu", @@ -586,7 +586,7 @@ "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Ja tā sakrīt, tad nospied zemāk esošo verifikācijas pogu . Ja nesakrīt, tad kāds cits ir piekļuvis šai ierīcei un šādā gadījumā Tu, iespējams, vēlies izmantot \"melnais saraksts\" iespēju.", "Verify device": "Verificēt ierīci", "I verify that the keys match": "Es pārbaudu, vai atslēgas sakrīt", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Mēs sastapāmies ar kļūdu, mēģinot atjaunot tavu iepriekšējo sesiju. Ja vēlies turpināt, tev ir jāpierakstās par jaunu un šifrēta čata ziņu vēsture nebūs izlasāma.", + "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Atgadījās kļūda, mēģinot atjaunot tavu iepriekšējo sesiju. Ja vēlies turpināt, Tev ir jāpierakstās no jauna, taču šifrētā čata ziņu vēsture nebūs izlasāma.", "Unable to restore session": "Nav iespējams atjaunot sesiju", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Ja Tu iepriekš izmantoji jaunāku Riot versiju, tava sesija var nebūt saderīga ar šo versiju. Aizver šo logu un atgriezies jaunākajā versijā.", "Continue anyway": "Turpināt jebkurā gadījumā", @@ -624,8 +624,8 @@ "Online": "Tiešsaistē (pieslēgumā)", "Idle": "Dīkstāve", "Offline": "Atsaistē (ārpus tīkla)", - "Updates": "Atjauninājumi", - "Check for update": "Pārbaudīt, vai ir atjauninājumi", + "Updates": "Aktualizācijas", + "Check for update": "Pārbaudīt, vai ir aktualizācijas", "Start chatting": "Sākt čalošanu", "Start Chatting": "Sākt čalošanu", "Click on the button below to start chatting!": "Klikšķini uz zemāk esošās pogas, lai uzsāktu čalošanu!", @@ -651,7 +651,7 @@ "Cannot add any more widgets": "Nav iespējams pievienot vairāk vidžetu", "Changes colour scheme of current room": "Nomaina pašreizējās istabas krāsu paleti", "Delete widget": "Dzēst widžetu", - "Define the power level of a user": "Definēt lietotāja pakāpes līmeni", + "Define the power level of a user": "Definē lietotāja statusu", "Do you want to load widget from URL:": "Vai vēlies ielādēt widžetu no URL:", "Edit": "Rediģēt", "Enable automatic language detection for syntax highlighting": "Iespējot automātisko valodas noteikšanu sintakses iezīmējumiem", @@ -662,12 +662,12 @@ "AM": "AM", "PM": "PM", "NOTE: Apps are not end-to-end encrypted": "PIEZĪME: Aplikācijās nav ierīce-ierīce šifrēšanas", - "Sets the room topic": "Uzstāda istabas tēmas nosaukumu", + "Sets the room topic": "Uzstāda istabas tematu", "Show Apps": "Rādīt aplikācijas", "The maximum permitted number of widgets have already been added to this room.": "Atļautais vidžetu skaits jau ir sasniegts šai istabai.", "To get started, please pick a username!": "Lai sāktu, lūdzu izvēlies lietotājvārdu!", "Unable to create widget.": "Nav iespējams izveidot widžetu.", - "Unbans user with given id": "Atceļ pieejas liegumu (atbano) lietotāju pēc norādītā id", + "Unbans user with given id": "Atbloķē (atceļ pieejas liegumu) lietotāju pēc norādītā ID (atbano)", "You are not in this room.": "Tu neatrodies šajā istabā.", "You do not have permission to do that in this room.": "Tev nav atļaujas šai darbībai šajā istabā.", "Verifies a user, device, and pubkey tuple": "Verificē lietotāju, ierīci, un publiskās atslēgas", @@ -685,11 +685,11 @@ "Robot check is currently unavailable on desktop - please use a web browser": "Robotu pārbaude šobrīd nav pieejama darbvirsmas versijā. Lūdzu izmanto web pārlūku", "Revoke widget access": "Atsaukt vidžeta piekļuvi", "Unpin Message": "Atkabināt ziņu", - "Add rooms to this community": "Pievienot istabas šai komūnai", + "Add rooms to this community": "Pievienot istabas šai kopienai", "Failed to set direct chat tag": "Neizdevās tiešajam čatam uzstādīt birku", "Warning": "Brīdinājums", "Send": "Sūtīt", - "Leave": "Pamest", + "Leave": "Atstāt", "Unnamed room": "Nenosaukta istaba", "Guests can join": "Var pievienoties viesi", "The platform you're on": "Izmantotā operētājsistēma", @@ -889,5 +889,66 @@ "Create Community": "Radīt kopienu", "Community Name": "Kopienas nosaukums", "Community ID": "Kopienas ID", - "example": "piemērs" + "example": "piemērs", + "Advanced options": "Papildus parametri", + "Block users on other matrix homeservers from joining this room": "Neļaut lietotājiem no citiem mājasserveriem pievienoties šai istabai", + "This setting cannot be changed later!": "Šo parametru vēlāk izmainīt nebūs iespējams!", + "%(severalUsers)sleft and rejoined %(count)s times|one": "%(severalUsers)s aizgājuši un atgriezušies", + "%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)s aizgājis un atgriezies %(count)s reizes", + "%(oneUser)sleft and rejoined %(count)s times|one": "%(oneUser)s aizgājis un atgriezies", + "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)s nepieņēma uzaicinājumus", + "were invited %(count)s times|one": "tika uzaicināti", + "was invited %(count)s times|other": "tika uzaicināta %(count)s reizes", + "was invited %(count)s times|one": "tika uzaicināts(a)", + "were unbanned %(count)s times|one": "tika atbloķēti (atcelts pieejas liegums)", + "was unbanned %(count)s times|other": "tika atbloķēts %(count)s reizes", + "was banned %(count)s times|one": "tika bloķēts", + "were banned %(count)s times|one": "tika bloķēti", + "was unbanned %(count)s times|one": "tika atbloķēts", + "were kicked %(count)s times|one": "tika padzīti", + "was kicked %(count)s times|other": "tika padzīts %(count)s reizes", + "was kicked %(count)s times|one": "tika padzīts", + "%(severalUsers)schanged their name %(count)s times|other": "%(severalUsers)s izmainīja savu lietotājvārdu %(count)s reizes", + "%(severalUsers)schanged their name %(count)s times|one": "%(severalUsers)s izmainīja savu lietotājvārdu", + "

    HTML for your community's page

    \n

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

    \n

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

    \n": "

    Tavas kopienas lapas HTML

    \n

    \n Izmanto garāku aprakstu, lai iepazīstinātu jaunos lietoājus ar kopienu, \n vai padalies ar kādām attiecināmām web-saitēm\n

    \n

    \n Vari izmantot arī 'img' birkas\n

    \n", + "Add rooms to the community summary": "Pievienot istabas kopienas informatīvajā kopsavilkumā", + "Which rooms would you like to add to this summary?": "Kuras istabas vēlaties pievienot šim kopsavilkumam?", + "Add to summary": "Pievienot kopsavilkumam", + "Failed to add the following rooms to the summary of %(groupId)s:": "Neizdevās sekojošās istabas pievienot %(groupId)s kopsavilkumam:", + "Add a Room": "Pievienot istabu", + "Failed to remove the room from the summary of %(groupId)s": "Neizdevās dzēst istabu no %(groupId)s kopsavilkuma", + "The room '%(roomName)s' could not be removed from the summary.": "Istabu '%(roomName)s' neizdevās dzēst no kopsavilkuma.", + "Leave Community": "Atstāt kopienu", + "Unable to leave room": "Nav iespējams atstāt istabu", + "Community Settings": "Kopienas iestatījumi", + "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Šīs istabas tiek rādītas kopienas dalībniekiem šīs kopienas lapā. Kopienas dalībnieki var pievienoties istabām, uzklikšķinot uz tām.", + "Your community hasn't got a Long Description, a HTML page to show to community members.
    Click here to open settings and give it one!": "Jūsu kopienai nav plašāka HTML-lapas apraksta ko parādīt dalībniekiem.
    Klikšķini šeit, lai atvērtu iestatījumus un to pievienotu!", + "Description": "Apraksts", + "Failed to load %(groupId)s": "Neizdevās ielādēt %(groupId)s", + "This Home server does not support communities": "Šis mitināšanas serveris neatbalsta kopienas", + "This room is not public. You will not be able to rejoin without an invite.": "Šīs istaba nav publiska. Tu nevari tajā ieiet bez uzaicinājuma.", + "Cryptography data migrated": "Sifrēšanas dati tika pārnesti", + "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "Veikta vienreizēja šifrēšanas datu pārnese. Sifrēšana (end-to-end) nedarbosies, ja Tu atgriezīses pie vecākas Riot versijas. Ja nepieciešams izmantot end-to-end šifrēšanu, izmantojot vecāku versija, vispirms izraksties no Riot. Lai saglabātu ziņu vēsturi, eksportē un tad importē savas kripto-atslēgas.", + "Old cryptography data detected": "Tika uzieti novecojuši šifrēšanas dati", + "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Uzieti dati no vecākas Riot versijas. Tas novedīs pie end-to-end šifrēšanas problēmām vecākajā versijā. Šajā versijā nevar tikt atšifrēti ziņojumi, kuri radīti izmantojot vecākajā versijā end-to-end šifrētas ziņas. Tas var arī novest pie ziņapmaiņas, kas veikta ar šo versiju. Ja rodas ķibeles, izraksties un par jaunu pieraksties sistēmā. Lai saglabātu ziņu vēsturi, eksportē un tad importē savas šifrēšanas atslēgas.", + "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Radi kopienu, lai apvienotu lietotājus un istabas. Izveido mājaslapu, lai iezīmētu Matrix visumā savu klātbūtni, vietu un telpu.", + "Error whilst fetching joined communities": "Ielādējot kopienas radās kļūda", + "%(count)s of your messages have not been sent.|one": "Tava ziņa netika nosūtīta.", + "Show devices, send anyway or cancel.": "Parādīt ierīces, vienalga nosūtīt vai sūtīšanu atcelt.", + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Atkārtoti nosūtīt ziņu vai atcelt sūtīšanu.", + "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Šeit neviena nav. Ja vēlies kādu uzaicināt vai atslēgt paziņojumu par tukšu istabu?", + "Light theme": "Gaiša tēma", + "Dark theme": "Tumša tēma", + "Status.im theme": "Status.im tēma", + "Ignored Users": "Ignorētie lietotāji", + "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Privātumu augstu respektējam, tādēļ nevācam nekādus personas un identificējamus datus analītikas mērķiem.", + "Learn more about how we use analytics.": "Sīkāk par to, kā tiek izmantota analītika.", + "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "Epasts ir nosūtīts uz %(emailAddress)s. Izmantojiet epastā nosūtīto tīmekļa saiti un tad noklišķiniet šeit zemāk.", + "Please note you are logging into the %(hs)s server, not matrix.org.": "Lūdzu ņem vērā, ka Tu pieraksties %(hs)s serverī, nevis matrix.org serverī.", + "This homeserver doesn't offer any login flows which are supported by this client.": "Šis bāzes serveris neatbalsta nevienu pierakstīšanās metodi, kuru piedāvā šis Riot klients.", + "Sign in to get started": "Pierakstīties, lai sāktu", + "Ignores a user, hiding their messages from you": "Ignorē lietotāju, Tev nerādot viņa sūtītās ziņas", + "Stops ignoring a user, showing their messages going forward": "Atceļ lietotāja ignorēšanu, rādot viņa turpmāk sūtītās ziņas", + "Notify the whole room": "Paziņot visai istabai", + "Room Notification": "Istabas paziņojums" } From e3f68f12c859e23342b6f7266338d9feb2655f50 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 12 Feb 2018 18:01:08 +0000 Subject: [PATCH 0294/1160] Add context menu to TagTile With two options: View Community and Remove, which removes the tag from the panel. --- src/actions/TagOrderActions.js | 47 ++++++++++++++++++++++++ src/components/views/elements/TagTile.js | 35 ++++++++++++++++++ src/i18n/strings/en_EN.json | 2 +- src/stores/TagOrderStore.js | 20 +++++++++- 4 files changed, 101 insertions(+), 3 deletions(-) diff --git a/src/actions/TagOrderActions.js b/src/actions/TagOrderActions.js index dd4df6a9d4..3504adb09b 100644 --- a/src/actions/TagOrderActions.js +++ b/src/actions/TagOrderActions.js @@ -56,4 +56,51 @@ TagOrderActions.moveTag = function(matrixClient, tag, destinationIx) { }); }; +/** + * Creates an action thunk that will do an asynchronous request to + * label a tag as removed in im.vector.web.tag_ordering account data. + * + * The reason this is implemented with new state `removedTags` is that + * we incrementally and initially populate `tags` with groups that + * have been joined. If we remove a group from `tags`, it will just + * get added (as it looks like a group we've recently joined). + * + * NB: If we ever support adding of tags (which is planned), we should + * take special care to remove the tag from `removedTags` when we add + * it. + * + * @param {MatrixClient} matrixClient the matrix client to set the + * account data on. + * @param {string} tag the tag to remove. + * @returns {function} an action thunk that will dispatch actions + * indicating the status of the request. + * @see asyncAction + */ +TagOrderActions.removeTag = function(matrixClient, tag) { + // Don't change tags, just removedTags + const tags = TagOrderStore.getOrderedTags(); + const removedTags = TagOrderStore.getRemovedTagsAccountData() || []; + + if (removedTags.includes(tag)) { + // Return a thunk that doesn't do anything, we don't even need + // an asynchronous action here, the tag is already removed. + return () => {}; + } + + removedTags.push(tag); + + const storeId = TagOrderStore.getStoreId(); + + return asyncAction('TagOrderActions.removeTag', () => { + Analytics.trackEvent('TagOrderActions', 'removeTag'); + return matrixClient.setAccountData( + 'im.vector.web.tag_ordering', + {tags, removedTags, _storeId: storeId}, + ); + }, () => { + // For an optimistic update + return {removedTags}; + }); +}; + export default TagOrderActions; diff --git a/src/components/views/elements/TagTile.js b/src/components/views/elements/TagTile.js index f52f758cc0..8d801d986d 100644 --- a/src/components/views/elements/TagTile.js +++ b/src/components/views/elements/TagTile.js @@ -21,6 +21,7 @@ import { MatrixClient } from 'matrix-js-sdk'; import sdk from '../../../index'; import dis from '../../../dispatcher'; import { isOnlyCtrlOrCmdIgnoreShiftKeyEvent } from '../../../Keyboard'; +import ContextualMenu from '../../structures/ContextualMenu'; import FlairStore from '../../../stores/FlairStore'; @@ -81,6 +82,35 @@ export default React.createClass({ }); }, + onContextButtonClick: function(e) { + e.preventDefault(); + e.stopPropagation(); + + // Hide the (...) immediately + this.setState({ hover: false }); + + const TagTileContextMenu = sdk.getComponent('context_menus.TagTileContextMenu'); + const elementRect = e.target.getBoundingClientRect(); + + // The window X and Y offsets are to adjust position when zoomed in to page + const x = elementRect.right + window.pageXOffset + 3; + const chevronOffset = 12; + let y = (elementRect.top + (elementRect.height / 2) + window.pageYOffset); + y = y - (chevronOffset + 8); // where 8 is half the height of the chevron + + const self = this; + ContextualMenu.createMenu(TagTileContextMenu, { + chevronOffset: chevronOffset, + left: x, + top: y, + tag: this.props.tag, + onFinished: function() { + self.setState({ menuDisplayed: false }); + }, + }); + this.setState({ menuDisplayed: true }); + }, + onMouseOver: function() { this.setState({hover: true}); }, @@ -109,10 +139,15 @@ export default React.createClass({ const tip = this.state.hover ? :
    ; + const contextButton = this.state.hover || this.state.menuDisplayed ? +
    + { "\u00B7\u00B7\u00B7" } +
    :
    ; return
    { tip } + { contextButton }
    ; }, diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 6139ac2a91..3cfbe24122 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -500,8 +500,8 @@ "Download %(text)s": "Download %(text)s", "Invalid file%(extra)s": "Invalid file%(extra)s", "Error decrypting image": "Error decrypting image", - "Image '%(Body)s' cannot be displayed.": "Image '%(Body)s' cannot be displayed.", "This image cannot be displayed.": "This image cannot be displayed.", + "Image '%(Body)s' cannot be displayed.": "Image '%(Body)s' cannot be displayed.", "Error decrypting video": "Error decrypting video", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s changed the avatar for %(roomName)s", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s removed the room avatar.", diff --git a/src/stores/TagOrderStore.js b/src/stores/TagOrderStore.js index 69b22797fb..3ec751d075 100644 --- a/src/stores/TagOrderStore.js +++ b/src/stores/TagOrderStore.js @@ -55,6 +55,7 @@ class TagOrderStore extends Store { const tagOrderingEventContent = tagOrderingEvent ? tagOrderingEvent.getContent() : {}; this._setState({ orderedTagsAccountData: tagOrderingEventContent.tags || null, + removedTagsAccountData: tagOrderingEventContent.removedTags || null, hasSynced: true, }); this._updateOrderedTags(); @@ -70,6 +71,7 @@ class TagOrderStore extends Store { this._setState({ orderedTagsAccountData: payload.event_content ? payload.event_content.tags : null, + removedTagsAccountData: payload.event_content ? payload.event_content.removedTags : null, }); this._updateOrderedTags(); break; @@ -90,6 +92,14 @@ class TagOrderStore extends Store { }); break; } + case 'TagOrderActions.removeTag.pending': { + // Optimistic update of a removed tag + this._setState({ + removedTagsAccountData: payload.request.removedTags, + }); + this._updateOrderedTags(); + break; + } case 'select_tag': { let newTags = []; // Shift-click semantics @@ -165,13 +175,15 @@ class TagOrderStore extends Store { _mergeGroupsAndTags() { const groupIds = this._state.joinedGroupIds || []; const tags = this._state.orderedTagsAccountData || []; + const removedTags = this._state.removedTagsAccountData || []; + const tagsToKeep = tags.filter( - (t) => t[0] !== '+' || groupIds.includes(t), + (t) => (t[0] !== '+' || groupIds.includes(t)) && !removedTags.includes(t), ); const groupIdsToAdd = groupIds.filter( - (groupId) => !tags.includes(groupId), + (groupId) => !tags.includes(groupId) && !removedTags.includes(groupId), ); return tagsToKeep.concat(groupIdsToAdd); @@ -181,6 +193,10 @@ class TagOrderStore extends Store { return this._state.orderedTags; } + getRemovedTagsAccountData() { + return this._state.removedTagsAccountData; + } + getStoreId() { // Generate a random ID to prevent this store from clobbering its // state with redundant remote echos. From 7a4c1994c327e4616a801c0a5d4aa1495fbdbb67 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 12 Feb 2018 18:35:13 +0000 Subject: [PATCH 0295/1160] Use Boolean() instead of assuming filter is based on truthiness --- 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 269f04c963..4a491c8a03 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -371,7 +371,7 @@ module.exports = React.createClass({ return; } - return isRoomVisible[taggedRoom.roomId]; + return Boolean(isRoomVisible[taggedRoom.roomId]); }); }); From 3eeef064bf5e7abaca367f2c62dce174d9707644 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 12 Feb 2018 18:37:54 +0000 Subject: [PATCH 0296/1160] Remove unused asyncId --- src/actions/actionCreators.js | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/actions/actionCreators.js b/src/actions/actionCreators.js index 697930414c..967ce609e7 100644 --- a/src/actions/actionCreators.js +++ b/src/actions/actionCreators.js @@ -33,28 +33,25 @@ limitations under the License. * `${id}.failure`. * * The shape of each are: - * { action: '${id}.pending', request, asyncId } - * { action: '${id}.success', result, asyncId } - * { action: '${id}.failure', err, asyncId } + * { action: '${id}.pending', request } + * { action: '${id}.success', result } + * { action: '${id}.failure', err } * - * where `request` is returned by `pendingFn`, result - * is the result of the promise returned by `fn` and - * `asyncId` is a unique ID for each dispatch of the - * asynchronous action. + * where `request` is returned by `pendingFn` and + * result is the result of the promise returned by + * `fn`. */ export function asyncAction(id, fn, pendingFn) { return (dispatch) => { - const asyncId = Math.random().toString(16).slice(2, 10); dispatch({ action: id + '.pending', request: typeof pendingFn === 'function' ? pendingFn() : undefined, - asyncId, }); fn().then((result) => { - dispatch({action: id + '.success', result, asyncId}); + dispatch({action: id + '.success', result}); }).catch((err) => { - dispatch({action: id + '.failure', err, asyncId}); + dispatch({action: id + '.failure', err}); }); }; } From 322012cf889c00fe5b2bc790a01c52e6ca1e689e Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 12 Feb 2018 18:46:36 +0000 Subject: [PATCH 0297/1160] Add comment to explain hacky optimism --- src/stores/RoomListStore.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/stores/RoomListStore.js b/src/stores/RoomListStore.js index 193784811c..b71e1c5cc1 100644 --- a/src/stores/RoomListStore.js +++ b/src/stores/RoomListStore.js @@ -79,6 +79,11 @@ class RoomListStore extends Store { } break; case 'RoomListActions.tagRoom.pending': { + // XXX: we only show one optimistic update at any one time. + // Ideally we should be making a list of in-flight requests + // that are backed by transaction IDs. Until the js-sdk + // supports this, we're stuck with only being able to use + // the most recent optimistic update. this._generateRoomLists(payload.request); } break; From 5e9368e794eac546569d93ae2738bd24566cdc74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Mon, 12 Feb 2018 21:13:53 +0100 Subject: [PATCH 0298/1160] Add comments explaining our non standard usage of aria-described-by --- src/components/views/dialogs/BaseDialog.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index 08fd972621..053aef66c3 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -76,6 +76,12 @@ export default React.createClass({ className={this.props.className} role="dialog" aria-labelledby='mx_BaseDialog_title' + // This should point to a node describing the dialog. + // If we were about to completelly follow this recommendation we'd need to + // make all the components relying on BaseDialog to be aware of it. + // So instead we will use the whole content as the description. + // Description comes first and if the content contains more text, + // AT users can skip its presentation. aria-describedby={this.props.contentId} > Date: Tue, 13 Feb 2018 09:44:00 +0000 Subject: [PATCH 0299/1160] Move groups button to TagPanel --- src/components/structures/TagPanel.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/components/structures/TagPanel.js b/src/components/structures/TagPanel.js index 49a7a4020a..f10936e802 100644 --- a/src/components/structures/TagPanel.js +++ b/src/components/structures/TagPanel.js @@ -111,8 +111,7 @@ const TagPanel = React.createClass({ }, render() { - const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); - const TintableSvg = sdk.getComponent('elements.TintableSvg'); + const GroupsButton = sdk.getComponent('elements.GroupsButton'); const DNDTagTile = sdk.getComponent('elements.DNDTagTile'); const tags = this.state.orderedTags.map((tag, index) => { @@ -142,9 +141,9 @@ const TagPanel = React.createClass({ ) } - - - +
    + +
    ; }, }); From 493116b17e57d56036a896ef60ab9886ebb97112 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 13 Feb 2018 11:43:22 +0000 Subject: [PATCH 0300/1160] Give the login page its spinner back --- src/components/structures/login/Login.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/structures/login/Login.js b/src/components/structures/login/Login.js index 5042ca1fd0..7f4aa0325a 100644 --- a/src/components/structures/login/Login.js +++ b/src/components/structures/login/Login.js @@ -431,10 +431,10 @@ module.exports = React.createClass({ // FIXME: remove status.im theme tweaks const theme = SettingsStore.getValue("theme"); if (theme !== "status") { - header =

    { _t('Sign in') }

    ; + header =

    { _t('Sign in') } { loader }

    ; } else { if (!this.state.errorText) { - header =

    { _t('Sign in to get started') }

    ; + header =

    { _t('Sign in to get started') } { loader }

    ; } } From 8377abcd1987a34cecbb3b363f807731f5dd861e Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 13 Feb 2018 11:49:59 +0000 Subject: [PATCH 0301/1160] Store component state for editors to prevent a forceUpdate from /sync causing the editors to revert before the user had a chance to hit "Save". Part of fixing https://github.com/vector-im/riot-web/issues/6019 --- src/components/views/rooms/RoomNameEditor.js | 21 ++++++++++++++--- src/components/views/rooms/RoomTopicEditor.js | 23 +++++++++++++++---- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/components/views/rooms/RoomNameEditor.js b/src/components/views/rooms/RoomNameEditor.js index 5c224d79c0..d073a0be25 100644 --- a/src/components/views/rooms/RoomNameEditor.js +++ b/src/components/views/rooms/RoomNameEditor.js @@ -29,13 +29,21 @@ module.exports = React.createClass({ room: PropTypes.object.isRequired, }, + getInitialState: function() { + return { + name: null, + }; + }, + componentWillMount: function() { const room = this.props.room; const name = room.currentState.getStateEvents('m.room.name', ''); const myId = MatrixClientPeg.get().credentials.userId; const defaultName = room.getDefaultRoomName(myId); - this._initialName = name ? name.getContent().name : ''; + this.setState({ + name: name ? name.getContent().name : '', + }); this._placeholderName = _t("Unnamed Room"); if (defaultName && defaultName !== 'Empty room') { // default name from JS SDK, needs no translation as we don't ever show it. @@ -44,7 +52,13 @@ module.exports = React.createClass({ }, getRoomName: function() { - return this.refs.editor.getValue(); + return this.state.name; + }, + + _onValueChanged: function(value, shouldSubmit) { + this.setState({ + name: value, + }); }, render: function() { @@ -57,7 +71,8 @@ module.exports = React.createClass({ placeholderClassName="mx_RoomHeader_placeholder" placeholder={this._placeholderName} blurToCancel={false} - initialValue={this._initialName} + initialValue={this.state.name} + onValueChanged={this._onValueChanged} dir="auto" />
    ); diff --git a/src/components/views/rooms/RoomTopicEditor.js b/src/components/views/rooms/RoomTopicEditor.js index 8f950d625c..7ad02f264c 100644 --- a/src/components/views/rooms/RoomTopicEditor.js +++ b/src/components/views/rooms/RoomTopicEditor.js @@ -28,26 +28,41 @@ module.exports = React.createClass({ room: PropTypes.object.isRequired, }, + getInitialState: function() { + return { + topic: null, + }; + }, + componentWillMount: function() { const room = this.props.room; const topic = room.currentState.getStateEvents('m.room.topic', ''); - this._initialTopic = topic ? topic.getContent().topic : ''; + this.setState({ + topic: topic ? topic.getContent().topic : '', + }); }, getTopic: function() { - return this.refs.editor.getValue(); + return this.state.topic; + }, + + _onValueChanged: function(value) { + this.setState({ + topic: value, + }); }, render: function() { const EditableText = sdk.getComponent("elements.EditableText"); return ( - ); }, From 36e8bf1f20661c380bec1ad5a2337f914480cd0a Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 13 Feb 2018 14:13:47 +0000 Subject: [PATCH 0302/1160] Change CSS class for message panel spinner to stop scrollbars appearing when we - jump to a message or, - permalink that is to an not paginated in event --- src/components/structures/TimelinePanel.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/structures/TimelinePanel.js b/src/components/structures/TimelinePanel.js index 4ade78af85..12f745146e 100644 --- a/src/components/structures/TimelinePanel.js +++ b/src/components/structures/TimelinePanel.js @@ -1121,9 +1121,9 @@ var TimelinePanel = React.createClass({ // exist. if (this.state.timelineLoading) { return ( -
    - -
    +
    + +
    ); } From 5af560f625ef48000063c1a5b9ee3b060bf6d46e Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 13 Feb 2018 14:43:34 +0000 Subject: [PATCH 0303/1160] Make removedTags a Set for perf --- src/stores/TagOrderStore.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/stores/TagOrderStore.js b/src/stores/TagOrderStore.js index 3ec751d075..78e4a6e95d 100644 --- a/src/stores/TagOrderStore.js +++ b/src/stores/TagOrderStore.js @@ -175,15 +175,15 @@ class TagOrderStore extends Store { _mergeGroupsAndTags() { const groupIds = this._state.joinedGroupIds || []; const tags = this._state.orderedTagsAccountData || []; - const removedTags = this._state.removedTagsAccountData || []; + const removedTags = new Set(this._state.removedTagsAccountData || []); const tagsToKeep = tags.filter( - (t) => (t[0] !== '+' || groupIds.includes(t)) && !removedTags.includes(t), + (t) => (t[0] !== '+' || groupIds.includes(t)) && !removedTags.has(t), ); const groupIdsToAdd = groupIds.filter( - (groupId) => !tags.includes(groupId) && !removedTags.includes(groupId), + (groupId) => !tags.includes(groupId) && !removedTags.has(groupId), ); return tagsToKeep.concat(groupIdsToAdd); From f16bc93fee1c46dddf90f323d82e1646fab4b5a4 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 13 Feb 2018 16:09:17 +0000 Subject: [PATCH 0304/1160] If a tag is unrecognised, assume manual ordering (as we did previously) Fixes https://github.com/vector-im/riot-web/issues/6135 --- src/stores/RoomListStore.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/stores/RoomListStore.js b/src/stores/RoomListStore.js index b71e1c5cc1..693275952b 100644 --- a/src/stores/RoomListStore.js +++ b/src/stores/RoomListStore.js @@ -176,12 +176,13 @@ class RoomListStore extends Store { listOrders[order].forEach((listKey) => { let comparator; switch (order) { - case "manual": - comparator = this._getManualComparator(listKey, optimisticRequest); - break; case "recent": comparator = this._recentsComparator; break; + case "manual": + default: + comparator = this._getManualComparator(listKey, optimisticRequest); + break; } lists[listKey].sort(comparator); }); From 06b18dda1856b45b9d17a2f7c1707cbcbddbcb78 Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Tue, 13 Feb 2018 17:23:42 +0000 Subject: [PATCH 0305/1160] Added translation using Weblate (Bulgarian) --- src/i18n/strings/bg.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/i18n/strings/bg.json diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/src/i18n/strings/bg.json @@ -0,0 +1 @@ +{} From bee0a952c37c1d7c6abc3b2092430f4fc815affa Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Tue, 13 Feb 2018 18:57:09 +0000 Subject: [PATCH 0306/1160] Translated using Weblate (Bulgarian) Currently translated at 0.2% (2 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 0967ef424b..1300a32895 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -1 +1,4 @@ -{} +{ + "OK": "ОК", + "Operation failed": "Операцията е неуспешна" +} From 02e0663409b965bcc165dcf8703aadbc8ae80c20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sim=C3=B3=20Albert=20i=20Beltran?= Date: Tue, 13 Feb 2018 18:44:58 +0000 Subject: [PATCH 0307/1160] Translated using Weblate (Catalan) Currently translated at 88.3% (871 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ca/ --- src/i18n/strings/ca.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/ca.json b/src/i18n/strings/ca.json index 1ff3e7f8e9..0b1a7b10ef 100644 --- a/src/i18n/strings/ca.json +++ b/src/i18n/strings/ca.json @@ -376,7 +376,7 @@ "Idle for %(duration)s": "Inactiu durant %(duration)s", "Offline for %(duration)s": "Desconnectat durant %(duration)s", "Unknown for %(duration)s": "Desconegut durant %(duration)s", - "Online": "En línia", + "Online": "Conectat", "Idle": "Inactiu", "Offline": "Desconnectat", "Unknown": "Desconegut", From ed871cbd83987e6f2492327f8df7d6a308e17293 Mon Sep 17 00:00:00 2001 From: Walter Date: Tue, 13 Feb 2018 18:55:45 +0000 Subject: [PATCH 0308/1160] Translated using Weblate (Russian) Currently translated at 100.0% (986 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index e7cc2f2319..d24ee71de1 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -536,7 +536,7 @@ "Drop file here to upload": "Перетащите файл сюда для отправки", " (unsupported)": " (не поддерживается)", "Ongoing conference call%(supportedText)s.": "Установлен групповой вызов %(supportedText)s.", - "Online": "В сети", + "Online": "Онлайн", "Idle": "Неактивен", "Offline": "Не в сети", "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s сменил аватар комнаты на ", From db2f6f863a8c63ec434c4cd11b7fa52cae846ea5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sim=C3=B3=20Albert=20i=20Beltran?= Date: Tue, 13 Feb 2018 18:00:22 +0000 Subject: [PATCH 0309/1160] Translated using Weblate (Spanish) Currently translated at 58.1% (573 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/es/ --- src/i18n/strings/es.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/es.json b/src/i18n/strings/es.json index 1b513cc51f..ccfd6f7761 100644 --- a/src/i18n/strings/es.json +++ b/src/i18n/strings/es.json @@ -571,5 +571,6 @@ "Nov": "Nov", "Dec": "Dic", "Warning": "Advertencia", - "Unpin Message": "Desmarcar Mensaje" + "Unpin Message": "Desmarcar Mensaje", + "Online": "Conectado" } From 3020c8cd94a08210070a7633bfa35a93a049c367 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 14 Feb 2018 11:23:29 +0000 Subject: [PATCH 0310/1160] Fix custom tags not being ordered manually Actually fixes vector-im/riot-web#6135 unlike #1748, which incorrectly assumed that custom tags would be included in listOrders. This fix makes sure that the `default` case in the `switch` is actually used. --- src/stores/RoomListStore.js | 42 ++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/src/stores/RoomListStore.js b/src/stores/RoomListStore.js index 693275952b..fdd9ca6692 100644 --- a/src/stores/RoomListStore.js +++ b/src/stores/RoomListStore.js @@ -160,32 +160,26 @@ class RoomListStore extends Store { }); const listOrders = { - "manual": [ - "m.favourite", - ], - "recent": [ - "im.vector.fake.invite", - "im.vector.fake.recent", - "im.vector.fake.direct", - "m.lowpriority", - "im.vector.fake.archived", - ], + "m.favourite": "manual", + "im.vector.fake.invite": "recent", + "im.vector.fake.recent": "recent", + "im.vector.fake.direct": "recent", + "m.lowpriority": "recent", + "im.vector.fake.archived": "recent", }; - Object.keys(listOrders).forEach((order) => { - listOrders[order].forEach((listKey) => { - let comparator; - switch (order) { - case "recent": - comparator = this._recentsComparator; - break; - case "manual": - default: - comparator = this._getManualComparator(listKey, optimisticRequest); - break; - } - lists[listKey].sort(comparator); - }); + Object.keys(lists).forEach((listKey) => { + let comparator; + switch (listOrders[listKey]) { + case "recent": + comparator = this._recentsComparator; + break; + case "manual": + default: + comparator = this._getManualComparator(listKey, optimisticRequest); + break; + } + lists[listKey].sort(comparator); }); this._setState({ From db4f0cb0bffc091df477899f00eded9c265bedc7 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 14 Feb 2018 16:40:24 +0000 Subject: [PATCH 0311/1160] Handle adding previously removed tags --- src/actions/TagOrderActions.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/actions/TagOrderActions.js b/src/actions/TagOrderActions.js index 3504adb09b..38bada2228 100644 --- a/src/actions/TagOrderActions.js +++ b/src/actions/TagOrderActions.js @@ -35,6 +35,7 @@ const TagOrderActions = {}; TagOrderActions.moveTag = function(matrixClient, tag, destinationIx) { // Only commit tags if the state is ready, i.e. not null let tags = TagOrderStore.getOrderedTags(); + let removedTags = TagOrderStore.getRemovedTagsAccountData(); if (!tags) { return; } @@ -42,17 +43,19 @@ TagOrderActions.moveTag = function(matrixClient, tag, destinationIx) { tags = tags.filter((t) => t !== tag); tags = [...tags.slice(0, destinationIx), tag, ...tags.slice(destinationIx)]; + removedTags = removedTags.filter((t) => t !== tag); + const storeId = TagOrderStore.getStoreId(); return asyncAction('TagOrderActions.moveTag', () => { Analytics.trackEvent('TagOrderActions', 'commitTagOrdering'); return matrixClient.setAccountData( 'im.vector.web.tag_ordering', - {tags, _storeId: storeId}, + {tags, removedTags, _storeId: storeId}, ); }, () => { // For an optimistic update - return {tags}; + return {tags, removedTags}; }); }; From b626420eb93e4f25333cd5c98758d7d3cc586265 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 14 Feb 2018 16:40:58 +0000 Subject: [PATCH 0312/1160] Move DND context to LoggedInView so that we can drag things from any part of the logged in app to another. (Specifically GroupView and TagPanel). --- src/components/structures/LoggedInView.js | 70 +++++++++++++++++++---- 1 file changed, 60 insertions(+), 10 deletions(-) diff --git a/src/components/structures/LoggedInView.js b/src/components/structures/LoggedInView.js index d7fe699156..f6bbfd247b 100644 --- a/src/components/structures/LoggedInView.js +++ b/src/components/structures/LoggedInView.js @@ -19,6 +19,7 @@ limitations under the License. import * as Matrix from 'matrix-js-sdk'; import React from 'react'; import PropTypes from 'prop-types'; +import { DragDropContext } from 'react-beautiful-dnd'; import { KeyCode, isOnlyCtrlOrCmdKeyEvent } from '../../Keyboard'; import Notifier from '../../Notifier'; @@ -30,6 +31,9 @@ import sessionStore from '../../stores/SessionStore'; import MatrixClientPeg from '../../MatrixClientPeg'; import SettingsStore from "../../settings/SettingsStore"; +import TagOrderActions from '../../actions/TagOrderActions'; +import RoomListActions from '../../actions/RoomListActions'; + /** * This is what our MatrixChat shows when we are logged in. The precise view is * determined by the page_type property. @@ -207,6 +211,50 @@ const LoggedInView = React.createClass({ } }, + _onDragEnd: function(result) { + // Dragged to an invalid destination, not onto a droppable + if (!result.destination) { + return; + } + + const dest = result.destination.droppableId; + + if (dest === 'tag-panel-droppable') { + // Could be "GroupTile +groupId:domain" + const draggableId = result.draggableId.split(' ').pop(); + + // Dispatch synchronously so that the TagPanel receives an + // optimistic update from TagOrderStore before the previous + // state is shown. + dis.dispatch(TagOrderActions.moveTag( + this._matrixClient, + draggableId, + result.destination.index, + ), true); + } else if (dest.startsWith('room-sub-list-droppable_')) { + this._onRoomTileEndDrag(result); + } + }, + + _onRoomTileEndDrag: function(result) { + let newTag = result.destination.droppableId.split('_')[1]; + let prevTag = result.source.droppableId.split('_')[1]; + if (newTag === 'undefined') newTag = undefined; + if (prevTag === 'undefined') prevTag = undefined; + + const roomId = result.draggableId.split('_')[1]; + + const oldIndex = result.source.index; + const newIndex = result.destination.index; + + dis.dispatch(RoomListActions.tagRoom( + this._matrixClient, + this._matrixClient.getRoom(roomId), + prevTag, newTag, + oldIndex, newIndex, + ), true); + }, + render: function() { const LeftPanel = sdk.getComponent('structures.LeftPanel'); const RightPanel = sdk.getComponent('structures.RightPanel'); @@ -328,16 +376,18 @@ const LoggedInView = React.createClass({ return (
    { topBar } -
    - -
    - { page_element } -
    - { right_panel } -
    + +
    + +
    + { page_element } +
    + { right_panel } +
    +
    ); }, From 74c8a74e7d2106057b9c1e368914146c8d2ad8d3 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 14 Feb 2018 16:43:01 +0000 Subject: [PATCH 0313/1160] Add Droppable to GroupView to contain the GroupTiles as Draggables --- src/components/structures/MyGroups.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/components/structures/MyGroups.js b/src/components/structures/MyGroups.js index 22157beaca..4c9229a2ea 100644 --- a/src/components/structures/MyGroups.js +++ b/src/components/structures/MyGroups.js @@ -17,6 +17,7 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import GeminiScrollbar from 'react-gemini-scrollbar'; +import { Droppable } from 'react-beautiful-dnd'; import sdk from '../../index'; import { _t } from '../../languageHandler'; import dis from '../../dispatcher'; @@ -74,7 +75,13 @@ export default withMatrixClient(React.createClass({ contentHeader = groupNodes.length > 0 ?

    { _t('Your Communities') }

    :
    ; content = groupNodes.length > 0 ? - { groupNodes } + + { (provided, snapshot) => ( +
    + { groupNodes } +
    + ) } +
    :
    { _t( From 3850b552a5bddb753d21da3634d30914ed1f520f Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 14 Feb 2018 16:46:06 +0000 Subject: [PATCH 0314/1160] Make GroupTile avatar draggable --- src/components/views/groups/GroupTile.js | 32 +++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/components/views/groups/GroupTile.js b/src/components/views/groups/GroupTile.js index ce426a9b78..70947afa65 100644 --- a/src/components/views/groups/GroupTile.js +++ b/src/components/views/groups/GroupTile.js @@ -17,10 +17,12 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import {MatrixClient} from 'matrix-js-sdk'; +import { Draggable } from 'react-beautiful-dnd'; import sdk from '../../../index'; import dis from '../../../dispatcher'; import FlairStore from '../../../stores/FlairStore'; + const GroupTile = React.createClass({ displayName: 'GroupTile', @@ -78,9 +80,33 @@ const GroupTile = React.createClass({ profile.avatarUrl, avatarHeight, avatarHeight, "crop", ) : null; return -
    - -
    + + { (provided, snapshot) => ( +
    +
    +
    + +
    +
    + { /* Instead of a blank placeholder, use a copy of the avatar itself. */ } + { provided.placeholder ? +
    + +
    : +
    + } +
    + ) } +
    { name }
    { descElement } From 389d96bc46047bf2791b2fc6bf8200d68f7673ed Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 14 Feb 2018 16:47:29 +0000 Subject: [PATCH 0315/1160] Use optimistic removedTagsAccountData state in TagOrderStore when receiving TagOrderActions.moveTag.pending, which now exposes this state. --- src/stores/TagOrderStore.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/stores/TagOrderStore.js b/src/stores/TagOrderStore.js index 78e4a6e95d..eef078d8da 100644 --- a/src/stores/TagOrderStore.js +++ b/src/stores/TagOrderStore.js @@ -89,6 +89,7 @@ class TagOrderStore extends Store { // Optimistic update of a moved tag this._setState({ orderedTags: payload.request.tags, + removedTagsAccountData: payload.request.removedTags, }); break; } From 3948ee8ca14d5f00f2a0163a692569f303be9811 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 14 Feb 2018 17:53:54 +0000 Subject: [PATCH 0316/1160] Give each GroupTile avatar its own droppable so that they can be dragged and dropped without interacting with each other, as they would do if GroupView contained one droppable to contain them all. --- src/components/structures/MyGroups.js | 13 ++---- src/components/views/groups/GroupTile.js | 56 +++++++++++++----------- 2 files changed, 35 insertions(+), 34 deletions(-) diff --git a/src/components/structures/MyGroups.js b/src/components/structures/MyGroups.js index 4c9229a2ea..116607fb08 100644 --- a/src/components/structures/MyGroups.js +++ b/src/components/structures/MyGroups.js @@ -17,7 +17,6 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import GeminiScrollbar from 'react-gemini-scrollbar'; -import { Droppable } from 'react-beautiful-dnd'; import sdk from '../../index'; import { _t } from '../../languageHandler'; import dis from '../../dispatcher'; @@ -74,14 +73,10 @@ export default withMatrixClient(React.createClass({ }); contentHeader = groupNodes.length > 0 ?

    { _t('Your Communities') }

    :
    ; content = groupNodes.length > 0 ? - - - { (provided, snapshot) => ( -
    - { groupNodes } -
    - ) } -
    + +
    + { groupNodes } +
    :
    { _t( diff --git a/src/components/views/groups/GroupTile.js b/src/components/views/groups/GroupTile.js index 70947afa65..f1dbb75988 100644 --- a/src/components/views/groups/GroupTile.js +++ b/src/components/views/groups/GroupTile.js @@ -17,7 +17,7 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import {MatrixClient} from 'matrix-js-sdk'; -import { Draggable } from 'react-beautiful-dnd'; +import { Draggable, Droppable } from 'react-beautiful-dnd'; import sdk from '../../../index'; import dis from '../../../dispatcher'; import FlairStore from '../../../stores/FlairStore'; @@ -80,33 +80,39 @@ const GroupTile = React.createClass({ profile.avatarUrl, avatarHeight, avatarHeight, "crop", ) : null; return - - { (provided, snapshot) => ( -
    -
    + { (droppableProvided, droppableSnapshot) => ( +
    + -
    - -
    -
    - { /* Instead of a blank placeholder, use a copy of the avatar itself. */ } - { provided.placeholder ? -
    - -
    : -
    - } + { (provided, snapshot) => ( +
    +
    +
    + +
    +
    + { /* Instead of a blank placeholder, use a copy of the avatar itself. */ } + { provided.placeholder ? +
    + +
    : +
    + } +
    + ) } +
    ) } - +
    { name }
    { descElement } From a4c7da63afe4a58551a8497c221e91e1d97fdeec Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Thu, 15 Feb 2018 10:47:20 +0000 Subject: [PATCH 0317/1160] Translated using Weblate (Bulgarian) Currently translated at 4.6% (46 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 46 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 1300a32895..a05100dd3f 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -1,4 +1,48 @@ { "OK": "ОК", - "Operation failed": "Операцията е неуспешна" + "Operation failed": "Операцията е неуспешна", + "Search": "Търсене", + "Custom Server Options": "Потребителски опции за сървър", + "Dismiss": "Отказ", + "powered by Matrix": "базирано на Matrix", + "Warning": "Предупреждение", + "Error": "Грешка", + "Remove": "Премахни", + "Close": "Затвори", + "Cancel": "Отказ", + "Send": "Изпрати", + "Edit": "Редактирай", + "Continue": "Продължи", + "Failed to change password. Is your password correct?": "Неуспешна промяна. Правилно ли сте въвели Вашата парола?", + "Unpin Message": "Откачи съобщението", + "Sun": "нд.", + "Mon": "пн.", + "Tue": "вт.", + "Wed": "ср.", + "Thu": "чт.", + "Fri": "пт.", + "Sat": "сб.", + "Jan": "ян.", + "Feb": "февр.", + "Mar": "март", + "Apr": "апр.", + "May": "май", + "Jun": "юни", + "Jul": "юли", + "Aug": "авг.", + "Sep": "септ.", + "Oct": "окт.", + "Nov": "ноем.", + "Dec": "дек.", + "%(weekDayName)s %(time)s": "%(weekDayName)s %(time)s", + "%(weekDayName)s, %(monthName)s %(day)s %(time)s": "%(weekDayName)s, %(day)s %(monthName)s %(time)s", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(day)s %(monthName)s %(fullYear)s, %(weekDayName)s", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s": "%(weekDayName)s, %(day)s %(monthName)s %(fullYear)s %(time)s", + "Online": "Онлайн", + "Failed to remove tag %(tagName)s from room": "Неуспешно премахване на %(tagName)s етикет от стаята", + "unknown error code": "неизвестен код за грешка", + "Failed to forget room %(errCode)s": "Не успешно забравяне на стаята %(errCode)s", + "Mute": "Заглуши", + "Leave": "Напусни", + "Favourite": "Любим" } From ceec40551908db8b35a0bd33d9fff6aa01b83b87 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 15 Feb 2018 11:23:00 +0000 Subject: [PATCH 0318/1160] Remove RoomListStore listener This caused the the RoomList component to leak (although in practice only accross logins because that's the only time it's unmounted) --- package.json | 2 +- src/components/views/rooms/RoomList.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index bb8db64d28..9d5013de28 100644 --- a/package.json +++ b/package.json @@ -128,7 +128,7 @@ "require-json": "0.0.1", "rimraf": "^2.4.3", "sinon": "^1.17.3", - "source-map-loader": "^0.1.5", + "source-map-loader": "^0.1.6", "walk": "^2.3.9", "webpack": "^1.12.14" } diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 4a491c8a03..41a200420d 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -191,6 +191,10 @@ module.exports = React.createClass({ this._tagStoreToken.remove(); } + if (this._roomListStoreToken) { + this._roomListStoreToken.remove(); + } + if (this._groupStoreTokens.length > 0) { // NB: GroupStore is not a Flux.Store this._groupStoreTokens.forEach((token) => token.unregister()); From 44964e80a9c3f8974be669b9bf453375649ea986 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 15 Feb 2018 11:25:40 +0000 Subject: [PATCH 0319/1160] undo unintentional commit --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9d5013de28..bb8db64d28 100644 --- a/package.json +++ b/package.json @@ -128,7 +128,7 @@ "require-json": "0.0.1", "rimraf": "^2.4.3", "sinon": "^1.17.3", - "source-map-loader": "^0.1.6", + "source-map-loader": "^0.1.5", "walk": "^2.3.9", "webpack": "^1.12.14" } From 39af04f09048d872beef7c0059148aa7cd978d2c Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Thu, 15 Feb 2018 13:18:15 +0000 Subject: [PATCH 0320/1160] Translated using Weblate (Bulgarian) Currently translated at 5.5% (55 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index a05100dd3f..6ce4acf267 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -44,5 +44,14 @@ "Failed to forget room %(errCode)s": "Не успешно забравяне на стаята %(errCode)s", "Mute": "Заглуши", "Leave": "Напусни", - "Favourite": "Любим" + "Favourite": "Любим", + "Register": "Регистрация", + "Notifications": "Известия", + "Rooms": "Стаи", + "Add rooms to this community": "Добави стаи в това общество", + "Unnamed room": "Ненаименувана стая", + "World readable": "Четимо за всички", + "Guests can join": "Гости могат да се присъединят", + "No rooms to show": "Няма стаи, които да бъдат показани", + "Failed to add tag %(tagName)s to room": "Неуспешно добавяне на %(tagName)s етикет в стаята" } From 57419a7f8d485c621b6de0a85467a499874c3c45 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 15 Feb 2018 14:11:45 +0000 Subject: [PATCH 0321/1160] Give emptySubListTip a container for correct bg colour --- src/components/views/rooms/RoomList.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 4a491c8a03..e53b7b6536 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -544,17 +544,20 @@ module.exports = React.createClass({ const RoomDirectoryButton = sdk.getComponent('elements.RoomDirectoryButton'); const CreateRoomButton = sdk.getComponent('elements.CreateRoomButton'); + let tip = null; + switch (section) { case 'im.vector.fake.direct': - return
    + tip =
    { _t( "Press to start a chat with someone", {}, { 'StartChatButton': }, ) }
    ; + break; case 'im.vector.fake.recent': - return
    + tip =
    { _t( "You're not in any rooms yet! Press to make a room or"+ " to browse the directory", @@ -565,6 +568,13 @@ module.exports = React.createClass({ }, ) }
    ; + break; + } + + if (tip) { + return
    + { tip } +
    ; } // We don't want to display drop targets if there are no room tiles to drag'n'drop From 19b6684089e7a50e5bb80ed2bc8ba4c7d6e6961e Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Thu, 15 Feb 2018 14:50:16 +0000 Subject: [PATCH 0322/1160] Translated using Weblate (Bulgarian) Currently translated at 7.0% (70 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 6ce4acf267..7574c0278f 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -53,5 +53,20 @@ "World readable": "Четимо за всички", "Guests can join": "Гости могат да се присъединят", "No rooms to show": "Няма стаи, които да бъдат показани", - "Failed to add tag %(tagName)s to room": "Неуспешно добавяне на %(tagName)s етикет в стаята" + "Failed to add tag %(tagName)s to room": "Неуспешно добавяне на %(tagName)s етикет в стаята", + "This email address is already in use": "Този имейл адрес е вече зает", + "This phone number is already in use": "Този телефонен номер е вече зает", + "Failed to verify email address: make sure you clicked the link in the email": "Неуспешно потвърждаване на имейл адреса: уверете се, че сте кликнали върху връзката в имейла", + "The platform you're on": "Платформата, която използвате", + "The version of Riot.im": "Версията на Riot.im", + "Whether or not you're logged in (we don't record your user name)": "Независимо дали сте в профила си или не (не записваме Вашето потребителско име)", + "Your language of choice": "Вашият език по избор", + "Which officially provided instance you are using, if any": "Коя официално предоставена инстанция използвате, ако има такава", + "Whether or not you're using the Richtext mode of the Rich Text Editor": "Независимо дали използвате Richtext режим на Rich Text Editor", + "Your homeserver's URL": "Адрес на Вашия Home сървър", + "Your identity server's URL": "Адрес на Вашия сървър за самоличност", + "Analytics": "Статистика", + "The information being sent to us to help make Riot.im better includes:": "За да направи Riot по-добър, информацията изпратена до нас включва:", + "Call Failed": "Неуспешно повикване", + "Call": "Обаждане" } From 07b691a45d14fa817fe9d08d8ed1ecc2886b313c Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Thu, 15 Feb 2018 20:20:19 +0000 Subject: [PATCH 0323/1160] typo --- src/components/views/messages/MFileBody.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/messages/MFileBody.js b/src/components/views/messages/MFileBody.js index c324c291e7..90efe24df3 100644 --- a/src/components/views/messages/MFileBody.js +++ b/src/components/views/messages/MFileBody.js @@ -82,7 +82,7 @@ Tinter.registerTintable(updateTintedDownloadImage); // downloaded. This limit does not seem to apply when the url is used as // the source attribute of an image tag. // -// Blob URLs are generated using window.URL.createObjectURL and unforuntately +// Blob URLs are generated using window.URL.createObjectURL and unfortunately // for our purposes they inherit the origin of the page that created them. // This means that any scripts that run when the URL is viewed will be able // to access local storage. From b111a824e88fc4ceb29ec03ef7c2765480ada2d1 Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Thu, 15 Feb 2018 19:36:52 +0000 Subject: [PATCH 0324/1160] Translated using Weblate (Bulgarian) Currently translated at 12.0% (119 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 53 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 7574c0278f..948181fa9d 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -49,7 +49,7 @@ "Notifications": "Известия", "Rooms": "Стаи", "Add rooms to this community": "Добави стаи в това общество", - "Unnamed room": "Ненаименувана стая", + "Unnamed room": "Стая без име", "World readable": "Четимо за всички", "Guests can join": "Гости могат да се присъединят", "No rooms to show": "Няма стаи, които да бъдат показани", @@ -68,5 +68,54 @@ "Analytics": "Статистика", "The information being sent to us to help make Riot.im better includes:": "За да направи Riot по-добър, информацията изпратена до нас включва:", "Call Failed": "Неуспешно повикване", - "Call": "Обаждане" + "Call": "Обаждане", + "Answer": "Отговори, приеми", + "You are already in a call.": "Вече сте в разговор.", + "VoIP is unsupported": "Не се поддържа VoIP", + "You cannot place VoIP calls in this browser.": "Не може да осъществите VoIP разговори в този браузър.", + "You cannot place a call with yourself.": "Не може да осъществите разговор със себе си.", + "Existing Call": "Съществуващ разговор", + "Conference calls are not supported in this client": "Групови разговори не се поддържат в тази програма", + "Conference calls are not supported in encrypted rooms": "Групови разговори не се поддържат в шифровани стаи", + "Warning!": "Внимание!", + "Conference calling is in development and may not be reliable.": "Груповите разговори са в процес на разработка и не са надеждни.", + "Review Devices": "Преглед на устройства", + "Failed to set up conference call": "Неуспешно осъществяване на групов чат", + "Conference call failed.": "Неуспешен групов разговор.", + "The file '%(fileName)s' failed to upload": "Неуспешно качване на файл '%(fileName)s'", + "The file '%(fileName)s' exceeds this home server's size limit for uploads": "Файлът '%(fileName)s' надхвърля ограничението на размера за качвания на този Home сървър", + "Upload Failed": "Качването е неуспешно", + "PM": "PM", + "AM": "AM", + "Who would you like to add to this community?": "Кой бихте желали да добавите в това общество?", + "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Предупреждение: Всеки човек, който добавяте в дадено общество, ще бъде публично видим за знаещите идентификатора на обществото", + "Invite new community members": "Покани нови членове на обществото", + "Name or matrix ID": "Име или matrix ID", + "Invite to Community": "Покани в обществото", + "Which rooms would you like to add to this community?": "Кои стаи бихте желали да добавите в това общество?", + "Show these rooms to non-members on the community page and room list?": "Показване на тези стаи на не-членове на страницата на обществата и списъка със стаи?", + "Add rooms to the community": "Добави стаи в обществото", + "Room name or alias": "Име или псевдоним на стая", + "Add to community": "Добави в обществото", + "Failed to invite the following users to %(groupId)s:": "Следните потребители не могат да бъдат поканени в %(groupId)s:", + "Failed to invite users to community": "Потребителите не могат да бъдат поканени в обществото", + "Failed to invite users to %(groupId)s": "Потребителите не могат да бъдат поканени в %(groupId)s", + "Failed to add the following rooms to %(groupId)s:": "Следните стаи не могат да бъдат добавени в %(groupId)s:", + "Riot does not have permission to send you notifications - please check your browser settings": "Riot няма разрешение да Ви изпраща известия - моля проверете вашите настройки на браузъра", + "Riot was not given permission to send notifications - please try again": "Riot не е получил разрешение да изпраща известия - моля опитайте отново", + "Unable to enable Notifications": "Неупешно включване на известия", + "This email address was not found": "Този имейл адрес не беше открит", + "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Изглежда вашият имейл адрес не може да се асоциира с Matrix ID на този Home сървър.", + "Default": "По подразбиране", + "Restricted": "Ограничен", + "Moderator": "Модератор", + "Admin": "Администратор", + "Start a chat": "Започване на чат", + "Who would you like to communicate with?": "С кой бихте желали да си комуникирате?", + "Email, name or matrix ID": "Имейл, име или matrix ID", + "Start Chat": "Започни чат", + "Invite new room members": "Покани нови членове на стаята", + "Who would you like to add to this room?": "Кой бихте желали да добавите в тази стая?", + "Send Invites": "Изпрати покани", + "Failed to invite user": "Неуспешна покана на потребителя" } From 94a0a904574ba3e63bf80dffc381db2f20842747 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 16 Feb 2018 14:16:50 +0000 Subject: [PATCH 0325/1160] Make RoomListStore aware of Room.timeline events so that we can do reorderings of lists ordered by most recent event. No optimisations here; we only update for timeline events on live timelines that could update the "unread count". --- src/actions/MatrixActionCreators.js | 10 ++++++ src/components/views/rooms/RoomList.js | 9 ------ src/stores/RoomListStore.js | 43 +++++++++++++++++--------- 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/actions/MatrixActionCreators.js b/src/actions/MatrixActionCreators.js index dbfe910533..27fbb6dda5 100644 --- a/src/actions/MatrixActionCreators.js +++ b/src/actions/MatrixActionCreators.js @@ -66,6 +66,15 @@ function createRoomTagsAction(matrixClient, roomTagsEvent, room) { return { action: 'MatrixActions.Room.tags', room }; } +function createRoomTimelineAction(matrixClient, timelineEvent, room, toStartOfTimeline, removed, data) { + return { + action: 'MatrixActions.Room.timeline', + event: timelineEvent, + isLiveEvent: data.liveEvent, + room, + }; +} + function createRoomMembershipAction(matrixClient, membershipEvent, member, oldMembership) { return { action: 'MatrixActions.RoomMember.membership', member }; } @@ -87,6 +96,7 @@ export default { this._addMatrixClientListener(matrixClient, 'sync', createSyncAction); this._addMatrixClientListener(matrixClient, 'accountData', createAccountDataAction); this._addMatrixClientListener(matrixClient, 'Room.tags', createRoomTagsAction); + this._addMatrixClientListener(matrixClient, 'Room.timeline', createRoomTimelineAction); this._addMatrixClientListener(matrixClient, 'RoomMember.membership', createRoomMembershipAction); }, diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 41a200420d..bab8054c60 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -76,7 +76,6 @@ module.exports = React.createClass({ cli.on("Room", this.onRoom); cli.on("deleteRoom", this.onDeleteRoom); - cli.on("Room.timeline", this.onRoomTimeline); cli.on("Room.name", this.onRoomName); cli.on("Room.receipt", this.onRoomReceipt); cli.on("RoomState.events", this.onRoomStateEvents); @@ -177,7 +176,6 @@ module.exports = React.createClass({ if (MatrixClientPeg.get()) { MatrixClientPeg.get().removeListener("Room", this.onRoom); MatrixClientPeg.get().removeListener("deleteRoom", this.onDeleteRoom); - MatrixClientPeg.get().removeListener("Room.timeline", this.onRoomTimeline); MatrixClientPeg.get().removeListener("Room.name", this.onRoomName); MatrixClientPeg.get().removeListener("Room.receipt", this.onRoomReceipt); MatrixClientPeg.get().removeListener("RoomState.events", this.onRoomStateEvents); @@ -236,13 +234,6 @@ module.exports = React.createClass({ this._updateStickyHeaders(true, scrollToPosition); }, - onRoomTimeline: function(ev, room, toStartOfTimeline, removed, data) { - if (toStartOfTimeline) return; - if (!room) return; - if (data.timeline.getTimelineSet() !== room.getUnfilteredTimelineSet()) return; - this._delayedRefreshRoomList(); - }, - onRoomReceipt: function(receiptEvent, room) { // because if we read a notification, it will affect notification count // only bother updating if there's a receipt from us diff --git a/src/stores/RoomListStore.js b/src/stores/RoomListStore.js index fdd9ca6692..707a9da17e 100644 --- a/src/stores/RoomListStore.js +++ b/src/stores/RoomListStore.js @@ -23,6 +23,16 @@ import Unread from '../Unread'; * the RoomList. */ class RoomListStore extends Store { + + static _listOrders = { + "m.favourite": "manual", + "im.vector.fake.invite": "recent", + "im.vector.fake.recent": "recent", + "im.vector.fake.direct": "recent", + "m.lowpriority": "recent", + "im.vector.fake.archived": "recent", + }; + constructor() { super(dis); @@ -68,6 +78,14 @@ class RoomListStore extends Store { this._generateRoomLists(); } break; + case 'MatrixActions.Room.timeline': { + if (!this._state.ready || + !payload.isLiveEvent || + !this._eventTriggersRecentReorder(payload.event) + ) break; + this._generateRoomLists(); + } + break; case 'MatrixActions.accountData': { if (payload.event_type !== 'm.direct') break; this._generateRoomLists(); @@ -159,18 +177,9 @@ class RoomListStore extends Store { } }); - const listOrders = { - "m.favourite": "manual", - "im.vector.fake.invite": "recent", - "im.vector.fake.recent": "recent", - "im.vector.fake.direct": "recent", - "m.lowpriority": "recent", - "im.vector.fake.archived": "recent", - }; - Object.keys(lists).forEach((listKey) => { let comparator; - switch (listOrders[listKey]) { + switch (RoomListStore._listOrders[listKey]) { case "recent": comparator = this._recentsComparator; break; @@ -188,13 +197,17 @@ class RoomListStore extends Store { }); } + _eventTriggersRecentReorder(ev) { + return ev.getTs() && ( + Unread.eventTriggersUnreadCount(ev) || + ev.getSender() === this._matrixClient.credentials.userId + ); + } + _tsOfNewestEvent(room) { for (let i = room.timeline.length - 1; i >= 0; --i) { const ev = room.timeline[i]; - if (ev.getTs() && - (Unread.eventTriggersUnreadCount(ev) || - (ev.getSender() === this._matrixClient.credentials.userId)) - ) { + if (this._eventTriggersRecentReorder(ev)) { return ev.getTs(); } } @@ -210,6 +223,8 @@ class RoomListStore extends Store { } _recentsComparator(roomA, roomB) { + // XXX: We could use a cache here and update it when we see new + // events that trigger a reorder return this._tsOfNewestEvent(roomB) - this._tsOfNewestEvent(roomA); } From 84ab1ae3e2996157c358f0ca152669585be93863 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 16 Feb 2018 15:52:15 +0000 Subject: [PATCH 0326/1160] Do not assume that tags have been removed when moving tags --- src/actions/TagOrderActions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/actions/TagOrderActions.js b/src/actions/TagOrderActions.js index 38bada2228..a257ff16d8 100644 --- a/src/actions/TagOrderActions.js +++ b/src/actions/TagOrderActions.js @@ -35,7 +35,7 @@ const TagOrderActions = {}; TagOrderActions.moveTag = function(matrixClient, tag, destinationIx) { // Only commit tags if the state is ready, i.e. not null let tags = TagOrderStore.getOrderedTags(); - let removedTags = TagOrderStore.getRemovedTagsAccountData(); + let removedTags = TagOrderStore.getRemovedTagsAccountData() || []; if (!tags) { return; } From cca820c3538ae6e806fd6929b34f728eaf35d109 Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Fri, 16 Feb 2018 11:48:04 +0000 Subject: [PATCH 0327/1160] Translated using Weblate (Bulgarian) Currently translated at 15.2% (150 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 948181fa9d..5df65775fe 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -117,5 +117,36 @@ "Invite new room members": "Покани нови членове на стаята", "Who would you like to add to this room?": "Кой бихте желали да добавите в тази стая?", "Send Invites": "Изпрати покани", - "Failed to invite user": "Неуспешна покана на потребителя" + "Failed to invite user": "Неуспешна покана на потребителя", + "Failed to invite": "Неуспешна покана", + "Failed to invite the following users to the %(roomName)s room:": "Следните потребителите не успяха да бъдат добавени в %(roomName)s:", + "You need to be logged in.": "Трябва да влезете в профила си.", + "You need to be able to invite users to do that.": "Трябва да имате право да добавите потребители, за да извършите това.", + "Unable to create widget.": "Неуспешно създаване на приспособление.", + "Failed to send request.": "Неуспешно изпращане на запитване.", + "This room is not recognised.": "Стаята не е разпозната.", + "Power level must be positive integer.": "Нивото на достъп трябва да бъде позитивно число.", + "Call Anyway": "Обади се въпреки това", + "Answer Anyway": "Отговори въпреки това", + "Call Timeout": "Изтекло време за повикване", + "The remote side failed to pick up": "Отсрещната страна не успя да отговори", + "Unable to capture screen": "Неуспешно заснемане на екрана", + "You are not in this room.": "Не сте в тази стая.", + "You do not have permission to do that in this room.": "Нямате достъп да направите това в тази стая.", + "Missing room_id in request": "Липсва room_id в заявката", + "Room %(roomId)s not visible": "Стая %(roomId)s не е видима", + "Missing user_id in request": "Липсва user_id в заявката", + "Failed to lookup current room": "Неуспешно намиране на текущата стая", + "/ddg is not a command": "/ddg не е команда", + "To use it, just wait for autocomplete results to load and tab through them.": "За използване, изчакайте зареждането на списъка с предложения и изберете от него.", + "Unrecognised room alias:": "Непознат псевдоним на стая:", + "Ignored user": "Игнориран потребител", + "You are now ignoring %(userId)s": "Вече игнорирате %(userId)s", + "Unignored user": "Неигнориран потребител", + "You are no longer ignoring %(userId)s": "Вече не игнорирате %(userId)s", + "Device already verified!": "Устройството е вече верифицирано!", + "WARNING: Device already verified, but keys do NOT MATCH!": "ВНИМАНИЕ: Устройстовото е верифицирано, но ключовете не съвпадат!", + "Verified key": "Верифициран ключ", + "Unrecognised command:": "Неразпозната команда:", + "Reason": "Причина" } From f2903d1439eb62cdc97dca0b2eb71ed586c39472 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 16 Feb 2018 08:45:19 +0000 Subject: [PATCH 0328/1160] Translated using Weblate (Finnish) Currently translated at 95.2% (939 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fi/ --- src/i18n/strings/fi.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/fi.json b/src/i18n/strings/fi.json index fc7eac51a7..48a8ea755f 100644 --- a/src/i18n/strings/fi.json +++ b/src/i18n/strings/fi.json @@ -561,7 +561,7 @@ "Sep": "syyskuu", "Oct": "lokakuu", "Nov": "marraskuu", - "Dec": "jolukuu", + "Dec": "joulukuu", "User names may only contain letters, numbers, dots, hyphens and underscores.": "Käyttäjänimet voivat sisältää vain kirjaimia, numeroita, pisteitä, viivoja ja alaviivoja.", "To continue, please enter your password.": "Ole hyvä ja syötä salasanasi jatkaaksesi.", "Verifies a user, device, and pubkey tuple": "Varmentaa käyttäjän, laitteen ja julkisen avaimen kolmikon", From 3f6c15506c4116cb7bbe016c167d8d759842ab1f Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 16 Feb 2018 16:17:47 +0000 Subject: [PATCH 0329/1160] Remove unused `room` parameter of MatrixActions.Room.timeline --- src/actions/MatrixActionCreators.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/actions/MatrixActionCreators.js b/src/actions/MatrixActionCreators.js index 27fbb6dda5..a9ea671fbe 100644 --- a/src/actions/MatrixActionCreators.js +++ b/src/actions/MatrixActionCreators.js @@ -71,7 +71,6 @@ function createRoomTimelineAction(matrixClient, timelineEvent, room, toStartOfTi action: 'MatrixActions.Room.timeline', event: timelineEvent, isLiveEvent: data.liveEvent, - room, }; } From cbeee72062c6e9f4fb7fb3e24b91beb92454d1f6 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 16 Feb 2018 10:11:04 -0700 Subject: [PATCH 0330/1160] Don't show empty custom tags when filtering tags Signed-off-by: Travis Ralston --- src/components/views/rooms/RoomList.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 41a200420d..68b171b0ee 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -34,6 +34,7 @@ import RoomListStore from '../../../stores/RoomListStore'; import GroupStoreCache from '../../../stores/GroupStoreCache'; const HIDE_CONFERENCE_CHANS = true; +const STANDARD_TAGS_REGEX = /^(m\.(favourite|lowpriority)|im\.vector\.fake\.(invite|recent|direct|archived))$/; function phraseForSection(section) { switch (section) { @@ -365,7 +366,7 @@ module.exports = React.createClass({ }); Object.keys(lists).forEach((tagName) => { - filteredLists[tagName] = lists[tagName].filter((taggedRoom) => { + const filteredRooms = lists[tagName].filter((taggedRoom) => { // Somewhat impossible, but guard against it anyway if (!taggedRoom) { return; @@ -377,6 +378,10 @@ module.exports = React.createClass({ return Boolean(isRoomVisible[taggedRoom.roomId]); }); + + if (filteredRooms.length > 0 || tagName.match(STANDARD_TAGS_REGEX)) { + filteredLists[tagName] = filteredRooms; + } }); return filteredLists; @@ -682,7 +687,7 @@ module.exports = React.createClass({ onShowMoreRooms={self.onShowMoreRooms} /> { Object.keys(self.state.lists).map((tagName) => { - if (!tagName.match(/^(m\.(favourite|lowpriority)|im\.vector\.fake\.(invite|recent|direct|archived))$/)) { + if (!tagName.match(STANDARD_TAGS_REGEX)) { return Date: Fri, 16 Feb 2018 17:43:24 +0000 Subject: [PATCH 0331/1160] Implement global filter to deselect all tags and make TagPanel scrollable whilst we're at it. --- src/components/structures/TagPanel.js | 51 +++++++++++++++++---------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/src/components/structures/TagPanel.js b/src/components/structures/TagPanel.js index 6e3bcf521b..74b6656b79 100644 --- a/src/components/structures/TagPanel.js +++ b/src/components/structures/TagPanel.js @@ -17,6 +17,7 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import { MatrixClient } from 'matrix-js-sdk'; +import GeminiScrollbar from 'react-gemini-scrollbar'; import TagOrderStore from '../../stores/TagOrderStore'; import GroupActions from '../../actions/GroupActions'; @@ -93,9 +94,14 @@ const TagPanel = React.createClass({ dis.dispatch({action: 'view_create_group'}); }, + onLogoClick(ev) { + dis.dispatch({action: 'deselect_tags'}); + }, + render() { const GroupsButton = sdk.getComponent('elements.GroupsButton'); const DNDTagTile = sdk.getComponent('elements.DNDTagTile'); + const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); const tags = this.state.orderedTags.map((tag, index) => { return ; }); return
    - - { (provided, snapshot) => ( -
    - { tags } - { provided.placeholder } -
    - ) } -
    + + + +
    + + + { (provided, snapshot) => ( +
    + { tags } + { provided.placeholder } +
    + ) } +
    +
    +
    From 7a0c82a327b7df5e28160c10cfd89fb55ee9b798 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 16 Feb 2018 18:08:29 +0000 Subject: [PATCH 0332/1160] Fix click background to deselect --- src/components/structures/TagPanel.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/components/structures/TagPanel.js b/src/components/structures/TagPanel.js index 74b6656b79..d614588ccc 100644 --- a/src/components/structures/TagPanel.js +++ b/src/components/structures/TagPanel.js @@ -84,8 +84,6 @@ const TagPanel = React.createClass({ }, onClick(e) { - // Ignore clicks on children - if (e.target !== e.currentTarget) return; dis.dispatch({action: 'deselect_tags'}); }, @@ -116,7 +114,11 @@ const TagPanel = React.createClass({
    - + { tags } { provided.placeholder } From 8062494692d5781cb223d2dc63c4ef42391ad94f Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 16 Feb 2018 20:58:39 +0000 Subject: [PATCH 0333/1160] show replies in ReplyPreview Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/EventTile.js | 21 +++++++++++++++++++++ src/components/views/rooms/ReplyPreview.js | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 3b72525fbd..36fc87b7cd 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -609,6 +609,27 @@ module.exports = withMatrixClient(React.createClass({
    ); } + case 'reply_preview': { + return ( +
    + { avatar } + { sender } +
    + + { timestamp } + + { this._renderE2EPadlock() } + { Reply.getQuote(this.props.mxEvent, this.props.onWidgetLoad) } + +
    +
    + ); + } default: { return (
    diff --git a/src/components/views/rooms/ReplyPreview.js b/src/components/views/rooms/ReplyPreview.js index 045c3da9b3..0404511c9f 100644 --- a/src/components/views/rooms/ReplyPreview.js +++ b/src/components/views/rooms/ReplyPreview.js @@ -71,7 +71,7 @@ export default class ReplyPreview extends React.Component { onClick={cancelQuoting} />
    - +
    ; } From cb293a852dec1ba884ade960e65b9288f4039851 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 16 Feb 2018 21:07:25 +0000 Subject: [PATCH 0334/1160] reply and reply_preview only differ in whether they contain Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/EventTile.js | 29 ++++++------------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 36fc87b7cd..5ccba1cf0f 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -589,37 +589,22 @@ module.exports = withMatrixClient(React.createClass({
    ); } - case 'reply': { - return ( -
    - { avatar } - { sender } -
    - - { timestamp } - - { this._renderE2EPadlock() } - -
    -
    - ); - } + + case 'reply': case 'reply_preview': { return (
    { avatar } { sender } -
    +
    { timestamp } { this._renderE2EPadlock() } - { Reply.getQuote(this.props.mxEvent, this.props.onWidgetLoad) } + { + this.props.tileShape === 'reply_preview' + && Reply.getQuote(this.props.mxEvent, this.props.onWidgetLoad) + } Date: Fri, 16 Feb 2018 21:14:03 +0000 Subject: [PATCH 0335/1160] fix 12/24h in Reply/ReplyPreview Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Reply.js | 5 ++++- src/components/views/rooms/ReplyPreview.js | 7 ++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/components/views/elements/Reply.js b/src/components/views/elements/Reply.js index 944d90cdbd..f9161c7ada 100644 --- a/src/components/views/elements/Reply.js +++ b/src/components/views/elements/Reply.js @@ -197,7 +197,10 @@ export default class Reply extends React.Component { return
    { dateSep } - +
    ; }); diff --git a/src/components/views/rooms/ReplyPreview.js b/src/components/views/rooms/ReplyPreview.js index 0404511c9f..18e21c5ebc 100644 --- a/src/components/views/rooms/ReplyPreview.js +++ b/src/components/views/rooms/ReplyPreview.js @@ -19,6 +19,7 @@ import dis from '../../../dispatcher'; import sdk from '../../../index'; import { _t } from '../../../languageHandler'; import RoomViewStore from '../../../stores/RoomViewStore'; +import SettingsStore from "../../../settings/SettingsStore"; function cancelQuoting() { dis.dispatch({ @@ -71,7 +72,11 @@ export default class ReplyPreview extends React.Component { onClick={cancelQuoting} />
    - +
    ; } From 0d6fc9bd3a31ffa64e93030ff36ebb40db146250 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 16 Feb 2018 21:17:41 +0000 Subject: [PATCH 0336/1160] fix Composer focus after twiddling with Replies Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Reply.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/views/elements/Reply.js b/src/components/views/elements/Reply.js index f9161c7ada..4a9d0d3380 100644 --- a/src/components/views/elements/Reply.js +++ b/src/components/views/elements/Reply.js @@ -17,6 +17,7 @@ import React from 'react'; import sdk from '../../../index'; import {_t} from '../../../languageHandler'; import PropTypes from 'prop-types'; +import dis from '../../../dispatcher'; import MatrixClientPeg from '../../../MatrixClientPeg'; import {wantsDateSeparator} from '../../../DateUtils'; import {MatrixEvent} from 'matrix-js-sdk'; @@ -131,6 +132,8 @@ export default class Reply extends React.Component { loadedEv: null, events, }, this.loadNextEvent); + + dis.dispatch({action: 'focus_composer'}); } static getInReplyTo(ev) { From 4c08c51044e5bca4523b7374310d486d23e1507c Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 16 Feb 2018 21:24:42 +0000 Subject: [PATCH 0337/1160] Reply; delay call to onWidgetLoad until after async setState completes Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Reply.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/components/views/elements/Reply.js b/src/components/views/elements/Reply.js index 4a9d0d3380..bbcfa00b25 100644 --- a/src/components/views/elements/Reply.js +++ b/src/components/views/elements/Reply.js @@ -82,7 +82,6 @@ export default class Reply extends React.Component { } async loadNextEvent() { - this.props.onWidgetLoad(); const ev = this.state.events[0]; const inReplyTo = Reply.getInReplyTo(ev); @@ -90,7 +89,7 @@ export default class Reply extends React.Component { if (this.unmounted) return; this.setState({ loading: false, - }); + }, this.props.onWidgetLoad); return; } @@ -98,9 +97,9 @@ export default class Reply extends React.Component { if (this.unmounted) return; if (loadedEv) { - this.setState({loadedEv}); + this.setState({loadedEv}, this.props.onWidgetLoad); } else { - this.setState({err: true}); + this.setState({err: true}, this.props.onWidgetLoad); } } From 2d5a2a9d48b3c7446cb00a2b3c8014b4edac3b11 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Fri, 16 Feb 2018 23:59:48 +0000 Subject: [PATCH 0338/1160] improve origin check of ScalarMessaging postmessage API. ensures that https://scalar.ve can't access the API. many thanks to @rugk for pointing out the potential vuln. cc @rxl881 in case this bug has been transplanted elsewhere. --- src/ScalarMessaging.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index 3c164c6551..fc8ee9edf6 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -563,7 +563,7 @@ const onMessage = function(event) { const url = SdkConfig.get().integrations_ui_url; if ( event.origin.length === 0 || - !url.startsWith(event.origin) || + !url.startsWith(event.origin + '/') || !event.data.action || event.data.api // Ignore messages with specific API set ) { From 32130fbc28bc315adae9cd88bc19226f9ff121a6 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 19 Feb 2018 09:56:03 +0000 Subject: [PATCH 0339/1160] Don't regenerate RoomListStore state for notifs/scrollback/etc. Only do so for the live timeline of rooms. --- src/actions/MatrixActionCreators.js | 2 ++ src/stores/RoomListStore.js | 1 + 2 files changed, 3 insertions(+) diff --git a/src/actions/MatrixActionCreators.js b/src/actions/MatrixActionCreators.js index a9ea671fbe..a307af6f57 100644 --- a/src/actions/MatrixActionCreators.js +++ b/src/actions/MatrixActionCreators.js @@ -71,6 +71,8 @@ function createRoomTimelineAction(matrixClient, timelineEvent, room, toStartOfTi action: 'MatrixActions.Room.timeline', event: timelineEvent, isLiveEvent: data.liveEvent, + isLiveUnfilteredRoomTimelineEvent: + room && data.timeline.getTimelineSet() === room.getUnfilteredTimelineSet(), }; } diff --git a/src/stores/RoomListStore.js b/src/stores/RoomListStore.js index 707a9da17e..8a3af309fc 100644 --- a/src/stores/RoomListStore.js +++ b/src/stores/RoomListStore.js @@ -81,6 +81,7 @@ class RoomListStore extends Store { case 'MatrixActions.Room.timeline': { if (!this._state.ready || !payload.isLiveEvent || + !payload.isLiveUnfilteredRoomTimelineEvent || !this._eventTriggersRecentReorder(payload.event) ) break; this._generateRoomLists(); From da35871cb1952255335ab502aebf2ad5939825f6 Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Sun, 18 Feb 2018 20:21:27 +0000 Subject: [PATCH 0340/1160] Translated using Weblate (Bulgarian) Currently translated at 24.4% (241 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 93 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 92 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 5df65775fe..ae049dff52 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -148,5 +148,96 @@ "WARNING: Device already verified, but keys do NOT MATCH!": "ВНИМАНИЕ: Устройстовото е верифицирано, но ключовете не съвпадат!", "Verified key": "Верифициран ключ", "Unrecognised command:": "Неразпозната команда:", - "Reason": "Причина" + "Reason": "Причина", + "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s прие поканата за %(displayName)s.", + "%(targetName)s accepted an invitation.": "%(targetName)s прие поканата.", + "%(senderName)s requested a VoIP conference.": "%(senderName)s заяви VoIP конферентен разговор.", + "%(senderName)s invited %(targetName)s.": "%(senderName)s покани %(targetName)s.", + "%(senderName)s banned %(targetName)s.": "%(senderName)s блокира %(targetName)s.", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s смени своето име/псевдоним на %(displayName)s.", + "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s промени своето име на %(displayName)s.", + "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s премахна своето име (%(oldDisplayName)s).", + "%(senderName)s removed their profile picture.": "%(senderName)s премахна своята профилна снимка.", + "%(senderName)s changed their profile picture.": "%(senderName)s промени своята профилна снимка.", + "%(senderName)s set a profile picture.": "%(senderName)s зададе снимка на профила си.", + "VoIP conference started.": "VoIP конференцията започна.", + "%(targetName)s joined the room.": "%(targetName)s се присъедини към стаята.", + "VoIP conference finished.": "VoIP конференцията приключи.", + "%(targetName)s rejected the invitation.": "%(targetName)s отказа поканата.", + "%(targetName)s left the room.": "%(targetName)s напусна стаята.", + "%(senderName)s unbanned %(targetName)s.": "%(senderName)s отблокира %(targetName)s.", + "%(senderName)s kicked %(targetName)s.": "%(senderName)s изгони %(targetName)s.", + "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s оттегли поканата си към %(targetName)s.", + "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s смени темата на \"%(topic)s\".", + "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s премахна името на стаята.", + "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s промени името на стаята на %(roomName)s.", + "%(senderDisplayName)s sent an image.": "%(senderDisplayName)s изпрати снимка.", + "Someone": "Някой", + "(not supported by this browser)": "(не се поддържа от този браузър)", + "%(senderName)s answered the call.": "%(senderName)s отговори на повикването.", + "(no answer)": "(няма отговор)", + "(unknown failure: %(reason)s)": "(непозната грешка: %(reason)s)", + "%(senderName)s ended the call.": "%(senderName)s прекрати разговора.", + "%(senderName)s placed a %(callType)s call.": "%(senderName)s започна %(callType)s разговор.", + "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s изпрати покана на %(targetDisplayName)s да се присъедини към стаята.", + "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s направи бъдещата история на стаята видима за всички членове на стаята, от момента, в който те са поканени в нея.", + "%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s направи бъдещата история на стаята видима за всички членове на стаята, от момента, в който те се присъединят към нея.", + "%(senderName)s made future room history visible to all room members.": "%(senderName)s направи бъдещата история на стаята видима за всички членове в нея.", + "%(senderName)s made future room history visible to anyone.": "%(senderName)s направи бъдещата история на стаята видима за всеки.", + "%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s направи бъдещата история на стаята видима за непознат (%(visibility)s).", + "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s включи шифроване от край до край (алгоритъм %(algorithm)s).", + "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s с %(fromPowerLevel)s на %(toPowerLevel)s", + "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s смени нивото на достъп на %(powerLevelDiffText)s.", + "%(senderName)s changed the pinned messages for the room.": "%(senderName)s смени закачените съобщения на стаята.", + "%(widgetName)s widget modified by %(senderName)s": "Приспособлението %(widgetName)s е променено от %(senderName)s", + "%(widgetName)s widget added by %(senderName)s": "Приспособлението %(widgetName)s е добавено от %(senderName)s", + "%(widgetName)s widget removed by %(senderName)s": "Приспособлението %(widgetName)s е премахнато от %(senderName)s", + "%(displayName)s is typing": "%(displayName)s пише", + "%(names)s and %(count)s others are typing|other": "%(names)s и %(count)s други пишат", + "%(names)s and %(count)s others are typing|one": "%(names)s и още един човек пишат", + "%(names)s and %(lastPerson)s are typing": "%(names)s и %(lastPerson)s пишат", + "Failure to create room": "Неуспешно създаване на стая", + "Server may be unavailable, overloaded, or you hit a bug.": "Сървърът може би е претоварен, недостъпен или се натъкнахте на проблем.", + "Send anyway": "Изпрати така или иначе", + "Unnamed Room": "Стая без име", + "Your browser does not support the required cryptography extensions": "Вашият браузър не поддържа необходимите разширения за шифроване", + "Not a valid Riot keyfile": "Невалиден Riot ключов файл", + "Authentication check failed: incorrect password?": "Неуспешна автентикация: неправилна парола?", + "Failed to join room": "Неуспешно присъединяване към стаята", + "Message Replies": "Отговори на съобщението", + "Message Pinning": "Закачания на съобщението", + "Presence Management": "Управление на присъствието", + "Tag Panel": "Панел с етикети", + "Disable Emoji suggestions while typing": "Деактивиране на предложенията за емотиконите при писане", + "Use compact timeline layout": "Използване на компактно оформление за списъка със съобщения", + "Hide removed messages": "Скриване на премахнати съобщения", + "Hide join/leave messages (invites/kicks/bans unaffected)": "Скриване на съобщения присъединяване/напускане (покани/изгонвания/блокиране незасегнати)", + "Hide avatar changes": "Скриване промени на аватара", + "Hide display name changes": "Скриване промени на името", + "Hide read receipts": "Скриване", + "Show timestamps in 12 hour format (e.g. 2:30pm)": "Показване на времето в 12-часов формат (напр. 2:30pm)", + "Always show message timestamps": "Винаги показвай времето", + "Autoplay GIFs and videos": "Автоматично възпроизвеждане на GIF-файлове и видеа", + "Enable automatic language detection for syntax highlighting": "Активиране на автоматичното разпознаване на език за подчертаване на синтаксиса", + "Disable big emoji in chat": "Деактивиране на големи емотикони в чата", + "Don't send typing notifications": "Не изпращай известия за писане", + "Automatically replace plain text Emoji": "Автоматично откриване и заместване на емотикони в текста", + "Mirror local video feed": "Огледален образ", + "Disable Peer-to-Peer for 1:1 calls": "Деактивиране на Peer-to-Peer в 1:1 разговор", + "Opt out of analytics": "Отказване от събиране на статистически данни", + "Never send encrypted messages to unverified devices from this device": "Никога не изпращай шифровани съобщения до непотвърдени устройства от това устройство", + "Never send encrypted messages to unverified devices in this room from this device": "Никога не изпращай шифровани съобщение до непотвърдени устройства в тази стая от това устройство", + "Enable inline URL previews by default": "Включване по подразбиране на URL прегледи", + "Enable URL previews for this room (only affects you)": "Включване на URL прегледи за тази стая (засяга само Вас)", + "Enable URL previews by default for participants in this room": "Включване по подразбиране на URL прегледи за участниците в тази стая", + "Room Colour": "Цвят на стая", + "Active call (%(roomName)s)": "Активен разговор (%(roomName)s)", + "unknown caller": "повикване от непознат", + "Incoming voice call from %(name)s": "Входящо гласово повикване от %(name)s", + "Incoming video call from %(name)s": "Входящо видео повикване от %(name)s", + "Incoming call from %(name)s": "Входящо повикване от %(name)s", + "Decline": "Откажи", + "Accept": "Приеми", + "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Съобщение е изпратено до +%(msisdn)s. Моля въведете кода за потвърждение, което то съдържа", + "Incorrect verification code": "Неправилен код за потвърждение" } From 71a1de1e73e77367d8d51841bb312633a0b3ee4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sim=C3=B3=20Albert=20i=20Beltran?= Date: Sat, 17 Feb 2018 13:40:44 +0000 Subject: [PATCH 0341/1160] Translated using Weblate (Catalan) Currently translated at 89.2% (880 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ca/ --- src/i18n/strings/ca.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ca.json b/src/i18n/strings/ca.json index 0b1a7b10ef..120134e296 100644 --- a/src/i18n/strings/ca.json +++ b/src/i18n/strings/ca.json @@ -869,5 +869,14 @@ "Email": "Correu electrònic", "Add email address": "Afegeix correu electrònic", "I have verified my email address": "He verificat l'adreça de correu electrònic", - "Send Reset Email": "Envia email de reinici" + "Send Reset Email": "Envia email de reinici", + "Your homeserver's URL": "URL del teu homeserver", + "Your identity server's URL": "URL del teu servidor d'identitat", + "Analytics": "Analítiques", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s ha canviat el seu nom visible a %(displayName)s", + "Server may be unavailable or overloaded": "El servidor pot estar inaccessible o sobrecarregat", + "Report it": "Informa", + "Found a bug?": "Has trobat un error?", + "Display name": "Nom visible", + "Identity Server is": "El servidor d'identitat es" } From 8fa56f8c9a882299c1308ba9c42b6098ca1408b5 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 19 Feb 2018 14:27:10 +0000 Subject: [PATCH 0342/1160] update and improve comments Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Reply.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/views/elements/Reply.js b/src/components/views/elements/Reply.js index bbcfa00b25..6da589e7f2 100644 --- a/src/components/views/elements/Reply.js +++ b/src/components/views/elements/Reply.js @@ -24,14 +24,14 @@ import {MatrixEvent} from 'matrix-js-sdk'; import {makeUserPermalink} from "../../../matrix-to"; import SettingsStore from "../../../settings/SettingsStore"; -// This component does no cycle detection, simply because the only way to make such a cycle -// would be to craft event_id's, using a custom homeserver; even then the impact would be low -// as each event being loaded (after the first) is triggered by an explicit user action. +// This component does no cycle detection, simply because the only way to make such a cycle would be to +// craft event_id's, using a homeserver that generates predictable event IDs; even then the impact would +// be low as each event being loaded (after the first) is triggered by an explicit user action. export default class Reply extends React.Component { static propTypes = { - // The parent event + // the latest event in this chain of replies parentEv: PropTypes.instanceOf(MatrixEvent), - + // called when the preview's contents has loaded onWidgetLoad: PropTypes.func.isRequired, }; From 6510989ac6affa725a026d348cceb623883de37a Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 19 Feb 2018 14:28:31 +0000 Subject: [PATCH 0343/1160] move unmounted init to willMount Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Reply.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/views/elements/Reply.js b/src/components/views/elements/Reply.js index 6da589e7f2..67e6b9d9ca 100644 --- a/src/components/views/elements/Reply.js +++ b/src/components/views/elements/Reply.js @@ -52,11 +52,10 @@ export default class Reply extends React.Component { }; this.onQuoteClick = this.onQuoteClick.bind(this); - - this.unmounted = false; } componentWillMount() { + this.unmounted = false; this.room = this.getRoom(this.props.parentEv.getRoomId()); this.initialize(); } From 4998890a0ef656f2d5a979f3ed57a6e551bd40fe Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Mon, 19 Feb 2018 16:12:43 +0000 Subject: [PATCH 0344/1160] Translated using Weblate (Bulgarian) Currently translated at 27.7% (274 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index ae049dff52..d5dd208602 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -239,5 +239,38 @@ "Decline": "Откажи", "Accept": "Приеми", "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Съобщение е изпратено до +%(msisdn)s. Моля въведете кода за потвърждение, което то съдържа", - "Incorrect verification code": "Неправилен код за потвърждение" + "Incorrect verification code": "Неправилен код за потвърждение", + "Enter Code": "Въведи код", + "Submit": "Изпрати", + "Phone": "Телефон", + "Add phone number": "Добави телефонен номер", + "Add": "Добави", + "Failed to upload profile picture!": "Неуспешно качване на профилна снимка!", + "Upload new:": "Качи нов:", + "No display name": "Няма име", + "New passwords don't match": "Новите пароли не съвпадат", + "Passwords can't be empty": "Полето с парола не може да е празно", + "Export E2E room keys": "Експортиране E2E ключове на стая", + "Do you want to set an email address?": "Искате ли да зададете имейл адрес?", + "Current password": "Текуща парола", + "Password": "Парола", + "New Password": "Нова парола", + "Confirm password": "Потвърждаване на парола", + "Change Password": "Смяна на парола", + "Your home server does not support device management.": "Вашият home сървър не поддръжа управление на устройства.", + "Unable to load device list": "Неуспешно зареждане на списък с устройства", + "Authentication": "Автентикация", + "Delete %(count)s devices|other": "Изтрий %(count)s устройства", + "Delete %(count)s devices|one": "Изтрий устройство", + "Device ID": "Идентификатор на устройство", + "Device Name": "Име на устройство", + "Last seen": "Последно видян", + "Select devices": "Избери устройства", + "Failed to set display name": "Неуспешно задаване на име", + "Disable Notifications": "Изключване на известия", + "Enable Notifications": "Включване на известия", + "Cannot add any more widgets": "Не могат да се добавят повече приспособления", + "The maximum permitted number of widgets have already been added to this room.": "Максимално разрешеният брой приспособления е вече добавен към тази стая.", + "Add a widget": "Добавяне на приспособление", + "Drop File Here": "Постави файл тук" } From 34b427d15e106eb46a459ff0a1fe8722e8a57701 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 19 Feb 2018 23:41:07 +0000 Subject: [PATCH 0345/1160] s/quote_event/reply_to_event/ Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- .../views/rooms/MessageComposerInput.js | 11 ++--------- src/components/views/rooms/ReplyPreview.js | 2 +- src/stores/RoomViewStore.js | 16 +++++++++++----- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index c051471ba6..1de53b4cfc 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -275,7 +275,7 @@ export default class MessageComposerInput extends React.Component { let contentState = this.state.editorState.getCurrentContent(); switch (payload.action) { - case 'quote_event': + case 'reply_to_event': case 'focus_composer': editor.focus(); break; @@ -838,14 +838,7 @@ export default class MessageComposerInput extends React.Component { sendTextFn = ContentHelpers.makeEmoteMessage; } - const quotingEv = RoomViewStore.getQuotingEvent(); - const content = quotingEv ? Reply.getRelationship(quotingEv) : {}; - // we have finished quoting, clear the quotingEvent - // TODO maybe delay this until the event actually sends? - dis.dispatch({ - action: 'quote_event', - event: null, - }); + const content = Reply.getMRelatesTo(RoomViewStore.getQuotingEvent()); let sendMessagePromise; if (contentHTML) { diff --git a/src/components/views/rooms/ReplyPreview.js b/src/components/views/rooms/ReplyPreview.js index 18e21c5ebc..dd11b0df33 100644 --- a/src/components/views/rooms/ReplyPreview.js +++ b/src/components/views/rooms/ReplyPreview.js @@ -23,7 +23,7 @@ import SettingsStore from "../../../settings/SettingsStore"; function cancelQuoting() { dis.dispatch({ - action: 'quote_event', + action: 'reply_to_event', event: null, }); } diff --git a/src/stores/RoomViewStore.js b/src/stores/RoomViewStore.js index 4c010f4e8e..2c81f9de23 100644 --- a/src/stores/RoomViewStore.js +++ b/src/stores/RoomViewStore.js @@ -111,10 +111,16 @@ class RoomViewStore extends Store { forwardingEvent: payload.event, }); break; - case 'quote_event': + case 'reply_to_event': this._setState({ - quotingEvent: payload.event, + replyingToEvent: payload.event, }); + break; + case 'message_sent': + this._setState({ + replyingToEvent: null, + }); + break; } } @@ -132,8 +138,8 @@ class RoomViewStore extends Store { shouldPeek: payload.should_peek === undefined ? true : payload.should_peek, // have we sent a join request for this room and are waiting for a response? joining: payload.joining || false, - // Reset quotingEvent because we don't want cross-room because bad UX - quotingEvent: null, + // Reset replyingToEvent because we don't want cross-room because bad UX + replyingToEvent: null, }; if (this._state.forwardingEvent) { @@ -297,7 +303,7 @@ class RoomViewStore extends Store { // The mxEvent if one is currently being replied to/quoted getQuotingEvent() { - return this._state.quotingEvent; + return this._state.replyingToEvent; } shouldPeek() { From 7048d85246200aefa04dfa4bfbc8d1aa8b31836a Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 19 Feb 2018 23:42:04 +0000 Subject: [PATCH 0346/1160] attach message_sent and replies to file uploads Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/ContentMessages.js | 6 +++--- src/components/structures/RoomView.js | 13 ++++++++--- src/components/views/elements/Reply.js | 30 +++++++++++--------------- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/ContentMessages.js b/src/ContentMessages.js index 8d40b65124..f0e8736aba 100644 --- a/src/ContentMessages.js +++ b/src/ContentMessages.js @@ -275,13 +275,13 @@ class ContentMessages { this.nextId = 0; } - sendContentToRoom(file, roomId, matrixClient) { - const content = { + sendContentToRoom(file, roomId, matrixClient, baseContent) { + const content = Object.assign({}, baseContent, { body: file.name || 'Attachment', info: { size: file.size, }, - }; + }); // if we have a mime type for the file, add it to the message metadata if (file.type) { diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 5304f38901..869dffcf9b 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -45,6 +45,7 @@ import { KeyCode, isOnlyCtrlOrCmdKeyEvent } from '../../Keyboard'; import RoomViewStore from '../../stores/RoomViewStore'; import RoomScrollStateStore from '../../stores/RoomScrollStateStore'; import SettingsStore from "../../settings/SettingsStore"; +import Reply from "../views/elements/Reply"; const DEBUG = false; let debuglog = function() {}; @@ -895,11 +896,17 @@ module.exports = React.createClass({ return; } + const baseContent = Reply.getMRelatesTo(RoomViewStore.getQuotingEvent()); + ContentMessages.sendContentToRoom( - file, this.state.room.roomId, MatrixClientPeg.get(), - ).done(undefined, (error) => { + file, this.state.room.roomId, MatrixClientPeg.get(), baseContent, + ).done(() => { + dis.dispatch({ + action: 'message_sent', + }); + }, (error) => { if (error.name === "UnknownDeviceError") { - // Let the staus bar handle this + // Let the status bar handle this return; } const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); diff --git a/src/components/views/elements/Reply.js b/src/components/views/elements/Reply.js index 67e6b9d9ca..5b213690cc 100644 --- a/src/components/views/elements/Reply.js +++ b/src/components/views/elements/Reply.js @@ -56,7 +56,7 @@ export default class Reply extends React.Component { componentWillMount() { this.unmounted = false; - this.room = this.getRoom(this.props.parentEv.getRoomId()); + this.room = MatrixClientPeg.get().getRoom(this.props.parentEv.getRoomId()); this.initialize(); } @@ -67,8 +67,12 @@ export default class Reply extends React.Component { async initialize() { const {parentEv} = this.props; const inReplyTo = Reply.getInReplyTo(parentEv); + if (!inReplyTo) { + this.setState({err: true}); + return; + } - const ev = await this.getEvent(this.room, inReplyTo['event_id']); + const ev = await Reply.getEvent(this.room, inReplyTo['event_id']); if (this.unmounted) return; if (ev) { @@ -81,18 +85,18 @@ export default class Reply extends React.Component { } async loadNextEvent() { + if (this.unmounted) return; const ev = this.state.events[0]; const inReplyTo = Reply.getInReplyTo(ev); if (!inReplyTo) { - if (this.unmounted) return; this.setState({ loading: false, }, this.props.onWidgetLoad); return; } - const loadedEv = await this.getEvent(this.room, inReplyTo['event_id']); + const loadedEv = await Reply.getEvent(this.room, inReplyTo['event_id']); if (this.unmounted) return; if (loadedEv) { @@ -102,23 +106,14 @@ export default class Reply extends React.Component { } } - getRoom(id) { - const cli = MatrixClientPeg.get(); - if (id[0] === '!') return cli.getRoom(id); - - return cli.getRooms().find((r) => { - return r.getAliases().includes(id); - }); - } - - async getEvent(room, eventId) { + static async getEvent(room, eventId) { const event = room.findEventById(eventId); if (event) return event; try { await MatrixClientPeg.get().getEventTimeline(room.getUnfilteredTimelineSet(), eventId); } catch (e) { - return; + return null; } return room.findEventById(eventId); } @@ -144,7 +139,8 @@ export default class Reply extends React.Component { } } - static getRelationship(ev) { + static getMRelatesTo(ev) { + if (!ev) return {}; return { 'm.relates_to': { 'm.in_reply_to': { @@ -155,7 +151,7 @@ export default class Reply extends React.Component { } static getQuote(parentEv, onWidgetLoad) { - if (!SettingsStore.isFeatureEnabled("feature_rich_quoting") || !Reply.getInReplyTo(parentEv)) return null; + if (!SettingsStore.isFeatureEnabled("feature_rich_quoting") || !Reply.getInReplyTo(parentEv)) return
    ; return ; } From 1c96c1f4d9262cabc1841f0504abc1aee10fc88f Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Tue, 20 Feb 2018 10:17:13 +0000 Subject: [PATCH 0347/1160] Translated using Weblate (Bulgarian) Currently translated at 38.0% (375 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 109 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 105 insertions(+), 4 deletions(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index d5dd208602..1c7c2026ed 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -144,9 +144,9 @@ "You are now ignoring %(userId)s": "Вече игнорирате %(userId)s", "Unignored user": "Неигнориран потребител", "You are no longer ignoring %(userId)s": "Вече не игнорирате %(userId)s", - "Device already verified!": "Устройството е вече верифицирано!", - "WARNING: Device already verified, but keys do NOT MATCH!": "ВНИМАНИЕ: Устройстовото е верифицирано, но ключовете не съвпадат!", - "Verified key": "Верифициран ключ", + "Device already verified!": "Устройството е вече потвърдено!", + "WARNING: Device already verified, but keys do NOT MATCH!": "ВНИМАНИЕ: Устройстовото е потвърдено, но ключовете не съвпадат!", + "Verified key": "Потвърден ключ", "Unrecognised command:": "Неразпозната команда:", "Reason": "Причина", "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s прие поканата за %(displayName)s.", @@ -272,5 +272,106 @@ "Cannot add any more widgets": "Не могат да се добавят повече приспособления", "The maximum permitted number of widgets have already been added to this room.": "Максимално разрешеният брой приспособления е вече добавен към тази стая.", "Add a widget": "Добавяне на приспособление", - "Drop File Here": "Постави файл тук" + "Drop File Here": "Пусни файла тук", + "Drop file here to upload": "Пуснете файла тук, за да се качи", + " (unsupported)": " (не се поддържа)", + "Join as voice or video.": "Присъединете се като voice или video.", + "Ongoing conference call%(supportedText)s.": "Текущ групов разговор %(supportedText)s.", + "%(senderName)s sent an image": "%(senderName)s изпрати снимка", + "%(senderName)s sent a video": "%(senderName)s изпрати видео", + "%(senderName)s uploaded a file": "%(senderName)s качи файл", + "Options": "Настройки", + "Undecryptable": "Невъзможно разшифроване", + "Encrypted by a verified device": "Шифровано от потвърдено устройство", + "Encrypted by an unverified device": "Шифровано от непотвърдено устройство", + "Unencrypted message": "Нешифровано съобщение", + "Please select the destination room for this message": "Моля изберете стаята, в която искате да изпратите това съобщение", + "Blacklisted": "В черен списък", + "Verified": "Потвърдено", + "Unverified": "Непотвърдено", + "device id: ": "идентификатор на устройството: ", + "Disinvite": "Отмени поканата", + "Kick": "Изгони", + "Disinvite this user?": "Отмени поканата към този потребител?", + "Kick this user?": "Изгони този потребител?", + "Failed to kick": "Неуспешно изгонване", + "Unban": "Отблокирай", + "Ban": "Блокирай", + "Unban this user?": "Отблокирай този потребител?", + "Ban this user?": "Блокирай този потребител?", + "Failed to ban user": "Неуспешно блокиране на потребителя", + "Failed to mute user": "Неуспешно заглушаване на потребителя", + "Failed to toggle moderator status": "Неуспешна промяна на статуса на модератора", + "Failed to change power level": "Неуспешна промяна на нивото на достъп", + "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "След като си намалите нивото на достъп, няма да можете да възвърнете тази промяна. Ако сте потребителя с най-малко привилегии в тази стая, ще бъде невъзможно да възвърнете своите привилегии.", + "Are you sure?": "Сигурни ли сте?", + "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Няма да можете да възвърнете тази промяна, тъй като повишавате този потребител да има същото ниво на достъп като Вашето.", + "No devices with registered encryption keys": "Няма устройства с регистрирани шифровани ключове", + "Devices": "Устройства", + "Unignore": "Премахни игнорирането", + "Ignore": "Игнориране", + "Mention": "Спомени", + "Direct chats": "Директни чатове", + "User Options": "Опции на потребителя", + "Invite": "Покани", + "Unmute": "Премахни заглушаването", + "Make Moderator": "Направи потребителя модератор", + "Admin Tools": "Инструменти на администратора", + "Level:": "Ниво:", + "and %(count)s others...|other": "и %(count)s други...", + "and %(count)s others...|one": "и още един...", + "Invited": "Поканен", + "Filter room members": "Филтриране на членовете в стаята", + "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (ниво на достъп %(powerLevelNumber)s)", + "Attachment": "Прикачване", + "Upload Files": "Качи файлове", + "Are you sure you want to upload the following files?": "Сигурни ли сте, че искате да качите тези файлове?", + "Encrypted room": "Шифрована стая", + "Unencrypted room": "Нешифрована стая", + "Hangup": "Затвори", + "Voice call": "Гласово повикване", + "Video call": "Видео повикване", + "Hide Apps": "Скрий приложенията", + "Show Apps": "Покани приложенията", + "Upload file": "Качи файл", + "Show Text Formatting Toolbar": "Показване на лентата с инструменти за форматиране на текст", + "Send an encrypted reply…": "Изпрати шифрован отговор…", + "Send a reply (unencrypted)…": "Отговори (нешифрованo)…", + "Send an encrypted message…": "Изпрати шифровано съобщение…", + "Send a message (unencrypted)…": "Изпрати съобщение (нешифровано)…", + "You do not have permission to post to this room": "Нямате разрешение да публикувате в тази стая", + "Turn Markdown on": "Включи Markdown", + "Turn Markdown off": "Изключи Markdown", + "Hide Text Formatting Toolbar": "Скриване на лентата с инструменти за форматиране на текст", + "Server error": "Сървърна грешка", + "Server unavailable, overloaded, or something else went wrong.": "Сървърът е недостъпен, претоварен или нещо друго се обърка.", + "Command error": "Грешка в командата", + "bold": "удебелен", + "italic": "курсивен", + "strike": "задраскан", + "underline": "подчертан", + "code": "код", + "quote": "цитат", + "bullet": "списък", + "numbullet": "номериран списък", + "Markdown is disabled": "Markdown е изключен", + "Markdown is enabled": "Markdown е включен", + "No pinned messages.": "Няма закачени съобщения.", + "Loading...": "Зареждане...", + "Pinned Messages": "Закачени съобщения", + "%(duration)ss": "%(duration)sсек", + "%(duration)sm": "%(duration)sмин", + "%(duration)sh": "%(duration)sч", + "%(duration)sd": "%(duration)sд", + "Online for %(duration)s": "Онлайн от %(duration)s", + "Idle for %(duration)s": "Неактивен от %(duration)s", + "Offline for %(duration)s": "Офлайн от %(duration)s", + "Unknown for %(duration)s": "Неизвестен от %(duration)s", + "Idle": "Неактивен", + "Offline": "Офлайн", + "Unknown": "Неизвестен", + "Replying": "Отговаря", + "Seen by %(userName)s at %(dateTime)s": "Видяно от %(userName)s в %(dateTime)s", + "Failed to set avatar.": "Неуспешно задаване на аватар.", + "Save": "Запази" } From c5ad486c57d59eef7044126be2f21fe36ae61748 Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Mon, 19 Feb 2018 20:17:44 +0000 Subject: [PATCH 0348/1160] Translated using Weblate (Catalan) Currently translated at 89.2% (880 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ca/ --- src/i18n/strings/ca.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/ca.json b/src/i18n/strings/ca.json index 120134e296..40fbcc53b4 100644 --- a/src/i18n/strings/ca.json +++ b/src/i18n/strings/ca.json @@ -873,7 +873,7 @@ "Your homeserver's URL": "URL del teu homeserver", "Your identity server's URL": "URL del teu servidor d'identitat", "Analytics": "Analítiques", - "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s ha canviat el seu nom visible a %(displayName)s", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s ha canviat el seu nom visible a %(displayName)s.", "Server may be unavailable or overloaded": "El servidor pot estar inaccessible o sobrecarregat", "Report it": "Informa", "Found a bug?": "Has trobat un error?", From d21f55633dfb3d5f99cf8b58f37d969b85da736e Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 20 Feb 2018 14:03:43 +0000 Subject: [PATCH 0349/1160] Fix DMs being marked as with the current user ("me") Whilst testing various DM paths, @lukebarnard1 found that there were many failures to add the room as a DM against the correct user. It turned out most of the failures seen were because the user chosen was the current user. If the user accepted an invite it would often be marked as with themselves because we chose the sender of the join event as the DM user. This fix makes the DM room setting process the same for both the inviting client and the invited client. A RoomState.members event causes the DM room state to be set in the room, regardless of whether we are currently `joining` (see previous impl.) The two cases for setting a DM are: - this user accepting an invite with is_direct - this user inviting someone with is_direct This should handle all cases for setting DM state. --- src/components/structures/RoomView.js | 61 +++++++++++++++------------ 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 5304f38901..c827a63057 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -678,21 +678,40 @@ module.exports = React.createClass({ // refresh the conf call notification state this._updateConfCallNotification(); - // if we are now a member of the room, where we were not before, that - // means we have finished joining a room we were previously peeking - // into. - const me = MatrixClientPeg.get().credentials.userId; - if (this.state.joining && this.state.room.hasMembershipState(me, "join")) { - // Having just joined a room, check to see if it looks like a DM room, and if so, - // mark it as one. This is to work around the fact that some clients don't support - // is_direct. We should remove this once they do. - const me = this.state.room.getMember(MatrixClientPeg.get().credentials.userId); - if (Rooms.looksLikeDirectMessageRoom(this.state.room, me)) { - // XXX: There's not a whole lot we can really do if this fails: at best - // perhaps we could try a couple more times, but since it's a temporary - // compatability workaround, let's not bother. - Rooms.setDMRoom(this.state.room.roomId, me.events.member.getSender()).done(); - } + const me = this.state.room.getMember(MatrixClientPeg.get().credentials.userId); + if (!me || me.membership !== "join") { + return; + } + + // The user may have accepted an invite with is_direct set + if (me.events.member.getPrevContent().membership === "invite" && + me.events.member.getPrevContent().is_direct + ) { + // This is a DM with the sender of the invite event (which we assume + // preceded the join event) + Rooms.setDMRoom( + this.state.room.roomId, + me.events.member.getUnsigned().prev_sender, + ); + return; + } + + const invitedMembers = this.state.room.getMembersWithMembership("invite"); + const joinedMembers = this.state.room.getMembersWithMembership("join"); + + // There must be one invited member and one joined member + if (invitedMembers.length !== 1 || joinedMembers.length !== 1) { + return; + } + + // The user may have sent an invite with is_direct sent + const other = invitedMembers[0]; + if (other && + other.membership === "invite" && + other.events.member.getContent().is_direct + ) { + Rooms.setDMRoom(this.state.room.roomId, other.userId); + return; } }, 500), @@ -826,18 +845,6 @@ module.exports = React.createClass({ action: 'join_room', opts: { inviteSignUrl: signUrl }, }); - - // if this is an invite and has the 'direct' hint set, mark it as a DM room now. - if (this.state.room) { - const me = this.state.room.getMember(MatrixClientPeg.get().credentials.userId); - if (me && me.membership == 'invite') { - if (me.events.member.getContent().is_direct) { - // The 'direct' hint is there, so declare that this is a DM room for - // whoever invited us. - return Rooms.setDMRoom(this.state.room.roomId, me.events.member.getSender()); - } - } - } return Promise.resolve(); }); }, From bc15303358c58226c4ef47793d34276d58d9b1ee Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 20 Feb 2018 14:10:34 +0000 Subject: [PATCH 0350/1160] Factor out updateDmState --- src/components/structures/RoomView.js | 75 ++++++++++++++------------- 1 file changed, 39 insertions(+), 36 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index c827a63057..8ceba2a850 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -677,42 +677,7 @@ module.exports = React.createClass({ // a member state changed in this room // refresh the conf call notification state this._updateConfCallNotification(); - - const me = this.state.room.getMember(MatrixClientPeg.get().credentials.userId); - if (!me || me.membership !== "join") { - return; - } - - // The user may have accepted an invite with is_direct set - if (me.events.member.getPrevContent().membership === "invite" && - me.events.member.getPrevContent().is_direct - ) { - // This is a DM with the sender of the invite event (which we assume - // preceded the join event) - Rooms.setDMRoom( - this.state.room.roomId, - me.events.member.getUnsigned().prev_sender, - ); - return; - } - - const invitedMembers = this.state.room.getMembersWithMembership("invite"); - const joinedMembers = this.state.room.getMembersWithMembership("join"); - - // There must be one invited member and one joined member - if (invitedMembers.length !== 1 || joinedMembers.length !== 1) { - return; - } - - // The user may have sent an invite with is_direct sent - const other = invitedMembers[0]; - if (other && - other.membership === "invite" && - other.events.member.getContent().is_direct - ) { - Rooms.setDMRoom(this.state.room.roomId, other.userId); - return; - } + this._updateDMState(); }, 500), _checkIfAlone: function(room) { @@ -753,6 +718,44 @@ module.exports = React.createClass({ }); }, + _updateDMState() { + const me = this.state.room.getMember(MatrixClientPeg.get().credentials.userId); + if (!me || me.membership !== "join") { + return; + } + + // The user may have accepted an invite with is_direct set + if (me.events.member.getPrevContent().membership === "invite" && + me.events.member.getPrevContent().is_direct + ) { + // This is a DM with the sender of the invite event (which we assume + // preceded the join event) + Rooms.setDMRoom( + this.state.room.roomId, + me.events.member.getUnsigned().prev_sender, + ); + return; + } + + const invitedMembers = this.state.room.getMembersWithMembership("invite"); + const joinedMembers = this.state.room.getMembersWithMembership("join"); + + // There must be one invited member and one joined member + if (invitedMembers.length !== 1 || joinedMembers.length !== 1) { + return; + } + + // The user may have sent an invite with is_direct sent + const other = invitedMembers[0]; + if (other && + other.membership === "invite" && + other.events.member.getContent().is_direct + ) { + Rooms.setDMRoom(this.state.room.roomId, other.userId); + return; + } + }, + onSearchResultsResize: function() { dis.dispatch({ action: 'timeline_resize' }, true); }, From f227d13dfe701b4b96a2cfb1e1e75b3d868195bd Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Tue, 20 Feb 2018 14:21:24 +0000 Subject: [PATCH 0351/1160] Translated using Weblate (Bulgarian) Currently translated at 43.8% (432 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 63 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 1c7c2026ed..f47b3b24ee 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -41,7 +41,7 @@ "Online": "Онлайн", "Failed to remove tag %(tagName)s from room": "Неуспешно премахване на %(tagName)s етикет от стаята", "unknown error code": "неизвестен код за грешка", - "Failed to forget room %(errCode)s": "Не успешно забравяне на стаята %(errCode)s", + "Failed to forget room %(errCode)s": "Неуспешно забравяне на стаята %(errCode)s", "Mute": "Заглуши", "Leave": "Напусни", "Favourite": "Любим", @@ -372,6 +372,63 @@ "Unknown": "Неизвестен", "Replying": "Отговаря", "Seen by %(userName)s at %(dateTime)s": "Видяно от %(userName)s в %(dateTime)s", - "Failed to set avatar.": "Неуспешно задаване на аватар.", - "Save": "Запази" + "Failed to set avatar.": "Неуспешно задаване на профилна снимка.", + "Save": "Запази", + "(~%(count)s results)|other": "(~%(count)s резултати)", + "(~%(count)s results)|one": "(~%(count)s резултат)", + "Join Room": "Присъедини се към стаята", + "Upload avatar": "Качи профилната снимка", + "Remove avatar": "Премахни профилната снимка", + "Settings": "Настройки", + "Forget room": "Забрави стаята", + "Show panel": "Покажи панелa", + "Drop here to favourite": "За любим пуснeте тук", + "Drop here to tag direct chat": "Пуснете тук, за да означите директен чат", + "Drop here to restore": "Пуснете тук за възстановяване", + "Drop here to demote": "Пуснете тук за", + "Drop here to tag %(section)s": "Пуснете тук, за да означите %(section)s", + "Failed to set direct chat tag": "Неуспешно означаване на директен чат", + "Press to start a chat with someone": "Натиснете , за да започнете чат с някого", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Все още не сте в нито една стая! Натиснете , за да направите такава или , за да прегледате директорията", + "Community Invites": "Покани за общества", + "Invites": "Покани", + "Favourites": "Любими", + "People": "Хора", + "Low priority": "Нисък приоритет", + "Historical": "Архив", + "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Не може да се потвърди, че адреса към който е изпратена тази покана е обвързан с акаунта Ви.", + "This invitation was sent to an email address which is not associated with this account:": "Тази покана е изпратена на имейл адрес, който не е свързан с този профил:", + "You may wish to login with a different account, or add this email to this account.": "Може да искате да влезете с друг профил или да добавите този имейл в този профил.", + "You have been invited to join this room by %(inviterName)s": "Вие сте поканен да се присъедините към тази стая от %(inviterName)s", + "Would you like to accept or decline this invitation?": "Желаете да приемете или да откажете тази покана?", + "Reason: %(reasonText)s": "Причина: %(reasonText)s", + "Rejoin": "Повторно присъединяване", + "You have been kicked from %(roomName)s by %(userName)s.": "Вие сте изгонен от %(roomName)s от %(userName)s.", + "You have been kicked from this room by %(userName)s.": "Вие сте изгонен от тази стая от %(userName)s.", + "You have been banned from %(roomName)s by %(userName)s.": "Вие сте блокиран в %(roomName)s от %(userName)s.", + "You have been banned from this room by %(userName)s.": "Вие сте блокиран в тази стая от %(userName)s.", + "This room": "В тази стая", + "%(roomName)s does not exist.": "%(roomName)s не съществува.", + "%(roomName)s is not accessible at this time.": "%(roomName)s не е достъпна към този момент.", + "You are trying to access %(roomName)s.": "Опитвате се да влезете в %(roomName)s.", + "You are trying to access a room.": "Опитвате се да влезете в стая.", + "Click here to join the discussion!": "Натиснете тук, за да се присъедините към дискусията!", + "This is a preview of this room. Room interactions have been disabled": "Това е преглед на стаята. Интеракции в нея са деактивирани", + "To change the room's avatar, you must be a": "За да смените снимката на стаята, трябва да бъдете", + "To change the room's name, you must be a": "За да смените името на стаята, трябва да бъдете", + "To change the room's main address, you must be a": "За да смените основния адрес на стаята, трябва да бъдете", + "To change the room's history visibility, you must be a": "За да смените видимостта на историята на стаята, трябва да бъдете", + "To change the permissions in the room, you must be a": "За да промените разрешенията в стаята, трябва да бъдете", + "To change the topic, you must be a": "За да смените темата, трябва да бъдете", + "To modify widgets in the room, you must be a": "За да промените приспособленията в стаята, трябва да бъдете", + "Failed to unban": "Неуспешно отблокиране", + "Banned by %(displayName)s": "Блокиран от %(displayName)s", + "Privacy warning": "Предупреждение за сигурност", + "Changes to who can read history will only apply to future messages in this room": "Промени за това кой може да чете историята ще се отнасят само за бъдещи съобщения в тази стая", + "The visibility of existing history will be unchanged": "Видимостта на съществуващата история ще остане непроменена", + "End-to-end encryption is in beta and may not be reliable": "Шифроване от край до край е в бета версия и може да не е надеждно", + "Devices will not yet be able to decrypt history from before they joined the room": "Устройства все още не могат да разшифроват история от преди присъединяването към стая", + "Once encryption is enabled for a room it cannot be turned off again (for now)": "Веднъж включено шифроване в стаята не може да бъде изключено (за сега)", + "Encrypted messages will not be visible on clients that do not yet implement encryption": "Шифровани съобщения не са видими за клиенти, които все още не поддържат шифроване", + "Enable encryption": "Включване на шифроване" } From 90f9badbf3c0f18eb799a9b80bb7dd23a9d1e453 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 20 Feb 2018 15:40:19 +0000 Subject: [PATCH 0352/1160] s/Reply/ReplyThread/ Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/RoomView.js | 2 +- .../views/elements/{Reply.js => ReplyThread.js} | 8 ++++---- src/components/views/rooms/EventTile.js | 2 +- src/components/views/rooms/MessageComposerInput.js | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) rename src/components/views/elements/{Reply.js => ReplyThread.js} (96%) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 869dffcf9b..ae9522e511 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -45,7 +45,7 @@ import { KeyCode, isOnlyCtrlOrCmdKeyEvent } from '../../Keyboard'; import RoomViewStore from '../../stores/RoomViewStore'; import RoomScrollStateStore from '../../stores/RoomScrollStateStore'; import SettingsStore from "../../settings/SettingsStore"; -import Reply from "../views/elements/Reply"; +import Reply from "../views/elements/ReplyThread"; const DEBUG = false; let debuglog = function() {}; diff --git a/src/components/views/elements/Reply.js b/src/components/views/elements/ReplyThread.js similarity index 96% rename from src/components/views/elements/Reply.js rename to src/components/views/elements/ReplyThread.js index 5b213690cc..24ab6163fb 100644 --- a/src/components/views/elements/Reply.js +++ b/src/components/views/elements/ReplyThread.js @@ -159,7 +159,7 @@ export default class Reply extends React.Component { let header = null; if (this.state.err) { - header =
    + header =
    { _t('Unable to load event that was replied to, ' + 'it either does not exist or you do not have permission to view it.') @@ -169,10 +169,10 @@ export default class Reply extends React.Component { const ev = this.state.loadedEv; const Pill = sdk.getComponent('elements.Pill'); const room = MatrixClientPeg.get().getRoom(ev.getRoomId()); - header =
    + header =
    { _t('In reply to ', {}, { - 'a': (sub) => { sub }, + 'a': (sub) => { sub }, 'pill': , }) @@ -192,7 +192,7 @@ export default class Reply extends React.Component { dateSep = ; } - return
    + return
    { dateSep } Date: Tue, 20 Feb 2018 15:45:25 +0000 Subject: [PATCH 0353/1160] restrict to m.text for now Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/ContentMessages.js | 6 +++--- src/components/structures/RoomView.js | 4 +--- src/components/views/rooms/MessageComposerInput.js | 5 +++++ src/stores/RoomViewStore.js | 5 ----- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/ContentMessages.js b/src/ContentMessages.js index f0e8736aba..8d40b65124 100644 --- a/src/ContentMessages.js +++ b/src/ContentMessages.js @@ -275,13 +275,13 @@ class ContentMessages { this.nextId = 0; } - sendContentToRoom(file, roomId, matrixClient, baseContent) { - const content = Object.assign({}, baseContent, { + sendContentToRoom(file, roomId, matrixClient) { + const content = { body: file.name || 'Attachment', info: { size: file.size, }, - }); + }; // if we have a mime type for the file, add it to the message metadata if (file.type) { diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index ae9522e511..75fa316030 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -896,10 +896,8 @@ module.exports = React.createClass({ return; } - const baseContent = Reply.getMRelatesTo(RoomViewStore.getQuotingEvent()); - ContentMessages.sendContentToRoom( - file, this.state.room.roomId, MatrixClientPeg.get(), baseContent, + file, this.state.room.roomId, MatrixClientPeg.get(), ).done(() => { dis.dispatch({ action: 'message_sent', diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index e8725bdf05..c2fcfd9688 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -853,6 +853,11 @@ export default class MessageComposerInput extends React.Component { dis.dispatch({ action: 'message_sent', }); + // Once replies are not only for text, we can use message_sent for this + dis.dispatch({ + action: 'reply_to_event', + event: null, + }); }, (e) => onSendMessageFailed(e, this.props.room)); this.setState({ diff --git a/src/stores/RoomViewStore.js b/src/stores/RoomViewStore.js index 2c81f9de23..1e7e50eae0 100644 --- a/src/stores/RoomViewStore.js +++ b/src/stores/RoomViewStore.js @@ -116,11 +116,6 @@ class RoomViewStore extends Store { replyingToEvent: payload.event, }); break; - case 'message_sent': - this._setState({ - replyingToEvent: null, - }); - break; } } From 644ddbf9b9d7488c247129f4718afed523185d90 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 20 Feb 2018 17:57:46 +0000 Subject: [PATCH 0354/1160] Regenerate room lists on Room event To make sure that we handle rooms that our client has not seen previously, we regenerate the room list when the room is stored - which is indicated by the js-sdk by the Room event. --- src/actions/MatrixActionCreators.js | 5 +++++ src/stores/RoomListStore.js | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/src/actions/MatrixActionCreators.js b/src/actions/MatrixActionCreators.js index a307af6f57..78c653c551 100644 --- a/src/actions/MatrixActionCreators.js +++ b/src/actions/MatrixActionCreators.js @@ -62,6 +62,10 @@ function createAccountDataAction(matrixClient, accountDataEvent) { }; } +function createRoomAction(matrixClient, room) { + return { action: 'MatrixActions.Room', room }; +} + function createRoomTagsAction(matrixClient, roomTagsEvent, room) { return { action: 'MatrixActions.Room.tags', room }; } @@ -96,6 +100,7 @@ export default { start(matrixClient) { this._addMatrixClientListener(matrixClient, 'sync', createSyncAction); this._addMatrixClientListener(matrixClient, 'accountData', createAccountDataAction); + this._addMatrixClientListener(matrixClient, 'Room', createRoomAction); this._addMatrixClientListener(matrixClient, 'Room.tags', createRoomTagsAction); this._addMatrixClientListener(matrixClient, 'Room.timeline', createRoomTimelineAction); this._addMatrixClientListener(matrixClient, 'RoomMember.membership', createRoomMembershipAction); diff --git a/src/stores/RoomListStore.js b/src/stores/RoomListStore.js index 8a3af309fc..80db6ca9a8 100644 --- a/src/stores/RoomListStore.js +++ b/src/stores/RoomListStore.js @@ -97,6 +97,14 @@ class RoomListStore extends Store { this._generateRoomLists(); } break; + // This could be a new room that we've been invited to, joined or created + // we won't get a RoomMember.membership for these cases if we're not already + // a member. + case 'MatrixActions.Room': { + if (!this._state.ready || !this._matrixClient.credentials.userId) break; + this._generateRoomLists(); + } + break; case 'RoomListActions.tagRoom.pending': { // XXX: we only show one optimistic update at any one time. // Ideally we should be making a list of in-flight requests From a78575929c47f6895cfe09ec812c5bcfdde3d6ce Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 21 Feb 2018 10:15:52 +0000 Subject: [PATCH 0355/1160] Document a few action creators --- src/actions/MatrixActionCreators.js | 79 +++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/src/actions/MatrixActionCreators.js b/src/actions/MatrixActionCreators.js index 78c653c551..1998ecfef2 100644 --- a/src/actions/MatrixActionCreators.js +++ b/src/actions/MatrixActionCreators.js @@ -62,14 +62,75 @@ function createAccountDataAction(matrixClient, accountDataEvent) { }; } +/** + * @typedef RoomAction + * @type {Object} + * @property {string} action 'MatrixActions.Room'. + * @property {Room} room the Room that was stored. + */ + +/** + * Create a MatrixActions.Room action that represents a MatrixClient `Room` + * matrix event, emitted when a Room is stored in the client. + * + * @param {MatrixClient} matrixClient the matrix client. + * @param {Room} room the Room that was stored. + * @returns {RoomAction} an action of type `MatrixActions.Room`. + */ function createRoomAction(matrixClient, room) { return { action: 'MatrixActions.Room', room }; } +/** + * @typedef RoomTagsAction + * @type {Object} + * @property {string} action 'MatrixActions.Room.tags'. + * @property {Room} room the Room whose tags changed. + */ + +/** + * Create a MatrixActions.Room.tags action that represents a MatrixClient + * `Room.tags` matrix event, emitted when the m.tag room account data + * event is updated. + * + * @param {MatrixClient} matrixClient the matrix client. + * @param {MatrixEvent} roomTagsEvent the m.tag event. + * @param {Room} room the Room whose tags were changed. + * @returns {RoomTagsAction} an action of type `MatrixActions.Room.tags`. + */ function createRoomTagsAction(matrixClient, roomTagsEvent, room) { return { action: 'MatrixActions.Room.tags', room }; } +/** + * @typedef RoomTimelineAction + * @type {Object} + * @property {string} action 'MatrixActions.Room.timeline'. + * @property {boolean} isLiveEvent whether the event was attached to a + * live timeline. + * @property {boolean} isLiveUnfilteredRoomTimelineEvent whether the + * event was attached to a timeline in the set of unfiltered timelines. + * @property {Room} room the Room whose tags changed. + */ + +/** + * Create a MatrixActions.Room.timeline action that represents a + * MatrixClient `Room.timeline` matrix event, emitted when an event + * is added to or removed from a timeline of a room. + * + * @param {MatrixClient} matrixClient the matrix client. + * @param {MatrixEvent} timelineEvent the event that was added/removed. + * @param {Room} room the Room that was stored. + * @param {boolean} toStartOfTimeline whether the event is being added + * to the start (and not the end) of the timeline. + * @param {boolean} removed whether the event was removed from the + * timeline. + * @param {Object} data + * @param {boolean} data.liveEvent whether the event is a live event, + * belonging to a live timeline. + * @param {EventTimeline} data.timeline the timeline being altered. + * @returns {RoomTimelineAction} an action of type `MatrixActions.Room.timeline`. + */ function createRoomTimelineAction(matrixClient, timelineEvent, room, toStartOfTimeline, removed, data) { return { action: 'MatrixActions.Room.timeline', @@ -80,6 +141,24 @@ function createRoomTimelineAction(matrixClient, timelineEvent, room, toStartOfTi }; } +/** + * @typedef RoomMembershipAction + * @type {Object} + * @property {string} action 'MatrixActions.RoomMember.membership'. + * @property {RoomMember} member the member whose membership was updated. + */ + +/** + * Create a MatrixActions.RoomMember.membership action that represents + * a MatrixClient `RoomMember.membership` matrix event, emitted when a + * member's membership is updated. + * + * @param {MatrixClient} matrixClient the matrix client. + * @param {MatrixEvent} membershipEvent the m.room.member event. + * @param {RoomMember} member the member whose membership was updated. + * @param {string} oldMembership the member's previous membership. + * @returns {RoomMembershipAction} an action of type `MatrixActions.RoomMember.membership`. + */ function createRoomMembershipAction(matrixClient, membershipEvent, member, oldMembership) { return { action: 'MatrixActions.RoomMember.membership', member }; } From b7601f86d1dbdb347c439c73e4477dc3ee799583 Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Wed, 21 Feb 2018 13:37:58 +0000 Subject: [PATCH 0356/1160] Translated using Weblate (Bulgarian) Currently translated at 76.8% (758 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 356 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 341 insertions(+), 15 deletions(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index f47b3b24ee..35505c0038 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -48,7 +48,7 @@ "Register": "Регистрация", "Notifications": "Известия", "Rooms": "Стаи", - "Add rooms to this community": "Добави стаи в това общество", + "Add rooms to this community": "Добави стаи в тази общност", "Unnamed room": "Стая без име", "World readable": "Четимо за всички", "Guests can join": "Гости могат да се присъединят", @@ -87,18 +87,18 @@ "Upload Failed": "Качването е неуспешно", "PM": "PM", "AM": "AM", - "Who would you like to add to this community?": "Кой бихте желали да добавите в това общество?", - "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Предупреждение: Всеки човек, който добавяте в дадено общество, ще бъде публично видим за знаещите идентификатора на обществото", - "Invite new community members": "Покани нови членове на обществото", + "Who would you like to add to this community?": "Кого бихте желали да добавите в тaзи общност?", + "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Предупреждение: Всеки човек, който добавяте в дадена общност, ще бъде публично видим за знаещите идентификатора на общността", + "Invite new community members": "Покани нови членове в общността", "Name or matrix ID": "Име или matrix ID", - "Invite to Community": "Покани в обществото", - "Which rooms would you like to add to this community?": "Кои стаи бихте желали да добавите в това общество?", - "Show these rooms to non-members on the community page and room list?": "Показване на тези стаи на не-членове на страницата на обществата и списъка със стаи?", - "Add rooms to the community": "Добави стаи в обществото", + "Invite to Community": "Покани в общността", + "Which rooms would you like to add to this community?": "Кои стаи бихте желали да добавите в тази общност?", + "Show these rooms to non-members on the community page and room list?": "Показване на тези стаи на не-членове на страницата на общностите и списъка със стаи?", + "Add rooms to the community": "Добави стаи в общността", "Room name or alias": "Име или псевдоним на стая", - "Add to community": "Добави в обществото", + "Add to community": "Добави в общност", "Failed to invite the following users to %(groupId)s:": "Следните потребители не могат да бъдат поканени в %(groupId)s:", - "Failed to invite users to community": "Потребителите не могат да бъдат поканени в обществото", + "Failed to invite users to community": "Потребителите не могат да бъдат поканени в общността", "Failed to invite users to %(groupId)s": "Потребителите не могат да бъдат поканени в %(groupId)s", "Failed to add the following rooms to %(groupId)s:": "Следните стаи не могат да бъдат добавени в %(groupId)s:", "Riot does not have permission to send you notifications - please check your browser settings": "Riot няма разрешение да Ви изпраща известия - моля проверете вашите настройки на браузъра", @@ -123,7 +123,7 @@ "You need to be logged in.": "Трябва да влезете в профила си.", "You need to be able to invite users to do that.": "Трябва да имате право да добавите потребители, за да извършите това.", "Unable to create widget.": "Неуспешно създаване на приспособление.", - "Failed to send request.": "Неуспешно изпращане на запитване.", + "Failed to send request.": "Неуспешно изпращане на заявката.", "This room is not recognised.": "Стаята не е разпозната.", "Power level must be positive integer.": "Нивото на достъп трябва да бъде позитивно число.", "Call Anyway": "Обади се въпреки това", @@ -198,7 +198,7 @@ "%(names)s and %(lastPerson)s are typing": "%(names)s и %(lastPerson)s пишат", "Failure to create room": "Неуспешно създаване на стая", "Server may be unavailable, overloaded, or you hit a bug.": "Сървърът може би е претоварен, недостъпен или се натъкнахте на проблем.", - "Send anyway": "Изпрати така или иначе", + "Send anyway": "Изпрати въпреки това", "Unnamed Room": "Стая без име", "Your browser does not support the required cryptography extensions": "Вашият браузър не поддържа необходимите разширения за шифроване", "Not a valid Riot keyfile": "Невалиден Riot ключов файл", @@ -286,7 +286,7 @@ "Encrypted by an unverified device": "Шифровано от непотвърдено устройство", "Unencrypted message": "Нешифровано съобщение", "Please select the destination room for this message": "Моля изберете стаята, в която искате да изпратите това съобщение", - "Blacklisted": "В черен списък", + "Blacklisted": "В черния списък", "Verified": "Потвърдено", "Unverified": "Непотвърдено", "device id: ": "идентификатор на устройството: ", @@ -390,7 +390,7 @@ "Failed to set direct chat tag": "Неуспешно означаване на директен чат", "Press to start a chat with someone": "Натиснете , за да започнете чат с някого", "You're not in any rooms yet! Press to make a room or to browse the directory": "Все още не сте в нито една стая! Натиснете , за да направите такава или , за да прегледате директорията", - "Community Invites": "Покани за общества", + "Community Invites": "Покани за общност", "Invites": "Покани", "Favourites": "Любими", "People": "Хора", @@ -430,5 +430,331 @@ "Devices will not yet be able to decrypt history from before they joined the room": "Устройства все още не могат да разшифроват история от преди присъединяването към стая", "Once encryption is enabled for a room it cannot be turned off again (for now)": "Веднъж включено шифроване в стаята не може да бъде изключено (за сега)", "Encrypted messages will not be visible on clients that do not yet implement encryption": "Шифровани съобщения не са видими за клиенти, които все още не поддържат шифроване", - "Enable encryption": "Включване на шифроване" + "Enable encryption": "Включване на шифроване", + "(warning: cannot be disabled again!)": "(внимание: не може да бъде изключено отново!)", + "Encryption is enabled in this room": "Шифроването е включено в тази стая", + "Encryption is not enabled in this room": "Шифроването не е включено в тази стая", + "Privileged Users": "Потребители с привилегии", + "%(user)s is a": "%(user)s е", + "No users have specific privileges in this room": "Никой няма специфични привилегии в тази стая", + "Banned users": "Блокирани потребители", + "This room is not accessible by remote Matrix servers": "Тази стая не е достъпна за далечни Matrix сървъри", + "Leave room": "Напусни стаята", + "Tagged as: ": "Означен като: ", + "To link to a room it must have an address.": "За да дадете линк към стаята, тя трябва да има адрес.", + "Guests cannot join this room even if explicitly invited.": "Гости не могат да се присъединят към тази стая, дори изрично поканени.", + "Click here to fix": "Натиснете тук за поправяне", + "Who can access this room?": "Кой има достъп до тази стая?", + "Only people who have been invited": "Само хора, които са поканени", + "Anyone who knows the room's link, apart from guests": "Всеки, който знае адреса на стаята, освен гости", + "Anyone who knows the room's link, including guests": "Всеки, който знае адрес на стаята, включително гости", + "Publish this room to the public in %(domain)s's room directory?": "Публично публикуване на тази стая в директорията на %(domain)s?", + "Who can read history?": "Кой може да чете историята?", + "Anyone": "Всеки", + "Members only (since the point in time of selecting this option)": "Само членове (от момента на избиране на тази опция)", + "Members only (since they were invited)": "Само членове (от момента, в който те са поканени)", + "Members only (since they joined)": "Само членове (от момента, в който са се присъединили)", + "Permissions": "Разрешения", + "The default role for new room members is": "По подразбиране ролята за нови членове в стаята е", + "To send messages, you must be a": "За да изпращате съобщения, трябва да бъдете", + "To invite users into the room, you must be a": "За да поканите потребители в стаята, трябва да бъдете", + "To configure the room, you must be a": "За да конфигурирате стаята, трябва да бъдете", + "To kick users, you must be a": "За да изгоните потребител, трябва да бъдете", + "To ban users, you must be a": "За да блокирате потребител, трябва да бъдете", + "To remove other users' messages, you must be a": "За да премахнете съобщения на друг потребител, трябва да бъдете", + "To send events of type , you must be a": "За да изпратите събития от вида , трябва да бъдете", + "Advanced": "Разширени", + "This room's internal ID is": "Вътрешният идентификатор на тази стая е", + "Add a topic": "Добавете тема", + "Jump to first unread message.": "Отиди до първото непрочетено съобщение.", + "Scroll to unread messages": "Скролирай до непрочетените съобщения", + "Invalid alias format": "Невалиден формат на псевдонима", + "'%(alias)s' is not a valid format for an alias": "%(alias)s не е валиден формат на псевдоним", + "Invalid address format": "Невалиден формат на адреса", + "'%(alias)s' is not a valid format for an address": "%(alias)s не е валиден формат на адрес", + "not specified": "неопределен", + "not set": "незададен", + "Remote addresses for this room:": "Далечни адреси на тази стая:", + "Addresses": "Адреси", + "The main address for this room is": "Основният адрес на тази стая е", + "Local addresses for this room:": "Локалните адреси на тази стая са:", + "This room has no local addresses": "Тази стая няма локални адреси", + "New address (e.g. #foo:%(localDomain)s)": "Нов адрес (напр. #foo:%(localDomain)s)", + "Invalid community ID": "Невалиден идентификатор на общност", + "'%(groupId)s' is not a valid community ID": "'%(groupId)s' е невалиден идентификатор на общност", + "Flair": "Значка", + "Showing flair for these communities:": "Показване на значки за тези общности:", + "This room is not showing flair for any communities": "Тази стая не показва значки за нито една общност", + "New community ID (e.g. +foo:%(localDomain)s)": "Нов идентификатор на общност (напр. +foo:%(localDomain)s)", + "You have enabled URL previews by default.": "Вие сте включил URL прегледи по подразбиране.", + "You have disabled URL previews by default.": "Вие сте изключил URL прегледи по подразбиране.", + "URL previews are enabled by default for participants in this room.": "URL прегледи са включени по подразбиране за участниците в тази стая.", + "URL previews are disabled by default for participants in this room.": "URL прегледи са изключени по подразбиране за участниците в тази стая.", + "URL Previews": "URL прегледи", + "Error decrypting audio": "Грешка при разшифроване на аудио файл", + "Error decrypting attachment": "Грешка при разшифроване на прикачване", + "Decrypt %(text)s": "Разшифровай %(text)s", + "Download %(text)s": "Изтегли %(text)s", + "(could not connect media)": "(неуспешно свързване на медийните устройства)", + "Must be viewing a room": "Трябва да видите стаята", + "Usage": "Употреба", + "Remove from community": "Премахни от общността", + "Disinvite this user from community?": "Оттегляне на поканата към този потребител от общността?", + "Remove this user from community?": "Премахване на този потребител от общността?", + "Failed to remove user from community": "Неуспешно премахване на потребителя от тази общност", + "Filter community members": "Филтриране на членовете на общността", + "Removing a room from the community will also remove it from the community page.": "Премахване на стая от общността ще бъде също премахната от страницата с общността.", + "Failed to remove room from community": "Неуспешно премахване на стаята от общността", + "Only visible to community members": "Видимо само за членове на общността", + "Filter community rooms": "Филтрирай стаи на общността", + "Community IDs cannot not be empty.": "Идентификаторите на общността не могат да бъдат празни.", + "Create Community": "Създай общност", + "Community Name": "Име на общност", + "Community ID": "Идентификатор на общност", + "

    HTML for your community's page

    \n

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

    \n

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

    \n": "

    HTML за страница на Вашата общност

    \n

    \n Използвайте дългото описание, за да въведете нови членове в общността, \n или да разпространите важни връзки\n

    \n

    \n Можете дори да използвате 'img' тагове\n

    \n", + "Add rooms to the community summary": "Добавете стаи към обобщението на общността", + "Add users to the community summary": "Добавете потребители към обобщението на общността", + "Failed to update community": "Неуспешно обновяване на общността", + "Leave Community": "Напусни общността", + "Community Settings": "Настройки на общността", + "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Тези стаи са показани на членове на общността на страницата на общността. Членовете на общността могат да се присъединят към стаите като натиснат върху тях.", + "%(inviter)s has invited you to join this community": "%(inviter)s Ви покани да се присъедините към тази общност", + "You are an administrator of this community": "Вие сте администратор на тази общност", + "You are a member of this community": "Вие сте член на тази общност", + "Your community hasn't got a Long Description, a HTML page to show to community members.
    Click here to open settings and give it one!": "Вашата общност няма дълго описание - HTML страница, която да се показва на членовете на общността.
    Натиснете тук, за да отворите настройките и да създадете такова!", + "Community %(groupId)s not found": "Общност %(groupId)s не е намерена", + "Create a new community": "Създаване на нова общност", + "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Създайте общност, за да обедините заедно потребители и стаи! Изградете персонализирана начална страница, за да маркирате своето пространство във Вселената на матрицата.", + "Join an existing community": "Присъединяване към вече съществуваща общност", + "To join an existing community you'll have to know its community identifier; this will look something like +example:matrix.org.": "За да се присъедините към вече съществуваща общност, трябва да знаете неиния идентификатор; това изглежда нещо подобно на +example:matrix.org.", + "Unknown (user, device) pair:": "Непозната двойка (потребител, устройство):", + "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Подписващият ключ, който сте предоставили, съвпада с подписващия ключ, който сте получили от устройството %(deviceId)s на %(userId)s. Устройството е маркирано като потвърдено.", + "Hide avatars in user and room mentions": "Скриване на профилната снимка при споменаване на потребители и стаи", + "Jump to message": "Отиди до съобщението", + "Jump to read receipt": "Отиди до потвърдението за прочетено", + "Revoke Moderator": "Премахване на правата на модератора", + "You should not yet trust it to secure data": "Все още не трябва да се доверявате на това, че ще запази Вашите данни", + "Invalid file%(extra)s": "Невалиден файл%(extra)s", + "Error decrypting image": "Грешка при разшифроване на снимка", + "This image cannot be displayed.": "Тази снимка не може да бъде показана.", + "Image '%(Body)s' cannot be displayed.": "Снимката '%(Body)s' не може да бъде показана.", + "Error decrypting video": "Грешка при разшифроване на видео", + "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s промени аватара на %(roomName)s", + "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s премахна аватара на стаята.", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s промени аватара на стаята на ", + "Copied!": "Копирано!", + "Failed to copy": "Неуспешно копиране", + "Add an Integration": "Добавяне на интеграция", + "Removed or unknown message type": "Премахнато или неизвестен тип съобщение", + "Message removed by %(userId)s": "Съобщението е премахнато от %(userId)s", + "Message removed": "Съобщението е премахнато", + "This Home Server would like to make sure you are not a robot": "Този Home сървър би искал да се увери, че не сте робот", + "Sign in with CAS": "Влез с CAS", + "To continue, please enter your password.": "За да продължите, моля, въведете своята парола.", + "Password:": "Парола:", + "An email has been sent to %(emailAddress)s": "Имейл беше изпратен на %(emailAddress)s", + "Please check your email to continue registration.": "Моля, проверете имейла си, за да продължите регистрацията.", + "Token incorrect": "Неправителен token", + "A text message has been sent to %(msisdn)s": "Текстово съобщение беше изпратено на %(msisdn)s", + "Please enter the code it contains:": "Моля, въведете кода, който то съдържа:", + "Start authentication": "Започнете автентикация", + "Username on %(hs)s": "Потребителско име на %(hs)s", + "User name": "Потребителско име", + "Mobile phone number": "Мобилен номер", + "Forgot your password?": "Забравена парола?", + "%(serverName)s Matrix ID": "%(serverName)s Matrix ID", + "Sign in with": "Влезте с", + "Email address": "Имейл адрес", + "Sign in": "Вход", + "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Ако не посочите имейл адрес, няма да бъде възможно да възстановите Вашата парола. Сигурни ли сте?", + "Email address (optional)": "Имейл адрес (по избор)", + "You are registering with %(SelectedTeamName)s": "Регистрирате се с %(SelectedTeamName)s", + "Mobile phone number (optional)": "Мобилен номер (по избор)", + "Default server": "Сървър по подразбиране", + "Custom server": "Потребителски сървър", + "Home server URL": "Адрес на home сървър", + "Identity server URL": "Адрес на сървър за самоличност", + "What does this mean?": "Какво означава това?", + "Failed to withdraw invitation": "Неуспешно оттегляне на поканата", + "Flair will appear if enabled in room settings": "Значката ще се покаже, ако е включена в настройките на стаята", + "Flair will not appear": "Значката няма да се покаже", + "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Сигурни ли сте, че искате да премахнете '%(roomName)s' от %(groupId)s?", + "Failed to remove '%(roomName)s' from %(groupId)s": "Неуспешно премахване на '%(roomName)s' от %(groupId)s", + "Something went wrong!": "Нещо се обърка!", + "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "Видимостта на '%(roomName)s' в %(groupId)s не може да бъде обновена.", + "Visibility in Room List": "Видимост в списъка със стаи", + "Visible to everyone": "Видимо за всеки", + "Something went wrong when trying to get your communities.": "Нещо се обърка при зареждането на Вашите общности.", + "Display your community flair in rooms configured to show it.": "Показване на значката на общността в стаи, кофигурирани да я показват.", + "You're not currently a member of any communities.": "Към момента не сте член на нито една общност.", + "Unknown Address": "Неизвестен адрес", + "NOTE: Apps are not end-to-end encrypted": "ЗАБЕЛЕЖКА: Приложенията не са шифровани от край до край", + "Do you want to load widget from URL:": "Искате ли да заредите приспособление от URL адреса:", + "Allow": "Позволение", + "Delete Widget": "Изтриване на приспособление", + "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Изтриването на приспособление го премахва за всички потребители в тази стая. Сигурни ли сте, че искате да изтриете това приспособление?", + "Delete widget": "Изтрий приспособлението", + "Revoke widget access": "Премахване на достъпа до приспособления", + "Minimize apps": "Минимизирай приложенията", + "Create new room": "Създай нова стая", + "Unblacklist": "Премахване от черния списък", + "Blacklist": "Черен списък", + "Unverify": "Махни потвърждението", + "Verify...": "Потвърди...", + "Your unverified device '%(displayName)s' is requesting encryption keys.": "Вашето непотвърдено устройство '%(displayName)s' изисква ключове за шифроване.", + "I have verified my email address": "Потвърдих имейл адреса си", + "NOT verified": "НЕ е потвърдено", + "verified": "потвърдено", + "No results": "Няма резултати", + "Delete": "Изтрий", + "Communities": "Общности", + "Home": "Начална страница", + "Integrations Error": "Грешка при интеграциите", + "Could not connect to the integration server": "Неуспешно свързване със сървъра с интеграции", + "Manage Integrations": "Управление на интеграциите", + "%(nameList)s %(transitionList)s": "%(nameList)s %(transitionList)s", + "%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)sсе присъединиха %(count)s пъти", + "%(severalUsers)sjoined %(count)s times|one": "%(severalUsers)sсе присъединиха", + "%(oneUser)sjoined %(count)s times|other": "%(oneUser)sсе присъедини %(count)s пъти", + "%(oneUser)sjoined %(count)s times|one": "%(oneUser)sсе присъедини", + "%(severalUsers)sleft %(count)s times|other": "%(severalUsers)sнапуснаха %(count)s пъти", + "%(severalUsers)sleft %(count)s times|one": "%(severalUsers)sнапуснаха", + "%(oneUser)sleft %(count)s times|other": "%(oneUser)sнапусна %(count)s пъти", + "%(oneUser)sleft %(count)s times|one": "%(oneUser)sнапусна", + "%(severalUsers)sjoined and left %(count)s times|other": "%(severalUsers)sсе присъединиха и напуснаха %(count)s пъти", + "%(severalUsers)sjoined and left %(count)s times|one": "%(severalUsers)sсе присъединиха и напуснаха", + "%(oneUser)sjoined and left %(count)s times|other": "%(oneUser)sсе присъедини и напусна %(count)s пъти", + "%(oneUser)sjoined and left %(count)s times|one": "%(oneUser)sсе присъедини и напусна", + "%(severalUsers)sleft and rejoined %(count)s times|other": "%(severalUsers)sнапуснаха и се присъединиха отново %(count)s пъти", + "%(severalUsers)sleft and rejoined %(count)s times|one": "%(severalUsers)sнапуснаха и се присъединиха отново", + "%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)sнапусна и се присъедини отново %(count)s пъти", + "%(oneUser)sleft and rejoined %(count)s times|one": "%(oneUser)sнапусна и се присъедини отново", + "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)sотказаха своите покани %(count)s пъти", + "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)sотказаха своите покани", + "%(oneUser)srejected their invitation %(count)s times|other": "%(oneUser)sотказа своята покана %(count)s пъти", + "%(oneUser)srejected their invitation %(count)s times|one": "%(oneUser)sотказа своята покана", + "%(severalUsers)shad their invitations withdrawn %(count)s times|other": "%(severalUsers)sоттеглиха своите покани %(count)s пъти", + "%(severalUsers)shad their invitations withdrawn %(count)s times|one": "%(severalUsers)sоттеглиха своите покани", + "%(oneUser)shad their invitation withdrawn %(count)s times|other": "%(oneUser)sоттегли своята покана %(count)s пъти", + "%(oneUser)shad their invitation withdrawn %(count)s times|one": "%(oneUser)sоттегли своята покана", + "were invited %(count)s times|other": "бяха поканени %(count)s пъти", + "were invited %(count)s times|one": "бяха поканени", + "was invited %(count)s times|other": "беше поканен %(count)s пъти", + "was invited %(count)s times|one": "беше поканен", + "were banned %(count)s times|other": "бяха блокирани %(count)s пъти", + "were banned %(count)s times|one": "бяха блокирани", + "was banned %(count)s times|other": "беше блокиран %(count)s пъти", + "was banned %(count)s times|one": "беше блокиран", + "were unbanned %(count)s times|other": "бяха отблокирани %(count)s пъти", + "were unbanned %(count)s times|one": "бяха отблокирани", + "was unbanned %(count)s times|other": "беше отблокиран %(count)s пъти", + "was unbanned %(count)s times|one": "беше отблокиран", + "were kicked %(count)s times|other": "бяха изгонени %(count)s пъти", + "were kicked %(count)s times|one": "бяха изгонени", + "was kicked %(count)s times|other": "беше изгонен %(count)s пъти", + "was kicked %(count)s times|one": "беше изгонен", + "%(severalUsers)schanged their name %(count)s times|other": "%(severalUsers)sсмениха своето име %(count)s пъти", + "%(severalUsers)schanged their name %(count)s times|one": "%(severalUsers)sсмениха своето име", + "%(oneUser)schanged their name %(count)s times|other": "%(oneUser)sсмени своето име %(count)s пъти", + "%(oneUser)schanged their name %(count)s times|one": "%(oneUser)sсмени своето име", + "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)sсмениха своята профилна снимка %(count)s пъти", + "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)sсмениха своята профилна снимка", + "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)sсмени своята профилна снимка %(count)s пъти", + "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)sсмени своята профилна снимка", + "%(items)s and %(count)s others|other": "%(items)s и %(count)s други", + "%(items)s and %(count)s others|one": "%(items)s и още един", + "%(items)s and %(lastItem)s": "%(items)s и %(lastItem)s", + "collapse": "свий", + "expand": "разшири", + "Custom of %(powerLevel)s": "Персонализирано със стойност %(powerLevel)s", + "Custom level": "Персонализирано ниво", + "Custom": "Персонализирано", + "In reply to ": "В отговор на ", + "Room directory": "Директория на стаята", + "Start chat": "Започни чат", + "And %(count)s more...|other": "И %(count)s други...", + "ex. @bob:example.com": "напр. @bob:example.com", + "Add User": "Добави потребител", + "Matrix ID": "Matrix ID", + "Matrix Room ID": "Идентификатор на стаята", + "email address": "имейл адрес", + "Try using one of the following valid address types: %(validTypesList)s.": "Опитайте се да използвате един от следните видове валидни адреси: %(validTypesList)s.", + "You have entered an invalid address.": "Въвели сте невалиден адрес.", + "Create a new chat or reuse an existing one": "Създаване на нов чат или повторно използване на съществуващ", + "Start new chat": "Започни нов чат", + "You already have existing direct chats with this user:": "Вече имате налични директни чатове с този потребител:", + "Start chatting": "Започнете чата", + "Click on the button below to start chatting!": "Натиснете бутона по-долу, за да започнете чата!", + "Start Chatting": "Започнете чата", + "Confirm Removal": "Потвърдете премахването", + "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "Идентификаторите на общността могат да съдържат само a-z, 0-9, или '=_-./'", + "Something went wrong whilst creating your community": "Нещо се обърка по време на създаването на Вашата общност", + "Example": "Пример", + "example": "пример", + "Create": "Създай", + "Create Room": "Създай стая", + "Room name (optional)": "Име на стая (по избор)", + "Advanced options": "Разширени настройки", + "Block users on other matrix homeservers from joining this room": "Не позволявай на потребители от други matrix home сървъри да се присъединяват към тази стая", + "This setting cannot be changed later!": "Тази настройка не може да бъде променена по-късно!", + "Unknown error": "Непозната грешка", + "Incorrect password": "Неправилна парола", + "Deactivate Account": "Деактивация на профила", + "Deactivate my account": "Деактивирай моя профил", + "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Това ще направи профил Ви перманентно неизползваем. Няма да можете да се регистрирате отново със същия потребителски идентификатор.", + "This action is irreversible.": "Това действие е необратимо.", + "Device name": "Име на устройството", + "Device key": "Ключ на устройството", + "In future this verification process will be more sophisticated.": "В бъдеще този процес на потвърждение ще бъде по-лесен.", + "Verify device": "Потвърди устройството", + "Start verification": "Започни потвърждението", + "Verification Pending": "Очакване на потвърждението", + "Verification": "Потвърждение", + "I verify that the keys match": "Потвърждавам, че ключовете съвпадат", + "An error has occurred.": "Възникна грешка.", + "You added a new device '%(displayName)s', which is requesting encryption keys.": "Добавихте ново устройство '%(displayName)s', което изисква ключове за шифроване.", + "Share without verifying": "Сподели без потвърждение", + "Ignore request": "Игнорирай поканата", + "Loading device info...": "Зареждане на информация за устройството...", + "Encryption key request": "Шифроване на ключове за заявка", + "Otherwise, click here to send a bug report.": "В противен случай, натиснете тук, за да изпратите съобщение за грешка.", + "Report it": "Съобщете го", + "Bug Report": "Съобщение за грешка", + "Unable to restore session": "Неуспешно възстановяване на сесията", + "Continue anyway": "Продължете въпреки това", + "Invalid Email Address": "Невалиден имейл адрес", + "This doesn't appear to be a valid email address": "Това не изглежда да е валиден имейл адрес", + "Please check your email and click on the link it contains. Once this is done, click continue.": "Моля, проверете своя имейл адрес и натиснете връзката, която той съдържа. След като направите това, натиснете продължи.", + "Unable to add email address": "Неуспешно добавяне на имейл адрес", + "Unable to verify email address.": "Неуспешно потвърждение на имейл адрес.", + "Unable to accept invite": "Неуспешно приемане на поканата", + "Unable to reject invite": "Неуспешно отхвърляне на поканата", + "Unable to leave room": "Неуспешно напускане на стаята", + "Tried to load a specific point in this room's timeline, but was unable to find it.": "Опита се да зареди конкретна точка в хронологията на тази стая, но не успя да я намери.", + "Unable to remove contact information": "Неуспешно премахване на информацията на контакта", + "This will allow you to reset your password and receive notifications.": "Това ще Ви позволи да възстановите Вашата парола и да получавате известия.", + "Skip": "Пропусни", + "User names may only contain letters, numbers, dots, hyphens and underscores.": "Потребителските имена могат да съдържат само букви, цифри, точки, тирета и долни черти.", + "Username not available": "Потребителското име е заето", + "Username invalid: %(errMessage)s": "Невалидно потребителско име: %(errMessage)s", + "An error occurred: %(error_string)s": "Възникна грешка: %(error_string)s", + "Username available": "Потребителското име не е заето", + "To get started, please pick a username!": "За да започнете, моля изберете потребителско име!", + "If you already have a Matrix account you can log in instead.": "Ако вече имате Matrix профил, можете да влезете с него.", + "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "В момента Вие блокирате непотвърдени устройства; за да изпращате съобщения до тези устройства, трябва да ги потвърдите.", + "Room contains unknown devices": "Стаята съдържа непознати устройства", + "\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" съдържа устройства, който не сте виждали до сега.", + "Unknown devices": "Непознати устройства", + "Private Chat": "Личен чат", + "Public Chat": "Публичен чат", + "Alias (optional)": "Псевдоним (по избор)", + "Name": "Име", + "Topic": "Тема", + "Make this room private": "Направи тази стая лична", + "Share message history with new users": "Сподели историята на съобщението с новите потребители", + "Encrypt room": "Шифровай стаята", + "You must register to use this functionality": "Трябва да се регистрирате, за да използвате тази функционалност", + "You must join the room to see its files": "Трябва да се присъедините към стаята, за да видите файловете, които съдържа", + "There are no visible files in this room": "Няма видими файлове в тази стая", + "Which rooms would you like to add to this summary?": "Кои стаи бихте искали да добавите в това обобщение?" } From 5e90da73f0489d5e6c25c8f31bf017889116c951 Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Wed, 21 Feb 2018 11:56:55 +0000 Subject: [PATCH 0357/1160] Translated using Weblate (Galician) Currently translated at 98.7% (974 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/gl/ --- src/i18n/strings/gl.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/gl.json b/src/i18n/strings/gl.json index 7a1fd567ee..d972376d41 100644 --- a/src/i18n/strings/gl.json +++ b/src/i18n/strings/gl.json @@ -768,7 +768,7 @@ "Create a new community": "Crear unha nova comunidade", "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Crear unha comunidade para agrupar usuarias e salas! Poña unha páxina de inicio personalizada para destacar o seu lugar no universo Matrix.", "Join an existing community": "Unirse a unha comunidade existente", - "To join an existing community you'll have to know its community identifier; this will look something like +example:matrix.org.": "Para unirse a unha comunidade existente deberá coñecer o identificador de esa comunidade; terá un aspecto como +exemplo:matrix.org", + "To join an existing community you'll have to know its community identifier; this will look something like +example:matrix.org.": "Para unirse a unha comunidade existente deberá coñecer o identificador de esa comunidade; terá un aspecto como +exemplo:matrix.org.", "You have no visible notifications": "Non ten notificacións visibles", "Scroll to bottom of page": "Desplácese ate o final da páxina", "Message not sent due to unknown devices being present": "Non se enviou a mensaxe porque hai dispositivos non coñecidos", From fc73442cdc4fba8cf7c610bee8a45c76aee8b67b Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 21 Feb 2018 15:06:10 +0000 Subject: [PATCH 0358/1160] Change icon from "R" to "X" --- src/components/structures/TagPanel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/TagPanel.js b/src/components/structures/TagPanel.js index d614588ccc..59365d8139 100644 --- a/src/components/structures/TagPanel.js +++ b/src/components/structures/TagPanel.js @@ -111,7 +111,7 @@ const TagPanel = React.createClass({ }); return
    - +
    Date: Wed, 21 Feb 2018 17:15:43 +0000 Subject: [PATCH 0359/1160] Only show "X" when filtering, add alt/title --- src/components/structures/TagPanel.js | 17 ++++++++++++++--- src/i18n/strings/en_EN.json | 9 +++++---- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/components/structures/TagPanel.js b/src/components/structures/TagPanel.js index 59365d8139..46e539fa04 100644 --- a/src/components/structures/TagPanel.js +++ b/src/components/structures/TagPanel.js @@ -24,6 +24,7 @@ import GroupActions from '../../actions/GroupActions'; import sdk from '../../index'; import dis from '../../dispatcher'; +import { _t } from '../../languageHandler'; import { Droppable } from 'react-beautiful-dnd'; @@ -92,7 +93,7 @@ const TagPanel = React.createClass({ dis.dispatch({action: 'view_create_group'}); }, - onLogoClick(ev) { + onClearFilterClick(ev) { dis.dispatch({action: 'deselect_tags'}); }, @@ -109,9 +110,19 @@ const TagPanel = React.createClass({ selected={this.state.selectedTags.includes(tag)} />; }); + + const clearButton = this.state.selectedTags.length > 0 ? + {_t("Clear : +
    ; + return
    - - + + { clearButton }
    to start a chat with someone": "Press to start a chat with someone", "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", "Community Invites": "Community Invites", @@ -826,6 +823,7 @@ "Click to mute video": "Click to mute video", "Click to unmute audio": "Click to unmute audio", "Click to mute audio": "Click to mute audio", + "Clear filter": "Clear filter", "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.", "Tried to load a specific point in this room's timeline, but was unable to find it.": "Tried to load a specific point in this room's timeline, but was unable to find it.", "Failed to load timeline position": "Failed to load timeline position", @@ -984,5 +982,8 @@ "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.", "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.", "File to import": "File to import", - "Import": "Import" + "Import": "Import", + "Failed to set direct chat tag": "Failed to set direct chat tag", + "Failed to remove tag %(tagName)s from room": "Failed to remove tag %(tagName)s from room", + "Failed to add tag %(tagName)s to room": "Failed to add tag %(tagName)s to room" } From bb386c05d906eda9e519a7c70812ee5b98948e65 Mon Sep 17 00:00:00 2001 From: Ralitsa Bozhkova Date: Wed, 21 Feb 2018 14:27:58 +0000 Subject: [PATCH 0360/1160] Translated using Weblate (Bulgarian) Currently translated at 79.5% (784 of 986 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 35505c0038..4b0993e4ba 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -756,5 +756,31 @@ "You must register to use this functionality": "Трябва да се регистрирате, за да използвате тази функционалност", "You must join the room to see its files": "Трябва да се присъедините към стаята, за да видите файловете, които съдържа", "There are no visible files in this room": "Няма видими файлове в тази стая", - "Which rooms would you like to add to this summary?": "Кои стаи бихте искали да добавите в това обобщение?" + "Which rooms would you like to add to this summary?": "Кои стаи бихте искали да добавите в това обобщение?", + "Add to summary": "Добави в обобщението", + "Failed to add the following rooms to the summary of %(groupId)s:": "Неуспешно добавяне на следните стаи в обобщението на %(groupId)s:", + "Add a Room": "Добавяне на стая", + "Failed to remove the room from the summary of %(groupId)s": "Неуспешно премахване на стаята от обобщението на %(groupId)s", + "The room '%(roomName)s' could not be removed from the summary.": "Стаята '%(roomName)s' не може да бъде премахната от обобщението.", + "Who would you like to add to this summary?": "Кого бихте желали да добавите в това обобщение?", + "Failed to add the following users to the summary of %(groupId)s:": "Неуспешно добавяне на следните потребители в обобщението на %(groupId)s:", + "Add a User": "Добавяне на потребител", + "Failed to remove a user from the summary of %(groupId)s": "Неуспешно премахване на потребител от обобщението на %(groupId)s", + "The user '%(displayName)s' could not be removed from the summary.": "Потребителят '%(displayName)s' не може да бъде премахнат от обобщението.", + "Failed to upload image": "Неуспешно качване на снимка", + "Leave %(groupName)s?": "Напускане на %(groupName)s?", + "Featured Rooms:": "Препоръчани стаи:", + "Featured Users:": "Препоръчани потребители:", + "Long Description (HTML)": "Дълго описание (HTML)", + "Description": "Описание", + "This Home server does not support communities": "Този Home сървър не поддържа общности", + "Failed to load %(groupId)s": "Неуспешно зареждане на %(groupId)s", + "Reject invitation": "Отхвърли поканата", + "Are you sure you want to reject the invitation?": "Сигурни ли сте, че искате да отхвърлите поканата?", + "Failed to reject invitation": "Неуспешно отхвърляне на поканата", + "This room is not public. You will not be able to rejoin without an invite.": "Тази стая не е публична. Няма да можете да се присъедините отново без покана.", + "Are you sure you want to leave the room '%(roomName)s'?": "Сигурни ли сте, че искате да напуснете стаята '%(roomName)s'?", + "Failed to leave room": "Неуспешно напускане на стаята", + "Old cryptography data detected": "Старите криптирани данни са изтрити", + "Your Communities": "Вашите общности" } From d9032d706f5ea80b51edaaad86dbbdbe8d748144 Mon Sep 17 00:00:00 2001 From: Walter Date: Tue, 13 Feb 2018 18:55:45 +0000 Subject: [PATCH 0361/1160] Translated using Weblate (Russian) Currently translated at 100.0% (987 of 987 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index d24ee71de1..c07ea1e1fb 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -984,5 +984,6 @@ "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s изменил отображаемое имя на %(displayName)s.", "Failed to set direct chat tag": "Не удалось установить тег прямого чата", "Failed to remove tag %(tagName)s from room": "Не удалось удалить тег %(tagName)s из комнаты", - "Failed to add tag %(tagName)s to room": "Не удалось добавить тег %(tagName)s в комнату" + "Failed to add tag %(tagName)s to room": "Не удалось добавить тег %(tagName)s в комнату", + "Clear filter": "Очистить фильтр" } From 296e2bd928e703d1afbb48a778bde338e0d81c00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Tue, 6 Feb 2018 19:11:45 +0000 Subject: [PATCH 0362/1160] Translated using Weblate (French) Currently translated at 100.0% (987 of 987 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index f0f9b2dae9..7efbf5f548 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -984,5 +984,6 @@ "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s a changé son nom affiché en %(displayName)s.", "Failed to set direct chat tag": "Échec de l'ajout de l'étiquette discussion directe", "Failed to remove tag %(tagName)s from room": "Échec de la suppression de l'étiquette %(tagName)s du salon", - "Failed to add tag %(tagName)s to room": "Échec de l'ajout de l'étiquette %(tagName)s au salon" + "Failed to add tag %(tagName)s to room": "Échec de l'ajout de l'étiquette %(tagName)s au salon", + "Clear filter": "Supprimer les filtres" } From 5cd7a7fc061784bff84795c961782d73866c97f2 Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Wed, 21 Feb 2018 19:26:14 +0000 Subject: [PATCH 0363/1160] Fix group member spinner being out of flex order --- src/components/views/groups/GroupMemberInfo.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/views/groups/GroupMemberInfo.js b/src/components/views/groups/GroupMemberInfo.js index 305aec8cdd..097fb1f7db 100644 --- a/src/components/views/groups/GroupMemberInfo.js +++ b/src/components/views/groups/GroupMemberInfo.js @@ -132,7 +132,9 @@ module.exports = React.createClass({ render: function() { if (this.state.removingUser) { const Spinner = sdk.getComponent("elements.Spinner"); - return ; + return
    + +
    ; } let adminTools; From ffb524b6a5a614734d9ae30401b95b44eb62ca48 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Wed, 21 Feb 2018 23:10:08 +0000 Subject: [PATCH 0364/1160] Allow widget iframes to request camera and microphone permissions. --- src/components/views/elements/AppTile.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index a63823555f..b325dace84 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -393,6 +393,10 @@ export default React.createClass({ const sandboxFlags = "allow-forms allow-popups allow-popups-to-escape-sandbox "+ "allow-same-origin allow-scripts allow-presentation"; + // Additional iframe feature pemissions + // (see - https://sites.google.com/a/chromium.org/dev/Home/chromium-security/deprecating-permissions-in-cross-origin-iframes and https://wicg.github.io/feature-policy/) + const iframeFeatures = "microphone; camera; encrypted-media;"; + if (this.props.show) { const loadingElement = (
    @@ -413,6 +417,8 @@ export default React.createClass({
    { this.state.loading && loadingElement } + ); + } +}); diff --git a/src/components/views/settings/Notifications.js b/src/components/views/settings/Notifications.js new file mode 100644 index 0000000000..be03b4d70a --- /dev/null +++ b/src/components/views/settings/Notifications.js @@ -0,0 +1,919 @@ +/* +Copyright 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import React from 'react'; +import Promise from 'bluebird'; +import sdk from 'matrix-react-sdk'; +import { _t } from 'matrix-react-sdk/lib/languageHandler'; +import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg'; +import UserSettingsStore from 'matrix-react-sdk/lib/UserSettingsStore'; +import SettingsStore, {SettingLevel} from "matrix-react-sdk/lib/settings/SettingsStore"; +import Modal from 'matrix-react-sdk/lib/Modal'; +import { + NotificationUtils, + VectorPushRulesDefinitions, + PushRuleVectorState, + ContentRules +} from '../../../notifications'; + +// TODO: this "view" component still has far too much application logic in it, +// which should be factored out to other files. + +// TODO: this component also does a lot of direct poking into this.state, which +// is VERY NAUGHTY. + + +/** + * Rules that Vector used to set in order to override the actions of default rules. + * These are used to port peoples existing overrides to match the current API. + * These can be removed and forgotten once everyone has moved to the new client. + */ +const LEGACY_RULES = { + "im.vector.rule.contains_display_name": ".m.rule.contains_display_name", + "im.vector.rule.room_one_to_one": ".m.rule.room_one_to_one", + "im.vector.rule.room_message": ".m.rule.message", + "im.vector.rule.invite_for_me": ".m.rule.invite_for_me", + "im.vector.rule.call": ".m.rule.call", + "im.vector.rule.notices": ".m.rule.suppress_notices" +}; + +function portLegacyActions(actions) { + const decoded = NotificationUtils.decodeActions(actions); + if (decoded !== null) { + return NotificationUtils.encodeActions(decoded); + } else { + // We don't recognise one of the actions here, so we don't try to + // canonicalise them. + return actions; + } +} + +module.exports = React.createClass({ + displayName: 'Notifications', + + phases: { + LOADING: "LOADING", // The component is loading or sending data to the hs + DISPLAY: "DISPLAY", // The component is ready and display data + ERROR: "ERROR" // There was an error + }, + + propTypes: { + // The array of threepids from the JS SDK (required for email notifications) + threepids: React.PropTypes.array.isRequired, + // The brand string set when creating an email pusher + brand: React.PropTypes.string, + }, + + getDefaultProps: function() { + return { + threepids: [] + }; + }, + + getInitialState: function() { + return { + phase: this.phases.LOADING, + masterPushRule: undefined, // The master rule ('.m.rule.master') + vectorPushRules: [], // HS default push rules displayed in Vector UI + vectorContentRules: { // Keyword push rules displayed in Vector UI + vectorState: PushRuleVectorState.ON, + rules: [] + }, + externalPushRules: [], // Push rules (except content rule) that have been defined outside Vector UI + externalContentRules: [] // Keyword push rules that have been defined outside Vector UI + }; + }, + + componentWillMount: function() { + this._refreshFromServer(); + }, + + onEnableNotificationsChange: function(event) { + const self = this; + this.setState({ + phase: this.phases.LOADING + }); + + MatrixClientPeg.get().setPushRuleEnabled('global', self.state.masterPushRule.kind, self.state.masterPushRule.rule_id, !event.target.checked).done(function() { + self._refreshFromServer(); + }); + }, + + onEnableDesktopNotificationsChange: function(event) { + SettingsStore.setValue( + "notificationsEnabled", null, + SettingLevel.DEVICE, + event.target.checked, + ).finally(() => { + this.forceUpdate(); + }); + }, + + onEnableDesktopNotificationBodyChange: function(event) { + SettingsStore.setValue( + "notificationBodyEnabled", null, + SettingLevel.DEVICE, + event.target.checked, + ).finally(() => { + this.forceUpdate(); + }); + }, + + onEnableAudioNotificationsChange: function(event) { + SettingsStore.setValue( + "audioNotificationsEnabled", null, + SettingLevel.DEVICE, + event.target.checked, + ).finally(() => { + this.forceUpdate(); + }); + }, + + onEnableEmailNotificationsChange: function(address, event) { + let emailPusherPromise; + if (event.target.checked) { + const data = {} + data['brand'] = this.props.brand || 'Riot'; + emailPusherPromise = UserSettingsStore.addEmailPusher(address, data); + } else { + const emailPusher = UserSettingsStore.getEmailPusher(this.state.pushers, address); + emailPusher.kind = null; + emailPusherPromise = MatrixClientPeg.get().setPusher(emailPusher); + } + emailPusherPromise.done(() => { + this._refreshFromServer(); + }, (error) => { + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + Modal.createTrackedDialog('Error saving email notification preferences', '', ErrorDialog, { + title: _t('Error saving email notification preferences'), + description: _t('An error occurred whilst saving your email notification preferences.'), + }); + }); + }, + + onNotifStateButtonClicked: function(event) { + // FIXME: use .bind() rather than className metadata here surely + const vectorRuleId = event.target.className.split("-")[0]; + const newPushRuleVectorState = event.target.className.split("-")[1]; + + if ("_keywords" === vectorRuleId) { + this._setKeywordsPushRuleVectorState(newPushRuleVectorState) + } + else { + const rule = this.getRule(vectorRuleId); + if (rule) { + this._setPushRuleVectorState(rule, newPushRuleVectorState); + } + } + }, + + onKeywordsClicked: function(event) { + const self = this; + + // Compute the keywords list to display + let keywords = []; + for (let i in this.state.vectorContentRules.rules) { + const rule = this.state.vectorContentRules.rules[i]; + keywords.push(rule.pattern); + } + if (keywords.length) { + // As keeping the order of per-word push rules hs side is a bit tricky to code, + // display the keywords in alphabetical order to the user + keywords.sort(); + + keywords = keywords.join(", "); + } + else { + keywords = ""; + } + + const TextInputDialog = sdk.getComponent("dialogs.TextInputDialog"); + Modal.createTrackedDialog('Keywords Dialog', '', TextInputDialog, { + title: _t('Keywords'), + description: _t('Enter keywords separated by a comma:'), + button: _t('OK'), + value: keywords, + onFinished: function onFinished(should_leave, newValue) { + + if (should_leave && newValue !== keywords) { + let newKeywords = newValue.split(','); + for (let i in newKeywords) { + newKeywords[i] = newKeywords[i].trim(); + } + + // Remove duplicates and empty + newKeywords = newKeywords.reduce(function(array, keyword){ + if (keyword !== "" && array.indexOf(keyword) < 0) { + array.push(keyword); + } + return array; + },[]); + + self._setKeywords(newKeywords); + } + } + }); + }, + + getRule: function(vectorRuleId) { + for (let i in this.state.vectorPushRules) { + const rule = this.state.vectorPushRules[i]; + if (rule.vectorRuleId === vectorRuleId) { + return rule; + } + } + }, + + _setPushRuleVectorState: function(rule, newPushRuleVectorState) { + if (rule && rule.vectorState !== newPushRuleVectorState) { + + this.setState({ + phase: this.phases.LOADING + }); + + const self = this; + const cli = MatrixClientPeg.get(); + const deferreds = []; + const ruleDefinition = VectorPushRulesDefinitions[rule.vectorRuleId]; + + if (rule.rule) { + const actions = ruleDefinition.vectorStateToActions[newPushRuleVectorState]; + + if (!actions) { + // The new state corresponds to disabling the rule. + deferreds.push(cli.setPushRuleEnabled('global', rule.rule.kind, rule.rule.rule_id, false)); + } + else { + // The new state corresponds to enabling the rule and setting specific actions + deferreds.push(this._updatePushRuleActions(rule.rule, actions, true)); + } + } + + Promise.all(deferreds).done(function() { + self._refreshFromServer(); + }, function(error) { + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + console.error("Failed to change settings: " + error); + Modal.createTrackedDialog('Failed to change settings', '', ErrorDialog, { + title: _t('Failed to change settings'), + description: ((error && error.message) ? error.message : _t('Operation failed')), + onFinished: self._refreshFromServer + }); + }); + } + }, + + _setKeywordsPushRuleVectorState: function(newPushRuleVectorState) { + // Is there really a change? + if (this.state.vectorContentRules.vectorState === newPushRuleVectorState + || this.state.vectorContentRules.rules.length === 0) { + return; + } + + const self = this; + const cli = MatrixClientPeg.get(); + + this.setState({ + phase: this.phases.LOADING + }); + + // Update all rules in self.state.vectorContentRules + const deferreds = []; + for (let i in this.state.vectorContentRules.rules) { + const rule = this.state.vectorContentRules.rules[i]; + + let enabled, actions; + switch (newPushRuleVectorState) { + case PushRuleVectorState.ON: + if (rule.actions.length !== 1) { + actions = PushRuleVectorState.actionsFor(PushRuleVectorState.ON); + } + + if (this.state.vectorContentRules.vectorState === PushRuleVectorState.OFF) { + enabled = true; + } + break; + + case PushRuleVectorState.LOUD: + if (rule.actions.length !== 3) { + actions = PushRuleVectorState.actionsFor(PushRuleVectorState.LOUD); + } + + if (this.state.vectorContentRules.vectorState === PushRuleVectorState.OFF) { + enabled = true; + } + break; + + case PushRuleVectorState.OFF: + enabled = false; + break; + } + + if (actions) { + // Note that the workaround in _updatePushRuleActions will automatically + // enable the rule + deferreds.push(this._updatePushRuleActions(rule, actions, enabled)); + } + else if (enabled != undefined) { + deferreds.push(cli.setPushRuleEnabled('global', rule.kind, rule.rule_id, enabled)); + } + } + + Promise.all(deferreds).done(function(resps) { + self._refreshFromServer(); + }, function(error) { + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + console.error("Can't update user notification settings: " + error); + Modal.createTrackedDialog('Can\'t update user notifcation settings', '', ErrorDialog, { + title: _t('Can\'t update user notification settings'), + description: ((error && error.message) ? error.message : _t('Operation failed')), + onFinished: self._refreshFromServer + }); + }); + }, + + _setKeywords: function(newKeywords) { + this.setState({ + phase: this.phases.LOADING + }); + + const self = this; + const cli = MatrixClientPeg.get(); + const removeDeferreds = []; + + // Remove per-word push rules of keywords that are no more in the list + const vectorContentRulesPatterns = []; + for (let i in self.state.vectorContentRules.rules) { + const rule = self.state.vectorContentRules.rules[i]; + + vectorContentRulesPatterns.push(rule.pattern); + + if (newKeywords.indexOf(rule.pattern) < 0) { + removeDeferreds.push(cli.deletePushRule('global', rule.kind, rule.rule_id)); + } + } + + // If the keyword is part of `externalContentRules`, remove the rule + // before recreating it in the right Vector path + for (let i in self.state.externalContentRules) { + const rule = self.state.externalContentRules[i]; + + if (newKeywords.indexOf(rule.pattern) >= 0) { + removeDeferreds.push(cli.deletePushRule('global', rule.kind, rule.rule_id)); + } + } + + const onError = function(error) { + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + console.error("Failed to update keywords: " + error); + Modal.createTrackedDialog('Failed to update keywords', '', ErrorDialog, { + title: _t('Failed to update keywords'), + description: ((error && error.message) ? error.message : _t('Operation failed')), + onFinished: self._refreshFromServer + }); + } + + // Then, add the new ones + Promise.all(removeDeferreds).done(function(resps) { + const deferreds = []; + + let pushRuleVectorStateKind = self.state.vectorContentRules.vectorState; + if (pushRuleVectorStateKind === PushRuleVectorState.OFF) { + // When the current global keywords rule is OFF, we need to look at + // the flavor of rules in 'vectorContentRules' to apply the same actions + // when creating the new rule. + // Thus, this new rule will join the 'vectorContentRules' set. + if (self.state.vectorContentRules.rules.length) { + pushRuleVectorStateKind = PushRuleVectorState.contentRuleVectorStateKind(self.state.vectorContentRules.rules[0]); + } + else { + // ON is default + pushRuleVectorStateKind = PushRuleVectorState.ON; + } + } + + for (let i in newKeywords) { + const keyword = newKeywords[i]; + + if (vectorContentRulesPatterns.indexOf(keyword) < 0) { + if (self.state.vectorContentRules.vectorState !== PushRuleVectorState.OFF) { + deferreds.push(cli.addPushRule + ('global', 'content', keyword, { + actions: PushRuleVectorState.actionsFor(pushRuleVectorStateKind), + pattern: keyword + })); + } + else { + deferreds.push(self._addDisabledPushRule('global', 'content', keyword, { + actions: PushRuleVectorState.actionsFor(pushRuleVectorStateKind), + pattern: keyword + })); + } + } + } + + Promise.all(deferreds).done(function(resps) { + self._refreshFromServer(); + }, onError); + }, onError); + }, + + // Create a push rule but disabled + _addDisabledPushRule: function(scope, kind, ruleId, body) { + const cli = MatrixClientPeg.get(); + return cli.addPushRule(scope, kind, ruleId, body).then(() => + cli.setPushRuleEnabled(scope, kind, ruleId, false) + ); + }, + + // Check if any legacy im.vector rules need to be ported to the new API + // for overriding the actions of default rules. + _portRulesToNewAPI: function(rulesets) { + const self = this; + const needsUpdate = []; + const cli = MatrixClientPeg.get(); + + for (let kind in rulesets.global) { + const ruleset = rulesets.global[kind]; + for (let i = 0; i < ruleset.length; ++i) { + const rule = ruleset[i]; + if (rule.rule_id in LEGACY_RULES) { + console.log("Porting legacy rule", rule); + needsUpdate.push( function(kind, rule) { + return cli.setPushRuleActions( + 'global', kind, LEGACY_RULES[rule.rule_id], portLegacyActions(rule.actions) + ).then(() => + cli.deletePushRule('global', kind, rule.rule_id) + ).catch( (e) => { + console.warn(`Error when porting legacy rule: ${e}`); + }); + }(kind, rule)); + } + } + } + + if (needsUpdate.length > 0) { + // If some of the rules need to be ported then wait for the porting + // to happen and then fetch the rules again. + return Promise.all(needsUpdate).then(() => + cli.getPushRules() + ); + } else { + // Otherwise return the rules that we already have. + return rulesets; + } + }, + + _refreshFromServer: function() { + const self = this; + const pushRulesPromise = MatrixClientPeg.get().getPushRules().then(self._portRulesToNewAPI).then(function(rulesets) { + + /// XXX seriously? wtf is this? + MatrixClientPeg.get().pushRules = rulesets; + + // Get homeserver default rules and triage them by categories + const rule_categories = { + // The master rule (all notifications disabling) + '.m.rule.master': 'master', + + // The default push rules displayed by Vector UI + '.m.rule.contains_display_name': 'vector', + '.m.rule.contains_user_name': 'vector', + '.m.rule.room_one_to_one': 'vector', + '.m.rule.message': 'vector', + '.m.rule.invite_for_me': 'vector', + //'.m.rule.member_event': 'vector', + '.m.rule.call': 'vector', + '.m.rule.suppress_notices': 'vector' + + // Others go to others + }; + + // HS default rules + const defaultRules = {master: [], vector: {}, others: []}; + + for (let kind in rulesets.global) { + for (let i = 0; i < Object.keys(rulesets.global[kind]).length; ++i) { + const r = rulesets.global[kind][i]; + const cat = rule_categories[r.rule_id]; + r.kind = kind; + + if (r.rule_id[0] === '.') { + if (cat === 'vector') { + defaultRules.vector[r.rule_id] = r; + } + else if (cat === 'master') { + defaultRules.master.push(r); + } + else { + defaultRules['others'].push(r); + } + } + } + } + + // Get the master rule if any defined by the hs + if (defaultRules.master.length > 0) { + self.state.masterPushRule = defaultRules.master[0]; + } + + // parse the keyword rules into our state + const contentRules = ContentRules.parseContentRules(rulesets); + self.state.vectorContentRules = { + vectorState: contentRules.vectorState, + rules: contentRules.rules, + }; + self.state.externalContentRules = contentRules.externalRules; + + // Build the rules displayed in the Vector UI matrix table + self.state.vectorPushRules = []; + self.state.externalPushRules = []; + + const vectorRuleIds = [ + '.m.rule.contains_display_name', + '.m.rule.contains_user_name', + '_keywords', + '.m.rule.room_one_to_one', + '.m.rule.message', + '.m.rule.invite_for_me', + //'im.vector.rule.member_event', + '.m.rule.call', + '.m.rule.suppress_notices' + ]; + for (let i in vectorRuleIds) { + const vectorRuleId = vectorRuleIds[i]; + + if (vectorRuleId === '_keywords') { + // keywords needs a special handling + // For Vector UI, this is a single global push rule but translated in Matrix, + // it corresponds to all content push rules (stored in self.state.vectorContentRule) + self.state.vectorPushRules.push({ + "vectorRuleId": "_keywords", + "description" : ( + + { _t('Messages containing keywords', + {}, + { 'span': (sub) => + {sub} + }, + )} + + ), + "vectorState": self.state.vectorContentRules.vectorState + }); + } + else { + const ruleDefinition = VectorPushRulesDefinitions[vectorRuleId]; + const rule = defaultRules.vector[vectorRuleId]; + + const vectorState = ruleDefinition.ruleToVectorState(rule); + + //console.log("Refreshing vectorPushRules for " + vectorRuleId +", "+ ruleDefinition.description +", " + rule +", " + vectorState); + + self.state.vectorPushRules.push({ + "vectorRuleId": vectorRuleId, + "description" : _t(ruleDefinition.description), // Text from VectorPushRulesDefinitions.js + "rule": rule, + "vectorState": vectorState, + }); + + // if there was a rule which we couldn't parse, add it to the external list + if (rule && !vectorState) { + rule.description = ruleDefinition.description; + self.state.externalPushRules.push(rule); + } + } + } + + // Build the rules not managed by Vector UI + const otherRulesDescriptions = { + '.m.rule.message': _t('Notify for all other messages/rooms'), + '.m.rule.fallback': _t('Notify me for anything else'), + }; + + for (let i in defaultRules.others) { + const rule = defaultRules.others[i]; + const ruleDescription = otherRulesDescriptions[rule.rule_id]; + + // Show enabled default rules that was modified by the user + if (ruleDescription && rule.enabled && !rule.default) { + rule.description = ruleDescription; + self.state.externalPushRules.push(rule); + } + } + }); + + const pushersPromise = MatrixClientPeg.get().getPushers().then(function(resp) { + self.setState({pushers: resp.pushers}); + }); + + Promise.all([pushRulesPromise, pushersPromise]).then(function() { + self.setState({ + phase: self.phases.DISPLAY + }); + }, function(error) { + console.error(error); + self.setState({ + phase: self.phases.ERROR + }); + }).finally(() => { + // actually explicitly update our state having been deep-manipulating it + self.setState({ + masterPushRule: self.state.masterPushRule, + vectorContentRules: self.state.vectorContentRules, + vectorPushRules: self.state.vectorPushRules, + externalContentRules: self.state.externalContentRules, + externalPushRules: self.state.externalPushRules, + }); + }).done(); + }, + + _updatePushRuleActions: function(rule, actions, enabled) { + const cli = MatrixClientPeg.get(); + + return cli.setPushRuleActions( + 'global', rule.kind, rule.rule_id, actions + ).then( function() { + // Then, if requested, enabled or disabled the rule + if (undefined != enabled) { + return cli.setPushRuleEnabled( + 'global', rule.kind, rule.rule_id, enabled + ); + } + }); + }, + + renderNotifRulesTableRow: function(title, className, pushRuleVectorState) { + return ( + + + { title } + + + + + + + + + + + + + + + ); + }, + + renderNotifRulesTableRows: function() { + const rows = []; + for (let i in this.state.vectorPushRules) { + const rule = this.state.vectorPushRules[i]; + //console.log("rendering: " + rule.description + ", " + rule.vectorRuleId + ", " + rule.vectorState); + rows.push(this.renderNotifRulesTableRow(rule.description, rule.vectorRuleId, rule.vectorState)); + } + return rows; + }, + + emailNotificationsRow: function(address, label) { + return (
    +
    + +
    +
    + +
    +
    ); + }, + + render: function() { + const self = this; + + let spinner; + if (this.state.phase === this.phases.LOADING) { + const Loader = sdk.getComponent("elements.Spinner"); + spinner = ; + } + + let masterPushRuleDiv; + if (this.state.masterPushRule) { + masterPushRuleDiv = ( +
    +
    + +
    +
    + +
    +
    + ); + } + + // When enabled, the master rule inhibits all existing rules + // So do not show all notification settings + if (this.state.masterPushRule && this.state.masterPushRule.enabled) { + return ( +
    + {masterPushRuleDiv} + +
    + { _t('All notifications are currently disabled for all targets.') }. +
    +
    + ); + } + + const emailThreepids = this.props.threepids.filter((tp) => tp.medium === "email"); + let emailNotificationsRow; + if (emailThreepids.length === 0) { + emailNotificationsRow =
    + { _t('Add an email address above to configure email notifications') } +
    ; + } else { + // This only supports the first email address in your profile for now + emailNotificationsRow = this.emailNotificationsRow( + emailThreepids[0].address, + `${_t('Enable email notifications')} (${emailThreepids[0].address})` + ); + } + + // Build external push rules + const externalRules = []; + for (let i in this.state.externalPushRules) { + const rule = this.state.externalPushRules[i]; + externalRules.push(
  • { _t(rule.description) }
  • ); + } + + // Show keywords not displayed by the vector UI as a single external push rule + let externalKeywords = []; + for (let i in this.state.externalContentRules) { + const rule = this.state.externalContentRules[i]; + externalKeywords.push(rule.pattern); + } + if (externalKeywords.length) { + externalKeywords = externalKeywords.join(", "); + externalRules.push(
  • { _t('Notifications on the following keywords follow rules which can’t be displayed here:') } { externalKeywords }
  • ); + } + + let devicesSection; + if (this.state.pushers === undefined) { + devicesSection =
    { _t('Unable to fetch notification target list') }
    + } else if (this.state.pushers.length == 0) { + devicesSection = null; + } else { + // TODO: It would be great to be able to delete pushers from here too, + // and this wouldn't be hard to add. + const rows = []; + for (let i = 0; i < this.state.pushers.length; ++i) { + rows.push( + {this.state.pushers[i].app_display_name} + {this.state.pushers[i].device_display_name} + ); + } + devicesSection = ( + + {rows} + +
    ); + } + if (devicesSection) { + devicesSection = (
    +

    { _t('Notification targets') }

    + { devicesSection } +
    ); + } + + let advancedSettings; + if (externalRules.length) { + advancedSettings = ( +
    +

    { _t('Advanced notification settings') }

    + { _t('There are advanced notifications which are not shown here') }.
    + { _t('You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply') }. +
      + { externalRules } +
    +
    + ); + } + + return ( +
    + + {masterPushRuleDiv} + +
    + + { spinner } + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + + { emailNotificationsRow } + +
    + + + + + + + + + + + + { this.renderNotifRulesTableRows() } + + +
    { _t('Off') }{ _t('On') }{ _t('Noisy') }
    +
    + + { advancedSettings } + + { devicesSection } + +
    + +
    + ); + } +}); From 178fb647adcd53473ab992526f70d088480dec7f Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Wed, 11 Apr 2018 23:58:37 +0100 Subject: [PATCH 0755/1160] move notifications logic over from riot-web --- src/notifications/ContentRules.js | 125 +++++++++++++++ src/notifications/NotificationUtils.js | 89 +++++++++++ src/notifications/PushRuleVectorState.js | 94 +++++++++++ src/notifications/StandardActions.js | 30 ++++ .../VectorPushRulesDefinitions.js | 146 ++++++++++++++++++ src/notifications/index.js | 24 +++ 6 files changed, 508 insertions(+) create mode 100644 src/notifications/ContentRules.js create mode 100644 src/notifications/NotificationUtils.js create mode 100644 src/notifications/PushRuleVectorState.js create mode 100644 src/notifications/StandardActions.js create mode 100644 src/notifications/VectorPushRulesDefinitions.js create mode 100644 src/notifications/index.js diff --git a/src/notifications/ContentRules.js b/src/notifications/ContentRules.js new file mode 100644 index 0000000000..25a7bac96e --- /dev/null +++ b/src/notifications/ContentRules.js @@ -0,0 +1,125 @@ +/* +Copyright 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +'use strict'; + +var PushRuleVectorState = require('./PushRuleVectorState'); + +module.exports = { + /** + * Extract the keyword rules from a list of rules, and parse them + * into a form which is useful for Vector's UI. + * + * Returns an object containing: + * rules: the primary list of keyword rules + * vectorState: a PushRuleVectorState indicating whether those rules are + * OFF/ON/LOUD + * externalRules: a list of other keyword rules, with states other than + * vectorState + */ + parseContentRules: function(rulesets) { + // first categorise the keyword rules in terms of their actions + var contentRules = this._categoriseContentRules(rulesets); + + // Decide which content rules to display in Vector UI. + // Vector displays a single global rule for a list of keywords + // whereas Matrix has a push rule per keyword. + // Vector can set the unique rule in ON, LOUD or OFF state. + // Matrix has enabled/disabled plus a combination of (highlight, sound) tweaks. + + // The code below determines which set of user's content push rules can be + // displayed by the vector UI. + // Push rules that does not fit, ie defined by another Matrix client, ends + // in externalRules. + // There is priority in the determination of which set will be the displayed one. + // The set with rules that have LOUD tweaks is the first choice. Then, the ones + // with ON tweaks (no tweaks). + + if (contentRules.loud.length) { + return { + vectorState: PushRuleVectorState.LOUD, + rules: contentRules.loud, + externalRules: [].concat(contentRules.loud_but_disabled, contentRules.on, contentRules.on_but_disabled, contentRules.other), + }; + } + else if (contentRules.loud_but_disabled.length) { + return { + vectorState: PushRuleVectorState.OFF, + rules: contentRules.loud_but_disabled, + externalRules: [].concat(contentRules.on, contentRules.on_but_disabled, contentRules.other), + }; + } + else if (contentRules.on.length) { + return { + vectorState: PushRuleVectorState.ON, + rules: contentRules.on, + externalRules: [].concat(contentRules.on_but_disabled, contentRules.other), + }; + } + else if (contentRules.on_but_disabled.length) { + return { + vectorState: PushRuleVectorState.OFF, + rules: contentRules.on_but_disabled, + externalRules: contentRules.other, + } + } else { + return { + vectorState: PushRuleVectorState.ON, + rules: [], + externalRules: contentRules.other, + } + } + }, + + _categoriseContentRules: function(rulesets) { + var contentRules = {on: [], on_but_disabled:[], loud: [], loud_but_disabled: [], other: []}; + for (var kind in rulesets.global) { + for (var i = 0; i < Object.keys(rulesets.global[kind]).length; ++i) { + var r = rulesets.global[kind][i]; + + // check it's not a default rule + if (r.rule_id[0] === '.' || kind !== 'content') { + continue; + } + + r.kind = kind; // is this needed? not sure + + switch (PushRuleVectorState.contentRuleVectorStateKind(r)) { + case PushRuleVectorState.ON: + if (r.enabled) { + contentRules.on.push(r); + } + else { + contentRules.on_but_disabled.push(r); + } + break; + case PushRuleVectorState.LOUD: + if (r.enabled) { + contentRules.loud.push(r); + } + else { + contentRules.loud_but_disabled.push(r); + } + break; + default: + contentRules.other.push(r); + break; + } + } + } + return contentRules; + }, +}; diff --git a/src/notifications/NotificationUtils.js b/src/notifications/NotificationUtils.js new file mode 100644 index 0000000000..c8aeb46854 --- /dev/null +++ b/src/notifications/NotificationUtils.js @@ -0,0 +1,89 @@ +/* +Copyright 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +'use strict'; + +module.exports = { + // Encodes a dictionary of { + // "notify": true/false, + // "sound": string or undefined, + // "highlight: true/false, + // } + // to a list of push actions. + encodeActions: function(action) { + var notify = action.notify; + var sound = action.sound; + var highlight = action.highlight; + if (notify) { + var actions = ["notify"]; + if (sound) { + actions.push({"set_tweak": "sound", "value": sound}); + } + if (highlight) { + actions.push({"set_tweak": "highlight"}); + } else { + actions.push({"set_tweak": "highlight", "value": false}); + } + return actions; + } else { + return ["dont_notify"]; + } + }, + + // Decode a list of actions to a dictionary of { + // "notify": true/false, + // "sound": string or undefined, + // "highlight: true/false, + // } + // If the actions couldn't be decoded then returns null. + decodeActions: function(actions) { + var notify = false; + var sound = null; + var highlight = false; + + for (var i = 0; i < actions.length; ++i) { + var action = actions[i]; + if (action === "notify") { + notify = true; + } else if (action === "dont_notify") { + notify = false; + } else if (typeof action === 'object') { + if (action.set_tweak === "sound") { + sound = action.value + } else if (action.set_tweak === "highlight") { + highlight = action.value; + } else { + // We don't understand this kind of tweak, so give up. + return null; + } + } else { + // We don't understand this kind of action, so give up. + return null; + } + } + + if (highlight === undefined) { + // If a highlight tweak is missing a value then it defaults to true. + highlight = true; + } + + var result = {notify: notify, highlight: highlight}; + if (sound !== null) { + result.sound = sound; + } + return result; + }, +}; diff --git a/src/notifications/PushRuleVectorState.js b/src/notifications/PushRuleVectorState.js new file mode 100644 index 0000000000..c838aa20ed --- /dev/null +++ b/src/notifications/PushRuleVectorState.js @@ -0,0 +1,94 @@ +/* +Copyright 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +'use strict'; + +var StandardActions = require('./StandardActions'); +var NotificationUtils = require('./NotificationUtils'); + +var states = { + /** The push rule is disabled */ + OFF: "off", + + /** The user will receive push notification for this rule */ + ON: "on", + + /** The user will receive push notification for this rule with sound and + highlight if this is legitimate */ + LOUD: "loud", +}; + + +module.exports = { + /** + * Enum for state of a push rule as defined by the Vector UI. + * @readonly + * @enum {string} + */ + states: states, + + /** + * Convert a PushRuleVectorState to a list of actions + * + * @return [object] list of push-rule actions + */ + actionsFor: function(pushRuleVectorState) { + if (pushRuleVectorState === this.ON) { + return StandardActions.ACTION_NOTIFY; + } + else if (pushRuleVectorState === this.LOUD) { + return StandardActions.ACTION_HIGHLIGHT_DEFAULT_SOUND; + } + }, + + /** + * Convert a pushrule's actions to a PushRuleVectorState. + * + * Determines whether a content rule is in the PushRuleVectorState.ON + * category or in PushRuleVectorState.LOUD, regardless of its enabled + * state. Returns null if it does not match these categories. + */ + contentRuleVectorStateKind: function(rule) { + var decoded = NotificationUtils.decodeActions(rule.actions); + + if (!decoded) { + return null; + } + + // Count tweaks to determine if it is a ON or LOUD rule + var tweaks = 0; + if (decoded.sound) { + tweaks++; + } + if (decoded.highlight) { + tweaks++; + } + var stateKind = null; + switch (tweaks) { + case 0: + stateKind = this.ON; + break; + case 2: + stateKind = this.LOUD; + break; + } + return stateKind; + }, +}; + +for (var k in states) { + module.exports[k] = states[k]; +}; diff --git a/src/notifications/StandardActions.js b/src/notifications/StandardActions.js new file mode 100644 index 0000000000..22a8f1db40 --- /dev/null +++ b/src/notifications/StandardActions.js @@ -0,0 +1,30 @@ +/* +Copyright 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +'use strict'; + +var NotificationUtils = require('./NotificationUtils'); + +var encodeActions = NotificationUtils.encodeActions; + +module.exports = { + ACTION_NOTIFY: encodeActions({notify: true}), + ACTION_NOTIFY_DEFAULT_SOUND: encodeActions({notify: true, sound: "default"}), + ACTION_NOTIFY_RING_SOUND: encodeActions({notify: true, sound: "ring"}), + ACTION_HIGHLIGHT_DEFAULT_SOUND: encodeActions({notify: true, sound: "default", highlight: true}), + ACTION_DONT_NOTIFY: encodeActions({notify: false}), + ACTION_DISABLED: null, +}; diff --git a/src/notifications/VectorPushRulesDefinitions.js b/src/notifications/VectorPushRulesDefinitions.js new file mode 100644 index 0000000000..6f72164265 --- /dev/null +++ b/src/notifications/VectorPushRulesDefinitions.js @@ -0,0 +1,146 @@ +/* +Copyright 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +'use strict'; + +import { _td } from 'matrix-react-sdk/lib/languageHandler'; + +var StandardActions = require('./StandardActions'); +var PushRuleVectorState = require('./PushRuleVectorState'); + +class VectorPushRuleDefinition { + constructor(opts) { + this.kind = opts.kind; + this.description = opts.description; + this.vectorStateToActions = opts.vectorStateToActions; + } + + // Translate the rule actions and its enabled value into vector state + ruleToVectorState(rule) { + var enabled = false; + var actions = null; + if (rule) { + enabled = rule.enabled; + actions = rule.actions; + } + + for (var stateKey in PushRuleVectorState.states) { + var state = PushRuleVectorState.states[stateKey]; + var vectorStateToActions = this.vectorStateToActions[state]; + + if (!vectorStateToActions) { + // No defined actions means that this vector state expects a disabled (or absent) rule + if (!enabled) { + return state; + } + } else { + // The actions must match to the ones expected by vector state + if (enabled && JSON.stringify(rule.actions) === JSON.stringify(vectorStateToActions)) { + return state; + } + } + } + + console.error("Cannot translate rule actions into Vector rule state. Rule: " + + JSON.stringify(rule)); + return undefined; + } +}; + +/** + * The descriptions of rules managed by the Vector UI. + */ +module.exports = { + // Messages containing user's display name + ".m.rule.contains_display_name": new VectorPushRuleDefinition({ + kind: "override", + description: _td("Messages containing my display name"), // passed through _t() translation in src/components/views/settings/Notifications.js + vectorStateToActions: { // The actions for each vector state, or null to disable the rule. + on: StandardActions.ACTION_NOTIFY, + loud: StandardActions.ACTION_HIGHLIGHT_DEFAULT_SOUND, + off: StandardActions.ACTION_DISABLED + } + }), + + // Messages containing user's username (localpart/MXID) + ".m.rule.contains_user_name": new VectorPushRuleDefinition({ + kind: "override", + description: _td("Messages containing my user name"), // passed through _t() translation in src/components/views/settings/Notifications.js + vectorStateToActions: { // The actions for each vector state, or null to disable the rule. + on: StandardActions.ACTION_NOTIFY, + loud: StandardActions.ACTION_HIGHLIGHT_DEFAULT_SOUND, + off: StandardActions.ACTION_DISABLED + } + }), + + // Messages just sent to the user in a 1:1 room + ".m.rule.room_one_to_one": new VectorPushRuleDefinition({ + kind: "underride", + description: _td("Messages in one-to-one chats"), // passed through _t() translation in src/components/views/settings/Notifications.js + vectorStateToActions: { + on: StandardActions.ACTION_NOTIFY, + loud: StandardActions.ACTION_NOTIFY_DEFAULT_SOUND, + off: StandardActions.ACTION_DONT_NOTIFY + } + }), + + // Messages just sent to a group chat room + // 1:1 room messages are catched by the .m.rule.room_one_to_one rule if any defined + // By opposition, all other room messages are from group chat rooms. + ".m.rule.message": new VectorPushRuleDefinition({ + kind: "underride", + description: _td("Messages in group chats"), // passed through _t() translation in src/components/views/settings/Notifications.js + vectorStateToActions: { + on: StandardActions.ACTION_NOTIFY, + loud: StandardActions.ACTION_NOTIFY_DEFAULT_SOUND, + off: StandardActions.ACTION_DONT_NOTIFY + } + }), + + // Invitation for the user + ".m.rule.invite_for_me": new VectorPushRuleDefinition({ + kind: "underride", + description: _td("When I'm invited to a room"), // passed through _t() translation in src/components/views/settings/Notifications.js + vectorStateToActions: { + on: StandardActions.ACTION_NOTIFY, + loud: StandardActions.ACTION_NOTIFY_DEFAULT_SOUND, + off: StandardActions.ACTION_DISABLED + } + }), + + // Incoming call + ".m.rule.call": new VectorPushRuleDefinition({ + kind: "underride", + description: _td("Call invitation"), // passed through _t() translation in src/components/views/settings/Notifications.js + vectorStateToActions: { + on: StandardActions.ACTION_NOTIFY, + loud: StandardActions.ACTION_NOTIFY_RING_SOUND, + off: StandardActions.ACTION_DISABLED + } + }), + + // Notifications from bots + ".m.rule.suppress_notices": new VectorPushRuleDefinition({ + kind: "override", + description: _td("Messages sent by bot"), // passed through _t() translation in src/components/views/settings/Notifications.js + vectorStateToActions: { + // .m.rule.suppress_notices is a "negative" rule, we have to invert its enabled value for vector UI + on: StandardActions.ACTION_DISABLED, + loud: StandardActions.ACTION_NOTIFY_DEFAULT_SOUND, + off: StandardActions.ACTION_DONT_NOTIFY, + } + }), +}; diff --git a/src/notifications/index.js b/src/notifications/index.js new file mode 100644 index 0000000000..8ed77e9d41 --- /dev/null +++ b/src/notifications/index.js @@ -0,0 +1,24 @@ +/* +Copyright 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +'use strict'; + +module.exports = { + NotificationUtils: require('./NotificationUtils'), + PushRuleVectorState: require('./PushRuleVectorState'), + VectorPushRulesDefinitions: require('./VectorPushRulesDefinitions'), + ContentRules: require('./ContentRules'), +}; From 70f380422766d5b510cc5eacb7f786a471c9fbd2 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Wed, 11 Apr 2018 23:58:46 +0100 Subject: [PATCH 0756/1160] move room directory logic over from riot-web --- src/utils/DirectoryUtils.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/utils/DirectoryUtils.js diff --git a/src/utils/DirectoryUtils.js b/src/utils/DirectoryUtils.js new file mode 100644 index 0000000000..72e44681b6 --- /dev/null +++ b/src/utils/DirectoryUtils.js @@ -0,0 +1,23 @@ +// Find a protocol 'instance' with a given instance_id +// in the supplied protocols dict +export function instanceForInstanceId(protocols, instance_id) { + if (!instance_id) return null; + for (const proto of Object.keys(protocols)) { + if (!protocols[proto].instances && protocols[proto].instances instanceof Array) continue; + for (const instance of protocols[proto].instances) { + if (instance.instance_id == instance_id) return instance; + } + } +} + +// given an instance_id, return the name of the protocol for +// that instance ID in the supplied protocols dict +export function protocolNameForInstanceId(protocols, instance_id) { + if (!instance_id) return null; + for (const proto of Object.keys(protocols)) { + if (!protocols[proto].instances && protocols[proto].instances instanceof Array) continue; + for (const instance of protocols[proto].instances) { + if (instance.instance_id == instance_id) return proto; + } + } +} From 79d3cca6e9a2769239220d6eb057b176535fc4c3 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Thu, 12 Apr 2018 00:23:35 +0100 Subject: [PATCH 0757/1160] move components' CSS to be in the same repo as their JS --- res/css/_base.scss | 182 ++++++ res/css/_common.scss | 361 ++++++++++++ res/css/_components.scss | 111 ++++ res/css/_fonts.scss | 67 +++ res/css/rethemendex.sh | 13 + res/css/structures/_CompatibilityPage.scss | 19 + res/css/structures/_ContextualMenu.scss | 160 ++++++ res/css/structures/_CreateRoom.scss | 37 ++ res/css/structures/_FilePanel.scss | 114 ++++ res/css/structures/_GroupView.scss | 349 ++++++++++++ res/css/structures/_HomePage.scss | 35 ++ res/css/structures/_LeftPanel.scss | 129 +++++ res/css/structures/_LoginBox.scss | 47 ++ res/css/structures/_MatrixChat.scss | 104 ++++ res/css/structures/_MyGroups.scss | 151 +++++ res/css/structures/_NotificationPanel.scss | 100 ++++ res/css/structures/_RightPanel.scss | 133 +++++ res/css/structures/_RoomDirectory.scss | 131 +++++ res/css/structures/_RoomStatusBar.scss | 181 ++++++ res/css/structures/_RoomSubList.scss | 244 ++++++++ res/css/structures/_RoomView.scss | 272 +++++++++ res/css/structures/_SearchBox.scss | 68 +++ res/css/structures/_TagPanel.scss | 126 +++++ res/css/structures/_UploadBar.scss | 61 ++ res/css/structures/_UserSettings.scss | 253 +++++++++ res/css/structures/_ViewSource.scss | 23 + res/css/structures/login/_Login.scss | 284 ++++++++++ res/css/views/avatars/_BaseAvatar.scss | 35 ++ .../views/avatars/_MemberPresenceAvatar.scss | 43 ++ .../context_menus/_MessageContextMenu.scss | 25 + .../_PresenceContextMenuOption.scss | 42 ++ .../context_menus/_RoomTileContextMenu.scss | 114 ++++ .../context_menus/_TagTileContextMenu.scss | 44 ++ res/css/views/dialogs/_BugReportDialog.scss | 52 ++ res/css/views/dialogs/_ChangelogDialog.scss | 24 + .../dialogs/_ChatCreateOrReuseChatDialog.scss | 41 ++ res/css/views/dialogs/_ChatInviteDialog.scss | 77 +++ .../dialogs/_ConfirmUserActionDialog.scss | 53 ++ res/css/views/dialogs/_CreateGroupDialog.scss | 62 ++ res/css/views/dialogs/_CreateRoomDialog.scss | 33 ++ res/css/views/dialogs/_DevtoolsDialog.scss | 166 ++++++ .../views/dialogs/_EncryptedEventDialog.scss | 27 + .../views/dialogs/_GroupAddressPicker.scss | 25 + res/css/views/dialogs/_QuestionDialog.scss | 18 + res/css/views/dialogs/_SetEmailDialog.scss | 36 ++ res/css/views/dialogs/_SetMxIdDialog.scss | 50 ++ res/css/views/dialogs/_SetPasswordDialog.scss | 35 ++ .../views/dialogs/_UnknownDeviceDialog.scss | 54 ++ res/css/views/directory/_NetworkDropdown.scss | 84 +++ res/css/views/elements/_AccessibleButton.scss | 24 + res/css/views/elements/_AddressSelector.scss | 45 ++ res/css/views/elements/_AddressTile.scss | 138 +++++ .../views/elements/_DirectorySearchBox.scss | 70 +++ res/css/views/elements/_Dropdown.scss | 131 +++++ res/css/views/elements/_EditableItemList.scss | 62 ++ res/css/views/elements/_ImageView.scss | 134 +++++ res/css/views/elements/_InlineSpinner.scss | 24 + .../elements/_MemberEventListSummary.scss | 71 +++ res/css/views/elements/_ProgressBar.scss | 25 + res/css/views/elements/_Quote.scss | 26 + res/css/views/elements/_RichText.scss | 75 +++ res/css/views/elements/_RoleButton.scss | 33 ++ res/css/views/elements/_Spinner.scss | 28 + res/css/views/elements/_SyntaxHighlight.scss | 21 + res/css/views/elements/_ToolTipButton.scss | 51 ++ res/css/views/globals/_MatrixToolbar.scss | 62 ++ .../views/groups/_GroupPublicityToggle.scss | 42 ++ res/css/views/groups/_GroupRoomList.scss | 21 + res/css/views/groups/_GroupUserSettings.scss | 23 + .../_InteractiveAuthEntryComponents.scss | 42 ++ res/css/views/login/_ServerConfig.scss | 36 ++ res/css/views/messages/_DateSeparator.scss | 25 + res/css/views/messages/_MEmoteBody.scss | 23 + res/css/views/messages/_MFileBody.scss | 47 ++ res/css/views/messages/_MImageBody.scss | 20 + res/css/views/messages/_MNoticeBody.scss | 20 + res/css/views/messages/_MStickerBody.scss | 46 ++ res/css/views/messages/_MTextBody.scss | 24 + res/css/views/messages/_MessageTimestamp.scss | 18 + res/css/views/messages/_RoomAvatarEvent.scss | 26 + res/css/views/messages/_SenderProfile.scss | 15 + res/css/views/messages/_TextualEvent.scss | 20 + res/css/views/messages/_UnknownBody.scss | 16 + res/css/views/rooms/_AppsDrawer.scss | 271 +++++++++ res/css/views/rooms/_Autocomplete.scss | 93 +++ res/css/views/rooms/_EntityTile.scss | 114 ++++ res/css/views/rooms/_EventTile.scss | 530 ++++++++++++++++++ res/css/views/rooms/_LinkPreviewWidget.scss | 69 +++ res/css/views/rooms/_MemberDeviceInfo.scss | 74 +++ res/css/views/rooms/_MemberInfo.scss | 112 ++++ res/css/views/rooms/_MemberList.scss | 116 ++++ res/css/views/rooms/_MessageComposer.scss | 246 ++++++++ res/css/views/rooms/_PinnedEventTile.scss | 67 +++ res/css/views/rooms/_PinnedEventsPanel.scss | 37 ++ res/css/views/rooms/_PresenceLabel.scss | 20 + res/css/views/rooms/_QuotePreview.scss | 36 ++ res/css/views/rooms/_RoomDropTarget.scss | 55 ++ res/css/views/rooms/_RoomHeader.scss | 245 ++++++++ res/css/views/rooms/_RoomList.scss | 67 +++ res/css/views/rooms/_RoomPreviewBar.scss | 58 ++ res/css/views/rooms/_RoomSettings.scss | 247 ++++++++ res/css/views/rooms/_RoomTile.scss | 190 +++++++ res/css/views/rooms/_RoomTooltip.scss | 54 ++ res/css/views/rooms/_SearchBar.scss | 83 +++ .../views/rooms/_SearchableEntityList.scss | 77 +++ res/css/views/rooms/_Stickers.scss | 35 ++ .../views/rooms/_TopUnreadMessagesBar.scss | 53 ++ res/css/views/settings/_DevicesPanel.scss | 51 ++ .../views/settings/_IntegrationsManager.scss | 31 + res/css/views/settings/_Notifications.scss | 70 +++ res/css/views/voip/_CallView.scss | 25 + res/css/views/voip/_IncomingCallbox.scss | 69 +++ res/css/views/voip/_VideoView.scss | 49 ++ 113 files changed, 9623 insertions(+) create mode 100644 res/css/_base.scss create mode 100644 res/css/_common.scss create mode 100644 res/css/_components.scss create mode 100644 res/css/_fonts.scss create mode 100755 res/css/rethemendex.sh create mode 100644 res/css/structures/_CompatibilityPage.scss create mode 100644 res/css/structures/_ContextualMenu.scss create mode 100644 res/css/structures/_CreateRoom.scss create mode 100644 res/css/structures/_FilePanel.scss create mode 100644 res/css/structures/_GroupView.scss create mode 100644 res/css/structures/_HomePage.scss create mode 100644 res/css/structures/_LeftPanel.scss create mode 100644 res/css/structures/_LoginBox.scss create mode 100644 res/css/structures/_MatrixChat.scss create mode 100644 res/css/structures/_MyGroups.scss create mode 100644 res/css/structures/_NotificationPanel.scss create mode 100644 res/css/structures/_RightPanel.scss create mode 100644 res/css/structures/_RoomDirectory.scss create mode 100644 res/css/structures/_RoomStatusBar.scss create mode 100644 res/css/structures/_RoomSubList.scss create mode 100644 res/css/structures/_RoomView.scss create mode 100644 res/css/structures/_SearchBox.scss create mode 100644 res/css/structures/_TagPanel.scss create mode 100644 res/css/structures/_UploadBar.scss create mode 100644 res/css/structures/_UserSettings.scss create mode 100644 res/css/structures/_ViewSource.scss create mode 100644 res/css/structures/login/_Login.scss create mode 100644 res/css/views/avatars/_BaseAvatar.scss create mode 100644 res/css/views/avatars/_MemberPresenceAvatar.scss create mode 100644 res/css/views/context_menus/_MessageContextMenu.scss create mode 100644 res/css/views/context_menus/_PresenceContextMenuOption.scss create mode 100644 res/css/views/context_menus/_RoomTileContextMenu.scss create mode 100644 res/css/views/context_menus/_TagTileContextMenu.scss create mode 100644 res/css/views/dialogs/_BugReportDialog.scss create mode 100644 res/css/views/dialogs/_ChangelogDialog.scss create mode 100644 res/css/views/dialogs/_ChatCreateOrReuseChatDialog.scss create mode 100644 res/css/views/dialogs/_ChatInviteDialog.scss create mode 100644 res/css/views/dialogs/_ConfirmUserActionDialog.scss create mode 100644 res/css/views/dialogs/_CreateGroupDialog.scss create mode 100644 res/css/views/dialogs/_CreateRoomDialog.scss create mode 100644 res/css/views/dialogs/_DevtoolsDialog.scss create mode 100644 res/css/views/dialogs/_EncryptedEventDialog.scss create mode 100644 res/css/views/dialogs/_GroupAddressPicker.scss create mode 100644 res/css/views/dialogs/_QuestionDialog.scss create mode 100644 res/css/views/dialogs/_SetEmailDialog.scss create mode 100644 res/css/views/dialogs/_SetMxIdDialog.scss create mode 100644 res/css/views/dialogs/_SetPasswordDialog.scss create mode 100644 res/css/views/dialogs/_UnknownDeviceDialog.scss create mode 100644 res/css/views/directory/_NetworkDropdown.scss create mode 100644 res/css/views/elements/_AccessibleButton.scss create mode 100644 res/css/views/elements/_AddressSelector.scss create mode 100644 res/css/views/elements/_AddressTile.scss create mode 100644 res/css/views/elements/_DirectorySearchBox.scss create mode 100644 res/css/views/elements/_Dropdown.scss create mode 100644 res/css/views/elements/_EditableItemList.scss create mode 100644 res/css/views/elements/_ImageView.scss create mode 100644 res/css/views/elements/_InlineSpinner.scss create mode 100644 res/css/views/elements/_MemberEventListSummary.scss create mode 100644 res/css/views/elements/_ProgressBar.scss create mode 100644 res/css/views/elements/_Quote.scss create mode 100644 res/css/views/elements/_RichText.scss create mode 100644 res/css/views/elements/_RoleButton.scss create mode 100644 res/css/views/elements/_Spinner.scss create mode 100644 res/css/views/elements/_SyntaxHighlight.scss create mode 100644 res/css/views/elements/_ToolTipButton.scss create mode 100644 res/css/views/globals/_MatrixToolbar.scss create mode 100644 res/css/views/groups/_GroupPublicityToggle.scss create mode 100644 res/css/views/groups/_GroupRoomList.scss create mode 100644 res/css/views/groups/_GroupUserSettings.scss create mode 100644 res/css/views/login/_InteractiveAuthEntryComponents.scss create mode 100644 res/css/views/login/_ServerConfig.scss create mode 100644 res/css/views/messages/_DateSeparator.scss create mode 100644 res/css/views/messages/_MEmoteBody.scss create mode 100644 res/css/views/messages/_MFileBody.scss create mode 100644 res/css/views/messages/_MImageBody.scss create mode 100644 res/css/views/messages/_MNoticeBody.scss create mode 100644 res/css/views/messages/_MStickerBody.scss create mode 100644 res/css/views/messages/_MTextBody.scss create mode 100644 res/css/views/messages/_MessageTimestamp.scss create mode 100644 res/css/views/messages/_RoomAvatarEvent.scss create mode 100644 res/css/views/messages/_SenderProfile.scss create mode 100644 res/css/views/messages/_TextualEvent.scss create mode 100644 res/css/views/messages/_UnknownBody.scss create mode 100644 res/css/views/rooms/_AppsDrawer.scss create mode 100644 res/css/views/rooms/_Autocomplete.scss create mode 100644 res/css/views/rooms/_EntityTile.scss create mode 100644 res/css/views/rooms/_EventTile.scss create mode 100644 res/css/views/rooms/_LinkPreviewWidget.scss create mode 100644 res/css/views/rooms/_MemberDeviceInfo.scss create mode 100644 res/css/views/rooms/_MemberInfo.scss create mode 100644 res/css/views/rooms/_MemberList.scss create mode 100644 res/css/views/rooms/_MessageComposer.scss create mode 100644 res/css/views/rooms/_PinnedEventTile.scss create mode 100644 res/css/views/rooms/_PinnedEventsPanel.scss create mode 100644 res/css/views/rooms/_PresenceLabel.scss create mode 100644 res/css/views/rooms/_QuotePreview.scss create mode 100644 res/css/views/rooms/_RoomDropTarget.scss create mode 100644 res/css/views/rooms/_RoomHeader.scss create mode 100644 res/css/views/rooms/_RoomList.scss create mode 100644 res/css/views/rooms/_RoomPreviewBar.scss create mode 100644 res/css/views/rooms/_RoomSettings.scss create mode 100644 res/css/views/rooms/_RoomTile.scss create mode 100644 res/css/views/rooms/_RoomTooltip.scss create mode 100644 res/css/views/rooms/_SearchBar.scss create mode 100644 res/css/views/rooms/_SearchableEntityList.scss create mode 100644 res/css/views/rooms/_Stickers.scss create mode 100644 res/css/views/rooms/_TopUnreadMessagesBar.scss create mode 100644 res/css/views/settings/_DevicesPanel.scss create mode 100644 res/css/views/settings/_IntegrationsManager.scss create mode 100644 res/css/views/settings/_Notifications.scss create mode 100644 res/css/views/voip/_CallView.scss create mode 100644 res/css/views/voip/_IncomingCallbox.scss create mode 100644 res/css/views/voip/_VideoView.scss diff --git a/res/css/_base.scss b/res/css/_base.scss new file mode 100644 index 0000000000..51d2f70f78 --- /dev/null +++ b/res/css/_base.scss @@ -0,0 +1,182 @@ +/* Open Sans lacks combining diacritics, so these will fall through + to the next font. Helevetica's diacritics however do not combine + nicely with Open Sans (on OSX, at least) and result in a huge + horizontal mess. Arial empirically gets it right, hence prioritising + Arial here. */ +$font-family: 'Open Sans', Arial, Helvetica, Sans-Serif; + +// typical text (dark-on-white in light skin) +$primary-fg-color: #454545; +$primary-bg-color: #ffffff; + +// used for dialog box text +$light-fg-color: #747474; + +// used for focusing form controls +$focus-bg-color: #dddddd; + +// button UI (white-on-green in light skin) +$accent-fg-color: #ffffff; +$accent-color: #76CFA6; + +$selection-fg-color: $primary-bg-color; + +$focus-brightness: 125%; + +// red warning colour +$warning-color: #ff0064; +$mention-user-pill-bg-color: #ff0064; +$other-user-pill-bg-color: rgba(0, 0, 0, 0.1); + +// pinned events indicator +$pinned-unread-color: #ff0064; // $warning-color +$pinned-color: #888; + +// informational plinth +$info-plinth-bg-color: #f7f7f7; +$info-plinth-fg-color: #888; + +$preview-bar-bg-color: #f7f7f7; + +// left-panel style muted accent color +$secondary-accent-color: #eaf5f0; +$tertiary-accent-color: #d3efe1; + +// used by RoomDirectory permissions +$plinth-bg-color: $secondary-accent-color; + +// used by RoomDropTarget +$droptarget-bg-color: rgba(255,255,255,0.5); + +// used by AddressSelector +$selected-color: $secondary-accent-color; + +// selected for hoverover & selected event tiles +$event-selected-color: #f7f7f7; + +// used for the hairline dividers in RoomView +$primary-hairline-color: #e5e5e5; + +// used for the border of input text fields +$input-border-color: #f0f0f0; + +// apart from login forms, which have stronger border +$strong-input-border-color: #c7c7c7; + +// used for UserSettings EditableText +$input-underline-color: rgba(151, 151, 151, 0.5); +$input-fg-color: rgba(74, 74, 74, 0.9); + +// context menus +$menu-border-color: rgba(187, 187, 187, 0.5); +$menu-bg-color: #f6f6f6; + +$avatar-initial-color: #ffffff; +$avatar-bg-color: #ffffff; + +$h3-color: #3d3b39; + +$dialog-background-bg-color: #e9e9e9; +$lightbox-background-bg-color: #000; + +$greyed-fg-color: #888; + +$neutral-badge-color: #dbdbdb; + +$preview-widget-bar-color: #ddd; +$preview-widget-fg-color: $greyed-fg-color; + +$blockquote-bar-color: #ddd; +$blockquote-fg-color: #777; + +$settings-grey-fg-color: #a2a2a2; + +$voip-decline-color: #f48080; +$voip-accept-color: #80f480; + +$rte-bg-color: #e9e9e9; +$rte-code-bg-color: rgba(0, 0, 0, 0.04); +$rte-room-pill-color: #aaa; + +// ******************** + +$roomtile-name-color: rgba(69, 69, 69, 0.8); +$roomtile-selected-bg-color: rgba(255, 255, 255, 0.8); +$roomtile-focused-bg-color: rgba(255, 255, 255, 0.9); + +$roomtile-transparent-focused-color: rgba(0, 0, 0, 0.1); + +$roomsublist-background: rgba(0, 0, 0, 0.05); +$roomsublist-label-fg-color: $h3-color; +$roomsublist-label-bg-color: $tertiary-accent-color; +$roomsublist-chevron-color: $accent-color; + +$panel-divider-color: rgba(118, 207, 166, 0.2); + +// ******************** + +$widget-menu-bar-bg-color: $tertiary-accent-color; + +// ******************** + +// event tile lifecycle +$event-encrypting-color: #abddbc; +$event-sending-color: #ddd; +$event-notsent-color: #f44; + +// event redaction +$event-redacted-fg-color: #e2e2e2; +$event-redacted-border-color: #cccccc; + +// event timestamp +$event-timestamp-color: #acacac; + +$edit-button-url: "../../img/icon_context_message.svg"; +$copy-button-url: "../../img/icon_copy_message.svg"; + +// e2e +$e2e-verified-color: #76cfa5; // N.B. *NOT* the same as $accent-color +$e2e-unverified-color: #e8bf37; +$e2e-warning-color: #ba6363; + +// presence +$presence-online: #60de00; +$presence-unavailable: #deb800; +$presence-offline: #b7b7b7; + +/*** ImageView ***/ +$lightbox-bg-color: #454545; +$lightbox-fg-color: #ffffff; +$lightbox-border-color: #ffffff; + +// unused? +$progressbar-color: #000; + +// ***** Mixins! ***** + +@define-mixin mx_DialogButton { + /* align images in buttons (eg spinners) */ + vertical-align: middle; + border: 0px; + border-radius: 36px; + font-family: $font-family; + font-size: 14px; + color: $accent-fg-color; + background-color: $accent-color; + width: auto; + padding: 7px; + padding-left: 1.5em; + padding-right: 1.5em; + cursor: pointer; + display: inline-block; + outline: none; +} + +@define-mixin mx_DialogButton_hover { +} + +@define-mixin mx_DialogButton_small { + @mixin mx_DialogButton; + font-size: 15px; + padding: 0px 1.5em 0px 1.5em; +} diff --git a/res/css/_common.scss b/res/css/_common.scss new file mode 100644 index 0000000000..e81c228430 --- /dev/null +++ b/res/css/_common.scss @@ -0,0 +1,361 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd +Copyright 2017 Vector Creations Ltd +Copyright 2017 New Vector Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +html { + /* hack to stop overscroll bounce on OSX and iOS. + N.B. Breaks things when we have legitimate horizontal overscroll */ + height: 100%; + overflow: hidden; +} + +body { + font-family: $font-family; + font-size: 15px; + background-color: $primary-bg-color; + color: $primary-fg-color; + border: 0px; + margin: 0px; + /* This should render the fonts the same accross browsers */ + -webkit-font-smoothing: subpixel-antialiased; +} + +div.error, div.warning { + color: $warning-color; +} + +h2 { + color: $primary-fg-color; + font-weight: 400; + font-size: 18px; + margin-top: 16px; + margin-bottom: 16px; +} + +a:hover, +a:link, +a:visited { + color: $accent-color; +} + +input[type=text], input[type=password], textarea { + background-color: transparent; + color: $primary-fg-color; +} + +input[type=text].error, input[type=password].error { + border: 1px solid $warning-color; +} + +input[type=text]:focus, input[type=password]:focus, textarea:focus { + border: 1px solid $accent-color; + outline: none; + box-shadow: none; +} + +/* Required by Firefox */ +textarea { + font-family: $font-family; +} + +/* Prevent ugly dotted highlight around selected elements in Firefox */ +::-moz-focus-inner { + border: 0; +} + +/* applied to side-panels and messagepanel when in RoomSettings */ +.mx_fadable { + opacity: 1; + transition: opacity 0.2s ease-in-out; +} + +.mx_fadable.mx_fadable_faded { + opacity: 0.3; + pointer-events: none; +} + +/* XXX: critical hack to GeminiScrollbar to allow them to work in FF 42 and Chrome 48. + Stop the scrollbar view from pushing out the container's overall sizing, which causes + flexbox to adapt to the new size and cause the view to keep growing. + */ +.gm-scrollbar-container .gm-scroll-view { + position: absolute; +} + +/* Expand thumbs on hoverover */ +.gm-scrollbar { + border-radius: 5px ! important; +} +.gm-scrollbar.-vertical { + width: 6px; + transition: width 120ms ease-out ! important; +} +.gm-scrollbar.-vertical:hover, +.gm-scrollbar.-vertical:active { + width: 8px; + transition: width 120ms ease-out ! important; +} +.gm-scrollbar.-horizontal { + height: 6px; + transition: height 120ms ease-out ! important; +} +.gm-scrollbar.-horizontal:hover, +.gm-scrollbar.-horizontal:active { + height: 8px; + transition: height 120ms ease-out ! important; +} + +// These are magic constants which are excluded from tinting, to let themes +// (which only have CSS, unlike skins) tell the app what their non-tinted +// colourscheme is by inspecting the stylesheet DOM. +// +// They are not used for layout!! +#mx_theme_accentColor { + color: $accent-color; +} + +#mx_theme_secondaryAccentColor { + color: $secondary-accent-color; +} + +#mx_theme_tertiaryAccentColor { + color: $roomsublist-label-bg-color; +} + +.mx_Dialog_wrapper { + position: fixed; + z-index: 4000; + top: 0; + left: 0; + width: 100%; + height: 100%; + + display: flex; + align-items: center; + justify-content: center; +} + +/* Spinner Dialog overide */ +.mx_Dialog_wrapper.mx_Dialog_spinner .mx_Dialog { + width: auto; + border-radius: 8px; + padding: 0px; + box-shadow: none; +} + +/* View Source Dialog overide */ +.mx_Dialog_wrapper.mx_Dialog_viewsource .mx_Dialog { + padding-left: 10px; + padding-right: 10px; +} + +.mx_Dialog { + background-color: $primary-bg-color; + color: $light-fg-color; + z-index: 4010; + font-weight: 300; + font-size: 15px; + position: relative; + padding-left: 58px; + padding-bottom: 36px; + width: 60%; + max-width: 704px; + box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.2); + max-height: 80%; + overflow-y: auto; +} + +.mx_Dialog_background { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: $dialog-background-bg-color; + opacity: 0.8; +} + +.mx_Dialog_lightbox .mx_Dialog_background { + opacity: 0.85; + background-color: $lightbox-background-bg-color; +} + +.mx_Dialog_lightbox .mx_Dialog { + border-radius: 0px; + background-color: transparent; + width: 100%; + height: 100%; + max-width: 100%; + max-height: 100%; + pointer-events: none; +} + +.mx_Dialog_cancelButton { + position: absolute; + right: 11px; + top: 13px; + cursor: pointer; +} + +.mx_Dialog_cancelButton object { + pointer-events: none; +} + +.mx_Dialog_content { + margin: 24px 58px 68px 0; + font-size: 14px; + color: $primary-fg-color; + word-wrap: break-word; +} + +.mx_Dialog button, .mx_Dialog input[type="submit"] { + @mixin mx_DialogButton; + margin-left: 0px; + margin-right: 8px; + + // flip colours for the secondary ones + font-weight: 600; + border: 1px solid $accent-color ! important; + color: $accent-color; + background-color: $accent-fg-color; +} + +.mx_Dialog button:hover, .mx_Dialog input[type="submit"]:hover { + @mixin mx_DialogButton_hover; +} + +.mx_Dialog button:focus, .mx_Dialog input[type="submit"]:focus { + filter: brightness($focus-brightness); +} + +.mx_Dialog button.mx_Dialog_primary, .mx_Dialog input[type="submit"].mx_Dialog_primary { + color: $accent-fg-color; + background-color: $accent-color; +} + +.mx_Dialog button.danger, .mx_Dialog input[type="submit"].danger { + background-color: $warning-color; + border: solid 1px $warning-color; +} + +.mx_Dialog button:disabled, .mx_Dialog input[type="submit"]:disabled { + background-color: $light-fg-color; + border: solid 1px $light-fg-color; + opacity: 0.7; +} + +.mx_Dialog_title { + min-height: 16px; + padding-top: 40px; + font-weight: bold; + font-size: 22px; + line-height: 1.4; + color: $primary-fg-color; +} + +.mx_Dialog_title.danger { + color: $warning-color; +} + +.mx_TextInputDialog_label { + text-align: left; + padding-bottom: 12px; +} + +.mx_TextInputDialog_input { + font-size: 15px; + border-radius: 3px; + border: 1px solid $input-border-color; + padding: 9px; + color: $primary-fg-color; + background-color: $primary-bg-color; +} + +.mx_emojione { + height: 1em; + vertical-align: middle; +} + +::-moz-selection { + background-color: $accent-color; + color: $selection-fg-color; +} + +::selection { + background-color: $accent-color; + color: $selection-fg-color; +} + +.mx_textButton { + @mixin mx_DialogButton_small; +} + +.mx_textButton:hover { + @mixin mx_DialogButton_hover; +} + +.mx_button_row { + margin-top: 69px; +} + +.mx_Beta { + color: red; + margin-right: 10px; + position: relative; + top: -3px; + background-color: white; + padding: 0 4px; + border-radius: 3px; + border: 1px solid darkred; + cursor: help; + transition-duration: 200ms; + font-size: smaller; + filter: opacity(0.5); +} + +.mx_Beta:hover { + color: white; + border: 1px solid gray; + background-color: darkred; +} + +.mx_TintableSvgButton { + position: relative; + display: flex; + flex-direction: row; + justify-content: center; + align-content: center; +} + +.mx_TintableSvgButton object { + margin: 0; + padding: 0; + width: 100%; + height: 100%; + max-width: 100%; + max-height: 100%; +} + +.mx_TintableSvgButton span { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + opacity: 0; + cursor: pointer; +} diff --git a/res/css/_components.scss b/res/css/_components.scss new file mode 100644 index 0000000000..0bcc48c3b8 --- /dev/null +++ b/res/css/_components.scss @@ -0,0 +1,111 @@ +// autogenerated by rethemendex.sh +@import "./_common.scss"; +@import "./matrix-react-sdk/structures/_ContextualMenu.scss"; +@import "./matrix-react-sdk/structures/_CreateRoom.scss"; +@import "./matrix-react-sdk/structures/_FilePanel.scss"; +@import "./matrix-react-sdk/structures/_GroupView.scss"; +@import "./matrix-react-sdk/structures/_LoginBox.scss"; +@import "./matrix-react-sdk/structures/_MatrixChat.scss"; +@import "./matrix-react-sdk/structures/_MyGroups.scss"; +@import "./matrix-react-sdk/structures/_NotificationPanel.scss"; +@import "./matrix-react-sdk/structures/_RoomStatusBar.scss"; +@import "./matrix-react-sdk/structures/_RoomView.scss"; +@import "./matrix-react-sdk/structures/_SearchBox.scss"; +@import "./matrix-react-sdk/structures/_TagPanel.scss"; +@import "./matrix-react-sdk/structures/_UploadBar.scss"; +@import "./matrix-react-sdk/structures/_UserSettings.scss"; +@import "./matrix-react-sdk/structures/login/_Login.scss"; +@import "./matrix-react-sdk/views/avatars/_BaseAvatar.scss"; +@import "./matrix-react-sdk/views/avatars/_MemberPresenceAvatar.scss"; +@import "./matrix-react-sdk/views/dialogs/_BugReportDialog.scss"; +@import "./matrix-react-sdk/views/dialogs/_ChatCreateOrReuseChatDialog.scss"; +@import "./matrix-react-sdk/views/dialogs/_ChatInviteDialog.scss"; +@import "./matrix-react-sdk/views/dialogs/_ConfirmUserActionDialog.scss"; +@import "./matrix-react-sdk/views/dialogs/_CreateGroupDialog.scss"; +@import "./matrix-react-sdk/views/dialogs/_CreateRoomDialog.scss"; +@import "./matrix-react-sdk/views/dialogs/_EncryptedEventDialog.scss"; +@import "./matrix-react-sdk/views/dialogs/_GroupAddressPicker.scss"; +@import "./matrix-react-sdk/views/dialogs/_QuestionDialog.scss"; +@import "./matrix-react-sdk/views/dialogs/_SetMxIdDialog.scss"; +@import "./matrix-react-sdk/views/dialogs/_UnknownDeviceDialog.scss"; +@import "./matrix-react-sdk/views/elements/_AccessibleButton.scss"; +@import "./matrix-react-sdk/views/elements/_AddressSelector.scss"; +@import "./matrix-react-sdk/views/elements/_AddressTile.scss"; +@import "./matrix-react-sdk/views/elements/_DirectorySearchBox.scss"; +@import "./matrix-react-sdk/views/elements/_Dropdown.scss"; +@import "./matrix-react-sdk/views/elements/_EditableItemList.scss"; +@import "./matrix-react-sdk/views/elements/_MemberEventListSummary.scss"; +@import "./matrix-react-sdk/views/elements/_ProgressBar.scss"; +@import "./matrix-react-sdk/views/elements/_Quote.scss"; +@import "./matrix-react-sdk/views/elements/_RichText.scss"; +@import "./matrix-react-sdk/views/elements/_RoleButton.scss"; +@import "./matrix-react-sdk/views/elements/_ToolTipButton.scss"; +@import "./matrix-react-sdk/views/groups/_GroupPublicityToggle.scss"; +@import "./matrix-react-sdk/views/groups/_GroupRoomList.scss"; +@import "./matrix-react-sdk/views/groups/_GroupUserSettings.scss"; +@import "./matrix-react-sdk/views/login/_InteractiveAuthEntryComponents.scss"; +@import "./matrix-react-sdk/views/login/_ServerConfig.scss"; +@import "./matrix-react-sdk/views/messages/_MEmoteBody.scss"; +@import "./matrix-react-sdk/views/messages/_MFileBody.scss"; +@import "./matrix-react-sdk/views/messages/_MImageBody.scss"; +@import "./matrix-react-sdk/views/messages/_MStickerBody.scss"; +@import "./matrix-react-sdk/views/messages/_MNoticeBody.scss"; +@import "./matrix-react-sdk/views/messages/_MTextBody.scss"; +@import "./matrix-react-sdk/views/messages/_RoomAvatarEvent.scss"; +@import "./matrix-react-sdk/views/messages/_TextualEvent.scss"; +@import "./matrix-react-sdk/views/messages/_UnknownBody.scss"; +@import "./matrix-react-sdk/views/rooms/_AppsDrawer.scss"; +@import "./matrix-react-sdk/views/rooms/_Autocomplete.scss"; +@import "./matrix-react-sdk/views/rooms/_EntityTile.scss"; +@import "./matrix-react-sdk/views/rooms/_EventTile.scss"; +@import "./matrix-react-sdk/views/rooms/_LinkPreviewWidget.scss"; +@import "./matrix-react-sdk/views/rooms/_MemberDeviceInfo.scss"; +@import "./matrix-react-sdk/views/rooms/_MemberInfo.scss"; +@import "./matrix-react-sdk/views/rooms/_MemberList.scss"; +@import "./matrix-react-sdk/views/rooms/_MessageComposer.scss"; +@import "./matrix-react-sdk/views/rooms/_Stickers.scss"; +@import "./matrix-react-sdk/views/rooms/_PinnedEventTile.scss"; +@import "./matrix-react-sdk/views/rooms/_PinnedEventsPanel.scss"; +@import "./matrix-react-sdk/views/rooms/_PresenceLabel.scss"; +@import "./matrix-react-sdk/views/rooms/_QuotePreview.scss"; +@import "./matrix-react-sdk/views/rooms/_RoomHeader.scss"; +@import "./matrix-react-sdk/views/rooms/_RoomList.scss"; +@import "./matrix-react-sdk/views/rooms/_RoomPreviewBar.scss"; +@import "./matrix-react-sdk/views/rooms/_RoomSettings.scss"; +@import "./matrix-react-sdk/views/rooms/_RoomTile.scss"; +@import "./matrix-react-sdk/views/rooms/_SearchableEntityList.scss"; +@import "./matrix-react-sdk/views/rooms/_TopUnreadMessagesBar.scss"; +@import "./matrix-react-sdk/views/settings/_DevicesPanel.scss"; +@import "./matrix-react-sdk/views/settings/_IntegrationsManager.scss"; +@import "./matrix-react-sdk/views/voip/_CallView.scss"; +@import "./matrix-react-sdk/views/voip/_IncomingCallbox.scss"; +@import "./matrix-react-sdk/views/voip/_VideoView.scss"; +@import "./vector-web/_fonts.scss"; +@import "./vector-web/structures/_CompatibilityPage.scss"; +@import "./vector-web/structures/_HomePage.scss"; +@import "./vector-web/structures/_LeftPanel.scss"; +@import "./vector-web/structures/_RightPanel.scss"; +@import "./vector-web/structures/_RoomDirectory.scss"; +@import "./vector-web/structures/_RoomSubList.scss"; +@import "./vector-web/structures/_ViewSource.scss"; +@import "./vector-web/views/context_menus/_MessageContextMenu.scss"; +@import "./vector-web/views/context_menus/_PresenceContextMenuOption.scss"; +@import "./vector-web/views/context_menus/_RoomTileContextMenu.scss"; +@import "./vector-web/views/context_menus/_TagTileContextMenu.scss"; +@import "./vector-web/views/dialogs/_ChangelogDialog.scss"; +@import "./vector-web/views/dialogs/_DevtoolsDialog.scss"; +@import "./vector-web/views/dialogs/_SetEmailDialog.scss"; +@import "./vector-web/views/dialogs/_SetPasswordDialog.scss"; +@import "./vector-web/views/directory/_NetworkDropdown.scss"; +@import "./vector-web/views/elements/_ImageView.scss"; +@import "./vector-web/views/elements/_InlineSpinner.scss"; +@import "./vector-web/views/elements/_Spinner.scss"; +@import "./vector-web/views/elements/_SyntaxHighlight.scss"; +@import "./vector-web/views/globals/_MatrixToolbar.scss"; +@import "./vector-web/views/messages/_DateSeparator.scss"; +@import "./vector-web/views/messages/_MessageTimestamp.scss"; +@import "./vector-web/views/messages/_SenderProfile.scss"; +@import "./vector-web/views/rooms/_RoomDropTarget.scss"; +@import "./vector-web/views/rooms/_RoomTooltip.scss"; +@import "./vector-web/views/rooms/_SearchBar.scss"; +@import "./vector-web/views/settings/_Notifications.scss"; diff --git a/res/css/_fonts.scss b/res/css/_fonts.scss new file mode 100644 index 0000000000..52ac95b569 --- /dev/null +++ b/res/css/_fonts.scss @@ -0,0 +1,67 @@ +/* + * Open Sans + * Includes extended Latin, Greek, Cyrillic and Vietnamese character sets + */ + +/* the 'src' links are relative to the bundle.css, which is in a subdirectory. + */ +@font-face { + font-family: 'Open Sans'; + src: url('../../fonts/Open_Sans/OpenSans-Regular.ttf') format('truetype'); + font-weight: 400; + font-style: normal; +} + +@font-face { + font-family: 'Open Sans'; + src: url('../../fonts/Open_Sans/OpenSans-Italic.ttf') format('truetype'); + font-weight: 400; + font-style: italic; +} + +@font-face { + font-family: 'Open Sans'; + src: url('../../fonts/Open_Sans/OpenSans-Semibold.ttf') format('truetype'); + font-weight: 600; + font-style: normal; +} + +@font-face { + font-family: 'Open Sans'; + src: url('../../fonts/Open_Sans/OpenSans-SemiboldItalic.ttf') format('truetype'); + font-weight: 600; + font-style: italic; +} + +@font-face { + font-family: 'Open Sans'; + src: url('../../fonts/Open_Sans/OpenSans-Bold.ttf') format('truetype'); + font-weight: 700; + font-style: normal; +} + +@font-face { + font-family: 'Open Sans'; + src: url('../../fonts/Open_Sans/OpenSans-BoldItalic.ttf') format('truetype'); + font-weight: 700; + font-style: italic; +} + +/* + * Fira Mono + * Used for monospace copy, i.e. code + */ + +@font-face { + font-family: 'Fira Mono'; + src: url('../../fonts/Fira_Mono/FiraMono-Regular.ttf') format('truetype'); + font-weight: 400; + font-style: normal; +} + +@font-face { + font-family: 'Fira Mono'; + src: url('../../fonts/Fira_Mono/FiraMono-Bold.ttf') format('truetype'); + font-weight: 700; + font-style: normal; +} diff --git a/res/css/rethemendex.sh b/res/css/rethemendex.sh new file mode 100755 index 0000000000..a7d9a657ac --- /dev/null +++ b/res/css/rethemendex.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +cd `dirname $0` + +{ + echo "// autogenerated by rethemendex.sh" + + find . \! \( -path ./themes -prune \) -iname _\*.scss | + fgrep -v _components.scss | LC_ALL=C sort | + while read i; do + echo "@import \"$i\";" + done +} > _components.scss diff --git a/res/css/structures/_CompatibilityPage.scss b/res/css/structures/_CompatibilityPage.scss new file mode 100644 index 0000000000..f3f032c975 --- /dev/null +++ b/res/css/structures/_CompatibilityPage.scss @@ -0,0 +1,19 @@ +.mx_CompatibilityPage { + width: 100%; + height: 100%; + background-color: #e55; +} + +.mx_CompatibilityPage_box { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; + width: 500px; + height: 300px; + border: 1px solid; + padding: 10px; + background-color: #fcc; +} \ No newline at end of file diff --git a/res/css/structures/_ContextualMenu.scss b/res/css/structures/_ContextualMenu.scss new file mode 100644 index 0000000000..a0191b92cf --- /dev/null +++ b/res/css/structures/_ContextualMenu.scss @@ -0,0 +1,160 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_ContextualMenu_wrapper { + position: fixed; + z-index: 2000; +} + +.mx_ContextualMenu_background { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + opacity: 1.0; + z-index: 2000; +} + +.mx_ContextualMenu { + border: solid 1px $menu-border-color; + border-radius: 4px; + background-color: $menu-bg-color; + color: $primary-fg-color; + position: absolute; + padding: 6px; + font-size: 14px; + z-index: 2001; +} + +.mx_ContextualMenu.mx_ContextualMenu_right { + right: 8px; +} + +.mx_ContextualMenu_chevron_right { + position: absolute; + right: -8px; + top: 0px; + width: 0; + height: 0; + border-top: 8px solid transparent; + border-left: 8px solid $menu-border-color; + border-bottom: 8px solid transparent; +} + +.mx_ContextualMenu_chevron_right:after { + content:''; + width: 0; + height: 0; + border-top: 7px solid transparent; + border-left: 7px solid $menu-bg-color; + border-bottom: 7px solid transparent; + position:absolute; + top: -7px; + right: 1px; +} + +.mx_ContextualMenu.mx_ContextualMenu_left { + left: 8px; +} + +.mx_ContextualMenu_chevron_left { + position: absolute; + left: -8px; + top: 0px; + width: 0; + height: 0; + border-top: 8px solid transparent; + border-right: 8px solid $menu-border-color; + border-bottom: 8px solid transparent; +} + +.mx_ContextualMenu_chevron_left:after{ + content:''; + width: 0; + height: 0; + border-top: 7px solid transparent; + border-right: 7px solid $menu-bg-color; + border-bottom: 7px solid transparent; + position:absolute; + top: -7px; + left: 1px; +} + +.mx_ContextualMenu.mx_ContextualMenu_top { + top: 8px; +} + +.mx_ContextualMenu_chevron_top { + position: absolute; + left: 0px; + top: -8px; + width: 0; + height: 0; + border-left: 8px solid transparent; + border-bottom: 8px solid $menu-border-color; + border-right: 8px solid transparent; +} + +.mx_ContextualMenu_chevron_top:after{ + content:''; + width: 0; + height: 0; + border-left: 7px solid transparent; + border-bottom: 7px solid $menu-bg-color; + border-right: 7px solid transparent; + position:absolute; + left: -7px; + top: 1px; +} + +.mx_ContextualMenu.mx_ContextualMenu_bottom { + bottom: 8px; +} + +.mx_ContextualMenu_chevron_bottom { + position: absolute; + left: 0px; + bottom: -8px; + width: 0; + height: 0; + border-left: 8px solid transparent; + border-top: 8px solid $menu-border-color; + border-right: 8px solid transparent; +} + +.mx_ContextualMenu_chevron_bottom:after{ + content:''; + width: 0; + height: 0; + border-left: 7px solid transparent; + border-top: 7px solid $menu-bg-color; + border-right: 7px solid transparent; + position:absolute; + left: -7px; + bottom: 1px; +} + +.mx_ContextualMenu_field { + padding: 3px 6px 3px 6px; + cursor: pointer; + white-space: nowrap; +} + +.mx_ContextualMenu_spinner { + display: block; + margin: 0 auto; +} diff --git a/res/css/structures/_CreateRoom.scss b/res/css/structures/_CreateRoom.scss new file mode 100644 index 0000000000..2be193525e --- /dev/null +++ b/res/css/structures/_CreateRoom.scss @@ -0,0 +1,37 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_CreateRoom { + width: 960px; + margin-left: auto; + margin-right: auto; + color: $primary-fg-color; +} + +.mx_CreateRoom input, +.mx_CreateRoom textarea { + border-radius: 3px; + border: 1px solid $strong-input-border-color; + font-weight: 300; + font-size: 13px; + padding: 9px; + margin-top: 6px; +} + +.mx_CreateRoom_description { + width: 330px; +} + diff --git a/res/css/structures/_FilePanel.scss b/res/css/structures/_FilePanel.scss new file mode 100644 index 0000000000..58e090645f --- /dev/null +++ b/res/css/structures/_FilePanel.scss @@ -0,0 +1,114 @@ +/* +Copyright 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_FilePanel { + order: 2; + + flex: 1 1 0; + + width: 100%; + + overflow-y: auto; +} + +.mx_FilePanel .mx_RoomView_messageListWrapper { + margin-right: 20px; +} + +.mx_FilePanel .mx_RoomView_MessageList h2 { + display: none; +} + +/* FIXME: rather than having EventTile's default CSS be for MessagePanel, + we should make EventTile a base CSS class and customise it specifically + for usage in {Message,File,Notification}Panel. */ + +.mx_FilePanel .mx_EventTile_avatar { + display: none; +} + +/* Overrides for the attachment body tiles */ + +.mx_FilePanel .mx_EventTile { + word-break: break-word; +} + +.mx_FilePanel .mx_EventTile .mx_MImageBody { + margin-right: 0px; +} + +.mx_FilePanel .mx_EventTile .mx_MImageBody_download { + display: flex; + font-size: 14px; + color: $event-timestamp-color; +} + +.mx_FilePanel .mx_EventTile .mx_MImageBody_downloadLink { + flex: 1 1 auto; + color: $light-fg-color; +} + +.mx_FilePanel .mx_EventTile .mx_MImageBody_size { + flex: 1 0 0; + font-size: 11px; + text-align: right; + white-space: nowrap; +} + +/* Overides for the sender details line */ + +.mx_FilePanel .mx_EventTile_senderDetails { + display: flex; + margin-top: -2px; +} + +.mx_FilePanel .mx_EventTile_senderDetailsLink { + text-decoration: none; +} + +.mx_FilePanel .mx_EventTile .mx_SenderProfile { + flex: 1 1 auto; + line-height: initial; + padding: 0px; + font-size: 11px; + opacity: 1.0; + color: $event-timestamp-color; +} + +.mx_FilePanel .mx_EventTile .mx_MessageTimestamp { + flex: 1 0 0; + text-align: right; + visibility: visible; + position: initial; + font-size: 11px; + opacity: 1.0; + color: $event-timestamp-color; +} + +/* Overrides for the wrappers around the body tile */ + +.mx_FilePanel .mx_EventTile_line { + margin-right: 0px; + padding-left: 0px; +} + +.mx_FilePanel .mx_EventTile:hover .mx_EventTile_line { + background-color: $primary-bg-color; +} + +.mx_FilePanel .mx_EventTile_selected .mx_EventTile_line { + padding-left: 0px; +} diff --git a/res/css/structures/_GroupView.scss b/res/css/structures/_GroupView.scss new file mode 100644 index 0000000000..02e5a948e9 --- /dev/null +++ b/res/css/structures/_GroupView.scss @@ -0,0 +1,349 @@ +/* +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. +*/ + +.mx_GroupView { + max-width: 960px; + width: 100%; + margin-left: auto; + margin-right: auto; + display: flex; + flex-direction: column; + overflow: hidden; +} + +.mx_GroupView_error { + margin: auto; +} + +.mx_GroupView_header { + max-width: 960px; + min-height: 70px; + align-items: center; + display: flex; + padding-bottom: 10px; +} + +.mx_GroupView_header_view { + border-bottom: 1px solid $primary-hairline-color; + padding-bottom: 0px; +} + +.mx_GroupView_header_avatar, .mx_GroupView_header_info { + display: table-cell; + vertical-align: middle; +} + +.mx_GroupHeader_button { + margin-left: 12px; + cursor: pointer; +} + +.mx_GroupHeader_button object { + // prevents clicks from being swallowed by svg in 'object' tag + pointer-events: none; +} + +.mx_GroupView_editable { + border-bottom: 1px solid $strong-input-border-color ! important; + min-width: 150px; + cursor: text; +} + +.mx_GroupView_editable:focus { + border-bottom: 1px solid $accent-color ! important; + outline: none; + box-shadow: none; +} + +.mx_GroupView_header_isUserMember .mx_GroupView_header_name:hover div:not(.mx_GroupView_editable) { + color: $accent-color; + cursor: pointer; +} + +.mx_GroupView_avatarPicker { + position: relative; +} + +.mx_GroupView_avatarPicker_edit { + position: absolute; + top: 50px; + left: 15px; +} + +.mx_GroupView_avatarPicker .mx_Spinner { + width: 48px; + height: 48px ! important; +} + +.mx_GroupView_header_leftCol { + flex: 1; + + overflow: hidden; +} + +.mx_GroupView_header_rightCol { + display: flex; + align-items: center; +} + +.mx_GroupView_textButton { + display: inline-block; +} + +.mx_GroupView_header_groupid { + font-weight: normal; + font-size: initial; + padding-left: 10px; +} + +.mx_GroupView_header_name { + vertical-align: middle; + width: 100%; + height: 31px; + overflow: hidden; + color: $primary-fg-color; + font-weight: bold; + font-size: 22px; + padding-left: 19px; + padding-right: 16px; + /* why isn't text-overflow working? */ + text-overflow: ellipsis; + border-bottom: 1px solid transparent; +} + +.mx_GroupView_header_shortDesc { + vertical-align: bottom; + float: left; + max-height: 42px; + color: $settings-grey-fg-color; + font-weight: 300; + font-size: 13px; + padding-left: 19px; + margin-right: 16px; + overflow: hidden; + text-overflow: ellipsis; + border-bottom: 1px solid transparent; +} + +.mx_GroupView_avatarPicker_label { + cursor: pointer; +} + +.mx_GroupView_cancelButton { + padding-left: 8px; +} + +.mx_GroupView_cancelButton img { + position: relative; + top: 5px; +} + +.mx_GroupView input[type='radio'] { + margin: 10px 10px 0px 10px; +} + +.mx_GroupView_label_text { + display: inline-block; + max-width: 80%; + vertical-align: 0.1em; + line-height: 2em; +} + +.mx_GroupView_body { + flex-grow: 1; +} + +.mx_GroupView_rooms { + flex-grow: 1; + display: flex; + flex-direction: column; + min-height: 200px; + user-select: none; +} + +.mx_GroupView h3 { + text-transform: uppercase; + color: $h3-color; + font-weight: 600; + font-size: 13px; + margin-bottom: 10px; +} + +.mx_GroupView_rooms_header .mx_AccessibleButton { + padding-left: 14px; + margin-bottom: 14px; + height: 24px; +} + +.mx_GroupView_group { + border-top: 1px solid $primary-hairline-color; +} + +.mx_GroupView_group_disabled { + opacity: 0.3; + pointer-events: none; +} + +.mx_GroupView_rooms_header_addRow_button { + display: inline-block; +} + +.mx_GroupView_rooms_header_addRow_button object { + pointer-events: none; +} + +.mx_GroupView_rooms_header_addRow_label { + display: inline-block; + vertical-align: top; + line-height: 24px; + padding-left: 28px; + color: $accent-color; +} + +.mx_GroupView_rooms .mx_RoomDetailList { + flex-grow: 1; + border-top: 1px solid $primary-hairline-color; + padding-top: 10px; + word-break: break-word; +} + +.mx_GroupView .mx_RoomView_messageListWrapper { + justify-content: flex-start; +} + +.mx_GroupView_membershipSection { + color: $greyed-fg-color; + margin-top: 10px; +} + +.mx_GroupView_membershipSubSection { + justify-content: space-between; + display: flex; +} + +.mx_GroupView_membershipSubSection .mx_Spinner { + justify-content: flex-end; +} + +.mx_GroupView_membershipSection_description { + /* To match textButton */ + line-height: 34px; +} + +.mx_GroupView_membershipSection_description .mx_BaseAvatar { + margin-right: 10px; +} + +.mx_GroupView_membershipSection .mx_GroupView_textButton { + margin-right: 0px; + margin-top: 0px; + margin-left: 8px; +} + +.mx_GroupView_memberSettings_toggle label { + cursor: pointer; + user-select: none; +} + +.mx_GroupView_memberSettings input { + margin-right: 6px; +} + +.mx_GroupView_featuredThings { + margin-top: 20px; +} + +.mx_GroupView_featuredThings_header { + font-weight: bold; + font-size: 120%; + margin-bottom: 20px; +} + +.mx_GroupView_featuredThings_category { + font-weight: bold; + font-size: 110%; + margin-top: 10px; +} + +.mx_GroupView_featuredThings_container { + display: flex; +} + +.mx_GroupView_featuredThings_addButton, +.mx_GroupView_featuredThing { + display: table-cell; + text-align: center; + + width: 100px; + margin: 0px 20px; +} + +.mx_GroupView_featuredThing { + position: relative; +} + +.mx_GroupView_featuredThing .mx_GroupView_featuredThing_deleteButton { + position: absolute; + top: -7px; + right: 11px; + opacity: 0.4; +} + +.mx_GroupView_featuredThing .mx_BaseAvatar { + /* To prevent misalignment with mx_TintableSvg (in addButton) */ + vertical-align: initial; +} + +.mx_GroupView_featuredThings_addButton object { + pointer-events: none; +} + +.mx_GroupView_featuredThing_name { + word-wrap: break-word; +} + +.mx_GroupView_uploadInput { + display: none; +} + +.mx_GroupView_body .gm-scroll-view > *{ + margin: 11px 50px 0px 68px; +} + +.mx_GroupView_groupDesc textarea { + width: 100%; + max-width: 100%; + height: 150px; +} + +.mx_GroupView_groupDesc_placeholder, +.mx_GroupView_changeDelayWarning { + background-color: $info-plinth-bg-color; + color: $info-plinth-fg-color; + border-radius: 10px; + text-align: center; + + margin: 20px 0px; +} + +.mx_GroupView_groupDesc_placeholder { + padding: 100px 20px; + cursor: pointer; +} + +.mx_GroupView_changeDelayWarning { + padding: 40px 20px; +} diff --git a/res/css/structures/_HomePage.scss b/res/css/structures/_HomePage.scss new file mode 100644 index 0000000000..cdac1bcc8a --- /dev/null +++ b/res/css/structures/_HomePage.scss @@ -0,0 +1,35 @@ +/* +Copyright 2016 OpenMarket Ltd +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. +*/ + +.mx_HomePage { + max-width: 960px; + width: 100%; + height: 100%; + margin-left: auto; + margin-right: auto; +} + +.mx_HomePage iframe { + display: block; + width: 100%; + height: 100%; + border: 0px; +} + +.mx_HomePage_body { +// margin-left: 63px; +} diff --git a/res/css/structures/_LeftPanel.scss b/res/css/structures/_LeftPanel.scss new file mode 100644 index 0000000000..96ed5878ac --- /dev/null +++ b/res/css/structures/_LeftPanel.scss @@ -0,0 +1,129 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_LeftPanel { + position: relative; + + display: flex; + flex-direction: column; +} + +.mx_LeftPanel_container { + display: flex; + /* LeftPanel 235px */ + flex: 0 0 235px; +} + +.mx_LeftPanel_container.mx_LeftPanel_container_hasTagPanel { + /* TagPanel 60px + LeftPanel 235px */ + flex: 0 0 295px; +} + +.mx_LeftPanel_container_collapsed { + /* Collapsed LeftPanel 60px */ + flex: 0 0 60px; +} + +.mx_LeftPanel_container_collapsed.mx_LeftPanel_container_hasTagPanel { + /* TagPanel 60px + Collapsed LeftPanel 60px */ + flex: 0 0 120px; +} + +.mx_LeftPanel_hideButton { + position: absolute; + top: 10px; + right: 0px; + padding: 8px; + cursor: pointer; +} + +.mx_LeftPanel_callView { + +} + +.mx_LeftPanel .mx_RoomList_scrollbar { + order: 1; + + flex: 1 1 0; + + overflow-y: auto; + z-index: 6; +} + +.mx_LeftPanel.collapsed .mx_BottomLeftMenu { + flex: 0 0 160px; + margin-bottom: 9px; +} + +.mx_LeftPanel .mx_BottomLeftMenu { + order: 3; + + border-top: 1px solid $panel-divider-color; + margin-left: 16px; /* gutter */ + margin-right: 16px; /* gutter */ + flex: 0 0 60px; + z-index: 1; +} + +.mx_LeftPanel .mx_BottomLeftMenu_options { + margin-top: 18px; +} + +.mx_BottomLeftMenu_options object { + pointer-events: none; +} + +.collapsed .mx_RoleButton { + margin-right: 0px ! important; + padding-top: 3px ! important; + padding-bottom: 3px ! important; +} + +.mx_BottomLeftMenu_options > div { + display: inline-block; +} + +.mx_BottomLeftMenu_options .mx_RoleButton { + margin-left: 0px; + margin-right: 10px; + height: 30px; +} + +.mx_BottomLeftMenu_options .mx_BottomLeftMenu_settings { + float: right; +} + +.mx_BottomLeftMenu_options .mx_BottomLeftMenu_settings .mx_RoleButton { + margin-right: 0px; +} + +.mx_LeftPanel.collapsed .mx_BottomLeftMenu_settings { + float: none; +} + +.mx_MatrixChat_useCompactLayout { + .mx_LeftPanel .mx_BottomLeftMenu { + flex: 0 0 50px; + } + + .mx_LeftPanel.collapsed .mx_BottomLeftMenu { + flex: 0 0 160px; + } + + .mx_LeftPanel .mx_BottomLeftMenu_options { + margin-top: 12px; + } +} diff --git a/res/css/structures/_LoginBox.scss b/res/css/structures/_LoginBox.scss new file mode 100644 index 0000000000..7f6199c451 --- /dev/null +++ b/res/css/structures/_LoginBox.scss @@ -0,0 +1,47 @@ +/* +Copyright 2017 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_LoginBox { + min-height: 24px; + height: unset !important; + padding-top: 13px !important; + padding-bottom: 14px !important; +} + +.mx_LoginBox_loginButton_wrapper { + text-align: center; + width: 100%; +} + +.mx_LoginBox_loginButton, +.mx_LoginBox_registerButton { + margin-top: 3px; + height: 40px; + border: 0px; + border-radius: 40px; + margin-left: 4px; + margin-right: 4px; + min-width: 80px; + + background-color: $accent-color; + color: $primary-bg-color; + + cursor: pointer; + + font-size: 15px; + padding: 0 11px; + word-break: break-word; +} diff --git a/res/css/structures/_MatrixChat.scss b/res/css/structures/_MatrixChat.scss new file mode 100644 index 0000000000..156b1709fe --- /dev/null +++ b/res/css/structures/_MatrixChat.scss @@ -0,0 +1,104 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_MatrixChat_splash { + position: relative; + height: 100%; +} + +.mx_MatrixChat_splashButtons { + text-align: center; + width: 100%; + position: absolute; + bottom: 30px; +} + +.mx_MatrixChat_wrapper { + display: flex; + + flex-direction: column; + + width: 100%; + height: 100%; +} + +.mx_MatrixToolbar { + order: 1; + + height: 40px; +} + +.mx_MatrixChat_toolbarShowing { + height: auto; +} + +.mx_MatrixChat { + width: 100%; + height: 100%; + + display: flex; + + order: 2; + + flex: 1; +} + +.mx_MatrixChat .mx_LeftPanel { + order: 1; + + background-color: $secondary-accent-color; + + flex: 0 0 235px; +} + +.mx_MatrixChat .mx_LeftPanel.collapsed { + flex: 0 0 60px; +} + +.mx_MatrixChat .mx_MatrixChat_middlePanel { + order: 2; + + padding-left: 20px; + padding-right: 22px; + background-color: $primary-bg-color; + + flex: 1; + + /* Experimental fix for https://github.com/vector-im/vector-web/issues/947 + and https://github.com/vector-im/vector-web/issues/946. + Empirically this stops the MessagePanel's width exploding outwards when + gemini is in 'prevented' mode + */ + overflow-x: auto; + + display: flex; + + /* To fix https://github.com/vector-im/riot-web/issues/3298 where Safari + needed height 100% all the way down to the HomePage. Height does not + have to be auto, empirically. + */ + height: 100%; +} + +.mx_MatrixChat .mx_RightPanel { + order: 3; + + flex: 0 0 235px; +} + +.mx_MatrixChat .mx_RightPanel.collapsed { + flex: 0 0 122px; +} diff --git a/res/css/structures/_MyGroups.scss b/res/css/structures/_MyGroups.scss new file mode 100644 index 0000000000..6d140721c8 --- /dev/null +++ b/res/css/structures/_MyGroups.scss @@ -0,0 +1,151 @@ +/* +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. +*/ + +.mx_MyGroups { + max-width: 960px; + margin-left: auto; + margin-right: auto; + + display: flex; + flex-direction: column; +} + +.mx_MyGroups .mx_RoomHeader_simpleHeader { + margin-left: 0px; +} + +.mx_MyGroups_header { + /* Keep mid-point of create button aligned with icon in page header */ + margin-left: 2px; + display: flex; + flex-wrap: wrap; +} + +.mx_MyGroups_headerCard { + flex: 1 0 50%; + margin-bottom: 30px; + min-width: 400px; + display: flex; + align-items: center; +} + +.mx_MyGroups_headerCard .mx_MyGroups_headerCard_button { + margin-right: 13px; + height: 50px; +} + +.mx_MyGroups_headerCard_button object { + /* Otherwise the SVG object absorbs clicks and the button doesn't work */ + pointer-events: none; +} + +.mx_MyGroups_headerCard_header { + font-weight: bold; + margin-bottom: 10px; +} + +.mx_MyGroups_headerCard_content { + padding-right: 15px; +} + +/* Until the button is wired up */ +.mx_MyGroups_joinBox { + visibility: hidden; + + /* When joinBox wraps onto its own row, it should take up zero height so + that there isn't an awkward gap between MyGroups_createBox and + MyGroups_content. + */ + height: 0px; + margin: 0px; +} + +.mx_MyGroups_content { + margin-left: 2px; + + flex: 1 0 0; + + display: flex; + flex-direction: column; +} + +.mx_MyGroups_placeholder { + background-color: $info-plinth-bg-color; + color: $info-plinth-fg-color; + line-height: 400px; + border-radius: 10px; + text-align: center; +} + +.mx_MyGroups_joinedGroups { + border-top: 1px solid $primary-hairline-color; + overflow-x: hidden; + + display: flex; + flex-direction: row; + flex-flow: wrap; + align-content: flex-start; +} + +.mx_MyGroups_joinedGroups .mx_GroupTile { + min-width: 300px; + max-width: 33%; + flex: 1 0 300px; + height: 75px; + margin: 10px 0px; + display: flex; + align-items: flex-start; + cursor: pointer; +} + +.mx_GroupTile_avatar { + cursor: grab, -webkit-grab; +} + +.mx_GroupTile_profile { + margin-left: 10px; + display: flex; + flex-direction: column; + justify-content: center; +} + +.mx_GroupTile_profile .mx_GroupTile_name, +.mx_GroupTile_profile .mx_GroupTile_groupId, +.mx_GroupTile_profile .mx_GroupTile_desc { + padding-right: 10px; +} + +.mx_GroupTile_profile .mx_GroupTile_name { + margin: 0px; + font-size: 15px; +} + +.mx_GroupTile_profile .mx_GroupTile_groupId { + font-size: 13px; +} + +.mx_GroupTile_profile .mx_GroupTile_desc { + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + font-size: 13px; + max-height: 36px; + overflow: hidden; +} + +.mx_GroupTile_profile .mx_GroupTile_groupId { + opacity: 0.7; +} diff --git a/res/css/structures/_NotificationPanel.scss b/res/css/structures/_NotificationPanel.scss new file mode 100644 index 0000000000..a899808d57 --- /dev/null +++ b/res/css/structures/_NotificationPanel.scss @@ -0,0 +1,100 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_NotificationPanel { + order: 2; + + flex: 1 1 0; + + width: 100%; + + overflow-y: auto; +} + +.mx_NotificationPanel .mx_RoomView_messageListWrapper { + margin-right: 20px; +} + +.mx_NotificationPanel .mx_RoomView_MessageList h2 { + margin-left: 0px; +} + +/* FIXME: rather than having EventTile's default CSS be for MessagePanel, + we should make EventTile a base CSS class and customise it specifically + for usage in {Message,File,Notification}Panel. */ + +.mx_NotificationPanel .mx_EventTile { + word-break: break-word; +} + +.mx_NotificationPanel .mx_EventTile_roomName { + font-weight: bold; + font-size: 14px; +} + +.mx_NotificationPanel .mx_EventTile_roomName a { + color: $primary-fg-color; +} + +.mx_NotificationPanel .mx_EventTile_avatar { + top: 8px; + left: 0px; +} + +.mx_NotificationPanel .mx_EventTile .mx_SenderProfile, +.mx_NotificationPanel .mx_EventTile .mx_MessageTimestamp { + color: $primary-fg-color; + font-size: 12px; + display: inline; + padding-left: 0px; +} + +.mx_NotificationPanel .mx_EventTile_senderDetails { + padding-left: 32px; + padding-top: 8px; + position: relative; +} + +.mx_NotificationPanel .mx_EventTile_roomName a, +.mx_NotificationPanel .mx_EventTile_senderDetails a { + text-decoration: none ! important; +} + +.mx_NotificationPanel .mx_EventTile .mx_MessageTimestamp { + visibility: visible; + position: initial; + display: inline; +} + +.mx_NotificationPanel .mx_EventTile_line { + margin-right: 0px; + padding-left: 32px; + padding-top: 0px; + padding-bottom: 0px; + padding-right: 0px; +} + +.mx_NotificationPanel .mx_EventTile:hover .mx_EventTile_line { + background-color: $primary-bg-color; +} + +.mx_NotificationPanel .mx_EventTile_selected .mx_EventTile_line { + padding-left: 0px; +} + +.mx_NotificationPanel .mx_EventTile_content { + margin-right: 0px; +} \ No newline at end of file diff --git a/res/css/structures/_RightPanel.scss b/res/css/structures/_RightPanel.scss new file mode 100644 index 0000000000..b4dff612ed --- /dev/null +++ b/res/css/structures/_RightPanel.scss @@ -0,0 +1,133 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_RightPanel { + position: relative; + + display: flex; + flex-direction: column; +} + +.mx_RightPanel_header { + order: 1; + + border-bottom: 1px solid $primary-hairline-color; + margin-right: 20px; + + flex: 0 0 70px; +} + +/** Fixme - factor this out with the main header **/ + +.mx_RightPanel_headerButtonGroup { + margin-top: 6px; + display: flex; + width: 100%; + background-color: $primary-bg-color; + margin-left: 0px; +} + +.mx_RightPanel_headerButton { + cursor: pointer; + flex: 0 0 auto; + vertical-align: top; + padding-left: 4px; + padding-right: 5px; + text-align: center; + position: relative; +} + +.mx_RightPanel_headerButton object { + pointer-events: none; + padding-bottom: 3px; +} + +.mx_RightPanel_headerButton_highlight { + width: 25px; + height: 5px; + border-radius: 5px; + background-color: $accent-color; + opacity: 0.2; +} + +.mx_RightPanel_headerButton_badge { + font-size: 11px; + color: $accent-color; + font-weight: bold; + padding-bottom: 2px; +} + +.mx_RightPanel_collapsebutton { + flex: 1; + text-align: right; + margin-top: 20px; +} + +.mx_RightPanel .mx_MemberList, +.mx_RightPanel .mx_MemberInfo, +.mx_RightPanel .mx_GroupRoomList, +.mx_RightPanel_blank { + order: 2; + flex: 1 1 0; +} + +.mx_RightPanel .mx_RoomView_messagePanelSpinner { + order: 2; + margin: auto; +} + +.mx_RightPanel_footer { + order: 3; + + border-top: 1px solid $primary-hairline-color; + margin-right: 20px; + + flex: 0 0 60px; +} + +.mx_RightPanel_footer .mx_RightPanel_invite { + font-size: 14px; + color: $primary-fg-color; + padding-top: 13px; + padding-left: 5px; + cursor: pointer; + display: flex; + align-items: center; +} + +.collapsed .mx_RightPanel_footer .mx_RightPanel_invite { + display: none; +} + +.mx_RightPanel_invite .mx_RightPanel_icon object { + pointer-events: none; +} + +.mx_RightPanel_invite .mx_RightPanel_message { + padding-left: 10px; + line-height: 18px; +} + +.mx_MatrixChat_useCompactLayout { + .mx_RightPanel_footer { + flex: 0 0 50px; + } + + .mx_RightPanel_footer .mx_RightPanel_invite { + line-height: 25px; + padding-top: 8px; + } +} diff --git a/res/css/structures/_RoomDirectory.scss b/res/css/structures/_RoomDirectory.scss new file mode 100644 index 0000000000..9cd3e7284c --- /dev/null +++ b/res/css/structures/_RoomDirectory.scss @@ -0,0 +1,131 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_RoomDirectory { + max-width: 960px; + width: 100%; + margin-left: auto; + margin-right: auto; + margin-bottom: 12px; + color: $primary-fg-color; + word-break: break-word; + + display: flex; + + flex-direction: column; +} + +.mx_RoomDirectory .mx_RoomHeader_simpleHeader { + margin-left: 0px; +} + +.mx_RoomDirectory_list { + flex: 1; + + display: flex; + + flex-direction: column; +} + +.mx_RoomDirectory_list .mx_RoomView_messageListWrapper { + justify-content: flex-start; +} + +.mx_RoomDirectory_listheader { + display: table; + table-layout: fixed; + width: 100%; + margin-top: 12px; + margin-bottom: 12px; + border-spacing: 5px; +} + +.mx_RoomDirectory_searchbox { + display: table-cell; + vertical-align: middle; +} + +.mx_RoomDirectory_listheader .mx_NetworkDropdown { + display: table-cell; + width: 200px; +} + +.mx_RoomDirectory_tableWrapper { + overflow-y: auto; + flex: 1 1 0; +} + +.mx_RoomDirectory_table { + font-size: 14px; + color: $primary-fg-color; + width: 100%; + text-align: left; + table-layout: fixed; +} + +.mx_RoomDirectory_roomAvatar { + width: 24px; + padding-left: 12px; + padding-right: 24px; + vertical-align: top; +} + +.mx_RoomDirectory_roomDescription { + padding-bottom: 16px; +} + +.mx_RoomDirectory_name { + display: inline-block; + font-weight: 600; +} + +.mx_RoomDirectory_perms { + display: inline-block; +} + +.mx_RoomDirectory_perm { + display: inline; + padding-left: 5px; + padding-right: 5px; + margin-right: 5px; + height: 15px; + border-radius: 11px; + background-color: $plinth-bg-color; + text-transform: uppercase; + font-weight: 600; + font-size: 11px; + color: $accent-color; +} + +.mx_RoomDirectory_topic { + cursor: initial; +} + +.mx_RoomDirectory_alias { + font-size: 12px; + color: $settings-grey-fg-color; +} + +.mx_RoomDirectory_roomMemberCount { + text-align: right; + width: 100px; + padding-right: 10px; +} + +.mx_RoomDirectory_table tr { + padding-bottom: 10px; + cursor: pointer; +} diff --git a/res/css/structures/_RoomStatusBar.scss b/res/css/structures/_RoomStatusBar.scss new file mode 100644 index 0000000000..ca7431eac2 --- /dev/null +++ b/res/css/structures/_RoomStatusBar.scss @@ -0,0 +1,181 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_RoomStatusBar { + margin-left: 65px; + min-height: 50px; +} + +/* position the indicator in the same place horizontally as .mx_EventTile_avatar. */ +.mx_RoomStatusBar_indicator { + padding-left: 17px; + padding-right: 12px; + margin-left: -73px; + margin-top: 15px; + float: left; + width: 24px; + text-align: center; +} + +.mx_RoomStatusBar_callBar { + height: 50px; + line-height: 50px; +} + +.mx_RoomStatusBar_placeholderIndicator span { + color: $primary-fg-color; + opacity: 0.5; + position: relative; + top: -4px; +/* + animation-duration: 1s; + animation-name: bounce; + animation-direction: alternate; + animation-iteration-count: infinite; +*/ +} + +.mx_RoomStatusBar_placeholderIndicator span:nth-child(1) { + animation-delay: 0.3s; +} +.mx_RoomStatusBar_placeholderIndicator span:nth-child(2) { + animation-delay: 0.6s; +} +.mx_RoomStatusBar_placeholderIndicator span:nth-child(3) { + animation-delay: 0.9s; +} + +@keyframes bounce { + from { + opacity: 0.5; + top: 0; + } + + to { + opacity: 0.2; + top: -3px; + } +} + +.mx_RoomStatusBar_typingIndicatorAvatars { + width: 52px; + margin-top: -1px; + text-align: left; +} + +.mx_RoomStatusBar_typingIndicatorAvatars .mx_BaseAvatar_image { + margin-right: -12px; + border: 1px solid $primary-bg-color; +} + +.mx_RoomStatusBar_typingIndicatorAvatars .mx_BaseAvatar_initial { + padding-left: 1px; + padding-top: 1px; +} + +.mx_RoomStatusBar_typingIndicatorRemaining { + display: inline-block; + color: #acacac; + background-color: #ddd; + border: 1px solid $primary-bg-color; + border-radius: 40px; + width: 24px; + height: 24px; + line-height: 24px; + font-size: 0.8em; + vertical-align: top; + text-align: center; + position: absolute; +} + +.mx_RoomStatusBar_scrollDownIndicator { + cursor: pointer; + padding-left: 1px; +} + +.mx_RoomStatusBar_unreadMessagesBar { + padding-top: 10px; + color: $warning-color; + cursor: pointer; +} + +.mx_RoomStatusBar_connectionLostBar { + margin-top: 19px; + min-height: 58px; +} + +.mx_RoomStatusBar_connectionLostBar img { + padding-left: 10px; + padding-right: 22px; + vertical-align: middle; + float: left; +} + +.mx_RoomStatusBar_connectionLostBar_title { + color: $warning-color; +} + +.mx_RoomStatusBar_connectionLostBar_desc { + color: $primary-fg-color; + font-size: 13px; + opacity: 0.5; +} + +.mx_RoomStatusBar_resend_link { + color: $primary-fg-color ! important; + text-decoration: underline ! important; + cursor: pointer; +} + +.mx_RoomStatusBar_typingBar { + height: 50px; + line-height: 50px; + + color: $primary-fg-color; + opacity: 0.5; + overflow-y: hidden; + display: block; +} + +.mx_RoomStatusBar_isAlone { + height: 50px; + line-height: 50px; + + color: $primary-fg-color; + opacity: 0.5; + overflow-y: hidden; + display: block; +} + +.mx_MatrixChat_useCompactLayout { + .mx_RoomStatusBar { + min-height: 40px; + } + + .mx_RoomStatusBar_indicator { + margin-top: 10px; + } + + .mx_RoomStatusBar_callBar { + height: 40px; + line-height: 40px; + } + + .mx_RoomStatusBar_typingBar { + height: 40px; + line-height: 40px; + } +} diff --git a/res/css/structures/_RoomSubList.scss b/res/css/structures/_RoomSubList.scss new file mode 100644 index 0000000000..a2863460ad --- /dev/null +++ b/res/css/structures/_RoomSubList.scss @@ -0,0 +1,244 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_RoomSubList { + display: table; + table-layout: fixed; + width: 100%; + + background-color: $roomsublist-background; +} + +.mx_RoomSubList_labelContainer { + height: 31px; /* mx_RoomSubList_label height including border */ + width: 235px; /* LHS Panel width */ + position: relative; +} + +.mx_RoomSubList_label { + position: relative; + text-transform: uppercase; + color: $roomsublist-label-fg-color; + font-weight: 600; + font-size: 12px; + width: 203px; /* padding + width = LHS Panel width */ + height: 19px; /* height + padding = 31px = mx_RoomSubList_label height */ + padding-left: 16px; /* gutter */ + padding-right: 16px; /* gutter */ + padding-top: 6px; + padding-bottom: 6px; + cursor: pointer; + background-color: $secondary-accent-color; +} + +.mx_RoomSubList_label.mx_RoomSubList_fixed { + position: fixed; + top: 0; + z-index: 5; + /* pointer-events: none; */ +} + +.collapsed .mx_RoomSubList_label { + height: 17px; + width: 28px; /* collapsed LHS Panel width */ +} + +.collapsed .mx_RoomSubList_labelContainer { + width: 28px; /* collapsed LHS Panel width */ +} + +.mx_RoomSubList_roomCount { + display: inline-block; + font-size: 12px; + font-weight: normal; + color: $accent-color; + padding-left: 5px; + text-transform: none; +} + +.collapsed .mx_RoomSubList_roomCount { + display: none; +} + +.mx_RoomSubList_badge { + display: inline-block; + min-width: 15px; + height: 15px; + position: absolute; + right: 8px; /*gutter */ + top: 7px; + border-radius: 8px; + color: $accent-fg-color; + font-weight: 600; + font-size: 10px; + text-align: center; + padding-top: 1px; + padding-left: 4px; + padding-right: 4px; + background-color: $accent-color; +} + +/* +.collapsed .mx_RoomSubList_badge { + display: none; +} +*/ + +.mx_RoomSubList_badgeHighlight { + background-color: $warning-color; +} + +/* This is the bottom of the speech bubble */ +.mx_RoomSubList_badgeHighlight:after { + content: ""; + position: absolute; + display: block; + width: 0; + height: 0; + margin-left: 5px; + border-top: 5px solid $warning-color; + border-right: 7px solid transparent; +} + +/* Hide the bottom of speech bubble */ +.collapsed .mx_RoomSubList_badgeHighlight:after { + display: none; +} + +.mx_RoomSubList_chevron { + pointer-events: none; + position: absolute; + right: 41px; + top: 11px; +} + +.mx_RoomSubList_chevronDown { + width: 0; + height: 0; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-top: 6px solid $roomsublist-chevron-color; +} + +.mx_RoomSubList_chevronUp { + width: 0; + height: 0; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-bottom: 6px solid $roomsublist-chevron-color; +} + +.mx_RoomSubList_chevronRight { + width: 0; + height: 0; + border-top: 5px solid transparent; + border-left: 6px solid $roomsublist-chevron-color; + border-bottom: 5px solid transparent; +} + +/* The overflow section */ +.mx_RoomSubList_ellipsis { + display: block; + line-height: 11px; + height: 18px; + position: relative; + cursor: pointer; + font-size: 13px; + + background-color: $secondary-accent-color; +} + +.collapsed .mx_RoomSubList_ellipsis { + height: 20px; +} + +.mx_RoomSubList_line { + display: inline-block; + width: 159px; + border-top: dotted 2px $accent-color; + vertical-align: middle; +} + +.collapsed .mx_RoomSubList_line { + display: none; +} + +.mx_RoomSubList_more { + display: inline-block; + text-transform: uppercase; + font-size: 10px; + font-weight: 600; + text-align: left; + color: $accent-color; + padding-left: 7px; + padding-right: 7px; + padding-left: 7px; + vertical-align: middle; +} + +.collapsed .mx_RoomSubList_more { + display: none; +} + +.mx_RoomSubList_moreBadge { + display: inline-block; + min-width: 15px; + height: 13px; + position: absolute; + right: 8px; /*gutter */ + top: -2px; + border-radius: 8px; + border: solid 1px $accent-color; + color: $accent-fg-color; + font-weight: 600; + font-size: 10px; + text-align: center; + padding-top: 1px; + padding-left: 3px; + padding-right: 3px; + background-color: $primary-bg-color; + vertical-align: middle; +} + +.mx_RoomSubList_moreBadge.mx_RoomSubList_moreBadgeNotify { + background-color: $accent-color; + border: 0; + padding-top: 3px; + padding-left: 4px; + padding-right: 4px; +} + +.mx_RoomSubList_moreBadge.mx_RoomSubList_moreBadgeHighlight { + background-color: $warning-color; + border: 0; + padding-top: 3px; + padding-left: 4px; + padding-right: 4px; +} + +.collapsed .mx_RoomSubList_moreBadge { + position: static; + margin-left: 16px; + margin-top: 2px; +} + +.mx_RoomSubList_ellipsis .mx_RoomSubList_chevronDown { + position: relative; + top: 4px; + left: 2px; +} + + diff --git a/res/css/structures/_RoomView.scss b/res/css/structures/_RoomView.scss new file mode 100644 index 0000000000..b8e1190375 --- /dev/null +++ b/res/css/structures/_RoomView.scss @@ -0,0 +1,272 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_RoomView { + word-wrap: break-word; + position: relative; + + display: flex; + width: 100%; + + flex-direction: column; +} + +.mx_RoomView .mx_RoomHeader { + order: 1; + + flex: 0 0 70px; +} + +.mx_RoomView_fileDropTarget { + min-width: 0px; + max-width: 960px; + width: 100%; + font-size: 18px; + text-align: center; + + pointer-events: none; + + padding-left: 12px; + padding-right: 12px; + margin-left: -12px; + + border-top-left-radius: 10px; + border-top-right-radius: 10px; + + background-color: $droptarget-bg-color; + border: 2px #e1dddd solid; + border-bottom: none; + position: absolute; + top: 70px; + bottom: 0px; + z-index: 3000; +} + +.mx_RoomView_fileDropTargetLabel { + top: 50%; + width: 100%; + margin-top: -50px; + position: absolute; +} + +.mx_RoomView_auxPanel { + order: 2; + + min-width: 0px; + max-width: 960px; + width: 100%; + margin: 0px auto; + + overflow: auto; + border-bottom: 1px solid $primary-hairline-color; + + flex: 0 0 auto; +} + +.mx_RoomView_auxPanel_apps { + max-width: 1920px ! important; +} + + +.mx_RoomView_body { + order: 3; + flex: 1 1 0; + flex-direction: column; + display: flex; +} + +.mx_RoomView_body .mx_RoomView_topUnreadMessagesBar { + order: 1; +} + +.mx_RoomView_body .mx_RoomView_messagePanel { + order: 2; +} + +.mx_RoomView_body .mx_RoomView_messagePanelSpinner { + order: 2; + margin: auto; +} + +.mx_RoomView_body .mx_RoomView_statusArea { + order: 3; +} + +.mx_RoomView_body .mx_MessageComposer { + order: 4; +} + +.mx_RoomView_messagePanel { + width: 100%; + overflow-y: auto; +} + +.mx_RoomView_messageListWrapper { + max-width: 960px; + margin: auto; + + min-height: 100%; + + display: flex; + + flex-direction: column; + + justify-content: flex-end; +} + +.mx_RoomView_searchResultsPanel .mx_RoomView_messageListWrapper { + justify-content: flex-start; +} + +.mx_RoomView_empty { + flex: 1 1 auto; + font-size: 13px; + padding-left: 3em; + padding-right: 3em; + margin-right: 20px; + margin-top: 33%; + text-align: center; +} + +.mx_RoomView_MessageList { + width: 100%; + list-style-type: none; + padding: 0px; +} + +.mx_RoomView_MessageList li { + clear: both; +} + +li.mx_RoomView_myReadMarker_container { + height: 0px; + margin: 0px; + padding: 0px; + border: 0px; +} + +hr.mx_RoomView_myReadMarker { + border-top: solid 1px $accent-color; + border-bottom: solid 1px $accent-color; + margin-top: 0px; + position: relative; + top: -1px; + z-index: 1; +} + +.mx_RoomView_statusArea { + width: 100%; + flex: 0 0 auto; + + max-height: 0px; + background-color: $primary-bg-color; + z-index: 1000; + overflow: hidden; + + -webkit-transition: all .2s ease-out; + -moz-transition: all .2s ease-out; + -ms-transition: all .2s ease-out; + -o-transition: all .2s ease-out; +} + +.mx_RoomView_statusArea_expanded { + max-height: 100px; +} + +.mx_RoomView_statusAreaBox { + max-width: 960px; + margin: auto; + min-height: 50px; +} + +.mx_RoomView_statusAreaBox_line { + margin-left: 65px; + border-top: 1px solid $primary-hairline-color; + height: 1px; +} + +.mx_RoomView_callStatusBar .mx_UploadBar_uploadProgressInner { + background-color: $primary-bg-color; +} + +.mx_RoomView_callStatusBar .mx_UploadBar_uploadFilename { + color: $accent-fg-color; + opacity: 1.0; +} + +.mx_RoomView_inCall .mx_RoomView_statusAreaBox_line { + margin-top: 2px; + border: none; + height: 0px; +} + +.mx_RoomView_inCall .mx_MessageComposer_wrapper { + border-top: 2px hidden; + padding-top: 1px; +} + +.mx_RoomView_inCall .mx_RoomView_statusAreaBox { + background-color: $accent-color; + color: $accent-fg-color; + position: relative; +} + +.mx_RoomView_voipChevron { + position: absolute; + bottom: -11px; + right: 11px; +} + +.mx_RoomView_voipButton { + float: right; + margin-right: 13px; + margin-top: 10px; + cursor: pointer; +} + +.mx_RoomView_voipButton object { + pointer-events: none; +} + +.mx_RoomView .mx_MessageComposer { + width: 100%; + flex: 0 0 auto; + margin-right: 2px; +} + +.mx_RoomView_ongoingConfCallNotification { + width: 100%; + text-align: center; + background-color: $warning-color; + color: $accent-fg-color; + font-weight: bold; + padding: 6px 0; + cursor: pointer; +} + +.mx_RoomView_ongoingConfCallNotification a { + color: $accent-fg-color ! important; +} + +.mx_MatrixChat_useCompactLayout { + .mx_RoomView_MessageList { + margin-bottom: 4px; + } + + .mx_RoomView_statusAreaBox { + min-height: 42px; + } +} diff --git a/res/css/structures/_SearchBox.scss b/res/css/structures/_SearchBox.scss new file mode 100644 index 0000000000..6f08fd47b2 --- /dev/null +++ b/res/css/structures/_SearchBox.scss @@ -0,0 +1,68 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_SearchBox { + height: 24px; + margin-left: 16px; + margin-right: 16px; + padding-top: 24px; + padding-bottom: 22px; + + border-bottom: 1px solid $panel-divider-color; + + display: flex; +} + +.mx_SearchBox_searchButton { + margin-right: 10px; + margin-top: 5px; + pointer-events: none; +} + +.mx_SearchBox_closeButton { + cursor: pointer; + margin-top: -5px; +} + +.mx_SearchBox_search { + flex: 1 1 auto; + width: 0px; + font-family: $font-family; + font-size: 12px; + margin-top: -2px; + height: 24px; + border: 0px ! important; + /* border-bottom: 1px solid rgba(0, 0, 0, 0.1) ! important; */ + border: 0px; +} + +.mx_SearchBox_minimise, +.mx_SearchBox_maximise { + margin-top: 3px; + cursor: pointer; +} + +.mx_SearchBox_minimise { + margin-left: 10px; +} + +.mx_SearchBox_maximise { + margin-left: 9px; +} + +.mx_SearchBox object { + pointer-events: none; +} diff --git a/res/css/structures/_TagPanel.scss b/res/css/structures/_TagPanel.scss new file mode 100644 index 0000000000..ab1d4feac3 --- /dev/null +++ b/res/css/structures/_TagPanel.scss @@ -0,0 +1,126 @@ +/* +Copyright 2017 New Vector Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_TagPanel { + flex: 0 0 60px; + background-color: $tertiary-accent-color; + cursor: pointer; + + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-between; +} + +.mx_TagPanel .mx_TagPanel_clearButton { + /* Constant height within flex mx_TagPanel */ + height: 70px; + width: 60px; + + flex: none; + + display: flex; + justify-content: center; + align-items: flex-start; +} + +.mx_TagPanel .mx_TagPanel_clearButton object { + /* Same as .mx_SearchBox padding-top */ + margin-top: 24px; + pointer-events: none; +} + +.mx_TagPanel .mx_TagPanel_divider { + height: 0px; + width: 42px; + border-bottom: 1px solid $panel-divider-color; +} + +.mx_TagPanel .mx_TagPanel_scroller { + flex-grow: 1; +} + +.mx_TagPanel .mx_TagPanel_tagTileContainer { + display: flex; + flex-direction: column; + align-items: center; + + height: 100%; +} + +.mx_TagPanel .mx_TagTile { + padding: 6px 3px; + opacity: 0.5; + position: relative; +} +.mx_TagPanel .mx_TagTile:focus, +.mx_TagPanel .mx_TagTile:hover, +.mx_TagPanel .mx_TagTile.mx_TagTile_selected { + opacity: 1; +} + +.mx_TagPanel .mx_TagTile.mx_TagTile_selected { + /* To offset border of mx_TagTile_avatar */ + padding: 3px 0px; +} + +.mx_TagPanel .mx_TagTile.mx_TagTile_selected .mx_TagTile_avatar .mx_BaseAvatar { + border: 3px solid $accent-color; + background-color: $accent-color; + border-radius: 60px; + + /* In case this is a "initial" avatar */ + display: block; + height: 35px; + width: 35px; +} + +.mx_TagPanel .mx_TagTile.mx_AccessibleButton:focus { + filter: none; +} + +.mx_TagTile_tooltip { + position: relative; + top: -30px; + left: 5px; +} + +.mx_TagTile_context_button { + min-width: 15px; + height: 15px; + position: absolute; + right: -5px; + top: 1px; + border-radius: 8px; + background-color: $neutral-badge-color; + color: #ffffff; + font-weight: 600; + font-size: 10px; + text-align: center; + padding-top: 1px; + padding-left: 4px; + padding-right: 4px; +} + +.mx_TagPanel_groupsButton { + margin-bottom: 17px; + margin-top: 18px; + height: 25px; +} + +.mx_TagPanel_groupsButton object { + pointer-events: none; +} diff --git a/res/css/structures/_UploadBar.scss b/res/css/structures/_UploadBar.scss new file mode 100644 index 0000000000..d76c81668c --- /dev/null +++ b/res/css/structures/_UploadBar.scss @@ -0,0 +1,61 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_UploadBar { + position: relative; +} + +.mx_UploadBar_uploadProgressOuter { + height: 5px; + margin-left: 63px; + margin-top: -1px; + padding-bottom: 5px; +} + +.mx_UploadBar_uploadProgressInner { + background-color: $accent-color; + height: 5px; +} + +.mx_UploadBar_uploadFilename { + margin-top: 5px; + margin-left: 65px; + opacity: 0.5; + color: $primary-fg-color; +} + +.mx_UploadBar_uploadIcon { + float: left; + margin-top: 5px; + margin-left: 14px; +} + +.mx_UploadBar_uploadCancel { + float: right; + margin-top: 5px; + margin-right: 10px; + position: relative; + opacity: 0.6; + cursor: pointer; + z-index: 1; +} + +.mx_UploadBar_uploadBytes { + float: right; + margin-top: 5px; + margin-right: 30px; + color: $accent-color; +} diff --git a/res/css/structures/_UserSettings.scss b/res/css/structures/_UserSettings.scss new file mode 100644 index 0000000000..4830814e4f --- /dev/null +++ b/res/css/structures/_UserSettings.scss @@ -0,0 +1,253 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd +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. +*/ + +.mx_UserSettings { + max-width: 960px; + width: 100%; + margin-left: auto; + margin-right: auto; + + display: flex; + flex-direction: column; +} + +.mx_UserSettings .mx_RoomHeader { + order: 1; + + flex: 0 0 70px; +} + +.mx_UserSettings_body { + order: 2; + + flex: 1 1 0; + + margin-top: -20px; + overflow-y: auto; +} + +.mx_UserSettings h3 { + clear: both; + margin-left: 63px; + text-transform: uppercase; + color: $h3-color; + font-weight: 600; + font-size: 13px; + margin-top: 26px; + margin-bottom: 10px; +} + +.mx_UserSettings_section h3 { + margin-left: 0px; +} + +.mx_UserSettings_spinner { + display: inline-block; + vertical-align: middle; + margin-right: 12px; + width: 32px; + height: 32px; +} + +.mx_UserSettings_button { + @mixin mx_DialogButton; + display: inline; + margin: auto; +} + +.mx_UserSettings_button:hover { + @mixin mx_DialogButton_hover; +} + +.mx_UserSettings_button.danger { + background-color: $warning-color; +} + +.mx_UserSettings_section { + margin-left: 63px; + margin-top: 28px; + margin-bottom: 28px; +} + +.mx_UserSettings_cryptoSection ul { + display: table; +} +.mx_UserSettings_cryptoSection li { + display: table-row; +} +.mx_UserSettings_cryptoSection label, +.mx_UserSettings_cryptoSection span { + display: table-cell; + padding-right: 1em; +} + +.mx_UserSettings_passwordWarning { + /* To move the "Sign out" button out of the way */ + clear: both; + color: $warning-color; + margin-bottom: 5px; +} + +.mx_UserSettings_importExportButtons { + padding-top: 10px; + padding-left: 40px; +} + +.mx_UserSettings_importExportButtons .mx_UserSettings_button { + margin-right: 1em; +} + +.mx_UserSettings_toggle input { + width: 16px; + margin-right: 8px; + margin-bottom: 8px; +} + +.mx_UserSettings_toggle label { + padding-bottom: 21px; +} + +.mx_UserSettings_accountTable +.mx_UserSettings_notifTable +{ + display: table; +} + +.mx_UserSettings_notifTable .mx_Spinner { + position: absolute; +} + +.mx_UserSettings_language { + width: 200px; +} + +.mx_UserSettings_webRtcDevices_dropdown { + width: 50%; +} + +.mx_UserSettings_profileTable +{ + display: table; + float: left; +} + +.mx_UserSettings_profileTableRow +{ + display: table-row; +} + +.mx_UserSettings_profileLabelCell +{ + padding-bottom: 21px; + display: table-cell; + font-weight: bold; + padding-right: 24px; +} + +.mx_UserSettings_profileInputCell { + display: table-cell; + padding-bottom: 21px; + width: 240px; +} + +.mx_UserSettings_profileInputCell input, +.mx_UserSettings_profileInputCell .mx_EditableText +{ + display: inline-block; + border: 0px; + border-bottom: 1px solid $input-underline-color; + padding: 0px; + width: 240px; + color: $input-fg-color; + font-family: 'Open Sans', Helvetica, Arial, Sans-Serif; + font-size: 16px; +} + +.mx_UserSettings_threepidButton { + display: table-cell; + padding-left: 0.5em; + position: relative; + cursor: pointer; +} + +.mx_UserSettings_phoneSection { + display:table; +} + +.mx_UserSettings_phoneCountry { + width: 70px; + display: table-cell; +} + +input.mx_UserSettings_phoneNumberField { + margin-left: 3px; + width: 172px; + border: 1px solid transparent; +} + +.mx_UserSettings_changePasswordButton { + float: right; + margin-right: 32px; + margin-left: 32px; +} + +.mx_UserSettings_logout { + float: right; + margin-right: 32px; + margin-left: 32px; +} + +.mx_UserSettings_avatarPicker { + margin-left: 32px; + margin-right: 32px; + float: right; + cursor: pointer; +} + +.mx_UserSettings_avatarPicker_img .mx_BaseAvatar_image { + object-fit: cover; +} + +.mx_UserSettings_avatarPicker_edit { + text-align: center; + margin-top: 10px; +} + +.mx_UserSettings_avatarPicker_edit img { + cursor: pointer; +} + +.mx_UserSettings_avatarPicker_edit > input { + display: none; +} + +.mx_UserSettings_avatarPicker_imgContainer { + display: inline-block; +} + +.mx_UserSettings_avatarPicker_remove { + display: inline-block; + float: right; + margin-right: -15px; +} + +.mx_UserSettings_advanced_spoiler, +.mx_UserSettings_link { + cursor: pointer; + color: $accent-color; + word-break: break-all; +} diff --git a/res/css/structures/_ViewSource.scss b/res/css/structures/_ViewSource.scss new file mode 100644 index 0000000000..a4c7dcf58a --- /dev/null +++ b/res/css/structures/_ViewSource.scss @@ -0,0 +1,23 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_ViewSource pre { + text-align: left; + font-size: 12px; + padding: 0.5em 1em 0.5em 1em; + word-wrap: break-word; + white-space: pre-wrap; +} diff --git a/res/css/structures/login/_Login.scss b/res/css/structures/login/_Login.scss new file mode 100644 index 0000000000..84b8306a74 --- /dev/null +++ b/res/css/structures/login/_Login.scss @@ -0,0 +1,284 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_Login { + width: 100%; + height: 100%; + + display: flex; + align-items: center; + justify-content: center; + + overflow: auto; +} + +.mx_Login h2 { + font-weight: 300; + margin-top: 32px; + margin-bottom: 20px; +} + +.mx_Login_box { + width: 300px; + min-height: 450px; + padding-top: 50px; + padding-bottom: 50px; + margin: auto; +} + +.mx_Login_logo { + text-align: center; + height: 150px; + margin-bottom: 45px; +} + +.mx_Login_logo img { + max-height: 100% +} + +.mx_Login_support { + text-align: center; + font-size: 13px; + margin-top: 0px; + opacity: 0.7; +} + +.mx_Login_field { + width: 280px; + border-radius: 3px; + border: 1px solid $strong-input-border-color; + font-weight: 300; + font-size: 13px; + padding: 9px; + margin-bottom: 14px; +} + +.mx_Login_field_disabled { + opacity: 0.3; +} + +.mx_Login_fieldLabel { + margin-top: -10px; + margin-left: 8px; + margin-bottom: 14px; + font-size: 13px; + opacity: 0.8; +} + +.mx_Login_submit { + @mixin mx_DialogButton; + width: 100%; + margin-top: 35px; + margin-bottom: 24px; +} + +.mx_Login_submit:hover { + @mixin mx_DialogButton_hover; +} + +.mx_Login_submit:disabled { + opacity: 0.3; +} + +.mx_Login_label { + font-size: 13px; + opacity: 0.8; +} + +.mx_Login_checkbox, +.mx_Login_radio { + margin-right: 10px; +} + +.mx_Login_create { + display: block; + text-align: center; + width: 100%; + font-size: 13px; + opacity: 0.8; +} + +.mx_Login_create:link { + color: $primary-fg-color; +} + +.mx_Login_links { + display: block; + text-align: center; + margin-top: 15px; + width: 100%; + font-size: 13px; + opacity: 0.8; +} + +.mx_Login_links a:link { + color: $primary-fg-color; +} + +.mx_Login_prompt { + padding-top: 15px; + padding-bottom: 15px; + font-size: 13px; +} + +.mx_Login_forgot { + font-size: 15px; +} + +.mx_Login_forgot:link { + color: $primary-fg-color; +} + +.mx_Login_loader { + display: inline; + position: relative; + top: 2px; + left: 8px; +} + +.mx_Login_loader .mx_Spinner { + display: inline; +} + +.mx_Login_loader .mx_Spinner img { + width: 16px; + height: 16px; +} + +.mx_Login_error { + color: $warning-color; + font-weight: bold; + text-align: center; +/* + height: 24px; +*/ + margin-top: 12px; + margin-bottom: 12px; +} + +.mx_Login_type_container { + display: flex; + margin-bottom: 14px; +} + +.mx_Login_type_label { + flex-grow: 1; + line-height: 35px; +} + +.mx_Login_type_dropdown { + display: inline-block; + min-width: 170px; + align-self: flex-end; + flex: 1 1 auto; +} + +.mx_Login_field_group { + display: flex; +} + +.mx_Login_field_prefix { + height: 34px; + padding: 0px 5px; + line-height: 33px; + + background-color: #eee; + border: 1px solid #c7c7c7; + border-right: 0px; + border-radius: 3px 0px 0px 3px; + + text-align: center; +} + +.mx_Login_field_suffix { + height: 34px; + padding: 0px 5px; + line-height: 33px; + + background-color: #eee; + border: 1px solid #c7c7c7; + border-left: 0px; + border-radius: 0px 3px 3px 0px; + + text-align: center; + flex-grow: 1; +} + +.mx_Login_username { + height: 16px; + flex-shrink: 1; + min-width: 0px; +} + +.mx_Login_phoneNumberField { + height: 16px; +} + +.mx_Login_field_has_prefix { + border-top-left-radius: 0px; + border-bottom-left-radius: 0px; +} + +.mx_Login_field_has_suffix { + border-top-right-radius: 0px; + border-bottom-right-radius: 0px; +} + +.mx_Login_phoneSection { + display:flex; +} + +.mx_Login_phoneCountry { + margin-bottom: 14px; + width: 150px; + + /* To override mx_Login_field_prefix */ + text-align: left; + padding: 0px; + background-color: $primary-bg-color; +} + +.mx_Login_field_prefix .mx_Dropdown_input { + /* To use prefix border instead of dropdown border */ + border: 0; +} + +.mx_Login_phoneCountry .mx_Dropdown_option { + /* + To match height of mx_Login_field + 33px + 2px border from mx_Dropdown_option = 35px + */ + height: 33px; + line-height: 33px; +} + +.mx_Login_phoneCountry .mx_Dropdown_option img { + margin: 3px; + vertical-align: top; +} + +.mx_Login_language { + margin-left: auto; + margin-right: auto; + min-width: 60%; +} + +.mx_Login_language_div { + display: flex; + margin-top: 12px; + margin-bottom: 12px; +} + diff --git a/res/css/views/avatars/_BaseAvatar.scss b/res/css/views/avatars/_BaseAvatar.scss new file mode 100644 index 0000000000..ee2d9c190f --- /dev/null +++ b/res/css/views/avatars/_BaseAvatar.scss @@ -0,0 +1,35 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_BaseAvatar { + position: relative; +} + +.mx_BaseAvatar_initial { + position: absolute; + left: 0px; + color: $avatar-initial-color; + text-align: center; + speak: none; + pointer-events: none; + font-weight: normal; +} + +.mx_BaseAvatar_image { + border-radius: 40px; + vertical-align: top; + background-color: $avatar-bg-color; +} diff --git a/res/css/views/avatars/_MemberPresenceAvatar.scss b/res/css/views/avatars/_MemberPresenceAvatar.scss new file mode 100644 index 0000000000..a15f8eaa65 --- /dev/null +++ b/res/css/views/avatars/_MemberPresenceAvatar.scss @@ -0,0 +1,43 @@ +/* +Copyright 2017 Travis Ralston + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_MemberPresenceAvatar { + display: inline-block; + position: relative; +} + +.mx_MemberPresenceAvatar_status { + display: block; + width: 10px; + height: 10px; + border-radius: 10px; + + position: absolute; + bottom: -2px; + right: -3px; +} + +.mx_MemberPresenceAvatar_status_online { + background-color: $presence-online; +} + +.mx_MemberPresenceAvatar_status_unavailable { + background-color: $presence-unavailable; +} + +.mx_MemberPresenceAvatar_status_offline { + background-color: $presence-offline; +} diff --git a/res/css/views/context_menus/_MessageContextMenu.scss b/res/css/views/context_menus/_MessageContextMenu.scss new file mode 100644 index 0000000000..85e8080c88 --- /dev/null +++ b/res/css/views/context_menus/_MessageContextMenu.scss @@ -0,0 +1,25 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_MessageContextMenu_field { + padding: 3px 6px 3px 6px; + cursor: pointer; + white-space: nowrap; +} + +.mx_MessageContextMenu_field.mx_MessageContextMenu_fieldSet { + font-weight: bold; +} diff --git a/res/css/views/context_menus/_PresenceContextMenuOption.scss b/res/css/views/context_menus/_PresenceContextMenuOption.scss new file mode 100644 index 0000000000..bfe81125e0 --- /dev/null +++ b/res/css/views/context_menus/_PresenceContextMenuOption.scss @@ -0,0 +1,42 @@ +/* +Copyright 2017 Travis Ralston + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +.mx_PresenceContextMenuOption_indicator { + width: 10px; + height: 10px; + border-radius: 10px; + display: inline-block; + margin-right: 5px; +} + +.mx_PresenceContextMenuOption_indicator.mx_PresenceContextMenuOption_indicator_online { + background-color: $presence-online; +} + +.mx_PresenceContextMenuOption_indicator.mx_PresenceContextMenuOption_indicator_unavailable { + background-color: $presence-unavailable; +} + +.mx_PresenceContextMenuOption_indicator.mx_PresenceContextMenuOption_indicator_offline { + background-color: $presence-offline; +} + +.mx_PresenceContextMenuOption { + padding: 2px; +} + +.mx_PresenceContextMenuOption.mx_PresenceContextMenuOption_current { + font-weight: 700; +} diff --git a/res/css/views/context_menus/_RoomTileContextMenu.scss b/res/css/views/context_menus/_RoomTileContextMenu.scss new file mode 100644 index 0000000000..598f8ac249 --- /dev/null +++ b/res/css/views/context_menus/_RoomTileContextMenu.scss @@ -0,0 +1,114 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_RoomTileContextMenu_tag_field, .mx_RoomTileContextMenu_leave { + padding-top: 8px; + padding-right: 20px; + padding-bottom: 8px; + cursor: pointer; + white-space: nowrap; + display: flex; + align-items: center; + line-height: 16px; +} + +.mx_RoomTileContextMenu_tag_field.mx_RoomTileContextMenu_tag_fieldSet { + font-weight: bold; +} + +.mx_RoomTileContextMenu_tag_field.mx_RoomTileContextMenu_tag_fieldSet .mx_RoomTileContextMenu_tag_icon { + display: none; +} + +.mx_RoomTileContextMenu_tag_field.mx_RoomTileContextMenu_tag_fieldSet .mx_RoomTileContextMenu_tag_icon_set { + display: inline-block; +} + +.mx_RoomTileContextMenu_tag_field.mx_RoomTileContextMenu_tag_fieldDisabled { + color: rgba(0, 0, 0, 0.2); +} + +.mx_RoomTileContextMenu_tag_icon { + padding-right: 8px; + padding-left: 4px; + display: inline-block +} + +.mx_RoomTileContextMenu_tag_icon_set { + padding-right: 8px; + padding-left: 4px; + display: none; +} + +.mx_RoomTileContextMenu_separator { + margin-top: 0; + margin-bottom: 0; + border-bottom-style: none; + border-left-style: none; + border-right-style: none; + border-top-style: solid; + border-top-width: 1px; + border-color: $menu-border-color; +} + +.mx_RoomTileContextMenu_leave { + color: $warning-color; +} + +.mx_RoomTileContextMenu_tag_fieldSet .mx_RoomTileContextMenu_tag_icon { + /* Something to indicate that the icon is the set tag */ +} + +.mx_RoomTileContextMenu_notif_picker { + position: absolute; + top: 16px; + left: 5px; +} + +.mx_RoomTileContextMenu_notif_field { + padding-top: 4px; + padding-right: 6px; + padding-bottom: 10px; + padding-left: 8px; /* 20px */ + cursor: pointer; + white-space: nowrap; + display: flex; + align-items: center; +} + +.mx_RoomTileContextMenu_notif_field.mx_RoomTileContextMenu_notif_fieldSet { + font-weight: bold; +} + +.mx_RoomTileContextMenu_notif_field.mx_RoomTileContextMenu_notif_fieldDisabled { + color: rgba(0, 0, 0, 0.2); +} + +.mx_RoomTileContextMenu_notif_icon { + padding-right: 4px; + padding-left: 4px; +} + +.mx_RoomTileContextMenu_notif_activeIcon { + display: inline-block; + opacity: 0; + position: relative; + left: -5px; +} + +.mx_RoomTileContextMenu_notif_fieldSet .mx_RoomTileContextMenu_notif_activeIcon { + opacity: 1; +} diff --git a/res/css/views/context_menus/_TagTileContextMenu.scss b/res/css/views/context_menus/_TagTileContextMenu.scss new file mode 100644 index 0000000000..759b92bd68 --- /dev/null +++ b/res/css/views/context_menus/_TagTileContextMenu.scss @@ -0,0 +1,44 @@ +/* +Copyright 2018 New Vector Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_TagTileContextMenu_item { + padding-top: 8px; + padding-right: 20px; + padding-bottom: 8px; + cursor: pointer; + white-space: nowrap; + display: flex; + align-items: center; + line-height: 16px; +} + + +.mx_TagTileContextMenu_item_icon { + padding-right: 8px; + padding-left: 4px; + display: inline-block +} + +.mx_TagTileContextMenu_separator { + margin-top: 0; + margin-bottom: 0; + border-bottom-style: none; + border-left-style: none; + border-right-style: none; + border-top-style: solid; + border-top-width: 1px; + border-color: $menu-border-color; +} diff --git a/res/css/views/dialogs/_BugReportDialog.scss b/res/css/views/dialogs/_BugReportDialog.scss new file mode 100644 index 0000000000..e00d446eda --- /dev/null +++ b/res/css/views/dialogs/_BugReportDialog.scss @@ -0,0 +1,52 @@ +/* +Copyright 2017 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_BugReportDialog_field_container { + display: flex; +} + +.mx_BugReportDialog_field_label { + flex-basis: 150px; + + text-align: right; + + padding-top: 9px; + padding-right: 4px; + + line-height: 18px; +} + +.mx_BugReportDialog_field_input { + flex-grow: 1; + + /* taken from mx_ChatInviteDialog_inputContainer */ + border-radius: 3px; + border: solid 1px $input-border-color; + + font-size: 14px; + + padding-left: 4px; + padding-right: 4px; + padding-top: 7px; + padding-bottom: 7px; + + margin-bottom: 4px; +} + +.mx_BugReportDialog_field_input[type="text" i] { + padding-top: 9px; + padding-bottom: 9px; +} diff --git a/res/css/views/dialogs/_ChangelogDialog.scss b/res/css/views/dialogs/_ChangelogDialog.scss new file mode 100644 index 0000000000..460a5f94b1 --- /dev/null +++ b/res/css/views/dialogs/_ChangelogDialog.scss @@ -0,0 +1,24 @@ +/* +Copyright 2016 Aviral Dasgupta + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_ChangelogDialog_content { + max-height: 300px; + overflow: auto; +} + +.mx_ChangelogDialog_li { + padding: 0.2em; +} diff --git a/res/css/views/dialogs/_ChatCreateOrReuseChatDialog.scss b/res/css/views/dialogs/_ChatCreateOrReuseChatDialog.scss new file mode 100644 index 0000000000..0f358a588e --- /dev/null +++ b/res/css/views/dialogs/_ChatCreateOrReuseChatDialog.scss @@ -0,0 +1,41 @@ +/* +Copyright 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_ChatCreateOrReuseDialog .mx_ChatCreateOrReuseDialog_tiles { + margin-top: 24px; +} + +.mx_ChatCreateOrReuseDialog .mx_Dialog_content { + margin-bottom: 24px; + + /* + To stop spinner that mx_ChatCreateOrReuseDialog_profile replaces from causing a + height change + */ + min-height: 100px; +} + +.mx_ChatCreateOrReuseDialog .mx_RoomTile_badge { + display: none; +} + +.mx_ChatCreateOrReuseDialog_profile { + display: flex; +} + +.mx_ChatCreateOrReuseDialog_profile_name { + padding: 14px; +} diff --git a/res/css/views/dialogs/_ChatInviteDialog.scss b/res/css/views/dialogs/_ChatInviteDialog.scss new file mode 100644 index 0000000000..6fc211743d --- /dev/null +++ b/res/css/views/dialogs/_ChatInviteDialog.scss @@ -0,0 +1,77 @@ +/* +Copyright 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_ChatInviteDialog { + /* XXX: padding-left is on mx_Dialog but padding-right has subsequently + * been added on other dialogs. Surely all our dialogs should have consistent + * right hand padding? + */ + padding-right: 58px; +} + +/* Using a textarea for this element, to circumvent autofill */ +.mx_ChatInviteDialog_input, +.mx_ChatInviteDialog_input:focus +{ + height: 26px; + font-size: 14px; + font-family: $font-family; + padding-left: 12px; + padding-right: 12px; + margin: 0 !important; + border: 0 !important; + outline: 0 !important; + width: 1000%; /* Pretend that this is an "input type=text" */ + resize: none; + overflow: hidden; + vertical-align: middle; + box-sizing: border-box; + word-wrap: nowrap; +} + +.mx_ChatInviteDialog .mx_Dialog_content { + min-height: 50px +} + +.mx_ChatInviteDialog_inputContainer { + border-radius: 3px; + border: solid 1px $input-border-color; + line-height: 36px; + padding-left: 4px; + padding-right: 4px; + padding-top: 1px; + padding-bottom: 1px; + max-height: 150px; + overflow-x: hidden; + overflow-y: auto; +} + +.mx_ChatInviteDialog_error { + margin-top: 10px; + color: $warning-color; +} + +.mx_ChatInviteDialog_cancel { + position: absolute; + right: 11px; + top: 13px; + cursor: pointer; +} + +.mx_ChatInviteDialog_cancel object { + pointer-events: none; +} + diff --git a/res/css/views/dialogs/_ConfirmUserActionDialog.scss b/res/css/views/dialogs/_ConfirmUserActionDialog.scss new file mode 100644 index 0000000000..b859d6bf4d --- /dev/null +++ b/res/css/views/dialogs/_ConfirmUserActionDialog.scss @@ -0,0 +1,53 @@ +/* +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. +*/ + +.mx_ConfirmUserActionDialog .mx_Dialog_content { + min-height: 48px; + margin-bottom: 24px; +} + +.mx_ConfirmUserActionDialog_avatar { + float: left; + margin-right: 20px; + margin-top: -2px; +} + +.mx_ConfirmUserActionDialog_name { + font-size: 18px; +} + +.mx_ConfirmUserActionDialog_userId { + font-size: 13px; +} + +.mx_ConfirmUserActionDialog_reasonField { + font-family: $font-family; + font-size: 14px; + color: $primary-fg-color; + background-color: $primary-bg-color; + + border-radius: 3px; + border: solid 1px $input-border-color; + line-height: 36px; + padding-left: 16px; + padding-right: 16px; + padding-top: 1px; + padding-bottom: 1px; + + margin-bottom: 24px; + + width: 90%; +} diff --git a/res/css/views/dialogs/_CreateGroupDialog.scss b/res/css/views/dialogs/_CreateGroupDialog.scss new file mode 100644 index 0000000000..500e12ee49 --- /dev/null +++ b/res/css/views/dialogs/_CreateGroupDialog.scss @@ -0,0 +1,62 @@ +/* +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. +*/ + +.mx_CreateGroupDialog_inputRow { + margin-top: 10px; + margin-bottom: 10px; +} + +.mx_CreateGroupDialog_label { + text-align: left; + padding-bottom: 12px; +} + +.mx_CreateGroupDialog_input { + font-size: 15px; + border-radius: 3px; + border: 1px solid $input-border-color; + padding: 9px; + color: $primary-fg-color; + background-color: $primary-bg-color; +} + +.mx_CreateGroupDialog_input_hasPrefixAndSuffix { + border-radius: 0px; +} + +.mx_CreateGroupDialog_input_group { + display: flex; +} + +.mx_CreateGroupDialog_prefix, +.mx_CreateGroupDialog_suffix { + height: 35px; + padding: 0px 5px; + line-height: 37px; + background-color: $input-border-color; + border: 1px solid $input-border-color; + text-align: center; +} + +.mx_CreateGroupDialog_prefix { + border-right: 0px; + border-radius: 3px 0px 0px 3px; +} + +.mx_CreateGroupDialog_suffix { + border-left: 0px; + border-radius: 0px 3px 3px 0px; +} diff --git a/res/css/views/dialogs/_CreateRoomDialog.scss b/res/css/views/dialogs/_CreateRoomDialog.scss new file mode 100644 index 0000000000..888f147d21 --- /dev/null +++ b/res/css/views/dialogs/_CreateRoomDialog.scss @@ -0,0 +1,33 @@ +/* +Copyright 2017 Michael Telatynski <7t3chguy@gmail.com> + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_CreateRoomDialog_details_summary { + outline: none; +} + +.mx_CreateRoomDialog_label { + text-align: left; + padding-bottom: 12px; +} + +.mx_CreateRoomDialog_input { + font-size: 15px; + border-radius: 3px; + border: 1px solid $input-border-color; + padding: 9px; + color: $primary-fg-color; + background-color: $primary-bg-color; +} diff --git a/res/css/views/dialogs/_DevtoolsDialog.scss b/res/css/views/dialogs/_DevtoolsDialog.scss new file mode 100644 index 0000000000..8918373ecf --- /dev/null +++ b/res/css/views/dialogs/_DevtoolsDialog.scss @@ -0,0 +1,166 @@ +/* +Copyright 2017 Michael Telatynski <7t3chguy@gmail.com> + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_DevTools_RoomStateExplorer_button, .mx_DevTools_RoomStateExplorer_query { + margin-bottom: 10px; +} + +.mx_DevTools_label_left { + float: left; +} + +.mx_DevTools_label_right { + float: right; +} + +.mx_DevTools_label_bottom { + clear: both; + border-bottom: 1px solid #e5e5e5; +} + +.mx_DevTools_inputRow +{ + display: table-row; +} + +.mx_DevTools_inputLabelCell +{ + padding-bottom: 21px; + display: table-cell; + font-weight: bold; + padding-right: 24px; +} + +.mx_DevTools_inputCell { + display: table-cell; + padding-bottom: 21px; + width: 240px; +} + +.mx_DevTools_inputCell input +{ + display: inline-block; + border: 0; + border-bottom: 1px solid $input-underline-color; + padding: 0; + width: 240px; + color: $input-fg-color; + font-family: 'Open Sans', Helvetica, Arial, Sans-Serif; + font-size: 16px; +} + +.mx_DevTools_tgl { + display: none; + + // add default box-sizing for this scope + &, + &:after, + &:before, + & *, + & *:after, + & *:before, + & + .mx_DevTools_tgl-btn { + box-sizing: border-box; + &::selection { + background: none; + } + } + + + .mx_DevTools_tgl-btn { + outline: 0; + display: block; + width: 7em; + height: 2em; + position: relative; + cursor: pointer; + user-select: none; + &:after, + &:before { + position: relative; + display: block; + content: ""; + width: 50%; + height: 100%; + } + + &:after { + left: 0; + } + + &:before { + display: none; + } + } + + &:checked + .mx_DevTools_tgl-btn:after { + left: 50%; + } +} + +.mx_DevTools_tgl-flip { + + .mx_DevTools_tgl-btn { + padding: 2px; + transition: all .2s ease; + font-family: sans-serif; + perspective: 100px; + &:after, + &:before { + display: inline-block; + transition: all .4s ease; + width: 100%; + text-align: center; + position: absolute; + line-height: 2em; + font-weight: bold; + color: #fff; + top: 0; + left: 0; + backface-visibility: hidden; + border-radius: 4px; + } + + &:after { + content: attr(data-tg-on); + background: #02C66F; + transform: rotateY(-180deg); + } + + &:before { + background: #FF3A19; + content: attr(data-tg-off); + } + + &:active:before { + transform: rotateY(-20deg); + } + } + + &:checked + .mx_DevTools_tgl-btn { + &:before { + transform: rotateY(180deg); + } + + &:after { + transform: rotateY(0); + left: 0; + background: #7FC6A6; + } + + &:active:after { + transform: rotateY(20deg); + } + } +} diff --git a/res/css/views/dialogs/_EncryptedEventDialog.scss b/res/css/views/dialogs/_EncryptedEventDialog.scss new file mode 100644 index 0000000000..b4dd353370 --- /dev/null +++ b/res/css/views/dialogs/_EncryptedEventDialog.scss @@ -0,0 +1,27 @@ +/* +Copyright 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_EncryptedEventDialog .mx_MemberDeviceInfo { + float: right; + padding: 0px; + margin-right: 42px; +} + +.mx_EncryptedEventDialog .mx_MemberDeviceInfo_textButton { + @mixin mx_DialogButton; + background-color: $primary-bg-color; + color: $accent-color; +} \ No newline at end of file diff --git a/res/css/views/dialogs/_GroupAddressPicker.scss b/res/css/views/dialogs/_GroupAddressPicker.scss new file mode 100644 index 0000000000..d6c961c0ec --- /dev/null +++ b/res/css/views/dialogs/_GroupAddressPicker.scss @@ -0,0 +1,25 @@ +/* +Copyright 2017 New Vector Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_GroupAddressPicker_checkboxContainer{ + margin-top: 10px; + display: flex; +} + +.mx_GroupAddressPicker_checkboxContainer input[type="checkbox"] { + /* Stop flex from shrinking the checkbox */ + width: 20px; +} diff --git a/res/css/views/dialogs/_QuestionDialog.scss b/res/css/views/dialogs/_QuestionDialog.scss new file mode 100644 index 0000000000..3d47f17592 --- /dev/null +++ b/res/css/views/dialogs/_QuestionDialog.scss @@ -0,0 +1,18 @@ +/* +Copyright 2017 New Vector Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +.mx_QuestionDialog { + padding-right: 58px; +} diff --git a/res/css/views/dialogs/_SetEmailDialog.scss b/res/css/views/dialogs/_SetEmailDialog.scss new file mode 100644 index 0000000000..588f10c9cb --- /dev/null +++ b/res/css/views/dialogs/_SetEmailDialog.scss @@ -0,0 +1,36 @@ +/* +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. +*/ + +.mx_SetEmailDialog_email_input { + border-radius: 3px; + border: 1px solid $input-border-color; + padding: 9px; + color: $input-fg-color; + background-color: $primary-bg-color; + font-size: 15px; + width: 100%; + max-width: 280px; + margin-bottom: 10px; +} + +.mx_SetEmailDialog_email_input:focus { + outline: none; + box-shadow: none; + border: 1px solid $accent-color; +} + +.mx_SetEmailDialog_email_input_placeholder { +} diff --git a/res/css/views/dialogs/_SetMxIdDialog.scss b/res/css/views/dialogs/_SetMxIdDialog.scss new file mode 100644 index 0000000000..f7d8a3d001 --- /dev/null +++ b/res/css/views/dialogs/_SetMxIdDialog.scss @@ -0,0 +1,50 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd +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. +*/ + +.mx_SetMxIdDialog .mx_Dialog_title { + padding-right: 40px; +} + +.mx_SetMxIdDialog_input_group { + display: flex; +} + +.mx_SetMxIdDialog_input { + border-radius: 3px; + border: 1px solid $input-border-color; + padding: 9px; + color: $primary-fg-color; + background-color: $primary-bg-color; + font-size: 15px; + width: 100%; + max-width: 280px; +} + +.mx_SetMxIdDialog_input.error, +.mx_SetMxIdDialog_input.error:focus { + border: 1px solid $warning-color; +} + +.mx_SetMxIdDialog_input_group .mx_Spinner { + height: 37px; + padding-left: 10px; + justify-content: flex-start; +} + +.mx_SetMxIdDialog .success { + color: $accent-color; +} diff --git a/res/css/views/dialogs/_SetPasswordDialog.scss b/res/css/views/dialogs/_SetPasswordDialog.scss new file mode 100644 index 0000000000..28a8b7c9d7 --- /dev/null +++ b/res/css/views/dialogs/_SetPasswordDialog.scss @@ -0,0 +1,35 @@ +/* +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. +*/ + +.mx_SetPasswordDialog_change_password input { + border-radius: 3px; + border: 1px solid $input-border-color; + padding: 9px; + color: $primary-fg-color; + background-color: $primary-bg-color; + font-size: 15px; + width: 100%; + max-width: 280px; + margin-bottom: 10px; +} + +.mx_SetPasswordDialog_change_password_button { + margin-top: 68px; +} + +.mx_SetPasswordDialog .mx_Dialog_content { + margin-bottom: 0px; +} diff --git a/res/css/views/dialogs/_UnknownDeviceDialog.scss b/res/css/views/dialogs/_UnknownDeviceDialog.scss new file mode 100644 index 0000000000..3457e50b92 --- /dev/null +++ b/res/css/views/dialogs/_UnknownDeviceDialog.scss @@ -0,0 +1,54 @@ +/* +Copyright 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// CSS voodoo to support a gemini-scrollbar for the contents of the dialog +.mx_Dialog_unknownDevice .mx_Dialog { + // ideally we'd shrink the height to fit when needed, but in practice this + // is a pain in the ass. plus might as well make the dialog big given how + // important it is. + height: 100%; + + // position the gemini scrollbar nicely + padding-right: 58px; +} + +.mx_UnknownDeviceDialog { + height: 100%; + display: flex; + flex-direction: column; +} + +.mx_UnknownDeviceDialog .mx_Dialog_content { + margin-bottom: 24px; +} + +.mx_UnknownDeviceDialog .mx_MemberDeviceInfo { + float: right; + clear: both; + padding: 0px; + padding-top: 8px; +} + +.mx_UnknownDeviceDialog .mx_MemberDeviceInfo_textButton { + @mixin mx_DialogButton_small; + background-color: $primary-bg-color; + color: $accent-color; +} + +.mx_UnknownDeviceDialog .mx_UnknownDeviceDialog_deviceList li { + height: 40px; + border-bottom: 1px solid $primary-hairline-color; +} \ No newline at end of file diff --git a/res/css/views/directory/_NetworkDropdown.scss b/res/css/views/directory/_NetworkDropdown.scss new file mode 100644 index 0000000000..9850379597 --- /dev/null +++ b/res/css/views/directory/_NetworkDropdown.scss @@ -0,0 +1,84 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_NetworkDropdown { + position: relative; +} + +.mx_NetworkDropdown_input { + position: relative; + border-radius: 3px; + border: 1px solid $strong-input-border-color; + font-weight: 300; + font-size: 13px; + user-select: none; +} + +.mx_NetworkDropdown_arrow { + border-color: $primary-fg-color transparent transparent; + border-style: solid; + border-width: 5px 5px 0; + display: block; + height: 0; + position: absolute; + right: 10px; + top: 14px; + width: 0 +} + +.mx_NetworkDropdown_networkoption { + height: 35px; + line-height: 35px; + padding-left: 8px; + padding-right: 8px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +.mx_NetworkDropdown_networkoption img { + margin: 5px; + width: 25px; + vertical-align: middle; +} + +input.mx_NetworkDropdown_networkoption, input.mx_NetworkDropdown_networkoption:focus { + border: 0; + padding-top: 0; + padding-bottom: 0; +} + +.mx_NetworkDropdown_menu { + position: absolute; + left: -1px; + right: -1px; + top: 100%; + z-index: 2; + margin: 0; + padding: 0px; + border-radius: 3px; + border: 1px solid $accent-color; + background-color: $primary-bg-color; +} + +.mx_NetworkDropdown_menu .mx_NetworkDropdown_networkoption:hover { + background-color: $focus-bg-color; +} + +.mx_NetworkDropdown_menu_network { + font-weight: bold; +} + diff --git a/res/css/views/elements/_AccessibleButton.scss b/res/css/views/elements/_AccessibleButton.scss new file mode 100644 index 0000000000..edf455049b --- /dev/null +++ b/res/css/views/elements/_AccessibleButton.scss @@ -0,0 +1,24 @@ +/* +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. +*/ + +.mx_AccessibleButton:focus { + outline: 0; + filter: brightness($focus-brightness); +} + +.mx_AccessibleButton { + cursor: pointer; +} \ No newline at end of file diff --git a/res/css/views/elements/_AddressSelector.scss b/res/css/views/elements/_AddressSelector.scss new file mode 100644 index 0000000000..9871a7e881 --- /dev/null +++ b/res/css/views/elements/_AddressSelector.scss @@ -0,0 +1,45 @@ +/* +Copyright 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_AddressSelector { + position: absolute; + background-color: $primary-bg-color; + width: 485px; + max-height: 116px; + overflow-y: auto; + border-radius: 3px; + background-color: $primary-bg-color; + border: solid 1px $accent-color; + cursor: pointer; +} + +.mx_AddressSelector.mx_AddressSelector_empty { + display: none; +} + +.mx_AddressSelector_addressListElement .mx_AddressTile { + background-color: $primary-bg-color; + border: solid 1px $primary-bg-color; +} + +.mx_AddressSelector_addressListElement.mx_AddressSelector_selected { + background-color: $selected-color; +} + +.mx_AddressSelector_addressListElement.mx_AddressSelector_selected .mx_AddressTile { + background-color: $selected-color; + border: solid 1px $selected-color; +} diff --git a/res/css/views/elements/_AddressTile.scss b/res/css/views/elements/_AddressTile.scss new file mode 100644 index 0000000000..0ecfb17c83 --- /dev/null +++ b/res/css/views/elements/_AddressTile.scss @@ -0,0 +1,138 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_AddressTile { + display: inline-block; + border-radius: 3px; + background-color: rgba(74, 73, 74, 0.1); + border: solid 1px $input-border-color; + line-height: 26px; + color: $primary-fg-color; + font-size: 14px; + font-weight: normal; + margin-right: 4px; +} + +.mx_AddressTile.mx_AddressTile_error { + background-color: rgba(255, 0, 100, 0.1); + color: $warning-color; + border-color: $warning-color; +} + +.mx_AddressTile_network { + display: inline-block; + position: relative; + padding-left: 2px; + padding-right: 4px; + vertical-align: middle; +} + +.mx_AddressTile_avatar { + display: inline-block; + position: relative; + padding-left: 2px; + padding-right: 7px; + vertical-align: middle; +} + +.mx_AddressTile_mx { + display: inline-block; + margin: 0; + border: 0; + padding: 0; +} + +.mx_AddressTile_name { + display: inline-block; + padding-right: 4px; + font-weight: 600; + overflow: hidden; + height: 26px; + vertical-align: middle; +} + +.mx_AddressTile_name.mx_AddressTile_justified { + width: 180px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + vertical-align: middle; +} + +.mx_AddressTile_id { + display: inline-block; + padding-right: 11px; +} + +.mx_AddressTile_id.mx_AddressTile_justified { + width: 200px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + vertical-align: middle; +} + +.mx_AddressTile_unknownMx { + display: inline-block; + font-weight: 600; + padding-right: 11px; +} + +.mx_AddressTile_unknownMxl.mx_AddressTile_justified { + width: 380px; /* name + id width */ + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + vertical-align: middle; +} + +.mx_AddressTile_email { + display: inline-block; + font-weight: 600; + padding-right: 11px; +} + +.mx_AddressTile_email.mx_AddressTile_justified { + width: 200px; /* same as id width */ + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + vertical-align: middle; +} + +.mx_AddressTile_unknown { + display: inline-block; + padding-right: 11px; +} + +.mx_AddressTile_unknown.mx_AddressTile_justified { + width: 380px; /* name + id width */ + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + vertical-align: middle; +} + +.mx_AddressTile_dismiss { + display: inline-block; + padding-right: 11px; + padding-left: 1px; + cursor: pointer; +} + +.mx_AddressTile_dismiss object { + pointer-events: none; +} diff --git a/res/css/views/elements/_DirectorySearchBox.scss b/res/css/views/elements/_DirectorySearchBox.scss new file mode 100644 index 0000000000..94a92b23ce --- /dev/null +++ b/res/css/views/elements/_DirectorySearchBox.scss @@ -0,0 +1,70 @@ +/* +Copyright 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_DirectorySearchBox { + position: relative; + border-radius: 3px; + border: 1px solid $strong-input-border-color; +} + +.mx_DirectorySearchBox_container { + display: flex; + padding-left: 9px; + padding-right: 9px; +} + +.mx_DirectorySearchBox_input { + flex-grow: 1; + border: 0; + padding: 0; + font-weight: 300; + font-size: 13px; +} +input[type=text].mx_DirectorySearchBox_input:focus { + border: 0; +} + +.mx_DirectorySearchBox_joinButton { + display: table-cell; + padding: 3px; + padding-left: 10px; + padding-right: 10px; + background-color: $plinth-bg-color; + border-radius: 3px; + background-image: url('../../img/icon-return.svg'); + background-position: 8px 70%; + background-repeat: no-repeat; + text-indent: 18px; + font-weight: 600; + font-size: 12px; + user-select: none; + cursor: pointer; +} + +.mx_DirectorySearchBox_clear_wrapper { + display: table-cell; +} + +.mx_DirectorySearchBox_clear { + display: inline-block; + vertical-align: middle; + background: url('../../img/icon_context_delete.svg'); + background-position: 0 50%; + background-repeat: no-repeat; + width: 15px; + height: 15px; + cursor: pointer; +} diff --git a/res/css/views/elements/_Dropdown.scss b/res/css/views/elements/_Dropdown.scss new file mode 100644 index 0000000000..69dd1703ee --- /dev/null +++ b/res/css/views/elements/_Dropdown.scss @@ -0,0 +1,131 @@ +/* +Copyright 2017 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_Dropdown { + position: relative; +} + +.mx_Dropdown_disabled { + opacity: 0.3; +} + +.mx_Dropdown_input { + position: relative; + border-radius: 3px; + border: 1px solid $strong-input-border-color; + font-weight: 300; + font-size: 13px; + user-select: none; +} + +.mx_Dropdown_input:focus { + border-color: $accent-color; +} + +/* Disable dropdown highlight on focus */ +.mx_Dropdown_input.mx_AccessibleButton:focus { + filter: none; +} + +.mx_Dropdown_arrow { + border-color: $primary-fg-color transparent transparent; + border-style: solid; + border-width: 5px 5px 0; + display: block; + height: 0; + position: absolute; + right: 10px; + top: 14px; + width: 0 +} + +.mx_Dropdown.left_aligned .mx_Dropdown_arrow { + left: 10px; +} + +.mx_Dropdown_input > .mx_Dropdown_option { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.mx_Dropdown.left_aligned .mx_Dropdown_input > .mx_Dropdown_option { + padding-left: 25px; +} + +.mx_Dropdown_option { + height: 35px; + line-height: 35px; + padding-left: 8px; + padding-right: 8px; +} + +.mx_Dropdown_option div { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.mx_Dropdown_option img { + margin: 5px; + width: 27px; + vertical-align: middle; +} + +input.mx_Dropdown_option, input.mx_Dropdown_option:focus { + border: 0; + padding-top: 0; + padding-bottom: 0; + // XXX: hack to prevent text box being too big and pushing + // its parent out / overlapping the dropdown arrow. Only really + // works in the Country dropdown. + width: 60%; +} + +.mx_Dropdown_menu { + position: absolute; + left: -1px; + right: -1px; + top: 100%; + z-index: 2; + margin: 0; + padding: 0px; + border-radius: 3px; + border: 1px solid $accent-color; + background-color: $primary-bg-color; + max-height: 200px; + overflow-y: auto; +} + +.mx_Dropdown_menu .mx_Dropdown_option { + height: auto; + min-height: 35px; +} + +.mx_Dropdown_menu .mx_Dropdown_option_highlight { + background-color: $focus-bg-color; +} + +.mx_Dropdown_menu { + font-weight: bold; +} + +.mx_Dropdown_searchPrompt { + font-weight: normal; + margin-left: 5px; + margin-bottom: 5px; +} + diff --git a/res/css/views/elements/_EditableItemList.scss b/res/css/views/elements/_EditableItemList.scss new file mode 100644 index 0000000000..9fbb39aa17 --- /dev/null +++ b/res/css/views/elements/_EditableItemList.scss @@ -0,0 +1,62 @@ +/* +Copyright 2017 New Vector Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_EditableItemList { + margin-top: 12px; + margin-bottom: 0px; +} + +.mx_EditableItem { + display: flex; + margin-left: 56px; +} + +.mx_EditableItem .mx_EditableItem_editable { + border: 0px; + border-bottom: 1px solid $strong-input-border-color; + padding: 0px; + min-width: 240px; + max-width: 400px; + margin-bottom: 16px; +} + +.mx_EditableItem .mx_EditableItem_editable:focus { + border-bottom: 1px solid $accent-color; + outline: none; + box-shadow: none; +} + +.mx_EditableItem .mx_EditableItem_editablePlaceholder { + color: $settings-grey-fg-color; +} + +.mx_EditableItem .mx_EditableItem_addButton, +.mx_EditableItem .mx_EditableItem_removeButton { + padding-left: 0.5em; + position: relative; + cursor: pointer; + + visibility: hidden; +} + +.mx_EditableItem:hover .mx_EditableItem_addButton, +.mx_EditableItem:hover .mx_EditableItem_removeButton { + visibility: visible; +} + +.mx_EditableItemList_label { + margin-bottom: 8px; +} diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss new file mode 100644 index 0000000000..8ed0698a72 --- /dev/null +++ b/res/css/views/elements/_ImageView.scss @@ -0,0 +1,134 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* This has got to be the most fragile piece of CSS ever written. + But empirically it works on Chrome/FF/Safari + */ + +.mx_ImageView { + display: flex; + width: 100%; + height: 100%; + align-items: center; +} + +.mx_ImageView_lhs { + order: 1; + flex: 1 1 10%; + min-width: 60px; + // background-color: #080; + // height: 20px; +} + +.mx_ImageView_content { + order: 2; + /* min-width hack needed for FF */ + min-width: 0px; + height: 90%; + flex: 15 15 0; + display: flex; + align-items: center; + justify-content: center; +} + +.mx_ImageView_content img { + max-width: 100%; + /* XXX: max-height interacts badly with flex on Chrome and doesn't relayout properly until you refresh */ + max-height: 100%; + /* object-fit hack needed for Chrome due to Chrome not re-laying-out until you refresh */ + object-fit: contain; + /* background-image: url('../../img/trans.png'); */ + pointer-events: all; +} + +.mx_ImageView_labelWrapper { + position: absolute; + top: 0px; + right: 0px; + height: 100%; + overflow: auto; + pointer-events: all; +} + +.mx_ImageView_label { + text-align: left; + display: flex; + justify-content: center; + flex-direction: column; + padding-left: 30px; + padding-right: 30px; + min-height: 100%; + max-width: 240px; + color: $lightbox-fg-color; +} + +.mx_ImageView_cancel { + position: absolute; + top: 0px; + right: 0px; + padding: 35px; + cursor: pointer; +} + +.mx_ImageView_name { + font-size: 18px; + margin-bottom: 6px; + word-wrap: break-word; +} + +.mx_ImageView_metadata { + font-size: 15px; + opacity: 0.5; +} + +.mx_ImageView_download { + display: table; + margin-top: 24px; + margin-bottom: 6px; + border-radius: 5px; + background-color: $lightbox-bg-color; + font-size: 14px; + padding: 9px; + border: 1px solid $lightbox-border-color; +} + +.mx_ImageView_size { + font-size: 11px; +} + +.mx_ImageView_link { + color: $lightbox-fg-color ! important; + text-decoration: none ! important; +} + +.mx_ImageView_button { + font-size: 15px; + opacity: 0.5; + margin-top: 18px; + cursor: pointer; +} + +.mx_ImageView_shim { + height: 30px; +} + +.mx_ImageView_rhs { + order: 3; + flex: 1 1 10%; + min-width: 300px; + // background-color: #800; + // height: 20px; +} diff --git a/res/css/views/elements/_InlineSpinner.scss b/res/css/views/elements/_InlineSpinner.scss new file mode 100644 index 0000000000..612b6209c6 --- /dev/null +++ b/res/css/views/elements/_InlineSpinner.scss @@ -0,0 +1,24 @@ +/* +Copyright 2017 New Vector Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_InlineSpinner { + display: inline; +} + +.mx_InlineSpinner img { + margin: 0px 6px; + vertical-align: -3px; +} diff --git a/res/css/views/elements/_MemberEventListSummary.scss b/res/css/views/elements/_MemberEventListSummary.scss new file mode 100644 index 0000000000..02ecb5d84a --- /dev/null +++ b/res/css/views/elements/_MemberEventListSummary.scss @@ -0,0 +1,71 @@ +/* +Copyright 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_MemberEventListSummary { + position: relative; +} + +.mx_TextualEvent.mx_MemberEventListSummary_summary { + font-size: 14px; + display: inline-flex; +} + +.mx_MemberEventListSummary_avatars { + display: inline-block; + margin-right: 8px; + padding-top: 8px; + line-height: 12px; +} + +.mx_MemberEventListSummary_avatars .mx_BaseAvatar { + margin-right: -4px; + cursor: pointer; +} + +.mx_MemberEventListSummary_toggle { + color: $accent-color; + cursor: pointer; + float: right; + margin-right: 10px; + margin-top: 8px; +} + +.mx_MemberEventListSummary_line { + border-bottom: 1px solid $primary-hairline-color; + margin-left: 63px; + line-height: 30px; +} + +.mx_MatrixChat_useCompactLayout { + .mx_MemberEventListSummary { + font-size: 13px; + .mx_EventTile_line { + line-height: 20px; + } + } + + .mx_MemberEventListSummary_line { + line-height: 22px; + } + + .mx_MemberEventListSummary_toggle { + margin-top: 3px; + } + + .mx_TextualEvent.mx_MemberEventListSummary_summary { + font-size: 13px; + } +} diff --git a/res/css/views/elements/_ProgressBar.scss b/res/css/views/elements/_ProgressBar.scss new file mode 100644 index 0000000000..a3fee232d0 --- /dev/null +++ b/res/css/views/elements/_ProgressBar.scss @@ -0,0 +1,25 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_ProgressBar { + height: 5px; + border: 1px solid $progressbar-color; +} + +.mx_ProgressBar_fill { + height: 100%; + background-color: $progressbar-color; +} diff --git a/res/css/views/elements/_Quote.scss b/res/css/views/elements/_Quote.scss new file mode 100644 index 0000000000..0af555b5aa --- /dev/null +++ b/res/css/views/elements/_Quote.scss @@ -0,0 +1,26 @@ +/* +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. +*/ + +.mx_Quote .mx_DateSeparator { + font-size: 1em !important; + margin-bottom: 0; + padding-bottom: 1px; + bottom: -5px; +} + +.mx_Quote_show { + cursor: pointer; +} diff --git a/res/css/views/elements/_RichText.scss b/res/css/views/elements/_RichText.scss new file mode 100644 index 0000000000..474a123455 --- /dev/null +++ b/res/css/views/elements/_RichText.scss @@ -0,0 +1,75 @@ +// XXX: bleurgh, what is this? These classes totally break the component +// naming scheme; it's completely unclear where or how they're being used +// --Matthew + +.mx_UserPill, +.mx_RoomPill, +.mx_AtRoomPill { + border-radius: 16px; + display: inline-block; + height: 20px; + line-height: 20px; + padding-left: 5px; +} + +.mx_EventTile_body .mx_UserPill, +.mx_EventTile_body .mx_RoomPill { + cursor: pointer; +} + +/* More specific to override `.markdown-body a` color */ +.mx_EventTile_content .markdown-body a.mx_UserPill, +.mx_UserPill { + color: $primary-fg-color; + background-color: $other-user-pill-bg-color; + padding-right: 5px; +} + +.mx_EventTile_highlight .mx_EventTile_content .markdown-body a.mx_UserPill_me, +.mx_EventTile_content .mx_AtRoomPill, +.mx_MessageComposer_input .mx_AtRoomPill { + color: $accent-fg-color; + background-color: $mention-user-pill-bg-color; + padding-right: 5px; +} + +/* More specific to override `.markdown-body a` color */ +.mx_EventTile_content .markdown-body a.mx_RoomPill, +.mx_RoomPill { + color: $accent-fg-color; + background-color: $rte-room-pill-color; + padding-right: 5px; +} + +.mx_UserPill .mx_BaseAvatar, +.mx_RoomPill .mx_BaseAvatar, +.mx_AtRoomPill .mx_BaseAvatar { + position: relative; + left: -3px; + top: 2px; +} + +.mx_Markdown_BOLD { + font-weight: bold; +} + +.mx_Markdown_ITALIC { + font-style: italic; +} + +.mx_Markdown_CODE { + padding: .2em 0; + margin: 0; + font-size: 85%; + background-color: $rte-code-bg-color; + border-radius: 3px; +} + +.mx_Markdown_HR { + display: block; + background: $rte-bg-color; +} + +.mx_Markdown_STRIKETHROUGH { + text-decoration: line-through; +} diff --git a/res/css/views/elements/_RoleButton.scss b/res/css/views/elements/_RoleButton.scss new file mode 100644 index 0000000000..094e0b9b1b --- /dev/null +++ b/res/css/views/elements/_RoleButton.scss @@ -0,0 +1,33 @@ +/* +Copyright 2107 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. +*/ + +.mx_RoleButton { + margin-left: 4px; + margin-right: 4px; + cursor: pointer; + display: inline-block; +} + +.mx_RoleButton object { + pointer-events: none; +} + +.mx_RoleButton_tooltip { + display: inline-block; + position: relative; + top: -25px; + left: 6px; +} diff --git a/res/css/views/elements/_Spinner.scss b/res/css/views/elements/_Spinner.scss new file mode 100644 index 0000000000..aea5737918 --- /dev/null +++ b/res/css/views/elements/_Spinner.scss @@ -0,0 +1,28 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_Spinner { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + flex: 1; +} + +.mx_MatrixChat_middlePanel .mx_Spinner { + height: auto; +} \ No newline at end of file diff --git a/res/css/views/elements/_SyntaxHighlight.scss b/res/css/views/elements/_SyntaxHighlight.scss new file mode 100644 index 0000000000..e97401a160 --- /dev/null +++ b/res/css/views/elements/_SyntaxHighlight.scss @@ -0,0 +1,21 @@ +/* +Copyright 2017 Michael Telatynski <7t3chguy@gmail.com> + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_SyntaxHighlight { + /* inhibit hljs styling */ + background: none !important; + color: $light-fg-color !important; +} diff --git a/res/css/views/elements/_ToolTipButton.scss b/res/css/views/elements/_ToolTipButton.scss new file mode 100644 index 0000000000..c496e67515 --- /dev/null +++ b/res/css/views/elements/_ToolTipButton.scss @@ -0,0 +1,51 @@ +/* +Copyright 2017 New Vector Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_ToolTipButton { + display: inline-block; + width: 11px; + height: 11px; + margin-left: 5px; + + border: 2px solid $neutral-badge-color; + border-radius: 20px; + color: $neutral-badge-color; + + transition: opacity 0.2s ease-in; + opacity: 0.6; + + line-height: 11px; + text-align: center; + + cursor: pointer; +} + +.mx_ToolTipButton:hover { + opacity: 1.0; +} + +.mx_ToolTipButton_container { + position: relative; + top: -18px; + left: 4px; +} + +.mx_ToolTipButton_helpText { + width: 400px; + text-align: start; + line-height: 17px !important; +} + diff --git a/res/css/views/globals/_MatrixToolbar.scss b/res/css/views/globals/_MatrixToolbar.scss new file mode 100644 index 0000000000..be69b15f37 --- /dev/null +++ b/res/css/views/globals/_MatrixToolbar.scss @@ -0,0 +1,62 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_MatrixToolbar { + background-color: $accent-color; + color: $accent-fg-color; + + display: flex; + align-items: center; +} + +.mx_MatrixToolbar_warning { + margin-left: 16px; + margin-right: 8px; + margin-top: -2px; +} + +.mx_MatrixToolbar_content { + flex: 1; +} + +.mx_MatrixToolbar_link +{ + color: $accent-fg-color ! important; + text-decoration: underline ! important; + cursor: pointer; +} + +.mx_MatrixToolbar_clickable { + cursor: pointer; +} + +.mx_MatrixToolbar_close { + cursor: pointer; +} + +.mx_MatrixToolbar_close img { + display: block; + float: right; + margin-right: 10px; +} + +.mx_MatrixToolbar_action { + margin-right: 16px; +} + +.mx_MatrixToolbar_changelog { + white-space: pre; +} \ No newline at end of file diff --git a/res/css/views/groups/_GroupPublicityToggle.scss b/res/css/views/groups/_GroupPublicityToggle.scss new file mode 100644 index 0000000000..3ea4aa07d6 --- /dev/null +++ b/res/css/views/groups/_GroupPublicityToggle.scss @@ -0,0 +1,42 @@ +/* +Copyright 2017 New Vector Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_GroupPublicity_toggle { + display: flex; + align-items: center; + margin: 8px; +} + +.mx_GroupPublicity_toggle > label { + display: flex; + align-items: flex-start; +} + +.mx_GroupPublicity_toggle > label, +.mx_GroupPublicity_toggle .mx_GroupTile { + width: 50%; +} + +.mx_GroupPublicity_toggle input { + margin-right: 8px; + vertical-align: -4px; +} + +.mx_GroupPublicity_toggle .mx_GroupTile { + display: flex; + align-items: flex-start; + cursor: pointer; +} diff --git a/res/css/views/groups/_GroupRoomList.scss b/res/css/views/groups/_GroupRoomList.scss new file mode 100644 index 0000000000..fb41ebaa9e --- /dev/null +++ b/res/css/views/groups/_GroupRoomList.scss @@ -0,0 +1,21 @@ +/* +Copyright 2017 New Vector Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_GroupRoomTile { + position: relative; + color: $primary-fg-color; + cursor: pointer; +} diff --git a/res/css/views/groups/_GroupUserSettings.scss b/res/css/views/groups/_GroupUserSettings.scss new file mode 100644 index 0000000000..0c909b7cf7 --- /dev/null +++ b/res/css/views/groups/_GroupUserSettings.scss @@ -0,0 +1,23 @@ +/* +Copyright 2017 New Vector Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_GroupUserSettings_groupPublicity_scrollbox { + height: 200px; + border: 1px solid $primary-hairline-color; + border-radius: 3px; + margin-right: 32px; + overflow: hidden; +} diff --git a/res/css/views/login/_InteractiveAuthEntryComponents.scss b/res/css/views/login/_InteractiveAuthEntryComponents.scss new file mode 100644 index 0000000000..183b5cd251 --- /dev/null +++ b/res/css/views/login/_InteractiveAuthEntryComponents.scss @@ -0,0 +1,42 @@ +/* +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. +*/ + +.mx_InteractiveAuthEntryComponents_msisdnWrapper { + text-align: center; +} + +.mx_InteractiveAuthEntryComponents_msisdnEntry { + font-size: 200%; + font-weight: bold; + border: 1px solid $strong-input-border-color; + border-radius: 3px; + width: 6em; +} + +.mx_InteractiveAuthEntryComponents_msisdnEntry:focus { + border: 1px solid $accent-color; +} + +.mx_InteractiveAuthEntryComponents_msisdnSubmit { + margin-top: 4px; + margin-bottom: 5px; +} + +// XXX: This should be a common button class +.mx_InteractiveAuthEntryComponents_msisdnSubmit:disabled { + background-color: $light-fg-color; + cursor: default; +} diff --git a/res/css/views/login/_ServerConfig.scss b/res/css/views/login/_ServerConfig.scss new file mode 100644 index 0000000000..894ce19827 --- /dev/null +++ b/res/css/views/login/_ServerConfig.scss @@ -0,0 +1,36 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_ServerConfig { + margin-top: 7px; +} + +.mx_ServerConfig .mx_Login_field { + margin-top: 4px; + margin-bottom: 5px; +} + +.mx_ServerConfig_help:link { + opacity: 0.8; + font-size: 13px; + font-weight: 300; + color: $primary-fg-color; +} + +.mx_ServerConfig_selector { + text-align: center; + width: 302px; // for fr i18n +} \ No newline at end of file diff --git a/res/css/views/messages/_DateSeparator.scss b/res/css/views/messages/_DateSeparator.scss new file mode 100644 index 0000000000..f676d24bef --- /dev/null +++ b/res/css/views/messages/_DateSeparator.scss @@ -0,0 +1,25 @@ +/* +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. +*/ + +.mx_DateSeparator { + clear: both; + margin-top: 32px; + margin-bottom: 8px; + margin-left: 63px; + padding-bottom: 6px; + border-bottom: 1px solid $primary-hairline-color; +} + diff --git a/res/css/views/messages/_MEmoteBody.scss b/res/css/views/messages/_MEmoteBody.scss new file mode 100644 index 0000000000..cf722e5ae8 --- /dev/null +++ b/res/css/views/messages/_MEmoteBody.scss @@ -0,0 +1,23 @@ +/* +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. +*/ + +.mx_MEmoteBody { + white-space: pre-wrap; +} + +.mx_MEmoteBody_sender { + cursor: pointer; +} diff --git a/res/css/views/messages/_MFileBody.scss b/res/css/views/messages/_MFileBody.scss new file mode 100644 index 0000000000..6cbce68745 --- /dev/null +++ b/res/css/views/messages/_MFileBody.scss @@ -0,0 +1,47 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_MFileBody_download { + color: $accent-color; +} + +.mx_MFileBody_download a { + color: $accent-color; + text-decoration: none; + cursor: pointer; +} + +.mx_MFileBody_download object { + margin-left: -16px; + padding-right: 4px; + margin-top: -4px; + vertical-align: middle; + pointer-events: none; +} + +/* Remove the border and padding for iframes for download links. */ +.mx_MFileBody_download iframe { + margin: 0px; + padding: 0px; + border: none; + width: 100%; + /* Set the height of the iframe to be 1 line of text. + * Iframes don't automatically size themselves to fit their content. + * So either we have to fix the height of the iframe using CSS or + * use javascript's cross-origin postMessage API to communicate how + * big the content of the iframe is. */ + height: 1.5em; +} diff --git a/res/css/views/messages/_MImageBody.scss b/res/css/views/messages/_MImageBody.scss new file mode 100644 index 0000000000..bf483feda3 --- /dev/null +++ b/res/css/views/messages/_MImageBody.scss @@ -0,0 +1,20 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_MImageBody { + display: block; + margin-right: 34px; +} diff --git a/res/css/views/messages/_MNoticeBody.scss b/res/css/views/messages/_MNoticeBody.scss new file mode 100644 index 0000000000..a88c20863d --- /dev/null +++ b/res/css/views/messages/_MNoticeBody.scss @@ -0,0 +1,20 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_MNoticeBody { + white-space: pre-wrap; + opacity: 0.6; +} diff --git a/res/css/views/messages/_MStickerBody.scss b/res/css/views/messages/_MStickerBody.scss new file mode 100644 index 0000000000..3e6bbe5aa4 --- /dev/null +++ b/res/css/views/messages/_MStickerBody.scss @@ -0,0 +1,46 @@ +/* +Copyright 2018 New Vector Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_MStickerBody { + display: block; + margin-right: 34px; + min-height: 110px; + padding: 20px 0; +} + +.mx_MStickerBody_image_container { + display: inline-block; + position: relative; +} + +.mx_MStickerBody_image { + max-width: 100%; + opacity: 0; +} + +.mx_MStickerBody_image_visible { + opacity: 1; +} + +.mx_MStickerBody_placeholder { + position: absolute; + opacity: 1; +} + +.mx_MStickerBody_placeholder_invisible { + transition: 500ms; + opacity: 0; +} diff --git a/res/css/views/messages/_MTextBody.scss b/res/css/views/messages/_MTextBody.scss new file mode 100644 index 0000000000..fcf397fd2d --- /dev/null +++ b/res/css/views/messages/_MTextBody.scss @@ -0,0 +1,24 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_MTextBody { + white-space: pre-wrap; +} + +.mx_MTextBody pre{ + overflow-y: auto; + max-height: 30vh; +} diff --git a/res/css/views/messages/_MessageTimestamp.scss b/res/css/views/messages/_MessageTimestamp.scss new file mode 100644 index 0000000000..e21189c59e --- /dev/null +++ b/res/css/views/messages/_MessageTimestamp.scss @@ -0,0 +1,18 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_MessageTimestamp { +} diff --git a/res/css/views/messages/_RoomAvatarEvent.scss b/res/css/views/messages/_RoomAvatarEvent.scss new file mode 100644 index 0000000000..9adce42eef --- /dev/null +++ b/res/css/views/messages/_RoomAvatarEvent.scss @@ -0,0 +1,26 @@ +/* +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. +*/ + +.mx_RoomAvatarEvent { + opacity: 0.5; + overflow-y: hidden; +} + +.mx_RoomAvatarEvent_avatar { + display: inline; + position: relative; + top: 5px; +} \ No newline at end of file diff --git a/res/css/views/messages/_SenderProfile.scss b/res/css/views/messages/_SenderProfile.scss new file mode 100644 index 0000000000..060709b82e --- /dev/null +++ b/res/css/views/messages/_SenderProfile.scss @@ -0,0 +1,15 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ diff --git a/res/css/views/messages/_TextualEvent.scss b/res/css/views/messages/_TextualEvent.scss new file mode 100644 index 0000000000..be7565b3c5 --- /dev/null +++ b/res/css/views/messages/_TextualEvent.scss @@ -0,0 +1,20 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_TextualEvent { + opacity: 0.5; + overflow-y: hidden; +} diff --git a/res/css/views/messages/_UnknownBody.scss b/res/css/views/messages/_UnknownBody.scss new file mode 100644 index 0000000000..9036e12bf0 --- /dev/null +++ b/res/css/views/messages/_UnknownBody.scss @@ -0,0 +1,16 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_UnknownBody { + white-space: pre-wrap; +} diff --git a/res/css/views/rooms/_AppsDrawer.scss b/res/css/views/rooms/_AppsDrawer.scss new file mode 100644 index 0000000000..0cf3e7b9cb --- /dev/null +++ b/res/css/views/rooms/_AppsDrawer.scss @@ -0,0 +1,271 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_AppsDrawer { + margin: 5px; +} + +.mx_AppsDrawer_hidden { + display: none; +} + +.mx_AppsContainer { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; +} + +.mx_AddWidget_button { + order: 2; + cursor: pointer; + padding-right: 12px; + padding: 0; + margin: 5px auto 5px auto; + color: $accent-color; + font-size: 12px; +} + +.mx_AddWidget_button_full_width { + max-width: 960px; +} + +.mx_SetAppURLDialog_input { + border-radius: 3px; + border: 1px solid $input-border-color; + padding: 9px; + color: $primary-hairline-color; + background-color: $primary-bg-color; + font-size: 15px; +} + +.mx_AppTile { + max-width: 960px; + width: 50%; + margin-right: 5px; + border: 1px solid $primary-hairline-color; + border-radius: 2px; + background-color: $dialog-background-bg-color; +} + +.mx_AppTile:last-child { + margin-right: 1px; +} + +.mx_AppTileFullWidth { + max-width: 960px; + width: 100%; + height: 100%; + margin: 0; + padding: 0; + border: 1px solid $primary-hairline-color; + border-radius: 2px; +} + +.mx_AppTileMenuBar { + margin: 0; + padding: 2px 10px; + border-bottom: 1px solid $primary-hairline-color; + font-size: 10px; + background-color: $widget-menu-bar-bg-color; + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + cursor: pointer; +} + +.mx_AppTileMenuBarTitle { + display: flex; + flex-direction: row; + align-items: center; + pointer-events: none; +} + +.mx_AppTileMenuBarWidgets { + float: right; + display: flex; + flex-direction: row; + align-items: center; +} + +.mx_AppTileMenuBarWidget { + cursor: pointer; + width: 10px; + height: 10px; + padding: 1px; + transition-duration: 500ms; + border: 1px solid transparent; +} + +.mx_AppTileMenuBarWidgetDelete { + filter: none; +} + +.mx_AppTileMenuBarWidget:hover { + border: 1px solid $primary-fg-color; + border-radius: 2px; +} + +.mx_AppTileBody{ + height: 280px; + width: 100%; + overflow: hidden; +} + +.mx_AppTileBody iframe { + width: 100%; + height: 280px; + overflow: hidden; + border: none; + padding: 0; + margin: 0; + display: block; +} + +.mx_AppTileMenuBarWidgetPadding { + margin-right: 5px; +} + +.mx_AppIconTile { + background-color: $lightbox-bg-color; + border: 1px solid rgba(0, 0, 0, 0); + width: 200px; + box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2); + transition: 0.3s; + border-radius: 3px; + margin: 5px; + display: inline-block; +} + +.mx_AppIconTile.mx_AppIconTile_active { + color: $accent-color; + border-color: $accent-color; +} + +.mx_AppIconTile:hover { + border: 1px solid $accent-color; + box-shadow: 0 0 10px 5px rgba(200,200,200,0.5); +} + +.mx_AppIconTile_content { + padding: 2px 16px; + height: 60px; + overflow: hidden; +} + +.mx_AppIconTile_content h4 { + margin-top: 5px; + margin-bottom: 2px; +} + +.mx_AppIconTile_content p { + margin-top: 0; + margin-bottom: 5px; + font-size: smaller; +} + +.mx_AppIconTile_image { + padding: 10px; + width: 75%; + max-width:100px; + max-height:100px; + width: auto; + height: auto; +} + +.mx_AppIconTile_imageContainer { + text-align: center; + width: 100%; + background-color: white; + border-radius: 3px 3px 0 0; + height: 155px; + display: flex; + justify-content: center; + align-items: center; +} + +form.mx_Custom_Widget_Form div { + margin-top: 10px; + margin-bottom: 10px; +} + +.mx_AppPermissionWarning { + text-align: center; + background-color: $primary-bg-color; + display: flex; + height: 100%; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.mx_AppPermissionWarningImage { + margin: 10px 0; +} + +.mx_AppPermissionWarningImage img { + width: 100px; +} + +.mx_AppPermissionWarningText { + max-width: 400px; + margin: 10px auto 10px auto; + color: $primary-fg-color; +} + +.mx_AppPermissionWarningTextLabel { + font-weight: bold; + display: block; +} + +.mx_AppPermissionWarningTextURL { + color: $accent-color; +} + +.mx_AppPermissionButton { + padding: 5px; + border-radius: 5px; + color: $warning-color; + background-color: $primary-bg-color; +} + +.mx_AppPermissionButton:hover { + background-color: $primary-fg-color; + cursor: pointer; +} + +.mx_AppLoading { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + font-weight: bold; + position: relative; + height: 280px; +} + +.mx_AppLoading .mx_Spinner { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; +} + +.mx_AppLoading iframe { + display: none; +} diff --git a/res/css/views/rooms/_Autocomplete.scss b/res/css/views/rooms/_Autocomplete.scss new file mode 100644 index 0000000000..732ada088b --- /dev/null +++ b/res/css/views/rooms/_Autocomplete.scss @@ -0,0 +1,93 @@ +.mx_Autocomplete { + position: absolute; + bottom: 0; + z-index: 1001; + width: 100%; + border: 1px solid $primary-hairline-color; + background: $primary-bg-color; + border-bottom: none; + border-radius: 4px 4px 0 0; + max-height: 50vh; + overflow: auto +} + +.mx_Autocomplete_ProviderSection { + border-bottom: 1px solid $primary-hairline-color; +} + +.mx_Autocomplete_Completion_container_pill { + margin: 12px; + display: flex; +} + +/* a "block" completion takes up a whole line */ +.mx_Autocomplete_Completion_block { + height: 34px; + display: flex; + padding: 0 12px; + user-select: none; + cursor: pointer; + align-items: center; + color: $primary-fg-color; +} + +.mx_Autocomplete_Completion_block * { + margin: 0 3px; +} + +.mx_Autocomplete_Completion_pill { + border-radius: 17px; + height: 34px; + padding: 0px 5px; + display: flex; + user-select: none; + cursor: pointer; + align-items: center; + color: $primary-fg-color; +} + +.mx_Autocomplete_Completion_pill > * { + margin: 0 3px; +} + +.mx_Autocomplete_Completion_container_truncate { + .mx_Autocomplete_Completion_title, + .mx_Autocomplete_Completion_subtitle, + .mx_Autocomplete_Completion_description { + /* Ellipsis for long names/subtitles/descriptions*/ + max-width: 150px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } +} + +/* container for pill-style completions */ +.mx_Autocomplete_Completion_container_pill { + margin: 12px; + display: flex; + flex-flow: wrap; +} + +.mx_Autocomplete_Completion.selected { + background: $menu-bg-color; + outline: none; +} + +.mx_Autocomplete_provider_name { + margin: 12px; + color: $primary-fg-color; + font-weight: 400; + opacity: 0.4; +} + +/* styling for common completion elements */ +.mx_Autocomplete_Completion_subtitle { + font-style: italic; + flex: 1; +} + +.mx_Autocomplete_Completion_description { + color: gray; +} + diff --git a/res/css/views/rooms/_EntityTile.scss b/res/css/views/rooms/_EntityTile.scss new file mode 100644 index 0000000000..031894afde --- /dev/null +++ b/res/css/views/rooms/_EntityTile.scss @@ -0,0 +1,114 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_EntityTile { + display: table-row; + position: relative; + color: $primary-fg-color; + cursor: pointer; +} + +.mx_EntityTile_invite { + display: table-cell; + vertical-align: middle; + margin-left: 10px; + width: 26px; +} + +.mx_EntityTile_avatar, +.mx_GroupRoomTile_avatar { + display: table-cell; + padding-left: 3px; + padding-right: 12px; + padding-top: 4px; + padding-bottom: 4px; + vertical-align: middle; + width: 36px; + height: 36px; + position: relative; +} + +.mx_EntityTile_power { + position: absolute; + width: 16px; + height: 17px; + top: 0px; + right: 6px; +} + +.mx_EntityTile_name, +.mx_GroupRoomTile_name { + display: table-cell; + vertical-align: middle; + overflow: hidden; + font-size: 14px; + text-overflow: ellipsis; + white-space: nowrap; + max-width: 155px; +} + +.mx_EntityTile_details { + display: table-cell; + padding-right: 14px; + vertical-align: middle; +} + +.mx_EntityTile_name_hover { + font-size: 13px; +} + +.mx_EntityTile_chevron { + margin-top: 8px; + margin-right: -4px; + margin-left: 6px; + float: right; +} + +.mx_EntityTile_ellipsis .mx_EntityTile_name { + font-style: italic; + color: $primary-fg-color; +} + +.mx_EntityTile_invitePlaceholder .mx_EntityTile_name { + font-style: italic; + color: $primary-fg-color; +} + +.mx_EntityTile_unavailable .mx_EntityTile_avatar, +.mx_EntityTile_unavailable .mx_EntityTile_name, +.mx_EntityTile_unavailable .mx_EntityTile_name_hover, +.mx_EntityTile_offline_beenactive .mx_EntityTile_avatar, +.mx_EntityTile_offline_beenactive .mx_EntityTile_name, +.mx_EntityTile_offline_beenactive .mx_EntityTile_name_hover +{ + opacity: 0.66; +} + +.mx_EntityTile_offline_neveractive .mx_EntityTile_avatar, +.mx_EntityTile_offline_neveractive .mx_EntityTile_name, +.mx_EntityTile_offline_neveractive .mx_EntityTile_name_hover +{ + opacity: 0.25; +} + +.mx_EntityTile_unknown .mx_EntityTile_avatar, +.mx_EntityTile_unknown .mx_EntityTile_name, +.mx_EntityTile_unknown .mx_EntityTile_name_hover +{ + opacity: 0.25; +} + + diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss new file mode 100644 index 0000000000..4bb81a2e53 --- /dev/null +++ b/res/css/views/rooms/_EventTile.scss @@ -0,0 +1,530 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_EventTile { + max-width: 100%; + clear: both; + padding-top: 18px; + font-size: 14px; + position: relative; +} + +.mx_EventTile.mx_EventTile_info { + padding-top: 0px; +} + +.mx_EventTile_avatar { + position: absolute; + top: 14px; + left: 8px; + cursor: pointer; + z-index: 2; +} + +.mx_EventTile.mx_EventTile_info .mx_EventTile_avatar { + top: 8px; + left: 65px; +} + +.mx_EventTile_continuation { + padding-top: 0px ! important; +} + +.mx_EventTile .mx_SenderProfile { + color: $primary-fg-color; + font-size: 14px; + display: block; /* anti-zalgo, with overflow hidden */ + overflow-y: hidden; + cursor: pointer; + padding-left: 65px; /* left gutter */ + padding-bottom: 0px; + padding-top: 0px; + margin: 0px; + line-height: 22px; +} + +.mx_EventTile .mx_SenderProfile .mx_SenderProfile_name, +.mx_EventTile .mx_SenderProfile .mx_SenderProfile_aux { + opacity: 0.5; +} + +.mx_EventTile .mx_SenderProfile .mx_Flair { + opacity: 0.7; + margin-left: 5px; +} + +.mx_EventTile .mx_SenderProfile .mx_Flair img { + vertical-align: -2px; + margin-right: 2px; + border-radius: 8px; +} + +.mx_EventTile .mx_MessageTimestamp { + display: block; + visibility: hidden; + white-space: nowrap; + color: $event-timestamp-color; + font-size: 10px; + left: 0px; + width: 46px; /* 8 + 30 (avatar) + 8 */ + text-align: center; + position: absolute; +} + +.mx_EventTile_line { + position: relative; + /* ideally should be 100px, but 95px gives us a max thumbnail size of 800x600, which is nice */ + margin-right: 110px; + padding-left: 65px; /* left gutter */ + padding-top: 4px; + padding-bottom: 2px; + border-radius: 4px; + min-height: 24px; + line-height: 22px; +} + +.mx_EventTile_quote { + margin-right: 10px; +} + +.mx_EventTile_info .mx_EventTile_line { + padding-left: 83px; +} + +/* HACK to override line-height which is already marked important elsewhere */ +.mx_EventTile_bigEmoji.mx_EventTile_bigEmoji { + font-size: 48px ! important; + line-height: 48px ! important; +} + +/* this is used for the tile for the event which is selected via the URL. + * TODO: ultimately we probably want some transition on here. + */ +.mx_EventTile_selected > .mx_EventTile_line { + border-left: $accent-color 5px solid; + padding-left: 60px; + background-color: $event-selected-color; +} + +.mx_EventTile:hover .mx_EventTile_line:not(.mx_EventTile_quote), +.mx_EventTile.menu .mx_EventTile_line +{ + background-color: $event-selected-color; +} + +.mx_EventTile_searchHighlight { + background-color: $accent-color; + color: $accent-fg-color; + border-radius: 5px; + padding-left: 2px; + padding-right: 2px; + cursor: pointer; +} + +.mx_EventTile_searchHighlight a { + background-color: $accent-color; + color: $accent-fg-color; +} + +.mx_EventTile_encrypting { + color: $event-encrypting-color ! important; +} + +.mx_EventTile_sending { + color: $event-sending-color; +} + +.mx_EventTile_sending .mx_UserPill, +.mx_EventTile_sending .mx_RoomPill, +.mx_EventTile_sending .mx_emojione { + opacity: 0.5; +} + +.mx_EventTile_notSent { + color: $event-notsent-color; +} + +.mx_EventTile_redacted .mx_EventTile_line .mx_UnknownBody { + display: block; + width: 100%; + height: 22px; + width: 250px; + border-radius: 11px; + background: repeating-linear-gradient( + -45deg, + $event-redacted-fg-color, + $event-redacted-fg-color 3px, + transparent 3px, + transparent 6px + ); + box-shadow: 0px 0px 3px $event-redacted-border-color inset; +} + +.mx_EventTile_highlight, +.mx_EventTile_highlight .markdown-body + { + color: $warning-color; +} + +.mx_EventTile_contextual { + opacity: 0.4; +} + +.mx_EventTile_msgOption { + float: right; + text-align: right; + z-index: 1; + position: relative; + width: 90px; + + /* Hack to stop the height of this pushing the messages apart. + Replaces margin-top: -6px. This interacts better with a read + marker being in between. Content overflows. */ + height: 1px; + + margin-right: 10px; +} + +.mx_EventTile_msgOption a { + text-decoration: none; +} + +.mx_EventTile_last .mx_MessageTimestamp, +.mx_EventTile:hover .mx_MessageTimestamp, +.mx_EventTile.menu .mx_MessageTimestamp +{ + visibility: visible; +} + +.mx_MessagePanel_alwaysShowTimestamps .mx_MessageTimestamp { + visibility: visible; +} + +.mx_EventTile_selected > div > a > .mx_MessageTimestamp { + left: 3px; + width: auto; +} + +.mx_EventTile_editButton { + position: absolute; + display: inline-block; + visibility: hidden; + cursor: pointer; + top: 6px; + right: 6px; + width: 19px; + height: 19px; + background-image: url($edit-button-url); + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.mx_EventTile:hover .mx_EventTile_editButton, +.mx_EventTile.menu .mx_EventTile_editButton +{ + visibility: visible; +} + +.mx_EventTile.menu .mx_MessageTimestamp { + visibility: visible; +} + +.mx_EventTile_readAvatars { + position: relative; + display: inline-block; + width: 14px; + height: 14px; + top: 29px; +} + +.mx_EventTile_continuation .mx_EventTile_readAvatars, +.mx_EventTile_info .mx_EventTile_readAvatars, +.mx_EventTile_emote .mx_EventTile_readAvatars { + top: 7px; +} + +.mx_EventTile_readAvatars .mx_BaseAvatar { + position: absolute; + display: inline-block; +} + +.mx_EventTile_readAvatarRemainder { + color: $event-timestamp-color; + font-size: 11px; + position: absolute; +} + +/* all the overflow-y: hidden; are to trap Zalgos - + but they introduce an implicit overflow-x: auto. + so make that explicitly hidden too to avoid random + horizontal scrollbars occasionally appearing, like in + https://github.com/vector-im/vector-web/issues/1154 + */ +.mx_EventTile_content { + display: block; + overflow-y: hidden; + overflow-x: hidden; + margin-right: 34px; +} + +/* De-zalgoing */ +.mx_EventTile_body { + overflow-y: hidden; +} + +/* End to end encryption stuff */ + +.mx_EventTile_e2eIcon { + display: block; + position: absolute; + top: 9px; + left: 46px; + z-index: 2; + cursor: pointer; +} + +.mx_EventTile_keyRequestInfo { + font-size: 12px; +} + +.mx_EventTile_keyRequestInfo_text { + opacity: 0.5; +} + +.mx_EventTile_keyRequestInfo_text a { + color: $primary-fg-color; + text-decoration: underline; + cursor: pointer; +} + +.mx_EventTile_keyRequestInfo_tooltip_contents p { + text-align: auto; + margin-left: 3px; + margin-right: 3px; +} + +.mx_EventTile_keyRequestInfo_tooltip_contents p:first-child { + margin-top: 0px; +} + +.mx_EventTile_keyRequestInfo_tooltip_contents p:last-child { + margin-bottom: 0px; +} + +.mx_EventTile_12hr .mx_EventTile_e2eIcon { + padding-left: 5px; +} + +.mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_line, +.mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_line { + padding-left: 60px; +} + +.mx_EventTile_selected.mx_EventTile_info .mx_EventTile_line, +.mx_EventTile:hover.mx_EventTile_verified.mx_EventTile_info .mx_EventTile_line, +.mx_EventTile:hover.mx_EventTile_unverified.mx_EventTile_info .mx_EventTile_line { + padding-left: 78px; +} + +.mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_line { + border-left: $e2e-verified-color 5px solid; +} +.mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_line { + border-left: $e2e-unverified-color 5px solid; +} + +.mx_EventTile:hover.mx_EventTile_verified .mx_MessageTimestamp, +.mx_EventTile:hover.mx_EventTile_unverified .mx_MessageTimestamp { + left: 3px; + width: auto; +} + +/* +.mx_EventTile_verified .mx_EventTile_e2eIcon { + display: none; +} +*/ + +.mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_e2eIcon, +.mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_e2eIcon { + display: block; + left: 41px; +} + +/* Various markdown overrides */ + +.mx_EventTile_content .markdown-body { + font-family: inherit ! important; + white-space: normal ! important; + line-height: inherit ! important; + color: inherit; // inherit the colour from the dark or light theme by default (but not for code blocks) + font-size: 14px; +} + +/* have to use overlay rather than auto otherwise Linux and Windows + Chrome gets very confused about vertical spacing: + https://github.com/vector-im/vector-web/issues/754 +*/ +.mx_EventTile_content .markdown-body pre { + overflow-x: overlay; + overflow-y: visible; +} + +.mx_EventTile_content .markdown-body code { + // deliberate constants as we're behind an invert filter + background-color: #f8f8f8; + color: #333; +} + +.mx_EventTile_copyButton { + position: absolute; + display: inline-block; + visibility: hidden; + cursor: pointer; + top: 6px; + right: 6px; + width: 19px; + height: 19px; + background-image: url($copy-button-url); +} + +.mx_EventTile_body pre { + position: relative; + border: 1px solid transparent; +} + +.mx_EventTile:hover .mx_EventTile_body pre +{ + border: 1px solid #e5e5e5; // deliberate constant as we're behind an invert filter +} + +.mx_EventTile_body pre:hover .mx_EventTile_copyButton +{ + visibility: visible; +} + +.mx_EventTile_content .markdown-body h1, +.mx_EventTile_content .markdown-body h2, +.mx_EventTile_content .markdown-body h3, +.mx_EventTile_content .markdown-body h4, +.mx_EventTile_content .markdown-body h5, +.mx_EventTile_content .markdown-body h6 +{ + font-family: inherit ! important; + color: inherit; +} + + +/* Make h1 and h2 the same size as h3. */ +.mx_EventTile_content .markdown-body h1, +.mx_EventTile_content .markdown-body h2 +{ + font-size: 1.5em; +} + +.mx_EventTile_content .markdown-body a { + color: $accent-color; +} + +.mx_EventTile_content .markdown-body .hljs { + display: inline ! important; +} + +/* end of overrides */ + +.mx_MatrixChat_useCompactLayout { + .mx_EventTile { + padding-top: 4px; + } + + .mx_EventTile.mx_EventTile_info { + // same as the padding for non-compact .mx_EventTile.mx_EventTile_info + padding-top: 0px; + font-size: 13px; + .mx_EventTile_line { + line-height: 20px; + } + .mx_EventTile_avatar { + top: 4px; + } + } + + .mx_EventTile .mx_SenderProfile { + font-size: 13px; + } + + .mx_EventTile.mx_EventTile_emote { + // add a bit more space for emotes so that avatars don't collide + padding-top: 8px; + .mx_EventTile_avatar { + top: 2px; + } + .mx_EventTile_line { + padding-top: 0px; + padding-bottom: 1px; + } + } + + .mx_EventTile.mx_EventTile_emote.mx_EventTile_continuation { + padding-top: 0; + .mx_EventTile_line { + padding-top: 0px; + padding-bottom: 0px; + } + } + + .mx_EventTile_line { + padding-top: 0px; + padding-bottom: 0px; + } + + .mx_EventTile_avatar { + top: 2px; + } + + .mx_EventTile_e2eIcon { + top: 7px; + } + + .mx_EventTile_editButton { + top: 3px; + } + + .mx_EventTile_readAvatars { + top: 27px; + } + + .mx_EventTile_continuation .mx_EventTile_readAvatars, + .mx_EventTile_emote .mx_EventTile_readAvatars { + top: 5px; + } + + .mx_EventTile_info .mx_EventTile_readAvatars { + top: 4px; + } + + .mx_RoomView_MessageList h2 { + margin-top: 6px; + } + + .mx_EventTile_content .markdown-body { + p, ul, ol, dl, blockquote, pre, table { + margin-bottom: 4px; // 1/4 of the non-compact margin-bottom + } + } +} diff --git a/res/css/views/rooms/_LinkPreviewWidget.scss b/res/css/views/rooms/_LinkPreviewWidget.scss new file mode 100644 index 0000000000..4495b142e6 --- /dev/null +++ b/res/css/views/rooms/_LinkPreviewWidget.scss @@ -0,0 +1,69 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_LinkPreviewWidget { + margin-top: 15px; + margin-right: 15px; + margin-bottom: 15px; + display: flex; + border-left: 4px solid $preview-widget-bar-color; + color: $preview-widget-fg-color; +} + +.mx_LinkPreviewWidget_image { + flex: 0 0 100px; + margin-left: 15px; + text-align: center; + cursor: pointer; +} + +.mx_LinkPreviewWidget_caption { + margin-left: 15px; + flex: 1 1 auto; +} + +.mx_LinkPreviewWidget_title { + display: inline; + font-weight: bold; + white-space: normal; +} + +.mx_LinkPreviewWidget_siteName { + display: inline; +} + +.mx_LinkPreviewWidget_description { + margin-top: 8px; + white-space: normal; + word-wrap: break-word; +} + +.mx_LinkPreviewWidget_cancel { + visibility: hidden; + cursor: pointer; + flex: 0 0 40px; +} + +.mx_LinkPreviewWidget:hover .mx_LinkPreviewWidget_cancel { + visibility: visible; +} + +.mx_MatrixChat_useCompactLayout { + .mx_LinkPreviewWidget { + margin-top: 6px; + margin-bottom: 6px; + } +} diff --git a/res/css/views/rooms/_MemberDeviceInfo.scss b/res/css/views/rooms/_MemberDeviceInfo.scss new file mode 100644 index 0000000000..5888820e0d --- /dev/null +++ b/res/css/views/rooms/_MemberDeviceInfo.scss @@ -0,0 +1,74 @@ +/* +Copyright 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_MemberDeviceInfo { + padding: 10px 0px; +} + +.mx_MemberDeviceInfo.mx_DeviceVerifyButtons { + padding: 6px 0; + display: flex; + flex-wrap: wrap; + justify-content: space-between; +} + +.mx_MemberDeviceInfo_textButton { + @mixin mx_DialogButton_small; + margin: 2px; + flex: 1; +} + +.mx_MemberDeviceInfo_textButton:hover { + @mixin mx_DialogButton_hover; +} + +.mx_MemberDeviceInfo_deviceId { + font-size: 13px; +} + +.mx_MemberDeviceInfo_deviceInfo { + margin-bottom: 10px; + padding-bottom: 10px; + border-bottom: 1px solid rgba(0,0,0,0.1); +} + +/* "Unblacklist" is too long for a regular button: make it wider and + reduce the padding. */ +.mx_EncryptedEventDialog .mx_MemberDeviceInfo_blacklist, +.mx_EncryptedEventDialog .mx_MemberDeviceInfo_unblacklist { + width: 8em; + padding-left: 1em; + padding-right: 1em; +} + +.mx_MemberDeviceInfo div.mx_MemberDeviceInfo_verified, +.mx_MemberDeviceInfo div.mx_MemberDeviceInfo_unverified, +.mx_MemberDeviceInfo div.mx_MemberDeviceInfo_blacklisted { + float: right; + padding-left: 1em; +} + +.mx_MemberDeviceInfo div.mx_MemberDeviceInfo_verified { + color: $e2e-verified-color; +} + +.mx_MemberDeviceInfo div.mx_MemberDeviceInfo_unverified { + color: $e2e-unverified-color; +} + +.mx_MemberDeviceInfo div.mx_MemberDeviceInfo_blacklisted { + color: $e2e-warning-color; +} diff --git a/res/css/views/rooms/_MemberInfo.scss b/res/css/views/rooms/_MemberInfo.scss new file mode 100644 index 0000000000..5d47275efe --- /dev/null +++ b/res/css/views/rooms/_MemberInfo.scss @@ -0,0 +1,112 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_MemberInfo { + margin-top: 20px; + padding-right: 20px; + height: 100%; + overflow-y: auto; +} + +.mx_MemberInfo h2 { + margin-top: 6px; +} + +.mx_MemberInfo .mx_RoomTile_nameContainer { + width: 154px; +} + +.mx_MemberInfo .mx_RoomTile_badge { + display: none; +} + +.mx_MemberInfo .mx_RoomTile_name { + width: 160px; +} + +.mx_MemberInfo_cancel { + float: right; + margin-right: 10px; + cursor: pointer; +} + +.mx_MemberInfo_avatar { + clear: both; +} + +.mx_MemberInfo_avatar .mx_BaseAvatar { +} + +.mx_MemberInfo_avatar .mx_BaseAvatar.mx_BaseAvatar_image { + cursor: zoom-in; +} + +.mx_MemberInfo_profile { + margin-bottom: 16px; +} + +.mx_MemberInfo h3 { + text-transform: uppercase; + color: $h3-color; + font-weight: 600; + font-size: 13px; + margin-top: 16px; + margin-bottom: 14px; +} + +.mx_MemberInfo_profileField { + font-size: 13px; + position: relative; + background-color: $primary-bg-color; +} + +.mx_MemberInfo_buttons { + margin-bottom: 16px; +} + +.mx_MemberInfo_field { + cursor: pointer; + font-size: 13px; + color: $accent-color; + margin-left: 8px; + line-height: 23px; +} + +.mx_MemberInfo_createRoom { + cursor: pointer; +} + +.mx_MemberInfo_createRoom_label { + width: initial ! important; + cursor: pointer; +} + +.mx_MemberInfo label { + font-size: 13px; +} + +.mx_MemberInfo label .mx_MemberInfo_label_text { + display: inline-block; + max-width: 180px; + vertical-align: text-top; +} + +.mx_MemberInfo input[type="radio"] { + vertical-align: -2px; + margin-right: 5px; + margin-left: 8px; +} + diff --git a/res/css/views/rooms/_MemberList.scss b/res/css/views/rooms/_MemberList.scss new file mode 100644 index 0000000000..83fc70aefb --- /dev/null +++ b/res/css/views/rooms/_MemberList.scss @@ -0,0 +1,116 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_MemberList, +.mx_GroupMemberList, +.mx_GroupRoomList { + height: 100%; + + margin-top: 12px; + margin-right: 20px; + + flex: 1; + + display: flex; + + flex-direction: column; +} + +.mx_MemberList .mx_Spinner { + flex: 0 0 auto; +} + +.mx_MemberList_chevron { + position: absolute; + right: 35px; + margin-top: -15px; +} + +.mx_MemberList_border { + overflow-y: auto; + + order: 1; + flex: 1 1 0px; +} + +.mx_MemberList_query, +.mx_GroupMemberList_query, +.mx_GroupRoomList_query { + font-family: $font-family; + border-radius: 3px; + border: 1px solid $input-border-color; + padding: 9px; + color: $primary-fg-color; + background-color: $primary-bg-color; + margin-left: 3px; + font-size: 14px; + margin-bottom: 8px; + width: 189px; +} + +.mx_MemberList_query::-moz-placeholder, +.mx_GroupMemberList_query::-moz-placeholder, +.mx_GroupRoomList_query::-moz-placeholder { + color: $primary-fg-color; + opacity: 0.5; + font-size: 14px; +} + +.mx_MemberList_query::-webkit-input-placeholder, +.mx_GroupMemberList_query::-webkit-input-placeholder, +.mx_GroupRoomList_query::-webkit-input-placeholder { + color: $primary-fg-color; + opacity: 0.5; + font-size: 14px; +} + +.mx_MemberList_joined { + order: 2; + flex: 1 0 0; + + overflow-y: auto; +} + +/* +.mx_MemberList_invited { + order: 3; + flex: 0 0 100px; + overflow-y: auto; +} +*/ + +.mx_GroupMemberList_invited h2, +.mx_MemberList_invited h2 { + text-transform: uppercase; + color: $h3-color; + font-weight: 600; + font-size: 13px; + padding-left: 3px; + padding-right: 12px; + margin-top: 8px; + margin-bottom: 4px; +} + +/* we have to have display: table in order for the horizontal wrapping to work */ +.mx_MemberList_wrapper { + display: table; + table-layout: fixed; + width: 100%; +} + +.mx_MemberList_outerWrapper { + height: 0px; +} diff --git a/res/css/views/rooms/_MessageComposer.scss b/res/css/views/rooms/_MessageComposer.scss new file mode 100644 index 0000000000..2e8f07b7ef --- /dev/null +++ b/res/css/views/rooms/_MessageComposer.scss @@ -0,0 +1,246 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_MessageComposer_wrapper { + max-width: 960px; + vertical-align: middle; + margin: auto; + border-top: 1px solid $primary-hairline-color; + position: relative; +} + +.mx_MessageComposer_autocomplete_wrapper { + position: relative; + height: 0; +} + +.mx_MessageComposer_row { + display: flex; + flex-direction: row; + align-items: center; + width: 100%; +} + +.mx_MessageComposer_row div:last-child{ + padding-right: 0; +} + +.mx_MessageComposer .mx_MessageComposer_avatar { + padding-left: 10px; + padding-right: 28px; +} + +.mx_MessageComposer .mx_MessageComposer_avatar .mx_BaseAvatar { + display: block; +} + +.mx_MessageComposer_composecontrols { + width: 100%; +} + +.mx_MessageComposer_e2eIcon { + position: absolute; + left: 44px; +} + +.mx_MessageComposer_noperm_error { + width: 100%; + height: 60px; + font-style: italic; + color: $greyed-fg-color; + display: flex; + align-items: center; + justify-content: center; +} + +.mx_MessageComposer_input_wrapper { + flex: 1; + display: flex; + flex-direction: column; +} + +.mx_MessageComposer_input { + flex: 1; + vertical-align: middle; + display: flex; + flex-direction: column; + min-height: 60px; + justify-content: center; + align-items: flex-start; + font-size: 14px; + margin-right: 6px; +} + +@keyframes visualbell +{ + from { background-color: #faa } + to { background-color: $primary-bg-color } +} + +.mx_MessageComposer_input_error { + animation: 0.2s visualbell; +} + +.mx_MessageComposer_input_empty .public-DraftEditorPlaceholder-root { + display: none; +} + +.mx_MessageComposer_input .DraftEditor-root { + width: 100%; + flex: 1; + word-break: break-word; + max-height: 120px; + min-height: 21px; + overflow: auto; +} + +.mx_MessageComposer_input .DraftEditor-root .DraftEditor-editorContainer { + /* Ensure mx_UserPill and mx_RoomPill (see _RichText) are not obscured from the top */ + padding-top: 2px; +} + +.mx_MessageComposer .public-DraftStyleDefault-block { + overflow-x: hidden; +} + +.mx_MessageComposer_input blockquote { + color: $blockquote-fg-color; + margin: 0 0 16px; + padding: 0 15px; + border-left: 4px solid $blockquote-bar-color; +} + +.mx_MessageComposer_input pre.public-DraftStyleDefault-pre pre { + background-color: $rte-code-bg-color; + border-radius: 3px; + padding: 10px; +} + +.mx_MessageComposer_input textarea { + display: block; + width: 100%; + padding: 0px; + margin-top: 6px; + margin-bottom: 6px; + border: 0px; + resize: none; + outline: none; + box-shadow: none; + color: $primary-fg-color; + background-color: $primary-bg-color; + font-size: 14px; + max-height: 120px; + overflow: auto; + /* needed for FF */ + font-family: $font-family; +} + +/* hack for FF as vertical alignment of custom placeholder text is broken */ +.mx_MessageComposer_input textarea::-moz-placeholder { + line-height: 100%; + color: $accent-color; + opacity: 1.0; +} +.mx_MessageComposer_input textarea::-webkit-input-placeholder { + color: $accent-color; +} + +.mx_MessageComposer_upload, +.mx_MessageComposer_hangup, +.mx_MessageComposer_voicecall, +.mx_MessageComposer_videocall, +.mx_MessageComposer_apps, +.mx_MessageComposer_stickers { + /*display: table-cell;*/ + /*vertical-align: middle;*/ + /*padding-left: 10px;*/ + padding-right: 5px; + cursor: pointer; + padding-top: 4px; +} + +.mx_MessageComposer_upload object, +.mx_MessageComposer_hangup object, +.mx_MessageComposer_voicecall object, +.mx_MessageComposer_videocall object, +.mx_MessageComposer_apps object, +.mx_MessageComposer_stickers object { + pointer-events: none; +} + +.mx_MessageComposer_formatting { + cursor: pointer; + margin: 0 11px; + width: 24px; + height: 18px; +} + +.mx_MessageComposer_formatbar_wrapper { + width: 100%; + background-color: $menu-bg-color; + box-shadow: inset 0 1px 0 0 rgba(0, 0, 0, 0.08); +} + +.mx_MessageComposer_formatbar { + margin: auto; + max-width: 960px; + display: flex; + + height: 30px; + + box-sizing: border-box; + padding-left: 62px; + + flex-direction: row; + align-items: center; + font-size: 10px; + color: $greyed-fg-color; +} + +.mx_MessageComposer_formatbar * { + margin-right: 4px; +} + +.mx_MessageComposer_format_button, +.mx_MessageComposer_formatbar_cancel, +.mx_MessageComposer_formatbar_markdown { + cursor: pointer; +} + +.mx_MessageComposer_formatbar_cancel { + margin-right: 22px; +} + +.mx_MessageComposer_formatbar_markdown { + margin-right: 64px; +} + +.mx_MessageComposer_input_markdownIndicator { + cursor: pointer; + height: 10px; + padding: 4px 4px 4px 0; + opacity: 0.8; +} + +.mx_MatrixChat_useCompactLayout { + .mx_MessageComposer_input { + min-height: 50px; + } + + .mx_MessageComposer_noperm_error { + height: 50px; + } +} diff --git a/res/css/views/rooms/_PinnedEventTile.scss b/res/css/views/rooms/_PinnedEventTile.scss new file mode 100644 index 0000000000..ca790ef8f0 --- /dev/null +++ b/res/css/views/rooms/_PinnedEventTile.scss @@ -0,0 +1,67 @@ +/* +Copyright 2017 Travis Ralston + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_PinnedEventTile { + min-height: 40px; + margin-bottom: 5px; + width: 100%; + border-radius: 5px; // for the hover +} + +.mx_PinnedEventTile:hover { + background-color: $event-selected-color; +} + +.mx_PinnedEventTile .mx_PinnedEventTile_sender { + color: #868686; + font-size: 0.8em; + vertical-align: top; + display: block; + padding-bottom: 3px; +} + +.mx_PinnedEventTile .mx_EventTile_content { + margin-left: 50px; + position: relative; + top: 0; + left: 0; +} + +.mx_PinnedEventTile .mx_BaseAvatar { + float: left; + margin-right: 10px; +} + +.mx_PinnedEventTile:hover .mx_PinnedEventTile_actions { + display: block; +} + +.mx_PinnedEventTile_actions { + float: right; + margin-right: 10px; + display: none; +} + +.mx_PinnedEventTile_unpinButton { + display: inline-block; + cursor: pointer; + margin-left: 10px; +} + +.mx_PinnedEventTile_gotoButton { + display: inline-block; + font-size: 0.8em; +} diff --git a/res/css/views/rooms/_PinnedEventsPanel.scss b/res/css/views/rooms/_PinnedEventsPanel.scss new file mode 100644 index 0000000000..663d5bdf6e --- /dev/null +++ b/res/css/views/rooms/_PinnedEventsPanel.scss @@ -0,0 +1,37 @@ +/* +Copyright 2017 Travis Ralston + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_PinnedEventsPanel { + border-top: 1px solid $primary-hairline-color; +} + +.mx_PinnedEventsPanel_body { + max-height: 300px; + overflow-y: auto; + padding-bottom: 15px; +} + +.mx_PinnedEventsPanel_header { + margin: 0; + padding-top: 8px; + padding-bottom: 15px; +} + +.mx_PinnedEventsPanel_cancel { + margin: 12px; + float: right; + display: inline-block; +} diff --git a/res/css/views/rooms/_PresenceLabel.scss b/res/css/views/rooms/_PresenceLabel.scss new file mode 100644 index 0000000000..682c849cee --- /dev/null +++ b/res/css/views/rooms/_PresenceLabel.scss @@ -0,0 +1,20 @@ +/* +Copyright 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_PresenceLabel { + font-size: 11px; + opacity: 0.5; +} \ No newline at end of file diff --git a/res/css/views/rooms/_QuotePreview.scss b/res/css/views/rooms/_QuotePreview.scss new file mode 100644 index 0000000000..86fd79d473 --- /dev/null +++ b/res/css/views/rooms/_QuotePreview.scss @@ -0,0 +1,36 @@ +.mx_QuotePreview { + position: absolute; + bottom: 0; + z-index: 1000; + width: 100%; + border: 1px solid $primary-hairline-color; + background: $primary-bg-color; + border-bottom: none; + border-radius: 4px 4px 0 0; + max-height: 50vh; + overflow: auto +} + +.mx_QuotePreview_section { + border-bottom: 1px solid $primary-hairline-color; +} + +.mx_QuotePreview_header { + margin: 12px; + color: $primary-fg-color; + font-weight: 400; + opacity: 0.4; +} + +.mx_QuotePreview_title { + float: left; +} + +.mx_QuotePreview_cancel { + float: right; + cursor: pointer; +} + +.mx_QuotePreview_clear { + clear: both; +} diff --git a/res/css/views/rooms/_RoomDropTarget.scss b/res/css/views/rooms/_RoomDropTarget.scss new file mode 100644 index 0000000000..1076a0563a --- /dev/null +++ b/res/css/views/rooms/_RoomDropTarget.scss @@ -0,0 +1,55 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_RoomDropTarget_container { + background-color: $secondary-accent-color; + padding-left: 18px; + padding-right: 18px; + padding-top: 8px; + padding-bottom: 7px; +} + +.collapsed .mx_RoomDropTarget_container { + padding-right: 10px; + padding-left: 10px; +} + +.mx_RoomDropTarget { + font-size: 13px; + padding-top: 5px; + padding-bottom: 5px; + border: 1px dashed $accent-color; + color: $primary-fg-color; + background-color: $droptarget-bg-color; + border-radius: 4px; +} + + +.mx_RoomDropTarget_label { + position: relative; + margin-top: 3px; + line-height: 21px; + z-index: 1; + text-align: center; +} + +.collapsed .mx_RoomDropTarget_avatar { + float: none; +} + +.collapsed .mx_RoomDropTarget_label { + display: none; +} diff --git a/res/css/views/rooms/_RoomHeader.scss b/res/css/views/rooms/_RoomHeader.scss new file mode 100644 index 0000000000..9c1349adbc --- /dev/null +++ b/res/css/views/rooms/_RoomHeader.scss @@ -0,0 +1,245 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* add 20px to the height of the header when editing */ +.mx_RoomHeader_editing { + flex: 0 0 93px ! important; +} + +.mx_RoomHeader_wrapper { + max-width: 960px; + margin: auto; + height: 70px; + align-items: center; + display: flex; +} + +.mx_RoomHeader_leftRow { + margin-left: -2px; + order: 1; + flex: 1; + overflow: hidden; +} + +.mx_RoomHeader_spinner { + height: 36px; + order: 2; + padding-left: 12px; + padding-right: 12px; +} + +.mx_RoomHeader_textButton { + @mixin mx_DialogButton; + margin-right: 8px; + margin-top: -5px; + order: 2; +} + +.mx_RoomHeader_textButton:hover { + @mixin mx_DialogButton_hover; +} + +.mx_RoomHeader_textButton_danger { + background-color: $warning-color; +} + +.mx_RoomHeader_cancelButton { + order: 2; + cursor: pointer; + padding-left: 12px; + padding-right: 12px; +} + +.mx_RoomHeader_rightRow { + margin-top: 4px; + background-color: $primary-bg-color; + display: flex; + align-items: center; + order: 3; +} + +.mx_RoomHeader_info { + display: table-cell; + width: 100%; + vertical-align: middle; +} + +.mx_RoomHeader_simpleHeader { + line-height: 70px; + color: $primary-fg-color; + font-size: 22px; + font-weight: bold; + overflow: hidden; + margin-left: 63px; + text-overflow: ellipsis; + width: 100%; +} + +.mx_RoomHeader_simpleHeader .mx_RoomHeader_cancelButton { + float: right; +} + +.mx_RoomHeader_simpleHeader .mx_RoomHeader_icon { + margin-left: 14px; + margin-right: 24px; + vertical-align: -4px; +} + +.mx_RoomHeader_name { + vertical-align: middle; + width: 100%; + height: 31px; + overflow: hidden; + color: $primary-fg-color; + font-weight: bold; + font-size: 22px; + padding-left: 19px; + padding-right: 16px; + /* why isn't text-overflow working? */ + text-overflow: ellipsis; + border-bottom: 1px solid transparent; +} + +.mx_RoomHeader_nametext { + display: inline-block; +} + +.mx_RoomHeader_settingsHint { + color: $settings-grey-fg-color ! important; +} + +.mx_RoomHeader_searchStatus { + display: inline-block; + font-weight: normal; + opacity: 0.6; +} + +.mx_RoomHeader_settingsButton object { + pointer-events: none; +} + +.mx_RoomHeader_name, +.mx_RoomHeader_avatar, +.mx_RoomHeader_avatarPicker, +.mx_RoomHeader_avatarPicker_edit, +.mx_RoomHeader_avatarPicker_remove { + cursor: pointer; +} + +.mx_RoomHeader_avatarPicker_remove { + position: absolute; + top: -11px; + right: -9px; +} + +.mx_RoomHeader_name:hover div:not(.mx_RoomHeader_editable) { + color: $accent-color; +} + +.mx_RoomHeader_placeholder { + color: $settings-grey-fg-color ! important; +} + +.mx_RoomHeader_editable { + border-bottom: 1px solid $strong-input-border-color ! important; + min-width: 150px; + cursor: text; +} + +.mx_RoomHeader_editable:focus { + border-bottom: 1px solid $accent-color ! important; + outline: none; + box-shadow: none; +} + +.mx_RoomHeader_topic { + vertical-align: bottom; + float: left; + max-height: 38px; + color: $settings-grey-fg-color; + font-weight: 300; + font-size: 13px; + margin-left: 19px; + margin-right: 16px; + overflow: hidden; + text-overflow: ellipsis; + border-bottom: 1px solid transparent; + column-width: 960px; +} + +.mx_RoomHeader_avatar { + display: table-cell; + width: 48px; + height: 50px; + vertical-align: middle; +} + +.mx_RoomHeader_avatar .mx_BaseAvatar_image { + object-fit: cover; +} + +.mx_RoomHeader_avatarPicker { + margin-top: 23px; + position: relative; +} + +.mx_RoomHeader_avatarPicker_edit { + margin-left: 16px; + margin-top: 4px; +} + +.mx_RoomHeader_avatarPicker_edit > label { + cursor: pointer; +} + +.mx_RoomHeader_avatarPicker_edit > input { + display: none; +} + +.mx_RoomHeader_button { + margin-left: 12px; + cursor: pointer; +} + +.mx_RoomHeader_button object { + pointer-events: none; +} + +.mx_RoomHeader_voipButton { + display: table-cell; +} + +.mx_RoomHeader_voipButtons { + margin-top: 18px; +} + +.mx_RoomHeader_pinnedButton { + position: relative; +} + +.mx_RoomHeader_pinsIndicator { + position: absolute; + right: 0; + bottom: 4px; + width: 8px; + height: 8px; + border-radius: 8px; + background-color: $pinned-color; +} + +.mx_RoomHeader_pinsIndicatorUnread { + background-color: $pinned-unread-color; +} diff --git a/res/css/views/rooms/_RoomList.scss b/res/css/views/rooms/_RoomList.scss new file mode 100644 index 0000000000..581016d5ba --- /dev/null +++ b/res/css/views/rooms/_RoomList.scss @@ -0,0 +1,67 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd +Copyright 2107 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. +*/ + +.mx_RoomList { + padding-bottom: 12px; + min-height: 400px; +} + +.mx_RoomList_expandButton { + margin-left: 8px; + cursor: pointer; + padding-left: 12px; + padding-right: 12px; +} + +/* Evil hacky override until Chrome fixes drop and drag table cells + and we can correctly fix horizontal wrapping in the sidebar again */ +.mx_RoomList_scrollbar .gm-scroll-view { + overflow-x: hidden ! important; + overflow-y: scroll ! important; +} + +/* Make sure the scrollbar is above the sticky headers from RoomList */ +.mx_RoomList_scrollbar .gm-scrollbar.-vertical { + z-index: 6; +} + +.mx_RoomList_emptySubListTip_container { + background-color: $secondary-accent-color; + padding-left: 18px; + padding-right: 18px; + padding-top: 8px; + padding-bottom: 7px; +} + +.mx_RoomList_emptySubListTip { + font-size: 13px; + padding: 5px; + border: 1px dashed $accent-color; + color: $primary-fg-color; + background-color: $droptarget-bg-color; + border-radius: 4px; + line-height: 16px; +} + +.mx_RoomList_emptySubListTip .mx_RoleButton { + vertical-align: -2px; +} + +.mx_RoomList_headerButtons { + position: absolute; + right: 60px; +} diff --git a/res/css/views/rooms/_RoomPreviewBar.scss b/res/css/views/rooms/_RoomPreviewBar.scss new file mode 100644 index 0000000000..331eb582ea --- /dev/null +++ b/res/css/views/rooms/_RoomPreviewBar.scss @@ -0,0 +1,58 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_RoomPreviewBar { + text-align: center; + height: 176px; + background-color: $event-selected-color; + align-items: center; + flex-direction: column; + justify-content: center; + display: flex; + background-color: $preview-bar-bg-color; + -webkit-align-items: center; +} + +.mx_RoomPreviewBar_wrapper { +} + +.mx_RoomPreviewBar_invite_text { + color: $primary-fg-color; +} + +.mx_RoomPreviewBar_join_text { + color: $warning-color; +} + +.mx_RoomPreviewBar_preview_text { + margin-top: 25px; + color: $settings-grey-fg-color; +} + +.mx_RoomPreviewBar_join_text a { + text-decoration: underline; + cursor: pointer; +} + +.mx_RoomPreviewBar_warning { + display: flex; + align-items: center; + padding: 8px; +} + +.mx_RoomPreviewBar_warningIcon { + padding: 12px; +} diff --git a/res/css/views/rooms/_RoomSettings.scss b/res/css/views/rooms/_RoomSettings.scss new file mode 100644 index 0000000000..4013af4c7c --- /dev/null +++ b/res/css/views/rooms/_RoomSettings.scss @@ -0,0 +1,247 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd +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. +*/ + +.mx_RoomSettings { + margin-left: 65px; + margin-bottom: 20px; +} + +.mx_RoomSettings_leaveButton, +.mx_RoomSettings_unbanButton { + @mixin mx_DialogButton; + position: relative; + margin-right: 8px; +} + +.mx_RoomSettings_leaveButton:hover, +.mx_RoomSettings_unbanButton:hover { + @mixin mx_DialogButton_hover; +} + +.mx_RoomSettings_integrationsButton_error { + position: relative; + cursor: not-allowed; +} +.mx_RoomSettings_integrationsButton_error img { + position: absolute; + right: -5px; + top: -5px; +} +.mx_RoomSettings_leaveButton, +.mx_RoomSettings_integrationsButton_error { + float: right; +} +.mx_RoomSettings_integrationsButton_error .mx_RoomSettings_integrationsButton_errorPopup { + display: none; +} +.mx_RoomSettings_integrationsButton_error:hover .mx_RoomSettings_integrationsButton_errorPopup { + display: inline; +} +.mx_RoomSettings_integrationsButton_errorPopup { + position: absolute; + top: 110%; + left: -125%; + width: 348%; + padding: 2%; + font-size: 10pt; + line-height: 1.5em; + border-radius: 5px; + background-color: $accent-color; + color: $accent-fg-color; + text-align: center; +} +.mx_RoomSettings_unbanButton { + display: inline; +} + +.mx_RoomSettings_e2eIcon { + padding-left: 4px; + padding-right: 7px; +} + +.mx_RoomSettings_leaveButton { + margin-right: 32px; +} + +.mx_RoomSettings_powerLevels { + display: table; +} + +.mx_RoomSettings_powerLevel { + display: table-row; +} + +.mx_RoomSettings_powerLevelKey, +.mx_RoomSettings_powerLevel .mx_PowerSelector { + display: table-cell; + padding-bottom: 5px; +} + +.mx_RoomSettings_powerLevelKey { + text-align: right; + padding-right: 0.3em; +} + +.mx_RoomSettings h3 { + text-transform: uppercase; + color: $h3-color; + font-weight: 600; + font-size: 13px; + margin-top: 36px; + margin-bottom: 10px; +} + +.mx_RoomSettings .mx_RoomSettings_toggles label { + margin-bottom: 8px; + display: block; +} + +.mx_RoomSettings .mx_RoomSettings_toggles input[type="checkbox"], +.mx_RoomSettings .mx_RoomSettings_toggles input[type="radio"] { + margin-right: 7px; +} + +.mx_RoomSettings .mx_RoomSettings_tags input[type="checkbox"] { + margin-left: 1em; + margin-right: 7px; +} + +.mx_RoomSettings .mx_RoomSettings_tags { + margin-bottom: 8px; +} + +.mx_RoomSettings .mx_RoomSettings_roomColor { + display: inline-block; + position: relative; + width: 37px; + height: 37px; + border: 1px solid #979797; + margin-right: 13px; + cursor: pointer; +} + +.mx_RoomSettings .mx_RoomSettings_roomColor_selected { + position: absolute; + left: 10px; + top: 4px; + cursor: default ! important; +} + +.mx_RoomSettings .mx_RoomSettings_roomColorPrimary { + height: 10px; + position: absolute; + bottom: 0px; + width: 100%; +} + +.mx_RoomSettings .mx_RoomSettings_aliasLabel { + margin-bottom: 8px; +} + +.mx_RoomSettings .mx_RoomSettings_aliasesTable { + margin-top: 12px; + margin-bottom: 0px; + margin-left: 56px; + display: table; +} + +.mx_RoomSettings .mx_RoomSettings_aliasesTableRow { + display: table-row; + margin-bottom: 16px; +} + +.mx_RoomSettings .mx_RoomSettings_alias { + max-width: 400px; + margin-bottom: 16px; + /* + commented out so margin applies + display: table-cell; */ +} + +.mx_RoomSettings .mx_RoomSettings_addAlias, +.mx_RoomSettings .mx_RoomSettings_deleteAlias { + display: table-cell; + padding-left: 0.5em; + position: relative; + cursor: pointer; +} + +.mx_RoomSettings .mx_RoomSettings_addAlias img, +.mx_RoomSettings .mx_RoomSettings_deleteAlias img { + visibility: hidden; +} + +.mx_RoomSettings .mx_RoomSettings_aliasesTableRow:hover .mx_RoomSettings_addAlias img, +.mx_RoomSettings .mx_RoomSettings_aliasesTableRow:hover .mx_RoomSettings_deleteAlias img { + visibility: visible; +} + +.mx_RoomSettings_warning { + color: $warning-color; + font-weight: bold; + margin-top: 8px; + margin-bottom: 8px; +} + +.mx_RoomSettings_editable { + border: 0px; + border-bottom: 1px solid $strong-input-border-color; + padding: 0px; + min-width: 240px; +} + +.mx_RoomSettings_editable:focus { + border-bottom: 1px solid $accent-color; + outline: none; + box-shadow: none; +} + +.mx_RoomSettings_deleteAlias, +.mx_RoomSettings_addAlias { + display: table-cell; + visibility: visible; +} + +.mx_RoomSettings_deleteAlias:hover, +.mx_RoomSettings_addAlias:hover { + visibility: visible; +} + +.mx_RoomSettings_aliasPlaceholder { + color: $settings-grey-fg-color; +} + +.mx_RoomSettings_buttons { + text-align: right; + margin-bottom: 16px; +} + +.mx_RoomSettings_button { + display: inline; + border: 0px; + height: 36px; + border-radius: 36px; + font-weight: 400; + font-size: 15px; + color: $accent-fg-color; + background-color: $accent-color; + width: auto; + margin: auto; + padding: 6px; + padding-left: 1em; + padding-right: 1em; +} diff --git a/res/css/views/rooms/_RoomTile.scss b/res/css/views/rooms/_RoomTile.scss new file mode 100644 index 0000000000..ccd3afe26c --- /dev/null +++ b/res/css/views/rooms/_RoomTile.scss @@ -0,0 +1,190 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_RoomTile { + position: relative; + cursor: pointer; + font-size: 13px; + display: block; + height: 34px; + + background-color: $secondary-accent-color; +} + +.mx_RoomTile_tooltip { + display: inline-block; + position: relative; + top: -54px; + left: -12px; +} + + +.mx_RoomTile_nameContainer { + display: inline-block; + width: 180px; + height: 24px; +} + +.mx_RoomTile_avatar_container { + position: relative; +} + +.mx_RoomTile_avatar { + display: inline-block; + padding-top: 5px; + padding-bottom: 5px; + padding-left: 16px; + padding-right: 6px; + width: 24px; + height: 24px; + vertical-align: middle; +} + +.mx_RoomTile_dm { + display: block; + position: absolute; + bottom: 0; + right: -5px; + z-index: 2; +} + +.mx_RoomTile_name { + display: inline-block; + position: relative; + width: 165px; + vertical-align: middle; + padding-left: 6px; + padding-right: 6px; + padding-top: 2px; + padding-bottom: 3px; + color: $roomtile-name-color; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.mx_RoomTile_invite { +/* color: rgba(69, 69, 69, 0.5); */ +} + +.collapsed .mx_RoomTile_nameContainer { + width: 60px; /* colapsed panel width */ +} + +.collapsed .mx_RoomTile_name { + display: none; +} + +.collapsed .mx_RoomTile_badge { + top: 0px; + min-width: 12px; + border-radius: 16px; + padding: 0px 4px 0px 4px; + z-index: 3; +} + +/* Hide the bottom of speech bubble */ +.collapsed .mx_RoomTile_highlight .mx_RoomTile_badge:after { + display: none; +} + +/* This is the bottom of the speech bubble */ +.mx_RoomTile_highlight .mx_RoomTile_badge:after { + content: ""; + position: absolute; + display: block; + width: 0; + height: 0; + margin-left: 5px; + border-top: 5px solid $warning-color; + border-right: 7px solid transparent; +} + +.mx_RoomTile_badge { + display: inline-block; + min-width: 15px; + height: 15px; + position: absolute; + right: 8px; /*gutter */ + top: 9px; + border-radius: 8px; + color: $accent-fg-color; + font-weight: 600; + font-size: 10px; + text-align: center; + padding-top: 1px; + padding-left: 4px; + padding-right: 4px; +} + +.mx_RoomTile .mx_RoomTile_badge.mx_RoomTile_badgeButton, +.mx_RoomTile.mx_RoomTile_menuDisplayed .mx_RoomTile_badge { + letter-spacing: 0.1em; + opacity: 1; +} + +.mx_RoomTile.mx_RoomTile_noBadges .mx_RoomTile_badge.mx_RoomTile_badgeButton, +.mx_RoomTile.mx_RoomTile_menuDisplayed.mx_RoomTile_noBadges .mx_RoomTile_badge { + background-color: $neutral-badge-color; +} + +.mx_RoomTile_unreadNotify .mx_RoomTile_badge { + background-color: $accent-color; +} + +.mx_RoomTile_highlight .mx_RoomTile_badge { + background-color: $warning-color; +} + +.mx_RoomTile_unread, .mx_RoomTile_highlight { + font-weight: 800; +} + +.mx_RoomTile_selected { + background-color: $roomtile-selected-bg-color; +} + +.mx_DNDRoomTile { + transform: none; + transition: transform 0.2s; +} + +.mx_DNDRoomTile_dragging { + transform: scale(1.05, 1.05); +} + +.mx_RoomTile:focus { + filter: none ! important; + background-color: $roomtile-focused-bg-color; +} + +.mx_RoomTile .mx_RoomTile_name.mx_RoomTile_badgeShown { + width: 140px; +} + +.mx_RoomTile_arrow { + position: absolute; + right: 0px; +} + +.mx_RoomTile.mx_RoomTile_transparent { + background-color: transparent; +} + +.mx_RoomTile.mx_RoomTile_transparent:focus { + background-color: $roomtile-transparent-focused-color; +} + diff --git a/res/css/views/rooms/_RoomTooltip.scss b/res/css/views/rooms/_RoomTooltip.scss new file mode 100644 index 0000000000..9988425b8f --- /dev/null +++ b/res/css/views/rooms/_RoomTooltip.scss @@ -0,0 +1,54 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_RoomTooltip_chevron { + position: absolute; + left: -8px; + top: 4px; + width: 0; + height: 0; + border-top: 8px solid transparent; + border-right: 8px solid $menu-border-color; + border-bottom: 8px solid transparent; +} + +.mx_RoomTooltip_chevron:after { + content:''; + width: 0; + height: 0; + border-top: 7px solid transparent; + border-right: 7px solid $primary-bg-color; + border-bottom: 7px solid transparent; + position:absolute; + top: -7px; + left: 1px; +} + +.mx_RoomTooltip { + display: none; + position: fixed; + border: 1px solid $menu-border-color; + border-radius: 5px; + background-color: $primary-bg-color; + z-index: 2000; + padding: 5px; + pointer-events: none; + line-height: 14px; + font-size: 13px; + color: $primary-fg-color; + max-width: 600px; + margin-right: 50px; +} diff --git a/res/css/views/rooms/_SearchBar.scss b/res/css/views/rooms/_SearchBar.scss new file mode 100644 index 0000000000..079ea16c68 --- /dev/null +++ b/res/css/views/rooms/_SearchBar.scss @@ -0,0 +1,83 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_SearchBar { + padding-top: 5px; + padding-bottom: 5px; + display: flex; + align-items: center; +} + +.mx_SearchBar_input { + display: inline block; + border-radius: 3px 0px 0px 3px; + border: 1px solid $input-border-color; + font-size: 15px; + padding: 9px; + padding-left: 11px; + width: auto; + flex: 1 1 0; +} + +.mx_SearchBar_searchButton { + cursor: pointer; + margin-right: 10px; + width: 37px; + height: 37px; + border-radius: 0px 3px 3px 0px; + background-color: $accent-color; +} + +@keyframes pulsate { + 0% { opacity: 1.0; } + 50% { opacity: 0.1; } + 100% { opacity: 1.0; } +} + +.mx_SearchBar_searching img { + animation: pulsate 0.5s ease-out; + animation-iteration-count: infinite; +} + +.mx_SearchBar_button { + display: inline; + border: 0px; + border-radius: 36px; + font-weight: 400; + font-size: 15px; + color: $accent-fg-color; + background-color: $accent-color; + width: auto; + margin: auto; + margin-left: 7px; + padding-top: 6px; + padding-bottom: 4px; + padding-left: 24px; + padding-right: 24px; + cursor: pointer; +} + +.mx_SearchBar_unselected { + background-color: $primary-bg-color; + color: $accent-color; + border: $accent-color 1px solid; +} + +.mx_SearchBar_cancel { + padding-left: 14px; + padding-right: 14px; + cursor: pointer; +} diff --git a/res/css/views/rooms/_SearchableEntityList.scss b/res/css/views/rooms/_SearchableEntityList.scss new file mode 100644 index 0000000000..37a663123d --- /dev/null +++ b/res/css/views/rooms/_SearchableEntityList.scss @@ -0,0 +1,77 @@ +/* +Copyright 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_SearchableEntityList { + display: flex; + + flex-direction: column; +} + +.mx_SearchableEntityList_query { + font-family: $font-family; + border-radius: 3px; + border: 1px solid $input-border-color; + padding: 9px; + color: $primary-fg-color; + background-color: $primary-bg-color; + margin-left: 3px; + font-size: 15px; + margin-bottom: 8px; + width: 189px; +} + +.mx_SearchableEntityList_query::-moz-placeholder { + color: $primary-fg-color; + opacity: 0.5; + font-size: 12px; +} + +.mx_SearchableEntityList_query::-webkit-input-placeholder { + color: $primary-fg-color; + opacity: 0.5; + font-size: 12px; +} + +.mx_SearchableEntityList_listWrapper { + flex: 1; + + overflow-y: auto; +} + +.mx_SearchableEntityList_list { + display: table; + table-layout: fixed; + width: 100%; +} + +.mx_SearchableEntityList_list .mx_EntityTile_chevron { + display: none; +} + +.mx_SearchableEntityList_hrWrapper { + width: 100%; + flex: 0 0 auto; +} + +.mx_SearchableEntityList hr { + height: 1px; + border: 0px; + color: $primary-fg-color; + background-color: $primary-fg-color; + margin-right: 15px; + margin-top: 11px; + margin-bottom: 11px; +} diff --git a/res/css/views/rooms/_Stickers.scss b/res/css/views/rooms/_Stickers.scss new file mode 100644 index 0000000000..669ca13545 --- /dev/null +++ b/res/css/views/rooms/_Stickers.scss @@ -0,0 +1,35 @@ +.mx_Stickers_content { + overflow: hidden; +} + +.mx_Stickers_content_container { + overflow: hidden; + height: 300px; +} + +.mx_Stickers_content .mx_AppTileFullWidth { + border: none; +} + +.mx_Stickers_contentPlaceholder { + display: flex; + flex-grow: 1; + flex-direction: column; + align-items: center; + justify-content: center; + text-align: center; +} + +.mx_Stickers_contentPlaceholder p { + max-width: 200px; +} + +.mx_Stickers_addLink { + display: inline; + cursor: pointer; + text-decoration: underline; +} + +.mx_Stickers_hideStickers { + z-index: 2001; +} diff --git a/res/css/views/rooms/_TopUnreadMessagesBar.scss b/res/css/views/rooms/_TopUnreadMessagesBar.scss new file mode 100644 index 0000000000..1ee56d9532 --- /dev/null +++ b/res/css/views/rooms/_TopUnreadMessagesBar.scss @@ -0,0 +1,53 @@ +/* +Copyright 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_TopUnreadMessagesBar { + margin: auto; /* centre horizontally */ + max-width: 960px; + padding-top: 10px; + padding-bottom: 10px; + border-bottom: 1px solid $primary-hairline-color; +} + +.mx_TopUnreadMessagesBar_scrollUp { + display: inline; + cursor: pointer; + text-decoration: underline; +} + +.mx_TopUnreadMessagesBar_scrollUp img { + padding-left: 10px; + padding-right: 31px; + vertical-align: middle; +} + +.mx_TopUnreadMessagesBar_scrollUp span { + opacity: 0.5; +} + +.mx_TopUnreadMessagesBar_close { + float: right; + padding-right: 14px; + padding-top: 3px; + cursor: pointer; +} + +.mx_MatrixChat_useCompactLayout { + .mx_TopUnreadMessagesBar { + padding-top: 4px; + padding-bottom: 4px; + } +} diff --git a/res/css/views/settings/_DevicesPanel.scss b/res/css/views/settings/_DevicesPanel.scss new file mode 100644 index 0000000000..e4856531d9 --- /dev/null +++ b/res/css/views/settings/_DevicesPanel.scss @@ -0,0 +1,51 @@ +/* +Copyright 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_DevicesPanel { + display: table; + table-layout: fixed; + width: 880px; + border-spacing: 2px; +} + +.mx_DevicesPanel_header { + display: table-header-group; + font-weight: bold; +} + +.mx_DevicesPanel_header > div { + display: table-cell; +} + +.mx_DevicesPanel_header .mx_DevicesPanel_deviceLastSeen { + width: 30%; +} + +.mx_DevicesPanel_header .mx_DevicesPanel_deviceButtons { + width: 20%; +} + +.mx_DevicesPanel_device { + display: table-row; +} + +.mx_DevicesPanel_device > div { + display: table-cell; +} + +.mx_DevicesPanel_myDevice { + font-weight: bold; +} \ No newline at end of file diff --git a/res/css/views/settings/_IntegrationsManager.scss b/res/css/views/settings/_IntegrationsManager.scss new file mode 100644 index 0000000000..93ee0e20fe --- /dev/null +++ b/res/css/views/settings/_IntegrationsManager.scss @@ -0,0 +1,31 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_IntegrationsManager .mx_Dialog { + width: 60%; + height: 70%; + overflow: hidden; + padding: 0px; + max-width: initial; + max-height: initial; +} + +.mx_IntegrationsManager iframe { + background-color: #fff; + border: 0px; + width: 100%; + height: 100%; +} diff --git a/res/css/views/settings/_Notifications.scss b/res/css/views/settings/_Notifications.scss new file mode 100644 index 0000000000..4c88e44952 --- /dev/null +++ b/res/css/views/settings/_Notifications.scss @@ -0,0 +1,70 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_UserNotifSettings_tableRow +{ + display: table-row; +} + +.mx_UserNotifSettings_inputCell { + display: table-cell; + padding-bottom: 8px; + padding-right: 8px; + width: 16px; +} + +.mx_UserNotifSettings_labelCell +{ + padding-bottom: 8px; + width: 400px; + display: table-cell; +} + +.mx_UserNotifSettings_pushRulesTableWrapper { + padding-bottom: 8px; +} + +.mx_UserNotifSettings_pushRulesTable { + width: 100%; + table-layout: fixed; +} + +.mx_UserNotifSettings_pushRulesTable thead { + font-weight: bold; + font-size: 15px; +} + +.mx_UserNotifSettings_pushRulesTable tbody th { + font-weight: 400; + font-size: 15px; +} + +.mx_UserNotifSettings_pushRulesTable tbody th:first-child { + text-align: left; +} + +.mx_UserNotifSettings_keywords { + cursor: pointer; + color: $accent-color; +} + +.mx_UserSettings_devicesTable td { + padding-left: 20px; + padding-right: 20px; +} +.mx_UserSettings_devicesTable_nodevices { + font-style: italic; +} diff --git a/res/css/views/voip/_CallView.scss b/res/css/views/voip/_CallView.scss new file mode 100644 index 0000000000..deb89a837c --- /dev/null +++ b/res/css/views/voip/_CallView.scss @@ -0,0 +1,25 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_CallView_voice { + background-color: $accent-color; + color: $accent-fg-color; + cursor: pointer; + text-align: center; + padding: 6px; + font-weight: bold; + font-size: 13px; +} \ No newline at end of file diff --git a/res/css/views/voip/_IncomingCallbox.scss b/res/css/views/voip/_IncomingCallbox.scss new file mode 100644 index 0000000000..64eac25d01 --- /dev/null +++ b/res/css/views/voip/_IncomingCallbox.scss @@ -0,0 +1,69 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_IncomingCallBox { + text-align: center; + border: 1px solid #a4a4a4; + border-radius: 8px; + background-color: $primary-bg-color; + position: fixed; + z-index: 1000; + padding: 6px; + margin-top: -3px; + margin-left: -20px; + width: 200px; +} + +.mx_IncomingCallBox_chevron { + padding: 12px; + position: absolute; + left: -21px; + top: 0px; +} + +.mx_IncomingCallBox_title { + padding: 6px; + font-weight: bold; +} + +.mx_IncomingCallBox_buttons { + display: flex; +} + +.mx_IncomingCallBox_buttons_cell { + vertical-align: middle; + padding: 6px; + flex: 1; +} + +.mx_IncomingCallBox_buttons_decline, +.mx_IncomingCallBox_buttons_accept { + vertical-align: middle; + width: 80px; + height: 36px; + line-height: 36px; + border-radius: 36px; + color: $accent-fg-color; + margin: auto; +} + +.mx_IncomingCallBox_buttons_decline { + background-color: $voip-decline-color; +} + +.mx_IncomingCallBox_buttons_accept { + background-color: $voip-accept-color; +} diff --git a/res/css/views/voip/_VideoView.scss b/res/css/views/voip/_VideoView.scss new file mode 100644 index 0000000000..feb60f4763 --- /dev/null +++ b/res/css/views/voip/_VideoView.scss @@ -0,0 +1,49 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_VideoView { + width: 100%; + position: relative; + z-index: 30; +} + +.mx_VideoView video { + width: 100%; +} + +.mx_VideoView_remoteVideoFeed { + width: 100%; + background-color: #000; + z-index: 50; +} + +.mx_VideoView_localVideoFeed { + width: 25%; + height: 25%; + position: absolute; + left: 10px; + bottom: 10px; + z-index: 100; +} + +.mx_VideoView_localVideoFeed video { + width: auto; + height: 100%; +} + +.mx_VideoView_localVideoFeed.mx_VideoView_localVideoFeed_flipped video { + transform: scale(-1, 1); +} From cdb5d489a45c475248da8f564c4a7ead79d6c335 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Thu, 12 Apr 2018 00:24:22 +0100 Subject: [PATCH 0758/1160] organise themes (even light & dark) in the SDK layer --- res/themes/dark/css/_dark.scss | 204 ++++++++++++++++++++++++++++++++ res/themes/dark/css/dark.scss | 3 + res/themes/light/css/light.scss | 2 + 3 files changed, 209 insertions(+) create mode 100644 res/themes/dark/css/_dark.scss create mode 100644 res/themes/dark/css/dark.scss create mode 100644 res/themes/light/css/light.scss diff --git a/res/themes/dark/css/_dark.scss b/res/themes/dark/css/_dark.scss new file mode 100644 index 0000000000..31773ebd09 --- /dev/null +++ b/res/themes/dark/css/_dark.scss @@ -0,0 +1,204 @@ + +// typical text (dark-on-white in light skin) +$primary-fg-color: #dddddd; +$primary-bg-color: #2d2d2d; + +// used for focusing form controls +$focus-bg-color: #101010; + +// used for dialog box text +$light-fg-color: #747474; + +// button UI (white-on-green in light skin) +$accent-fg-color: $primary-bg-color; +$accent-color: #76CFA6; + +$selection-fg-color: $primary-fg-color; + +$focus-brightness: 200%; + +// red warning colour +$warning-color: #ff0064; + +// groups +$info-plinth-bg-color: #454545; + +$other-user-pill-bg-color: rgba(255, 255, 255, 0.1); + +$preview-bar-bg-color: #333; + +// left-panel style muted accent color +$secondary-accent-color: $primary-bg-color; +$tertiary-accent-color: #454545; + +// stop the tinter trying to change the secondary accent color +// by overriding the key to something untintable +// XXX: this is a bit of a hack. +#mx_theme_secondaryAccentColor { + color: #c0ffee ! important; +} + +#mx_theme_tertiaryAccentColor { + color: #c0ffee ! important; +} + +// used by RoomDirectory permissions +$plinth-bg-color: #474747; + +// used by RoomDropTarget +$droptarget-bg-color: rgba(45,45,45,0.5); + +// used by AddressSelector +$selected-color: #000000; + +// selected for hoverover & selected event tiles +$event-selected-color: #353535; + +// used for the hairline dividers in RoomView +$primary-hairline-color: #474747; + +// used for the border of input text fields +$input-border-color: #3a3a3a; + +// apart from login forms, which have stronger border +$strong-input-border-color: #656565; + +// used for UserSettings EditableText +$input-underline-color: $primary-fg-color; +$input-fg-color: $primary-fg-color; + +// context menus +$menu-border-color: rgba(187, 187, 187, 0.5); +$menu-bg-color: #373737; + +$avatar-initial-color: #2d2d2d; +$avatar-bg-color: #ffffff; + +$h3-color: $primary-fg-color; + +$dialog-background-bg-color: #000; +$lightbox-background-bg-color: #000; + +$greyed-fg-color: #888; + +$neutral-badge-color: #888; + +$preview-widget-bar-color: $menu-bg-color; +$preview-widget-fg-color: $greyed-fg-color; + +$blockquote-bar-color: #ddd; +$blockquote-fg-color: #777; + +$settings-grey-fg-color: #a2a2a2; + +$voip-decline-color: #f48080; +$voip-accept-color: #80f480; + +$rte-bg-color: #353535; +$rte-code-bg-color: #000; + +// ******************** + +$roomtile-name-color: rgba(186, 186, 186, 0.8); +$roomtile-selected-bg-color: #333; +$roomtile-focused-bg-color: rgba(255, 255, 255, 0.2); + +$roomsublist-background: rgba(0, 0, 0, 0.2); +$roomsublist-label-fg-color: $h3-color; +$roomsublist-label-bg-color: $tertiary-accent-color; +$roomsublist-chevron-color: $accent-color; + +$panel-divider-color: rgba(118, 207, 166, 0.2); + +// ******************** + +$widget-menu-bar-bg-color: $tertiary-accent-color; + +// ******************** + +// event tile lifecycle +$event-encrypting-color: rgba(171, 221, 188, 0.4); +$event-sending-color: #888; +$event-notsent-color: #f44; + +// event redaction +$event-redacted-fg-color: #606060; +$event-redacted-border-color: #000000; + +// event timestamp +$event-timestamp-color: #acacac; + +$edit-button-url: "../../img/icon_context_message_dark.svg"; +$copy-button-url: "../../img/icon_copy_message_dark.svg"; + +// e2e +$e2e-verified-color: #76cfa5; // N.B. *NOT* the same as $accent-color +$e2e-unverified-color: #e8bf37; +$e2e-warning-color: #ba6363; + +/*** ImageView ***/ +$lightbox-bg-color: #454545; +$lightbox-fg-color: #ffffff; +$lightbox-border-color: #ffffff; + +// unused? +$progressbar-color: #000; + +// XXX: copypasted from _base in order to pick up the right FG color... +@define-mixin mx_DialogButton { + /* align images in buttons (eg spinners) */ + vertical-align: middle; + border: 0px; + border-radius: 36px; + font-family: $font-family; + font-size: 14px; + color: $accent-fg-color; + background-color: $accent-color; + width: auto; + padding: 7px; + padding-left: 1.5em; + padding-right: 1.5em; + cursor: pointer; + display: inline-block; + outline: none; +} + +// Nasty hacks to apply a filter to arbitrary monochrome artwork to make it +// better match the theme. Typically applied to dark grey 'off' buttons or +// light grey 'on' buttons. +.mx_filterFlipColor { + filter: invert(1); +} + +.gm-scrollbar .thumb { + filter: invert(1); +} + +// markdown overrides: +.mx_EventTile_content .markdown-body pre:hover { + border-color: #808080 !important; // inverted due to rules below +} +.mx_EventTile_content .markdown-body { + pre, code { + filter: invert(1); + } + + pre code { + filter: none; + } + + table { + tr { + background-color: #000000; + } + + tr:nth-child(2n) { + background-color: #080808; + } + } +} + +// Add a line to the right side of the left panel to distinguish it from the middle panel +.mx_LeftPanel { + border-right: 1px solid $tertiary-accent-color; +} diff --git a/res/themes/dark/css/dark.scss b/res/themes/dark/css/dark.scss new file mode 100644 index 0000000000..5a37d0368e --- /dev/null +++ b/res/themes/dark/css/dark.scss @@ -0,0 +1,3 @@ +@import "_base.scss"; +@import "_dark.scss"; +@import "../_components.scss"; diff --git a/res/themes/light/css/light.scss b/res/themes/light/css/light.scss new file mode 100644 index 0000000000..ea0f93d5a3 --- /dev/null +++ b/res/themes/light/css/light.scss @@ -0,0 +1,2 @@ +@import "_base.scss"; +@import "../_components.scss"; \ No newline at end of file From 848403a0abbe545030bb4d83918160fec6623800 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Thu, 12 Apr 2018 00:24:51 +0100 Subject: [PATCH 0759/1160] move default fonts over from riot-web --- res/fonts/Fira_Mono/FiraMono-Bold.ttf | Bin 0 -> 134512 bytes res/fonts/Fira_Mono/FiraMono-Regular.ttf | Bin 0 -> 140212 bytes res/fonts/Fira_Mono/OFL.txt | 92 ++++++++ res/fonts/Open_Sans/LICENSE.txt | 202 ++++++++++++++++++ res/fonts/Open_Sans/OpenSans-Bold.ttf | Bin 0 -> 224592 bytes res/fonts/Open_Sans/OpenSans-BoldItalic.ttf | Bin 0 -> 213292 bytes res/fonts/Open_Sans/OpenSans-Italic.ttf | Bin 0 -> 212896 bytes res/fonts/Open_Sans/OpenSans-Regular.ttf | Bin 0 -> 217360 bytes res/fonts/Open_Sans/OpenSans-Semibold.ttf | Bin 0 -> 221328 bytes .../Open_Sans/OpenSans-SemiboldItalic.ttf | Bin 0 -> 212820 bytes 10 files changed, 294 insertions(+) create mode 100755 res/fonts/Fira_Mono/FiraMono-Bold.ttf create mode 100755 res/fonts/Fira_Mono/FiraMono-Regular.ttf create mode 100755 res/fonts/Fira_Mono/OFL.txt create mode 100755 res/fonts/Open_Sans/LICENSE.txt create mode 100755 res/fonts/Open_Sans/OpenSans-Bold.ttf create mode 100755 res/fonts/Open_Sans/OpenSans-BoldItalic.ttf create mode 100755 res/fonts/Open_Sans/OpenSans-Italic.ttf create mode 100755 res/fonts/Open_Sans/OpenSans-Regular.ttf create mode 100755 res/fonts/Open_Sans/OpenSans-Semibold.ttf create mode 100755 res/fonts/Open_Sans/OpenSans-SemiboldItalic.ttf diff --git a/res/fonts/Fira_Mono/FiraMono-Bold.ttf b/res/fonts/Fira_Mono/FiraMono-Bold.ttf new file mode 100755 index 0000000000000000000000000000000000000000..4b8b1cfbcb1ba253d560fc2dcb50787c7f17e3ea GIT binary patch literal 134512 zcmd4434BylvOj*8PC9$i=`G#q^qOAM>8zdZ&QA7(07-xV34{>#ebKOQq9Pz50^>G{ z$_SzZi0FuefIfc?;tH-a&v8T%9mc1Q`W(k`)O7yey7%@15og}-{r{iOA1u!4bI(0X zovJ!jb?RIhmSGqL{*f_h4P%El;}^$p$#am#HFva+RXv#eBg6jlbriqaJa$~&_xWFq zWY{0~FihIZ?PCjy{pZ&Ho?+O#P`_{b!l_H<8a|hy!5KgFeKL-W!#|EFl?@s*Ap0jZ2%I*g~b>sJU7>{hh;^|X!kKJYmx&R0KY*w@fs?6*r6_b;9JXyJDZ`-dkO#umHe+L=oljRi`EF}{lW zV;RB?$JCuXwEXmx)XKjz@%$$!Vb0e7>TOETrF>Bt{A(~t_OMKky78zh{vmYggGqR~ zEBMzRx?~RvElCe4k+D=FW4R_~5;KR9OV1OiJH_=3kKZz`i#x@{pkyltY%wFmlMrG)K za1bznJd5-nVi|J}QW`U*4k>>xQtFq+H4NYcFM>sLTYA1E}sOz)V0KU@U;F_JciGH+ztEIHYG`1K(0)TK$^Zi#T(FpM{ z&6(aO{8CC#0H8Vd{6tFQr+4XjsP8M& z68~J8hSu-jO_gW^yeH5Yt?xhZo8BcpxiYQAbE1Euwa~mm;|q<0@V7{U-AJzkoCE9y z90Du>%m)zP5iA5y*)IT8_bgy0fa+fhpy%&J!2#qC0#Il01EgmFb34+I-0YU}ct@BYtsRY>)&Mjhtce17DlY-hGs;&1{Nir`N7#8tUWVl; z-WSTPC?oo(y6Bgw0Z>^nAO%2cO3x<)s1D(n>JWgs;CN zMO(DnGO+-{2LZkFH>4qaMdOO(0DcQ?hHypu9m!$hI}@G_Af@>c9+Jf}0jKnCE}#uS z>qpP>q_%X(H%0-?lkgBtuk@U7Ol=UKQXT3Cv?1^|;f&g$vMfL+fc5~4iBSU3mmo{1 zZ(4U+vvCrjZDCGSmH?o>s1Kq$!XM3z@PKuoeN|YWZlu(f9ncN{-3T}*T+%oQ&(sd} zMJWTIXM`_WOTq`{BhZ&Nk_xyY+!IboX3?4u9%y~3jA((zMsuP(J*W0VD?bLuYy z=BP4y_DU2G4TPW)d4hWZz^^dZJ;)Oz0d@d3OX*gmcT2x1e-N-&f^$e;15o|P0J{L& z0RNMBY0NbM2IKe|Da{XSE9~8Wj7mR4{!Qukds0eel>e*rn{=!%0ikq*_*+=(1hgx` z;5$-(QYzrD73w+ zmU!q1u8Y!8o_>d(htmJ)b7~_RLhbzjJq_W2#u>s(XdcmH57nb*|4w;yovY=UQuHYS z)d}I8Qu-Y|p3v`58s;<5>i+L3|M%ui5Xag+~3Fo z#oB?FLwqgZj(9y5bcpM|%tbty{FNNO+tH*bBH8K+oR; z901U|WCCd1dqfcAFX4l5^$cJoKv-j>G}jLRc7OpuIHL4UEI)iT@HW7g0*?b_Ul)82 z^qXhkjfi=dk@1J|;A3V3=w$|S$;^6Y2Xi00p54t3a+zF!dx3k2JI~AbI6jG2@-E)b zZ{oM|+xcJd=VVE;c3F>Xifp=Und}#`du97%hh)Ezos>N*dsX(D?2odKWd9}m(i~?_ zG^@>ev(aodJIsaVa&v=uiFv*GI`a9hHt6N1db3G2JoCG2fZz{8g^}2QD}`I7oQFEX_1aW-n&>BbR|$p1~~N;Tb-b zPvFye2k+xI@>?*=9sE8SD@&1$mi5Y}$*z^{l-(iQD?2DVB0G**zJgi4BfBX3MD~SQ zj#;LgwPphxG&IXHVU|lV%MF*!a;#;i<&rc@1!k!W&$7=tLz<=8<`8Dd*puwn*bjzh zdB*;d{ha;x_CMPHV*e7eEDz6eremJdjakP0zzVZu2me0!(cs&I&kvp+d~C2~uy9Zv z+#K8#Tp1i692e{iwg;<%MFSrXd^B)z;KP9n14jlP88|#}XyDfa_Y7P=aNWSVffWPG z2Cf-cI52%+>Ol9v=z&oK!!H(JEW8NWbJ2OxanW{Be=+@H{D<#<_@|Gq|M1-ppZ;*d zhvPnM{jmANnhy;ZKEJT{!p#>pU08o%-Gwz5R$f^4;U6x{y)cSlE_gq9>w~*4e0t$e zA1wQz|NS@4?>&Fl`P^{02=SrNBhc7sUK!fO71@z0k3MWf`s{D0{WKfu*+wOk!{2OorH4W5O! zQ~2+H)d3I55Ce{vGjZ^1CNPOi5_lqoNoCR)1(VJw85N^uG>n$XV04V0$z%*n7Gq>g z;2R5LWo(cjcE-Ut85fg--6)swFnLTqQ@|85Mez7~nG(jw_?ZAx%9JtXOa)WPR58`e zFs6p7W$KuErh#c>nwVy$g&EGYG9#Fg%qXUfX=gf^(aae5W;>a2%y?!313QkH2rp_6 zGnwgSrZ9cXRLpz}b2GDzxrMo%xtrO`Jjm>44loZh4>7-H4l$1~hnXYHqs(K>QRZ>x zH_S2Sx6G5wapnZ`6!Q%8H1i+Kvs@Fil$piMhCScHtY-Ex*Fpj>U{*q|-@$B!)cpms zjJuP&i$!!@LFN>5BQq27d^cOq-Og=i7Q_A@4(Yj(+06Ws z)v#KwimT@8xdvK0<|N<9{En^UMsahw5!^`rI(`G!%&fthHgc`ZCdi?im|L0c%r0g( z^9yDtd;T@1p_cQl0e`iO*8{W@$u%p>A%vyFFJC<$3YT-}J2KpC&mWqk+FNgyx zDFXSc&4Bd)+68tMb1#X&wj+H9a319yV%NM3`SHj@E8*jipM(_D%wr~OFVb`XJo7A8mv;bM z$YX5058y|B7SfG?O~}tdx&^Qm`T0n1aR?@&iaQ4%rlpJ02-;Bt!pPBGPLC%a8|NWjg`CKwg3L4#2(0tC0eSGW5q~ zAw38IF$Vn+B%kb*u4IM9H3i3nU9QqZLtbj1PJ=IcZN z88GGzfE_5Gi1e@s++2pSVEqZWc}O)PaPyI3ECk?C#)7dBfDai9@I}BaLOK>eYquEb zPQWjbUyJk-;8Wx`F>q#yz->bsD+0Kev8IZ^-GUVBY6ZSHjL!<35pZbFssj+Nb|D3x z2p}aGE7p>L2cKATMS!GWtSusNw6e~a)FCnIm$sZKd=A} z`RnMEO$7dWhW%Tb01STvgYAUzj5yB3cXU0*vOBtuvwb%mXBx7e!fwh>>CHRNupYCy zac;v=whuoz4+`8CWrf@yO83+%&px8=A+Em zuDSTPv&(X{raLp7o!Q-8j&@|!4qid^t=(v0p40+Tp{QU0m0~<2%tv`gN7v}CqZ=AB zkJdDFXId=g#-q=6bRB)RA=A>`jasqckz&N_=4MD^mSfDZZaj|@TN&GRv?lW?)4g>o zwK=xSW;wcH>(fk1uS!AL5)-ZOrQ;5qVYJpp#zN}u~{;y04lx(k@KgWM7OOW|xt+HoiU&nODyd9eoyI#)7-SX3Mj<{>%o{W1t?wk1Z_>~Eo zgz*Wd60M1I689#)nN*#$KIv4_C&||2hU6zwl2R6>98PtlE=~P5Ejw*_+QGCR6-|ou zipLeND?U!=(yi(K^w#v(m7U7ts&duCYDWFNrc-mb=7QF&ouU0CqbB1%ol*CI?nnJ5 z{e{fZ%mtax7&t?xVWZ(y!~0o|tlq47SsasDWXxI^jB#bGJL&UFfcKx41jqeeMPBmF|tXOm0$cMs9X)VQyt^OYUu+3{SSF&{OGY z@pO9r;JN7e!t;GzY+ica>iq2d!u-nomi*5AzWfFGEAuzz@66wm|6Re(f;|Nf7d%n$ zY{9Dq?-Z66zFT;y@aw{0Q9_ZX$Xb+NR9@6nG^VJxXkO8)#pT6K#bb(li{}+DFTSDp zQ}0CYEbm?3OC>!eb4r$$Y$(}Ya;D_XlJ`qKE&0~R`BHp(pTpPVd(!uu@0{;l-zDGI zzMwzBztaD{|5N|B0WOdd&<7lWH%sp--CugN^i=7KrEiyBDE++jyE0i>TG@&6^75wg zG3EDFa1|*P`ikC)a~1DaT&noGB3PMFsj0M9=2wZ@8%wX$ks z)y}FtRS#D^QSGQMuCA_btsY-Jt$I=Q>gr9^C#v7B{$dz6ta{kQVaJDkT%)fktr=O< zSF^h2)0$wdySAxzdF|u1uh)KBmsFQu*HO2j?r`0+b#K>wQg5ht)tA)Q)Q_z1s-IE6 zq<(Gv#`^8`x7F{df4ly@`i~nr8oC<#8g6UY)3CqcLc=EwUp0K!=xHoztZaOs@nGZk zO$@>D}gO%|}{_TaFA*8NO)vyR9Xy8(QCQy)?o#V*iN4Be{`_ zMxGv3JZi_N3vI1!_qE5iuW#SlenAw4doPbhtWh>)6w=zvF1f@zLp{7mR*( z^sA%a8KWO#9W!Ulk}-FU`C`nsWBbOw*Ximk>0H_Qc;|`E=Q>~R{BfLYT+%qzxSnx) z$2~mmPUGH~ycAxJ4d}8&)rilk9l}_3?Y3HQZdlGu) z^*r2jwC7^ar#)X!Hcxg<{=S#%t?Av=`|=e1l-?F5JKH@WSsFH7pvr z==fsC;^M{Ciw`eREio_gNPlaVbS{~-WYLn_mYi5};Tr2Teb?;2=JYk6Uz>jIwf$}V zv-;QfZ|}dOe{cW6{wMmM>3^~R&HnfLFZF-b|NTCUBhFLNwAxO~y_(<_QsY+7;0iUTX2TybW_A68si@$Jgkm70}~mHw4Y zE61$dzVh_S?^czpx?$BbtG-)Zyn4av1FPR%<6hId=9#q_Yd5Vuy7sGe+3QNz)vRk- zw`kqx>r2-^u>Rt8Y1dU>H|x6FuKRq0`TDf$>#pB_{qgHxz5c@WU*C{)gY|~;8#->7 zcf*Do?z-W~4KLpC{te&Wm~^A##>yKzZ=84ImK*opc>2aqHp(^{H87|%=1n!5`ZjIYbl0XQH@&^->&*$9{hKFl zUcY(I<};hW+M?f5y=B^#O$XMPc5gei?c?o9+pD+F+P;1Jv)ezvMRQBrEvs+Yf6IG2j5~UF z9NBSt$Gba%x2E6fxV8M&wp*v&y7bm9x88m0@mpWN^^2XcJM}v~JF9n&**Rn9%AMPH z?%nys&KGySxAUuAvR#^8u3hE3+HRY1{}T^>Dm`@Vp~HvXJoMdRKk5oR=^T>`zo_XYx zBdR0gkG%J&@zH6I9(eTAqrFGpe5~oQ6OTXfo2K8q`h@$5l~25PtoYb{$1Xh?_hiSD zdrq`GEqnTt=k`B$`nivPXa3!o-<>ok z5dP-B?0>oX<))X9y!_rP##gR=W$!DWzPjMmO=mS{XPsSicKO-$XE&YQarTb0_nkd( z_Q=^M&pvbZ%-M5i|A4>mpS^VUi?iRJ4W5fVmvT;X&UnsoF8`eWT=lu8b8Y9wpX)uh z_1x}rcb|LU+`)5?pF45xxpUvW#=I8yTH0$%U)%B8!>^rtUG{p$>kY5Zd42!u7hVs( zVSJJI{$LNgDEQI?Y4HiEe!JF@ zrHzY8OinkLQ_Z=$M31*pm71y|km>*VbxF*D?w7;k)aw^X2@0tLfYcVqm#mlwuH z!%X2Yy3f@IReO96rA3#LqO&L+J_NcQ3yyfw;iI2a?1R?CF&o%(>^sn+2xo%g27Ji~ zXHk77hWm`6K4TaZh<$p|?=O^hD%+KJDbY|y@Dl=R*M@)mm_sI%zI#G*P}1wls5xk< zKpRycb%04pLx`suP}QruPoh;0_7c>^|pS1y1$20z))b=4!48!+*HP_NH049ADx)PNF5HR+Q`%T%GEX>eg!ldEmB{JKj8DK@q;fx z6+f>sa#~+(Ec<&ymC4)YGZ=hr-q9oa?W3&Cc?%~moIJXEnte-#z3L@dl2&ER;&~+A=d!0ZkC~Hj`)x6~reH&sTX`sj-IJtBSH#~EV+R@V zgMZ{YxmPjcRIIZT{PncNaXOl7XucBVM&_GK2*?%JvsIi;|sy0oW2jqEqI zF>oHrnO_39$+Zf2K;^)X9G*-$QwnGSATm#g+gyn>Zt`&^7w_8XT?Gp4pe;KFW`}#z zj)kzpO=*WS(ax*@#7(Y^fmhEC51t(z6c%ZntTu-DK31*Lc#Hi3Q5pz5ue?h6{!Vtn zxZtT|oi0_O)g{jvQC~lDWPSaJvne`VN}5)eGJ8aQ!-x?L^&^}%?seO?LU&$XUVdKw z=&r8Oqk6i7#g`RK>LT8;BRZfC{yIDSv)6@qCykJn7R4$I6@c7`GmLnPuy_KjVq%P- zoa0OyFrfuC)y4yH6QK8O}q_C8==Z~GFkeQcfSLNw!o>r~eo$d6_3jUxlWu&q_Dyv6ZT$P%17F2No zqGg33qcR8^SI|{h82t@`NEAYNXZzqZ_AEaUzVSr76N`7!3cy3e8uEOe<`U4R@NB*+ zr@}eg(_U$_RknL(J1cTjY;WVzIn%w3-Z?98ojCE%?WH9$8vvxJZO`6CoFvvXo2DJukMD62iseMAQ0$4K+MI4bMfI^l9a<# zwQ{H28E^))POm(mWmn8xR9~}b`pvHOnwvH2b2x5#$J%urGqvlhw%<~{9v!go=1<{b zxpZKx7-P9|9C9Kw!K4?Mlmuxk=!ZobM}ib`6k-YT)8}Ou-F4SZciwpuyL`=_J!|$* z+ouLg*t?n6Fi%=TKD36?9Ajuh34}IRIpnd!@gLO%h1D8O%RH}EH$A_)y1-ajwD0#R z1sE#YTL985+{sn)Md+XCOVlz%3G&Nz?EbY&%J?~Dv=d6Hq_5~}Z0xPjWmfdoH&3b10Uwww z=fZxUfYT#sj?!KpnPX%xC&5Mg90z$7BS|dHAwQwoqi~RMvhA{)Xr~bor+-bxc(+% zu{*mWYnprM=!))2BgZ(~dKNdWzGlqwt~!&u&|+^5)R_IlMVi!sCNeRH0&GLl9C#Ws zA2kOJ6=+21js=H4MbbS9sY4j92E)w~=Osr*3vdDg0Fv%J9(zL5_F&o`OxuHLdjvXB zic=t!R#GWIBBW1X*P~h50#XLkbr&vgDebB*hx^?!Z>BHLAcqST$=Xh(YN{6NA z<(CKY-1S-9-26gAQEhfzhe8&k&8f=qj4HSIi#u(mlA=K2qP#pup4lMI--9)DWBw^P zWt8S0OVf>wntw!TIEh(@v^~<=cu-1`By{YMI2NB$%R^yPd)4fp_XIzBcFVq%>029j z?b0{r-T6<|>r`cNPukj}&v&*i%Eh)iN-buV9$eCQ=)Qo*Q zOjTKg)vPG2N(#83Gtey=i!j4143`fP3lC!9K`cCo1$zx<7>jE00?{c^(HTO86R2Z^}PT>PWMN(N41+u~(!q|nJQp%A~B4moDo~WOZ86a+BJn18`k_yYKG+N1+ zjpdZy(xw_q?X=pODK+MX3V*(>dR(!0T&4A-a)fn8kH1^EC;(-?WBxTtrlz3xc+0X zTo_jxutSpIsXhBX4B4GzCww4J|Bt&EFP1 z{S*%TIM{7Fxit0zaF-kma+0=Pyh(OFsh6T2rvy9309x1=gQe_??6h_3-VEtT& zVuik0b&S()4{*xh>K3*kc&eH0zxL~e&m8YZ>jCg{s=&_$h-{ITamel)u~5aWRMN=e zK(!eF7oZeCLNC0PrpVOTjY_IzlA53t)?aiM<#U1D742mc%CihPg*k@Z8TMRzhR0^D z$<&J88PQY2P4bpy7F1bs{4SH(m8H_jHY0<;Isjs;|+n&27`kSa1$_> z60FAR&|K_9qjr(UR6uBffY>TbU38r!Bj*#ueib%R2Ae4vRCe&7F=TQZVRFNw6isd; zW^BZajhL|!OJ{`1ZG_2fL=cVMX39(d1BTgKq~s#`^hf?W@M-=6G8xODh)svUkd^>0XV!IEyV*IBN?VE0Wb2 zN$=qm$6POD#yriduH&7y0(iTC$0_oY|M^bu~Hu%MC z?5!_lA9?$ww;zA&w&s}IZ|9B;j9`;lJFOiL>5eE5L0?uvN{$MRV935Ai5#Ir=&`~g zl2LiA&j1Ifss z18P6ZSin7*r}MT*;6S$(UO*FqSOt z2c%_)Mhy9Aw3kyK`%PB0E4#vzp>>yMdz-RGIQqx7EblBRny{jA#9R-j*Jfr`Od3`_ zu{_hJ?X&v|dT#EXuz7N!8xBj7O#%$#~rkY3Bief{-A>`Un3 z$rZsbs0W&p2DDNJTCp(;Lv#8WTlggOE)H}=o?bG2;ky_8S*egpsgO#kkV>f_3rI0M zCY@VQ({-R49jHbJs)2_eLMjGseNiBb4y*_P`D{*$0^ZWb+wb;HSXMuBZq5XAncY_5 z&PcO(ty)j|_%xRHtx`PoMAw#{f~SSI`CyFuyb4<@d-~Q}gO#`5 z${kx3tX{pEeGXk?jAI7JvFFiuDpm><7t%-~{fi=s8dH!p4JVmTVH?kGF6`OZ=^Qp8 zknthr!nH2$tky19di)I@b~~oSK&|JdqFvaXsHlhk+E$FO8YBZu-4pBBEtS-G0(LTvDAQz0Z6Nmv8b3iwo zl4_pzBl>IOaj*pz2-tWVe>cbTT+9yV!QryzgU(%XEX&I{+3q>axq@hTDyvV9ZXBv?L35${WMX)Hf5m_d33^9_I zlj4KO-w8J0ZI}>og3=2$2#9BU9+UC$aWS{Nc1RYdxP{ZFl?|Ve9~{6+{MoUymz5K9 zaDvRKgUnGvnuK>K33-tLMkE`~YQPge<2xspz*U_uWSvEuzD7Dv#Iain6G^e3q zPE&R$Jy={`UhFNaEMzB*-87}7c*^F^F`LD7Lx2B<4gE`L4psQ47BnTtCK}$Ch9EgY z5u#R&9TSpMf#HgFE?Xk11LCGcoL#J8?^qkCDyur=YME6v;=rGF+{3=L;KS0Ys_qKI zCGOY~ylEaB%dG+a$Oa~<9kw}!Xe-etSwCY1$AU$2v8KlvQeSZRA_{dogt{F<-43B{ z7x#J+7g{4vKKp1RP#!Y;$YI3|OEs6++3d90C!c)%#gjLMkv*)Z!mxDxbxRR@h&e;C;U)v$w9$n1!z9}F zlcKbm%OomsvBU?00N0?IIAH;jFiRz7DUt>hDqaxi#Tudv($xH1vD#6bb?n6L1qc3g z>#c{%%Y2o-0DIA1Szt{HzQ@J|zvGV0T3DR-0-cv7N_%J#(;wo$A^KK?nt#T7b(|qp z?5g-b0S6?``LIwYU`8Ze#gPSXgLt44eK>?;79-D6l#V9hQ_;m|Z#6 zmyy#l#oxXrug%txQ&5_0^0|uI{DxPGMwgq*-IJ}^9+%RfRVONQOKO~jBT6z0awleG zSuKhTwJJHy;cLY500)RV=2`@P2!wDjWFv_95D{UCiQ*OPa^ydh(SZf+sy^r`>kmA~ z6)QOZz{{Nfy6ez3`3eirwhlKOB-u2?KRM(mJ0i}0R(loB(;&LwvJk8!%BH{@UpuYF z{E%FkZ8T;phgVz=`7i47MA9hF3>zh=MaAM4#Zbxwwh56Tn#yDhW z95QIhz5#Voa3(f=(OiH$#g^b@Ju%lEeBs=gqg%P$fe~n%`a$$LHwpPv+@rV}E~EqP zh$xNVLV6{-V;=32oldUPP>zJWXuDfzcfw$#P0P#0A1;uUJlcAXQdYX7SZ3bIUJB|V z-!HP~f?kT@$3zeX%#FtwlX3e*>QEX%WJp6yyCJ)2#Dho20*Ejc#+V@Gu$y|d@G?Vj zpaCk=j!l=%J$mAmV=H7!A3Mz*d*_|tbHSTgTm@@#WzB* zC(tccNLU{tR1qOi{w_YbL3aJ4tStB=%d?L|G-Lw>s0!DcK(q0Y^OqsId&HWhND|@& z8F(RNA&~9|*AX3c2+q*IvUQ4JA{3+d*bg^uT+2SSVIAJOXYeNWX+D7Ag*-QMh`5L? zfHN?Ks50KeTDNUm!#}=apn_C?ynFeX84Ep;$C<1$z{(Bl*nR7`@5+9>t87RgAXEIM zK44qHzeE}_s}K}YANzFh{cYR$z>jS!xYGy}XYn1ORIZpGiF!Js1@uAv$l#lzZ#mJL z;%%kP2{WBt_Vk|lv+sMF9~u1JnKLYQSYeD!T;<^JQ2X+8MJ;?$2F`q9-8ykD_j1>< zC;1-Ki$4Ejaooyo`=aR`?z&kk1Ra)a;~dTo+t`DJ9WHyxV)yE6|EUk8IO?jLcN;V1b7RaFyG`e*vQOw$ z=D1Q)=BZS@y}|E{hH);Z5yNI0fr}#UAJAZI@Gwa;m2B%sjFDsmMUWFwDx_B=-5Fv` z^v+4DSR8b+41fzz3Lun_t0hZ733-_jTqW9vYT!-{+^K;(wNNn)>#Y{3BjV7*VW|Uz zq6jGIR16k9jxZ2r^JiVNv!u09Yw)+1xEi#vJNAxr7bR(oN_~zZHJd$eaXMS))KXsnP9YIZnVX4h2pIT|yo44EEN zy3*`fs8r7~T3xNPtE=aZ%C(vM)XH>cb)KifmWtl7o=(g|iS<;1{=(}iEnj3kB~cui zT0}J&LhLBOgjAsksW1%{CZxiIRKhZmU7!-ylX&5(2jwC!7{v7~)+)3LTbS6ZIV}bF z(EbY|cQ}4%F50^zPSfHm9$uJ{6=?6tp~XzsyA_IT&R)dwiUEDO$&=GMx29^&2=}s4 z-9tSz|)>D*29gI$%h zA*qGa+ROc4Vw9p2bP5aU^|%JFwbokiTu|FMx6x*;>#HuCT$jyq-?_ap|A)=}Q*A(_ zpJZ~oN6fCSm^~`b-ZZNw#gz0xRb5#VM#$p!Cxe@h|9~Xz4RNcqn32_uwm9gVRkB)Jbq>4qtiqu{(94TgyNYxy>qoUj9F_dK$xb~&*x_|Lv zL+M!VAIj7@iSbrv)8gPd_Qu5{oejlwu*@;qK`X{P5BmBzHX$@(GwJN+s56^7DyU-+ zaw3tR6j>$c>}_bKP*|KgOaX@(qP&R3;>2QcVzD^bfhch71JwHxz+pZVYE>SpTaLQr zs9TP@;HC{(;K_)LtN{Ua4m-F(@M)$B>wc1`}&^lG@Tm;d1#^Q1qokKB@ zLEl0KEeWl-q~=6uRMLYZ>?l#Ouz?89mk57~{;;e18A*+ZWl{yf;#C9`bk?mQpM+rI z%N31#Ep2(tBlc!$bsjBuDJ}RHn|p%7FP4}C+MeLc^NEfiXYifjkr4mVT8@Iei2-K9mX|b+$Z8I8Bn?rXBs2Wk$U~2ud@^`sFKheiGx$-lMZ*+fnM}y?B;iI`*y5LDL!|cz zrG(EgeoA(eM4)3CLD!;LILMoDPBC=jXh&&?aByx+KEs-b=t4DDl%M5@EPzoSDiii16 z>Jb@jVh&0sBsbijh%X?^|4L2>vxI(GqRwkGy5lp-ZDszO6H=4)X-nc$Q!;UY?6umA z7K5#IOmGFe0%xJB;3`TLs^Ho%Z`*Ou66Wn8c#xEdpP6P++k(6R{o5``kBV3sME zWr{S*7$!yHZOrQm*501jGzF}!&LY-UR<#R!-CgJi^R?(VunW8t_A^S$5E)>^%_(X- zX`%6?VLWLVPa4LPhVh6;9`GWGdk}r&K?C8g!M>uwW7;-_{T^B>$#Oxf(SX({zQ$8E zwa&I>&6+K?`o5~d{QN=yXLq&Eso8YLZJUS9ZOvKUHleGnt$TbMM3N{6U_aUgUGDY} z)eS+eME#M;NW2%>Oe0hm*5k-!sRcLzfuGakh90j+>v1twr&=zN8_hd~Lj*{aTFy>y zE8M$7ZXV?*8D5~t^o^Y6E=W`hTDiii2>eaK{da}i7E;ZZjqH|m@(k$I9DF`j>?3v% zLX>S{zEXEEP=O&znXpoUHA+HpWp z98d(OAy_UIbWf7&1pKbhZv?VrFVkF=A^VL2e>7S|O*&auE=^jccPY|rUTs4j;ldDT z_d4q{Y zCwkFgtVbOxoxo(EFk$dGPQrZCg{QQ2X`ugUAwi_ADK>g<*Q->!5>itYiHUlL-|4CIXx!Od8KeudOf_)g#y1MI%zSWj*kdmV!w6m^ zTRKt@If4|Akx7lmfe2PB4M1_Fl6f|it));995a#n9w1d-x){K@&67&z&Ro2B@1eAN zvYm!}rAcL&-}B|7e&wb`U%D*Gi8N;N4=6b$WKj5A>1xt5GTz9BEbVF$i$pxvgsg{) z3W$(_y<}i7gc@NflfYo2e@!VwtoQ?P#fnxUw&_0`bQy(;z1!uPU4?C}h$On*k!8}e z%Le{h?R0gIWbwfP__M$(l^Cxa3cl3&knu_aGBVz1<%D!ekzho3CvP)6GD9}^fyYjv z$3^V!fxilC36Ci^4*d-E!A6>ue6W#%2v15wi>OJoorgTH|CSFn;b^Wb?~%6MCYgUz zfy{CXJ0^GpBb>%g3OV{8Vlk}<}31Y$|;OYWY?@^g(n9 zrlA^p4M{5b*H*7Zk(bxh6VQ?#p$+sj<$Dx}jbM9XG|r0L-45Mim8Z$Oqb%o!oU&WI z%^uZaonyDV(y56N=KJB`o$PYh7^1I~e6k$*eZg)Y-hMmp{&C@uG1Gk}IPfs$1mtkN z1vwm`k@7&^Uz|6ILxmn74qhB;c<=#s77f~yA3f;2JYmp%7<8pu9CWky7GcmkyiMYu zb1Q^F6FtAl)#DpPnGhUe-{iA73H^YBeL|zK17qY7#L`n(m7wI~M$s+V{=6JbmP^&0 znw{&n+WmP>E&WQ%_W0g3IZW@ zpcTFl<&&wL?SrHQJ>ZV07k5O-y(!*o3EwW1cnY+PAu4T3;iy-#%Md2JKyyfaPjt-T zm%#@1)UkBB5Ndb$Q^nXqmT4QD!X zd$L-}oBOBEp4)eAOIc%Pq261XYH%)0SI^2%y8SNY&IJqaP~CZZQemG)F`_%eRGi+>)GMHtsro{|r zchATh6)?|g&dTr<^^G0js8-5W^~Y`e`byUX_%du1reI%q}wL4pZkh z*eY{%M*U<5Jy4|MfxXb5s!^#^(=52Tij>Z5W^xBs?Y&9-~}7 z-l+UxDNPy=yqH^vnWJs<%IEay8B2s z1z4!|L`foHQZ5x`FoLlPi#K1r8XjcD_Xq7SJ( zs-~vZlS)b^t!`>sHL(P^8VdsDfGZ24G79iTMTsw^)5M66N-|0X*+_?nZUK1|rAT@J zSP<++C%<$mN@s=+C^MlmLkW>uAQHzLA|fxpJlui@U4S`&l>oYRZN(yFgB6JC|HaXw z5*KYE$BXPoDQPB;FICs*vLPyV$y}d3PdUtH$?vw!=`umXyzdK5PKv1{mp!Rb$8^W& z!4N9D*VNdSWYZ=lO-f5`Zyk7GA#2fTsXjY+292gFXH1l%7L}diq<--<$bf`P;u26Kap{#m?qp*|iX93PFO1u~j6} z&=y@lvv9E+ac$^{*>~duWh|`FAJ{jpayNA|+bZ2nl|f>>g;--cKXW36zXD&+lvY%- zX$0!082-p{(f@Uf{uSiw3`gjTM}he8ggSP*ioAQ7T>)hk*4d$ZkcCa~0aO(t)RMM`nu$!2rAZMNLWT2GD3H7r-F z%^l`))p$s^!`R2*pIG=O5+SyRU$Mp!jbC!$3S3JYrnqI&78$u_4VjC{QE4ci>N}RzZi{g>NUn!2OYv^LGPFy9K>+8@ru7E0oZCmn9_`TmhSzhW4=v73{=?8 zzgqZiWO~t_QHnjFfE$FN3QDqr>1nb`N_7GJ@8G?yslPt}AR;q8F4xIEGwVXUG4jr2Lli{Y3cM&&^E<0X0|#nKc&m>9o?8cOogLwMMmZ>Rq}?K*b>|URwfOP zi%$_~>M_vS0q!l(*)JuU;&GVCz>XjpXM$&SS%~^2dWq~=W}+9fsL$&$9&x75J&BG@p}`QR2!8TNOm4KNoVFv@Q!=K^WGWj|QZly8 zNU6i)aR7cz8xZ#oYt`5yZ)c^&QrYP(99w0ZUeVZuFU2)h3@pHT&CvaZZo|a`XthX3 zqNpIXyZ~REP|Ka{u728RR`%1b!RY8S zFX6rx{|fA23V4gXGtah08y_to)8}IX+?(RsYj) z`F~Nlbbm~Yixj<;f=)~kz!Kj_jG~AqN5XXE`#)s5iW^?UO@kJM{fn&A6y(T^JpuN? zb|Cnigd1kKHLitC1h5D<&C0fA-hYJsh2ofH&lcNl!EblXDU7-6E<|r1S@PQ@Y&=UJ z&A>ga;6H_XTKmbH-h>Tf+M)HI`mPRH;Qw=>XJkB`q7&mvsqYV>? z$OIL~1R}ymYM^%uV&;mVVNnkeyeROe4G}^8dHIPIQ|j%~J+9GL-14%`Z1$0Ss#YP+ zN|aAC;!7v3YZvc!^<8%B%i@hOUn#pLU{Q?%ebEsO=nEnZ^djEDiYmV-`D?`bL|OFb-0d!+bQP{31NlG!DA2Rmamf#QLFeh~?D2Sbll? zG(NFh7$3-HDl>!q2m3vCF|r~_GLlb;bc{q%Bd0IbKq=SCSxEcNEid_~1mj?t3Zhf!8NNuYfOJ?J(J`bCengHNib=K= zlWY^iYp~c9V@z><2%>_xg3yH~LFc#-z#=V>yHyEVPy#V;E4(vPW`YginPIcjQTPS{vRqDtwC$Zu$%TS>o3A32ZPn1cjP zpmkx#)57Jw)IPop_dV953pP&? z(A3DhAJY4z-6Uf5cxVYcQFg+R^SsE3`bn&=XbhhO|09l8*or6+^r}&mCtxfkFucIh z;-(}ilO`yW*r7yalAPQotf>iuHNh@4L76l`nKVI}G(nl95Arz}lh8^r94EyPIrQPd zGUUrhd_{#~I-DueRi!JVs-+Mam0XI?B<~X}0nvra&XgCpGjcSQStGrrZTgffi%Vw< zI91bU=j7*RIE~rPI#-}ZnLaG9w~c?)Wa8Jbn&3xjODe~yi(J}^&Gl(%9XhkerN&oN z$RjmwqSjlSm@+}3bePSK?KkN&KB#DGt_$8_GHMI7xlXGC>jWG^C!knlZ$u{;5=k^f zC$Q0?*+iXyE+mnINi z+&o*-2OKHT2Mn-RW~p{A7!t^g5a+Vk%aj4|j1bc+@KOtK1YRPd`-$=i6hRO!Cteck zcS(Dv*becGSU#DK!%$z0|07=gyV$;{%MK}@An~49AMLYU7)h+~R-_%Y&kAQlVmZk! z@LnEo#12_3d~qxe$ z`MH)c>=VIP=*%wkHP@d?S$55uUtaNmeKu4;=X=t3L+JaYD-i2-r=UaS315pM4{6wf z8RE+saw8*R!AOL4*%b{C3Xx*gla%3INFLtvXR21 zEs?Y())S|Qbu4uT%58{ei%X5OFLRYrzN|1$)e{rbqnsGS#}#=vJIgM$uC%QiQ#ZHO z$+D}hYb@)!a23OiaJOzNYhw3z*n)py;gukI0iP%ZKJUV6fX}~2@)PADJ{Ri~U5NGR z-$;F0f3aLxf3zdSA_(pG2<=ZupcjOgTj2kSdlQo88qrpUU|m9T#Km;wJ(#P0rG|K% zm-v}{QCE%NA)i{ZaKVC3Aj2ArO$facj~vBAZ@LC!Zn8>|c7=$%!zGwVxE=ex(;SMl zL*yNQS~0LND&Q`R8^W20o5`ZAlkEBRD9Fen%Gn~9gze=uDC(q;9n z;rf%PKH2TTAa_4}c?QPJgl{zdYny#YK!|kpS@71TfS(a2i(@H@TOhtZfz~fG*uBaW zgndC#3`YXvqrJH1D19a7_b`W;Kr3kM`cfRA0$pE+jr2s)oCJ*gTAVKum zl1J%EeQC%oG)-n&tS(b!OEBxoOm*$0B@Xq!zLl0_$kZo>ahKDqOLP3(EwvD>wFx#3 z=}53~$b<$B3iq}Ier}?2c0#6DPPEx3*vMl2kNnZ~NnVKcyDZW5e~ogn{$G62_1)q6 zJ+|oj6dNMe|LiL5_et%O?LSP2C2^tw#FAVP+8I2Laqi&j&`$G{@CmZhSmoebpi{|r z02|DLGsfeht{{2iBYv!C+l?$X1l561D5#S{l*LoU3@F5MD8_oEWEhh~k_=b zBH{ABc&1NRpt;6C&+?j6fxyw)HB-tDYaD))b;Sy+#cx-$z4SdCwqOQp#V2v*(`RxH z&iF09lY{wS1nGo#$k9wFE58YiTXMHW;197r(Y09rFOm;U)Psqx#ri#@H$&76hwK^- zS!|5N>Pa?xgz6&qAf?5M4*a1{hEqsb>-)N#-hjScX9U($|dW?jQd5MuP2B4r@{xUoP23 zxj$#nMr5z_O7z)B8m2^n4JSchEU*+3##gm)#ZR7>h_X5k=g1iV7oZeCf;VzcP#!gR z(TVR5z~2&f=aahv@obmh9?U4w!)GC&CBHV)=ho-D%-) zk_{fSqb7rOwayy$6ITqwG()mYq?ykoKdMMGBs)c#>5COBn2`b5KG{l8q+KGCpPzb8~b z_%z~8UkKG_r<UUzf=$Ac;@?07xAM&?}w#z#xA0d|Wgb#`}6u)htg!EVw zqA@96HNquVJC2OFx*}oSClPbQqFtgfiUXx@Owm;n$Z|+KN-5Zzq#s?;q*M*|5x+qt zeBE1(FMJDPi}%^o?7F@Ce7=2q_xb(%_R?3W*l&7f;!h9$UmU+4L35#~6a1eSaYru` zXIK)+OZrqqO8@KlCrb~J^M(YLGUU;_R-(N}kQ;0j6WLgO_eD zNkQreFT3*YQgc<+-tF6?Z}N?vT$K4=(!SKgNuS?nIlNY(>$= z?+%LPVttaqV*QYQE7pe$W+x7SE<{^C+&VNe~lKec+@OGL^mqW*HJg zAEA~Z%B&=H1#K`ASw)Ah2t$A*B?l-DiIIx|ij4phfI<_@NG&8?#cw{?enP`WVdbJeA$dhYySgXxaI(5=Vt`jWg6*Y_{9z8I`P4?>K1I0|t{_p(#;R7cEibekP_P-3`TX z#p|F87t$cmN8Dfwmj_zW3NicPGn7b-uf(j;E?K(RNH;%8-xIGd!SRP4>HoPxdJTnh zrh*{Ed!eB($4U1?k5!E=*6c3{e%8{$+1=yTceW^Vd@aT7;a~=WfhPhlsO7dq<=N8UXAQ&H?_HyowD?FVTkqW|t$FZycS(ucO_y!U7X;_FFYfSbmZw?@ z8;aSo;F-wX+b9~q_wzVb*wgZ`_Sh4&NI)C7o6GSO`^|RgP|l7d(m;7R_8fc{4>Xf6 z)c^cTsXoeae-`ENZ=n8kQXs&>w6}}`Ez!N&=8yy)a+7k%6@(#1V?=I%;icQOUb;;tkZV0&gToPO~HfC?ZEABu1Z8!vE%3u!u>yr5v^xA6!~s z0eHC(NIpN$KmEX(z~lH*;KzopDz@wEQR5fCcq85n-8+u@&VnSnhU||ZXL9D?>MD8& ze`5jvFH10r9CnEuY9kCY>~!f;C4`uRQOQJuAx0y)%nLyyL~uLqB-fO!3SUc}(&H(e zft$(f`>u(tC#CDjbGkBe@j~k*>M<0LA)YT^l-5hsW60Mk`d}wW`kWW*i0@;D z>wgZTliF!SIqvR->ra>VNwIy>3&r*k*CN)(x+wo2+TH}Pt>RiA*IaquWm%Rjd66v3 z^1j>hzQ)rk^~-wmZdB3+VZ+k+R~O% z9;LiOOCKfj|NCa<>dICU=zITP;Cim+&YgSa%$YN1&N*{N?uStIuhVM`sCtoqwyp>L zKFRkGs}N&|aXE{uSd4MeT;syn>9w!LU3Ax5+(k=Z=nl;zE$M_?%Mzsy?Fc$W-N8h} zoiq$vj^I()asvY)b`C+^>1Z*6!QKV6f$o;Xt|`$B8~T>_S7o13&|DoK*O18IemS*g zwaBu0#<|_aMUjkaidHHb_NUy{E@mWpfI3>;u)DKE&~q2G3-+M{SrkoTcGY z8aq6dMcHzv^g*?4x_4+rf1MLs!2?a@qC#z&R-33*zbbzM%0BpnWzg4a3QRP=e%dh1$44#<=zOWek0E$6>-!XY+ z9HGP=JrbuGx8_de-O4!UD(oS?f?1UEDmMWu>6PIS1E%XLHzEg26J-GFx&YQl0j%o+ zSQ7=HYYxCf8Gwm0ApPA~Q=RHN9_8l76~Yz9#buz#r^gUnYakFz-8bw{PL#ooOb;A{ zUAf+ubir=BJNJ8$Kjl{!!6B}o04{PxHHE_Ih`gPgTauq&>_|?@EpoX^a#M_vfwRu( zT3L2Za$4i+E0-<7SutrT=e#v@UAM>Evu?(Wbv;EzJ?n^9`{X}>*ELu(2f#tPY`--z zs}X69xH$37LZlvXRyc#$wem@=!PsR2B-NTon(p03V{wkH7MxWHgeP27^IVS-TdOQc z?pm&DOu^0c(+j4WhUFd}bK{3vb>t-n%}w3XeITrs-(q`GU9~#|d+^+*w$Xyz?xwX9 zuDY3xEj_t;{mrY!?2(l|Pf}KXPELMSlJ}Rzr3t%)>-E_~(h6LKNGqSaoV)yML&5q_ zU+O9N;oOxC{UJwAXrOV$+*}%hF@`!pf~(~m%}Et=^goawpKFwm)N?`#rJfTK8S^{A zs}U0uV?~vJJ3*I6KK6_wUzOkZTU}n(Padwy{}-I~topgOSLIC}F5_BCc&Ok6JbI3h z`@1DPOPMdE9R={H@?1-+^1sVf^{eu%UzK03^-bxpbu;$#4BL$+-Nl`d5-0SuQlEp} z7u<<51g6_92QYo~5cQpmlKYC>xI(yaW(Niv?0hF93WofF?hw>-1Oi;Tj8CS0;-oE= zR)XX09#@fhFnK^p6Xzc{x4u4Y{QQbf5NUJwnX#U7w2ZG$YOnYNfj1kM@60Hh;x`9$ zR0F5ndp~0BmeM%ISU!p^J;K%_F?Ldve3ItJY@UyAelL6h`qu@pPrl*g8|q8Lb8Du1 z2CPr4EXBV0kK14$>Z$c4OhG`D21( zlbu)$J}){~AKbU^AmFj$HI&*e1OB5Cq4cuW!hc+#z*xneWtO4Qg8Yf`)euQef~VHJ zG|#y4n~@x}wIUfeQxBShysD-u*?n43#wI{nrq&NSqQl0Gs?%=2-HPgP%Bejvu0zkM zr>Mvd(A2UU5>gR1R_WgKPUrAE;?+tbJg{tnMmm^wWF=G&Nrt=yi+W;L0$f4R;I;4i4eSotF8#i+uw{ zrp-gOX#{N=gC3#6c8xiI#`%iGDXHS*Ha$I9OQ$lI-BX=EQ7?`)}$5AZR?)HAEljQ0WBaDrEC zmwK8munp*G@Ru|LS4d-tT$7R-VSCWN2_GPTy)56ueEaWIzV-{Dd;+Zm%cBC+qkU^{ zM!qWlrb&CKr$Nd^y|SLy^>=3>KU2y@^f-ZBq}Sk8vOIN)s{9}I8eEm94MUY*l`g*v z=SJ4gIZTy5dF%mU8^pRZA9mM(?Lw0dbkG$`UlB(K+HPlYvVd|Tlxu2hZe!$qDl6m) zG#}!0J{CRs7^Dn&rBsYOzPUK6VpM@58UILy4syu|l3Z;M7FHEyFI-sIGOwk6zOU9( zl~+}KaqgL=o%8F@$dK#M?Pu3l3^x_Yc#^(~%CjSP4y_rib+9kEuVkgf`PB;NG{+!c z`n5`&e`yNNm0$Ynz~P;${9mBNlY9@pR`%J*e?pc2D}+(xr$c6jEQITFE7^~UPr#-GL`qtE~Gh$T% zTs?BDiK(gJ(w=&u2O1Wf)!(LL`K_CA>Rf6wbre5-=Pctw@s@o6I^k@5N1cNT9W?i- z;TTVZEqI{w(;GhBd6{wH;DG~!l=u10KD;xm-{D!X+y}s2`BYE^LSa#RnS9H5X9?fp zJD+TysIcur-9NXtVPg&B!ZXss^w>wBQKc@IBsM)P7hovE9(>biihv$9RejY3_T_1n zWr3=+s=&P@(K1?Z2D>v(_Oo!!wm-wRBKS>pDt?i3Jddi`C7~K^2%F%IyIgxEG#T2z@J6=<&9o%W4X(v zQZgW6`*I{Az6#mFCHF&2h#yTQYg!QT}na(4=;GMQ8i ziVWl0x^~;{m7BL-Vm$ht=10q)Y5zLlyvtaJ7~q3=mwj%Y0c^zpUw6j&pCO*6mYcG# z_CII6V?6Si^Usj@+-7XVxM)1dSn9e?j-`!**IqlgM!s{7u^YI`$9m#&z!1BW&*H_} z14d?WUklo;`0I4yhqQ>th}@x~DI|i%;6R~h4CmqEMyDD0vpdU?mCsJ`JF{}+U5%gJ1KfSqxB>gaX%RZ^{_r1( zX5)slQEne__j7w0sD*yEYTT<$b;{3n`lzn0mZLhgDiEkjU2ZR^=`%K#G!6K(%j@dO zv;6~2CF=V>GaM#8IQ|&8I6t4mNhjoeui;T zJsdO;H>2K62^aasg!ra?gX9|=CBzlCzgr9gqa-FoOx&Qak%PXVfP>!Y#Gv=9)c8t) zhlAczaGXJJ*v>W15r43+h>jOEPRwy*jhAyzJrk#kZ@t*~+_TN!toU~8Hvr#M`ep;wZ{3mZ%lFmSmgQEv*Gs&-YHULtXHTnxp6gLtZgTSLRu#s!X;lFBS8+zv-pQvv zaUGE-+1Zzx;me~&P+xBQ&}%Srh6F!YLoF2WGL7ou~+)4I0~+ zkMRu|Fo=4J?cabs_%`Gxi7hmWp&rVrn;;t|5q^||gvhfc@jEDgPvAG!qKIMgt*PaW zYf*uqmK1yR|6iOl_|dO^B{Ff0*rRl#+x1nRGYI(PdPBm8^#*>o;QO=~1X$kkc96VSC&M2+oU1ua99*JCY<(0-`2M$F3B+vB)T)N)@7sd&G zN9jWRK>h}`aE~dT;|acjm6K5hI5S{h(AbF6rCKT#6DqDXp(vv{JQ=59wuM6g&hHiv z92M=6ydVEqydC+$VG({}@9tl{xqJ7sgbUx{+KbWu0hd~*%ikQg*u#qFivfoN0qFv^ z2@{sM-LJ70E6Ta#qDLX^2@ok&9`v7~4;wX$^ua4YN@puK(o!sV)r1v>_nlPsBJ!S{ z0cCM`B{abyN1y$@z31)RbMCGSF4%SMs#JHVw7W)B*LIbL+^ORU2d=nsZ{jJZB<{WP ziUSGbVomi>U4anm#qy;~my5_fqM&||I0sZbO9^f5mN zszoWJ1!?wXY!)|kRXClT8Y`^VUB5eL^R>y&GVevLW!HMz7KV@H9M~l6k^d=fD03%@ z8zSeV&*&1#kz-AZ25M3$^60(+ufRSl@JjraW6Vw+3VCpn{Z0Ih_La>g);vZRUS;7`HDBQ9>tr@dInHWrR3T7 z%ko=}A;DOY--X?z2wL<@O^S(A?pk=$^lh=cBOn}vA(d7nm%cm621|8ROi(et6if`$ zkJ?MDw})UJmLiqfz1MnI3muYF3pm5Ug+{I7%DKhi2Y*dEb_?nwk9qHcCJAVY zxc#8YY;F~rTZJ!FVH&8yV;bI69gtX~yYIAFjXSk*U^kYRAW>4>Y0^tc zIUwn1ASqCD6yP%VTC=BUIB79EvIQO4f{tuKN4BULnHEpgCsgQ~Lc6K%LmxRAHIecy zI!mlUu=B#;@Vf5ab;E&EMmwv{I=gRO*_fxTG~i3lE1#QISmSq>_m4Cg!`T4cK<-YH41;M8(qtU(uSJ!L<$7?Eff`f;v8CBM`bVB)WV#h-H7JY$ zE#eCsTdLZ_Yi7-Eyl{T!`jODwo|gVV|KjHUosBb#XI9iURMu>Lt+cqbta75X%vIf2 z)is!!kl9yP)*f_vi+snw#^T&cvtxDvCvmvY)_Ih6%{r+ZFy4!1PS56)e9-rTZ` zlIDuWfskWjO;@10$jGnl7;SG_xnxn5Jt487y|1jIsCenjv)3%FE)JD?vT{rPA@9JN z%5{0=-W-VXQdS_}M!&f&U#U1B(m1y-Jz-mJU$Oj{JD>DM$`srb;EFw|Dixv=PpZO% z$D=Uh*lUNH8gh{KnfkATnJG7=q$kXZo+=^sh30wkGArHVi^h(9)nSC`Cq?+VXP0ME zGX7mYB-Q8$)Bst0(h>(5@0n*2E6E}n4>uX&k{eeDR~Q#ZAVszlI?Yp$pyPpI{5d%p zz=O?6j@VLf7qu5cu-JR$m3s?%P4cTE*lzJ)=Gkr^QKV*^hM)!$Ms8`Eg{Y-t=--*;!bKRb8>n^Phjk5 zqY!_A0b`LPKrYxh&tXBd7#4qs&)MHOnSr{>9N(ic(yEe)_<@+ni;tc5h9v%z5R( z%#1r786sa~c75+sw=?l#dzPoNc#V-Wva#M#ecocy2+oZGjhupg79Lx4XRDS$EvPiX zSd)q6xTqUqoeIMRMXoJbiWrXQU4g#C%!&RFg>gEsI-oZcu!p|ain9p9mCn)4vm2aw zp~^b%-JVLHHzVQ9yNv>G5F0qRr3FXMn7{Z_o934_S1dmL;_=9WAmpc6h_MGw4!QG! zM7AXxh#tUr&9>&jIJ!8|JSc?()MCq&pmQGN9Y&&tmvi9vb1EC#OK!}sDlbk=*nRuA z#&5suwBlyZ!ZY{J5nl)#ivWhX;Ca31=U(i|iSdchJG>;%>qJj-$1FFyciB4e6}2C$ z*_1q*LD|h<49$={n&o`vq~NQ(cz6&xI$ZO}HkHPhvdF`e!S4U!s2phxw3jtiB}FS6kpKS>nhI1slq@V0lAXR`Hr3`hxV1z0II2 zC6lZ-sXfkFT(7e%y0VU8&~z2cJ89BZYeb$ipN82)xhbHFXmygir0J>5Ngj46$MRuu zS9O1JZlKZSZkV}ni#WI=CFQ(y`=9;g={qwPF2uR3>i{Y`V;Fp%=h$R}`|UBIJrQsg zW48pC!*BuAlXMQocMce34j3g5@R z@B(qEOXNACm5_?Czr&n=wMQz@9@T23fD{XGRpRQvMXg3q(;FpN9f4ZO_{mDFM_~9% z$`Ng5<*IIfZK|u>TZ;&RQm% zxp7WanQv{yj8pt|fnwPQq@Tq`17@mn+g3muJyT4t3oRniGp^*3G(G5Djw!e)z*UK> z0~hBg`mAuuJxN$O0oNik2ni%!wy-^%jEPG5tYD}ai`~7IRrLV`k=S!p+3=}@iw<=D zDbQBtz`+J}Uh!;Fl2N>Juy51MiW@KQKW%npO8SL46~isd#>SS-nDX^Vx zQdb;b(mEQenb!0KbvN1oLe&nxB!3rjPU7F;GzSDCV=3PoJ!w66uQ;`Cs5rM_e5kzC zr4AIsq;>bsl$2fBAH+^spdYyog*`atOzXI*AkIK+O<~ahShSM4afNV&aVghgeR?45 zid@S}Hx%$S11J2|j;?QST+rz|7$~dh$ik@?z1J)m-Z}nZxpg-newUw9C!fT=hv|OzItysgc0aqD8HX zTGS}vV0~-;@(qhiyB4?Y*|Eu&cc7p!(6FbmG9fKDt2k54IBUoCSB{)I5=weDZ95nB=1W_*g5uIO7 zY~0kwJB)98$QiS~b0$MB+kWd~6&rePuO7@#*mTPSNAB9WDDt9D?Am;5dwc7rR*7tX z<|Zd+yq=opN`U)&Ci;~&^K6xa)Oie;Wot_ z=&U3|YS9X%DXIBm6^HQk>T;@Cfk!z5-&~5+O+evmy?2>b85uw$dQh4vN)^- zpUA>QPgU4oI&03{K<`yc&flN$E!CbZIcGVcT{+KePaK-#ppD%MA(uCnETr_x-1#Qg zZ_^J1<=zOVJZ}?Q6rrjUT;C|&K}a=@6G1=F5uNrGCa=p0Wymfk0^nWhZXqsmi{wK*@gyu_!} zdwmfFp(pdH^2@->N~B(mHWKL7Ah>~^;OD$1vGNKQW|BF z#bA&;Xi(@)y7ELC%1z+r7@^#FLhnjZRM1_%e5Jp0thT1K!j)25UKq@}^;+>whcWQE zyn=0K-PSjO-89=Xiz^y^_cv7JW<|bb4D8$~+br!P^!1^A1Z{XdfCOVg#`S<5qRd)v z#ldf}_Sg`vg#RRS*~f5vL1i14SFS)zU^y^XIi=;h#rueU>hG*8N|>BXS~1)*6DNl4 zSTuXr;szZZ)hKp*T{Sc6cWzh_aIX%wHLSX7LIpyV?UjD>)R|I)jy|7mmpFkA)rNhF z;#X2PTnGFZlm9*WHe&oehB>87YKIF=sYK6+RxihDzG*4&L|3KiKsav8pv|VS30)h; zW@4^5Av~dT?OFC@fpC!2y#=x{RMHaiMC10o{=TK{`#Lfca!YE9#Xxp_sH$l+)!Vjw zrr7bPZ994=x{8dk$nTe*Iit!ccK^?ep00kv41KFj!c5tYvWXn#aT@J7SIt=ARlcHU zAxJLD_AzxAJr~sQTfrpHed#>r4stE`NXfnPWOjkDYSDi$+P{C%C1+gtZd!XyL$g>M z`HJz_M<0D;oVx9e&7Cs_>*ZJi%rk*!H~a-P#Bp{G%V%7duy`4rmQ5v;V`;w}WOtN`b>{eyW9uW4-cSKLlJ+b)j-E%Q7)L5z zi1e9TXa5Yw*Gn@0C&@@KzFH<%$h~>#*axCK2>$QAp>%AJkb!gTNe=<%@;`CTj@-u& z@gJ;UKQLNh2_x-KwVeV@9l&)ba7`Wau!(IgrdsrDso`mcFo0lkEsCd%%?~RM?zoKL z8aYbJ^Z{3d9C&Ty(ivtPEHpp>_<(Os1 z1->Mo0&IzvPoJhs3o?r?K?i_>t1M~h0`(aUIg#I>{rivo5VaVSe*^vpaF?T{LaxKI zPB@13^a+YL1z2_ZFzr?*wWmsIhsGD!4`U=Fv#rR1tScP5YW>#h=X=+QfylSSUeOi#l?ce|xyWVAlWj`E9NvQYCPufc zyVHU=79LnXY(BulLF}^ys&J&TsS(up>pol;pJD=u9$Ip&&-kj9nN*FeckO1i+skm z+Inx(aAp5^WdiWF#Du?_vH`c%x3hal(;nE#uT!Rn~9Lv>2cG9!F+o zVMUQUEl=EcXlrU(N%Nf6iQJm;E6)1Gu~8#@)`jK{VeUAKSW1EEP)3pRNgS=jF=@R}wt%zb1yk?IC@o2xITSAN*YCJ@(K(AQ zKK2f%`Uzu(yhib5VJk&HkY2M9MITaz*$@8pS)(`J;sWU0bv8`bg>{I3}N zU5Wn)+6H?QCI1zx|EJ~3+pFfD*89slrK@W1kkNC2mh{EM@6x?>WgS?~a6G{s0%y^( z<iWs&|RQSDZLtO(D9gEtyA!m}8WBWw54nPw7s&;&7!xNhi8aaqYk2s`BBr-8YD@ z?2jyV^mMmErhLQLyt|L<5^ybXdZc5tbBOR7(vJ!J3-d`#?EE-rEe51u$&|2A=A`ma z!ZHPKa>i~yG<@alm2*z-fB(>MXHQSR@fc9nGtpHnmj0@}r$hNsWr80zLGCEA*12&K zZ|rgclmqR$De>w}S~#>E$WDOHHUUC3MjxaNs&r2%j1Xe!RieE3wF*%hN+D&016M^7 z=MFW^^3HEOciwgP)GyvOYvy@1r}#!1hsF~k;;!`z%G@g|8@~C->Z@1Q*H^Fd6fZpu zaFwDhV`xhOq^Rr75vvuO7CmYy%F3`hTKBx3q@>)(9SG_?B1%_?@v6M%OYo5rw6_H9 zEs^czTve$aC*#JAD}*bIOX^9r8v_<4a#^B;Eg23|DygY4>NAY7yt>i$*4cF~qweC1 z>ywsk2#?k|uS(3!cQ{;Gi89U4OcX0uT)C>gYT=&o$PX~H{OP(o>Q-L0a^A)+x4ZMy zv9VLT3f$cr6@8JfQ%=alnkMR1634Wx7Hbq(OzSA7N;BXmB}hhjNB1#eD`cqvj%Ti@ z2-8@_VD{zLU-$b%3(o(>ZCyPN^@qdV9bMw*XKy<;`r(J7(6eSncf%{~dXBCFR7o

    pYS0PaSmcS?=tus`raH(RK?oFEAh=1f))-)9R>Pm9#_L^-qIJ>T5WKHEjbo0X%IH=3xQwW; zgAnjgv;tg}xH@og^f44y7LIt#$BQ&tVfF_>DMG>U9uDWJ) zc73&DiK94UXx{BTjoou9h9_Fy?%dMVvaG-StG@Cp1Ahadp1-KJD=i^qW_wLPzwO0{J~yR~;=%4(4=6=?&?Xjx(w=^RhD% zv&3aBXE+{B%yJevpV)Y_NX`s&Eb9GIWKHCMZWd?vE$%GO7G$BIXBn?j((`O&K*j_P z)&l03^=X`)C=T>E1B}%cJpf`QV=0ViIY{!URN!9ep|}p`E_7<2oS4-yF!dSgoLyz; zE}ZrFKZVP#zi7`jOTDLgmtB3qMb|GceDh6F{P!Q@AC6Oh6RwlOR)}#)znKQxO(vbj zLFp&q`qc(r&JFdT(?Pp!oZyfSL9p8KDFrtLxGHgV;G#`64XIkIx$!3N5K<7YoREu^A>rXc}skLXGOTYt}8Pk!Rf0lsqU|FRrppFx&tM}4DyLR zmgr+A`Z#9Ysyoc0Mm>>Q8FA}Ci_IR9Uer8Vo(l`C2xSumd8}NoQh&%5tT^ZMw`8Rx z9Qyn%nW+hkxAwq{ZN-sm4Cfbn&I*7QC0zC-=-d7PIFsxjVE>c}?+D7KIs3@5Ka0EjSMFKZ=2mUS5({=MC&ZAb zPfVN@Ixa%AHK_Ekv+O|BEjVmW*+=QoyL^2I7OPB&(Er#25NVQXku&D96TQIw zy|MaY3kFTpa&DnWhF36K+QAPKzzYRc9yA&4KKNC`<`j2DHj2A;abJo&uR;1Ct-?EY z&}$j|UMQ2a*=E{)X?{=7)0R}Cv16^gQY3=I zN*mV7mchy4rrRGawbJC4pC5pLj#Es{6MDp^yvE|{)}pkWvi49>mE+v9wu<($oJ?PP zRdIFhxwRRN^aOiqc1Cu7M!NGzW^OtR=vldG2{5FK_dV{=+$}?co9Bky?sqajtmC;6 zJiWtRD2&Ww+Z|Oy&5gs=xmnqf*Wh%LCCak1a;t|M8-}W#=rgs}qu52jPS7Si zb&PC$J4SC2Hy>!;X3>hZ=Cqc^ROn)fEZM(Pt1B2qw@s@sUJRCansN^wEE;QExYTey zS5fTD{^PMfKkN2PjQs*=04%g~f%^gv)AbhCr{m~0&cJVtBva<({uJs71oRaqLX4hc zzqxY3S>qhSz{pB*KQ9GGA^PJqz>#g+g8qn}Hu~}XaT2B$+d=Fc#;vASgc1+WTQ%WQ zX&_X1)q=B5xw=+%mj+IC8Rl5hPnX0~o~6Ht>otuSDP>W@;Z9pn7I;glH&;I@5_dBX;sv8XF!N=FF6!)GR`QXk#T_yJHVNAkv%IF3h zsdAMzU1wqSS)4o(J6TFnk0mHZ_ohoWEf$RID3qQ+dRt6WSrlKo_kta#-z{#tEOMGV zR9#tbIPWtStzWa6y(*kvt7@u);lQ>Sa0WHLI!%rkhp(wHnE0ZjzrqsqCM`Zo#Uqil z_+XQ;g@#wR|Kwm4P3^O5az&cLlCTXy7WG0F^;vofZLhKL6MH-WJ!RCIiAMndaAg&- zfl=aUTwE})$(0h#&+JIaa8to>Qz3n(LPAZ&W6bGPN3_K%E267Mx^)ZDIFRz~r&GEb z0-eP(DzO z*FjH_msdBtwPCofz}|5A<&6mibwl+&rxVh1o)N5^yLo`j+}E=-{4>M(Qp=)l|LKd@ ztzEKo?dqj$zY~A5(Ee;-AnNmVBE}?VbV=l~%CJ0iGdc>*{UlDA`EHC%tcIXkS1Jps zgX+HU(%x-V2Txi5<^9!-U#P~(d4-OqDskr0jhSi3{(AWEFWqw*YAWwDL@nkVbv6Nf zYM>W~d@WX|urDDALtbE<`{2J4=Uxk+mS~{+TJoBc$GO*C7w_`6VGBL~V zEh~v|%N+0_*ZYi#BYuMn#36#&h4|jLEuLmy zGawzEQD{qNP5Bt|+I@X~TM1#pAMnK+pgm zWyu^l*Ktqp|4NqB;-@7)D5-(IVQMvE$|`6ogvzV$d2kC>dlV{<{rS#2Nh^SP47ywD zzDCXYHcp=%JBlcus9ir)yx?_w$&AoXhEIJssGfZAjZ#vvD83=CQ2eh1xpSPhFOINd zNr6!d)!7WnAS3{==~_Z!(As9r#u$ZANmx}DT)9@H++J1}DrY}OZPP}Z?Dy#U)}Y}?poGoXXnYIpiE7E?EO{Dm%W|Om0_>XB z#w_ico1*W)j9Q#fFuE}sp%Q2jwTWw!GBPq!?oG+g%u4y(i_d-SD)Hr_>QYZ;Nv79d zT}<;IX^-;z45I||;&fQ75f>*F#KMB*YaA?64}lou3Ywy?o|-Tx-JNxNYF2i3>fR?n zcV~(6`p#TurpI4h6gfaRCICl+eH`3}HehOAWe@95TWHWzww0l~Tu#}Xm&wj)ZUpH; z2boM`zPR}|<&bp89m*vM-;;BR@fH0&o=f=&Dax8QmC}eBN79i}D)W<4uk5&iisjpG z+ly}n(Kenxm1&z}j;y$LStD0zyLfJn8p9Z8Y!J8>*F-#rhA~+gQvg$~)G@R;j5#@x zUtf3Kp?TOszkmP6$iIpC8wKVD!P5_5@8G&T`fWXkt^T#l=sYo$*u`7%>O5HAp z3CFaG+$K23L%6|wPc3@&Ip-Yg?xrSPbgX#owH3c)n+0sih~W%was%2NJ@ZrRl&tR4 z%P%V<&R819-YwT8-D!Gzu#{vtdvR{3^F*%Pz0Ea=TDy_+=L2`sy{O!fU9hPP$oz*_ zc~TXwhbPsBx%H>!2IqU%$2(Jf2uA|#PKB2K1N?gfaID(uG-)Z08O0$!PQx8bT#_C& zxl8Jn8J7Nre!xl(e*{EtI)%q-qY~tLssS$r65djCZPsGIZ_A7J5@y3xR%vP3|7SmfDhNULXkBRP0 z>x4FIr{JalS0%0vTts3uCJ?o^QwC^`iRld^M2rVrEEbi)B0jEl3j!k#oF0f8CsL1Z z!|-*DH^$=9%c$Oofg)|KIPLfrjf(E-X(5z_Ee!s!M#>x18%6asniW~>Kudd8MjShc zm0geP-=-*Dk@kxXeOnw2+JwPT2O|d7G~nB-fS)`Y?FmttFphu5vCBA)5i0`GCw{62 zIk`JMOL01jau&c0W_p&o{=4Mnn@hs!=ihV3Ll5oF`s{s?@52M&&4UL;0i6Ry+kHSA z>Z2Wqc*~Q1L&wM2Nz`l_&9OKm7dQ1uN~4~o;e;G3ecPipAk0Iqkz2|da@X9x_o@fh z<~HE0lArF_@l#lX-rBkIEy9O?##Z1m%kt6DyxAfv&6}-^I6AXb=~lcyB?2g$vKfWj z^r@_9xPA2pb+_L2^=BUzjggn&MHGR4OLn7)%_U#meKbj2O4+1~06T)hVESu851eFQP8A+g zL5bNh88>cRAzWcx(tX6Tcwma7egTW@se3YEr;V|j$c;MX-L(bo>aKEb({cAz76tN> zan5rYLZEix5aXKA%<~r2oBMV=Zm+j{Wq;p_E^olS&K=6gDUCh(8G*W+aKMVWm521v z4_p*r{%f^xQO>59$85rj)rp!%rmEvnLF^~eiIxKwCp*qrBj7k8x2J7m=k{CdFJ9~I zDw>^N?{D?-lxv0_N9*gV`Zvrd56wP(pm$xxh_|=MTU(k7WBWFz>okWuy|i1MBg#{+ z(RQPH&Zb@}Wdgo+E@y72udcQ`!2M=%F}V;#9J;tc&}ynJ8lmCiSEYI!Ll<`hE;c}p z6ouSv+PByB+Vc->PT2PO=U;o>$c|hh_8t4{f1nS{cwiV8JfTqX*?(nxo>;g)LcOLf z4N!3Fxw^v=BP!-AxWs2Ro_FZH4KID;Qwf(mEP|_Fcwx2pOypGo!-9o}Y-=CnCmyes zPSUai>GoMnmkSXND)Bzu7u3;bO03Vo^o6sG+gddG2=;4h`wmGQJ}|KEwckvL$BD+s z?1>i%E7v9y;B^jZD~isox>u~R9Vd)f+F%WyC3|qak*b}wv!Zu7`i?$`ZcJHrbE$!C z9666|OxW_ZBbU$Kk=t^9!g-H;$9U{#KZ`u`cP=eNWKx`iMk1~Xc;PVU%OSPaQC_G) zv!;ePtyml?V_`Me&9b}6f0O|*s6BV!wW9?T;otDkH}3!X!i4cJ-L-B07DxZ4XPy!6 zkM6(!?-Wy>k?<9Odg=4$vFJZem!ZuJ7GkYM4EM9T^ycDl8(A9WE5u{KU+51oRRkRH zADir5*5N%=66klArXM;~6uf+%uXlO)@BiK2p7NXDB<7^kiyB_lX)6E{aAw*^3oV#* z-&*+61INm+#197k!frJ=CTSIwz`!>ib17iKAL-uxqPMWwUwH7Kx3t+=D6ONuQu~2V zrR38z`ZJyg>YXmDUUeb?>XyYr8447KKGMP5+2QN9&_kA+3^E6dN|e*sGv@%5z6pBwok zEVB;!$LeOyIap9oP@8YOkrVkm4z(RcblZk9kFO;1V`#zT{!h8bqgM7?0mdcw0l0Cl zWXwK*I1yLJXtR)K$so#ulvWyUU{AFnwif*nIm<__+9WW}t2h#`udPAP( zTpIq@7mrHQ`=QQinBJveqOI>zpZphjW@VB*;}SM5*g*y%ueh-?k4A2a!=4_EQd?8e6{YCQ|&lPeBeJy!6zDLvTa_pjl+sszLSL1!F-L!CyhPE{*|m9j@r&CEfcl9>xTl2J{CYg zm+F?J=aQOhs+*I(lhmv%&zIkP(-k}gFVfpFV@8JQo=>E#=!a!bLpb-95vsTpPx{Ly+A3qBH&isb*n;yvwp0KXiIGEBr{$iGAYE?(3 zSH-#}=Za6;?wbZzSVk(4JqHI!nA%@5>&kY_UQwItnq^kyu2)czpDYtk;v8fb7;yl! zqgu(>LFDYE(bmdPEwZszoMyB2PPV?PHOnE}{#Gn5YIE}yF4`(ICOjq#CT0{2&jE&F zz~GOAp%^eIENRb9`Vgp?49e3JzgJ2K+Oib{e^S5L7ySOWo&JKX)(Urh@U!R%d_U$F z+dnzi5E7Tc=(lMbrmwpn-;Tp-T!#F*+57mS{C>>u>1dCl!0HC{X%7%lWIO;$%QM$A zmedNOQ^pM{FkIsNoA1B>=KIAhkuBnuORm5E5^{L+eQKVxKyI-;ypQ)xI|XeOsvcH@ zf2`}W{h#^F{>xNttnV({^Wv!ZJ#a$Wm-;_oBN$z1s~JGlmbO;p=U23r>h$^iinbEm zyL6sQ`E?A27p$Q5Q*v|IW&Cm*(b{x})g} zADb~0TYP%ycK=DJCbR;8JB^1il+S1m*|)J zxGjjZ5NQ+AQPde`or$)qaB~|jeX0lr6>g6TL!t@8#2CirpD<1p3FB0euspfO849}X zQg+qip`HvV)>6N&x9zlJCky3&8P@4|<)sryK6D7~P3f-u^bD6PebdbT{#mp7`)5Wj zMpg#Sg-PEut8ZY|tbx8+R-sva{j;5A&Az@_B4^~WnUSYU0_DZU!Sa&f(b3_)@p*&O zev5NU%7f7YrEL|i`9SWSwjA+Ay0C>q!rfkNxT_u>6SgtT zCD(~-#rKS#8_D)tQS?SR*IglQM1;;)k#}b_PnG*I^6rY}U5$5tB;UO|ns>XnQaoj_ z+&$5}D^TubS?*vo?`m6b{~#W>wIUC= zispR*dApGZT9Z**pNk1U$Gct(#WZ(pu+ z-}#GYV&4JgV#dKrh3|hU%z4q1m8@vTnweTgos%4<$%fD+|MP+W`N02FO8%__FxkHZ4nYn3+b%ES0*VYwxB&H;+NlZ^(eBOnp^qjJ*`V~eD zG~C!o9ccFSRa65FP&pDA%Z(?|=cSO!I&H6;R8r4*q&{Y*2{R)clM!S_Fh&op7Yx>7 z$j1^s&P5uZT6Jw@)Urganyp}RB_&}=!8HTCKGl4Z2Yh1fq)w@t8i#o{9xTVT8P{%H zDWF2?waY-HBrRgsrMTv?Knpi|()tfD6T#L;O6{RFs}s z+*BTFDo#r;Y6>~h(j2(9y#IdW+^yK>ke0mjs!a)rX{kx)8Bdn=E^2C7+~fE6EN*FB z)En5?Ju&zH!-m=ZX631i3w_ZX-0TJcjM>I{Uq znilWXEUZmPOfWX4&)haHE~!eayfAZvk&tK%|MaINVSm}B2xaq}=vwy2KSs{J)b9%e zo9awmp5GF*Z8xbUPSt4n)#w&jOh)Y+2i++~V#5%zVTjl;L_m>J%uw#ybaO>KO35?K zLm?5w3d6w--J3jTA}X_CltAiii9NH|?Dr+?I*=Z0jrOFZMA*RY{o)I@&j8EYNc;AzUP z>6zC!xPE4JYD#E$c!`D$H5Lhb3?rbfayFx4w3s%f6Ys-Z=C?@}cv9!hbrT%6#cCcp0 zV7B~{d1^$qzN01^QTvl2ZHnX&oLG__uiG<k?D39<_vF$ydtVM z%<$Df)AKjt^HVmv@iXIk$SWb;KCaT)m-#pY(`*{|@WPHPyU#hjkydZAJ6DSPM6TDd zWeXfQ-rTaq;msA1H3G5Hwrq~PDGD}^1RX`$Kta04v11}~Bywb8hr^R@SHHzfF>_)p zgbdl&lQ$S!>^x!vTdAkDb4qtkYxJzrvJAUDtGskr_3w;;Kf`E_%peXt*)ujq{!>(K z94Xz7xOPk5s3-* z$f5Xevj6ktH}kd0)CFj0JcZ^&pzZh$4jD{zCWl(34k;wk#DvHx_atT{-^seKPZp_3 z_Q;nn5i4-6gh;t0Khl(XX>w*#peA2L9@Op3K|2@ecB-@J*iL1bVmqTIDgnaAB#H%| zJu!rEk65s}!{RKlL^l(ao6U?oU@VF}7;R^yNwjaZs&XPPZv<5t~) zw6XHzcX04-5KhN=QcvX;#{9?w(T1XO)ljiSydL>C-BRG(Y^fN7-}%pMnV26op*58J zlrAnAU(JSL+&mFL-JwUZ^!B?14)?rOiRsi)2+ePBLaZXb}}VcZXSaxS?=oF!GWNXs%9%fAxQIY|;3lW{lkwtOuu9dv4r>{OUAYmfcv$tMvC9sjUS(EXT%S;h^`6#J5AgC5`OEUt4c3qA)^ zx?Bhz0qL1{E`5igtUA&qx48h%ZMr`ZTC?qoW{=+I_Wmb3^}$KumdO9psXO6XOF`HVjR+FA*(gjE|0Eqq%CWE@3Hv11R@7G-L1SP-0A+=Wb26&JK2 z`Ck}+X{vH^)MJLjIT0i$?~+(fwe}j5@<|rc)030JjBmRf|3F!gqgi?E2?lJ2R2ds`fy=06ye_ zPfZ`}z-n)`#8#Y7f&PT$I-^@y9oJ?EV(M zv(WY-&dNN#9cQ6<^uvoT0yxkqX`LHvG}zaL-%r@y5O<2_u-|Ae;hltS(Dl)GWwA{s4j=1M#ka82-kCH*HRMLbU$7_+ee-cH{*Xzw#o>3fX^2PpYE{**)?V0Gy&Ce}y z*SqV=^K;!WH#E5G0{KtNOx()M5|s(Cfa}?|WbAp{1W5aVYwq_+hfE6(1UzNSxLHeW zB_M?{rUvPXp%T)NW+LS&mJZNW80YX}6^_df6*m^&xFQP{w9WZ!`*%g|g7LPwxcSUg z4J-Dn+;e%|1pX4Iqxh3yT#YYMc^KnuVy%$Kd@*)F=7%wUh)QQ$(4Cl=oCx+YDz0mZ zJTE$1BD=(+V#%i;JbT}+osV3AQ50Wybazo~-7?NuOx@v7Fc?mBVN!SPgV#Xh`Bw4i z$Q<$LBj=re@i`BEI`U;zHwYCz0q>))Q=u7{%5S5ioi4Y^N+N(D=`!uI!~WI$A$W>- z9}&{dm%IhALf?V&_PkPe6XoA=p2(I6#P|%{-S781f{BU#woo!oeEo;8i^NEuxbUeb zMe85`_})*x{AE--`8CMuzc=oM!mAdv`?#$LyK}U>J!;&(go=BVC64 z({*}2h+%qL>?Kj!)L_s#M+f=Pb5P@?fc{@s$1 z(w>5yi);8NCF9tyna<^(4ad2QTz;HPt6=0NJ{FJiZv{kTtPCJpI^14iW7hl8moL}f zkROWw^QDtNzTbKbIyw(@PdefmdZZ)T)fq2DC<;y{`G6u#auQEP3HI{g$braL#A5Lf z;S?Jcb;`$2iy2}NLK7=J& z%|jw1^1NJayT#=Q7>shZH&E^slp{9DJq%#e zj?F=7;c9=G^lr%6%cO9OHFA`tG~3n5;{} zmIw@Uk!U$j0}J>v>l71_55@uGN3TS`FX2p#!kNHcpHljjcaK$Q7*1F}1vJ1SzIgau zUAu(&ICaOCR5eR{5f8wtg5A)tGf*+H1_{`oC?>`uABf98y4)`9FTk;U=M}s&6~{59 zU-_sV!K2w9#NU+q*&<3Gy8b|-_~N^Vb@gWXZ;j?qzUwmg53t#dE&Z)9X$zL zqAx{iWns04UCN&O6~@A5zT?%~KXT|3Gjx9+JW zS+m58XqWVN0=xsBM3FiU70KlwZUpC)??9F(%__Xp{!ZA@OIGPujNFeRX8okwsr75T zbA!J>@$kEmWx9GfZX}>2?Hou3C*9iNj=Qmb7-{IJlQ13E2MtqY3Djgs;a6;NmIn zYJ4Vlp{_a8!}InBz8D&xzVD;ZRT<27l0R#9IYfFU@ap$*J~UGa8rvsrP!q?}IJpe_QZq6O9@Uq}X}g94BSpO{TW-B)^$Te@9%?yaWM`i6oj3?( zUrOd_y`%avir*_hYprjcq^(#U$~Q5$@>R2;$9s2LI}z(Zzk8SyGe4^uX}ufQ##ktI z3pF3tyq0~+@5J*gH3LAx0hNnXib9fQnRABbdmP`>`5ya3auf86dOPv~<{T2?-Q$=s z0k59ZEIdtXtA4-DeE$LVDZc;CyHnn`XjqOF{ZJFSgVq0}vm(mD7SV}!@| z3AHkuiEXEbm~)f~5B!$2Yy*ysMrn+XYXK*A zo|1Gvg|3cE0kKpS+m`exGL@#uDE#WXCw@0}T$ubgiceLG?pxI-|H9Zh0eyUeadn(G zV_RUvtf7-3O)Keu+9MUWCjlHsY3L!3V*(3ePQcQT^9iPU(LRoUT!)~Z=o*_R?<$R~ z)LVj5$=!oc9|l1U;tOEUhY!E;F8<-Ym^HWJl#0tr>7R~XEnIoypJ<0fvd7rKZ^f*? zr@j-0gvfWW3dg@Uz;wQ6Ad1)&*xb5})D)=bZsxkydYOLutKMz?xafw@L%5=6x&LQZnWR!GSB60)S>5l13!MUQOJ|)rxG3gokT7+RNET zgo+$M;e=X4Zh*w9Lc*j5AG8UP2gVO#5J2dmv<%Sn*a1Pjf;Y_ek@i(htkdKMZNM!7 z!|aX*O6>utM`;AidZ-gn?W0_4LdE_8oS6T(ro*U|V~O(n7eN@{OoT?utLST~TTr?J zwvU)fLHo=Im8#FxoQ2rH07}RjaiZk|XyP(Vr9>If)y`TeQ%3azRvXQpvw9PlSA7U{ z={|e_tcrbTH;%od`cTU;Rv(hrnLJY|+zqr*uI4aup-W&3l{P`nFsO#~7^72Q8>tIt z8%ZaO&Tn7;o$Fa6=RVRHadpD+h&rPqQg`REio{om zG(DCu=a36g6G2+zOh{{#NpniOLJq;HP;&{)go;l{Re)j@&{LWE2u1?PmOfi*eWz;9 z0IZ0NEafd)y402!Ni6|@iQ1jAmq9Zerj&LLQyD3TDtRY>mhz75XEpjw984XvrbMUv zIy!3AYF~D@T)hJaYP?Ou0c)jgCKV8y;|_2_pperMaPjD2+38?Spg_$m?a{id_7kI= z5s1+=-G0giiY8U>6Sry%D+&PLQ^Qyif#Sw$C@WHsFh|#v0rVS3A*q1%S)33w2c8qV zKGySt6eBqtF`I*E? zlwW5{PhN8*kQNj!%rT+n>|}g_+%h%FEy3p`b*S~&VXo5;V-_a(RUh3=`JPMVOS)h#b(J=6wn`W*f|!0WBcr`i5y# z-y_L|D>GuoT-C8^;v2Y$;e%6g!{{-L|D@AG?NJfU2qlH?=wiX0Kl;fPt zmaOBjf**h1k;`7)2F*W|%{fQXCe8ZO`G+}Mfiuf*p=C(v&CVSoSrTjJe9tkaFc{@C zN&t|ER3ZRmZn9W&{K_?uQ~DUtf01x}96r%v`DK+dUYA-gXtrd|s1nbb42c1WYLcQR zM_WR4y+rxJ0VkqaQQoZVRJovd$H!78umO1TfDs2$##B`Ex=E>oOZ5!30h(gT&{X$K zquXdV;kzBSGvF(=P}^|GH|&r;!*H+a5D#}o7JOd*1^L94C9k1f$SIP=c3H|;7+KIM z9-dM*T}rpAtl~{l{|b{_vK!`Q7@4;pJ=$shZ!9$Lki~j94y0}6xHc=y%~0-hyePRC zyyW<{C<;BY4a(jj%T2X`Q5umJCRris)3$}<*9WC^tUclQwlWEwww2Kiaxxnjs?%~) zTwO7c$;zZ`EA2s3VFNd(Jxw+hc+=~P6Y6C#id?urFN70g2>La$3G}mRubZli(NY$5 z`r}%oFOfR^Thh}LRBg(9q*aby@Fk`3q;d>(9PeAC6Y4A37XJ6>yC_Ix>j6d1@ge+5 zr`sGMulbGT#~w76e+U~b+h7ClS&kqqQ*i{wF3Uw;c)~0*c|eyTPq5+J5CCPFiy~K< zWo&)A495q{1aV3Rzt?x{M+Q7ZqUAoE_C0VaS=WchxW7)qBp#bq7sjxxOFZ_`GCMYL z=yJyPX?3BPYUB2Q-l1?O>$77Q6?hBbQsdDqXRrP6H?ifW<1AV(YNus=nQ^$4wN#EC_}w*AibM?^pW zi~Wii9mG*Yhhy|(&f}CLDN7%<`EaLv*36aaQFyZnNZ@?R_VKQq^pm6(4h4OAgzjNe+Mlt1c_a(-$=$}QsD8cy%AR-~M-+K}cU?Lg{6+KIFP zX%A9vCGSOAgmeIDG15V#KBO~{`jL(xEk`;VX%Oig{d-LRo`;m>$C0x90;H^OF;dpI z1S!9_94Wsyft2v9LP~g6BPG1+kP_bYNZFoKk+MCTkg~m-k+Qv8kWyki6Djer4JqL} z2Pxs(j+F46hm`Q_L`ryeBPBc+ASFB(A|*T*AtgMYLP~fpK}vWoMM`)sLrQqAL`rzB zLP~h9MM`)+jg;_w1}WjW0V(0R2`SJkLll!>)(fwviuWBS^i0+ ztnXV$S>Mx0`MvKT<@cUNN_bvCN_f7Dl<@ulDdGJgQnu$Mq-@X2NZH<>AZ2@hij?^H z8B*fo=SXcxUqvdAzNUZwM*n_Y|Ng!H{RjQ~P5t{V{rheG`_Gh6p|1;JBVzbtF8jwk z=lcO%-066-%lR?S`R*qvgH`s&!Yr^5b@M_STXbqvG{4Y1{ol>gGmi87!??WoocMYo zea+3M@=f_Ck}*2^+tJaRPw@Xg$4~G8FP!*E!q@(H&rbZ-hiCJ9>YoimU#gD~* zieHLfJ1(J&!5uu!+`HWzvmtybGnU3=Jjjd(V=^9M#zQd~|6s;HtPH`J@}eLnqna7j zF&X@di1~`Ri5WM=l(>@_cgAGg$Bg@8GJe5~UsxG7z1!W|e6#{3Y%8qI?SlIppwWz$ z5RJ@ejLGO@Mqfvu4Be^F&RXmcrYe|C`8l<3y$ZQ@fsgd^yxR>?^+$ZARK$?V< z&r*<5M@62QihDjwL&|3vNae0T+-KsR&$5v6Sq@UJw)vg|_k5O%l+W^z=ILiH++*uM zVrOs{d;Uw0i=)Y_5JbhIC9no2Q@6*U!e0j^kNtj*`I^<9;bx zw?wwC2DxidVl8qjala1t>u|pTCDzLl<;Xo1xu+u6hx^UA-;DeJkG(gKkF2Qrhi_H& zz9pSbr?aO!ouso*(n~s-J(EdhWhS#SY%^q%%uJX}GGt+s0c780k$p!I5m8Z47G)Du z6cA7m6%|lXK?Majkj(o%Rn@n97J*0KKYq{W^JM1sIklfUb*k!A-E*sGjvoa+3cMKj zZs5CtlRQlUHvp#rr{PDkcAS=^li+s}{3hV{G2j&cWI&3)2XN0UC2^+!KSjqo6*$E^ z4UpoIPWEvf?{wg&>v(7AGR}k_<$o67SqM88_}ReE22Qk|1Dx9IT)=bTmj-?w@J_(< z0jUiy0K5QU#J3B9UkH2y@QZ*`+KT}%)@eTh{1ZCvCBQGyaW4fzX>?i2M)5uk{L?z#ZNMqsX8h3a2N6~V z{OiES0KWnF4fs);JOun9;M6V;11G;n0LlF*;G+nmc6to>W59{u-vmzecpQ-G@dV%# z2qRj)1)S*kHsH76M{V*Q;M5*Z0zL^ps@r#ge-}8_?|Zq8QzXqIW`7Q7h0e=T*0RA5E_qy-D4xG}y0Z8rq2f#ld9kulzfgc6< zC%`xHtOfoS;9CeM8U8cyPQbqat^s@-@NI-qKJNg3N9Xfb;BUh3Z-9TtL$do%z<(l~ z`pLV%sV}_;_#XVI-TwvrU%;vD-v>^4&Hxf!dja<%41UZ24`|MZKV$I!J0ORj0Dd@d zD{y)jbr*0Oa69}VYs>)%Sz}K4(TNBsleyrB@|YWbbWbb!d4PL>lfM_?RHhG*%F9C- zoy3QJ#PZ>XKE(X+^TUtIC;(137g0F@gj2ji9WRKmppI7ryhz6jAsqZ+CGexu{=gqr z3P13NmBFtJevo%o4nN2`tAJkx{3!2A;FZ9Mjw*zsudpy6`U;C6ETYp^1Fr^7>7xjz z{AzT5wFs-#`PBg@O@Q)?0k;Fz1J*-!8UPy*Mzl5|EtTI4NO4;bM%n=JpcQy4aN@x% zgj1We!w>U6YXBYxo`65`H3>Y4xWwBOZ~@o>m_|79p%Zu~!ig7M@Pjg88 zAdL8VDAE!?Hvtkq4?`H~O~lW`fgcW>_<01v$?r%&avz1TqYy@NyBU5Yvs>UtnhC`_ zTE`oJ-++#{RmU5I-yr;m_96HY?ZfaJh9A+s4frw0#_5A4eGFe>!l|o2ZO45Ki)VCj8EXAIafa@aqIT8*mNaIS4xk zVMOn_@FQB!gWq}ZBOad*{CwcV;|qW<1H2FrdK0?{@FIkf41WS?DgGsZ6!%huU5YTO z&traM0(=GmjHgb^RU4E)Q$sa{{v z@$S*_?nT(WI^I`-lm0{TzJ_pW!~5Vz`VY0?{qUnUd;pNz@Ii!;{zG;8I`FRpr#gKD z;Z&!G0I5z7BkW;>QCmL(KWgho;rA%~h~~$Dlm0_=e-rp!fR6({jygU8_yod;AKyk= zYLD*#Qd>NUuqP1~1O8p$r1NYA{ypH&0X~Iz6M#>{{WQXk1^x_h(s_!3e_w|`3%_S| z`18P@*Wo`v_=$-3LqG%YM+o~7XrjDd&}n}RzdPZ65%5KX{RHqQNKftkGsK}XUjn4^ zevYu8BaHgXFMyMdL;dBKw8uyrg9kh~5Dj~BANJrB4Q$@+|KPk{Yyf`P6GQHH{nP>m z6pm{vQm`IO;rh!|l<9}!!QT#OCqHu2;f)k0hKJJ9Ltzw;!mNN42595joF!suJVgGF!dyRXHj~i#<#OI4} zg5MQ5rSk@yF?$=%AH2)B+ql=b-}r{{sPTmHr17-zobe;$C&tf>SB&2nzc>D9{MkZQ zuN-5V4UY?t4^IIe=$~qLxg6V?ct4pvb5ZZeW<5@!7^mdKIG;Su&+#~5yZL#F@qA8< zFnNTtyQzlW!#1~9v0;Q5I9bs=!<4pYaacgsAXzZbA1z- zvX`V|xp9>w{8GTw6`t+D;?l1LSgXWpfz?T@0azn2wGOqYIY#csVy=;UuLSeqUyj|g zO1XPRSAkYb>`jDqB8=k91|;`NfUST_0b2l<12zJ#1Z)6Y z1y~2z4_FJh7O)y{J>UjBmB2Rv9)_nB_>q7mfSUn}0FMSFI<^859YcUb$2LHsV+SD7 zaSR~QF$zd@i~$lIy8(%g2|%J_3Xtf4K1+IEV{2mMddcRe7{eH0h%(eWj~O9Afzg#IPzfbL~n0l)hI@5e)YAU%ud z_&Olb@em;K=@CGp<1s*@<8eTu<6D44$9DjU4(LRZj;8>L4(L9Tj%NXhjvoTv3-}@+ z^cG3SPXX_T-%EhdS0o+303$9yQ;UM zxydjM?&~DiLA-M2N9#-3sWOYnSEgAfu=lL{IF;iSypPTOXBpndNkIqk!sup*<{Ud4 z+L_|8uOcg1WzQv=zmCz9aqqve$H86P-W3^h9Lf*2NzKN=?6Am|NZMhM`3~P?#$hz` zP?@G}5C0R)wJ0y+-GkUAk*yi!#hUlAHG{2?`tG0VKsIb-H$^d7^ZTEL30r~AQ`bY; z*3p*;nX)Om%2yKjCr}Z1A7>rPI!PWKEPoie;UK>Q^H*{A&7X2dd=E$7`fLv3)j{~L z?CG*~#3@lG{}tsle^X0IZh&;6gKA1;yvP5js(S$KH1iX0$Sy9!8*ot)!!Umtd^RtK zEfsy!Dc?2g!&I`9ZuVq5SP3GJN?!i{ujzr!cs9KqGwg@wKxgC8n?X8u92Wg_;1qHs z+di2qdurxP%DJDNJaZ;}zmUnF?ijfylfOQ(EK6bb-aopMTVJ?Q0<*9ZBrAbASP4wQ zN?-<70u!(j7z31KF5D==iA1=>8z*7YnPT)dvYRf}h@!A)<{ zisFRBC=No8;vn>>x>&Xk|#jIlHSIjr_7iz0)8oNAiY`+xhGXpY^Lq1?O34&^VT+AGlIX%6H^6DQO zqwz=8_rqyW)zCCZ9?3NSLmFyfn`<&8LxtwU|FD0^s_6b9c_P#QH~j+#b^0}f%!UGs zGCV^5`~&*$J{Jx#8XkSR|7QC?m)~v37SqwQy-N=WIC@Q;Ld5*@k5z%O1-ZJ(RZ zM;%8f^~_%+oAya>o&T_KCJFc`rkXEh4vfqDjSy#c6M%E-q^T& zYiH-+vc~?(L|-h{o2;x%_Qqm;iOPO|WqqiqzOta8vc4!(U+HJQ-1wB9qU9#bjg8dQ z<}v)VB|$P)CznXq)rcK*g;FjtT-W5L~(-GcFXqdGylBjj=S!< zgU@;Sl~-PVg&i?-8y$&_vNG-ezkKfb(3bhohQLsr%ZoXfOz-{(bMb?)!Dg6zY4uGj z?Or+b(*=zGFV4~XOLSV^psKE&{STzO-|zJl6nMP%?haz1OR>|$8|M+q0EuWnk z7c$b=FUJLp4K3E8gGLx=++VsiK*#*j_D<5=WCkQ$wX>??V zhIIx`tF>p3<*nqkbiWTNX?%A5lFc3NToPvfk{O4XFFmld8CRv7L)+Pz(QM!Gp%S}w zT0{DP)=?Bm*(V*d1Ue?Ep12*(0i+mDJ)TZHOYv;NvjfiwcpP;2^?of|t98rZ0m8|i z%20VgV@uvr=>GH{^%3aT7X{HF?fc%Vx&-b+@odL)JRW_ST_JR9x=rXn+Ue5VR0RA# zkanNh`UenywwxOpre?wVS#9eU)btnEr>m+u8j6b> zI;yJD^~I##F&_oxM$L_Z6jBzMPp(6KkoGXiB32xR9)85%PM=Ztw!_HxT4n;NrBeXlfzJCvEoa0FlDn&Vuh$%1-R^wXJYXRA!w zBr$>*Bgb0L~Aw0;_I^*lprtEP*rktAJN@l_XIX(5)pP*N=QJQ8D~kocAA@Q>2G#t12USy?%wa%HP$t_m6O-)xdR|5y4?>roogg)e|MK=vD>fsn z&|a<3hpf<_tQat@7%;6EFs+#Z(~1Gpss>C`*fO^gk7X2N*<>_+panr4d1pqG9DU&< zuLrS>G+VC*wH!!(f7J8=ma`r75zEi6MN{P&$-Xpi!ck4&w~pSZ2Q zb+F)lgcI*2TzDM7-FP=a<np5CEE`bMXF7R4o?n0aH3d5+0#fmUb~W=40cFDsH0v< zEt74R0KQpnz?aa-oAz|Gx`+12?xsJ8$&*2cCw^qsdvZGaAMLH9CuejtJ)7YIpUn1n zEQlLZ>^}P0K`zx<{`aAy9 zdXk+0eZ{TTX#d%Ts0Y@QmYKM!W4=g11EYKDQU}zN`Ksr|tL?AKsw8_~@vKfCP|v>+ z3tqKX$LCcOLtabwyD$3>+mpU7&(@Px?NV(jh1yh_QJYGkHkG2~OQANELTxIA+Efa) zsT68c>Aq@Hraf_aE4}BSC3Pr`dvntV)bq7hs6neqWswcqvD$M$J&)E*h()PAFT2d$ zkF~*nCbxB{XVjEiveJ-pTM0Fct{SX_8deE4tP*NiCDgD=s9}{EHLMb97}l5vS+}Nr zxOhsv+DXHF4OdYeSkHZBvi~v&0r7RSK-QwvPPNPSKxQLi~NalZgu)x zZnq<7%k%hsqPKL3Kj`xM3Vk!*X)4M07B|m{R?lfJ_U4r~ZOQk#eGW&gv8lAq@3wpY z>GV1B>k9MJK{rbF=JN`FDCGAS7po@}I;$eDvNEs2-p`Q|ar}vVS1{k5@9;VQ>4CGZ zw5c)XaQKk6c|}38xT84I*$@gfbVh(C3vfM;6>>&v{xY0l5yO7=0$6`7$h7tcj>}}j z)FkB_mb^w9O-L3W^Jrc&*?91Gk!jf`x|MTqf!&E%!n{rQ0KuLU?mDEU`H-$ir0bC8 zmP5M2cb5f&W%S&fK~AY`uPqkMuGXfeR#&qqu5BmDr_DVzrqeR9W%bba|1npe+> zM(3;!7nYS321-i<8qT~QtZgrg#pAKE_FB5=(%gF{9#x^v^YCrwN13_Ej*G0kl&wq! zI7Bm8bLL8`W{d>QV0tq~f@XOYGMUD79*lvxlAeRx={B#Z><}^BVtoL^ew$&-=Q79{ zmGM}KXmTZ*ni8%iQ4)(Ez@PJSctJe*O|T}zj+&skHpqj8T8DfyYssvJOK5B;q1(M7 z0(7N$B8d40y|^fZSG~CA)*i#X&CwL@2aVAkdeGu)Pro0o{25KE?et3+J`9&7a@aHjka>_VJxNxzD|}roXCTR(-{)n*N|| zY|IwyuUUnxX4QxLYkttSU_o2k!iBVMx&RBzry%Q_}y*zSOd=eq^M6 zt);XfRhdKETo72!ek(^_x&hap;cG3CQ%mGLAUFE_^5U3scoBvXQ<4Zy$86DPH7?%` zfz$d@RLuC9dkS;uolEosnIb zxf@cc4Rgb(mb!E>|N8pwbD~vUZPndN*0i^;S<+qI)>RcfryIR9Lu)HWJ>8=ZSdoT^ z_>f}10|?y{nc3ej0ZpZ#v`qUyfbOhfU~iOW8z^7q9HWTDeT*6M<%M;)b3WO@nmZOb z^9r4T;!s=roR*qoA*h~7Qhk!qmO1Thq2fYUVV-jlFPqg?SXCTwIBfINvu0B@sB*Js zrRUomjzDo$VH@3Ih102U7k3#rxG+<%1NMavc!iN|ln1bIGxTM<5h9SL#UeRdVh0bE zV$G=|dSdyNO=ZbBq0pRUSyN?xtmnx2ySHy{E@`PQOtrVC3aeX6nm2DdmiBaZ?0tv5 z1$uJchwCkvgYQ#YMIgYMAAkID4=ZB+8C-eIj9tj%d7g(6n0kk_aiX;Y9U*~nNcIj+ zi0mB&8bj}hhx`fL3{7)-3_5Tu=9em?oa|o@7q`u7sc|_ftiB?Ds36i>*4`PYZvCW} zom+*z8j9t6DjTbc-FY*o=Y>oC(P$u2EZ@yDqZoIj7V~Z>H2d^cJ(@^*=z3k%TO%3+ zJ=xL|Agwls8gkp;H;E_>7qb<)t~XX?Y4Eb4jWY{!-RU`KGZfRf_Y;=S^1mAwvuoHx zIK$)DobK&jgVBV($d~J_{clA*;7|=5l>n|*W_v8V6&^TL!)z{g8+qKOG(l{4vQbQQ z58#Na^@c;Xzz!1|H?b)bJJH0>G_i|J>~a&k#>8$gv0F^+8z%Oci9KOr-!ieMOzc?` zd)dTZH?en2?A;8;@=UDM#41g!(Zo7Ttlz{;ZmncyB>>-hk?*7Up4 z#BMgR&zRU}P3#LMc8`fYY3BEw>Gy((y<}pqYD~@7`sPX+uc(*XZNVbCQN2>oe>ION zg*@iNQmZaT3oe@-mt11?j9?m*(Y-LS<4(>xITJw%Kv)bQ=LbU~F3FSu0QNLOLpEEm zFk~m40P%4^B)O?%8fy?z6pE)i;^`2|B7Fi&cPQ(zG>F5XL>aUSx{){0f$Oul8tspYeiLKiHkF**IgZ|>rL0%Fpc9LM!Ppq zXtz484lj3fV)qJ*w<$0!eDSc?Ti1{;Jdx^3XLLoS$ZLtW=3oAHURfTih}bPY5AJ%jFe|8F z0jDic;B~kixD(Rnb%z`lYelriW7{YeRxMlF9ded9EcT$w?co9!?YfEzeZpc7m4xgT z;b*P}kIh#Ya>Q_5Vu8z9QQK1LYHhC<-iF4g!|t~`9Ns`>yrrexEm)bCxgt)#x4g)W zdnp6ZW2|0lO2i}mYgbkTTWUQXXfwiY7q|k@<}7l$ovx*cwj~voX5P2VmFL6dmOe*e zf!FEwc>GqIIE1^}y1D`-UaPgRFwoT8SYYEmJM;HMo0s6c%sYLvN~)O8<1TWPF|W@< z#g|yigxBLP_4v!(9`_RAE^Uf9^Q<anc4snXwU zca{n!tiIBsKy#odh|4$a?gF=?!0rgtdy~+t{c|1Rg%vhyL80AISXWtO^_F?;fu@EU zPwin=E4K!F>&uHQuCUutY-jmsHfu#9&skDZ;&l593S2G{AI2??KtaCE8nD)t))srX zt3Kai#SOp?tHt87+C#;~4$uJZg`B0F72rgw;(*U;&1a!-tsk5y4hWaW#qIt)5BP7f zSW#1Netsk%ECpq53$t;Dy`-U{q{WpEW38NLcLc3-MX+pcvfgfU*pS9<%Xj*!9B!m^ zSGnyT57xtF1^$K-ma^8CxV%m)vv7;6AkP`{+6y635a>W4&*2C3&6{18!yT(t%LDBwjxW@#7F3tZmptf(lYTH8x`b&1z&aruHi;lv%Za~;+KKP$w% zYBAp1`&G-w_@gYyX5(zFt?Vn9Reww~DxM}h^v(S|JPYxyC*I%EnFb90^ld#m6#g}M za(6q;Pn#GWt;OOrm6C%0V|^2SiHSu_tlq@tn%HU+8!@p76Pq@%GfeC}6T8&JK4W5c znb^H1cE5>z)5PdZN~@geUox>@nApoE_L_<9&0x%CVrG4rSxaWtlC_!fQYMx*vDqfJ z(8T&o>_`*asxj!~YL3HPWsesn)L0u;!?PWOE=FXG+)CXIVP>OiTGO$32lgZ=Oio5R z3hC~oQrhf=nDj9JU{cU?WQ=ApBrOV2qGSgq4Qydi9++B?!e&QwOreyBb}K^=wjjvC z{1CDuOPWP7$6-=L?ld*TXx}zS-gLDoCe4_w8q)!Sh*a9xMI_ozky9NNlqM(k$7t@5 zGa0Gx@Q%q>-N>;nR%i<%Px?WeSVtPA6EO)&xqwr#a@MlOs%=r)l1Zmo5;qYqY0ht` zEw%g5cX&Z#b5o$O&}#LT1iHG~T>KD>dVcg&r?;TcfhbmAo@-ejZ$=-hSkjhQ>cUW0 zO0MW(< zuc&Wtb(OZ%RybV+MTH{fpoZbx)8Jx$b2jl67P&CP2<~yaf_96e#2M;dx~yuU*l6?A zL@TToN678OjNa{b(jfk`2_)7 z>rAr)cex4*{BAjGoEea#HhLs51r^DN7n;B={$^u*F0ThUisU>;kWZ^vwF+hcWFXsX5} zxyFVY;0vsrU1vitaadfn=u?m(C%e(+ z=8ta8w48+?7qj z=fH!{$?;f79yy0Q@*eW&$%)ZH9v$RCM=AgJ>*4#@tvDR444pEu4_Ql_@oqM;gRZ5`(1Wg} z&Cr~+wCVS%iT%!8U%zc)e>1W7G8p%oSe1!2m{_}sb(+|Gjp1;8OxH@6f!gqY>-GPK z*Xtpy;_gZ5DIG86LvDO{;!G)j6Hy{#tiI=l)&1n7&{#)mheAf?Oz2zEsT zLW)A9p@r&V*rAcH%HI3G4T1l)8v+YpdYI?1-AEIq3tI}9vioWNw&$M&ZIHAui*qI8 zm}~R7?KSh8D-uq7+>Tu% z?7U#_hp`kKZec6oZmW;cW&}J-uoDDjj)_@Vb+{~cXxSm?Xihu41!Faw1w0nvaM$Iz zpuHm#+@T5mEJJ$o@A3)i1HVs zeENc1>gjaCHg;9a7Yd*X9`+oM-1kvdsE{`3Gi~i5(2GkXS=0{-eikabgNnMNEaX8Q z-ja3550%mTB4h8Zux0rZ%BA-+X1O|7H*L09VTwwx^BzFC3RAD`aIF&VRRV|D9uz>l zKmq(usARsZyC`_d}R9c};i$K5@0)xJ>K!w_o2j?1Rkq$?VnjHH5&Bz(Y`udNBY4mj-?S15VW22@W{H0o=<84tT+!Jjt>E*j0!}z^6tfumcIb3svYy0}jJ60zvQpLLherLcT93EUK`lhWmRy&?$ zp3{;4{_W+3R$=(}-o5wF{C55ZY)R-9{w&bD5EgE$u%g`p3%3c}3v(vUSh~`<5$7!F zT5EI2EN_n{HXNOEve8!Z*qY-pNgk6q9@FG8o#T=FqViO9g*@32&N8u!P3&5Yp>xQW zm-Nm=8A_2FO0R5+U}*)F2Fur4JmgUn0z2)rr&Y(4+7nH~BZ&PqhW8-RB8rR%0qm|x zH76FRi;^N#S0}I+MjKZ}MFDJcsk{(b=0cfDB%l)6Y*aF3#c!Xp{ruId&)+^L1Bc5a z{0!!Cx4-`gkCZjH!Y((v_RMfkFre4@A)g6I~`4wKP1HXZet=uLm<^gGSh$uqlRj^?7reygnf2eWh;pAb} z1q~tptVffZs{M^XW-hHhELkzjKZ}j6zF_;@x!W%Qkvrzj-EscR?_)%2iHuzTxdP+;aq%`{#Jlb)EpQ z6?JJ(<da~?ufx#`Mtaj@@W`$cBFCQ%$@LeqTe_1*WkbU zPs;z6nOorh48AEk59#gV3Ji;5GLP@W?|kV8(_iiPIovk!1%5T+T?M}rWxR{o6#FiJ z6n=ahCc|uYfQgO;rDGB?^@IE0;GLf`dw%Gor8GK^2d?(decvpLHXTa z`kjxo&&aelnts=^-Rxmm?oFoOIf(b1jCZr?cRt&t)81nG-Hbal?&Ig6j9cM%jI77a z?C1b6#l|r8EPBz&7B~vZ3zrl(Rs{l8 zjm1j}%L^P|h<2rtdnqnd+iEKWDVEFR&_5NtROd%~R&i@qO>< zWSD8_&SAQ@S{p|t*p}6+x8eWy*R5K$PTu*3vpM#@%f8E&Aiof<+Sqqw!+5R^PZQEy zj?Cm>j;{=6orv$mK<&gp?S#Rs69%(R7|c3hnd;0K%sMe(VlJRjJjXsR*U*q{C@2aA zuq$6My>ZFXLl0fLWaG_=npj(FeQo=i4I9?1-n0?TgL>bMpU<#vC2%Ikh=ZnDkq73JY!1*F&s+@Tz0<%ADl$E9xD!oOAsWKqd>dJ*jE?yd` ztZg`KW#fj*?odNk*QE%oHfwmAoU zeHM4B_+a6bqtj)N7g1N6(ZPFQI|Nf;+V^AxR7xk_vA}{1hljD-M(#b~=&jv(o0>X1 zI~P40zJ2xT6<~>y({30woBYda9S<6GrC&huuNWBFKP$!JKa!DRKt38Eb z+c+QX{|wr{ELQ@uUj(Wv->9EGh%I#nC4?lv21s^07>pp1k&FaHAOR6bKm-yHfdoV# z0TD<*1QHO*NI(P<5K(&V4Yn$j>6pD5)3y`^_Hj>%zpB(JF5VUX*ul?2UELDsy{p4wjVG7UoGAxOVT~a8D8S zPx<{S*??vHX6`lI)>s-W46@o|F1(A?x|*I@+e5be=YT)Yfj=QAr_I?mc9MSNB+XKd zM05Zn8TR2aBFPsg_(GrZOC$a&q^<&As=${j@TCfTsRCcBz?Z5FU#h^DD)8k2=$BPS zFw@3hM20t{?O-zp4Qz+)3Emk(`qdVY9K_fo)m8P48`iDuuZ@+54_Uf&<<@YtIuYMk z7|P2l2n76ZmsPktb&;m7j^?Twx38)!8js)WgY|b|`E5?G-QjjRJZ>cuZ%dg7qM@kg z$Q77Yzh#Z-nq-oM2ho?+mDvx_;>;+LRMSQjw7P72(mRZFoXDp|L}AhA7W9WiVSVwe zg(b~%qia@QaN3YJ(ubxiWv{oFlgseA8hoFDdXBkRcs6ZZ?)d zZK*)Z*uhoRfOMO^I;@GhGK}WXj#fN3v*MZGvEuKpTlev`YeDGE#`z2<6e4ZrUe|1V z#DzYHBA}l{QBVi;85=G0;BMHvna>iN;I>P**!vT{o<9XQ-Z>$Bt+53!5AlWrBMr$+ zJ@lS7-Y4z9XQ90{2Xp1lg{sgcOAn$FTwb$CBM_~C_&eQBloOT`7XwV=p#_H(uXHn- zG|kbpCYNuO!RQcu&7h9%0)JWa;;jp+Di#d(_6{zns9G?1Mon3HO-*@O&BFNXybAib zyCQG4zj^ie;-0Zpjg70udKQnbZe~rTwY8;XwY4{G+@9!b4g{L}5<514ZwtVW2=BrA zwGDMKzqQWxf%~axV3y0#CFmtTW-5%NG|gkSlT%(I7&+#qvlqX3@yRpGj%O{09CP|i z@_3s2$o8}VyedEV+=n&mK64+>9F7s$ckYve2)6{%gR7a#KhtyM?stYpNKYutCx4ou852M_-^W?gp%pVjhrXl57W+(nPP?(nZ=jou)ALg^9g!%Xys}=Tt43Q<-iojV{`{ zVATorht274pEIYUv!Je}Bh|QU9((=B($)nv^ZWBGqPSsRedCJGa7TR2qC{&)`$$t` zeZy?f*|hgk-olqa%1Fl|U6A1pT@Psc_fuFT6$lAEg}rv&%*&6Q^{G<==PoI~;DR0O zoAH@Fx88ajQZu6&JgDHEnCyuMlqVg0M#DdcUP2h1Vo@M@PzFc}0O_Ih%?4FFQ*X@K z__j~aL^$c8qHf9HypdiS7p~ah=tKE*AL%@{I_DH)V-*JM&62?m1%%H0%|CRQYYK#KHTw0D}ULU z96(^{3jq^YK4UJ!7;8f`HBtu)@{;`-F#C-iK(Y-CPJ;mng|B|EkiMrV~Rfu>IF(!F;N_n}>E=my{b+8ZC-;~$N4 z)>wdUXl4bMzcKS;_VgKTyzuy)s9+=b*2=$)X`}_;luu?jS4NB~%i)}xJlw=NvZ!|( zWoXj}z)FSP4@uC2Q4`qG1co$WFv3SX*e)pp*U}mGrorAc*qa7>ae5MQ4ZT9yx2QvG z)YPSS0cf2eOT=i+mp?hz^T`A`buw2QxoX_?hf5}`k z7SDWER>|3^BD82$!_s7BtmmkX1)JwpC3f7rE3)U3rE}`4I~tR|P}Re%w7N3gpGY1` z9~K_nx$VlGONw?^ZasU>x{aN4BTXfkelef)8hJdxhcTbv2oAWH8kg{V_Di_K`-MlO zJ7_%5d)OBdJ|Nwz_HN-Weh=K+q#M=dv-r2+-Y(tHL3kG*f_sN_V^-s90W|+An)RThkHtg8<_uU;hvW60b>X&*>~Z_I$O?1YTcA90k6klf!)h+)qijN4iIGALt+0O$f)KBM854 z@44(7Vm92k%X}aALg_wh@A2#hVg=m;|Dh$!+>=H#vOq%#Qa`LuO?0VMa)?k zbr_907$*YJfcc4o9Aeo~MRx|T^OZybb*WTcAX4IEUz=IRzIIOm&{S<*M_x&U>XtC( zLE;VvE#pQD+~=S!&&j$RE9;UCKNX`OH|9b{3PD>Q_NdIST=X7umbUC%@&RAo$>A+~ zI9E|X*|K9&u%z%6TcOVa9Smbznq94GplWk+)A9XX8)sLPH?%dBUs_z-SX(X zJ8M&jQGmMUb-e#%ysNBrUZf#iUsc^uRan(DyP=}2JXlsyi7zj~wj21H>_PE8@R-gy zrL%IScCK|x?D>K^*nP7L-|Tylzd3yT1qY;&XBpEvNUu|6ngABMH@w*QC$aE?qT8>@jom&{q#lak=JfvW4{x(K#w4e zJ)q@Ujk%;{fMiIx+{DmU3Sb`Wn%GcrxTMhIFY@#|OCnHPBgKWD0=Nnm37a?H8w}PJ zH--ZWYg2vca*@ZL5T}4Yq~nuR>OO>-l07l=42z4ranN)s`1liX+ehwm&5iRKi!Ga6 z_0ed(Ym+E$oX_7ZYn>a(kJi*g^CNRx^*f$t_&eCgyaPRs+UFqek*KnI83)~wH8&=c zjd=Jw$yi+y>$)Te2GzsJ=WTH%@(DqHRZesV!hWr-Jv`K>@XAhpOqr8?A_u=O+SV4u z^Mr={omtVytXYxhtPG@bZ|1MEuZh=DF0EQIUV~R2w2@ls*;H$3&6d`3q5W1Rtf{c1 zq>!F)vL+CyNroc|iWH2-i;MBIE?C=ER@zn*4A!)jmbKAWv)q^v2Kx=lrFC5Z^`$Si z?0868t=RD-0ZrqX7#iKvKfLo4QTs&vYjxjDepSlqn~>G7Kvv6w9VD8|-6yABGM&$FHYpd_D zRANnU&HTdJys*Ex{L(`2X$x)1hD3M3v&`Y7H6`{}XJ%k?R*w8h4-8^{pzRpiP{JEK zSOlvP2b~7$I5r8O^pw{WI!em|QFpjxcIBe}E$i~Ds>;2=a;NnWudll+wJAj7Xc>$0 zc{FbFd2-w|;NB$N^QHTGV;=iDjkA1(9A~rcmE_+0SK}JYm8}TBTq@Y4v&ZB(TZa27 zOs!piLzW$Bvx{NUIB}W)^ej3_hd!RvT6+jxD1=NyP%A@H>!cMj)HAh0E{A71l+tqO zoY;(jQjc}J%qO!}#)N{+6ReaWrUBC9eLNs_^_VEaB6-2)1y!f)*>g(Og3Z?p%eD9- zrnsiaeN<7j*kilIUEz;!K4;^dk34ec#&b5u*{+(|A-1rjpltT$na7LTS9LB-&Ai~l z8(p++?s~rg-+S-dOXZFUt@mm76hWv%I8%p@u*%QUE*JTAigqZ;;i`pOdwRAmtO|E; zz02Xa#9ij2b^T~p-0u2>yX?T_eQR~1kOl2ltn1%8^oX)_#mpOaE6LVFxV`%t{w!)j z`UmwNF^d-S=#oK(|;+9Tlr1>L2ReLuQ>6hy-y%#9DUG%(FOw>0|Ul$oM7Bs)tU8K2P%mt*PiV z9}Lb>dXo>cTD#n=VtZ~pd~nv%a8qktMd^&ka>)_f1HK)F)wPrd^g^}=XZri0Q=nmK zPSr~)E4_;c#Y$3fP6iy%`oJ$$e`-n`5|v#&e>zfnV`Xw#aE-5B;KoW8}P?8ZpXds-`BXqXk_S> zGEb)wWpqk0{ozDK7{4mqV-(^2slvT@D|e>GeMtLdjTgvrk(0%V)SqTAfeC~&qkx~L zac(%U9#Z}SE6{5-jy17p)VS3s6@41F0Y6&fc4LP)N#hPek{*K)GP zVRd7{s3U3c8b?}wt#O~R-nww{$o7$`k&}jp!b1a71L48(-6u|rY~L{ze(a8LysbUn zf}cclc>Rvy@FC+Tjf{>CgnPy(c8^aCOpT0>g$Krl!s~}ehqsN7jSLQi*R^)H_Ki#o zAnw@sqVdt8o`H#p@sY_)lHny=*Vgq84UbLk9vR*_Jh5wFY^;09?66F;ZeVOO+_SW| zXT|LBqUn**p>Vvlt*xENNSK+1Dc6m|6O&ZB45uI}u7yIf@kS=Y1L3KOfuZ4D0~0&L zauw$K4488o{o_2zC-iaFf=sF=T}C48T1AY!Iuv-MCF`LdMzw-!S^c9r%r7FS;GSEgDN; z_cjcJ=N-r+jC1|Qk=uwdihq<(58M;TiGC^X5nyBRAHXk_xE`rS@oba+BPf?rt;4=! zH=aJkr*tacF~nJfXA~)W;5&hT0c{q{6X#6D&=+;Wbt5WNw%^wlZm?$ zd>ur-BqOR9OiS4$IU!Cfx$Xuf1Bj<-xypmt&4gCyJLsO)kg&ekInQVIzX~5mCH-sYR>DFo`$deM}R2dJEcMmL35T zm>*NvL!{m3F0|7eV=i>?`FLx!5OS~xv@ZtTeUP7}sL68lq?H&SRvD{}ew^d77PVRr zi>8fuC%XwBejSc^`bgYnxEXWw(Z&E13}4zApMsU$S-7+CO5=CN**M|s0^DbK2j)#1 z-YD8}!rA4aF#ZgCyw4ebHQq7)X55N951%x?ZF~V^!Ju&oBriD*!YKJM+`4!&G|^j(Q*rm99$-%9Vs7SP zUgk62H)dEKKIHbZ0%I=>egmu!-zXQc5G!UStdy0pa#q1ASrrSj2&*>!Vf+(2Yc;Hv z)v*|>XAQ90ZGsVP3u|SwSR2E^H7sHLm?c??b+9z+WL@~;c@CS)=CS!~0b9tr*&^dr z<5#SQEoQx}k1b(K*)rT%iK{Q!A#4>}&HC9I<4eZfY%N>I*0T+4Bfgm4#13PJvm=c6 zjDH!wHh#m7WJj^hYzsS@4d83)K{mvO**3PF?O-G97`Bs*!p3Thjl&}ASmQx9!6spc zHEq0R{MPskJB}UCPGBd(((7aFWVVN$V!UX)!cH}QX1s)ZCtt=J;a{@T*vHxF>P zaTYt9ox{$B)z$gz0(K$0h+WJ+!7gE!vdf_TeUe?lu4GrSt8re+wd^`}J-dP3$Zldc zvs>^<&!^a@*=?`~x}ANN-N8PG8;L&8?t)#^7ulEC-R#S-`MQVQ%f8CKhIiQavj^CN z?Cb0sICte?_6U2FJ;uJt9%oOmZ^0VqJM2m0I#@t`k39wZoM+hgVaf6wd!GG({gC~L zy?_;csC2Hpt!zh=C% zY{mPBHtc!Fae+Y+r)PKYH1EVah}nD&Ru=QHTfcxWrp5j^z`4l27qz zejGoZpTJM#C-IN*lldNg3O^NA@gIi;=o$P><3i&meilC))_dpj^RUl<0l$!6#4qNb z;Fs`A`DOfa{z-lXzmi`C+r?}6wfs7MJ->n9$Zz5|^IMFo`K`vaSfRYhKgBO&+5f%|qEux}E)QUP06ZN7&G>RtCELudX zm?hdoyNHW~NQ#u`5NXjVy2NZTN6Z!T#C)+pEEL^hk?0YNMX%@+OT<#KOe_~G#7c39 zSS41Ae&c?zMywU<#CowoY!ruzP2w15c8C#i zjMyng#V#=>#>H-Nte6m!VoFSl~#Hr#m@o{mwI76H%&Jt&f zbHusgJmV4LQE|SwKwKy;5*Le4h)cw!;xci$_@uZ(Tq&*+SBq=Jwc0^Q^OO(L-uavZ68q3*1dIN__$%) zfCTpL@$KVd!#nK*3c7m+M6|>4Joh~ z#ScuuMZn&x%f+IM$g=gSa)%{w^_rQuhE3GotEm}Q(AKLm9+tqpBukHbdlq*sF*9&& zH&MwI+)=Gz!o4(`!o4GlTb6Den6T`?k8Rl$R-(f;ERq52%QXEXn*L>q{t?BuWt!3v z1zpR`g88!LeB>DS@@x_AW3sp+C()r{+Ou=}#PIOgC|1`agSM3egVR&PwowUmltmi$ z*j6fTj7nfxi4rZN__3{0sm5|rB~vO@vctAYr5aN_92?j@J~=fpzI(^8=pEZGhR3$s zSL>RN>zb}sH6540yL!j;*!F>m>0P4((^KB@T$gRFDtRKOAuBh(Nt=5sStyhVsB(SWfwwj{0+MwEMTD8>%U4v;|gAJ+%(-K%WOpJ_e zw@%ZqcSA1y-sxPIeS>b(X$9SfX6bStpMxKkgP)kiZHKEGo+N?ma8n{&Cz+_dyH|$V z2Zj|NR!@!&Ozu$lcovs@h_`oY*rj2&hKn4?addcc@)+gO)8*VgF>u^4b{MugWoCrQ zutZzjDVdbxlhh%qsS<5z?N-Gl+Eg)#HYIwAwjLGUu9_v$o>1<%P9N9l<2rpp311@7 zVV%Nm&7^l|1S8Sp$fR_+x<_~K7?7x^clYGT==hj)IC`g)uX7oO8Wp~J*9eUr%CR9Q zvTOCO;q5Ate+1F@DZwgBuq+y$8n7-I*tKgwk=vED>+&pzBS@e;D>l2P1}s#db;ZE$ z-2>=>yS5Gu@I$8gs%gGy1bstN!23tU+8yK8btBt%4T$vv({@db=-)9Sdhqm5j;La~ zyF8R%hN3(jG2?a(WUD`%QzHimk@a*^eI!;mt->=&rKeSvpP~b!d2WYQV1Z zvYdnfL4nv?Le(fU>rPpEry#2`Z=sZ=c=|Jgl$;1+sWF*_#HB^$7Y*UhzY*P}NY*UhyY*Uh! z)RLNPQ<9c!Qyn9zB{r!gHmM~x*`_ARWLuvqr(I2!$#z|?mguCG=w!Ptw_TUpuFGv# z5}wo@GTE-nZC5=d*{*s@vR(C*Wcy-Wo-V&#mmk;V$94I7dP>H1z2mz4xGrD!u%zx` zN!`Peab12~mmk;V$94H}U4C4bAJ^q4bomKgenRs-q03L`@^ueR>Uk=e(DhGfz9)3~ z30;0dm!Ht(Cv^DhhDi z{G={Fsmo95@>9CplrA@=%T4KWQ=0F35=*9ZxhY+4N|&3`<)(DGDP3+#mzUDz>4^+) z!jwFub-C$`TbG;G<#uWQbZI*A4w96FUySb!ob~G+kYqt}abim*$67 z7L(mN|8AXsx6Z#?r|;J3yLElKb$u3T`WET*i*))$I{hL|&mv9FBAwqNonMbm-;;4` z`g(N!i*@?NI(@IszgOqqtHXOU;hMf)nLgg8#s@$d4{(ud+sO85sKJT)}Ext+S)PF-%NF1J&c+o{X#)a7>SayxaooxPUc>4|ac=*ZN>Fv(54y}iRZJUImo zc4~OY0X=_e$H>HxbL#kUiA<_UO6cS5O6UPq`Rz*R;a26hr@EcUVwheT?eI+PfZD3? zN%yvq<1)Bs5{rv59ia2?bJ7ctn9aBG=BV;!nT4qg-!1s8dF&) zxsSIixd&9NX;*R|Z|_yCYwy*hD>;F`CcU@Yx>(MV#1+&?=89|-?CG%X7@wY0JcGfR z^u;@M4OLkQHO9shJ-v=~eeG@ZCnKcV+Q~!uXpaOu+HyTq3#HU_6i>DFQG`S`3pF3b zQ))f}lsQ0tGi7L!Q))s&gf!)l%!#1tl2S7gA}pc^ojDOS4ed%gQ))_zr__`LsH8Nd zrX;u}30>I?)SQF>#h;YsPfE>6@YfWmISFn_K}SvongTT`A%g0(DK#m@Q)*HIRQ)8C zkQAh|8K_wa5i|vAR)Sl#P)f~8aI21zN=OP)IT>gQ)UX5|_;hBqc?M5Gesb z60#jAPR1vmi34fEA4MieNHP;SA)B94nTX^j`N(zwk}#1>P%=|QdnO<0K{>}Wq$bVC znVgdudXgD>l9`-kwIqdR1ESu0 zhv$?Yo>O{wPU+z}rHAKK8jZhu>*)C4PSu!tm`>?oI)!0+Xe>8eH@+UGQ=MsRZm5=i zJxHf8NRMvI4cDTlwr}F8&OZCZlnNi6!UAw;*eZYRLpv3ukt&5Hi-NjrJr1VyIGEDo zU`mgJDK-Bioth$2YW{~?m##LA;O=v7!wdf5p{?U5*p@=5GR#&AK|Ix+uq|!xLDgPv_sKYu2au)e&!VPVO4PR5~y?>_J^khnSomvu(p>+vu=`eyo$bAyk&Z z(dn($9m4}?kD-x)UE^az?p@Q9FyI&+8=o5X<={hGGr-vdz)*db#!2AY|Hw!E4;K@rCdGT>%FvXWx9O32PUus z2JHaboVzCSq*JN}((T+mIz6edlZGe8B}Tf8LZHh?#3dCH6>Z!2^n}Ksn5cM@BPXbM zQa@3s)KXN$u@Rl2Yxvmdfl(E{Yh+B9oI~Q!*!Zqo63MMdl$a!uFiE0Bh(tm(i87ib zQDH=)j7KEOc#1@cDiUQxNuu(UBuZ3~C{eWc;Bf0U?8Uig%z!T3I<+ki9NkJLG~35o zr^Y9@xrfGK*E1n;4>pQvLsvRf6)1{RR)H{C1&L4<2+>uL(PR}AMpcmUs0uQks)9sS z6=XzN1&Pt#m5QnOO`aa?ghEkO#N`cOS5WQ5%6LwbQtu?uWsG);owIqG>M#r~niI;Bo&@gSfO58`%rMO5mcy~>YPL1pyRoS_RMvfa9QV~5S zQxPpMyQmLmhBLnGU^Ne|ENiSeQ7 zLDeF@$!YBFn3Zs4iS)qKiRvTMct^&zjf{;ldwUo7~mZ|aYF8=whj(V4(Id;a_063a=Uk&h#lrJ88v?^WOC;) z_AAlDDbTMyR3DeQkq_CHsR((}nGMbxK4B2MSF}cu85C@X&DiMhF4_atNvL_++PW9Z z@PHYf&BK4}G%bZN0A_OWnOmkZknq9qb03O;vU{*;*v9y=p0~==8R;9^vW_LD>TG?)#It#`^>)I zN|<#$ZQnXF4KKEB8NoB^#S5ftmvUu9ZfduQZk_T<1GmY+ajd{*N7g@>$O88()#U42N{=*JWlhTV$F zM`(x~WWF%&me8glEQh6AeYH;Zsjk7@le>-i|Jg6dB-)8$1?h_f7i@j3_+`eg{v*4c zGht_QHr~{q3%i%|VP|t8tZFXC+wn_a6>}NvY(8mR0V|xVjH~em{aU;^zX6suH^D0A z7TDQ5j<@?{SMwBXYMwQohYigOu=MyTtUP`JE00%UNAeo%cV3rPF>k?Qhpcn{VY~~Q zn7ugs4u=#oJ8Wg#IEg5q6~Hd02sSaLu!pH+VOGs*SRL$N8e#j=3cHs$EM7Wb?J`?h zx-5W|%VOBJEQMXmzSbz(66HV}6n5&rwK@5ZtVKSWtqANnys+i)!;T{e8;%m#Z&bi` zBLcgPTG(tfz+Qu_HQHgPk%EoJE}^W4UF<2FZy#A+BxU&+Da)6cGD~M}P*13YK!M$of{;K^m*o{T?`3UvFxyd zqtjPr!FsI+7HaGMzxK{1G_EQN!0+Aj-WwZZGscaJrk(tt;G$F)>Y})i>82!6N{mo{ zn#tc-9FsN^FAV`rSUFfD1EuuxVh`7kA;?JV`oqIEX z>2sh@TnOfplRNL-_jm8P=bT5ra|ik?599SHGhr4jcdf2~lv@V{w+X^63&qw4p{DD< z?P0deF%w*?HPCczka9Od!ELeYp6{@{=3ZvhL9%fda=F5!EGCn9?nyb8R2E0%BQ@HW zFEvV(Pm)OuE9GP|S=gD+$@d8*@vHn)NG8XJ3bM=#enBo+`G?BDvof->`Jw#8gF$OD zsV^(RwaMf-hXv~s%8B8zpldvlBn}u2Zb&E}9xMi%iV5YeVsLYje+FK@)JP=QoJ?Xz zm9KSvwcXa*tZYVJ)qtPXV_c>%Sv%C-S%?g%tM&DTep8w}SP-twCQf5gZDR2WNwe;dSAi z;l6MwJR7B>ucPJETf~j+6QY4(klh+>PIG z^l};-yaE4l8=fJ{_HEeU0sNNc4dk)LO6h98!fyPXda@ZT?#Dz9okR}T*HW!DG^-<7 zAM+>|>dG+zDH#WZ@iCVTCD#a$Dp{e&xR0`1r&&X?(*?+}Tz<FbCiB$4gi?C}g7N|CPsxigmBVB$N3vgDGQD!aY?np$Jk5%V zd(A!aHuYy@-kUP_$`bVh^0N1cxli7q{;VuOXWlPIsXr&Lz-jJ~cd5_Hs}P$5KbH(@+S$a6OkXJ0T1Y0HhT zjitpike4oIP<>MUH#Q1EXg3tkevi_71kVzBBmypsYXIt~_3q7R(j7g-@yp zm7`K6*62`%bU2nl9fd)ywk6rj(yDivUI=Z7?K+zEZqr|F%P6KDL5M!?kLL$@j?nf7 z-;+VnRe9E-3mM8 z!%`k6klMmT?{N<8d;QTKXl1J(%~Ruh+3jDCYp|FDd1F0hZpEtTf;+U2COzMG&(^VO z&vws1Rd41J=(@=>fk0lz)rXJYqe7@Z#%sU&!H;}q%&_dPPjobObp#)6V^x#YXC<W$iFF*xFWSSIZW4ww}|LEtMys z-~Rl8PriIw*=C5|+y5aq>%2+3ow;f2L)3fdTf=Vk6^;CZCFGTaf8N@C=f~C3>1e74 zjl5?0jlbRUJ5sHi&znSbY)C&>Kf)G6p2JN29wmBpk9Q3=zd9GKc99uc)`S1w=v{uv zfB%hMQ$70q0S0!+AF*?}JcqlzP9iZ&u>YO^!3In>jI(;AgbmVsdVCDpb0u%^zV%di z3G7JVWhgCJk1U>L8|7+yH?8(=+N=drk3L7FRn_1wuca|JPumuIt$6Fe8Mzmy%l==n C1V9h~ literal 0 HcmV?d00001 diff --git a/res/fonts/Fira_Mono/FiraMono-Regular.ttf b/res/fonts/Fira_Mono/FiraMono-Regular.ttf new file mode 100755 index 0000000000000000000000000000000000000000..5238c09eda87aff8977b36778179b4cd44806988 GIT binary patch literal 140212 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%0DHjD-FRlMi|^X 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 literal 0 HcmV?d00001 diff --git a/res/fonts/Fira_Mono/OFL.txt b/res/fonts/Fira_Mono/OFL.txt new file mode 100755 index 0000000000..ba853c049e --- /dev/null +++ b/res/fonts/Fira_Mono/OFL.txt @@ -0,0 +1,92 @@ +Copyright (c) 2012-2013, The Mozilla Corporation and Telefonica S.A. +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/res/fonts/Open_Sans/LICENSE.txt b/res/fonts/Open_Sans/LICENSE.txt new file mode 100755 index 0000000000..75b52484ea --- /dev/null +++ b/res/fonts/Open_Sans/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/res/fonts/Open_Sans/OpenSans-Bold.ttf b/res/fonts/Open_Sans/OpenSans-Bold.ttf new file mode 100755 index 0000000000000000000000000000000000000000..fd79d43bea0293ac1b20e8aca1142627983d2c07 GIT binary patch literal 224592 zcmbTe349bq+CN^^*W8&qlRGn+9E1>Zk;HIi2qAQM&s|SFJ%kcM ztoRa0YJNqpo==B7){*c7z97W@SkL?(1tgw-mGBjZ&?~BEY2ON6wlN#$xK1AGSq zD5=XEgs-#_!XNKjk&?b;$_pWc&;z($J8bNb35hSKj3UIe4+De^oBEj3njH2FA(1*xUL`h==2ehvp%>%NZf8hd%rho_>j8a zE}aO%^E=~u)+jUtC2GrY{us_ zl92eM36q9Tcwf`}2q6&+zFUOhj)t!5_)^Ym4;wrGN;GOT5OOllv016VFM8pQzGbI& zxq3PJY6!<#@xguS)^auAJm@t4J5F5ciajAhZ>sOh+m47dPrUltPqjf1StrvwLw~6)2dGq)H|u z#QC5|Ejb{Dl4;@JZPe3A3a+ga zmJ=drO#Jn3}ACeJ4qc6{t&MC z?*Z;vn?PD`^J4)kp2Mq23Q8w77qJkqbs-ZOzUj8sCbU=c;UtIMuhNtD{xT4_@1o$H z;rtVF#4^kFTg{S_cX1vb$3N=A30MGwsa|W(+QU8Ei zh5A)S1K=UaUvCzVk~}S6bvgMU~%$87_zLY|bd|5$e- z(%oyIF~cdN>;1LrB$=i1*Vg9;8fLt=!_|qCP%jAa1?)|kQ$DrT;Yt7_c zkvS&spl?9#nd~w7zrTh|Z3d4X3-AErdB%5vx!r}ei5wJ^Lc>vi#dLwNiB{4bkn1LL zM%YI-;QXAhi5wK?x4zHhPSmz;lwN7wD1@SJY&|YTwl0#2T95O2ttS;(gRT?mf$x0C zCF2>u#%RyRW;A8=Q}mZ#&jHSIc1^sAcF2zKHgqj;#pWkn0^XtHR2&&A6+y>9E)^L| z2EHef5=K)VMNA|OBHBQc&B9W`DYAm=d^6f`UAPWC!D_}cS73QqzoSHA*A+SXfrO&Z zbftd|+Db?wd#2PM$A??@h89^Yhz=TkV16>>hji`if#hmijlzKS>UjgL^3&+n!#HP zw@1;2g1IvM66rANV&%MA%*L_brU+xf+u%oO9&iPFAkM+HTryLI{;Eqjeg)S~aqxU^;{80gNp`&oCKc{0ABThRL}q9B_x@e)M55urYv(&B6}wNGP7|mxn*r zid-=HfQ^S&qZDQf=^+xz3Rg*T=|K|8H~5MW2fOVeGlfhtljq1#=^UA&&4o^af57|( z?mBz~6rlk&M=MX`hmsNCS>^|ntK5KPCCQVR|By%$)j4FL2zoPK1n?=s$tb8hbQ~ArcpVx}qxe7QU&#u?Kf{&Sgt7IYgG@3Q z|0%wK-=0W~@+3U73eTLb-i*1UNb4ZS<4Lv32AgOjczSa%3Vh@{7g2xCiXt!IYlZ&c zFZDj?R~vkhp`b5tpjrpM9|5|b!#Qk)T8nYPZ_;?+pqbdzxL2jc^&p&2B+)9S8<>3h z^|lDU5ZJx`8b0bYO(OWZ(FdC{UNot`J1&!1X6G)DQNk3m4|u)-op&1Ll*2 z37E!!_pXB1e;|Tl;~D=$uk%-NegX6O1as*G_!nbr$S;#2=yu2&U}e7DDb#V`<(ue# z9(@`h7YA|uI_9<;&&TsL1apHtO4)!l7xLk^(TYACfw7tHhsPhNaWBJ>Rt5bdRl;8x zPsWO8$V?{xOa@UO5Gx@otI-cDn?TL<6Vo$H)%dq6yr54GWFbejQI+*DbrtcJ;6QEBM=AQ`N#CV_SsBqvGJ`Uznts06_LPDjRkjo9= z`65!H&WFC83Er#1oHqf!5uis2=3|09T!3Gc0y&)w`Yr{|PT|>qz{i8v&%6+~~ zKp*^HwZhj-cQZb}uV#KIbjU2|k7U%)NUUy7`(t5#3)i2RSm8g%dhY@m!T*f)9dtAb zTf;d}{$u?nrGc)OpyT~Mn&SU5ANan4b=3jb^W&&rM7|^Qcdu9*43UHWT)# zbt8@sw6^#PIY5?@-HMXM`j=1~>7fY_4`OXQ>>CRcsZO#{+yIrEo z>I!x_T`{hBS9@1Y3>PEC7-K9kVKGrLNil^nwK2ovKDZ;ut*tGst$^GKh@m&ghvZ}0 zhGx*AfOs=~6%gO%LKKLP1LA)GVsaPaCjs$O{8s*D{u4k zu2Hk2Hb=c5bt>vQASO<$)8TX~5T`qH{186|h_?dbm;V6qAV0+B`yj3Z!~_sGx3;!^ zMM&#ctw-=3D2?PDvX=~L?Zqh5x>}wuKPgXb9o0Ilb!h8gGO{(Fkd`y-TFYs9t_<#L zfkl(SeKHiatogd?>yWQzd|ginD_PCVn;l9KVKN%dg|tlgs=D@)N(2T;n&9fAi0iU-->@1HXdCgS*?%MB0`n(RMVM zwx=mHm8OB?GiV2zNwa7+eTe4Jj ztLb1`Lm#HKke8u!7_Fnj=?H!c9YsgeG4v7oC>=}3(eZQwok%Cq$@DQgg-+$Sa---5 zx{+?8&(qEPHhw$ZO1IJNbO(Kr8_kWOKhn$e3jK**rPsjA|EAaJFZ2fem3xHVq`z^i zxM#R$xz*fr+!}5zw~pSTzw+x2i4)HXVYI2%z3@$N!gL6dt(qqEl87>{bm zea*Fv9`qdXhn^l^PtV<+)a2|;IRf_XmvQ$;i$2Vd%_;trYltrxHdgH z?%{~qz=p+4dkm>-EG?_*kst1Id6V1qY7BDYNw`G1E01iHx;LtnM> zmn=JAB13DF^mXpKA=Ool{1Du`gzvFr$-+i+Qe&b!zcF#f*CD{s@WyuT{2q--?5VxW z?~c>^-jK9Wj5E2NOMWGoj{B!8n8$rBL;NjLoatA>E;e%A8)OT!xrmU$aZwWDZ9fT~QrpuBgZwQNvT zBNtcT95n>Uz<;jW^-#FWe76rC@ZT>JpasYQhFva(hNTBQWGGG=XO~s^&Yfgv_+H{k zN%A&wwd~5ffh+cY?8@xGmAkjsx$4|EG=$!H7;Ex-iMd2$fZho_t`;GsMp%J@%xg;Eo}+AlPU|*Rra{6!(Nin>)|P zMQC7P^%z}IrQG6c?a^rK-iRFn|6PqKJ#a5rzsC~BY5%XJoDEXWS>_$p5#zecs@^0S ztrz!naE8B@K{^m`KAzMV+#MVl-(yKt-H68M+VDEa=m=+3xU13Q1vhxzRl~iEMS;!4 zivSHDpa6VTS=GD3-MegH6*$1~TU|k3T%dT@~(o44Ac19jA6yapAld9ZhI( z7U000*BRf9syH=@3B*xa8I$LAc2?1F66g&u8WWv8hUfeHvGWHWiW5Grdtu;d5V!pwe(z4PNff+I)BqVFKc;au0WV-J_h1p3*9Y zB8DD?B7S5j^zl)!cV*T6XZIlsXd*6LRxsyBW@ACpT^usxHuhA`1Gol%J$SiS;Ieax z+TFWi38RGD|3CuBdo>cq?w*Itm^QQo;}|#ew9^FfSA>7b9*>6!K4T8&5_hkt(`5f; z+h;@WN*gJ@D+g7%Ad=3oli^EDKQT&qp@5c{zDf2h)wl|s{hXBV7hTBri{e|OON)b} z`}V1eE-9{yj_+XV7nc#+FVxx^trA+JC0y@Q92H$xOp6N)(bf!0KM}VI8MvLNMn0E+ zmFK121*Zy{3V3%$OuvYX@P5G=_I_q+>}Sd__IuTM#>k}_Da|1L#*CEkD%iKDY+$3bsFCy=IH+n5rB8Y1FJDgbB6~Nc zS5!4RBfY&F>u_L-+!IXlypty<;h%jb*Gztl)yfw;P(C3wh%Y#>Lf((>DdK+dGA5-uz7KWx1jCqI?J~78xt}|34oV3B%_baufTIN#rcqOF0~) zke|o}tO5wd&MH2!{=fcY2DwIO(C@hk+#>FE?n~au_vT0O_53FO5HAZ!!gS%1*jAh` zUX-*_z4W=ttSVGZR6VCUqK;C(qQ0&v*F2*+rIoaq+9ld|v_I>@bpv(Nb?@kI>pSab z>OV2W8lE)lGF%8U2aOGSHRvm2h_R!w$~eQg!}yl*qN$_lDbok$Nb_X#>y|Q0gXM3Q zTh?4_f9qcBPqtLsd|Q*|OO(f(DiJ$Pd9euwDj=$P-=;J6%;gum*LmqUfn+R(Q{ zzY41jdoJ7*J|g^J__^>45o05sj5ru^BeH$uyvQAq*P`4}`B6_qy&QEZIy1U=bZzw1 z=)XsQ7k$gAafUhDIlDMFICnbVbbjD$a{lC$T}G@A(_M32t6bY$ue*-B&bfYw35}T= zvoK~&%u6wUi}}zU_E6=l(u+PVDm7jj?}?eJl2(*bA{g$I&=z+{(BY z;`YQHiTgC}%eY_SJH$U7za{>)_@nXv6aRHW*MzyPS4C+Lg6i(eC4Rm)c!#Cnsx?!;;%3XC*IA{(JIw$-lK%w-0IGwtc7eyHe6q zx~Ej6Je=}K%Ht`^QZ}aiHRbJ;k5c}b@@>j*sj5^uw2#vMmG*NwO*f~7GfxU6Ye%d%d`+Mo47)`hHJvZd^x z?BMLI?5^1b*(KTivtP}ABm14~o7wV1(nI+V6+blbq3I7DedyFfXLGvc^vYSA)6&t{ z(bX}nW4DfF9fx*&tm8jB_2{&$v(R~b=QCY&U23~5>GE`!=B`55?5?}J?(5o|TbTQF z?!P>to&lb>yTx{!+U>J$-*vl{r_Kw>OU&z(_iWydyx;O#yQ{i~c6W7O(EVb5e13L* zVg8K#x%nsZ&*Y!$(WXagk0*P4T@YT-u3$*P^93&!yjt)^!8-*f3eFUq>*?y5*fXtX zUC)g@KP|Ks4laDT@cUk!dTs3WbFW)P1B>1$`g`w~-fer=_x@M0wK%qTQ1NrcU-k*^ z6V)fbPjR2hJ~R8w>+@ru>m_j|gG*MHeA?I1cWB>@eSawJUb?b$OPR4Ox@>IOl(PD= zhO+0%ekt!&{(O03`Mc#eDncu|R`ji?t(aIbx8j+K9Tjg>ykBv?;(Dd3GO4n-@{!6V zl`mIb>}T%Rt>1!v*ZW)g*Yy8=03DzikUe0;fJp-y2E12gta`Gl)jQAIJaE9k4+pgw zlsag^ppAp}4LUXG%j&Mx)2cUA|Ev0!!Lfsv4L&^hTuqyr+M3lhXKOChTz=U8aPGrH z9-jB`j)%Xfjjo+g`&RAOLyCv2{qw(}SB6y&8#`=D9j)tK_jcWxx{GyJ>TV4ehIbr3 zYk0%(=ZDK9YDYAVRE;!^3>_IWvSei4$SETij9fi($Ed_nPmcP>=r*ID8hv$4)|h!? zu02xy$lo9B`{?&$XOBxAcXiy&aq{?z@h^?PF`@H>k_ojFewa9M;@6Y)h;++1}Z2&54?`d#-10@!YDp%jX`QdupC)-oSY~ zpQKL?esar`U(HXMKV$x>1z`)y7c5#JFC4${=Ax;Ko>P~~9A*x|=!^wuGhAR#73gZgriqsW(D=JnDUomyXq7`dbyuae+ zO7+UHmB}kTEBmb+v+~%}&Zh@IJ^blYt2(XP{EYZa-7_bibv--v*)yvXR?k@d{&R-s z%AR{;jeSj$Y0WQd#kJvUQ`hFLtz0`|?O)a| zS-WBFD{J3f$E^!q7qhPYy4-c8>xQhGxNhFMXV<;B?#*?l)}3E>Z9QEdyuR)FPV0-; zSFNvGKVkjj>zA+Jw7zluk@f$x{@eApHfT3QY-qos`-TAUxj*mIt!NR&q}@FK@^YK_3F2!SfiFk5I&jyc1ek(O$8 znO)f^hxuO3Z;axmw=5L*-!2*@e9N9QrS%(nR(Xz*#Ct5fR?7*3$xKxSRi)Qp<#>{t zn`9=+^UN8_^QfD5(GFP|>A`lJ7!y4|<2`U6I)e@)T@$ih(>1K+@ewdz?N)dx~q0kM9#}c`>@FnhV`I$4Z z!k&W|wIGZ8kQWwB>OJ}Dh-kZD(`d8;#ddRuC`uM%kWSEAt+wE(NR=Qt93de#Nh>&A zYC)%qph3~ZXbiPmg7BwxSb0fn0RXufmK-d2F*$(2{*}r?9SnVz|Mm??RW3UqwYpi! zbY-JhGx!Wv>|#c?oBu9_a`L%8Uz8jvK38;=+EbdTt4~v(<0a=xer}0;FXcVH`1_CK zF?2O6AASD`eNG~e(?Gf8gWHZp+_L#)|lPDlz%aB1QseS{;Tuh-^~^rc==;w1*0ya2$10aMOQYpq-M_YirY!>EHJ5-oB4| zUwWNuZ2s(LK570R+XXVKzWMgd`ftDc=^{P((?4z(iTj&5U)wj|{d56sjN;|3S0sYD zMS|jKWTGc0+2GdF$Y7!kHdw6*prjwvX2& z2(DtUV5MN`+$0hLp|y~lkQ6pcg|s<}m@$pu<7q#|L3H#;OLe&tAj`3gqzYku(ygLd z*)B+G9K%62l_c6B9vHIQ99dZskrz&W=ifKvFQ>2So&UqpgBO;pqY*tj(5|shls3OR zXZRDt<$WEy(~*Ta-TOS;zk1^Qi|;HxT-kr);57&Tx^mhvuY7sRfrWDGuzCGQbfHD< zYPkiOT|Awt#-t9$Y8X0$ZcucF1xk(=IHoL4D|7HE3Pnly^aBTo-sU9*c+L$w3$)_K#1dCQjwfvSfDP5;B4IKlN1cXG=Oh742i*9 znJ#b-^q$#Go8)>ruZhl+>zlZ`Cb~eL(S-dR%t*dPPm!zGfwR8>(;ppRe#%ghx*SCx;XQ zp68h8+-El_bx}UQ<$`>fb1{pFJ2+C*dPOM2s#}M3b{mgP4<#*;kWh`iuUDhujeWhy z1r5mGT?-7paK#X_$>K^U)C5t=GMktj359p$J1uhSZ7Q@-z9n<;xJPS;JTkV1Ym(>4 zE9m3cW0^=z30ZiMPQ#N+U|~xYE!4#m6%j;L zB$x(AMF*=?oYtZ(@mf?Iji3=FUN(qN!}uy@DwXLnA!CDO(ym;lqAXMiT{&nI<}6@% zyGtl-=IHpXb?t_f_1ipP=c7;U9JTn<$9g_{=nz+bj!u4Y&bUrh{Ywf@R2L`K?R#wa zo`bvhfM9?Pn9l=j@nn!ECB^}*sNy3ckc44SCA4ux#YO@5A&wA7saGFD4SYz5HdbXY zX-$2-T1FBWyb##Gl!t2uD}V=_8VHpCPeGGnr7_&39GmW6=c*rQ60y9t#L3J@r?v}t36C34ETUKy$Xk?=tqvh3c9poD{ zMgD}QoZ}mtN8jpt#adn>KLQNb0mGSqD4g{7B*C0I_)wcINFBth`G`oHRb$n|%=Yz$ zBB{l04=M55B}w1cE8SywW^fd@LUBEP450wXED+Nn%w;5g#5yxOxEMN_d&*~LaU=fc zj{K?o-Hp|KKdqtRa#QB)HZ!yN(3YFw?k@a}t7m?dZ}p|Rwwd3bx9jt`ALQHeB~=jc zSO};~#S`!dVo5iTOS0(oF)<{wrS$P7+ZyC=zx`RhI)7FD zI4W5GGHUXqiL*ZYvhR>S!-tmCi6`ILGU3%8RqssN*Yx4v>W>ul-S^1GBXw^ezIuLkThsJS#7g25OwLlT$;1Z-hxPRa zt9W(k{o0r@XMo(8kR^w$I6&=~giHoJlNNYDaB2yNZi!Q-;hU6DBtIiJ%b~9b%iNZ0wT}+1t65Ob7s#b@|Dap;K}TP%DgO1Jm#KM;eBtnukB@nL zW+|h%f2D;iCuTX~Jyr{Zhma7Xz0zwm-8Er~)KH-0HI zb7kHtjK^&8S&SzU3oMn@pi)_RL4prw)tV~3T9Y8bGK0g|Xr?3SOqswyI}{7e-!~XN zWK^tmN?@?74xiQLngWA?pR33zAqT2UA_*RoNSXassRe}8!Pz3|qBs;7A;4E`DC8&D zDHU>>qxnlMmE7)AbbkZ=`Dgj4{2jwr72N_4h4HnD#Cptdb71P!B1>?=5*5$KGgAgL zAHfeha}y{^6@Q66l8Vz_n@^&kUIot1RBcwaU2-{zxq~GZX4OJjhwN-zm!uQbJI5DI z3N=0Y;+_ww{vZ9%baxbciWmH{;RE^a&m-|AWQ;uX@A4fa84dWHuB74@bl{<8vU^~S z){x<;U&{Tw;@YB~9p`-Z=2^7Z!z0U$2sdDljj#ny*yMI9n@teHqI9|#tow{cm)aC+3hm?7o8a%5Oh#f1EA|>K zB&67jyYH!Vh1qL!sy=(dV7x~F011o#A9Fyk_9ljq@Hw~Kl6Uav} zN%MrLtX3?>4GtS(7R6q(pc1uWu~)13?aVb({ILLd5QP}brFOx~6^qk`K$T?4a47e0Hv`e1~vS{{6D-=p#4xhQ~bSYdYYKkw2k!WT%AiyQ+i@hQ*7_ejp`Fsw+eS?EDVP&0g)?IFMhEtp(50@X8htgAY1YIV- zE!S?JPv3Chxq=zRKZz&Liq}5WYmo&v*y#y*TmBV4) z98a~yUba}j&lyo%(*P6@FU4tR3ofMyT=RausO1X1CYw1MhLzuu<%LYUVN_nms2bA2 z6Q<^Q9sCJOwQSJ)#$&4+g$bA$yf@1IgU}!3GkihIWeOd~23XkQqoSAqDu$6_PeNEo z2p429aGW*5s#b>wnRF&F8`utL)(IiOVld_=f~bm@syN(9_bAI0o$|*PuP!t618A!_ zTq;OBR^%|m*=85_6_>yK_qp=x@>cpR9eL@Kk(>W|^7_$(L+a$qd}fQbeH@*SWVE4l z*}z++^7XH;-my`(o@TTjpGZ&Ac}f5U+gVbQ?**uN<0n6e>vR$iEZs$tpI}PGFr`>p)R+%L7F8+8 z%7$(eOXbb-oOujgGw3o}C3D=UnwFbD*|6R8-z`|O`lKTlql;`#f(qJHqR^k1lwS_~ z)PR$#Jof-lUncIqQ-t(b}!S$PIsfNamPbPn|1Gr!(q`J2Bp+sHKBF3emFha1{P&}i%=D9C8E8KBh- z2BXQOF7}#uSfM}BHh1ldh$XhNUUdre>WGG?rp;Q;9g;tnf1VE}I*VY3otGv)I(F0t zS8li568C?@MxO>N$uMAq&z0wiVJ|i#GN=}`2yTa)wAwIU1rq~61Qn1Xs(_EmWZduXjZS-#=;QzXgq)-rh-E&Ov#iG>QL9Hhh(Z*@2XEn>CW zV0$R^g-#b@)#!<)4>YGvuLsife6UVonY&6F0bD=KrVvD~83Qp%1l;#*G?>_Dzlj45 z#?`u2%NkbK0D-%Z6CCx_Tv}8o@07Rl$wNnvs%n|uaz@<$`T02~b7boZ4(a}s)WAkN zpxqN-v0}o*!d%29+Vl{zHi}?-mm0F`Fs1>C|eg zMFTAZUh<2UFDB_1EwfD$z&uRz`WC=uv1X-w^>6aG^7}M%(Z)3}8Ocj7Sz;(rS!0t4K*mh-l>X5fPD*(R!UO zD#9x2_zCDve6gAoGVAbY9Tw)SM_H(8*KgyD6$3Al}vW0mfuVV;Ub~ z5%?GT%bVog_}fRnkvk&uy%QFAC2}U0*m91$&b`-ioeOG7^1*cz#pe}9}((y~=aQQ(fbQw86gOTOH4!5=rLBm?6+ zl<~1YgCK+kQ&kgHEF?7mfG_ftmg>kbV?WjG%D8ZWel15#6f4jE&OBP8=F~zL@omHy zl07zr6+}rugh7pKpp8o8Bs_@)NRj=ckU`Owz>gKi-i;~K{VV9TYjEGc=hXcE<|1xh z3tlv#t-#}3mn^u{khe9kYIT;PoekB+E3 z@SQYTaW=Ny!_NC$y|52hXemA(K3=fH&K=FYkx%>Q?iN08cP!67{QYod$@)X@cEbCS zY#+186K~P0^;}F$NJwm?TJ6?{_V()aqRnP3@Y>+hiO~gKF__pDo9bIEDVuxu+*ihW zY&GY?a$8cOSXf1~-AsQN0UP=VBPgqHencmApRMy=c=Pu=M_yU*`tZY-Fa0ckGIjpk zXU5E0Go<%{U3*{BNNKyuJ{tbs`z;O*IIbEvXU1^Aycsa>!+wF_4G=?#M;w~A1b-GxXB6eZ^9{oM8AxrTi~$5TDVor53nKJ>OeqP zSp~2qC?9nE;&&&GO|WPDK-2X4MlOYyB42iBS33)QIj~>}7Ii(nqKOy*S#SU{KhrYIiExZq=vOgQ zW)mzd)}9hKqU9!bJTynv4J>@T>(#4Ot9utcXXCoiNSa)HB{B{g_&`d!d?zIq_`$fs zL_dB!9+xKA1cy2(h#|^pwCjl(n`;VwObUMPLcxsbJ^TPe4hByQhYcgFdNbmgeQ|@Z z34n=hMkrR4k$@%1AnPO{t|lNBn+e<@R3| zZ4DsD59LrLE*K8W;N~rY5Nb9@TD01T5W9u96nS~(MUf(}!KAVmcvbhqsf1APx+Tmq zD4`yZ&4tCe;%8>06T97|?3^IBBXQ%0j8oIy+@vh|y8JN>z4a4Sx1@+G<__OCv~)ke zZsx>^Gn>odt(Xy9%aE^MeP-^{ZQEaIlfWb%)}5b%H)!povnR^NaVn^rU=bI&C-)w_?<6nAw#(bJ_Pu{>T{V1Bq-{`!r(a_H&Pi{)Zx-$d zxrGBua#Q>AeFlvgGw1`*ZZov@ zpTj4O%3@QoYG#&=p{&-R9Q>Ox!cO_jzS)!HGc*l5_cw(^;eFzT!$h!8n<}h zw*NT}9$y9Kxqz|pE ziXF5o8$_J-?6W=l-fT zN}(jkr>xVJjRwVAl=#4a1yd>udiCi^(>|J@3@h70f426o6n5Q7+kD_ z%qWQT^0)=qPDHLHQ8Wc<4FI8}IriU>e^%p>%zyWh~`mCAM(K zzi$<91jN{XWknRjeMivupjRRxo&Nz_u$?h){~E@<04C$LNk>0mgS~uQ0idkn> zFe|bKqw286#VTLY>%)oF8WybS=?yj+`JP_mU4`ru7{%WVY`{TcVC0|>xJ+iwf-Q8_ z*qJjPd35HCM|n}cD7U_F^GO;-c~o55j$JRkxMRom7v*d6hs&wDky>c#GWj-xVl%Yf zK0slGt?%xM34z;>sFo_yq%t|7If=nw>j?v)Hmbr&_&t;AM@1l&%}g)EFv z8L<2|PT~XB9;o7_V-rj!`OK}PphrGEesT1X^NO`UJ>1r?ELiR&6|LNX-S(eflW#5I zS1HDxmc!UHd;!vl3cj4oD+%T!d2Gal#%K^A4-0n~qk{Doi;C$RJ?ZJy-$mYkSY6*9 zbzH#6VoB%l+u&eF21}qccVK&j-1x^H701s!_lR)(;x{M8Z0f8I$NKRjgCT88)BGKA z`!>k0?A&n;UcU+G>`+?S@cVxHS(iu3Dt(f`PXnwbw!-8r3O|{dS~7?t^OxX*`=!Xo z;WXXBE7mH&;k>D9q9ZQz>8qR;GF5%-~G=A?^IVlUA%C>s(CXy(&F9wT+Ze;S+%jr zIq_N5(*``dwd#x5_Pr82cgn2(3xhWW@MhzeO6&wVCwjHfXtiq9oLOxSc4#d|OM%y* zHyTBd4j!35iRGyTM#vX6dst>?~+*3+ASkPMEagjTfKZS#=ak z<`caxxWCGH^Gz;%&WI~lziIiVTUQ3dI>;Pie30~XPY7o=+ibyD``axVBPRxlLCV;Q zhv8d;-CH6*;B$jW{xE>c%pXWJrR|%1?0uTXB%Y=u*YT$^B{WKVmhK*ybF~ zmHP`dE%T;7T05Vs_l*G+EFHrbkt|zM6tvJGk;LIZkXjWU9uX0Zg+Y{q1+b0AaLGtS zrhB1%fm00T^Q06Mvs6(Wuzx_nBTx4(7%UDD#WUT@AQH0sKc@OnJ|G{VsdJ*8k`QfL zLQCffW|M(Rn)ccSG)aD&E~HnRmkKqqdH#>Z+xu}LE#C+CA2K+i@J>5=4S-`64BV_% za8vAwl@K7&V5y0@L4_!cH@-Qsgqf#(-K;m>Zn+fqN z0lNtrO^As(HfXX4!FCh&eW4S>*;W(C=5qmjR!i{$6o?f2;1g~$3!?al$kuGWG=%JI zT5>jAE9snPXiqtz+rMAvTb$jkYN|5!e>Gi{I6}oRj2GK2KJ2 z+I`&NAC9+_VWeoR;XlI~KAJ^Ec$+#p+8h$%G(<$W1m0>jfSY0sdjE1>;Z$V=-%&;e z!#!+rCUz<^Suz9G26i)+d%<=)Q?+(TE{&d7|HRxQH-`0=zW%YO?#2-sG@$xgRk@mW zU0Z*NFUXfaI~1dL@6pJgNDZKe zh<>DGq}L;1!LJh(mF?$qOcypa6FM3}RPY9(#Xym8S)NV6G#@}YMRr;xIm%^;!x1E>^FYGkul*mtHZ*?@NmxI&~n;{$WUuv zuR5r&mx$_6{7K=V5;Bu~N$Z#(HWKg4O2XhQp)?kY@n!kV=w!Kz<`Cl!=$tWtE|OGv z+8Hf6PGc~H1qX8>rVxw86cw!x2@NUpYC=Pa6{g9Egvbyg0^kP{sC-FqzE>ug3RP$W zaQ*t{-U1XR%BF%}!MG_C8HQje?$FVrgEvktsif27#m{jc-T8iGpS^p(5l@wW>+x0` zZfe+7A~)Y^H>qxA)6tWkgJKhjEVzVSz-I#1$T23pRUgB124UTFM$apxAtBpCO)+L7@N+6ca!* z>~1?NE(P&GK0>vH2odJUbB^A;c~idh+i$yBd(6qF+*0w=$(Q&=K(ZTAV-d?1m+!tE&%?;l^=}=~> zXa{EQtSq5F5cg071iF@`dMHVJKC=T&p}2SPjL;4iF+h}mdSRFO7xwQuT%NzYq^xMz zq^;}fyXIaydFtu1;{`|J2A00DDIaoehgY15RYEi$q_GBBr%E}gXP`3CBYa3%t4@07s z;z}s51>Hp~JMeLmqGkh{#usf>;z|@*Oc}^xvfDW9g2i&#@C!21W7!J<_;nfVRL&YQ z=2Xs;Ie&Tb!;9xnJiDQ2VsribwB`d=j>ua+J|k~A`qVZWv1J<#-?~lyddoKXo2~ry zXXeS@M@7DqbNl=kzn1LmDF2|`BX9ZOn7rfTGj!l_*6qIA7-yw$KXV6=CFvk8WW`2> zsHnpcWl~|!M->(0HX01kI-Qk9Ww7{?t6V;IsJHif*wIoIDO%w?u4ZYrIU?PSz z3wVG!Y?6s04MMUs#K6xf2>L7Ht+=P4lh1E8{T=TxWE@s@15AfuEv(c*sS3Y)q*Uc} za+CZ6bu`J#VG<^N!H&O>pF(i=1ooNbZPVznuzQEhI+I(l&bi262=lPbC>1svk)W&C3#kKUd}^3B3o+zZ@yi;D_5RC%jH-2XO_v=bMm@n$rt`l&ZVul zC7U2g=OML$-59uYK7xV~8E&OJHw3+8JE^Sx`B0wu6G6yN3h`+0f?q_qMIXY5;(OUk z@liUk*bvit3LD>V&Z?_7*HphSc<|=ID^I?IAGR1csGDbyFp;%xsUG~oz!NJy1FO5{ z)>MN}t3bLOk%P`+c^@H0l?vHiIz1A9bUKsSpw}ViNJ1=0SOWc+wEJ|kLZ5sIkQdhy?ToLy+<`;}ukj1X2a0;o}5uyo-=8zTY z1ZFHbz|LLO?;9f<9tE@3_mW6eF7EA?=@&=jq_!y=HgnZmi#OHG8BJ@sqMc23-t_o3 zRcq$VpVDvjl!q~9CoYHEkNnU$($y1b({XTjh*NUvOp;EDPvC7fyIm9Ejt2&6cuviy@+$`hX6RpGEq$bRQ z-8O(8s&W{E!B0l~J|GLcvB0En@x(T40;}WuCk$JvWMZ-X8m2N691es95Du-Xc>+;@ z?~;sd|5DX;lv5O0e3X7NefnSDW6^-s{ra_U*KeczE`IBll8JJ&(175n5m9El&V(f| zCTlXQ)fDmFKHealr)02fc9zuco2ZFph+wKry4}c{#B$1%mEjT^Uf8jvYvn&q{quXS zT5gs~e{bY7EVu7afyHsBaEbIR)*Cuv_h?{%^}MFii`Tz=acjkUV0vD0@0C}nSh6{H zHsH=<@3aXKafC9kC)mN`Fd0}J3x>sJG8t?Jt0suOScY&o_yJ&oM{*wbgUdJuysErw z8Hg|?WM{xDpH##s@t|dfx>kg)>k=}Y(W@FV!7^)<_n!o$ zbl(5|Qxp>lCJ~Ga6&AoyKE(Lme~QcC3a|2FcxuU5n*0t|MBkq9aBSNyv*6j`7p8ya zF2QOtuO!-I2)x~8gi`_|dGGa6pE6aDthgiMeGW2r>5b>tzWLhLH3wyPx5C2Q+`__c zLiNjskG=TPkz+gRh7Yf+8#e3@R&SuEtqzeNWXvN84_nY`?34uEGkStz?5K#hn_>Kz zeqnR_Q=@k{9oJ#-@C}AQrZn<*MPDVXlb1KqVEM-;juG?dGz~uhSUpY73A=a5 zY*%~4kDdm$@MEpHIbYj|%Cf|HpU=)3Pf`;y1_o9L_B%b8eL z)^i}9+6WyJPo_jGPsMMn`<{Bx|I}pPQ-P^2@^t$S$JGrbfq`WXhx>J*&XnY1DW=4!4-x8Q~0m~o<`uyx7VEQxa-}pmDv5OS?;9w z(XlxLynXl8ju`sem@n=OX?Qr3wz;>uEgJe%pOUKFoT83x&p*`T@Jo+w8V&ce6YU?6 z5#_f%kx#Cg%*EpkCCrg@N8V#OQNM;g>3EWq`CocWC7=B7J!o&z-`6Aj!DrM4M!{8o z56go+`UiTDF-i~ZKAv+cUG71m_4koz>69vk#%{!QKx0q?A5|P^Y{cHccu!}^%A2gb zSuj&=P!RG#^w7a}q_5aaNWsz~!CH^k7J2p#0hO#8B`29joqzvSNDpTIh zyO-6VC<$gve3?kfu8NXM5A(@Ps0+JwZdF|KbFzK4e2i-lR=1o+2G4aa<4z=6Rg`QaGqcEE# zI9N}$+EAo3AcY>OMTp!W=UZ#x%q*)tAa{yky0;gv_(P14EMA0+MJ4MSw2Na7ff?&? zB-y7d_NUh?srHKn;p0!Y{`Av4dW0|M>X2jqSC(zhRWASjn!HYycl&52o>Vc8XQ_-T z%<$}kc<^P+DtKUqo=M&mr3V)kpoo%FdtZ;KwBUd50m(b+>){g`##1aWSAjzr1y}t& z!X6xjVcQ4C7^Mf3yd)ppVb$hPyy@uw>{R~@%J*1<^`5o86D&I%+`K{ckysafd)nPFOj|3S%Upu znd)2e>sCHBYtiF8_suOCuOfVNRqi}`#v`Ku7R%ETM<=5MgvBAep9pSWr-Q z`;?TdpfHz;BqXT9_>i_4ZF_n%NQ&JYQsg!Jx7QT^R{32Jrg(jj`InH)dNTNe@Wv3^ z{PQ`60rw3XguVk=-t^%Qy9X68LTI^&10hOOwFx!tqVSzh$S(1LN@7${HbWq>>Us_D3y86~# z&OP_6-^pwHxg7gkm;_0h_I77}1D&dB54OkdV1p6ZM0ez>cVKto4!weSznkp)CGcv9yGMT#MWQNN#YZ}YTDIq*1rL3kg#c3-Th|qh#-tVeH zh=35TYDAn_aTUek@v}7^0ncNNH2uY`ro&zq%Y_xkB9oa5J6#9$B`z7Mk!M_?MC5O4 zkQc>xwFVcmED8kEl`Q$Zdd%BTKK0g5Kfcje_rNnZymtDFnZ2LC?NcU1ixB&@f7hU0 z(Ox&*amNEU-X?}mxY$;4lJ~}mvl?G}hN2G}`t`1R@5Y6ZUdq|i2nQQ+CNE!1mgTFi zMjRsh;mnLXXw~8Orzk(nX_b1CvxWR5r}&96oEoZCYIu&XR(5Q)F8_QsyyjTVKl_{w zH1f|2+J2u_TWx<59fDZPlGtjutif|X;XU{n?{MlU2;spqm^IeMGMv62CfqT*rC-}S zTJFIe-?iSs1}g8Xceu1R2!CB%26IEMpgv_1zk~QyQ0)o05sxL&hq>fDJJJ=^S^|Mo zol&w#qUcIZwO9(WT(10}kR;+F+?h$D-;Y=UgquRR7VSAzjds5z4r~NCNUOm)76Yhi zSRfT5ml&T=#ca9~J1%nbD*fE2;6}n{I7{FO)`7}g93e3@8B&^=GPwH2hj0FT?B=zP zD*tZzMfn$#KRsM!>@)AHv7-C-$#bUPHe>E2U7$Q~Td&&tS5J6IS@DhXjdFmwzdOxb zW90R>KDahIVai{YJo3PU8;CyEffH}i)2( zHER30L6|Kp<|`on$sKw&5TO={d_ir2dcdE+hN_>Zw|xSwpxT2;_?#%ISX)2fKnb5B z2l@c`g9B^WF5>o^k+>}*_Bu^S4I;D^+@1_w(Ea%W(2}T97Hmtp1WS2h_BisRqYG<# z_a0EwtJlDq-hHa+H(*>&eqTGVen8dGdPyEwH>7{nka|3KRLc%TBQ4`nL%6NfkfTWr z6bB@Q`d=PS@_&^YN-N}56rgnHls>EbuA&&FyKkvnb;X0tO&-?0u;=Yl*kP-3D7WJF z$pF(qz*5nT6UVMa6ewbrIt`uDutsSbUCmAgo_TgiH>K3^99Eb|b?_A)p{_9J1S~B! z|7|~~72c@su|K&3D-1ys`#4SkY74Z2>JuhGWTqY1PF+FtfyWN;K8)ghn2r2Fw2;AX zzz*ecRl(L0=eep#*&1&zyg88HbF`&nw{Yl#yFa>nfGd@bYq`LY%uV{TSk$WCZMwzsyx z27b?52*)T=ZDAbx#{0kqu@h{5m~5Oi9tK2IRfE?1HYOvy+Y2qUr)j@_C@k3)}_E6E43IW-}u5XT7t z^if0&w|TZ6H(asA$7F4eMa(0pCbzsCjsoyNQZ0WMI?pb?`N=!~netq@IiS3a9H7!Q zYc58t6KbbTly6)#eb`tp%VZ);X10dG3vVnt@YGWWni>#AKX+y7w!7|oZpBI(DarYW zk-<9T^Es+(`Bj}|N5UM*V>pF#If2zR(OQe@&X2XgDO_!#zUA9LYJpR@+Cn{Fr^{Oy z5bwhvRR1U^?&4|F2fj|!0#Qp(wT(E%?ZR$AE|%H`-wiPGpm(E`d>L5+xQ=h~>pcZ8 zuKyk5PPB2<#%vt%eMzTYg8ap5VKTzFLowBib5eD@4W%pP#j9;#4|HL`<^Fx|#VcUyMDP2>zDK)j93Ow7HvV<$v*T8x zbtJhMHlyW%+8yO=iD22m!eKLfVgGi;>~Q)FXqq0_s)t1Ky@(v39JOEo0ZqVhGbIHK zwT*sqO$pWjUM4qE$W5_~xmLu>));lt_f*#vlswuwu(07pktwjYm50b-r5pFkD{5Z+ zE=tcvW<32RpFhy_5v9n>MF;ln+ZTOn#|}s)GMB)-LMrsoc5ZlUg>)n}5`k9!RDa|BFkL zT-t_P^L@4vV=Ll*WbuHQIy2dy{%W2&45a$SL8+FPDY8!@F8wT_vnezm- zjr!lUf&C}$<2*raqdwM;cpJSHFJTj?V}Yf4$gM<`g=*#kuGZq2xEi9Xuq49PNc%v2 z-XNht?X${3$d-WlILaf!v`BvkBOe%F57i#4M*8CxYEK!evw$Xfd$6t+K~AOX%fV%U zMTqP4bc0YQVpn0_fpQ?3_+BVdDP7TcV9c^Z85iQ$#0x|Ub_BOj-c{$U^|Zo1M4CLt z08a(&Lt!m{<~pS-WlZ2Y@lCzhWfmIXTEPW$)*V!`kMW>&Se^3*l92{!cZ_HE6Cbcz!BaUOpms1$peo=lv_s>pq1JCu zx>AOQ`dylp79F1z{#4z|>fP|-bY`y-f={=ci=O*>h|L$j1-aR@t8uz$MvX0&<4{wI|YBs+rD zVD6Bv0&D6(TP@PGFznmsF&!E^O0uenMs7(qvzCb(0cS7y2n# zt%j&~@XBO3z2n*kR#pd;3AGJQ*%#xKjl2}~n<{0i^pyBSNNwlTC&s0=b(|l^o~UQF z*cfXALgZMORz zQWE@?ZVjO%PqjKB7mxDEX-T!@V$~#o3pidh(2~klJdQk`=jhc-7jGVR&48)1P0dOi z55tJ?r5{y5ldFfx^%^op^Pb{O5T~piFj{&MLY~mU?vv}fcALwy&`uY4O1Ite z)_Z$++SX?Ahm%@1&!8(mI?%lJ#W#r-NaFdLpA4n6($I!9|3Li2=avF~GN_h5w<%Pe`1%Dsl6Kpm>1KA`q;5f{( zoJL4X%-8Dm<3>r2Rlq}TgB zes1eHW0(sH$`A@MOEV%@6nC^E$|g70*s)`p*V`%6Xe>+h1&e((jm5=+)7c(!i&L}% zTf6`{s7@gW!z%*G`!~v$8(tADq6KU4U!2;wu*J<~v_(jN$)teWSmG9i;!+|lqEOU8 zZhdP$XO)X+H znAkpXmUqpX2bl2%=3_;J>ef=et#STRB;3Np+E2>|+c$I0^m!UbspdQk0w?h>VVO#G zai0k|inN?l%$2wU8ZlT1I7-~cMjQ;08lXC~z&Y3s&cSdxQ63bo<9lsSCtbo5!Nbbb zC#J=?<}f^QSL+j5?c@B3{umGAcqY8h6rOn zfRYFQzm@W2R2UWtS5X!Cgkl0XA=HBvvOLrb9If<%>Otr%7cZ*#EWiFLHYh;*0!Rzs zJMeVsA7zZC3)e)7T_&$LDK*t(Np|=hHk0T#`7<)@0dJtHF@>uZNmhjMxV#QMQpmVR zgtElw!^IyuvSnHumh3Lr}ltfzsRrCw%fyL{|esbKvXj2Ha^u2k8kp9IsR0r z?Re@yE=pn!<9iKlB>I41zwoMU#8=@mo3CcSU~vzV+QM-3t{XiAaX4;m^r``aMuusZ zZ{j_L!I<-2jgQ5nd9Zt>&Ag}A;12LHbRGS4$JSbHfpk0G0_5_5+RwP9Ms0y~1Zn}2 zyRZ{oLmM$4)8)MYXZlfXBc{_5ztQ+H??sFsJ9sZhD#PbJ;fuBkSrMn%4(v>u1!?*H z8;ydj22+9^sLmr2yLjR@PCkG%h=b=VNA?_k^0xk?bVW;=M#?Haqb!{P zk!-{;BtxsP>da>3=cFYgyVahY3>=F9QhtFB1Dm;uw%`P6UP4%kD&uP=h1Nhs68hR8 zMfk{uD4yQ44MJbnd7C!FYH6A{$}YW;6=Q)9e5E-s!oy31AK6i zVKXAVDfYfdxHZz%rIQ1CuOT%pDU_6C5rnM#h$TNC8j$Gq8VJLt7+PnCfF3wo0RvJ% zy@errsyzo8{i?avR#r4h7RxXps=XhxLU=drvFrN^cSd^V<%ipc!(~N92x0EoGc75Of>Q+)oPO;q zD)PE@?Cp*Gf5YJj$w|&nO8@;nIk967NfjAKot@TMf?%2Vzar%zY&bSk2?=fnZPrLE z`=79MltX;pd>a-Vd2q&zdl%m{?cpbB0!uo!tN0&qc67yj0+S~8Ro_WDO8Bmp z;#`n>{dgO@aR+z{Gy$}rDgx*Q9772b4&;p{>f0#D8?EvUuD**e3%lhLGQ1721HgYt zczqBQp!$n;hiF;=qeO9OGHL*6+mQ}m9<@rOiZshg0LcV=Qo|E<^^YBTtq;2~+RgDO~P66uEUfmXG37(xe5@a3TsR91ZgV<}3 z2v~}^F*;JWaQNue|aDr@nCYuAOU(E0PE~Zn=C~LpJg31g|lfVcBTyM;yjv zImZ%F!Ap>B)gT|2YV_NATyti`0Sx#cP~S`$U_mAyFZV%6+I$U&ad4T3dym@?drcx8 zS9Am&>keE_qR88ZrEwi7&V_tjy~P8ovymdedE7VHQh?MpEmI%4X=O%0A(&`?Ok0aZ|4sO~h5=8QP1pG27X!QsN4_?!q^PQq| z0rEYP-@it66M=&GNRplJ(#%3r3X@Nirj|c1oYg^O2Q#|ZR#+aIT`;JwCY!%sb_>1N z^)9biwjq?4*@^!O!HguV1qBB|!6rnx=SN&NhubXck!vD&yf)nes1FGwjC_MnN-5`{ zmCcsLvJckwm=3Kg^UInu_jhJR!Glwfg>dEH3w-78R;0W+)mQlP5R8`{2krFLkH#U1 zEF)wW!6uBH2BT1{Wi)`tV^k_D&E=phMcVNB! z&}K^`e&BMYW~66i=v`L5H8YfvVwWUmP~q@7t?a-^Kh_eaW7PcfpIW_JSS2 zBl`>Fjcg3mz#5`Iwmc@-UKU-YKvdE75DMYh03Vqp<{>L#E=KOc^!LU$pTLe=ruzk! zseIuf?Yr;r?=nZJ!y$^X@6w&RU-+Gce{`o_pLnNqoZs1AX#Rbh33tAO*sLzN6Sk9~ zYQMi%`yDI|22G}Ti}ynHO5-hdV;NeDFQ~n=mIC9`7{Bu!+&P6>WV1&mw#c$ev$I{U z_+sU#9Vd{Z|}+$SXu<@OOmL?Ae57=h#&6h*3-P=?_HQJ;D*Bsn}d&3+}#G) z?{tVPwIgc{5XCy+mjnNrVi04|haf7heaQ{c)yjLioh?FB4Zei-5GxF@?mePj%#XKE zK0`fLgFfeyCjYy8>~q3l#^>;Gff~8>3RWXEilu)f2N;&H2#EkgHK$7GiB*Ehh@+12 z5LCi$HN>H8e{UYrjtID<2P4rOw1TjbvG(^)QyUX=Fy4&wI68@pfIv**=U-;~BF z%96`bZhvZO`st@;ev{c)a2bf$qK4vQC~#-Y;M=CRWLW{-5MB6U}qt6M-< zG&9=TqA##3s{vM zM8$}tMavK%(K3`sj`ZpfP}xK@10sX4wvq4$lmr14G-NaI;Q;(gqXVinfY>y@0!jTb z0~{8D+oOquxTLHu47>~FDE5F6XCYe#X;ZFxfMAtNUnn(Y+t@ow_=h5P(>0XbjOaRzpYuPTw3_K+-1X(hbj6VKZMhYv3A8< zCg8Bvuf)=&2$4vJPp3nH6AKat)9fg{C>veIx<;SNrBC)Cv6t8mRWVa7LJ6WenP6x{ z*w*BICc`g&QOEI%hUp6FS1SKhJ}OhbEkk(wNtU&8dj|7oY+cR5(sAW$<$_YncA$)# zpM9Z(o_IhqHeX!!DEk8a!wTu$;6jBQ_3UbBv4Kv|LflsS zP|G=a4?o==;VoR*S3BFZ@VRm=f(Vun@U?dEV7|D32qzC0QArGjmMBi2Jy|BeFYn>gKmTj? z4XZfam_Rxz~;C^j+=9!;aM}TkoS;vNk(UsRXO;FyQZT`XR ztQ+|(#)28cjAy{cR6zJ5S?TF!eO{h~C1QTgtI#7!lxY{=(gaFMf0o6Z4Yb(;YjI4@qXpC&h3G3)qR7nHvn+DWNcvFl^cpG6z_1Bem5ZU zJw1LJ(Ed~-Yi`Up4l+@o>X(m(WR?8Q|J;AF7 zNAm1Gx6dLF-X#RBtf0jbvIK*^j0~eOm)`6KLTQ#t>UEGV~cj zJV7Nd+to?Pf!>YCCLhXF`Ml{O)=c{8KIL$~L4(F2j05FPQy(f*{w)nZs9ao>H(-3P zjZfyR*n7>I;>-e19lP@=+t_R{f41{k97$gOaLgeM25$sZv{rtnDFOnH>Kw(IM>l?XyekamH z{0Q^+R5hBI1X6DU07zl|@r|jTXNl4^bZ6LNP~DA;Ch|()FP~F>Rn9Rh_#KYh=;yO0 z>y%1);+!edOza)wM9Hd5R%Wp^DAn>9yH}amTz>l8cW2~9$1Z$zie`vT2XGCW5Q04d zZCI^#o5O^FFq1}Uoh1lio0P$DfuRnV*PZ09ZcOr%pGBQk z*D5J|j97MH6<~}wZZVIfd(7nXh)M!LUqjsyieN&KQv_)k5at9VIyC@;crSGoeFa<} z=*sO1IUzEK^sLLj`Wa`AW1U94u}(RMS$*`&$5F$j5LIKADle@|*pD6H^)JoI%`GSh z%X$>1wCa-(u!|yR9aCWi2^AI=OF^I})PT-xxd5Xw*-U_u))=ZZPY7u8Fm3jb10FPc1U$r+Hf|0h5b8|;MvgG9A#}D`MOW6Zo`R=ae8#g__y7>Bg zH$JItaq}98~kB`g8M;?9-QOS*K z*xKargfS%y;?{Zl^emWPvGNJPi61$=T|R!M;$-+_Fnz<*V(;errCAHdosPa&2Kh`B z=3xC-g5SH~{R9FrrajY7n2{NFU=P}z<`gN|nu!tD?P2~uC*NeqSxcH!M%XP}vavGq;iuwsfvopTH zkXNv+Mll=9+V%X1=O^5GbLrSc&pv^5eRSvzSk`kWztVm1H@)}2RWrIvTKF%MR=xkv z>$3~J?M`d5qf@>PJSLgyD_Bi|fZYq2O(7L|4=GmE#RMaC$Sy5lL)+_dCK%r?Fo>!# zC?P0_SS;*p4w40`ls7GIdRA#xJ{NBlyDMMrXg+uA>|1W@+P8H5J?!KoU)+w|T%*|Y zv)9+J-SGIs(_b34f##|Jd`SRJxiMGCV0;EU5J#PMyGO7)?NyD=Hf)e9e;QxrTLtUb zh99DuRLCdJ9MEm>jLBBs6!9Sx%4+p^Q0)=e zg0e#ZxUit{-8kWDE2GNy9KjwuC{KlS0x2GWa7LXjT@N&%EI%-|(nCI@ zE(xXQQ|wlkwYm`^y(1k+eAQ|}gcvS3RdL`WNSto+Tai);21sW}07fFn!!dJto`k<8 z?U4ClQ@XsBTGhRz)0NZa{k78s%=oM9!ac#N&Yip7EKe=FY3`@&Y*er0 zM9OXFG8R9{s-i2TS?s#19-i|VL=}oxUj>Cch^VQr9g~aGq&U8nX{OZ_5ju&%fkhOYtPF{KBXPVQbyFjc z&5txiQQmd?+5&TjHMjorOvebznRml=!)jTuwqf+xc`PSVa?U$(;1JkW$@>A&g z(G6Q}xrgN`Cl=3q?rBsT(XUsOHK_RhF-{aK*Mku;q3XfHB;^;JEToI8Nf>0oRW)I{ zhik&Zq&)QwHRyou;O7!)({wJ8w%(g->+wu9wFT0)Rb9FP<}&Eo@!TXnhg=(9iSNVq zj!Y4LM?A}!>}?{q8NjMbQ3>4FPyN)eDLCgkrds4ss#?9OFEVMgD|`HlUfqh(&rN%`S}*X}xc zf+QvyR|9!F+4X!}vxP-!41*eHjZu*eGYl(TDoM;bt2-D>hpypvr%CY0OOnG6;NM2S z?0`MU(bg=TATe{R0y&%LjG#TMl{e&&fT(_zmn+q5{-;%(6J2CGxaV&_Pda=%Dsw%$ zoz?yKUp}2O{i+A$gKunBw(mm?%lt4EvHXHvwX3pYb51vmL95aQsRR*a_#2Dg#y>-VMWiDj0)7)TsJamqXqER7=uH$nIxlIhKnIq`IEB> z42c3n5)`1;^F%vx8rrYONd@J@Som z{f*;pgg==q$9yMI?f0J znI^f_4M0;2S3rYu4An0y#AGBF4QKEHG}X#G&`a1%LsQtshSs{&T*oAObrQMa6(dk~?snuMcaCmQh6C(s^@JxL zd347hB1ol@{A10aKrE&@gRLGn?QeM8L_P5w^wf;mfkzIKsE2a3P+Ly6$vA1PFp}Hg zIr3RiPr+o%bLlY{(5hPoCvA1o2xWAjwV5=mIcJ?*SSVAsl}e!uVf!JM`KD!?3Z#a& zlw-|Plw;z-%oW#&U6Iw8g_Ny9O|{Vm!j0FDKBWkUrR`de<32sCCw>g~qsK1fZsnVR zKPe%w!Ucpfqs46Yh=}uaxlz^@HBUegc8kkxkQtmxRC$x@aU{m5Jtq4Zmuh&I`E{@d zobl)`{vUfI8WkVx;V1C-2^K-tj}b+g1IlOkw?n)L@WO7W&qn`xM~&jCXbSy9KZ!FQ z2k%CnUL?mar=*ZY!EG?)hw`KV)Cjm#0_N=O^t#4uK;PG?1&6t$4^vSL$v`CqjeC&| z72sg10X39~GYN<`iFQ*c`FU`$0M=ylyMH@)93^xFhU4=6>_>qD3FP zxp*E+`rG#`O}=jFuAtt#^O5(y9mM3Kvg6lJ_-VwrfsMBw8CLf$?HkbarE86VnA-E_i;=odbZI243DAJ7Tl6vuJpt_xL8>1r? ztX;InYscl`s9XB_Qs!$~r_rhIQ@)S4Yx`KsdyMCMQGc#Of6R!sNCLt=D8Xt*?RD8= zfX_`f>e^P_15ILivA&wz8sf{!7gl$jvMzd#*rI4A!O$tbgm^feKb&KDP+cV` zx!tIf4CFAg*9~W(TQb6XXY?>^T5Z?HRiGHdxcpclAEL7QvO{Fe9~>Miwg1ke8uwV^ z^EO^h^?vFr_VYA;{*p`)_f4wzb5t=s=#b{QjbD&<6Y)>Xs)ur+L~tl1M>ug#8K49C zfbH%D__fZ1{7f9S@k*0?hsTGlDnNV>(e|-Z;WS?Nmy*!R0PxpE>2~Fc_aB)zWyHc^ z@)GXl~G`uKT}~V@>a?Ed4_Cx)@K#%)o1?16g2Z ziXwjSMa%~(Z+LmhO&vq=O-=$N%qJes{Kz0VUdvlB4(rTBdB>$1^|<14i89={7f*5^7PLns9W`@M*2Cm7==FG_(=JkU zkJW^;$>cWB*+>&fjJ}K^qD$RWq_z;j^PQeBqfC7=ruDZh_2ClaUO3Mqt+RWn1}6`# zs*2&}qr52K*~4iLq;(;H!of(#F`1C^2=NF}A#IAGYuqtTel!8Z7`a4;;U@|~D35*w zNA_@KnYdvtKQN2wsC;oSi9aNdw+cSsXV^RX#h4W{);vI3CoI$!pVu3t1VI@k=y>>t zLG~j)1*dmRO5-E|#vMNe<5Q#cDX~X1UGh5RD74KPtYRz@7s{jcLmq!{$(BCy@?&aoh3nsed)4|owJkYbnRWItBP>PH9%koWXf zpzK*aJjMhd(3>HK!uSqu1F*q|8^4kBLve zuGHm3uk{A6e-tp;Dj#F*!+%j;y7P|i21ohUu}8jAK5Y@;8Tec*IkCTDa-;7r;*;zy z_E33pzH-4);vM|x+@T|)XOth5kJ$9vSRo6S4k1ed_8X5PZzJhF?D^5@agqqr7k1qyN&k6H$43} zdGw0tir!t7ivvX6xKBINnSq{58_@GM5p+~qN6TSQXBHGpxrr`mgHog%kw>3uUX1UE zLYgvNSHi#T!S2q{(cv!&ZqaSQQQ$)vBh+{$v#-GtcI$8;z$#5+)=mSwi7i}Azvf3m zjtij)h$Z7^5xhC1SWBZ$1+S_@jMllRQ#m*Ky1yh#{tcgrt9L8gABjH9mMPQ487pv9 zWjEiYN&p<=L(efjaP)#RH=~~}Xwi9kgpWCZPsPh%24`iZ@P|6*^%A5dBKL0~hCWp63FaeRDfq zr|^6hGlih1|6dev~ z(uFb4Hj?=*R7py&hXd3unXR(TVX)GqwkA%ik_TxeE-x&=n7vLA`CRNkK$O{Z<%Bn? zD31VEpsGswL2@>&XRqISq8SwpiHq3c$N{}5zMdONItWEWI3eAK?k=W(-{>LKBH zL$DyTno)7UU@`099TbefM2K~WgpyW)UlR#pYYMub#|A6?*ncY}0DgC?e#}7O*=E%%+jEy3hDXiLvv_XI$ho=nbfQmYbJ{Rp6m2Jw#7PA5y+>RusN- z;$UHkNBNR%cr(4s6v}D;0$V5D)Z?Qmij`fQcA#(bLs+D6-Mjr)E}X_l{o?#^3wmV{ z$|6BbIig1y`SPs1S{E}*76)p1YQ)e+{^hb5^+9{Fqii!P!AuM%z60aQR?xv=r3{U0 z`y6PQI7^0N_0{LD!bdzt6Sd|{fG0H?WR%lIEgSy4__WihtUUwhY#+d-kM^6^Q=MG3 zZHjb2ok+AjjB61%r#LF3UZ~>FDhAK*&YzW!O7|47DVX#|QE$M;G{o3vECo!HbvY9a zmCN0gM=+#ioRLa%PGKYho`y@-n%Ev$bsvHkcHT7gx zd@jmzJZxKY%F-9y;yTx^#dp8tiH>z|r*%Rm0ad)i=wQ~Qb;7wZ7IXIp8kmFh6dXW4 zDIDJ`Z4E^5HYex{^4_PFbItXD!g-yQenv-uJeo=!<0*6T)OC1@n=~*;yGTC+dw?>E zL^`|K;6`;ynyudpyA&lyY8PIbD#o@f9`RTm5#pqsSHAo%C~^EF`I+ns5aXWC9bSE& zty8JbKzq?bo?@t7AbFSyWnw#e(P5Ms2$48|rdGC&O4GlH2gF{6&~NiGrd!p2>X7)b zaOz_A3{>|})4rg2k&@>kEf(>@c7&)|e>aJLqJ1UKBt6<=2yIZ#{&ueQ(d!cClsbS4 zhN|v0j*rwsx)){@m3mRvT?Z=%bJjGXDxbxII-C}V(N)uEq%kL2rV==xy5Gw(A*0do z%VWZgxbip?e^oru@07K2`S=O{_!#n)GI+yAWi2*LRP1$ya#54K^hM~28LR9^gm?&= zmeGq+yh(sDKmlW~PjJ+bx!-4U7}2v>U;aSpifO^r86*m!H?hv>=>5^1~tTQ2BUZ(17Jz&T_)~Z=!7~!$;}YCfIFd=E@ga)bgkI&7Y>Qo2{&r`9y%E)ZlCQ(AaN%{7| zr^>IX2WgQGr!m(*&$3`NXUt90$J{Vu`WQfMo>e}$c$$t9W#~W8DhHKco_+4QXP;L2!O1UQVCj{5^~eM20pHh5S4rAsEBKfK>gE%b8j!oYojW4PVXI3SQO< zGBbMk?=j5wXjn7br%k&Y%dGjk7vI$6J~cO-9p+=7oyMg;dn_xPPU#=`9splTa=Ku2 zPC*cgBqiIyiR^aZM_X`GItB0lvI%GxsP+Y|tYOUkS%GjpajEjHatbcK5Mp;WPo6l_ z!JbjBwoe;B=&$1*^s+D@7TdARniIWlpLb~CyzKVh4$!0(o<*uBlnkuna*P1A+;J+_ z(%&toKzPgB;2wVfG9*8>hI@>Av^wqhP8~kO!eeg{&p}le==|+Ohbt`&2Lk|)fv{rA zbV1pKO$>=-Rqzn%E!6}Rkp>-73$igh=uYBs;a6w8OMljFHNtc^8$gz%c_~Kw+2?)|dBJ z<)^A_NpfcFj7dcML!OJ<1K~Q|lBVJPnM`SZ1aABv;rUE@_hHq+;BP6;1qe6)TIR7-hP=7ZhcI-jocP9l$>* zNep9>)g0C_hY_bPwhqw`kN7D|uv@AOEsG7##X^%xc zKW$?+8~cZC5RS$bd=)3L>1cyEL0KF{MC}RTm5fyH5frq-@8L_W zgkrtR-~eboBo{yxXkGcZl#fQ8j8KmDo1IZ-1t#i@*gNUCHbL=;YJC#byhIII)c&%H zsQjg~nE?Q)w2>n$)<<#-vY8s*>wsO7BW+Z6R4U(ADhC-Vqx&mat+Xz^ zxwrIs`j6@CDdpO9T6bu$(r)y`C(MiVuv<)euS<}8!0?oHhzN0jhCDFpBP_%ZdeD>k z!C(MxtKDm{TWlVy)onB4rE>_Bw2LmP*to5|Oz0h76B6fQo#wV7{7qr?EXSvHJ+D&h zzb_{sP6ue|OO?v$&Hz@aEiR`2cV>Y~x>_t2W&D(ZGQ)H5>(ntC)NRVW_;rlNH3nrd z*2x7pV>~-S%ZNM&RD*^BfPI*dqCe)*`8(dT9*>Vn$n}?wHd11H7LOfa}BHH>0 zVZH02=>GoF zp0H0~4fd1enfp$iZ*nz)7OL%AED}X}mXjdCYY(DIBAf*|5Jo+J^Z^g{zWi>+x)zmQ zcU@@_dv*JkXLhj0=Ux)GH6QyyDqM8=bvC#?-PxY)-nMna4mRSsm!jpeFn?b2rMdII z`ugmD*uk^^MK0rJQN4ER>$9KX+P~GmzWj#&6`e$?*aPvCfNSvT*@XGoODz3&1#uIL;9lOgR-+I_U(h!G z0In+FP}EZo`1|SassL<6g0vuohQ;^{zF2i+6NREK{ig3-r zLQSqXRhr^8eHoTcT-JQ-d!W}KWgfSqzvIMa$&5OVZUI>_q(BR9liTAJOb85gWSG-c zgO*w#mW%ORGmEKYklB$QQaNYMsPdf?3gKkN@HwC&maWK*vcVgjGaOAeQ_ESpWkdP$iPz=^qN- z?|uEPYw8#F8(hoAE05#fW4fvus(U|npl&;UzSJEW`c+zZ`0$&y&D>ryB~NL-*lyC5 z+h=Z@`2j?CL=!->JB|4_BATE;xGB;tGc}x-m!6uF3LwBj1hP8{5xC}XvIU=g#cz_eWO$Fh%X8P!>HT zItn8r?V*Cn9dfdxCPN$dXaea!&dTbyHJ-^->kdOvUiBfrNRS-iGr!hk-k_Ns}&>~d|r>LaaUA`cXg}NAF=G({qp-e$29DD z`{~yY{j_srdESW8uir54lh=;ypI@>+IhC#1_59YAJCv3gr(cow-e22O*_F2m>jdr3 za1OhaYK9WJ?&wI7)06CFC=d+mg&{N9o9p!!Ap*L6I8cxlzzgY67O+nVZfC}$pD_Xw z&G;~Acj6UWEgbP$Hl_yC4dY?hO;Cae{-6jkQouY3s8)${+hB7?CTcL53OU&k^o!EPa?oYB%M@ct za=%82Tu^RZGZHhM`(l@ZrKTDYwB^dM*^G!LD=saDWY2kjnG4;Eoeb(GB2zgb zVsOX08{Ci*Bq}IP3-%Ul8G}ol^Tdyf?mNF?)z6EY-!9oWbm7ZGs>hsIUi$Qi=Wh=$ zXSyf;*7CrEO7t0JZF$wiy9(CaA>Pk?<-KPqr_uK-TE5Y51$9wvVmMauJ0g7)eGxX_ zx&KCN84#?Q3*4<-tx?<+cOS(LqPyW7;dfu)chACKm)|{-->tUY=5Db&1nJA~?t{A@ z*Lw1#*7obvw%8LEp*DA8j=O@3kAWOa(mCv~DOqmBg$h{)ApB)p(%~1f$UdK=f1}SJ zCne@6#!Tnh=?mV=Pa>o((H`#PCQd|*$l$^|H!F2l@^cuBNgngO^2we9AFcT9uM-;r z+bbR)zIo%fKSt+|-;`;uFRz+8Kw5=l#>h7xAKA(())btn=)xQ$m47!^Fz-J)b(->D zGgc98bV2+A@SqS4V<-G05lX%p(E=7AKRBE`gw?HQM9U=Nw007#6p954F^DjB5!zi| zZWs0{8_jk#6^j!^U;a69WV0oEyUu*+{5JV@$5r=5J4r&`T{!O$P(V1+;AcP)g^L%K z1%x7V3@dP#VtP=F8Q>JsteLVodO~?iUawT@=l!vT}YK>vx!ad(tj` zek^)WH-+SP?Q<0B7q)UMF!)=7b^tjz3e$p?h1c9}>E z#Hw>KfOr(i(BMr(f|so|Da6Ec^VFk-pO2tNKcpj7EQCmuWgtcX`AJu~bMdyhU6&79 zy5pq>w#}Tk>46uT7mcXT9bDSEUq5luRYL}k?A*6XJpADPZFSe|TK({wTQ|R=e6_f5 zpSo_{1~B8IC4;+MF_7jKmO7~xwg5jU#eozHGb$CB15gC41~~l@R-+OM^_j~n1n94Y zlK}0Xc8)Js+*;Oc|E{USukJH#->XxHH|o6Ay_)1#-z-q_9+WS>vNvDJ1=ktDu0d_S z-jKnr$4-Bn8R&OQh2VUFrS58}-I0piY!%22D=s`FchLoL`i+bf*_ zZ=@$+fY=FHOe~pyu<=_qc(8JvC@(xX>a4PL5POQPSI#!PadPts799T8iOnamr{QZs z54(dR%!rXmMpqCEgfbc6T6!Il63j*e{Idp3u*&M`$#{H1chEW#21V!#$` zEXimvnj{fwGHC&7$PbON4g12QiE2m^EQ0{)kq0Z?Z&tdqw{Cv*{Q2|ZXVH-OnfTw) zbhcU_2_Pr2fM$3oA zo!DhYAqASbhEWMitI+eH*2%UYm7@t9GI{Xu?ef=z2Dxn^wV`wsceX4<8wogg0atCvrR8-eg)6jEFJVO&6Hps`l=lF6AgPe`_9;zo2t`Ko@z zcD)|0_%<&g`X~^~#m{gKTVO%V1VW+>-tD#OMHRshPq&Bw6PS;lL#W z63ZznDecgqw4{jbR@QIemL9V6+_7N(+`03VGH&UiXIaG>@dD0Hio}3i<<=SOP{?os zi8|5awVMnky_>;w0NX*jlu4vW)DQm3`K;OvRdiQ5SlEXxUrszBRNko)<1~mD=ABdS zVt1XHr>xMM${q8?&mVhiwb(0qc*F29$x{MvfX*7kF5)4ag2^}qvteQL1_F{N2rx9G z9dNBuN-D%uU?PDi^+~>TD`r@YNF-)N+dj50=)L;4+8ek%HFgTVPHJ(MA&;;G4HazZ zLw|q$4k=6>l9Sf8LNmC1QW?Gmh z;rE~T`%~9^Ja!)mNJO@TNDOVCy%mFTeY$!r}*%^Zk2P z^qthZf%a%utl)9X9ndc$NYE0HR0oN|0C7Z=(gj*Fni8!mG&y8n15fs`)vQ6O6W1zl zpoJZ~RzwTHd}y2}xeQ2H;Z>24NAHt-IZ|OxA+&U7y4h*&P>f*j%*_1!6k8|@$23m} zi_Lp0f1+if)#0WWS_ea{KsN;MN>Wg{g%hW3o*pnhm;lsq#u~9jOE>kY9oRek#$!*t z-2bZiTfJ9w>Dq14jk5}iI_2h;w$mM&GqLB`!gk#Uw4b%&f!lgb>d<)SgxjOjin??u z8q&T!d%8HSpw#CnElexMx)p-5jzPM{`HPsIK(fw-2ntxo!r7LzG!R$7n_>LpMFWXz zE2c%&g!$reLo~{rsNh-XuXyaj*8?g_${x7iXzYLI?f30`bi*EHOL_0kT`Q~l%4JHk zV~>Bv!ZD97T(bFCxPPz8UOfx@3`2h!l)DUjb?0yjSkRvUH0TV--FeVPi-9m%2^7Pg zutE1n9OKo(WZ@R!4q*wiL>5Q7b<{Z=y}FkO*7}AUX3V(mx+zl@+&+H%?7L@Ao?Lx* z^@zI{FCNh#Sp)qFa?D=>btSM7w&z?Md;K0d~M_ES>8M5e> zQKJlQx3wrOh!U?>zb(5Yue5LX{yp-074}9PT<=~zx|f#NjI4cXlGVUEcgobua+mTD z33+NHHEn)+&yOg+m#y5ySQv_T`k5Es~)|2LudQ@L-h$X>;->5{DK_nkduW({B<9=z2L_$3M;N&ev53 zQwdqub0`ua7Qn9$hdnW?8qoJ?!-i2Ws+?E~n)m7(Sn->>4_L>kzX{Xd)Y;#f8Xdq~ zO`kKn@)NVmFHgl!(>~^G?l>J)!I<+_=DM_LI)3yDKKSe6`STYqo`2`P%FM<1VV`fA zI-^7Tt{tb2J~Fp=hwOI6U295mMzYbJQVWB_=S`GfXC0^S-8)_R$KKyWR=jWO)P2fP zdV*e=KK;@rC^8~*T*U)2{i=EVWYi|HQXi)YVHsfTK5Czr__#y@F93hi;MHda?e0Hx-N>FjN~#;W zru47sJ)pWzbw9ngd3f_x(sND4rM*gq-Z^6N>dx)955A(fd|*Z288uy%vpuT^^oR_o zRwHx7(-e83)$^+*fS5Ls7n%Il0aDsL$t zoIGhwNp07$cEzfZ;~m$JTDDyLkMi#N&)@!$rM7=W`s}$qox9w;;OoL7fIzK%W@Gup z!gi@?JBN=R(es}E0|$NeYeq=C<>&)Xy`h{`P7;C|esp@>Taa0*B3a1h5de)zAkzVu zW&BQ$2YF3iq}3YDI&)p4jAp)|HIIqWT6J}j| zW$*UE{PN^JJ1dm;l^`1|HQf8lw%#eHtc7{kDQh2$9uteD#aOE{)CZ#sA1|^qrbNok zNzOo0Ala8}l)~Z6Od|k(jBWriw6mdPRw$&iB{?lN1e)0(kmjc8ki{hEVh}D^7T#lZ zfnr)uD;;a>iVuc|V$yK|8xzzY;30)T%%apOFBCgBz=Swe>#EKUGY>uY>8YN|rLFpJ z6{Y8?vPko~9;3!L)Uu@7hVi4kAAZQ}&D)OxHtFd0X5}Z*`P|0`x2;?@bMcZTi)TIz z>3tW(qK^zzK^l0>(EDbyw^#$waJ)*@Itcr{iOPk++8yVxT(~1%K|zRa;#dY83mp}( zu4ZZ$?(pa)xoc~6YFx(`TUwNxVd?II%sY-jj{8SNf5QjRqoSL{dPvda<3;2L+`9zs z??Cxij_c2*N3J!zA3I%D`t&Cv`-}CzL-tozO}VW21hB{C32?F>2hr!?t;p}z9|xE9K)Ot)s)iOfGClPf4x5cq($d{X2?0OrlPsZxT`Yq!`2%hZ0@*S6>@+Ei|0cQ1DTLH$$jm@Rd5EM=4i}c`f})^jy07Di z9R6*(0w<0^T*=eGe%P2=om5Y<|?;GiUa1bVSTfDY-RJ_xU?hI^!AqV6?FoR#X8`-Q9%FV4{MUIrK9-P>zxhY;~?s~)wqk8;O zX57ZytYg1^ML+oOd17+%ywzHHxoAG<78RfjR1r26E6^oEXjAEW0K6U{jV0uc|xg!^!U@qR)qki(e*S6un&cMSM8rGW`!|AbA=po~5hC#N9dx!ZMj>i_ z9^T=2)frN-)qaLr$51BiDsXpvapv3avXbGW7u?KB`qyKIGpD@#;JSzEhJW;qcp^HJ zFh526EdTOb{A)Lj^EDr7X=(P$CzPw8r6Dry63$ax`G#l^48Zn~SUH2p_D-jW7) z3o4H_!D274<`eQ;$~yf9>;mu0I@D#dxI}2q2j9o!a)YwhUp7E~{5f`ow|GwJawyE3nCIo6g%+hAKHN^KfDtUoePh5ewC+td#Hi z<`Ww?HVoaUe7$mI|9X{|0(FWif#q{f*{9`pHTKRMizNiN1!e`|H&N0QMkq9>cf>2H zQf_QQ#c`p}bHr=Kc)hK4ly67em}kN1g+5l!i&Y$IoTT6e#_rHrN`*0zlC)HqRh_9) zVPSs0zhg(Uxf4IQ*y~ z1jN#1z=@6Q3t5fMZd2#85xaUA$6v!bz55U4+yO@=XCQ=^D12WhoCw z|NTCjrz`{?!4I<6C<8267zAV;w_m4Abug${X2i6^wg=${Ne9UQ)j{61(Iyy?$sfb8 zLhp)U-G`T-q8Z4DLh>H|(>8!F4hjSt3xoa_dp$K=>Rb2Tv)psfIrp3#i*WgH9KIB8KaZk$ z(k+-&Gank8sSE|P-4$b~&>FJWfb30ErI8g)G0&smjDIpp1bJwuwXM(i!`2ITUpiy| zBAoQUH}_3C=6|?WTq!C(eQ(Ox9it!ogHN6!FM8@vRh673twr=SkNM|_ZqrW&yFK;* zut6tj3URuDGX2+OyNj}r#0*i1$o&h0w#`^clxp1BNRM;Bu9uZ#=SIj)J<1RndK0h^|5J} zEm-&XuYAY8HBQxh__x}ML%rwE`{?SchJSOmNz;d6BTPr$kh2rzDl`x$jNuuXiVODf zbPv2gDC08}CxPrPIDw4pV9bLZ4~de*>Do1de~1g`2`^W`g91u@&}P|sXo~*rw72v_ za-CQzhfgjPU9b11Q?4@3SN8l*{go-A_3Rkwn8agr%7^SG@S0^v=}v2!LqYu(8%YK) zjE+e3=d|L)zSHK$86SmDktTa&vKGq*mIYBz1WzN(0d%;BdWD}LWT7&-ML$0LE);e+ zj9~6}vDa~njPmBfJeoK9pH8333x{tQJ%M_LwE_E^=dpt2N|zTiNEjB6wI4{^-67t;8OM0Yff)q^P3&|S8pTrtZPvMc_2Ydv z>wkG!KZt;Bhgkcxn8U~_|8i2cUmVaI`F}ouY#c_G*Z;XcTp-xZW0e^I>uD}Dzv~ix zF_zo{R0)uLdFgIGW&G4pK^714EM-)L7FN8P9R$wcDs6h-{cDB#sxA=#)=27hz z#g_^DaPJ5*T*KT&nB!rX>H0A$lIZkfjE)DH450uj=@MQfFXGYIUWJUS-csaOrNiCO z+!f(14Xx|8r*$VN_nl*Y&|UoF4dPSOGQ^2GtMAbJ_9!Yr(?!Zp7t>hGREw}m}$}dzcuD~sc&J` zvT^$RmYDut>*DImbbVspSz-NnQ;+P4V#W@Ay%@Xf*Ck^1%$fSyl3y>?H;drVzUg{z zu}AISqQ5IY_91pC#Fw*y% zF|q(uvT&{_uSCHZXPL8XNUK~}h-ZEINI*NZH4UpxTAIBC=d+v$>POK}DkDQ&%i=n@ zM0TbCfuxQG3Bc;b7ad7~uJOaa2tZDHu_ZMa`IksS$iwfdjUsg?SX%Cj3f} z{nz-(p|!0u*56p<9^3TPx7!bXb!yMHWY)pAUi{U0PcNEu?V+Z7T1HQ`eW%^!Twk{9 z>KmUy0>Y=)?mwypLu0Jg&?iuREZc5-bc5Y8bxtZBVbc(8(Y5(i_e^Q2$2LnU#{8CB zr{K)x)b>P`&_v?2K=Jy=OIenFcTB25W(X^J{i9~jF_0Zlu`t?Ar|HfEj zY*1@sqj%uIeiFHv2e(RzbL{=xMHK^Di}Jj|yaBDHrNN-L9#uQcMZSDyH?lv~MAiUakteA^4+TUMt;o#QuhqZM1RgpF-*8j;XpLpWaudllf8DHil6TSGukn zG3p}g6!*G}xn(z9c)`*FN&&NFdoUKOrrFnW9Cxq(-9w2!NCsnOipeQeFS#H;w0_!< zIA`O3=IlA%p9Z<#E>*=Mcd}Lw4hiaH_RQW)zVy^N5c?rd_-E?Jy zF?CWASu<}pT1oJZcBt~v!CrN-I2S)t+nOJI!P}POdwSb_&*sY?~8GP`!AxCR2rJh5fUu5Vk$ib27oE#XcP~iw>Di~3c z=h=VWQ?M7<3O!93s1VoIv9FyhQ!r4qeRScxOud(D&XmdXT;k=-*`2LYHzH}bbQ%81 z8|KfOH=igT|E!zYp5BLIL{!zD3Fi)SSh`$b_eBu1ihLJ*_eO^{?#&A=ru zFUBUHm0Bt->+OZgqaZzN-}*!~EP#(er|l|AYy4W%*7*1Ci@8^pLzZc<^`WX7%D`CC1nO>NW+EC)LWF`>Lyb2lDi}Cj2(Cq! zj8ng7>=b3J;r+MSAKI~?lf4f{;FYRf8XYq0{2|RX!IG#SM*jWSc;Ecsu(?-?F*na_ zDEP`-8$Wprw8*nW))@I}vc@QvTZ6F1(0R%b8*Gy2DG#xaXNB>MHdonyj zTQl+THr| zc{?A~220)&1NC5^?|;)WG~Vaj#buthKkGY@x9WNQDKP|z^!kaxCrdVMd-TEIJo>u_ zF?(x9%$q(=UUFTNpO(S2zl z@CwaHm!Hi@q_DgkGZKNQZK#7~x6U1aT{n=`VMb6b?EmbHbZ`Swq0M&IvuqGU-_A?7 zWfZ+7nt4u!4(pnrIXTfiWe2u)FcpI#X+{PwI&DTmrb+nWjuvC^CTY!!PF-v3YHNVD zTZPO%)!y>r++YUkRbbmwS}IA^h@cLY2Qz|5H1Ecd*Wz3|iicViM7{Tp?&qbuci#SX z%MKF)u_sn+7A00fK1vi&9z3iKS=l(V%P|pjU7@)v>2r&%D>RqCmCwJtQ2!9S`Fc^| z?%%Vq*&~WY!--`#ugN;QOWoPoB3u7DIBi-;KMH~Pl73Cqf&~>wJv9JCu{6*lQrkD6 zU#CC+>aoh|qN3_SuwmUibnsxLCZN22Ypov34vew}nU-snBCjha%~nxSUCr73>av{9 z+F(Vs3(ichmT^0{mY>J-w}j>n0lHReD&h@$q9q5vV$c_7F&33(aJ@>tyn{-A-f zc^A7?dcbD&eEVryb5qxWY40EV`={PHGyNa5om_FBw`BJW4G>2K~ee9*P^_1#E3Hey)X4+y@EBR(c&kry5^z6@L3H_eT>!0(bI7gYLyO@ zTBVJN;X{V?>@jj!BHG+MY*?0BSl|x9;uDfVppS|FLZMV#K@A%d9NN#;i`p({SF77sO(aIKGfAX4GqO!KK zWnjxlHu8phC5^lTM+|OB8hLw#*~oib|8CwzQ|AcJk01V^^m(}{lo9RTF!{2kKwUt8 za>9-FQJLL}ydHO6L1Q-@k7v)4ZI68fcIgS6A={J~(Z9JdHnh2>PoL&yr9911Dbr>m8~28Mg9r+~jqjm<62eV5}Kv`DKJ9@nt3BIqc_NM92>KG^01NO4ls<4{qCzIFSvt5!Ytgcy}sc&LZ|H#nn? z=zp3w&-OJTCDuK1_S9Y#gq7_R*VslmyB9N7V%=H|NeKUhy)XO|3F($Zb74X69^GSc z6nG&|MfUQ{TkRU}2 zD*j`g?0@dgQ2cN!m7D)J{-=EL?Bm17h^E$YaBi#|5s%#6a8|?Jk@)cco(JIQ7$jEd z*N$XIhdj4++jRWf#xu)459=n_qN=4;i9Y#hd1@$7SyWn9R$1wn3*bzL6C_{F%Y)uZ zrcS>=TKHNxL28OZp+I>tj+6xg)qYjDw7fjS8-iJZRf1*^^Tal$4m3<62>+9wX!=E1 zGcl(VTO9}>SVCD(Ya%~Mk&-Ob#-5T+Gbc9c)8IF$bi(ET&>GQuzuo8cSkq=s60z6b z*FRdhP7aQUH>_{q|A%A!y>{;9`Av`z3)^nb?$x`y|1NQZ2oQjqrg0A=vz=alY=B8F>(TN;S+-^ zWj|tMDOH>@7Tf&msOHIsUrrtO%-B7L#eLnLY|#(+k`+(Lh_C4%x<#c2^vLSb}{P{NIWkQA`=)NRW_?+g?`w^h^oqY_D2F5-R86?M^gipjsOGG8b zRxDa}t^StVi#6R&8HrF&?6<$&u&uHUenP}#pZW=Przu;tXQy5B`7Zb(-4l=DCCxvi{^E^cuwz~={5C5=M1|3X}5Jl zWnG|Y;e`#|V>w0fJ(3UyEqjnHV+{656$zJ9fi>FU@dCi?heGLZ7|dXdU?0sLMVw_K z7zBNxl*vu<+<`3!1L@yz)zjzO#&m1U&qE%fH%m=Hz-buJ@Md_ zBVtc*b}k%!gP6;lBYwl_i?AZ^T;7F3O=$VFvaC(-UgFiXy!=LzwGP;ob|Xr3EjpYB zy|YQ`k9F_@?8w(A1`UtZHrLkXTr{g&QJ`-iFi~;mr03+!nmB6Ks5x_|OdLIP`gxNk zO+Tkk_hIp~&+av3$XI(_WpOk=6e{b|#W!~B^yzjjJHuyD`BdiXk#Lk04t6WRdadCv z>{jST^4gHIbQ7co+!N;a@kvMgO8w3Am~G;!yvYllF7-zfrntjj6xQ*-@mc4uDPK&O zZy#puadu0@Iyimr_yxA)AJ!@IBlvT;wMTz^HpDvh#HXG9w0z#_&(l7&KAikCigthc zQ}Qov$+~vxgxcCr_~m~cn>L; z`T2qS`W#ttVr<`+h8Exhm@QFb4huI1810!MbzOa%RrHc42vdtJ?X*HyrOKQoXKA! z2a&M@D`3=&kU<^?Q`_T(k*tp_~}mHbiVSYogfKCJ)LSN8}2u@cLX^3(ntYQVB+f^SdP|28M#M zE(?MOP&PK*Mgy~BLseRWs+I{QGu@)O-2QZAvrYG>m75kA^0sx&qj4J9NX{_6-%~iA znb6r79Vc~Wp&m#L&rI?xYHrp4x;mNaIpqKQr@uKcT@~)M*7?(?IAj-cGY;VF&nH(< zYS&~2Xz}3-za4bv^_R3G>AKNGKVZ zSly*e3x3kwN;(#KM8@&rYN+PCpEf-FB&V3PdDleI5y@x?%Iwgwh?1z$-$@lxTD@8{ z8C4Lh#rg)0lql8jqGDbsr6l7tCvt*vJV!2e{UKX6a`@&uEZNxzH*w|JHHk8%B2L1A z6Kay=l3fUtaQWe*PR3qAp#EaCgqLE`@q_9WM$klgD&gG*L`WcnBbh&RgEE_=C9I9_ zzyGS zqH^kYV;v zX+<&W)Mt57;W1DaD9*{m0cD(0%Y^qI=PZi{wj!e}v@(nfIvF$jFN_a^fvU{wHjU17 zs?Z3LUA3G`)lxDRV;jdKRv{;H=IJ}w- zeo;Zq$g_A5kIhCVu2}@Di9EY; zkp8-|uI;{AckC7ocdt2d_nb9@R;*m}z^8IH1vfR{hYyJ^JC_WaSEX_~7HO z?4zD<)K$(RUnsRE>avii#*1U~QZc*=UN2SIQC)ei=GMGCup`a`_*`B;&aSG>troZ- z48ve*1jKY8zZ9o24N~tbxw~Bai);y{$-($Bm@JQF^^y;6yZO?(#SND&)Av@_>u)Iy zx-@9;eJ5_{|D>+3j0$^B(Svu12Ahs_<;TBw-l(6XoxFsKKpxCFF~^)l6BZNH;!z-h zv;5dpQrYATr!xydE2ue{?E=BM{B9Ik^Fsd@9=|6en5wcyOAO?%A%kg96l`j08W<2? zwm(7WfTEy>Dj_BEYruOYWGt)9vHYc!&{_A#Jc8qvjx zm>ruepU0+9F=Ll23n7Eq7-SZx2WOpdR>O^894w|jm&@blWX66qxoFb1In`sVn;iy| zx=kaaLfU5-35~BqMG3!9^>2RNxu}G7eS296{cc(*JC>F}%5L~KCPD_Ho*ZIDpMcN8 zt}GYGn9f5KfFt2rk6+RY)l2MKvc8T7*Lla2mPNZJC)4 zC(hfzd1Q4t%qoaR8AKje$Dy*-z*tX7ZqP6dl)>UYP=9Avr+R7)LQNtA%8gkXkNN~H z#@Yy+P@j;MS#ilo{-mb6kq;7{Zv+@-B2ORoWGJtK-5HL@IQ%xo0>}u`+Q7mubPFe+ zJM_$~_z*(z-ql9U2L**K+CFceUHtW7+isRO@UM|<^-32e!s&LW4LkEpB(=+MrE6NI z1CO92n#*rPniLY&c|XQQVX{5W!hS1TAwbEgAHaBn%W0OhOswX9+Eh?PEcG=hR>)drc9{EY zbQDw!ot8R?5D9_O^5q%=k2Z>ei`MQ!elIGc@$BKX7wR9=3@#NtR(wIlG=%!Nn6kKS zzp-jqD>0uwX;LEWMAVnV;`Sl%l?uurcq$9G-04W}E~Cz*9RXHQIzSvAPr54OkcJWM zW-MIBJo03+BsAt0!Uf&NIM7kjo1*9;W$(a$G`r;%C~~V;FA+B;CsSW>Emk*cc-1Oh z|9qSHo@P>>F|qAO3s}X-5BwuEyDVu&B8p_w86KMhX>l@u^qe%G!vY~FAh7X?2la$A z+&(|@HA2&)UT3&i!=v4?A;6hNS!*ECO|rtclazZz7-qj|4Ys2|UWcBOve#YT>$a?f zBX*45AF*5;^%r3S+F)Jqo8P>qZ`ZftsBV7SDzW!seUoJyNp4Ut)oCQ2Iv3S((yS9VO4H-^Z7NRm(dqG%W*4zvxdqKY;=t%%}`0-k&(QZON z(Ds56fF&BAF~uN4S207V?ZoFdNCr}VX6nnpLS-2yWqP+j@`^l}DD8yFL1Au_?SD~mW8Ol4F*#>cHz~=KNk>-Sg3Zr}vRk2X&R#Wq z#mZ~9zVk`9$q3SQ>91SHE9LG-^taz6rPG%WrSqLFuk7=;ouny6=V?{YRogq5$s!s@ zp2uVJCcN3CfR-R@X))AKP0iPuTl4d?kzIa3YmUpC{WJaZv;qi8semc=bR|zFk$z_l zlvBwk86gf8)b`He5AI+Ubiwj_?zCa*Q3*+Tclcf3U)TT1Q_?C^1-)Z~j&dYatw%4m z+@!Y=pDsGJ&H59p%poZzElKn)aVn8WxH?=>p=B3TS7Rk^D$umXim+52uC9#)YlpT5 z-9A_cd=}KGQmm0kX>n#T(1P0TD)hYGukhgnQ+39vO;Ai~x7R*2`kb*uAWFQAEo>G? z%fo-#=@3kLiQ&g%t1$F!D`%l&=e+gc-;2}J~vHJ#2P6nD=W!Fl!hI7vQShc6I)>v7dOtCAg;}v zs!qgAYeVPBG9Ke+&op0UP^<-p(FXCgKQ7@rhWL_v75n zyVh;73|leu;U}JXsB81JSB*}PJ`Dd5SG*12j3w*Ca#z-q$zOAX^kiv(abIl2Z;IC( z1uqKa-D*PRFIiUcC2R^Z(vc#SN_6v*V5|tqZKYwz$E^HpC6K@3Mc{RP0W$C`Fyy}l zbw+i{eHun)eyTW?jyy(%P8d2 zS39y<^GXhqy?-30h5gJYSXWxa@W=CtGn^G=+eM2$6xn>f0y8_#xuwUBN#eL6Tk&%0 z2iCfYiTZS#OHM-#53D3ubp zd~}LL!HES6Ho7hxV!(k6h<|Jp{dAzxMzz6wnRY+z*D+J3=udVE3X|DcVi?E~b0I>K z404>BQ)h9&!G2IbBFaynz)$pl3Hv9Vrx5B1_Hp|$gQPED4kgT38gzUdPlpPHG-7VM zgGxtPak2u6o+Cq5+)!+=rAzMU%w8J8ExCDu{tUh*J|dm&=dfDPX~kQ$r{sgnc)TbJ4zvmsX>D=1R}=YFOgv zl0Gx?yBP%F#Tgeq6H=}yrKM4^QeP*=zWbgStKa?^c<`I2j((+Yw%n-7-Q{w9gP78G zMBl__>E-$gLlW32m!C@-jJ)xZ)sesvopc#n7EN|%2H`AJY_b9y8%$9WWCI=XAdz6~ zRVXev>1+liXmqxgi6FVUo4>_66prhzUo7Y0p!8*iih$y7^}1wpG7=gbq{A z+%Xyh-n6P&F9fCZr=o)TB;q8h@N^71Z7F;g7bT)dnv)GHO#qp5sx=C92$fVwWqCMM zRO!x2q+_2^oSv4Rqu7zNg7WgUQrM^=!eM8El>s4Y`#?49lWC_Kq9H>asf<)0yEUa8 zPzXCQ%Akzn9Z{}Ytl@1#(rn1b@k z0;or?_uea#^d^Tr>tHa?jEi>Q@fjy-zvvO)E_=_8_+kJO(JDT$Y=Fp-3o- zCrc?F)T)>zacQi1G)_`YP5)CzE@>aHXrj__Nab!gUXjQHLl2hlz%gzl=(3{*o@gl* zS?^)ZZ_Bmbv1;aXlUrWAUT@Ri^6I-n2XiOMl@qT_6MN)E@?!`V{rk7KUvq0s-B-aX zVLkT2q_g9VEnh8IJnu@vCgdVvvjS1E%Myulq%#j?!$=0KR^{X%4k;r$yG{iW*=s9; z!Q9GxZ{?8Isx()^g7e8a77fLbB(J3?zbqedBV|A>4-qv4PseS0;F7sSlS+XV4`?<_ zUkGadB?L#A1dwI7)I_!N{Ezy3d1uD(^F#%+|JPOe;pGOd9aSh^o_Pi|6AdJKrRh^_ z3zPVUG$wpw!li2x{fbLUDl2`W5H1^Eg&)WBQIy{23prriuvV3n=i}&6R(VcoQOGuB56&lmqgCK48i)vh1DF1GZ%_ z+<~HLtynF_w7q26C&ITUymUs&`zu_D7k9T))gzX^XdQT4IW22b=G}Q z6&%*(mV^X~>qcC4 zbGrq0>=XJ|cOdCqo`3f?@l(#v%aeA6to%uXp zR@n|O75TP_w^9ZGW8qDm;RQ>jy5f`Q!~#2$H!#=e+p^JGgs z6UDNk(Dp<^y$PqeJrUTRC_#b4*-7sF8A6>e{WwZ7D>*pRKQd9BBc&m2wPN)kz%S2}ftnR?10$7~JD4S> z$u=w~9tbgyd19S6v#eqmhV_p4!jcRH6Jo5rfCafgj0mwNZ#n3zT;G`HMa{d-Vyq20 zGB%s^^*+*d!_+&(vQ&RyVcQtgsdxanGK^ri9Sv6t-wF27z%ODSf;ptTTZsEeSF`i8 zy|85<$xBhYOe?gxvR&4E4_vdS3pCE^fljhd;7naNg&HN+FINJ=AWgFu;S9ZGh&EfP z8O!#OyQ${YclXycc=eCPrr#Gu(@HCApAZ{O2{*sj+n4B0aeU5e{ZGQVrI!!gH}KAD z=ZNhPc4yWItSd<)fX2ugfn;a|a;k#kDCCG5&-Fa};|ZJGghUj`5!JCCC0d|blH7tc zQyRtR8Wp)bb*_=x=+2dAxeaM1YJyTl;j=nclC;AoiyB?OVoe3#u<6L=XOp(@->9u& z>BIf3GW(fnXfCd#=3?ZsqPnBaMn93z4gEChOv=(GwCI6mOy_CA1&Dc3)xun;Ed?5) zb>LOCXZR^C74K;%=_9W}Q0WKvfA}Y*8R5(RLMXVJ%RO`!9qPOe2=dBUh z4~ntkTK#rJ5N**Pu+(I{eaC})(%bTOSPqOED4ge=taG^%pgvZCW}#xc=%<9^;#qdMNbIIQYDQC;;f03ciM5Ejgzc1( zB&$qnG>UEW@hW-jMVG63FZr?_!iOFDC#R(E_3!1+t#@93(KEBgytw!Bg>#lEkHKH~ zt^S4nhDiSoJB~o)tJ(_C5YHrGT>g-70gQiRV!R=RaUKO>T>cwjLz)TIvO^7NL(_yV zidGC=RGKNqa4WJ1rdlzyQM4jh8^tqj+@kZa!4&08#C#p*b`W>My{R+X>5*!u1<#aI zZ#aMpy?N7UrI*nPBxF}SF%xo$VkfI?xw(Q;Q)gn?&CkrU;qFkBz;Y^19G-Q0tqNP& zU}Q7>5bf@Wlup}WBLsUTTz(?Uf+`}VCCR`ja!a9x)r_{!l$Z43-=n_yb4W|p_WKD( zXFUASAKqH3jKvmLdR3pI{^gZFd^1egYa1`VblL?NqSO_(@==gPdC~~PdFJJzuT~l9 zmbd=s-m3M z-8rL|QMm$k&-G(RrNR%Rm;^;nhBnXd`YUoTfx4`)27C>!B zO#D`+@XKv5ez^^4CfXn>DNj)eGSyi>qgHSh%%GAz+=?RCq*@`GUB^;t1ocFki3&?Z zvtg4;{$Kt8IuVrhe>Q&rFr31Te3glty^I@+68<@Ec-q+T1bc09#&pPDq-A>dTE*s!Xb<_=8cFk&umP zs9BUFP}Rin45qQC!GW!&!(*d>6l29~xA}G4by!BWtv77x)}5!MldN5#N#5zqRW?DI z{j7E5;Q6`3u~X|Qw}G-ruQQC{)1$2?ALoKIjuvs(}km z>|y;3y`Ie6;E`g9JVf8w?MN*qc@?-&;4-&5Ft>g{6kq^Ms6m8F< zC;6a|^AaHtq9qVO7>(OqRU%2jtX#D`w|oeSr+QJML@A`+S#zPipkwSg!1_;4L7F^F zP7>t?uE~~>>?j+q*^R<+=)CDmb{!$!<8ksceSv6HhK(BAA{xH?`jXwjn#Y!X{;j;F z`QFtN#*LgTcK+8t<%Sc_^zAckzPL%R+w*2i&)$QMipMU#WYV-gU<1~AZTk`9SR&O@ z?#ZIG3PhM8QWXBPocd}-smlPTA)sVL;SQQ-9nr5rYugWjUD9LVaEy>D&LYmQW zrvm&SVZkqs1~f%orW^!xX29>m;3xrD6E-jgu8g6H+wNO6_0pl+hmF1B@O1}{9r}6; zBkAKKCvW}Ldiilm5mj0CPJLkG>KD4I!55Y=a`wJ)_f1o$y-g#@g@tATa8iu3c=aA7 zD+`IBGU(8)s+Q)LAc;|i;`Ml;@}u%(VIeZ<6!cZ!AIJp9l-heY-FA}588jTEmgwh|^bGa>}y>gQVPfQK@Q zrYj>fsPJInzrBl0T6MW z2_3LBLxACjhaG?D3Hu_8+ z(+{z36;q$JBFRMIQsFYN9DFpIqolDtMTvv`?b2PVVm}ioe z|5=Z@dj_c_MM@ACFz_A{cZi7GaxS`E_r>2n`%>0t!N$w6$!)nr8kp=?5A1(=6lGh) z4Ab7_JIIhiM0=DL78GRqQ9c><9*bPC(jx>1t1fgir^Skl{8n>TY4Pp2`=)bW#Au~d zA_c}8%KuQ3%>R%i4y93k4rvUZL#*(M--)3g3E#)FE`4dn3y0r*d;Mej8l`b5PR6Z6 zUW)0Th>=gt`l)NRe*DX$`onkG(M!@CjzL!BQZI9Ja-3dR3cPlEUIxO1v4rMQ!553_ zwjiOL#hl51(@W|kZ3T@!+Bio=W2t;6YHK{NQ?Y=vMeW~S89(@`<_GT){uQ_Bf05Ts zXnO*Bf(EaAmr-Aq2OoY?fA+GAh(@VO4e3)bJfm7JwgHH^BPz|-aE8%ClxcT*5K7ce zl}Y8rlvONvIXtX0AreL6NB(N?s4+uC!`Gi4{l*M?Owr%oHx9h0^yctK^dyX)3;f>0iWLo6V@3^u zBJuGT-^d8Fn)r!sF_nhBZ@l)3EYlW58Ut({O6m%pf-HL_`J~DU?e^-dva(R6*X{NW zg)h1osk;!4;bq6v=@!d&O~JJ8uwqY29WAPs_Sjcw!e)XGipwZ1si54Nje)?*8-BX~ zaiLtk>i2K1T=~xDOICk*bo17$McReCk*Di@edilb-~Y5_(!~#t>o@F^MduElHs;uj z3#VV$5Z1pQ_T}rhKJB&TK7+B4<*gEwR{;+o3fjROiTHVIK|uhuQY*a`a)k^pdj)ET z6eGIFodJhnhB>z>-MPa^AdYyBNzxnLrtB#G_Fgx}5Nu%t_L4TFG;g`}HX+UZaLhJj zANo=M?CM{?BgE0UpN<>x+ebfId5iq`+x^d3TwnFW(1$k7y1qbdICRsx+NyU3&gdJ5 zzU|iCHloaccnWC2uFrx6PC&;F5m#1;A zKs;fXM$xv>#-U^z$|7qi?|v28C=o$>R%%7JEl;+hEV5vyjNPvyhf-FA)7!biT5PtH zpWH>CdK>L@@6gT_G!Aa3OXqeRgHrujoa#@z#h3cC#dbW^pT(B_W;;DjYiDw*oh8;n zvp==T{_wcE+uf;lmZZkjr@b8=IN=H!m}4m@2BR|V2+Sno27Sl*FKUnX_KYW6iP0W# zJ@~{adeQ<#lAgq2^5m1aVO{C)rh2#38ZvvA+qrkP-KpL!wH!1@S>N8f)7rVx%onN1 zCBN9tm1e$3MQ%K;oiVBYEK9Z1Zuw+dLg^}#mXu|w{v=Lor+wD1O0{E{#*)<3an`R& zwPV^+=)^Y9`ZC0hWnkxunTL-K`*7G4WF*p4%rq5IWEhLYQ^ij#@tJK$XX@K!3o^mm z+VtBh9i`7_V=#A`8DfNxXYy#nrmqTDX4K&JE$F zoMr!ciK>_mA*>*s4*Jg}B!6QcbgvB@@;|H=_(K(n>tpMqEo?D&ktSNPJzw6HV{rHYO$8 z5F<`~d&V|0%{FYPO7rs;{$VG+=U#xPpJxh`g&{l$Q|Je31ry(MKk$r^X;hKRk{CY) zn#5?@+quHB+iWLA$*11u@wB&dg~<^e70CC4Q_0_?e&@6itN{i*K_zBh3pjN#EN=_A|g z;}F;Xop3hYas(C&;LH$_c#h+&81IO)BCIOp5$lL|I3(mAjQ78rPrybx|aJW=XIpbb=*gMvmWLz_4Xh|DnIaUqpd$vXDpMA> z0?MLu-?X9_Bu>pHa4PFd}~KW>L9%jnPIRDarS{zMUvGi4e5 zS)A%mG({0cJ49JVJ4;giiFF*8WgSzN(asVJ)_WdTyBC{r!jy$}B*+!QiLhg3AxXayA<+l%+<)EkLSqA4sZw zhVf&(DP6>915(Xs1K&Sz#x@|;jB$t&DE`o?1$_ino-I&*OOyCAdO`T&UI1U1GioD6HAXK8U)%Aa`s12+_QEnkcxtM>d zQ)jfm^AEzL82}zpAI|t5-$%M`+=pJkC&B_!4+AgMC%z9~8RKibao;w|xQ|suXMEv# z#>TtcLy?gjC41@^U-%|J@c@rfS=|wANA^807~v%Jvq<>(5(} z9T1@GgGKCzhkG+-ImFmxeO~?wy$~oGF64BOEz6fznq|)-r5`vi%4gF|YIi zz5ZM#>Pn}C+76v_sF<%T?=~EW`+JklXaGNrLMN+(4J7c5LF6Mb=HOW zPaF2HQMBGQ{6<3;r5vgha_VyYM>cYzMg92miwEXibm@f;%$qK{H?AsZJ-_k$ejC?W z-W@z{YM=aT?reFa_~mhP{H+Vodnan(<(luvO{AmXGUbMmh3r6)`3Vu2E5Zjc45N9Z zJEWJz@vAYKm3=ad7xZYjs_KCYFP(Yu17q&mlsMLOp5=#Y?rh#vo8M>Zqyc*tjrPxj z!GXte>V4aB98@ZiDia!x+fy+;x5bj>Di8&^zSNL#5R5i{7};s1^|0IPJlN7@w&iNP zZ)Ht+W!8X+^Y?Wcvu)C)xjiqFiwpfl>T+AN9%>&udeeYW=Od&h8>a(837;lOI7Czm zhnYX$Rf;0Ar6{Wtjvkp1c>^g3Vf~^6c9?~-dKo)tq^HBanzUBRP-pXY!hjyH7~I^i zpsFTge%h?_Du*`r%?pJx=R0TKcJobR&%5KMt$l^3%hf$>#kobfr44hh$t%jM=z;_} z&kj6yP)q)%NoQZz-Rz&uwi{IDmw**i!%kQHu1t}MRFu>!Sm(%$WMaFL{WQU-aqOTi zJ|KK#{DN!6Tj_f?KJ={PPRD{VV=hgz9=~{!f6j$1_wCrWdGvV`krjbwA^8^27k2BJ zE@W>-!YyO${0l}6(jZ#iO0b?MrfQ;&oP=m#8^wvL5Jb8ce9d;Yz9Vc9JT_vKV5J_&Vz`n~3ZP}WYRfzW?vGE%dOx(K-)`6?T ztgQ$GdL#J<@T@uM+=+%rlWmq74R&uV%o;FiioU*6XKc%3eLSH#X*sze#|&G)b*WCJ zdgVqw2%MfsWFvuHSt2c?xh$&)NkObGXR%XuDsWR13A_ptaKBLlh#9925Yp-Wm1iV} zlLzcGC-2R?BW>415AIHvZA=a|RUn7S<5T32KEoz=AF$%qyY9cC0fbOdKV>l!!t8kv zJ@5wm#74*#5Blasv~5O)Ly~-60GR&M^O4092V)Hj6s0;f`6W9R2x2eA6(o%~>4Pl; zo*dS<{DyghM)Zi6*L@V5-M7c!;o<4av$uPy@E%w_Q=)CoGdC%{+Rt!&hOr1sR%x;yK}$uZiT0GiV;dK?y-HD7PO3Rvc zj+)YS&x%FR0wvoLpLFs97kya|lpEj)3A8;wdT3xwGH(b&=0+bupJ$6$e z!+*JXq+Al~re1dG)M*PYohpB*e|PdH{qMs2(?5kv?*7Q{e)q_>t&cnc`{)4?5rrZP zVRvs}mU?1raahRCI5zjc8yn@53&M*XNBRP5#(6n=?i9y_Lsr+UbM@C&(dY#2Of0=I zx;)BV0Y9}*NKyf!+wvhtWmQvKTD5?TzjIq!=~af&&G^-B>}U51O=zR&g{15O5_d`8 z9Qxodwe&uzhzj&Zl_6aJ52_Ny^nqHiBX6kbi!j0Mw2ecgJ=<}Tge`SmW)Pc}xf82D2W zS&A$&IQB|8qTp($0}fWJ-{uompLKX^n$M@W>}~}E;NWWZ3V~lcSg|4RFx3d$!> zoaxFmi9nD;ma@X5z!>?KQJu*S!!9DN<4y9kKb_G3sDJjuox}b(QRM6IHC|n{G_K^f z{g_|gQ=a_ITmR6H4-@Itjh`R!JNwFCz$W{lJrg<}#cmC^zJ|z#Tu3+}#r5Yc!!7d= z16!N$Bh|Q!2uFu(=fKMrI)hh14%pMY;jnERk(M9Hm2F{5ZrfqB^0=_Pd?J(dNP5R0 z>wdf=AMcQ*zWP?nAj?X;v66D`6k5GbXL&i)wLs8W;&zt|hlL$J;k;q3Spmf{yp<5w z!5eS9oe~T)(RsR(UI(X$c^ZY0hV`H^Mwuo&IOS)0=W(ua5W<3Qxu)O9@%QYT>2P*i zcj-%i5$T^k@b_!lzMXW*KG&V&7f!b;u5%d&E=|$=JHsmx@x`aa2jdbwIUsp|`K~Qoa2}s-FD<%Wn;F1IM zfuO*9PuFCsE>JW_;`2HICQKgBf!GL|6&;dpBcvtC$`VR>wpOl1z1}E(#mf~rcg@1N zV-}353zt`3(j2_{(hKIr&gv1Ytg9Y$@c^-Ev(2*U_{Oc@Zn4-NQ?^f;U-RpxV0nJP z)7YaWHsR9PvV3G5EUvAHPSC%SwYmC4`H(IPy)7)(EpGdk=pclsIpouT#vTV9*rg?6 z1Mero$iES{4#EA==6%Rc&+5hI{j$9$Xw`ODIllSV6ZP|R}`+xQQ zVU+H<=^-54PZwSh-E<4a%l)Svr?M8T1q%b@FLrvdD}; zPCA^5w(k6C(5X|WUd5E#X$P&`iSO8@eyHfqmNaK_SNAZU_`Jgtm!BHf`H52-v7%br zpAdufPmL#%XBtkmp^ZlSho+vvOa z&VMi)Neuq~`OfKWNNdp75wwG+e$f70*>22VYKFJL_IW%tJFwv>w9CfBlC(1-iF0gM zBVAlmg=Cc~PR$35LoQmSt_-^|?15F;D)m407~p_YD**>GY-Tv<)E?X!&hT7@Bl!M# zd_9t{&*$q=4976MhTnB9!|NEXWOzNpRSfUv_ddWaJjid~#PA`8n;AaLa0|oV@{?N` zKEiMt!$%qJVE7cnoeZC5xQpSl44>n^JTMQ2|e4F7r3=cDWm*IO1k1%|n-}NEGj~IT!@F#-8#?ZkqgQ1JQB{YU!hJJ?G z{An)3LWZRbD+rq+z_5nz)G-V*Y+x8=*vPPnpFE4OAi6Q^N8=St31R?^S}+X=rU5aE zKfQqAWQG?rT+B}{IdvG%FJ*WY-&w(LxrXmt%kVmes~E0kcq2b~Ge3C?U;monZ4B>b zxQR!-mEZLkUo)1)>)gVde4lY4-r?*2;%9i~#b5dQONL)F{D$9kjGz38XW%45ouG{E zBH(CxMjk`Y$gR`|c@lkBp3L`W^7Wmq!PJM+>m-GFV3|BE+&G06M+Zi&I%5U=Z zTm0R38UC5ZBEQGif8pyReEnCx{(ztV8()9S@H@V9jNuOil{9)@QTaNZubq6&^rLwA zP8Q$EW0=pdfbSPFETWMr#e7}D*QI=2#@FS1UCA)OcY=If#n&OeuIB3+zOLo#I=-&w z>o8w;;p+yzj_`GquVZ}O#JxI;VK;_77$z9@W!RtLAcjL2wlHM5q_9L%M)937497AY z&u}6`#-_s9RHhJ4m1zuTFr3No5{7da&Lyf)<}+Nt@D@;u$`Vy&iK?=I`|Efe1RfUJ1AW2kJB8jR>BvDm~ zB&sTrL{%k{sH#K~Rh3AhsuD?5RU(P1;v5=5lBlXg5>=H*qN)-}R8=C0s!CfKl0;P{ zlBlXg5>=ImR#l03O_fNZsuD?56%lg;NusI}NmNxLiKBvDm~B&sTrL{%l?VpSrEs!AkLRf#03Dv?B0C6cJBM0~AEBvDm~ zB&sTrL{%k{sH#K~Rh3Ahsw`1eK@wFJBvDaFiN3`WRTU&rk-VNENmNykL{$YzR8^2f zRRu{@l_jbwNTRBOB&sS%qN;)*u>QB{_xDoa$AC9292 zRb`2)3X-U*Ac?99lBlX6iK+^cs47cTRggqg1xZv@kVI7lNmNykL{$YzR8^2fRRu{@ zRggqg1xZv@kVI7lNmNykL{$YzR8^2fRRu{@RWO!WqN;)*u>QB^?_Rb`2)vP4x`qN*%WRhFnKOH@^!N$toaQB|2F zsw$I2Rav5{GD%cbCW)%bBvDnFB&sTtL{(*`QkJNyOcGU zs!S49l}VziGD%cbCW)%bBvDnFB&sU^K#(P>$`VyoNTR9=NmNxKiK?-`5 zqN)l>R8=8~swyN=RfQy~s*prg6_Ti`LK0O~NTR9=NmNxKiK;3jQB{Q`s;ZDgRTYw` zszMS~RY;<$3Q1H|A&IIgBvDm`B&w>gTw;l;vP4xClBlXe5>-`5qN)l>R8=8~sAL`|3KpaHw2z^V0s)eIvHV+`XM zmrFVe_;N{I@kW&^qFhzvXXz&+zXI+xSx+osvP%D2z>oRtlHGI92@gq>@eVRdV?H9EO7#4rMru z;kgXYV|YHp(F|J|j$=51AH ze}crDnnb**NyM9)M7*g<#G9H#ys1gVo0>$tsY%3}nnb**NyM9)M7*gh*u zcvA!J=t<&DO%QKtf~Z$x-qd8`O^ta|W8T!5H#M1fQ)AxLWa3RtCf?L!;!RB^-qd8` zO-&}=)MVmK4HSa@FmGxy@unsdZ)%_xx=*~R$;6u)^QI;fZ)!5}rX~|_YBKSrCi7UB zH#M1fQh)L z@usE_Z)ythrlt^YY6|hDrVwvx3h}0<5N~P<@usE_Z)ythrlt^YYRsD&^QOkUsVT&p znnJv(Da4zaLcFOd#G9Hzys0U~n;JM}KFse{hAP7Vo~!`Z5Udl}Ie>TQny9OSd8Yzg z^BAtXF{Bl(0$f9%-p=q2hIcZ&i{Uzk>lqSvRDe6^`PUh~!SGFnr1MmOI|!1_QvvP( z1a}a0GxRX@F(mG&VD6{@<)c?j`4vq06`*|j)=zx@BtxAbQ(%Q`r|-(7FI9jJ@gy)p za4^H642Lm1m*IH~&u2KAVJpLN3@0!&+M#)_;CZg#d9L7ju9RGOd!?i?tibb?n9n_c zIE4q;jbV4b--EAvG9)d!68kBF*D)jxt;BwcAZgT9HNQpl=Ieg^t&M#B6T_1XQKDU{#Jmx7Q2%8o!!h(cbV!253`-f7GpuA7 zWEf&t!?2EFm|+9MD8sqbKIV*c;Nfh$@2MCW1s2LCAAJrivg_MUbf?C=*o#nJR)z6+!GK=nhdu z5c>#%L={2o9S9Ot1hHQrNK_HT9)TcHMG#U8Z(*tkGF1e@O?wbET!%cfA30 zxt=Mxo+-JWDY>30xt=Mxo+-JWDY>30xt=Mxo+-JWDY>30xt=Mxo+-JWDY>30xt=Mx zo+-JWDY>30xt=Mxo+-JWDY>30xt=Mxo+-JWDY>30IgE8=JZi_O42fq^I)NeaY?wzH z25r+dNue+(oUXeu>;asHc^<+%4`H5%FwaAn=ON7V5axLZL;Io@HZZ)G;e8D6=XQwS z!#qo2o~1C)QkZ8c%(E2cSqk$kg?W~cx{toavlQl83WHPV4vz)e7v2c%i(oy&E({|K zV+@=4`Ln1G;3k43F~Z;)f+rd31i>}<6l)M>3~LZUk_KVuLTH~c5@w8q86#oFNSHAa zW{iXxBVoo!m@yJ&jD#5@VFM%34XCw?7*1t4o#Dj{XEB`3a4z)+Tt;vK!&}gw2ur63 zOQ#5PR)nQfgr!r2rBj5ZQ-q~cgr!r2xi7-p7h&#;F!x26`y$MJ5tdF7=D`T_V1#)v z!qO?i(ka5yDZbc8uN!WNx8e?;vJ zjbR1!v?$L~l;kA7kvt82d5CevGjnW9-Km`!U9T zjIkeM?8g}UF~)w3u^(gX#~Ax@%-c#>+uhKS;+Q?UrnM=KIh+qj@+8i(G0v+%oMmGi z_vo4akOpyBR1tkoIeF*z*ZK!f+eIM;Y#5NPD+9?D+(rX1I&tvkYk;8izff z;0p|CHy4*);?a>+KMt!t&EzY5y_c_F6)~} zIIR72eTd=P49VIYhqa#|S#jgA_7gn9khID;Z2okIbjvs_|8z||nmFwLbp0`3f5O*4 zQO|{qp@U%tL)!Jkg^QlywJ9z%z9x+{F1&nAdTCtv`8u1wmCLY@XaL@U|Bs}%50CSz z&;0ew)8Eo9G^?s~Q+2p5Xh|jyU>rkR*&fR^7ix%0T0vqaS)xE%#qWU_*#))Rb>H-Y(C@xK`RBgA z*U>Z2Ip_YKbD!@y&(S$Xe;wG$*MY72I^ewA-?s+t?^^@+_pO2Z`&NA&FnWyM8dST5 z1b+a22=q6Ct@=hFR`rd*=+SMfz7#m!tFl{zHB#1%v6z1q3&CFk9a(K9vf8SZcIBo1 zsNZU(U2kIq+^Y3by|N_Z?*j{Y_Cpl)#|j!wCC5 z*zd*m>h#ud6Sh~Uw`z6TZ@3$K3-$-FKZxzs>8)Cw_A^!3+rT7P4SopxF!+a{XOUY& zdMhLNR;^U~J)R?M4QsJIQ`pLAzBQy5Gp271>BWrfTeXhuUwQ7ZRjb*y>C556*!1P_ z5p2&UwrYLb&p3+Ms#R{=Z*uqlAb+oo!>S}aswq3fqAp8jEcDuc7H>h*uWPcpI zAAErHJ=mYXPGRdmYxSgSv0a=vuO_e=OoJ_825jZYHn1J+06W1hup9g~xqJug1N*@N za1cBUeis}9kAO$P95@1=0KG=KUCL=Z1&)HJ$uSR(f#cvLWj@O@UW47PFQNWz5qk=| z#FKxEJ&pYX>>2Erv1hSg!G0C|A$T5K055=-z$@TYex?6FRgSNNKLURYz5!kbe*$_Q zx?P%S{AKW0!P`K$;qB5)|J5ydyP|sAzmENO?BBq?9a|?l>91~?+ohRCx4rGsNu%4| zcIl*%wkMsmU1MgXhkifpN_yyY+LiQBw%Wg1soKBsAyWR6e<}vJjw$(fI zS1F$Usy<@-UD&^k{X5w2#=aADEU{e?i=T|J--GR$*LL+Fr*Fc3KlWzqyRp4`yj^|D z&v=fuT~Uqg-^2D?X1l(}89hhauJ3Wi4}l*Bsk>$?F8N1Exexn~vHt|S7W-q^^e-u% z-$VbB;@PHuN%3sMk`&MOC;645m+hL}I2T7R+rv*`e;OMOrFc$%lf%#O*ZtsU!Owwz z3VvRgL_LzIN0QhqiFzbakECKVKV$Vsq8>@qBZ+z>6_qV0-Cj;=kA$DGdL$K<8C|=i zqB7gAT~bk*ZL3ET^+=)~Nz@~$xNBJHR*$6OE~C{WskqC}TRoDByNp(kq~b24)g!66 z%V_mTD(*5`J(Ai-VYGTAwU5GR^+;+Th0*GfRNQ5>dL*@v!f5qKY9EEs>XAe}lBh>g z`zV}Z^++o2GFm;7+DBoudL$Kb`5CK667@);9!c$^aJtnasff$=G`7_vsff$zR*$42 zF56a*q#`b()g!6>6-KK^QW2NY>XB5$Wwd%E6>%A@9!W)9Myp3s5tq^Gk<`8mqtzpc zdL&VgWMK73Y8}96^+=)~Nz@~WdL&VgWMK73D&q1pR*z(0^+=)~Nz@~WdL&VgB?&q2dgvmV=4k0k1mL_Lz40Xg03kyN~7+v<@- zJ(8$L67@);9!bSZ{;Sm^iFzbak0k1m)Yp8cTRoDfM-uf&DqeCetR6|lOSY{ZNv(d^ zrhlOxNz@~WdL&VgB1Nb_E!%9y_EG3qrHBLn>jkX6|6Fw1c_Q4(3Wbm@DmIuC#->(hlZIJ6Olt z!MtM!Gmah1HFmH)04!OJBTWG5Krz9GfsC5xr6AjTH2V_&M?ngtI@`4X`^k|x|&*7Q|oGK zT`g_wR{BRk?*yopHX1!5R7)Gr3cY`q9ul&`o zS_)}w2EDtcS_*0O9-C^|u7>Su*sg}{YS^xZ?P}PrmO?tO?|^+^KR5smf``HHg8s^1 zErm251#{pCcmniS#cC;}(cea^rI1GNG^=K(S+x|>ws)FUOCeq6vpiG4{yugQdkVWm z-TxMQ8v6&>GuSU<&tkuV{VMoF@I1HxUH~tFS3u86tEG^}*TElwKL+0buY*4Uy)&&^ z3TgDtv}!4&@izZe3aOgX8mpy{w%sPHrI5DWGOMMKw!LGmS_)}&Y*Q_TGwG`6m zU24@*NTYYDRkKU2S~F0;=MO+f9o5oIaVX97n`v*f|7vNbQ$Ff9OEdM1G}HKy-zLqp z?eC}6^pt98rfu)5td?f#uhLAVNHcA}3)^$&YH6m^-;I4Im>}gY>0Evfy9(R}Cc$d(L*R!&>P}CumS*}5_n8@KrtLq$uEqWs z_WdCJ4h5(V>38TrwKUVe@*J~TnrYi{X|*)dww0k;nrWL}Db2L)IcBvq)ApMjdT(mA zG}GvvRMpZ|{*Y$!M~ZabzbW$RDsD><{$?WJxD@{faU67VxdYdq}^B z^m|y5yN4CId&#xBi-|pUcb60*a}uVMeX1CA#jcKbtCV;C&v4kzkfvk{qUZ$ zk7!q^F!mNu{~)F_fn2KH<*m! zZgSsE?z_qTkCgkD%Kk{X3zfU^t-|}r{XTNPk6+!#uWE^e*s{{Y^90PjD*`yY7o z{dj*5x$GgAJ>;^7T=tO59&*`3E_=vj54r3imp$aNhg|lM%N}ysLoR#BWe>Te)W#kt zOR0?+9X+OKMX55kq7)*DO!GtmY<^K zr)c>pT7HU_pQ7cbX!$8xeu|c#qUEP(`6*g{ik6?ES#rEw4yp%Q5~(Qj#gAhE2^Uv)zOOT zXft)RnL64`9c`wLHd9BNsiV!*(PrvsGj+6?I@(MfZKIC1QAgXTqixjD9_sLZ9loo> zcXjx#4&T+`yE=SVhwtj}T^+uw!*_M~t`6VT;k!C~SBLNF@Le6gtHXDX!1g1st-ZJ6 zUpwYN`{)taegw83f$c|N`_qi7jnbC-vPNl((Q}YSMG;2tPirjuAhug$W107MHkNsR zT4R~_r!|&&e_A6mg+^uyjm#7pnJF|fQ)pzS(8x@oQQsx~yyNgjW@nAe&KjAWH8MME zBz|sWcGk%3tWlAMo+ln|3>*nJD$+3edtalzW*WUetugSf=|+9cG+MP9_0`hp-k;VO zcz;@BtjvFv`sr6vKcgeAMxwq(;=M*9y+*|z=QKR0;W-V@X?RYcx4?4?Jh#Ae3+=fDo?GC#1)f{rxdonE;JF2!Tj03`o?GC#1)f{rxdonE z;JF2!Tj03`o?GC#1)f{rxdonE;JF2!Tj03`o?GC#1)f{rxdonE;JF2!Tj03`o?GC# z1)f{rxdonE;JF2!Tj03`o?GC#1)f{rxdonE;JF2!Tj03`o?GC#1)ekToPlSZwWIc& zf#(c7XW%&l&lz~mz;gzkGw_^&=L|e&;5h@&8F@SK6?3_NGxIRnobc+S9c z2A(tUoPp;IJZIoJ1J4Af#(c7XW%&l&lz~mz;gzkGw_^&=L|e&;5h@& z8F@SK6?3_NGxIRnobc+S9c2A(tUoPp=Bv9q)lhFf8{6>eMMwiOOr;jk4B zTj8)34qM@{6%JcruNC%MVXqbTT4Aph_F7@D74}+TuNC%MVXqbTTH&Xay0=pIR_fkL z-CL=9D|K(B?yc0lmAbc5_g3oOO5Izj``4-Ce+Qoi{~COz%(2-sWsc3B(W>u)(7TbJ zQCnIPCczz~dwt-UvYlWfDNSHAm@E1n48Ka~9XNV!6iTO+7Gg{>{z7zCrEfdgSR$#YlF8ocxz*)TpPT#!CPBs-rCqH*A|+$Hg?Lju~V*1 z--euG-rCgHlncDI!CRa9+S#&pcx#8Zc6e)tw|01IhqrckYlpXXcx#8Zc6e)tw|01I zhqrckYlpXXcx#8Zc6e)tw|01IhqrckYlpXXcx#8Zc6e)tw|01IhqrckYlpXXcx#8Z zc6e)tw|01IhqrckYlpXXcx#8Zc6e)tw|01IhqrckYlpXXcx#8Zc6e)tw+?vgfVU2K z>wvcocwvcocwvcocwvcocwvcocwvco zcwvdTcPI&8tw@!HLgttz3>x8#XcPI&8tw@!HL zgttz3>x8#XcPI&8tw@!HLgttz3>x8#XcPI&8tw@!HLgttz3>x8#Xc zPI&8tw@!HLgttz3>x8#XcPI&8tw@!HLgttz3>x8#XcPI&8tw=Q_=g10Vs z>w>o~cw>o~cw>o~cw>o~cw>o~cw>o~ zcw-7^Kdwe1{g)o-@l?C*q`2Rpz{unX)4y+pyy+ zyhkD%c#lMuJrY^=NMzX~kqx{@A{%&*L^kjqi7b00vh0z_>I<66qc3Pi?~%x|M(<4ZTMq8~O`=HuN5eY)G$U zk3^PPc9uO7S@uX|L+_EuhTbEQWsgKQ^d5;UdnB^#k$8ds8he5N8hb%{(p~lfvB3*O zQ!l8$JEaM12Gd{*m;ooj0$4OM;=jO%{{kca3qg(3`LD4T_^+`Sc%SQj#*bDNk z@!jB^;9cN*!1sag2k!?~wkTnA7`6?<2jB z^gh!2N$)4UpY(px2S^_veSq`<(g#T&Bz=(dLDGjvA0mB-Z_`73n;zoZ^bp^shxj%< z#JA}ozD*DDZF-1r(?fil9^%{d5Z|VUc>mCw@8{d}5pp>~E=S1a2)P^~mm}nIgj|l0 z%Mo%pLM}(hk`y93_{de$I0b5xf~~#WvwwEZ|OO)*;%Jvdvdx^5WMA=@VY%fu^NtLa>Y*J-2IzF5vKAdFTev&A0 zk|=Rfb3;Gl?@*JP8yfu`YLX~!k~QZ^)|@9NrW>=Y%@tzGs(*HBoWIbvC1S-$|Uj0q~?+;kLHp_f4`m#{QY`Tb4la9&P8)Z zr~CW$q~?r5%^CGqv8P{&J)1^6$(e*yjr@Lz!c0{j=?zX1OQ z_%FbJ0saf{Ux5Dt{1@QA0RIK}FTj5R{tNJ5fd2yg7vR4D{{{Fjz<&Y$3-Din{{s9M z;J*O>1^6$(e*yjr@Lz!c0{nj;{=X0Z--rM2!+#O}i|}8B|04Vs;lBv~Mffkme-ZwR z@Lz=gBK#NOzX<(U+FT#Hj{)_Nmg#RM^7vaAM|3&yO z!haF|i|}8B|04Vs;lBv~Mffkme-ZwR@Lz=gBK#NOzX<(U+FT#Hj{)_Nmg#RM^Pr?5b{7=FE6#SRqyaeYZ*e=0#306z6T7uOQtd?N41gj-j zEx~6AK1=Xfg3l6smf*7lpC$M#!Dk6ROYm8O&k~H4V50;ZCDo zrm5XDwVS4P)6{O7+D%itX=*o3?WU>SG_{+icGJ{un%YfMyJ>1SP3@+s-88kErgqcR zZkpQ7P`epwH$&}asND>;o1u0y)NY2_%}~1;YBxjeW~ki^wVR=KGt_Q|+RaeA8EQ8} z?PjRm47Hn~b~Ds&hT6?gyBTUXL+xg$-3+yxp>{LWZid>;P`epwH$&}asND>;o27QM z)NYpA%~HErYBx*mW~tpQwVS1Ov(#>u+RakCS!y>+?PjUnEVY}ZcC*xOmfFoyyIE>C zOYLT<-7K}6rFOH_ZkF23QoC7dH%skisogBKo27QM)NYpA%~HErYBxuOFh_(ir`g;> z*<6{|e&@=(_B$tiGy0q0oK()X*M8?T%X5mq3C?L%$LMdVb6V9g`kUY!Yrk_^EwNny zi$>{{-Y>l}`djLp^vXzH%mn9{3C;!nmO7`Ipnv6WsdKFT&aw787xy7> ze@mTX?e|rptXGM$Ue$e5-z`s^Y~&OU(Dl+d3-UCFXr*ZJieI67xP-J zS}2>x7xVaH9$(Dki+Ox8k1yu&#XP>4#~1VXVjf@2`s^Y~&OU(Dl+d3T>jHUQAg>GLb%DGtlGi2jxE|J$I^14J`m&of9d0ir}OXPKlye^T~CGxsVURTKL3VB^2uPfwrg}kni*A?=* zLS9$M>k4^YA+Iasb%ngHkk=LRxM%9;5 z^<`9j8C73K)t6EAWmJ6`RbNKcmr?a)RDBs$Uq;oJQT1h1eHm3>M%9;5^<`9j8C73K z)t6EAWmJ6`RbNKcmr?a)RDBs$Uq;oJQT1h1eHm3>M%7oehQCm@Qs%kOO4)AE|G}}s z4)7IrfUmFve1#q0E9?MYVF&mMJHS`i0lvZx@D+A|udoArg&p84>;PY32lxs*z*pD- zzQPXh6?TBHumgOB9pEeM0AFDT_)6I&N^->*_zT)f;4f$^!LNhNG}VF&mMJHS`8n(7q)-^vO*z*oXrY-$~T0^9$$vceAVmC*lhyAt~U z^jFvczQPXhRd`#4w^evsW#{}Vysg69D!i@2+bX=R!rLmmt-{+Xysg69D!i@2+bX=R z!rLmmt-{+Xysg69D!i@2+bX=R!rLmmt(KX$Rd`#4w^evs4b0mrysg69D!i@2+bX=R z!rLmmt-{+Xysg69D!i@2+iGauR^e@xo%5^kwhC{n@U{wXtMIm_UiL`YntGWrq2I32 zv)1TYYxJx&jb%>vSihzb&9=R{rm^g-(BFX8=yz-MyEXdV8vSmKez!)yTjNx{HBQxA z)0xJ8TQBHS_15T>YxK%BdgU6ua*bZOMz36>SFX`3*XWgN^vX4QEid)XABwi_6$EWM~bRD0rE_;ekguH(~ne7cTL*YW8(K3xy&({+5hj!)O|={i1L$EWM~bRD0rE_;ekguH(~ne7cTL*YW8(K3&JB>-cmXpRVK6b$q&xPuKD3IzC;;r|bB19iOi2 z6lIlJrzjik)Ai6kU00+e-tg%|UCz^5DdbOWDm;L{C!x`9u9=eYBFUM1PUryKZm1D|f-(+zyOfloK^=>|UCz^5Dd zbOWDm;L{C!x`9tO@aYCV-N2_C_;drGZs5}me7b>8H}L5OKHb2l8~AhspKjpO4Sc$R zPdD)C20q=uryKZm1D|f-(+zyOfloK^=>|UCz^5DdbOWDm;L{C!x`9tO@aYCV-N2_C z_;drGZs5}me7b>8H}L5OKHb2l8~Aj?KGnr!`hP>A{@+ljnTYUrK+QyCYbGMpOhl-e zh)^>Tp=KgN%|wKMXWKIoq5l6a2;5GD(sQ9SP^kZA5`GZW|JTTto(rYtLg~3sdM=cn z3#I2mebX1}o4!!r^o9DSFVr`Eq1uU1?L>G8l%C6$o(t9Yh3fl4eM1-O>$yZ1@5TAzlG{mPNJ`M3{=)SLa+NU8t4e@D+PeXhf;?oeH zhWIqZry)KK@o9)pLwp*#?+2m#zR*4m@o9)pL-&29*ry>r4e@D+PeXhf;?oeHhWIqZ zry)KK@o9)pLwp+I(-5DA_%y_)q5FOi;?vN5U$%W3y6+3^(-5DA_%y_)AwCW9X^2ll z_kBHSpN9A}#HS%X4e@D+PeXhf;?rN2PnUGfqUNExhWRa^zE%gfmFb(5P~W74X6ZJ0 z_N-8=Izp|q2(_vs)T)k9t2#oh>Ik)}BWwn>sw2Av%z)bItrV^52n%4*C|~IP@`X{W zIzlVMZQ|Lu102s*X^rI>J@(=b%<~g4@KuQL8#aeLE9sRVTR3D+xla>Ik)} zBh;#nP%8<-yFjh#$kwWkP^&t^yFsn$$kwWkP^&sZt?CH1sw4cSN?s0c=jF>mGYRt|6F@K&yN>vZ#04sYe~Rt|6F@Kz3Q2kZm;!2xg( zJPdvp90HGkN5LF80-gX*g5LvAfurDA@cZBt__yE>z?Z>Sz*oT^g6F{n@B*m0zsj#U ztneB&`VsgB_!DFBAN<$g*T7!~e*=UWpBSLO!U++}?L;iM`^13YcF%l++kIky@Lk~V zfC(@H9m(7tZUQ%hIwedgj%{w&4lbid|Jyxx7CNfA-E(K5cCQIP3{sx(qu758YRy4^ z#YZ7N^4wV|)~?&bhe545$o@3w(pKXAO1xi*_bc&!WtqKSiT5k zMF{QvN}m@YwD&8$f+4i`E4_jtwD&8$f+4i`E4_jtwD&8$f+4i`EAf7%&x??4?^pV~ zh@cYhSK|H3z}~M6?EOlg7a_FwEAf6M-mk>_m3Y4r?^ojeO1xj`^CE)E(B7{M?fpva z?lao^l|C;*Xzy3z{Yt!FiT5k!aw4?%EAf6M-mk>_ zm3Y4r?^lNQekI z>U2k$&R`enjBDXXc=BFQXIv{qr#cID2D|WnP^UM`-h-{vn`Ni4bq2d^?W+`8Kkq2B zM&02Rc%j?s9a@2R*>ncGP-n0Uo53{L0%pKgo^J!&!49w!>;k(%ox!g6=nQtD&R`en z40fT;U>E8PcA?H-7wQal;ShKP)EVqb(HZPQoxv{D8SFxx!7ltBs597Q>kM|G&R`ej zL7l-aTW7EfCn$-|V3(~k*o6gboxv`>cV0wqM8A8SJuujIA@+Wnahs3HGW>9{fA- zm%(2JZ}T(iJ9?g3(jDqSwkt^28SJv(j;%A;W#7)PDnadNc&Wu6^G2T?oiKly3Sx1uJPM- zV@zkT3q$aiK<)ijiuQgBA97xb$MjqEbiIwa*d6NcPTA+bDo&HFzOTP3TC=S)*o8WS zU8pnIg*t;>cqgbc*k#{^tuxqV>kM|G&R`e54_jxj%hnm}LY=`b)EVqToxv{D8SFxx z!7kJp>_VNvF4P(9LY=`b)EVqToxv{D8SFxx!7ltm@Q++~X^2zq!`2z>vi}5IXRyou z820@jy_nhM9a0$oHATA4V3++6HY_pUyhEDfbo#QC$M&aqMrW|g_Nu}iQX$)Ka`+jT z+z);h{2chF;OD_V<5xO^J-AaNmr*CV1$Rn~jXLQ_t;d>{K+_UvS^`Z=plRHbrN4R< zPM~QCG%bOqCD614nwHQASg&W?W)f&x0!>SxX$g&nPPe8dG$z`%rX|X(X$dqffu<$U zv;>-#K+_UvS^`Z=plJy-EuqWrg3|h(3-~WT|#Rbw|5DxX$g(Ue%_jv zK+_UvS^`Z=plJy-ErF&b(6od`WdF*VmO#@IXj%eIOQ2~9G%cYK+0R(h5@=ciO-uM* z38h%m5@=dNb0t4xO-rC@360&ht!W93;I^%4360}Uv8E+7n%lOfB{Zhnwx%UCvfH+% zCD614nwCJ*5*pc^ZcR&|X$dqffu?b1nbNIk+*~HKrg49n(3+Oe|EH+rXj(%5pJLmZ z#_eW8YZ`Z)39V@fG%canz_v9lp$NgYH7yZX(-MI-ErF&b(6of|QOiWr5@=ciO-rC@ z2{bK%rX~E9Sx;Ki5@=ciO-rC@2{bK%rg6`jo}qoBX$dqf5m?g_Xj%eIOT?^ciI_Dl zfu<$Uv;>-#K+_UvS^`Z=plJy-ErF&b(6j`amO#@IXj%eIOQ2~9#X0gUnwC(sW80dR zK+_UvT0)VJ)2(RyU?_|(6k6m zi_o+PO^eX92u+KK(;_r2LenBNEke^GG%Z5YA~Y>R(;_r2LenBNEke^GG%Z5YA~Y>R z(;_r2LenBNEke^GG%Z5YA~Y>R(;_r2LenBNEke^GG%aEkH$u}QR&gUVEn*cnLenBN zEke^GG%Z5YA~Y>R(;_r2LenBNEke^GG%Z5YA~Y>R(;_r2LenBNEke^GG%Z5YA~Y>R z(;_r2LenBNEke^GG%Z5YA~Y>R(;_r2LenBNEke^GG%Z5YA~Y>R(;_r2LenBNEke^G zG%Z5YA~Y>R(<0)u2u+KK(;_r2B2J6YvR z(;_r2LenBNEke^GG%Z5YA~Y>R(;_r2LenBNEke^GG%Z5YA~Y>R(;_r2LenBNEke^G z;er-Xo72|C3YXQ{y|q-v-|e z-U;3X>c7AB%=xmVx}2NT#*8lKCd#=enR0HXoSP}e znR0HXoSP}r78oLea8 z7RtGWa&DoVTPWui%DIJdZlRo8DCZW+xrK6Wp`2SN=N8Jjg>r78oLea87RtGWa&DoV zAEcZgq@2FJaVhZ4j7GOl-^^&V-+eQq(SG-xj7Iz2cQOhor*BbQ2z-m8(e2Z>C>q^9 zeT$;ee)lbkM*H2jC>q^9eT$;ee)lbkMz>GjGq@mhKk_|;PH{PXhoI5r^c{jmm(zC$ z8eLA`9%ytqeH);Va{9hMy^V7EzCWc?PT%)u+vW6qe@2(n_x%}NPT%)ubUA(BpV8&4 zQaN>|hRSL5YEqR-J1k7_SAYAiQj}u!m+mUXCksNatX7qI)v>Bm}jl+pp}))?7cU^nPh z?kd(ft61l(Vx6;!b}v0Tg94fmEsEjm3F1LLblq!+NavT@gY)lYm98i`BjP>{ESz~ zs}woNR`1YXS>3HtAF=%||5ZK3w%7Tq)L(4t))=AJPOH>wY)9C-HAc2q9;(!XY;VHW ztueAUW8aPKF9KESQ%?7~Yn6JI?cc-px1lOU4#p(tZ$njz9E=|Z=~IdvT=I{Sav$~| zWB&0gQ*{091$A_v>_FIJMP6gl{9{+3jw$icQ(YpWDF*!F5|l_Ce*{<>79 z$iX%oDsr&>8E`+STVs^+IZ(I8$o{-=t7bqtUA@e^iF`xou+X~*xEnOs%BuTT`A#XU zz5AZT;lTIt>GV%MX|(2SljhjA7q&4o+9u7hZ4S3db9Ca5G{<-^xEnNA+oU;Xg*s_O zs1px_I%!0x6Ay$sX+)^oScJNbMd)=c-vH-aT^&PMe)JY>s82|^t!=O$YQTh<5lSX781#_TI8d1s# zP$!MZ{vLP=90he7i_-I;Zex+H+gOA;X+(IIXLQntY@IYB)JY@4DeMw8(n%vq@k-7% zDUa1yCoA=&w3yM5vQSgkGKACgm}{4(g;4*oMv!mSCHd$Ee#_ggR+Nc$@#KS&!bytY@2)$94tjzmENO?BBq?onPss5k2Ex zzfHkoirlU zNh87}sFOxy>!cCkhe7JjEM}Xu$mw2f-lkcMZLc37Uxwn>ZpSFbj2 zlNQsXHffP{-EqU~srZ_*rAinVAv3bP$8+Kv`&M~i%e;c$>di;`$jk|%v@o=zo3i+pR|f^2J% zZ_P8BAK#j1v=$}H+%|k`p8sks@~wGBbK+a`Y?~9`nrGWuyVkxt&pBF)e0QGF zTI9R)jMgIGo#!XpK(8(P?mVN{mVI}g(QC`TJI{Gpi+p#U(OTrY^NiLa-<@Z)7WwWx zqqWF)=NYXCx9N#1w8*#V`TdT!eVd+bYf%y{ z@@;y05-m!iMZQf>&!9!VP0zObk#Ez}lW37|)3a?Y@@;yytwp{~&$hM5x9K^>T9ibK ze4CzaYmsl$vu!Q%ZF;t?MZQhXwzbH&>Djgx`8GY<)*|1gXS5diHa(-Y$hYYktwp{~ z&-h2KHCp7`^lV#;e4CzaYmsl$vu!O(hV(nM$hYbFuht^prf1t)~o^5MU z5-sv=dbX`azD>_I9HK=@#YJY)TIAdGjMgIGrf0Mk`8K^J;d?>Po_0t*jGoK*Ha(-~ zGQLgE=(&t<(=&Q5s?zD>{Q*xtA486D62Ha(+b^&M)TM#tyAO;1RK z?A!EYi$kNMO5dhubUf+X^o))neVd-qaiee3GdfoEZF)-q_g)EIJMO&_x^~=qC3Nk$ z_e$v6aqpGTwd39^p=-yzS3=j0d#{A99rs=dT|4f*3b^-5=-P4bmC&{0-m8FnuLAD9 z61sNWdnI)3xc5rv+Hvod(6!^%3yQtkRe76hV?V@(O@ZBzIw+r9x!gssy-7adk z3*YUccDwN1E^4<6-|eDyyYSsEYPSpD?V@%y+5=o4)RgJu7NO(q8r9UOn@5Bm>1tG8 zqfTxS>f{!oPHqwEYP{)Sw|Xs7DRDQ6oP6ytSeRm8d}+i|lVI7w%0H{)$@8A1Zg_TZQ+qhx1y(lv8VToJ!6%h5qn1RVh8NK?0~&D*hP8`zw(aj zd)WbdFFRoG6{|`St47c4?j?@8SL2Ry(fDF~C+Hp5_i8jT-U;3Xz6X3C_lrJ zCzMhL|8?+R7d)uv>jJlmx?msZnQvY2IQE}m*DLorz2E6yApI%q2JmY}*rLO!KdXTp_n(mRrn~rdlcV2itiq!){p8v^}(a~?ooXAXkgzx zitir9caP$`NAcZb`0g=$_ZYr=4BtJ5?;gWzkKv=o@W^9$WG}wh%QxA*cx11B`$(`? zzcuayJ*Mx~8=P_g`$_SzR~~WtpR1gE_;EjN?6Z{lvy}O>uKBdwC#G@c75QsT~FJt58Srv1GnvZ+IBr{yIz{( zH@I!r)3)max9$4CZM!~j+pZ7Xw(Duz^|bB!z-_xeaNDjA+_vijx9$4CZM!~j+pZ7X zw(A48?fSrNyPmdPPus4iZP(Mb>uKBdwC#G@_CeS<2oDFvLpnGp9*kDqgS3Z(;=#66 z_aN=(AgX&1)jf#n9z=Byiifj$#;SWzJah})yAO(iVWCy`pcpV(bq|UGqgD4Hbw8-O z+qUW+RNehotL{P7+O}2qplWTj>K;_BZCiB@QpbbT@gS=Eq-xh4JgM3VX_HUVCZD8D zKB+c&R_PwOo}^7asWv$*`ylCGP+NLZtpgnE@e@k_0{nadX1)M3U!Z4w zfu8jg+&%@jPbv4|;3?&9+y`0>o>J~ku_io4`JbZvUsOpJf-llLzDSSwBJIC{cQ)|O z2K?24zZ&pY1LbMJUk#M1fl@W#uLk_pfWI2>R|EcPz+Vmcs{wyC;I9V!)quYm@K*!= zYQSF&_^SbbHQ=uX{MCTJ8t_*G{%XKq4fv}8e>LE*2I|{DeH-xCp9f#l`u3NkNJ~OT zgI|))7#$6MS?R;VUopb-m*M%#dPXUFW;pl?Z}_TM8VAi)TM>Gv``n{Dm5HrC}D;YX2kh|Qe3Kx*fzR68L_&cI{!cFpjlGqspN7s0``g>oECsnEX0SejO&i z4wFw)>!+#p(aIGLcQPkHsQ1U z_E~=WEWdr0-#*K4pXIl{dFO1(MjAL64ph20h}l zCl~+^>kU1Dch2_&W7scYd-bm;xJ=3w&}(r$!FBLoje5V{ruQ2^4}RIdjeQl{O4}3b z1fK^7!SDLbu_4}Yg6B_SdzG>$b_)A%ut%}Sczzsvg7h=klr!cTQ%~$1>F2Tk4O|9S zz*TS!{5iPJ^S`hiI_~NTf7L1BZQ{8nv{v_o<=D47_wYCMq;CXB3;ll_z864tkac>{ zr{{YE|Nla7FpTYb^#-m>Z*UsSOHX=(asM`$;jdmP?G0vmkN4m926H_5Dmc$ye+asE zy}@~&{NLDKLG2A*<5w53FM{5q+bgd*mn+~^Qm*mN*Lmhg;E%yK!0SBu6YNFs2G8Hb z{yXu|8~l{_ERpi}*#AIzZh`+q`oDnx%G>@8d&Q_$t@029^b!O3HUzP!R&D&8-xm8X zJo%^2H|FuZH&#!|LH_C)dT;D0QvNIW=b&Tw-k6oMH};o2>0Z_w^IW?(=DBun%=^82 zW1egG#=PIVH|9vJH`a>nn5Q@P-$5%|Z|tv0cU03Gb0pIn>jhunuipmoc+4yFy=uv> z-BE13A3KKqB2OOYZT}0~|H;xDJK>fPJISw3fumraXJ{d@GrVCEEP!5z?~QqPcW=z= z@V&7T_7C_KZ7DWO`YUkdRrlT)?I(5~n>G{kUhdu)?Ih;^Pw9=l4leSZo8V9F@fg02 z{R6-KKcxR7PyS!*TiE}E{mj%Kb)MevZQyM@>G82Qbkx)vR=8f_+p&Lx-~LCQ{7vT){uXwezrI6HX6c(* z`e2qmm{spvP`Y(28*@v`(sHu2lPoPHOWVlC+$yp$w}))Ze$2+~!L0mZwB}@E-v_5a zD^E6Nma;MPlZ}~~tm-aQ9gWuNtQ5xRF(Mnf7B7(U0x3R!emL;?^Fma*50&l>Asj%x(}7^i&>@n zVpi$Cm{qzDmF|mK&HB`0{kHF6TiNZ~zVm z;BWvA2jFl34hP_H01gM>(Dx(gop3k+hXZgp0EYu`H~@zOa5w;m18_J1hXZgp0EYu` zH~@zOa5w;m18_J1hXZgp0EYu`H~@zOa5w;m18_J1hXZgp0EYu`H~@zOa5w;m18_J1 zhXZgp0EYu`H~@!(=+7YfGl>2SqCbOTY#|tgpFvb;P&_CFEgD3N2GOEHv}h158bpf* z(V{`LXi&BDudGOes-4lgG$>u_7J7^rR85`Y9yf?O4WdqisMDb8<#cP*AR0A@Mh&7! zgDBD<8Z{VJDh57G{BxMd=dfz06e6F)L_UX!d=3ZJio>e4|LVPVhgIvd!oS6ymG=(^ zuPDdEif3%UhJ6XV3R=MqE8Z~vtZcvV@3H@ZH{9Y^|Lk<4h{Hq?hZRNWdGV|5CXg#FLh z_S#`a&%+u$ZF}@QtkKi9N6f<-F~xv9sJevzk@VjJJxU%9-=V+yMv{7=$KN6K^lqV} znj!UZr&!O2=;K4`<4(U!ihVRh@Amy8dQ$z`_<5((uZQT@L-gw*^=qd;4-SIg_1oyz zL+aQ5t;d%k_3O0oZ@@90p$zopAzJ$oeR&ABhiL6XwDuwT^$@LnC`JimZ}3i!BSW+Za%f9V z+M-;TkK|(im3MkRl8gNX_!XCy`A9DISJIq z&Cf9($;CV$$uS?vF(1jrUf`XckK|&WkK~w-2o{!|D1InHGNG|kzB*%Ot$9yD*qUM;7E5Sz zig^1};Hd8uY@E`F>}RGx?=m_iO*Y;#!u%w+Uz1!&M?v#4B@h9L7p7|Hh zGr?2D-lvGVPr>l1(Bto^(4*}sTF5C{$SL(cr&Rd28n2CUQr;nZl&^B5e3cs&&*@-P z+;$6xvCZwMSarI~KdSN0f3+fwiZ>x&=tlWMH!9wo@+9c*`=hWl3J;^ydQ>W>w@Kyv zq{qHd)z^3hbbUvu%P4gjRht=BiswP2s*8TBy6Ab;!uC64pQaa_rWc&17o4USoTmMs zrv0C$<)5bIpQh!Xrsbce<)5bIpQh!Xrsbce&7Y>VpC&#zO?+~ic7B?6ewucEns$Dg z7Jix*ewr43nihVV7Jix*o+kpy6M^K3K=PD4PXv+|^YuYq%y$btFUV7)JT=M_f#ium z@^u=j9^K9pf#ium@}bK1d=BL$rFL(i9qs1AY=5_G5YD4`sq?IMn4^+pN`Q_$LObH>Zksz=kH_cp=X7j zzmKVJ4hubhA5-tM?fLtddYSPm=$Y4;dWX^T_c8Sj+n&FVsdxBSp1+UL=ErFBW6a;j z)Y|n7EqqKZTu-VcJLNC^2DM(>X>8Bm$JBbA?)m$eTCZ)--^bK$jh?@cF@GP6dHz18 z7U*=(-^bJfZF~MchBl6&jbmuznA(+UjY5twe;=bQjWK^8Lo>%{Ib*b(F}D#q;+uwGG?9FyiYm=I>+pdW`w|82%lTf5m`2t6wpHACpi0D@T=M z%-_d}F2;#2#uZ&G1mp6laR5B5T8zuTPH}WG9(V*C4_*WvU5pc5j0gTNfN{peam5u* zp8_3Mj1yOk6IYBASBw)^j1yOk6IYBYuF$WDD8`8>#u+QeWB-%%?}Cmf#uZT*{|0nK zF|LTh=qO@bJR2QFj1xbMi(#iYei$cy7>{{AI3D{K@ZWgP3bj)(9Vc=aCvq4k zau_Fa7+2(=HxN0Di^-*6f{|;25o$s$e?ci;d6*#9nqcIeK#eDeJSWiD2^4h#EuBC` zC(zFclyd^bn?UO(h?gd4X%j?E6STJpbZi0zn;`O>pmj~4FcWCY1gbJYTr@$;nP6O= zU|gPHT%KTDo1Rpz?S#XDZzmM0Ev1G2MqCIS zqZU~8EvTK?_NsnC?ZkieicmpgtI>VGpwZLl`B#Be-vXOX@OPWg4&W&#MoJ(zY!P2n{9u6D6nee z8wQ61-!LeI!y+6O;jjpYMK~Vs+7=CBBdMK~)VtVw(Ys?6f=b>ackQ%jw$;76k0ch)=i;xQ}q2Q z6mJT}n?muXP`oKAp5NdZ(-h24!TA(yPl;!}8Qq&g_omRjDRgfN-J3%9rkF8Jp?g#4 zUJ15Kuw8=f5^R@Xy9C=M*e=0#3ARhHU4rcrY?olW1luLpF2QyQwo9;Gg6$G)mteaD z+a=g8!FCC@OR!yn?GkL4V7mm{CD<;(b_upiuw8=f5^R@Xy9C=M*e=0#3ARhHU4rcr zY?olW1luLpF2QyQwo9;Gg6$G)mteaD+a=g8!FCC@OR!yn?GkL4V0&8nuoO&7AB5`H zM(-$_3I0y&LNCh~-NJHt^JRHNws<=$^l139*t7i_wpWs0R>WoeDfsu`EkDCPqL1%m`#+doR%~PRI>XC~XM~Dj zjBf)g{G=ilr~DT94yDXe_gU&bOWkLw`zxfsLi#JDze4&PapoKm<{S~`91-Rm3OPrF zIY(?cNAx&HlsHFxI7ehSM@%?J95_eRH%GiThqBF~X>+ln*q)1(K#vY{L~(P(Z*xR$ zbHr?O=-3?5+8lA(98uXEQQ50_@Em16N14x2=5v(!9A!R7na@$?bCmfUWj;rl&r#-c zl=&QGK1Z3)QRZ`$`5a|FN14x2=5wg=Im&#FGM}T&=P2_z%6yJ8pQFs@DDyeW{2I)^ z2J^2m*M3bS(Ngf5Mk3=ivGJNpZu>g;uSR_I8a{fBIpAv=Wt@Hz^t$nD8b_RR2Al-F zGW?oK>vXT~zNWFm_A2;u@E1mAL$5I#dQBsRQ_8{L6kepv7b){a%6ySBU!=?zDf30j ze33F=)EKH?QRa)3`66Y$NSQBE=8G|x`66Y$NSQB+XaCA&zDSubQs#@4`66Y$s4>pZ zxXc$R^F_*hkuqPT%ojDHEd`h9*O%$nm+9A+>DQO(*O%$nm+9A+)n@d(+Kkct`m$P! z(f#@|{rWQf`ZE3cGX458{rWQf`ZE3cGX46p+LeB*c4c(GzN~g-bick#zrHLz^qbwU zFVn9t)2}bnuP@WDFVn9tOVjiu{rWQf`m!|bY;c7UvJ?puG&R;?2 zuc&NJ@%-_M-e!D<@G3sNichcN)2sOODn7l6Pp{(BtN8RPKD~-huj13I`1C41y^2q- z;?t}6^eR5RichcN)2sOODn7l6Pp{(BtN8RPKD~-huj13I`1C41y^2q-(bKQd)34Ff zugPl*!8LmNHG29rdiphb`Zap`HG29rdiphb`Zap`HG29rdiphb`Zap`HG29rdiphb z`Zap`HG29rdiphb`Zap`HG29rdiphb`Zap`>oEK}48IO8>GKM`gNtJ zgX>Bc;*sm}NVn`O^7wT;a$PkYmVKS{e|5Uvpy%}l;{ma8J?7P?>#ROqXHDrkp1Lki z>230q@f5!u1>F;`%WF++-V7k&mm zUdNBu7wFozri(Kq^671bdj1aQqx6hx=2kIsp%p$U8JUq)O1lT*6(pm z7pdtYHC?2pi_~d~COR}x@H>l|i)zr4t{sz5_`!oaY(-iuf z;|+S*4SLxPYH@>Jc0;w$ujpkrDESR~*$qm5gI;!nUUq|Cc7tAagEHTs%s1#|H|S+I z=w&x)pEqfrH!1T?%6yYD-=xepDf3Ore3LTYq$S^^CEujXH!1T?%6yYD-=xepDf3Or ze3LTYq|7%d^G(WplQQ3=%r`0XP0D3YLL@H4$(Ay{IhSYo7DVx(ANq*!94SYo8mcqpEi7%7$lj}%Lc6ibX0ONET9?G}CQ7Jcm&eeD)~?H1m@ zMPIx1|C99o;c;E{x$n##TU*ce$W)etO$i7g6d{BVLLqg1eR6&J^f~m`ZJ~R@~b@_Y~qtHc60w#D*x2U1^xuNdP4zI0jmNsYZ|@%XSLa zAWP$sXEZx|?)!fD=Y77;tu3K}B{Z-^ zTU(;7Ez#DBTxpRjEpnwruC&ON7P-)Uq{u~QT26HeH~R_N7W_z%93x<>6m*JyMfQQ{g)x;n>RPgSC?EYVk%=qpRQE|t?)mgp-> z^pz$0%4PDIW%8M2@|k7wnPu{sW%8M2@|k7wnPu{sW%8M2@|m*suqR#SzF1lNQOxXO znfdmzM$`AH#P`L@Y0qwznRP5P>saQ#Seg4`W$ufWxi41MnRq{5nNvnlW$ufW)4nfO z=Dt`t?K!Tp&emIcWllNmdmLpk?|)q&_R5^HYQZI5nNyY~jb52kMw#WbSLT#eJ4W9Z zE2q6Or!1{{ORvl+b6>2S_DpP<`(ov^SLT#eo8FJ_i zeX%n4#mdatmZdK5$C*i)mQ@aR6Z=VlGIP0Qsm}2*<$hA29E=b@0(xb5S!#5-SLT$t zFIMKhSeX`D=Dt`t@XDMr_r=O;v$|gHiIQPZM+!re|Yh6~0^OlQj>6JNU zX0Xd@eU3ddT$bDT{Jk=#EVnUwWlovJ{Qw+47sj=ZM|l-*H?bJ~rqGp?v-cIfBg^R7m6dcI=;s+%(hZ>JRrtcV(6cLiXI!|B zxXH)jZ8m&!T(MW$tfb!tz5{FlJHaln8|(pl!4HFeQ|JnB3SCM6C-(di%F$ICUC~lj zXeleaDRf0|CegomQ|Jos(&3BeD!I%5Bz`~TepBcQZwg(}8?hXJkn$el4-xxKp(~kNiEjfp zft$fC;8yUrK-v`V0^&RD`tR>@6~D)?zfb%J#D7Rk`^wP1GPJJ@?JGn3;!U9|nNP4~ zAOHF!@twqfO8hC}PZR$c@t+g_1@W&q{68uA4EW!`yFuTDU*S!m`sRD;kJ9?)JLt8_ zRq~=LPNMIdyPS+jUpXiC>g5>EiSeA6En_?<#&cpkC&qJPy|d`5wl_a<%G!wWoH%7| z#CkiQf3@etDRUC1%t@RwCvnQ0#3^$Ur|da#%AOOa>^U)>6XQ8?%AOOa>^U)>6Z2N6 z7|)4Q_MDivLdAL;l4E;L%v+)2lszZLb7DLvPT6zflszX-*>mEQJtx+C`Hc3Qn70$h zcut(M=fo*{PMn$q?KyEO5889$l<#B4cutJx#3_4DjOWBDdrpk!#3_4DoU-S{DSJ+g z=fo*{PMosm#3_4DoU-S{cut(M=fo*{PR!ehV>~C;d-+^$&xunrpgku}`JQ`>=frqU zjOWBDdrpk!#CT4O=frqUjOWC7PK@Woyq!44bKamJn# zXY4sKo)hCaamJn#XY4sKo)hCaF`g4=>^X79o)c&6IWe9SXY4s~#-0;r>^ZUC!e_MS z#Ci*#kv4_r#F>v$V$X>)_MA9l&xtekoR~L~#TnWco)hCaF`g6SIWe9S<2f;JCyq1r zoH%38iFsdHoU!M`8GBBgvFF4Ydrr*TiDTYQ9P2H7F0tptdJCV?o)haWe8zi)Z{j&` z;yG{1NhVa{=Of<4N#4YB-o$g>#B<(M4NjyJJSV|(61Gh6oCMEF@SFtCN${Km&q?r{ z1kXwEoCMEF@SFtCN${Km&q?r{1kXwEoCMEF@SFtCN${Km&q?r{1kXwEoCMEF@SFtC zN${Km&q?r{1kXwEoCMEF@SFtCN${Km&q?r{1kXwEoCMEF@SFtCN${M6JSV|(67rk` z&q?r{1kXwEoCMEF@SFtCN${Km&q?r{1kXwEoCMEF@SFtCN${Km&q?r{1kXwEoCMEF z@SFtCNyu{&JSV|(5RkfYB)&^&#B=#H9V(g&k0i6a*t3mJVLz@UHBei zWt)oM2gS2^2n5}za1TZmPDo>26Y!ENXdDOdRvQ7Zy^?HR$r(U9YW3R z3$>y{xQ@7qcs=n=#Ci*{e$`uug?bCIP;Vg?>Mg`Vy@goV4fcS&;DLTo~37PBPAO@;r+;q9DmZ=%Zs$VyvVWMLL8*zMf%lmAr|T_ z#KLzG>n+5J-%YHy5G&SOh=sRMqPGw$elKwcvED+g61|03_v-*TZwN2H-VeME#Ox0w?MAl?+ewQKT65(68|3Y?-Tz4@gEX@45Z!3i~KLzoxI5L zpRna8i2H~?Nqi^qpAvtHm{ut-@-@Pt-$JbTR~+h1Uy45i{x?u>Ay$drLM+rJleQNL^%g0i##};sQIPr#V_I`N!dt-mz(e3s@GPhigtqyy&N&q+|PeopMN{{k%>&q>uG5xEs`rv`U6R z%}6VLoa26xJ&beo!{8CnoY%>vjZcAkkB8zD;FrKJgHMD11nPMxZ8HVx`D?{r0iOfy z(sjxYjdtleT)Iv!?em%DC@&GeOstt_mA^v#P4@5__$^R#&ieIV!0&;&TcMH}@B%ms z{sjCtjyMO-gO@?OZXK>$hwIkix^?nf?M+T=Yyxir?XGpWYn|NHvEHjG)Yp)O`f{ky zPFsi5*5R~u%JE!cr>*n*-i5cZ3;zK7x)->m~+sb zCjF{s--Oh1+I?l6=C@r=U1)yW@xQVS%xiwz+y5N=1^7#jrI~z{ufRYICPwv#;(;Ed zPCbaWQ4gZCQs1Hd(09}YcN1^t*B#)4wX6DdC*{sq>H_B~b(#q`{vCJ>k~3ZZ-OI?b7Td-vLPfnBan^XD$neJJ5|qwgsQwaP`PXKjS; z4eN9t!MKi+w-Wz4sAu$4elz9z8nxng`byOsI(`?izDBM1-NgDDwcxg>ew{R=?Ti|bl9|eC8`~whQ zQcvgY_0~WHN;Uv<;Fg)9W}&JL*>Sf?Wmzf+&+pOHPndPXh#h-;x^h*LmV~Kh}&D90PU!u z@?N7IHPndP=(ZN(sG;&+$9B|EBW|M|HN;Uv95uvILmV~4QNxrSHB{c~`=FHPmR@Xh#h-f;QSwLmV~4Q9~Rx z#8E>WHN;Uvjg+;Yv>i3XQ9~Rx#8E>WHN;Uv95uvILmV~4Q9~Rx#8E>WHPn}dR0}w2 zh@*x$YKWtTIBJNahB#`7qlRfaYN)r28ttf|-YGgGw4;VNYUuZfDz>ABX*+6&qlRfa zYN+>!8ttfI+Kw8g?WiG+8m8^2VcL!wrtPSq@7)XSs3DFT;;12x8sexSjvC^qq3#%Z zOFL?aqlRfaYN&hSK9(Id#8E@ds;U)e9!rR$hB#`7qlP$Yh@*x$YKWtTfgLpr?5JU2 zM-6e*FtDSBIBJNahB#`ddy6hdr8sJcqlP$Yh@*x$YKWtTIBJNahB#`7qlP$Yh@*x$ zYKWtTIBJNahB#`7qlP$Yh@*zON2znrJxZe;HN;UvjW2W+IBJNahB#`dxek}xQA5pj zIJTpP8eh1?jv8uw;n^a~&?RqlOw;811N`W;TrY5{??;s3DFT;;12x8ftXlE$yfwjvC^q zA&wg2s3DFT;;12x8sexSjv8j{sG-088q}ve&ZeHW54c6`s8TH6Qz)koCY6~_;FZ^0n(F1E>myD1q0 zhrtnWKX}|n*C@t&cosYj>K#fd@k~p-o`~@g^$sQB^OV0p`HLL!tCVvs!Pkjj244Zc z&o=Hs>a~``ds_sH;G6u))#;fRZR6D!LTBCeUV|a@Y(~9CQaT@vq#XZe@OQ!A2mcWK z82EAUkHJrXo`0y<{GRdCAnaveFY|wx!_5B${@>t#2mc57m*6(e=RR-;`1d-Wh}>R$UP!*4~@*V&xp}nMD7uhdqm_O5xGZ1?h%oD zMC2Y3xkp6q5s`aD>R z$UP!*kBHnOBKL^MJtA_Ch}>R$UP!*kBHnO zBKL^MJtA_Ch}>R$UP!*kBHnOBKL^MJtA_C zh}>R$UP!*kBHnOBKL^MJ@hRd>xA4RBKL^M zJtA_Ch}>R$UP!*kBHnOBKL^MJtA_Ch}>R$UP!*kBHnOBKL^MJtA_Ch}>R$UP!*kBHnOBKL^MJtA_Ch}>R$UP!*kBHnOBKL^MJtA_Ch}>R z$UP!*kBHnOBKL^MJtA_Ch}>R$UP!*kBHnO zBKL^MJtA_Ch}>R$UP!*kBHnOBKL^MJtA_C zh}>R$UP!*kBHnOBKL^MJtA_Ch}2gRJg^8l8J&btly5+#{QE z?vYJ7_sFK4dt_72J+dk19$DQ5@HWmpvYPofI`_zudt^0x@7TFVHswA#OYV^+_sEia zWYf+)vYJuU7b(a+vg96Fa*r&zM>g%;BTMd)CHKgZdt}Kyvg96Fa*r&zN0!_pOYV^+ z_sFK5dt}qjJ+f)%9@(^WkF4e`eO%`rS}Aw)v7*! zM>cTokqw-CWCQ0O*}%C+mfRyt?vd5nQSZUIM>gQ<$UU;;9$9jaEV)OP+#^fwktO%Y zl6z!z7gBr3IQPhAoO@(5&ONdj=N?(j@Ee_bWHZh^vg96Fa*wR$@Ll5EBTMd)CHKf? zoO@(5&ONdj=N{RNbB}DsxkonR+#{QD?vd3@vc7a8Jw73d*ZUpnn~Z-C{sZ{`^6UR1 z{v5HshoWr`fR9l=N<3!Nb?H2HT}G`N4Eprcz+;RAi#W$R08RkO;qs#%yA zX^(wD=xYf))7Z!TwLb1o^+})Fv-D~7-Kak4)9Cw9ecXZSlRh2$u2Y}%Y4n|@KIzkF z)%BseK2+C->OSeGGlEZwXQ7U6)br-Sol@6?(D#+@l)7ew-p`%NYK&T?Beb^fOn;X6 zKGox$sQ1ovKjj0ITgi8(hmERb?M=08w6^~u^`CWr>Mv5C06&@fjN&`NKLtMpzGzIh zd7E@Q_#2c|!8eV;tu7Bf41OB?Gh^nn{x$P=#Qz|?OGo^S@Dreqco#>!E9E2JmGTkq zO8JO)>4?U5&_}#WYa5L|;$1qT@x$P!!9O!{#JhAv$NwO_8;0+O;k#k@ZWz7?hVOyl zd*t(1gL{<4%?R}t3!zpF3QvF&;7RaVew`%tJ(qjZ&lA50ehqwyZC(MjqEFlW09-Os z3-?e9_XOL$y)rbH-w!@O$u8m?_&6m`66-A%+H%sz^?MbBdW(hd4BI?U%$fMT3MzMN zx<|R3QST@aexF!t2o=wQKLLHO{GQ+qwkd%(D5-!|@J*xNs~`-)22d*oRid?mLao~o zYGt7C?UdZCm~Vawt>?c~K0G7*0k~v@6TaT1cn2llF=}tdn}zqP9w&s6QT3$~)s)e9 zFz;3WYkY~4AA@#@dsX8qSB)DV0C$PKd)1#BkF$+y`ChT=ZG4yWUUBPR^#&xN>-S#u zlExR=hGU6IZ~vxI{oSbWE#L-k$vw(#I_EvXHl4H3&jblQFR?BC6YY7MpXCwiDP5uS zgl&GxEZC-V*7iDQqx+6+eilaP+0kvmBj6LD=NY!qvu_K&!hfFw&+@B#_HBO3OsEyA z!f#OSwHe#|yopdx=?bq9{~Ro{2hTQd3u4d?xh+%YUo-WfXBD>5r*ESl|E!;%3O=js z$Y?cwR(X+e&Zw-$I0)_rhrnTQ1l$ik3!VnQ3Vt1Y8GHq_az3jJ#JC6+!NjOhhH(w( zKH{@FPvcF(?W&Rcgzne2OGTr?qoC)JwsX$gr6rfY1X@emxr*(oBgLv6ZK>KZ-b={? z-cotmgwXx<_P~AI_FxP=26{ElcI9R+cRscqrEMo4+fF{VT}tyd=54!_=GY8uS6g;$ z9=0nVbL=%X+oeFG+1T#)X$$AUHz_w8+cO!k!AJBHf5NvAo0IKor`iKr-2pQ@U}lHL zsx!e3jZ%%Xpmn;-i(CF1AzW}Y_9k8?mmUd_~s$Ws^4#uH7G!Au% zRlNgM@6edk@m_ErXr1rS$kb?^@6h{y6Tr-jRyVbsvlkTqpN;&)vvcm z>9}$*Z)08cqpN;&)sL?F(N#aX>PJ`o=&B!G^`onPbk&cp`q5QCy6Q(){phM6UG>ZB zd@Sp#A6@m!_wG|{UG<}@e%e|;y6Q()128iHGXv;q09_5Bs{#CQ09_5Bs{wR1fUXA6 z)d0F0z#9i(X#kc6(A5CC8bDVA=xP964WO$5bTxpk1~k_(6Aa*=1L$f1T@9eC0dzHh zmkyw-0dzGW-bVE=>uLa94d9{!=xP964QTemd$z6yG~;2kt_IN60J<7LR|Dv309_5B zs{wR1fUXA6)c}qZ3||fYO59!z{)YH(i0>zRxu5>@etOUQ$tdoZTCN87OD#rc z2=|jA+^_%61o!K|GrVioXnP&S zxZT^+Q$L{WLfb35@HQ7Hp9Oznlp7n}|307$L0i(NKcL*ev3vFhrI4#a=fDrrOFk%7 zIQ|LfUh+Yy!X=l$Wuuf}bhi9p@PxNfZ91L;-2*_j0uQHZ}RxhL?KC56h4t_ly!Np?vU z_X#J6C&91qtDa|6xmVckN`I4BZ*x`bmbFV7aO@s=7tXm0x7?+xc8UAnU4EOZ(7o_3 z%^`blOZ-c3a}E4mOPz_7V|0(aOIew=k&1LaQjzwr49z7w`E@t3`{iAladNqP=Utk2 za%?Z%6^sz?2i;Te^4na6dYh}zYTt#s?$S(@WB1*==zVt4@9a{);}X5iRrm_=tHhos z+$GidteoNOVitOrROhq(324{dr99Akw)gH*Ht5)XwM(;7j_t#{=(Bb)|GW$D-NpR# zE*yB5w5MZ9dpee~MEwgN-h~72k`Ddr&HD8rTKz+``iF4Hhj7S;aL9*fn-9@8AHo|S z!WAFF@gBnKa;PGQDsreIhbnTYB8Mt+@`uqNr(F7~(5lFxiX5uQ>9`Xru_|(?B8Mt+ zs3M0da;PGQDsreIhbnTYB8Mt+e#dW+LlrqxkwXq>=9ID8niX5uQp^6-;$f>uT)_$yt z9ID8niX5uQp^6-;$k7+)P(=<^Hn6RPivXcoR6%V6|-RxmEd)Un$cC&}w z>|r;1*v%exvxnX6VK;l&%^v*q*onYjj}@|qJ?vo*d(gdKm$L_Dud0zf>|qak*ux%% z*uxNe7@|iTqDLE|M;oF?8=^-Wl1gWSA$qhSzh_dhd$b{Xv>|%5A$qhSdbA;Byxzt= z+K|r8=pJoI=O*ObhB&t&dbA;(q02oVGDMFyM2|K^k2XY)Hbjp$M2|KUxJMhJM;oF? z8=^-WqDLE|M;oF?8=^-Wl8SV;V!-?VKCyeWA$qhSdbA;Wv>|%5A$qhSdbA;Wv>|%5 zA?3sR7d_e#J=zdG+7Lb35Ix$E7}inf(T3>JhQzks<3o?OmmX~|J=$J+w7v9bd+E{k z(xdIAN83w}wwE4lFFo2`dbGXtXnX0=_R^#6rAOOKkG7W{Z7)6AUbPn;mmX~|J=$J+ zw7v9bd+E{k(xdIAN83w}wwE4lFFo2Y3K>Qr!zg4Jg$$#RVH7fqLWWVuFbWw)A;TzS z7=;X@kYN-uj6#M{$S?{SMj^u}WEh1EqmW?~GK@loQOGa~8Ac()C}bFg45N@?6f%rL zhEd2c3K>Qr!zg4Jg$$#RVH7fqLWWVuFbWw)A;aW6!zg4Jg$$#RVH7fqLWWVuFbWw) zA;TzS7=;X@kYN-uj6#M{$S?{SMj^u}WEh3)Lm~T6$UYRZ4~6VQA^T9sJ`}PKh3rEi z`%uU}6tWM6>_Z{@P{=+MvJZvqLm~T6$UYRZ4~6VQA^T9sJ`}PKh3rEi`%uU}6tWM6 z>_Z{@Pzc|E4)_LiFoHrxP{;@h89^ZBmBPe79g^Zw( z5fn0lLPk&sUz!g1(zI~9TIC1|89^ZBmBPe79g^Zw( z5fn0lLPk)?2nrcNAtNYc1ci*CkP#FzfBslegYTER{ObbfS-bt}i;bR7*w3uperE0VOII%WHSi|k=ln+W;B$T>dhj`Z{T#o3 zo;LD%+Q{co{^wD?zr;Ne_)FYE>2OAP6!cv2qf(UdB}#q_dS>rY?Lp<*gVA%vk4iJs zLeCXHDxG*6&$K)$wfI-h6+bG?_*c&rKPt7jo|Z99MGBTUpi-_=ZX(#e#7W-&;gyZ%RN_oKy_#I?AZb3T}F?I4yXoQ?osoB zz$1RQpY$3QRyi4GKxQs;?JYh#VGzfia(Fy&!g}^D*m+}_#efeNAc%T{CO0A9)VmCYQ!a0`xq`UhD(h3 z9cU`?SanQaByfD5_**UAMUMD}6z5>3%mj6!tbN>7Pah_Kx`2{6j<2@#~^nQxO z*V(2-d;_c)gTQ+WJeNKetOD!(FS)DnZtpGlA8hG69bv_-aS;jQhbL{?QOk+LA%fyL~qBof7UwVU?vCieR zmoc?^|LR_2Ol{w>@0E|y>#+?WOL_OH^FOFUO|kn#9I zM&btlt%t}Z4#@)*%l%X?_cOYOJwy+Ch#vNk zdRUjAU`vnb4$;FNQV;9@7Qp8zcMp3=S(*3nRbuzEhsZh((c2!9qP&g!+(YCThsdlB zsW!D|@~cCtQ^y-X_rhP`8o$6beu1<70%!XLH1Gv9z?bWT$H__fe!XJnPX2!Vw9r@W zuh>rrebs!+Uid##|3UbmJe=>^3*FxNuD#H0obTETol`vy4}9HTv0LKfu<^Kh2gmNI z{iS>3%RVms_2X)Hj@@fNE(ZLoTL)jg7rI6GtM@ABiulsKVr%$u@{lK_%&Wl@(xh<~ zd>!-*{1Z~9@fSwHm3+jDwivJEg1^yH0dH5&j(Voz`IsPel4fJfl6H=qm z^Q%utlg2FQobUYqddPg46| z^cMkwar(Y-YIB@EZk*a2r#8o_&2egToZ1{GD;}pd$EnS6Jbawm9LKlEsm*b`dYsxE zr#8pQlgFveacXm%+8n1g$EnS6YIB_09H%zNsm*a}bDY{7$K}SU&2egToZ1|RpK)q) zoZ380Z62mJ4^x|m4^x|msm&wQ#Sv=Z2(@s8@yHRz zfJbnWBk+HOG2IcEKLYbdVEzcqAA$KJFnrwptD1LqvKR=3}9~J-J<`n2z^rKwGQO^G;YB`Edj&kNl@%f|p z{84=VC_aCbGe3&kAI0sD;`2xG`D5^Z4E~S7|1tPK2LH!6=VS1H4E~S7|1tPK2LH$4 z{}}uqga2dje+>SQ!T&MN{22TnsJu{|Wd%0skksmJ{gz1pJ>s z|0m%81pJ?X{}br{1pJ?X{}b@fx8?)BGA}g$C(u9NmsjjO=LGzpK>sJ;pRddZC(!>1 z^nU{WPr(0|=moySJj0i`qAzhpUuLZLWyX46W(4^@^{{i9#8oT z??#WOo=$r_(Jf3=*@sz*k?%3lgzUMCVc*@^%cZu`frx{N@9e6zD zue!Tr0`z!_ueu98p5m+SLXW5Ts=LtRsizrF@eOyy9#8oj?*6aGQ~rj#V~?l&4R^;L zPx%|}jy<08H{AU%kEi?%cOyz*JoPl=DSyM=?0G!pZ@Bwk9#8QNcOmu2c#5yLtHk3e zzTPhMc#5yL3q79V>+M31r~IvU9g*=A-)dJ}?>#e~^0(TxJ>w~VtKG44Ie)9&=<$@l z)$aXxJjJ)#g&t2m&3MY+YIp4Ml)u$J8cfjcCTMpPw7UsLRTE@86O5`R$ayBD_N&2! z)NXX{Iw7qZJ*v|Ca&!)Q^9^Vn>M2t1A01AR5lt}8njkOIJv9GUDl$4RnviCU&Wk2g zvqq1zCd9B~=Ry*F5_Ri zJn(GiNoG4wGTV7l*X1oe&v`Pi$DU*z*U7*$oG0n~PICSyIrEd8^GVM3BD;Fd{(tEBRmRvock=Z$Imj#c$QJdv&;`aD?arrBaUYoaXibM@Ux6No@LzeEVI6+ z=u=M7r<`Jz?3Auo-}7Mp@Ko9}U8i*IF7f=~DdrDP(fgdD_c_J<;VE6Oe%19F?I)*n zrH(z?I;AT$+A&V)8XddUpJM*-6!V9tm_IzFYuB&Lhn%AQo)Ql(@v5g&;^As=n*8K6 zJ=bY^uG8cvr>UdUc=c%<_%u1mX>yX&Br*XW~c-?7g znz6FFCgl%`IrB;N$fJtA0%uZv zvExb5I+^5(CYjru)OG2<>V>_{w?NM!Ps(BZU(aez(hEiZ5V@yzq2dSRp2u}so(CspGDY}EH1gl^rF>X#i~0o^Z8 zs$X`AzV9IXIs3Uv$uEe1$@wgSMaoOyGJCs0TrtWIwSW1caTVxQLzD7D~0*V})dJ^N|IN%hpmC-~Jp^`v@gm)JQcalA?O(T=Ho&3QWZoadxG+^3;*?>h*c z(M_tSFjxOVjDDnfm!lc=+Wr?hQLpV--**tY{Z29qI;p!bs&Vz*{?{)-k60(w?|4hk zg-)vXaqO9&N%cXFJr_DD2k`m(NvKIVfYH7Aq`&VV48S^Xi5pC+#p%E5zl?U^N%dmJ zwQTA8JCo|ojq7|}{=S3IGfR`|S zh4PFG@{9=bj0o~_p@|@mujX-~JY#`;`W)pR3*;FK}^JM;cGXK14WKWRCPx7h}ZBL$`$4~O)`FZmEJb8Ye zJU>sKpC`}HE6>-N(97gikKTjlQS+)z$99jr>eR8_Bd?luZ1>31`{Y&2E^(fpC(qB5 z=jX}u^W^q^&cN?3R}%eMDync|CXU5`A4l z=sqG(KA$I_&(nwIrCx7uPsmHdj_nC~DcN!2f04=O$>j5D?=Fe_tJ=HcEU~lqJiTq6 z>^)ERo+o?H)86xH1^$<3!18Jfj-9>d$=<)B7BLZgMJ+-oJzo_%Gx>^Iu}}(8xfEjb zO0chpE1`~J^y;YsZK^<J07Z3^QP7 zXf9P+MSR*;Vc=#S?S*;9`B!(=8YcjpOs3D9`B!( zK8+q{oz=M+J@!9Kws4kg;Vjw0S)HNE$r;X)Go0mY&vLeB$sEp-IXq7-JkLDj^KA1x z+q}S-@dd_=FEA2(fsx>gZ2uzLzsUA4vi(=t{;O>NRkr^s+fS=}I+#|ukg@G_`lwi% z*4)A#q3@+mGs4yPgemuvIMZ;YueMUM>=Nx$d(b|OzMrdA{KPrXE2gHYab>CAGj*;0 zO+A9#7xap$X=;C3v(w&#`JC1~gJZKgt@#AU=60HK>onumX~wP7nqly-=5|`6Y{f7z zt+BRa&oWIj;+{qcFX`GxgO_yeLay#5jlX6T`?_AzC|juO(yzKMqZRuSXZ}*)apFrF z1sJW^mvlbH6)-mH=o3PZJzwI8FN@Wg;AQ3tUS_V~WwGHBKcDroco6E$jc*ZtgIfCr zwe}5a?HknEE9~bL_VWt+d4>JF!hT+1Kd-Q#SJ=<1?B`YX^D6s!mHnKfrJtjXpQDYR zQyZTN&T*IFoN8Gyt@|8z8P3tJ&(W^W(XP+YuFuh~&(W^W(W1}MqR(-c;hgHx`}rE^ z`J!`-jLtD8I>%jxbE;F9d(3ihv6~`y77wnp*cv z@S0k;(RX=XQ|mVRT3%D@Hu^5lYiiv_-{pBtt=qU4^z$sQsdXEDm+dvRZlkZ_HR;f3 zFM16ZdW|!GO)cFe*FfLpc}*?d=rey!E!~&}eV6AoweFeVJgx6Mt?#^A?q`DY)a-d` z;XJMHyp%bua-aWsDN`|R?L2MmyvE&ERpJ(RUV6|r!9$efh#w|?1U$iit+(^iu=nHD z6z8R6@4;&-&P&gZefQx!ZSXu-eV#UWo@+mk8=r@P^SJSOcsNhnJP#Y^X^H2#_Vdhl zomYKnpUirlSFJhTDEt=J^(~I_E%yH{_V6wK`)%Cp+ql`csqt@94yr3G~BlP-GZe?gH)Zg6hlV zZg&@Ww)XER4;<*es0A!q_Z~&BE9$jLpK>ER4;<*es0A z!q_Z~&BE9$jLpK>ER6ja#(oTAKZda%!`SPTzfSqt#uWN5`Q#ic?dRw(=IEj3=%MCVi#r!Q={=}+jGiH%qtBY7 z&zcLodTLJf;$L4RcCRrPoCCiNdJH&6uQ8`g-oM)C=aju0y@Gd+mG*P2w4Y<8{TwUp z=U8b!r~1-1tn!^>mG2xLHHSORDeLyH9%Ig_zKn0D#N*A2)Xqg}=OS~z7o}L0D|0Y< z&i10z>)3Pk7nMZ_smF`d*G1+eFG`s%_gwwOz*)gX>Cmxro{Q3+(es2Cr8mb{h|9z) zU<^9jxyW4oMP}zNN_8&rT>V8U?P@TOLgrD(JPMgdA@e9?9)-+nygU=kqmX$NGM~0W z=26Hz3YkYC^C)BC}bXm%%hNb6f%!O=26Hz z3YkYC^C)BG5LN1|@ODNOu8;>_ArHJl9(aX3@Cte0 z74pC<8s%ww^1v(Pfmg@_uW%JtIR7hw^S~?QKUX;OE98M!$OErv#OGg~2VUXKuaE~` zArHKwQJ%`l1K*&9zCjCpgI4nft>z6{#~ZYcH)sWK&nP+p3b~F#uA`9a zDC9Z{xsF1vqmb(;nP+p3b~F#uA`9aDC9Z{xsF1v zqmb(;^DWQ-O3MrwG5(+7ykP-?hp^y>^DWQ-O3MrwG5(+7ykP-?hp^y>^ zDWQ-O3MrwG5(+7ykP-?hp^y>^DWQ-O3MrwG5(+7ykP-?hp^y>^DWQ-O3MrwG5(+7y zkP-?hp^y>^DWQ-O3MrwG5(+7ykP-?hp^y>^DWQ-O3MrwG5(+7ykP-?hp^y>^DWQ-O z3MrwGWfZcELY7g;G74EnA()mb5+EN*>OFUb6BiK#sIl~*ueqHXF!yC$h z9XoHlp-kAZ-+Xd|9P)@}Y^q&jgW)%mQPE#Hvpe4bt(azm;!dN%TgvS{zwbCNfdOFMQ(dP5ntW9OweR9`}6 z)cP0M=?&%8jy+d-L)z1^q&*!=*|q*f)_Q}i^@eolUvJj0WmU-qly?+#Hb=h z75?t?o}k96PJjJbF*6u7v{6GFHMCJf8#QJ&YSPAxw)7M0H7R65cwT-|V^wEOXX5>M zRcDQ!w3hxCw)d*eTH34fYH81z*L1et(yKaaX|K?$Nm2fnS9R934#a3TuBk8fQM{_N zCZ)N=GlaFYSM1cJI-^&0)>ze9Qy=Xuy{fa8_NvZW`VF@Cs?J*4t2%2^srTcRel@Ao zu~&80#GcWsI%`@PV)Uxcn%0Ln_NvYrt2%3}>a4M<(_hNgztD3{de+`p)mdYZ`@%97k?XN+v>a6L$zj4rKE9HAX4-r2MdZwtRR^aj>Vz26~F>6#)D{wqQ zxmR`8)E10h)maO?sbamICH46s(V%zN;v&RXDmIyL63YHDlVgI9Id z)Ycq(wzkHq&Km8mCf%AVuj;I66^ii(Aex~i)@X?}T4GHt(fjdCZ;e%*HCA=jSk+l$ zRcDQvv6|Ycw_IdPuj;HZOIA}mb?iIWHRWc$7O(28DK|5ERcB4BP>f#HStC!Yk*C#Y z*EO|k?SXb(Q@eJ&mMy)ivql@QsU_;VSk+l$&aI}F?k&Blv!?d$*ttPXt#wbv-(DXT z>YkBM8AT?gwl*!)Ouq03#Q#dHXEapuI;fQxinS6$sAn`XDX;1j>KP5;Dp1d8DAsB; z;oaU+`t+815?QD<8$zww5NgeaP-`}XTC*Y4nhl|z(GY5#hEUIF2$w)TqmfC84Wphr z7OwM_x>Cn_MnibBN-|tshO5hPbs0bTmC4wVgokSrLcK{ts3*UK6O?G3r(&%l5XzT? z@+G0NT%q2iA=Jt=q1FltmGudg^$Gu(?d492wenM_m7hYb{1i%KLaqE1Y7L?AU-_3- zek#_JUqU_kCDiIcp&Uu5^`AmHl2GeEh4Y}+e=64cPoca>s3*UKKj*(%|EX9{3<>q* zm++UwT2-jHNUSHn6qktgNVkZ zbEsPOmIIXN$uGrv@=K^Ezl3rjp`QE_%6Wu(@=GY^5$ee=p;m+n_2idO&LfoP2=(Nb zP%A=(dXt7wPkssY1V8d1esBPx{t2=(NbQ2ry- zlV3uuDi_LagnE;PP;MiX+X%I4RH#vaP@@2$Mgc;N0)%oKA=;4JcyC$>EYy=S zLumI{jZ3WdIt0abgVngfYJ6a|@&}h_RkrYwW7@)MueDSBpj>D*YF~}cSEKONXnQrP zUX7|(t7r6ot;5wQaJ70p$1i|dYo}Oim4$keOZW}SwboAYtHc^*E4C_DqleWfVYO;s z<<#bCjq&v>b+=l5!A!>At-dO>x7VpIjP~|AU6IiaU#A)o;@)-mb{)R$Z%n(~zFjBg zjrQ$2e7jC9#j);_3U!B6Xb<<7qmA}(e>vKy`(GJybeDPsf&RI(86<75F}{#}>iiwQ zEIo(LC4}FnL}O>gW;=xK5Vk|l6saUJs%071fNo78R}{j3=(}KMl*yu z6SX6kYXy!_Yp8^IumI|7(JHZ@uhE>Lw|8&8M)huVy{}QdJ9fRV3CNm3;qOjFT4h?UZeR#$L>SdX#UXnCTLZx(JZ1$aNsqXOLS}>UgH@>p_yOfc}1c5 zU!xgCou^vsbS4Y`S@_SAV`SkltMSWBCJU4PmYHKSnbr70F??p>GfV&I?~dtL_{qYC zzbxhwGvKd@8GY6Mf|${LP*(Y>QR^p#G3YDGaxGb|g71i_M7gNY=iI*uXV5pqYlinrT2Y z4QQqT%`~8y26$*dGYzoOfMy!tqyfz|Xoguw53HF6SZY8s4RFSzZU-2!v9)0TnmS5(ac(yTnm$HVR9{+Sqq+*22SD z7+A}-ujQ)Oa=mN0uC-`pEt*-2X4Y~=Yq^%ST*X?Qzutd`X4Z1fZ=tt+i&y<+-on+r zh3on?UCY(XujyKZIzyvYSY;Zy#zwBO5sfvXu|_o3h{hVxSR)#1L}QI;tPzbhqOnH! zX@s9fm}!KWMwn@YlSVjcL}QI;tPzbhqOnFa)`-R$;jIykHNsva8f%2ZMl{xl#v0LB zBdj)}u|~LUL}QIG+=#{+;kglwHNtiy8f%2}Ml{xl#v0LBBN}U@E*jBTBN}T&V~uF6 zks4`4V~x~HBN}U@b{f%GBel?o#u}-MMl{w)eXWE4b@0Cq4%flqIyANpCfC8_I+$FC z#@4~-I`~`%SLp15o&bf(mZbCCnXr>9xG@+R$G}DA;n$S!WnrT8aO=zZx>uutCo4C>@uC$3O zZQ>f6xW*7sn$S!WY&4;nCOBzAGfilw3C%RYQWKhKf~zJp z(*$EpXr>9?n$S!W>@}g8COB+DGfilw3C%R2nI^bxLNiThrU}h7p_wKaZbCCn@Z5xE znqa#L%`~BzCN$H8W}47U6a24-|Ml>{9uC*T;d(T)9wyhrtSg<{H%wK_3*GB2G(=!>$&RnT=+ zqM69tq!Eo!3b`sgsb1zLDa7dP@g~oX3O$CpNj0u*RLjO3_&D24f_kPv<$9(-=oyBa zR7b`OlsFr|Ni|};>~gVf425qMdq$66-YWL43ccl9#hX!U8Z&PdSNc_48K0o!EchCD z1uTPFuc&RbUNQ4lF<`6*osGPey4#>5PUsyU9w%;4d(m?mYA;5QTsFYN2Jzq$^RR)O ze1qDEOMXm=$4478 z@&#g!F6F!2d~T51jarE+^mucFST&l}4brm^Za2W~2GqL&-ENR#wP)4-OlBjB-H2j0 zqS%cnb|Z@2h+;RQ*o`Q5BZ}RKVmG4LjVN{_irt7}H=@{$D0U-?-H2j0qS%cnb|Z@2 zh+;RQ*o`Q5BZ}RKVmG4LjVN{_irt7}-^Tg8jXl4OJ->~8zK#FBoqqQ1^s{fLwZ5IY zzFAj#HFLABRH*Yex}SZA%I_0u22yy7IC)3veW1QHs`x|1w}Sf8s7myuQQ>BAi{>=m z;V+E}{}KEg_<2w(>Q#OK90m1NVwHGo`;L_B@g1r2;J3lo!JmQ`L96Q>X)E>}{?e#$ z9k?FUSBX_}3wWE)$6p#1ZU#TXHkyf5iDqJj9yPziUm6wai2$MQx(ff?Tl!0*!rujd zAN)h`W8lZZKL$SmeiHms@YCS0_Os3V&)f%U-d^$F>nQJp|98UwJK_JG@ZSvo&G6q0 z|IP5<>@U4$n&H3MUwTz+{+r>y8UCA7=D!*Ko8iAXW&WG}rB|W(Z-)P7f9X}R`EQ2* zX83Q0|K^nWZ%=9KwwPMQDal=*Ll|7Q4ahW}=N=~dy8UCB$zZw3UGv>e9UwRdq|K^POZ_b$i=8XAo&Y1sZf9X|d z{+l!Azd2+6o8iCNUwTz+{@(@v?}Gn#!T-D9zXkqV;J*d_Tj0M1{#)R`1^!#$zXkqV z;J*d_Tj0M1{#)R`1^!#$zXkqV;J*d_Tj0M1{#)R`1^!#$zXkqV;J*d_Tj0M1{#)R` z1^!#$zXkqV;J*d_Tj0M1{#)R`1^!#$zXkqV;J*d_Tj0M1{#)R`1^!#$zXkqV;J*d_ zTj0M1{#)R`1^!#$zXkqV;J*d_Tj2lQ@c(Z3e>eQU8~$72zZL#l;lCCBTj9SI{#)U{ z75-b{zZL#l;lCCBTj9SI{#)U{75-b{zZL#l;lCCBTj9SI{#)U{75-b{zZL#l;lCCB zTj9SI{#)U{75-b{zZL#l;lCCBTj9SI{#)U{75-b{zZL#l;lCCBTj9SI{#)U{75-b{ zzZL#l;lCCBTj9SI{#)U{75-b{zZL#l;lCCB-vj^ef&cfw|9jxS4gTBUzYYG|;J*$2 z+u*+q{@dWc4gTBUzYYG|;J*$2+u*+q{@dWc4gTBUzYYG|;J*$2+u*+q{@dWc4gTBU zzYYG|;J*$2+u*+q{@dWc4gTBUzYYG|;J*$2+u*+q{@dWc4gTBUzYYG|;J*$2+u*+q z{@dWc4gTBUzYYG|;J*$2+u*+q{@dWc4gTBUzYYG|;Qto*zXkqpf&W|Jza9SD;lCaJ z+u^?*{@dZd9sb+lza9SD;lCaJ+u^?*{@dZd9sb+lza9SD;lCaJ+u^?*{@dZd9sb+l zza9SD;lCaJ+u^?*{@dZd9sb+lza9SD;lCaJ+u^?*{@dZd9sb+lza9SD;lCaJ+u^?* z{@dZd9sb+lza9SD;lCaJ+u^?*{@dZd9sb+lza9SD;lCaJ+u{Gc@c&-;e=q#M7ydio zzXSd|;J*X@JK(c z|9<#?Km5NR{=4A63;w&{zYG4m;J*w0yWqbI{=4A63;w&{zYG4m;J*w0yWqbI{=4A6 z3;w&{zYG4m;J*w0yWqbI{=4A63;w&{zYG4m;J*w0yWqbI{=4A63;w&{zYG4m;J*w0 zyWqbI{=4A63;w&{zYG4m;J*w0yWqbI{=4A63;w&{zYG4m;J*w0yWqbI{=4A63;w&{ zzYG390RJC={|~_b2jIUO{=4D78~(fDzZ?F$;lCUHyWzhZ{=4D78~(fDzZ?F$;lCUH zyWzhZ{=4D78~(fDzZ?F$;lCUHyWzhZ{=4D78~(fDzZ?F$;lCUHyWzhZ{=4D78~(fD zzZ?F$;lCUHyWzhZ{=4D78~(fDzZ?F$;lCUHyWzhZ{=4D78~(fDzZ?F$;lCUHyWzhZ z{=4D78~(fD|AX-VLHPe5{C^Psd*HtZ{(IoR2mX8DzX$$%;J*j{d*HtZ{(IoR2mX8D zzX$$%;J*j{d*HtZ{(IoR2mX8DzX$$%;J*j{d*HtZ{(IoR2mX8DzX$$%;J*j{d*HtZ z{(IoR2mX8DzX$$%;J*j{d*HtZ{(IoR2mX8DzX$$%;J*j{d*HtZ{(IoR2mX8DzX$$% z;J*j{d*HtZ{(IoR2mU_<{~v{;lCIDd*Qzq z{(IrS7yf(UzZd>{;lCIDd*Qzq{(IrS7yf(UzZd>{;lCIDd*Qzq{(IrS7yf(UzZd>{ z;lCIDd*Qzq{(IrS7yf(UzZd>{;lCIDd*Qzq{(IrS7yf(UzZd>{;lCIDd*Qzq{(IrS z7yf(UzZd>{;lCIDd*Qzq{(Is7R`|aa{%?io+;pW{$O) zV{PVGn>p5IjpyU;+d0voQHJIA`6W8KcNZs%CHbFAAr*8k42wsNek9BV7b z+RCxEa;&W!Yb(dv%CWX`tgRetE63W(v9@xotsHAB$J)xVwsNfh$gzIw|F7=L!=otj z_q(b(lN-=*2m%hsC6LgQJBmk6$T19I7{C}}Cdnk3FquwIPq@4wD5$8x1J_$rM8$hO zR$Y%3Z(Vg=&(-z7WA&@9_kHc}Q*YNyqVDc@pM9S1A3u2VsZSqOZ}t1Bdb_K-W(HUl zz^VXN1+XfBRROFDU{wIC0$3HmssL66uquF60jvsORRF63Se3x40#+5Us(@7mtSVqt z0jmmFRluqORu!&oDqvLss|r|Ez^VdPttQ_u)N1nmLajE9+G;K7*aKwCs14VW zj!An6_RAJts~rj}=gez0TE|QFMA(yHH^Xj$rBCtD(LL}Vgq16ZYDt%~Q#%$R*z<)RJCFE8iN_l3tM|y^>bG0jb3skXpV%o-ZcB9soN9_CVO_ zurpx~f}I1K3p)?i16u%V%JNCCq^0j0Bs)kouS0a|5S=JXheM5hkXsY7(?5uJKOrykL%M|A2Doq9y49?_|%d(DTU9?_}S zWOV8goq9y4UX#(O*JO0+H5r|Hy4T3_WpwH_8J&7fMyDRpsYi6`5uJKOrykL%M|A3$ zj7~kGQ_o~{>Y0pAJ)%>O=+q-R^@vVAqEnCP)FV3eh)%tb(Ww_QI`u+Er(VeD)C(D% zdLg4zFJyG;g^W(UkkP3ZGCK7_MyHjQ0@gh22M8}Khco7{hqT@w$ zyoin$(eWZWUPQ->=y(wwFQVf`bi9a;7t!$|I$lJ_i|BX}9WSEeMRdG~ju+AKB063~ z$BXEA5gjk0<3)75h>jQ0@gh22M8}Khco7{hqT@w$yoin$(eWZWUPQ->=y(wwFQVf` zbi9a;7t!$|IzI5`18+X?<^yj&@a6+=KJexPZ$9wm18+X?<^yj&@a6+=KJexPZ$9wm z18+X?<^yj&@a6+=KJexPZ$9wm18+X?<^yj&@a6+=KJexPZ$9wm18+X?<^yj&@a6+= zKJexPZ$9wm18+X?<^yj&@a6+=KJexPZ$9wm18+X?<^yky;H?q7HG;QB@YV?48o^s5 zcxwc2jo_^jyfuQiM)1}M-WtJMBY0~BZ;jxs5xg~mw?^>R2;LgOTO)XD1aFPttr5I6 zg11KS)(GAj!CNDEYXonN;H?q7HG;QB@YV?48o^s5cxwc2jo_^jyfuQiM)1}M-WtJM zBY0~BZ;jxs5xg~mw?^>h2XB7x<_B+n@a6|^e(>f8Z+`IR2XB7x<_B+n@a6|^e(>f8 zZ+`IR2XB7x<_B+n@a6|^e(>f8Z+`IR2XB7x<_B+n@a6|^e(>f8Z+`IR2XB7x<_B+n z@a6|^e(>f8Z+`IR2XB7x<_B+n@a6|^e(>f8Z+`IR2XB7x<_B+n@D>1X0q_<8ZvpTY z0B-^C765Mn@D>1X0q_<8ZvpTY0B-^C765Mn@D>1X0q_<8ZvpTY0B-^C765Mn@D>1X z0q_<8ZvpTY0B-^C765Mn@D>1X0q_<8ZvpTY0B-^C765Mn@D>1X0q_<8ZvpTY0B-^C z765Mn@D>1X0q_<8ZvpVOLaWu5h!xs$*dw)0@|$3ff^CMqPg*uzp2KFsmSE5Kus=%6 z3*~-Z1iKQpMOx7(kBZabZzJ0T#3mp%X%evsh)tSAY|l;|wg9mOh%G>D0b&afTY%UC#1y# zEkJAmVha#kf!GSfRv@+lu@#7|Kx_qKD-c_O*b2l}AhrUr6^N}sYz1N~5Lla-%f3Q}*9R<4H+Qa_URLD+|-rG7z{T0WIS zEnnIdau2n9X%B#%0(&6rbl91&2f@yP&4rx@>wzsG+eyrHl3flf+gm4?=>#*KV5Sqy zbP_Xkl$eoLwzp0&(+Orei5c2M%t*TuwnbVn(@D%oe;e6uAa(<>8?opHVmA=Gf!Gbi zZXk98u^WipK;Yl~h!G%0fEWQ{1c(tJMt~RrVg!g0AVz=~0b&G* z5gteUA+(ds)>tASkryAZYx=P#zQ zn5i|wF2R03{H5>%@R!lp(9~AImn$($>QfSN6YPnwC&6xp-2y9D4Vjp=GcjvtV%E;Y zteuHjI}@{Zrgk~7u7IUao>HzWVd+~y$-fHrYFPTlPTI2@_F7o_Tq^Ck9`;t)+hA{p z{T=Kbuy?`AmEoo)*SwjUT!Ch4auvNv3LvlO0i5$7eEInilkTc=|0D3_x+YV548C05 zWNJ^qmus9%jedEAtXyehYVuQKrbeGpB}<=CB`ZHQW@_{qRkHMnX0r4<5oBM5l`C^h z?R8kWKF8GLCjv~&QkvRZ@ZW}g2lhKzXXb*HpSLnuHmqDpWit86P!sc+CX=5GH8HDc zvK;twZI8*uz?UoKOg0{Nl8iE&0y_tLa$)DedSDA+i(u!YoWo#`fUT5VF|;>^_J%o9 zlcBw_I$1I)DxE`$D(!Mv4(Y1&kCgS{N6T_}EBrQjl=PO4ipg>hsjl?h@Tb6^3jaX( z(_v>|&rJBU;2#8kHvBp8=fcm0p9g;)d;`7*em?vH_=WI`VM}2ThMf<41Z)K?t{pSI zrl`Xnx!%ka4e;fvCsQnfFV{YqnEN#a`W9IP)FKOS5G-hs1ue3m zMHaNkf)-iOA`4n%X;OQj08Tk;SAI zSq!wAwB1@oGLW?ZCv9h2=7PQC`Qj07hwa5}ui!33v$P!YE zEFrZh1}%y~i(;fOH_#qAyB>qW#GpknXi*GW6r%{9rVTB!p+z>d$c7f# z&>|aJWJ8N=Xps#qvY|ybw8(}Q+0Y^zT4Y0uY-o`UEwZ6SHnhlw7TM4u8(L&Ti)?6- z4K1>vMK-j^h8Ee-A{$y{LyK%^kqs@fp+z>d$c7f#&>|aJWJ8N=Xps#qvY|ybw8(}Q z+0Y^zT4Y0uY-o`UEwZ6SHnhlw7TM4u8(L&Ti)?6-4K1>vMK-j^h8Ee-A{$y{LyK%^ zkqs@fp+z>d$c7f#&>|aJWJ8N=Xps#qvY|ybw8(}Q+0Y^zT4Y0uY-o`UEwZ6SHnhlw z7TM4u8(L&Ti)?6-4K1>vMK-j^h8Ee-A{$y{LyK%^kqs@fp+z>d$c7f#&>|aJWJ8N= zXps#qvY|ybw8(}Q+0Y^zT4Y0uY-o`UEwZ6SHnhlw7TM4u8(L&Ti)?6-4K1>vMK-j^ zh8Ee-A{);|Hnhlw7TM4u8(L&Ti)?6-4K1>vMK-j^h8Ee-A{$y{LyK%^kqs@fp+z>d z$c7f#&>|aJWJ8N=Xps#qvY|ybw8(}Q+0Y^zT4Y0uY-o`UEwZ6SHnhlw7TM4u8(L&T zi)?6-4K1>vMK-j^h8Ee-A{$y{LyK%^kqs@fp+z>d$c7f#&>|aJWJ8N=Xps#qvY|zB zXi*$m6o(eYp+#{hOdMJihZe=5MR91+>6Ggj8nb0cOXo)>w@7R*v1bZSZeajH-*$hkHGDN-{-wi^?2BBkv z(6K@2*dTOl5IQzUIwsG*0`=bsdnN2H*sEZ#hP?)7?uNY<_Bz<>Vd?vYs2uq@@j=ot zX@3WM2kc$2zsJ?x4NJe>K|4!DN)J)nm*lbui${Qp#qjR8UgQRBCm!F*(BsG)19OVs?nn`~g za*c>8?{pC z+aT$iM6UyuT+1=Yew3EJqlWTw`V~~NI;|&rJBU;2#8kHvBp8=fcm0p9g;)d;`7*em?vH z_=WI`;g`Z53_Bn82-phPD%e_i?WBIPwsKTBNa`njIVv0^^^?9F6%IoE21)(o9{IVL zK~g{I%TLD)lKM$sK8X#I`bl3ti4BtaNnbvR4U+mvUp|QqlKM$sjtU1!{iN@3*a0Rx zVY^{_U?Z?mSh=cakXqtFH20JOn;|V}nzWhPL7MzGfgPqXc$!v5spB&(owgjGYr0mU ze4!nv)hJ)rMre)7Ptmfpu<~76w$`tF8hdI3%1_fqYtJb^Q=6#0r~E7}kLk+KCO=>K zBedD9Rim%E($lG4F?Oo*nYJ(cLHS%u<0F(Wv>HBE`MNfd&sBbkwjXa+zDt|H#D+C;dpp`sKeb6j0fHAX5YG4 zxT`zvzQ&zzc#K>!p1JM?rr8wI&QOP>d=Zj=I}Jv3QWup8i-(0)#SCCz4QLvvG}^aP)EoPcSWiGdEN2eNJE&e)h7IYTyeZRP7zQTsl*$qSn_%e{uR-uZ6S@%}swn+76P}u9;e& zwoZ%TtZv%t)~=zye9h22^hYbH;d!*Vw08lWZBl6wD#xu=k{_eo(#rC}0U^%0ZubZF(|x8qm`*%+OXOMkyU-<`}My?!cL=60h-hPDiOZG|WI=HW=9 zoCIoavXsP;p&Gd9 zRF1qRhv6`;UtVjB_6G?~^3g-rBAK?SoG>ww;LN5g_%%2GoL?EEI5B*%HjnEXw$M$36 z*#x#fo5&`y$?O2;W>eTyMxV1|^eHbklg(lWvDs`6o6B-p9-GGu=3)7)fEBVLMk`WT zDJx?KvqRW?b|^cH9nOwm<*b5LvMN^1YS;p{kkzs}R?ixkmn~vGwwN`tCCty3vH)Ag zma`S?NY=!TV$EzNYhg#TRu*J!tethR5bI=Jteb^d4_n0|td~WZ$@-YZV$5c7*3VY6 zHEb@0RR zJBMv&=d$0h^Vs?90(K$0h+WJsVVANU>@s#ayMpaxSF&B~Dt0xyhV5q8vg_FO>;`rt zyNTV*e#>rQx3b&V?TmiEn%&9nV!vm1vwPUR>^}Afc0b$0=$9nfL+oMp2z!)0#vW%+ zus^aV*;DLk_9ylX`!jo%J;$DBFR&NcOYAS~Wk$aS#$IKwvDeufY%hD0y~W;U@36nI zcNzWa345P?z&>PuXCJYT*(Z#CNrHXOzF=Rnuh`e@8}=>xj(yL5U_Y{-*gv?&8Rwk7 zXOO3G7fr48kLMHk{(K^z#3%CuxSLPm zQ~7~>8lTQ*@R@uTKZwufbNF1I%k%g=Zg3CJ=LNiw7x7|V!b^D>KbRlF=kr7PVf=7@ z1TW_mypmV(YF@(^@P)jV*YSGZz`cAC_wmKNkuTwXzLW>}GQOOz;79T%eiWzo0ckyl><~@8BkMLd|voUkKxDiMyVqcLXM$%+hlu&&P;rA5;u$Aid)33;x=)+ z_?@^z+$ru7zZZ9ld&IrsKJf=}zt|%l5D$un#KYnd@u+xAJT9IPe-uxOr^M6ZPvRNz zXYs6fPCPGO5HE_C#9zeA;uY~%@v3-Dye{4ld&QgLE%CN^NBm8^E8Y|TBiC^QY z`b>S6evm#}pQF#!bM-uZo^I$KJzp=-3-uzsSTE5_^)mfn{SbY=eyDz!ez<;wUanW@ zm3oz4t=H%a^o4q@UZ>aV4Z2rfr2F*6dZWHX_v=gbfWAy$uCLIK)SL99^k#jf-l89^ zx9UN?O>fsb^pM`Ecj?`FSnttS=@GqGkLsr0r(1eVxAnN*udmkE=xgzqi@&G)qkU( zr=PE1pkJt8q+hIGqF<`-&@a<3*RRlb>R0N!^sDr%^=tIq`n9QfQ8V5V>eQqCk;tg1 z8I_OY;b>PZ6z`8kQ*3&U4Y@*V+atl=G^^i?hdSCK8PWdUHu;F(6?Ju(kw`F>+82t^ zlX5&g*h`*G&+wTz*`|^rq4d6BEEJ7|I^!AeFz84N%18UKy-M$k^xG-)Y~CAmb+7B| z4n!alZGGRaCkx)ukEVw%K-#ibb%hE#^HBns#DNPa|p`&T-{V@tm`#P~M6s4lgRiP*q zn`(zJxJv5?)7Z-n+v&-XVx}4E=p3;IO)!uVF}uR;!3edc)c$DLFv_bk zhQ@E{=4xsd^4eV;A&LPt2?{!u({E=|SnYm9JeG~{Cbm+7?fvl(@9mfECrF(2b&qgb zhP(7-dc+w>uc=bRgAEJ1fyH zBw4O<#K~2TdSsS6aqNtQ*1F2Ubb5J$p_K9%@yW}p(<)V!T-8qIYA18`Q0DaNM6Qfl zoFkiCMlH^h?#SAqbLDn+ZQ^{nC931yu0?=%`5XwJ1K}IW=JGl9^Cfbo_4Y^N;l9W^ zmk+Jf6>zc!oUDPNtm%P79@mjLn6k9nj72lLLa|=z)@>2nB}1_~~ar%*c0%@uae2|MSg{v&x$4=2tMA)+Db&|o^J zo6hOxP?0XvsgIe+3_Z55`lgRXu1HMb^hv?bIWLB%_)N3ljCwct$AcrdF%kg;edToq|J1 zG8YWhD6?zGcP(&A?n0t3kag`MleGZK?Vx0J4co|EIFviHd&t)plE&!WQom{uAK9#3 zG%-a@C$rYM4!J8e?D!eAfOO7+n_27B+&RnfN7N=SQ0`8nEh+n9S8bi#=HZ^qx}iE` z_6+%1^}{Niwd!XZQmUd6YWLxGSA!G82$HOZ;pat$ZMYg7IwMH*21!(ejH|(EbP*?6 zp`372%bj~jYEX%$BjGrf z=_nceEdMb6vgl?@4^*o257jlr0e9$10Zr-2s_Bv`mqS7d2+kVLQ%c;7ns#>LVzHG` z9_i~2!c7m-y`P>kV}| zC+-ubEI-3b0iIqFiU(5`1nCO#uu)J}n5r=KCOSkn$spag$V-!;5-+7b*w+`NPTbqp z5#-)}zNnwC2vg@lE%@TFSki5#_`_YjL9sO0pQ>sk7I%k5CH*b7!wyt=*(h0NqE@o( zk?Q2czKmd!l&sLOD@&saIaJB(f;YO~IiARhohit#x6$b-UGgGRIzo|nFjbXBPsDVI z@*vGe$Ah{oEM*lgkDk)$@|=oRRPty)UmH#})iw5oMXcL&(PMjW(365h#OYF16+|Ch zW;^{+jZ#b*gDhEcqGlt1QPV6{tP? zQB)+EO>Py-t>pP7Nv|~Nl_k7lBk3iviW69#!lJ}cPqGwGvJ_9Ul>B5V`N>l96QvmW zg^5z~ljY?XC-)^w&QF${pDei`S#m+Lr#@e zOG&cil4Qvx$&yQwC6^>iE=`tPn!Mi9Bt~fxqcn+8n#3qgVw5H^N|P9+NsO{2Mp+W0 zEQwK;#3)N*lqE6Bk{D%4jFO>J5*XA|R2%XbiK8APf#ER{7#<^m;V}{z9wUL_F%lRa zBXJ!bBZ=WjVhq)}D6!8dD|Ib*9*fsF$#UFWTx*b|FHgup`kI92I?_3Dos-bJK^nEY zLcKD<)lm00O0$QCzch$Q$Ls)R1mIzGHezVXpe<;JvYjLJSRJD`a5OS=CLd%b=Ma^H ze91#Hm#ZV#MPrq8C!teZZ8WhFil>DlkuWKnok>GTdYbQ-lN2sF0*!}UG~hL(9T?DJ z#zJCX=!h+Vq^m)6TO_TM9+l+WL3%VX=1ieo(RSxzOUnv9G=X7DWv=dznb=$G$yZ&7 zJk_L%Jq1Pi>B(21DY)&W%V~*Tnxg1Prx66^G`h1eDt3H3Q%-v*KMOM-i32o9j)#Mh zj&NsZN)_%GeKE76zdfFA_tQN@);I+t?o@i~Du?Q6;b@`Z zO48)rT+W%K%jal#S!(tK8>ta{wLvQgN@`CXi02k$q9?ZhOBA6VHhe! z&1pMdZ5ODtP^CpGEmmoXN=sE*rqXhiR>-ubx~2wcO--drt7K|;YJh9xS75(UPz8KS zfln!LJkDV!{Ss z`=v!q3Y-#+0;fbu3-oT&TqQ%+7K)f_a8{u@tI%-p3X7cj7Z$1QVzpiDTt{KCa~*}n zsD)8j3?3;3kCfv2Ch1*EmgRs3b#z*lqno~1eWcquuS2UDV#EOon;EIOyQL&yfTGXrtr!X zUYWuxQ+Va-I?L5{mMi>ng7?a)n>6@XHl`xxz13_!SDj zLg7~^{0fC%q3|mdeucuXQ1}%Jze3?xDEtbAuli$Qg~G2;_!Tvo;I-0_kDw06m8uSv zst%Q^4wb47m8uSvst%Q^4wb47m8uSvst%Q^4wZ_7N>zu-YK2`hgk7b0P`Xj5bfd6J z)uBq&p-R=k(G#PvO4XrC)uBq&p-R=EO4XrC)uBq&p-S;krQ%Sn@T(OE)rx~^gTJM84iAt;aq=_(%T}#!7nnL>o4*+{1o4*+*I(oTzNgyhrJN=Zl6~5C?XTj5uNA5XQ@M=4d;@AOgHR@d+JQQB75 zUs)pi8f}**`WpFVYG3)VeX1T#U!`+YJt`Fsm8u?2KlM~Q{ghHw52v5fwyKBIPib4# z!|A8At>WPHQ`%N>aQZ22t2j9Ql(rSV(@#CsPCuno#lh*Pw5{Uc^i$eaad7%6ZL2sq z{gk#<9Grei+v@tAeoEWw`kj7C+v@tAe(I@q`YEOAdYyhr+v<9qeo5QvdYyimZ>al1 zfl-q)G<}6Z2t6#e4cmudhupXC(0TGX<`<`7K1=Q!fd|uMNzP`nkZc@Hn<(>*z<@+lW7 zJ>bgY^lU4S=vx^y{X zh6y2EdRfvWhL38%YZN60vPKbFhEeGBWJ(h~TeXnNa*bBp(n?zT#whw7X{^4@q6K4P z>5t1TaSd6Ww#ZjDLo3vZH5LiRqm*xy#=X7EZ(&+Dd@y&9E6|AyOSz9@V9SNUck zUj=fc(+b-(EtAe4q3uH}hR10Wus?%p;G$K@SyYRW+P>NtZ9i>)btFYgrO#_*Q*B3S zIaKfQREJ5Ca92>f3HEl_yCc+Sv^}to!afx-+aua@urHhP=o_%_!G0nenf49rPtr2o zmf_5R-4}L(Z5tjo6?QgkKG}SBFzgYqHDn7|1MCvm6>(Ww3v4HB6#U3_&T{4TkWGa@ z+@@iVw6uhaxcYUPh?NsDY2`{l8N2^99g6c%%;i3YQXI=^O}PtY4o@?P{mI%4TGLpp z9Y!m~7twmh7L{wUO4qA&w@M#Y=|?L4!b#aEm5xgd0w zy-xp`wwL~M?JfE*w0G#gPFs1@mgZ__XoK1|?M&@`?L+M&?Gx=Y?F(8}*hT9DFJqU} z3apoCHPQk)o6(w|YjAZFw2XhYN=TkVZH?MGdCob%Tt{>w9T9X+4xKZG&SbRSXn>+C zdm8zapHZEVo6Z?c=ZvM+z8|&T3DmMD(h)|;rvZU-&>572@~Ir;{kt3^G+nM@Vs18t za&R_{O{W0T8cSKO?7LJ8xoUqjAx+h0(Kl8IT1D!k@2`+)1APLDYqh+HtdAFxZII}6 zME;YW(;l=jEwnuvd$lpkjDayrTW6H3?^w9@| zmz{mdLr>hi@u7u(eShw!NA3FLM)!_^eO4L+V!biI+ja=K)^Swn^cTPTCV1l|Uu=7K z#%(V&J#S|S$jBK%OVY#iCL=o6T^nuB^UN_0k_SZ2 z)WiYz(r|Cc?T^!H9eU&A_J?AtX_30^t}HhukIObnjA9Qx=gNOgQ~1V>+Jm=!wq(rRCvR>& zXl&h4^XkuBwdKsuiRVUXZsc^Q=Ynb58qcMcvltQs161_nU#;EB^9i#pk(y=zs0>Yacmd(gl%* zwC$5$d*$PvOrFMs&r-2aS#Q8-=bkY7Z$Xsf_8f zj2XtX#J0gU@25TnV7A+Rc{F($rZ+87`Pl;_ix`=d!`MG`ZfHh<+&Vy?Ys@xg?U=D+ z+UBV$V|y&}vwZX7ww>D^%%lCrSea?MEF#OuNPvnoV}#s4QtsCUcm2VbEVuX3sZH$6 zG4}C{BwEn~Tuc4s9{Qli&zq7MU`$*5Q2nFRHoX3J_Ov~(O}P0oe%Y>p+^kJwHkM=z zjF@{<)41SmFQxo+@++U7dFCz4CLFQrgR|}}ExW0|IDYVXzPC&6I{%c%w^vNM>CQ)X zoWA^x@1F0_D~cAeX9_MK_o#RG%tt=kySagvdN-|o_y_+RAH3n(^6JiWFKNj-@69Xk zy>H;82U_>Oe*LVM9=Wo<=MoqAcp)_JF1@WI`wQx2~xPfxuqG;!M9 z3!kmp@WEwIKgMqz{q)jD#$K_Z`P+4et&AOa^0-UpR$l(N|Ec2+{c85XclgfHuI$a& zwDQ{){}=n+vV3IU1K)pn{q`Lr#=Z97*bS|ZjhqwRtbh8!7i(uelk(6;vvr@V}E&CX3l75hr5zysl%N# zO)KYZJqH+*ocN7Zhh+!06a80p+XCvTG+meIwsNx|(QW@vv|@lw9nOmEt^;hOW(=?l zE?d+!kNzJCA6`?`YnT+uP{<==n%c)_(N8mFu{{+;jB$9#5V)e`C(o3*1k6?Cj;aPp&O2 z*uL-i``-Cl_q^SIduz|Br_Fv~>y#~>_iS3R-0Z(^{_YuDRz5yz%=}AFe1GZv8PNxS zdZ_NzJ5%@h&D3LGIc(-Llh=NDspqjz|2B2}D-YhXpz?wVNAH-t?d_H?KRWi)?#SPq_}tO2bi-*Y!<$NFIaEZp)JfC-orEwKX&NMi zTISC2#<)cL7CBiYA=J=Hb3M651;gV{_as3&UAOAn_gCzxn&>%Y-T8CQy>H+;_QJ%5 zCvQ4+MfCNwgRW?K^zpNE-qn|6f4pGkJgxMmw;wxu(FM;qEzX z`E=GLpZw;hInN%lWdHq3XMTNnoiU*QKz||Ck3&ml?EP)tetVA`dC*DMO?|id7d1AH z9@dTj-CeZAC?Z0rhvrq%vQ*n$;9lI{Mz1;Ci(~Y{CbsV9J=R^`FPDtb%N5*F%Z#FY zdbyYAnsSrgi92`Hjko`YHBcgunKO3imKy7~()2mY%rKO0$EW7U(V}9~S6MNm*{b zd{p?~y8pdhlWuL@O{*oAjXSpUv6ju*&wqN|Ro136wx040EnXhux-0j@Dcj$E=Ay+7 z-~V~)JuiRu+oD4z4?d9o{SP^LP4}I0?4gHDpZwM5D~`G73wGPX8Fy@W>fV|0VAo7< z&pRJ(46ayr#T(;B?K@`XO?$nCC(K#kuDbKJ&S{;eKIyybfQL#SUAk>=?5pve{XKWq zc0XOZE_=6e^(%8*7hdw>?$PX;O)r+7X_V!hD-J&Ph^4n*|Hi!iH~sbMeU==?Z+UUf zk5g{Hs`-kMnb+(ZwRl8fp7*M!9&4HY+-Y}z9zFJ;yV=SgJX@NcKkcNh6(^71abM9V z@6Wkn%DdaX+VsxVe{Wsea!l){AD3sYEYEIV+WJD}l#iY6Kfqogre4Ht;Fn#wPj)f4 z9yYp+kSnuw^Fp@yn`)LiP8iFKS&6$lXJaS+%lNhT*~aYTncSE>;a{IivHtmU0(J7< zL|&Gq2aTgITe;&X<49w<5g40Jt-32TuPfY1Pp=0Usp?@^A3gZavlBL7clsHt9(Z~~ z&vOg+n|sXoJY)LU1J%zDCuRT}*0hABK^msJYaPORKO!Q1J_M;ut_V+=PFQ`lkT#-}d z5%iIQ(ZBiAs;g)8J$l*U=Nyoh`(V+9J1?93*)P;Y>fcuJhgZ*esr>R__@*&euYJUL zc-#ErE54p~``erBakP$q)J2!Q`Q65OAN=9*s&`{=EWSN3%DpLi?pbeN(AaZpiRZ6Z z=6-OR_Q)jPyWae}PWooiz29{OLZ9^9yZ-Tx(g~wRt*u_|`F!(wF|u{fEh{hnYHR1} zf&Gu%yXl>KYOgF^_ReeNYeuXXX$+*~&~wc9O8+|F`lM^!<73A5F7}%zkDsvV7d1Bi zzm*>vsgP)uaNdrRqy=UsWkC*x}~r%v|!_EheAeCsvKK8`MQU7a$f zY;yY{)ArqV=Xp;*o>p{R?5zdMe_Z#(sdeuj(U)7)e!>kKo__Ggm%jh{u^&!(>BXHp zUP=G#^3RU>_{skJzYZ<#n0oO&$K8GX9rb@)Q9Z)@%#jV=gxYN)wL5`^yVSvQFwXhe z&?I$(Q6&!@pdV_`?P^EKj-t&4iE)qJUO+<=d3(wIRoAWbS0)ak2cs0XQ_9b!lXM^< zDgRbFr5yf~2O(kfC$iJvPD=BCHn=-Hk;~x!^ooMv;Lm08XIB)883#yS4%Df2Z20F= zvyUs?xkXe^#b}tPkD`V&G%vBgj%P%T9ut4j$1%KH^tY*7UhgU&Gw#hle{}qar}mux zLi;_R+;;XmJ+ZdEU;cT1=|@)|ns)SE3pNfMeN=tz7n9uIjXXR3Pm{(ks~UIt$)A6J z`o%YVon7?W{H*J$&S|Zlec?|Rnhl5CT-en&YV$vu%9@+riVR#^bZn^p$Mbq`8*@(W zMJM--y7$nV+qU2O%B|16{NBao+m8R~xI1^A^+EKrsi!`?rr3LGQ>H(~^X!~iH!j(G z`ubJ3t*N>v>-sNNPM`bMlcySo)r*VPJ-%zv4VioXI4w2v{&NPt8ujU2+it(`f|r`- z=Y0A;ckMURJO323;M8X~zxF>X3i=QI;Oy|5Rpufs^7Qj3y}WGK1-lM^qG3w+w$EDc z+WVesW!aRR{J(n!L>I|oJ7>(;_{9IWvd2gLO3;Vqsdn@kqlUGJERURL7@wRqN*A82 zVTX0nxuNEh=@~&26hqr%j01-<>K?lPeOpp?^T9d(^#zZNT(z()>l`EXsfOV#jmCfa z#tp|6ei}Whd~mJN%-iydj(TQwdd9B$rxvEYQnY^6*&qDRjOjPE6^yxL`<`0^$IZLs zk7tTS8z0@e`X8tCO#a)IcW%A-(ks3RZ@D~e^ZO-F-@GjAv{}c$zvZjVRc|ltfBJ%X zUAuihy0gCgaLNszUh~(9xB3o#>F%!%3(URuVD^t0kt*NqgXgcAQ3X8&ZeZdg=S(&I&9l96JNncPTa6oTZD6wgSyrO}E$qsUWSL@$b) zeiedGcV2q--ffxBzFdAxvvoq-q3`jk!R^h($ literal 0 HcmV?d00001 diff --git a/res/fonts/Open_Sans/OpenSans-BoldItalic.ttf b/res/fonts/Open_Sans/OpenSans-BoldItalic.ttf new file mode 100755 index 0000000000000000000000000000000000000000..9bc800958a421d937fc392e00beaef4eea76dc71 GIT binary patch literal 213292 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

    JU{jq<7f203t|Ihq? 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

    93Tg2c}Lc^2oc3nPS$ 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

    r{ZX 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 literal 0 HcmV?d00001 diff --git a/res/fonts/Open_Sans/OpenSans-Italic.ttf b/res/fonts/Open_Sans/OpenSans-Italic.ttf new file mode 100755 index 0000000000000000000000000000000000000000..c90da48ff3b8ad6167236d70c48df4d7b5de3bbb GIT binary patch literal 212896 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 I-Ko?4FC8~NI{*Lx literal 0 HcmV?d00001 diff --git a/res/fonts/Open_Sans/OpenSans-Regular.ttf b/res/fonts/Open_Sans/OpenSans-Regular.ttf new file mode 100755 index 0000000000000000000000000000000000000000..db433349b7047f72f40072630c1bc110620bf09e GIT binary patch literal 217360 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 !}#gv~NV!5|5YF|kE)J0y^zWbk4>=%|6F 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 literal 0 HcmV?d00001 diff --git a/res/fonts/Open_Sans/OpenSans-Semibold.ttf b/res/fonts/Open_Sans/OpenSans-Semibold.ttf new file mode 100755 index 0000000000000000000000000000000000000000..1a7679e3949fb045f152f456bc4adad31e8b9f55 GIT binary patch literal 221328 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%0DJH?LFC28_mTUAZOar9j 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

    MAzfu-#(7W5VH7%hxxNU1% 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 b^2ROSp1r5Xdx>eYXCxdsa=Oc~d6M+Mf|cc} literal 0 HcmV?d00001 From 8ce4df7ce3ed6260995fc9cfa48732e449fcbc19 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Thu, 12 Apr 2018 00:25:07 +0100 Subject: [PATCH 0760/1160] move non-Riot image resources over from riot-web --- res/img/50e2c2.png | Bin 0 -> 146 bytes res/img/76cfa6.png | Bin 0 -> 966 bytes res/img/80cef4.png | Bin 0 -> 146 bytes res/img/admin.svg | 17 +++++ res/img/attach.png | Bin 0 -> 369 bytes res/img/avatar-error.svg | 15 ++++ res/img/button-md-false.png | Bin 0 -> 569 bytes res/img/button-md-false.svg | 29 ++++++++ res/img/button-md-false@2x.png | Bin 0 -> 1086 bytes res/img/button-md-false@3x.png | Bin 0 -> 1548 bytes res/img/button-md-true.png | Bin 0 -> 483 bytes res/img/button-md-true.svg | 14 ++++ res/img/button-md-true@2x.png | Bin 0 -> 906 bytes res/img/button-md-true@3x.png | Bin 0 -> 1201 bytes res/img/button-text-bold-o-n.svg | 17 +++++ res/img/button-text-bold.svg | 17 +++++ res/img/button-text-bullet-o-n.svg | 20 ++++++ res/img/button-text-bullet.svg | 20 ++++++ res/img/button-text-code-o-n.svg | 25 +++++++ res/img/button-text-code.svg | 25 +++++++ res/img/button-text-formatting.svg | 21 ++++++ res/img/button-text-italic-o-n.svg | 17 +++++ res/img/button-text-italic.svg | 17 +++++ res/img/button-text-numbullet-o-n.svg | 20 ++++++ res/img/button-text-numbullet.svg | 20 ++++++ res/img/button-text-quote-o-n.svg | 17 +++++ res/img/button-text-quote.svg | 17 +++++ res/img/button-text-strike-o-n.svg | 18 +++++ res/img/button-text-strike.svg | 18 +++++ res/img/button-text-underline-o-n.svg | 18 +++++ res/img/button-text-underline.svg | 18 +++++ res/img/call.png | Bin 0 -> 588 bytes res/img/call.svg | 17 +++++ res/img/camera.svg | 12 ++++ res/img/camera_green.svg | 15 ++++ res/img/cancel-black.png | Bin 0 -> 1136 bytes res/img/cancel-black2.png | Bin 0 -> 1182 bytes res/img/cancel-red.svg | 10 +++ res/img/cancel-small.svg | 13 ++++ res/img/cancel-white.svg | 10 +++ res/img/cancel.png | Bin 0 -> 316 bytes res/img/cancel.svg | 10 +++ res/img/cancel_green.svg | 10 +++ res/img/chevron-left.png | Bin 0 -> 14586 bytes res/img/chevron-right.png | Bin 0 -> 14594 bytes res/img/chevron.png | Bin 0 -> 14638 bytes res/img/close-white.png | Bin 0 -> 1305 bytes res/img/create-big.png | Bin 0 -> 581 bytes res/img/create-big.svg | 26 +++++++ res/img/create.png | Bin 0 -> 807 bytes res/img/delete.png | Bin 0 -> 1006 bytes res/img/directory-big.png | Bin 0 -> 325 bytes res/img/directory-big.svg | 22 ++++++ res/img/download.png | Bin 0 -> 1041 bytes res/img/download.svg | 18 +++++ res/img/e2e-blocked.svg | 12 ++++ res/img/e2e-unencrypted.svg | 23 +++++++ res/img/e2e-verified.svg | 12 ++++ res/img/e2e-warning.svg | 12 ++++ res/img/edit.png | Bin 0 -> 460 bytes res/img/edit.svg | 11 +++ res/img/edit_green.svg | 11 +++ res/img/ellipsis.svg | 25 +++++++ res/img/eol.svg | 16 +++++ res/img/f4c371.png | Bin 0 -> 146 bytes res/img/file.png | Bin 0 -> 482 bytes res/img/filegrid.png | Bin 0 -> 226 bytes res/img/fileicon.png | Bin 0 -> 658 bytes res/img/filelist.png | Bin 0 -> 223 bytes res/img/files.png | Bin 0 -> 503 bytes res/img/files.svg | 18 +++++ res/img/flags/AD.png | Bin 0 -> 2584 bytes res/img/flags/AE.png | Bin 0 -> 1015 bytes res/img/flags/AF.png | Bin 0 -> 2578 bytes res/img/flags/AG.png | Bin 0 -> 4234 bytes res/img/flags/AI.png | Bin 0 -> 4765 bytes res/img/flags/AL.png | Bin 0 -> 3094 bytes res/img/flags/AM.png | Bin 0 -> 654 bytes res/img/flags/AO.png | Bin 0 -> 2449 bytes res/img/flags/AQ.png | Bin 0 -> 3910 bytes res/img/flags/AR.png | Bin 0 -> 1666 bytes res/img/flags/AS.png | Bin 0 -> 3977 bytes res/img/flags/AT.png | Bin 0 -> 655 bytes res/img/flags/AU.png | Bin 0 -> 5229 bytes res/img/flags/AW.png | Bin 0 -> 1650 bytes res/img/flags/AX.png | Bin 0 -> 1844 bytes res/img/flags/AZ.png | Bin 0 -> 1744 bytes res/img/flags/BA.png | Bin 0 -> 3048 bytes res/img/flags/BB.png | Bin 0 -> 2078 bytes res/img/flags/BD.png | Bin 0 -> 2819 bytes res/img/flags/BE.png | Bin 0 -> 558 bytes res/img/flags/BF.png | Bin 0 -> 1596 bytes res/img/flags/BG.png | Bin 0 -> 659 bytes res/img/flags/BH.png | Bin 0 -> 1374 bytes res/img/flags/BI.png | Bin 0 -> 5652 bytes res/img/flags/BJ.png | Bin 0 -> 811 bytes res/img/flags/BL.png | Bin 0 -> 566 bytes res/img/flags/BM.png | Bin 0 -> 5295 bytes res/img/flags/BN.png | Bin 0 -> 5290 bytes res/img/flags/BO.png | Bin 0 -> 668 bytes res/img/flags/BQ.png | Bin 0 -> 672 bytes res/img/flags/BR.png | Bin 0 -> 4852 bytes res/img/flags/BS.png | Bin 0 -> 2291 bytes res/img/flags/BT.png | Bin 0 -> 4879 bytes res/img/flags/BV.png | Bin 0 -> 1695 bytes res/img/flags/BW.png | Bin 0 -> 669 bytes res/img/flags/BY.png | Bin 0 -> 2023 bytes res/img/flags/BZ.png | Bin 0 -> 5281 bytes res/img/flags/CA.png | Bin 0 -> 2246 bytes res/img/flags/CC.png | Bin 0 -> 3728 bytes res/img/flags/CD.png | Bin 0 -> 3704 bytes res/img/flags/CF.png | Bin 0 -> 2655 bytes res/img/flags/CG.png | Bin 0 -> 1381 bytes res/img/flags/CH.png | Bin 0 -> 1500 bytes res/img/flags/CI.png | Bin 0 -> 568 bytes res/img/flags/CK.png | Bin 0 -> 6029 bytes res/img/flags/CL.png | Bin 0 -> 1632 bytes res/img/flags/CM.png | Bin 0 -> 1409 bytes res/img/flags/CN.png | Bin 0 -> 2215 bytes res/img/flags/CO.png | Bin 0 -> 668 bytes res/img/flags/CR.png | Bin 0 -> 785 bytes res/img/flags/CU.png | Bin 0 -> 3023 bytes res/img/flags/CV.png | Bin 0 -> 2695 bytes res/img/flags/CW.png | Bin 0 -> 1756 bytes res/img/flags/CX.png | Bin 0 -> 5152 bytes res/img/flags/CY.png | Bin 0 -> 3540 bytes res/img/flags/CZ.png | Bin 0 -> 1711 bytes res/img/flags/DE.png | Bin 0 -> 568 bytes res/img/flags/DJ.png | Bin 0 -> 3562 bytes res/img/flags/DK.png | Bin 0 -> 1233 bytes res/img/flags/DM.png | Bin 0 -> 2636 bytes res/img/flags/DO.png | Bin 0 -> 1682 bytes res/img/flags/DZ.png | Bin 0 -> 2506 bytes res/img/flags/EC.png | Bin 0 -> 2818 bytes res/img/flags/EE.png | Bin 0 -> 641 bytes res/img/flags/EG.png | Bin 0 -> 1611 bytes res/img/flags/EH.png | Bin 0 -> 2687 bytes res/img/flags/ER.png | Bin 0 -> 4082 bytes res/img/flags/ES.png | Bin 0 -> 2144 bytes res/img/flags/ET.png | Bin 0 -> 3460 bytes res/img/flags/FI.png | Bin 0 -> 1558 bytes res/img/flags/FJ.png | Bin 0 -> 5060 bytes res/img/flags/FK.png | Bin 0 -> 5273 bytes res/img/flags/FM.png | Bin 0 -> 2410 bytes res/img/flags/FO.png | Bin 0 -> 1715 bytes res/img/flags/FR.png | Bin 0 -> 566 bytes res/img/flags/GA.png | Bin 0 -> 661 bytes res/img/flags/GB.png | Bin 0 -> 6309 bytes res/img/flags/GD.png | Bin 0 -> 5753 bytes res/img/flags/GE.png | Bin 0 -> 2583 bytes res/img/flags/GF.png | Bin 0 -> 2342 bytes res/img/flags/GG.png | Bin 0 -> 2777 bytes res/img/flags/GH.png | Bin 0 -> 1864 bytes res/img/flags/GI.png | Bin 0 -> 2750 bytes res/img/flags/GL.png | Bin 0 -> 3101 bytes res/img/flags/GM.png | Bin 0 -> 709 bytes res/img/flags/GN.png | Bin 0 -> 560 bytes res/img/flags/GP.png | Bin 0 -> 5619 bytes res/img/flags/GQ.png | Bin 0 -> 3090 bytes res/img/flags/GR.png | Bin 0 -> 2035 bytes res/img/flags/GS.png | Bin 0 -> 5684 bytes res/img/flags/GT.png | Bin 0 -> 1830 bytes res/img/flags/GU.png | Bin 0 -> 2591 bytes res/img/flags/GW.png | Bin 0 -> 1608 bytes res/img/flags/GY.png | Bin 0 -> 5108 bytes res/img/flags/HK.png | Bin 0 -> 3001 bytes res/img/flags/HM.png | Bin 0 -> 5229 bytes res/img/flags/HN.png | Bin 0 -> 1644 bytes res/img/flags/HR.png | Bin 0 -> 2420 bytes res/img/flags/HT.png | Bin 0 -> 1944 bytes res/img/flags/HU.png | Bin 0 -> 677 bytes res/img/flags/ID.png | Bin 0 -> 579 bytes res/img/flags/IE.png | Bin 0 -> 553 bytes res/img/flags/IL.png | Bin 0 -> 1856 bytes res/img/flags/IM.png | Bin 0 -> 2533 bytes res/img/flags/IN.png | Bin 0 -> 1687 bytes res/img/flags/IO.png | Bin 0 -> 8096 bytes res/img/flags/IQ.png | Bin 0 -> 2119 bytes res/img/flags/IR.png | Bin 0 -> 4018 bytes res/img/flags/IS.png | Bin 0 -> 1483 bytes res/img/flags/IT.png | Bin 0 -> 572 bytes res/img/flags/JE.png | Bin 0 -> 3023 bytes res/img/flags/JM.png | Bin 0 -> 3663 bytes res/img/flags/JO.png | Bin 0 -> 2572 bytes res/img/flags/JP.png | Bin 0 -> 2402 bytes res/img/flags/KE.png | Bin 0 -> 2738 bytes res/img/flags/KG.png | Bin 0 -> 3258 bytes res/img/flags/KH.png | Bin 0 -> 2888 bytes res/img/flags/KI.png | Bin 0 -> 3661 bytes res/img/flags/KM.png | Bin 0 -> 4023 bytes res/img/flags/KN.png | Bin 0 -> 4213 bytes res/img/flags/KP.png | Bin 0 -> 2293 bytes res/img/flags/KR.png | Bin 0 -> 4837 bytes res/img/flags/KW.png | Bin 0 -> 1667 bytes res/img/flags/KY.png | Bin 0 -> 5285 bytes res/img/flags/KZ.png | Bin 0 -> 3466 bytes res/img/flags/LA.png | Bin 0 -> 2119 bytes res/img/flags/LB.png | Bin 0 -> 2537 bytes res/img/flags/LC.png | Bin 0 -> 2445 bytes res/img/flags/LI.png | Bin 0 -> 1759 bytes res/img/flags/LK.png | Bin 0 -> 5077 bytes res/img/flags/LR.png | Bin 0 -> 1903 bytes res/img/flags/LS.png | Bin 0 -> 1848 bytes res/img/flags/LT.png | Bin 0 -> 640 bytes res/img/flags/LU.png | Bin 0 -> 677 bytes res/img/flags/LV.png | Bin 0 -> 641 bytes res/img/flags/LY.png | Bin 0 -> 1273 bytes res/img/flags/MA.png | Bin 0 -> 1449 bytes res/img/flags/MC.png | Bin 0 -> 574 bytes res/img/flags/MD.png | Bin 0 -> 2238 bytes res/img/flags/ME.png | Bin 0 -> 2965 bytes res/img/flags/MF.png | Bin 0 -> 566 bytes res/img/flags/MG.png | Bin 0 -> 823 bytes res/img/flags/MH.png | Bin 0 -> 5594 bytes res/img/flags/MK.png | Bin 0 -> 5066 bytes res/img/flags/ML.png | Bin 0 -> 552 bytes res/img/flags/MM.png | Bin 0 -> 3123 bytes res/img/flags/MN.png | Bin 0 -> 2328 bytes res/img/flags/MO.png | Bin 0 -> 2994 bytes res/img/flags/MP.png | Bin 0 -> 4619 bytes res/img/flags/MQ.png | Bin 0 -> 5810 bytes res/img/flags/MR.png | Bin 0 -> 2897 bytes res/img/flags/MS.png | Bin 0 -> 4967 bytes res/img/flags/MT.png | Bin 0 -> 1324 bytes res/img/flags/MU.png | Bin 0 -> 723 bytes res/img/flags/MV.png | Bin 0 -> 2047 bytes res/img/flags/MW.png | Bin 0 -> 2141 bytes res/img/flags/MX.png | Bin 0 -> 2140 bytes res/img/flags/MY.png | Bin 0 -> 3081 bytes res/img/flags/MZ.png | Bin 0 -> 3367 bytes res/img/flags/NA.png | Bin 0 -> 3679 bytes res/img/flags/NC.png | Bin 0 -> 3254 bytes res/img/flags/NE.png | Bin 0 -> 1660 bytes res/img/flags/NF.png | Bin 0 -> 2520 bytes res/img/flags/NG.png | Bin 0 -> 563 bytes res/img/flags/NI.png | Bin 0 -> 1701 bytes res/img/flags/NL.png | Bin 0 -> 672 bytes res/img/flags/NO.png | Bin 0 -> 1695 bytes res/img/flags/NP.png | Bin 0 -> 4044 bytes res/img/flags/NR.png | Bin 0 -> 1620 bytes res/img/flags/NU.png | Bin 0 -> 3319 bytes res/img/flags/NZ.png | Bin 0 -> 4697 bytes res/img/flags/OM.png | Bin 0 -> 1886 bytes res/img/flags/PA.png | Bin 0 -> 2285 bytes res/img/flags/PE.png | Bin 0 -> 556 bytes res/img/flags/PF.png | Bin 0 -> 2379 bytes res/img/flags/PG.png | Bin 0 -> 4393 bytes res/img/flags/PH.png | Bin 0 -> 3160 bytes res/img/flags/PK.png | Bin 0 -> 3165 bytes res/img/flags/PL.png | Bin 0 -> 567 bytes res/img/flags/PM.png | Bin 0 -> 8583 bytes res/img/flags/PN.png | Bin 0 -> 5945 bytes res/img/flags/PR.png | Bin 0 -> 3673 bytes res/img/flags/PS.png | Bin 0 -> 2147 bytes res/img/flags/PT.png | Bin 0 -> 2617 bytes res/img/flags/PW.png | Bin 0 -> 2714 bytes res/img/flags/PY.png | Bin 0 -> 1519 bytes res/img/flags/QA.png | Bin 0 -> 1564 bytes res/img/flags/RE.png | Bin 0 -> 566 bytes res/img/flags/RO.png | Bin 0 -> 555 bytes res/img/flags/RS.png | Bin 0 -> 3349 bytes res/img/flags/RU.png | Bin 0 -> 662 bytes res/img/flags/RW.png | Bin 0 -> 1695 bytes res/img/flags/SA.png | Bin 0 -> 3750 bytes res/img/flags/SB.png | Bin 0 -> 3424 bytes res/img/flags/SC.png | Bin 0 -> 3704 bytes res/img/flags/SD.png | Bin 0 -> 2103 bytes res/img/flags/SE.png | Bin 0 -> 1278 bytes res/img/flags/SG.png | Bin 0 -> 2210 bytes res/img/flags/SH.png | Bin 0 -> 4615 bytes res/img/flags/SI.png | Bin 0 -> 1613 bytes res/img/flags/SJ.png | Bin 0 -> 1695 bytes res/img/flags/SK.png | Bin 0 -> 2932 bytes res/img/flags/SL.png | Bin 0 -> 676 bytes res/img/flags/SM.png | Bin 0 -> 3009 bytes res/img/flags/SN.png | Bin 0 -> 1530 bytes res/img/flags/SO.png | Bin 0 -> 1958 bytes res/img/flags/SR.png | Bin 0 -> 1942 bytes res/img/flags/SS.png | Bin 0 -> 3072 bytes res/img/flags/ST.png | Bin 0 -> 2945 bytes res/img/flags/SV.png | Bin 0 -> 1666 bytes res/img/flags/SX.png | Bin 0 -> 3485 bytes res/img/flags/SY.png | Bin 0 -> 1195 bytes res/img/flags/SZ.png | Bin 0 -> 4133 bytes res/img/flags/TC.png | Bin 0 -> 4631 bytes res/img/flags/TD.png | Bin 0 -> 567 bytes res/img/flags/TF.png | Bin 0 -> 566 bytes res/img/flags/TG.png | Bin 0 -> 2523 bytes res/img/flags/TH.png | Bin 0 -> 764 bytes res/img/flags/TJ.png | Bin 0 -> 1647 bytes res/img/flags/TK.png | Bin 0 -> 4829 bytes res/img/flags/TL.png | Bin 0 -> 3046 bytes res/img/flags/TM.png | Bin 0 -> 3925 bytes res/img/flags/TN.png | Bin 0 -> 2635 bytes res/img/flags/TO.png | Bin 0 -> 1618 bytes res/img/flags/TR.png | Bin 0 -> 2875 bytes res/img/flags/TT.png | Bin 0 -> 5253 bytes res/img/flags/TV.png | Bin 0 -> 5915 bytes res/img/flags/TW.png | Bin 0 -> 2108 bytes res/img/flags/TZ.png | Bin 0 -> 2289 bytes res/img/flags/UA.png | Bin 0 -> 568 bytes res/img/flags/UG.png | Bin 0 -> 1973 bytes res/img/flags/US.png | Bin 0 -> 2845 bytes res/img/flags/UY.png | Bin 0 -> 2542 bytes res/img/flags/UZ.png | Bin 0 -> 1745 bytes res/img/flags/VA.png | Bin 0 -> 2211 bytes res/img/flags/VC.png | Bin 0 -> 2105 bytes res/img/flags/VE.png | Bin 0 -> 2157 bytes res/img/flags/VG.png | Bin 0 -> 5427 bytes res/img/flags/VI.png | Bin 0 -> 5938 bytes res/img/flags/VN.png | Bin 0 -> 2304 bytes res/img/flags/VU.png | Bin 0 -> 4080 bytes res/img/flags/WF.png | Bin 0 -> 2509 bytes res/img/flags/WS.png | Bin 0 -> 1896 bytes res/img/flags/YE.png | Bin 0 -> 652 bytes res/img/flags/YT.png | Bin 0 -> 5735 bytes res/img/flags/ZA.png | Bin 0 -> 3595 bytes res/img/flags/ZM.png | Bin 0 -> 1787 bytes res/img/flags/ZW.png | Bin 0 -> 2802 bytes res/img/fullscreen.svg | 23 +++++++ res/img/hangup.svg | 15 ++++ res/img/hide.png | Bin 0 -> 1165 bytes res/img/icon-address-delete.svg | 15 ++++ res/img/icon-call.svg | 8 +++ res/img/icon-context-delete.svg | 10 +++ res/img/icon-context-fave-on.svg | 15 ++++ res/img/icon-context-fave.svg | 15 ++++ res/img/icon-context-low-on.svg | 15 ++++ res/img/icon-context-low.svg | 15 ++++ res/img/icon-context-mute-mentions.svg | 11 +++ res/img/icon-context-mute-off-copy.svg | 10 +++ res/img/icon-context-mute-off.svg | 9 +++ res/img/icon-context-mute.svg | 9 +++ res/img/icon-delete-pink.svg | 19 ++++++ res/img/icon-email-user.svg | 17 +++++ res/img/icon-invite-people.svg | 24 +++++++ res/img/icon-mx-user.svg | 15 ++++ res/img/icon-return.svg | 18 +++++ res/img/icon-text-cancel.svg | 15 ++++ res/img/icon_context_delete.svg | 11 +++ res/img/icon_context_fave.svg | 12 ++++ res/img/icon_context_fave_on.svg | 29 ++++++++ res/img/icon_context_low.svg | 11 +++ res/img/icon_context_low_on.svg | 30 ++++++++ res/img/icon_context_message.svg | 15 ++++ res/img/icon_context_message_dark.svg | 15 ++++ res/img/icon_context_person.svg | 85 +++++++++++++++++++++++ res/img/icon_context_person_on.svg | 85 +++++++++++++++++++++++ res/img/icon_copy_message.svg | 86 +++++++++++++++++++++++ res/img/icon_copy_message_dark.svg | 77 +++++++++++++++++++++ res/img/icon_person.svg | 23 +++++++ res/img/icons-apps-active.svg | 24 +++++++ res/img/icons-apps.svg | 14 ++++ res/img/icons-close-button.svg | 15 ++++ res/img/icons-close.svg | 23 +++++++ res/img/icons-create-room.svg | 18 +++++ res/img/icons-directory.svg | 24 +++++++ res/img/icons-files.svg | 29 ++++++++ res/img/icons-groups.svg | 26 +++++++ res/img/icons-hide-apps.svg | 34 +++++++++ res/img/icons-hide-stickers.svg | 16 +++++ res/img/icons-home.svg | 27 ++++++++ res/img/icons-notifications.svg | 19 ++++++ res/img/icons-people.svg | 22 ++++++ res/img/icons-pin.svg | 7 ++ res/img/icons-room-add.svg | 23 +++++++ res/img/icons-room.svg | 12 ++++ res/img/icons-search-copy.svg | 10 +++ res/img/icons-search.svg | 9 +++ res/img/icons-settings-room.svg | 15 ++++ res/img/icons-settings.svg | 15 ++++ res/img/icons-show-apps.svg | 33 +++++++++ res/img/icons-show-stickers.svg | 16 +++++ res/img/icons-upload.svg | 12 ++++ res/img/icons-video.svg | 20 ++++++ res/img/icons_ellipsis.svg | 1 + res/img/icons_global.svg | 19 ++++++ res/img/info.png | Bin 0 -> 660 bytes res/img/leave.svg | 23 +++++++ res/img/list-close.png | Bin 0 -> 1033 bytes res/img/list-close.svg | 15 ++++ res/img/list-open.png | Bin 0 -> 1059 bytes res/img/list-open.svg | 15 ++++ res/img/maximise.svg | 19 ++++++ res/img/maximize.svg | 9 +++ res/img/member_chevron.png | Bin 0 -> 271 bytes res/img/menu.png | Bin 0 -> 122 bytes res/img/minimise.svg | 18 +++++ res/img/minimize.svg | 8 +++ res/img/mod.svg | 16 +++++ res/img/network-matrix.svg | 14 ++++ res/img/newmessages.png | Bin 0 -> 590 bytes res/img/newmessages.svg | 15 ++++ res/img/notif-active.svg | 20 ++++++ res/img/notif-slider.svg | 22 ++++++ res/img/placeholder.png | Bin 0 -> 394 bytes res/img/plus.svg | 13 ++++ res/img/right_search.svg | 17 +++++ res/img/scrolldown.svg | 15 ++++ res/img/scrollto.svg | 21 ++++++ res/img/scrollup.svg | 91 +++++++++++++++++++++++++ res/img/search-button.svg | 15 ++++ res/img/search-icon-vector.svg | 15 ++++ res/img/search.png | Bin 0 -> 742 bytes res/img/search.svg | 17 +++++ res/img/selected.png | Bin 0 -> 995 bytes res/img/settings-big.png | Bin 0 -> 810 bytes res/img/settings-big.svg | 18 +++++ res/img/settings.png | Bin 0 -> 391 bytes res/img/settings.svg | 12 ++++ res/img/sound-indicator.svg | 17 +++++ res/img/spinner.gif | Bin 0 -> 34411 bytes res/img/stickerpack-placeholder.png | Bin 0 -> 31995 bytes res/img/tick.svg | 12 ++++ res/img/trans.png | Bin 0 -> 959 bytes res/img/typing.png | Bin 0 -> 236 bytes res/img/upload-big.png | Bin 0 -> 1669 bytes res/img/upload-big.svg | 19 ++++++ res/img/upload.png | Bin 0 -> 713 bytes res/img/upload.svg | 19 ++++++ res/img/video-mute.svg | 17 +++++ res/img/video-unmute.svg | 18 +++++ res/img/video.png | Bin 0 -> 514 bytes res/img/voice-mute.svg | 14 ++++ res/img/voice-unmute.svg | 15 ++++ res/img/voice.png | Bin 0 -> 856 bytes res/img/voice.svg | 13 ++++ res/img/voip-chevron.svg | 12 ++++ res/img/voip-mute.png | Bin 0 -> 903 bytes res/img/voip.png | Bin 0 -> 709 bytes res/img/warning.png | Bin 0 -> 1478 bytes res/img/warning.svg | 31 +++++++++ res/img/warning2.png | Bin 0 -> 1420 bytes res/img/warning_yellow.svg | 34 +++++++++ res/img/zoom.png | Bin 0 -> 1288 bytes 435 files changed, 2592 insertions(+) create mode 100644 res/img/50e2c2.png create mode 100644 res/img/76cfa6.png create mode 100644 res/img/80cef4.png create mode 100644 res/img/admin.svg create mode 100644 res/img/attach.png create mode 100644 res/img/avatar-error.svg create mode 100644 res/img/button-md-false.png create mode 100644 res/img/button-md-false.svg create mode 100644 res/img/button-md-false@2x.png create mode 100644 res/img/button-md-false@3x.png create mode 100644 res/img/button-md-true.png create mode 100644 res/img/button-md-true.svg create mode 100644 res/img/button-md-true@2x.png create mode 100644 res/img/button-md-true@3x.png create mode 100644 res/img/button-text-bold-o-n.svg create mode 100644 res/img/button-text-bold.svg create mode 100644 res/img/button-text-bullet-o-n.svg create mode 100644 res/img/button-text-bullet.svg create mode 100644 res/img/button-text-code-o-n.svg create mode 100644 res/img/button-text-code.svg create mode 100644 res/img/button-text-formatting.svg create mode 100644 res/img/button-text-italic-o-n.svg create mode 100644 res/img/button-text-italic.svg create mode 100644 res/img/button-text-numbullet-o-n.svg create mode 100644 res/img/button-text-numbullet.svg create mode 100644 res/img/button-text-quote-o-n.svg create mode 100644 res/img/button-text-quote.svg create mode 100644 res/img/button-text-strike-o-n.svg create mode 100644 res/img/button-text-strike.svg create mode 100644 res/img/button-text-underline-o-n.svg create mode 100644 res/img/button-text-underline.svg create mode 100644 res/img/call.png create mode 100644 res/img/call.svg create mode 100644 res/img/camera.svg create mode 100644 res/img/camera_green.svg create mode 100644 res/img/cancel-black.png create mode 100644 res/img/cancel-black2.png create mode 100644 res/img/cancel-red.svg create mode 100644 res/img/cancel-small.svg create mode 100644 res/img/cancel-white.svg create mode 100644 res/img/cancel.png create mode 100644 res/img/cancel.svg create mode 100644 res/img/cancel_green.svg create mode 100644 res/img/chevron-left.png create mode 100644 res/img/chevron-right.png create mode 100644 res/img/chevron.png create mode 100644 res/img/close-white.png create mode 100644 res/img/create-big.png create mode 100644 res/img/create-big.svg create mode 100644 res/img/create.png create mode 100644 res/img/delete.png create mode 100644 res/img/directory-big.png create mode 100644 res/img/directory-big.svg create mode 100644 res/img/download.png create mode 100644 res/img/download.svg create mode 100644 res/img/e2e-blocked.svg create mode 100644 res/img/e2e-unencrypted.svg create mode 100644 res/img/e2e-verified.svg create mode 100644 res/img/e2e-warning.svg create mode 100644 res/img/edit.png create mode 100644 res/img/edit.svg create mode 100644 res/img/edit_green.svg create mode 100644 res/img/ellipsis.svg create mode 100644 res/img/eol.svg create mode 100644 res/img/f4c371.png create mode 100644 res/img/file.png create mode 100644 res/img/filegrid.png create mode 100644 res/img/fileicon.png create mode 100644 res/img/filelist.png create mode 100644 res/img/files.png create mode 100644 res/img/files.svg create mode 100644 res/img/flags/AD.png create mode 100644 res/img/flags/AE.png create mode 100644 res/img/flags/AF.png create mode 100644 res/img/flags/AG.png create mode 100644 res/img/flags/AI.png create mode 100644 res/img/flags/AL.png create mode 100644 res/img/flags/AM.png create mode 100644 res/img/flags/AO.png create mode 100644 res/img/flags/AQ.png create mode 100644 res/img/flags/AR.png create mode 100644 res/img/flags/AS.png create mode 100644 res/img/flags/AT.png create mode 100644 res/img/flags/AU.png create mode 100644 res/img/flags/AW.png create mode 100644 res/img/flags/AX.png create mode 100644 res/img/flags/AZ.png create mode 100644 res/img/flags/BA.png create mode 100644 res/img/flags/BB.png create mode 100644 res/img/flags/BD.png create mode 100644 res/img/flags/BE.png create mode 100644 res/img/flags/BF.png create mode 100644 res/img/flags/BG.png create mode 100644 res/img/flags/BH.png create mode 100644 res/img/flags/BI.png create mode 100644 res/img/flags/BJ.png create mode 100644 res/img/flags/BL.png create mode 100644 res/img/flags/BM.png create mode 100644 res/img/flags/BN.png create mode 100644 res/img/flags/BO.png create mode 100644 res/img/flags/BQ.png create mode 100644 res/img/flags/BR.png create mode 100644 res/img/flags/BS.png create mode 100644 res/img/flags/BT.png create mode 100644 res/img/flags/BV.png create mode 100644 res/img/flags/BW.png create mode 100644 res/img/flags/BY.png create mode 100644 res/img/flags/BZ.png create mode 100644 res/img/flags/CA.png create mode 100644 res/img/flags/CC.png create mode 100644 res/img/flags/CD.png create mode 100644 res/img/flags/CF.png create mode 100644 res/img/flags/CG.png create mode 100644 res/img/flags/CH.png create mode 100644 res/img/flags/CI.png create mode 100644 res/img/flags/CK.png create mode 100644 res/img/flags/CL.png create mode 100644 res/img/flags/CM.png create mode 100644 res/img/flags/CN.png create mode 100644 res/img/flags/CO.png create mode 100644 res/img/flags/CR.png create mode 100644 res/img/flags/CU.png create mode 100644 res/img/flags/CV.png create mode 100644 res/img/flags/CW.png create mode 100644 res/img/flags/CX.png create mode 100644 res/img/flags/CY.png create mode 100644 res/img/flags/CZ.png create mode 100644 res/img/flags/DE.png create mode 100644 res/img/flags/DJ.png create mode 100644 res/img/flags/DK.png create mode 100644 res/img/flags/DM.png create mode 100644 res/img/flags/DO.png create mode 100644 res/img/flags/DZ.png create mode 100644 res/img/flags/EC.png create mode 100644 res/img/flags/EE.png create mode 100644 res/img/flags/EG.png create mode 100644 res/img/flags/EH.png create mode 100644 res/img/flags/ER.png create mode 100644 res/img/flags/ES.png create mode 100644 res/img/flags/ET.png create mode 100644 res/img/flags/FI.png create mode 100644 res/img/flags/FJ.png create mode 100644 res/img/flags/FK.png create mode 100644 res/img/flags/FM.png create mode 100644 res/img/flags/FO.png create mode 100644 res/img/flags/FR.png create mode 100644 res/img/flags/GA.png create mode 100644 res/img/flags/GB.png create mode 100644 res/img/flags/GD.png create mode 100644 res/img/flags/GE.png create mode 100644 res/img/flags/GF.png create mode 100644 res/img/flags/GG.png create mode 100644 res/img/flags/GH.png create mode 100644 res/img/flags/GI.png create mode 100644 res/img/flags/GL.png create mode 100644 res/img/flags/GM.png create mode 100644 res/img/flags/GN.png create mode 100644 res/img/flags/GP.png create mode 100644 res/img/flags/GQ.png create mode 100644 res/img/flags/GR.png create mode 100644 res/img/flags/GS.png create mode 100644 res/img/flags/GT.png create mode 100644 res/img/flags/GU.png create mode 100644 res/img/flags/GW.png create mode 100644 res/img/flags/GY.png create mode 100644 res/img/flags/HK.png create mode 100644 res/img/flags/HM.png create mode 100644 res/img/flags/HN.png create mode 100644 res/img/flags/HR.png create mode 100644 res/img/flags/HT.png create mode 100644 res/img/flags/HU.png create mode 100644 res/img/flags/ID.png create mode 100644 res/img/flags/IE.png create mode 100644 res/img/flags/IL.png create mode 100644 res/img/flags/IM.png create mode 100644 res/img/flags/IN.png create mode 100644 res/img/flags/IO.png create mode 100644 res/img/flags/IQ.png create mode 100644 res/img/flags/IR.png create mode 100644 res/img/flags/IS.png create mode 100644 res/img/flags/IT.png create mode 100644 res/img/flags/JE.png create mode 100644 res/img/flags/JM.png create mode 100644 res/img/flags/JO.png create mode 100644 res/img/flags/JP.png create mode 100644 res/img/flags/KE.png create mode 100644 res/img/flags/KG.png create mode 100644 res/img/flags/KH.png create mode 100644 res/img/flags/KI.png create mode 100644 res/img/flags/KM.png create mode 100644 res/img/flags/KN.png create mode 100644 res/img/flags/KP.png create mode 100644 res/img/flags/KR.png create mode 100644 res/img/flags/KW.png create mode 100644 res/img/flags/KY.png create mode 100644 res/img/flags/KZ.png create mode 100644 res/img/flags/LA.png create mode 100644 res/img/flags/LB.png create mode 100644 res/img/flags/LC.png create mode 100644 res/img/flags/LI.png create mode 100644 res/img/flags/LK.png create mode 100644 res/img/flags/LR.png create mode 100644 res/img/flags/LS.png create mode 100644 res/img/flags/LT.png create mode 100644 res/img/flags/LU.png create mode 100644 res/img/flags/LV.png create mode 100644 res/img/flags/LY.png create mode 100644 res/img/flags/MA.png create mode 100644 res/img/flags/MC.png create mode 100644 res/img/flags/MD.png create mode 100644 res/img/flags/ME.png create mode 100644 res/img/flags/MF.png create mode 100644 res/img/flags/MG.png create mode 100644 res/img/flags/MH.png create mode 100644 res/img/flags/MK.png create mode 100644 res/img/flags/ML.png create mode 100644 res/img/flags/MM.png create mode 100644 res/img/flags/MN.png create mode 100644 res/img/flags/MO.png create mode 100644 res/img/flags/MP.png create mode 100644 res/img/flags/MQ.png create mode 100644 res/img/flags/MR.png create mode 100644 res/img/flags/MS.png create mode 100644 res/img/flags/MT.png create mode 100644 res/img/flags/MU.png create mode 100644 res/img/flags/MV.png create mode 100644 res/img/flags/MW.png create mode 100644 res/img/flags/MX.png create mode 100644 res/img/flags/MY.png create mode 100644 res/img/flags/MZ.png create mode 100644 res/img/flags/NA.png create mode 100644 res/img/flags/NC.png create mode 100644 res/img/flags/NE.png create mode 100644 res/img/flags/NF.png create mode 100644 res/img/flags/NG.png create mode 100644 res/img/flags/NI.png create mode 100644 res/img/flags/NL.png create mode 100644 res/img/flags/NO.png create mode 100644 res/img/flags/NP.png create mode 100644 res/img/flags/NR.png create mode 100644 res/img/flags/NU.png create mode 100644 res/img/flags/NZ.png create mode 100644 res/img/flags/OM.png create mode 100644 res/img/flags/PA.png create mode 100644 res/img/flags/PE.png create mode 100644 res/img/flags/PF.png create mode 100644 res/img/flags/PG.png create mode 100644 res/img/flags/PH.png create mode 100644 res/img/flags/PK.png create mode 100644 res/img/flags/PL.png create mode 100644 res/img/flags/PM.png create mode 100644 res/img/flags/PN.png create mode 100644 res/img/flags/PR.png create mode 100644 res/img/flags/PS.png create mode 100644 res/img/flags/PT.png create mode 100644 res/img/flags/PW.png create mode 100644 res/img/flags/PY.png create mode 100644 res/img/flags/QA.png create mode 100644 res/img/flags/RE.png create mode 100644 res/img/flags/RO.png create mode 100644 res/img/flags/RS.png create mode 100644 res/img/flags/RU.png create mode 100644 res/img/flags/RW.png create mode 100644 res/img/flags/SA.png create mode 100644 res/img/flags/SB.png create mode 100644 res/img/flags/SC.png create mode 100644 res/img/flags/SD.png create mode 100644 res/img/flags/SE.png create mode 100644 res/img/flags/SG.png create mode 100644 res/img/flags/SH.png create mode 100644 res/img/flags/SI.png create mode 100644 res/img/flags/SJ.png create mode 100644 res/img/flags/SK.png create mode 100644 res/img/flags/SL.png create mode 100644 res/img/flags/SM.png create mode 100644 res/img/flags/SN.png create mode 100644 res/img/flags/SO.png create mode 100644 res/img/flags/SR.png create mode 100644 res/img/flags/SS.png create mode 100644 res/img/flags/ST.png create mode 100644 res/img/flags/SV.png create mode 100644 res/img/flags/SX.png create mode 100644 res/img/flags/SY.png create mode 100644 res/img/flags/SZ.png create mode 100644 res/img/flags/TC.png create mode 100644 res/img/flags/TD.png create mode 100644 res/img/flags/TF.png create mode 100644 res/img/flags/TG.png create mode 100644 res/img/flags/TH.png create mode 100644 res/img/flags/TJ.png create mode 100644 res/img/flags/TK.png create mode 100644 res/img/flags/TL.png create mode 100644 res/img/flags/TM.png create mode 100644 res/img/flags/TN.png create mode 100644 res/img/flags/TO.png create mode 100644 res/img/flags/TR.png create mode 100644 res/img/flags/TT.png create mode 100644 res/img/flags/TV.png create mode 100644 res/img/flags/TW.png create mode 100644 res/img/flags/TZ.png create mode 100644 res/img/flags/UA.png create mode 100644 res/img/flags/UG.png create mode 100644 res/img/flags/US.png create mode 100644 res/img/flags/UY.png create mode 100644 res/img/flags/UZ.png create mode 100644 res/img/flags/VA.png create mode 100644 res/img/flags/VC.png create mode 100644 res/img/flags/VE.png create mode 100644 res/img/flags/VG.png create mode 100644 res/img/flags/VI.png create mode 100644 res/img/flags/VN.png create mode 100644 res/img/flags/VU.png create mode 100644 res/img/flags/WF.png create mode 100644 res/img/flags/WS.png create mode 100644 res/img/flags/YE.png create mode 100644 res/img/flags/YT.png create mode 100644 res/img/flags/ZA.png create mode 100644 res/img/flags/ZM.png create mode 100644 res/img/flags/ZW.png create mode 100644 res/img/fullscreen.svg create mode 100644 res/img/hangup.svg create mode 100644 res/img/hide.png create mode 100644 res/img/icon-address-delete.svg create mode 100644 res/img/icon-call.svg create mode 100644 res/img/icon-context-delete.svg create mode 100644 res/img/icon-context-fave-on.svg create mode 100644 res/img/icon-context-fave.svg create mode 100644 res/img/icon-context-low-on.svg create mode 100644 res/img/icon-context-low.svg create mode 100644 res/img/icon-context-mute-mentions.svg create mode 100644 res/img/icon-context-mute-off-copy.svg create mode 100644 res/img/icon-context-mute-off.svg create mode 100644 res/img/icon-context-mute.svg create mode 100644 res/img/icon-delete-pink.svg create mode 100644 res/img/icon-email-user.svg create mode 100644 res/img/icon-invite-people.svg create mode 100644 res/img/icon-mx-user.svg create mode 100644 res/img/icon-return.svg create mode 100644 res/img/icon-text-cancel.svg create mode 100644 res/img/icon_context_delete.svg create mode 100644 res/img/icon_context_fave.svg create mode 100644 res/img/icon_context_fave_on.svg create mode 100644 res/img/icon_context_low.svg create mode 100644 res/img/icon_context_low_on.svg create mode 100644 res/img/icon_context_message.svg create mode 100644 res/img/icon_context_message_dark.svg create mode 100644 res/img/icon_context_person.svg create mode 100644 res/img/icon_context_person_on.svg create mode 100644 res/img/icon_copy_message.svg create mode 100644 res/img/icon_copy_message_dark.svg create mode 100644 res/img/icon_person.svg create mode 100644 res/img/icons-apps-active.svg create mode 100644 res/img/icons-apps.svg create mode 100644 res/img/icons-close-button.svg create mode 100644 res/img/icons-close.svg create mode 100644 res/img/icons-create-room.svg create mode 100644 res/img/icons-directory.svg create mode 100644 res/img/icons-files.svg create mode 100644 res/img/icons-groups.svg create mode 100644 res/img/icons-hide-apps.svg create mode 100644 res/img/icons-hide-stickers.svg create mode 100644 res/img/icons-home.svg create mode 100644 res/img/icons-notifications.svg create mode 100644 res/img/icons-people.svg create mode 100644 res/img/icons-pin.svg create mode 100644 res/img/icons-room-add.svg create mode 100644 res/img/icons-room.svg create mode 100644 res/img/icons-search-copy.svg create mode 100644 res/img/icons-search.svg create mode 100644 res/img/icons-settings-room.svg create mode 100644 res/img/icons-settings.svg create mode 100644 res/img/icons-show-apps.svg create mode 100644 res/img/icons-show-stickers.svg create mode 100644 res/img/icons-upload.svg create mode 100644 res/img/icons-video.svg create mode 100644 res/img/icons_ellipsis.svg create mode 100644 res/img/icons_global.svg create mode 100644 res/img/info.png create mode 100644 res/img/leave.svg create mode 100644 res/img/list-close.png create mode 100644 res/img/list-close.svg create mode 100644 res/img/list-open.png create mode 100644 res/img/list-open.svg create mode 100644 res/img/maximise.svg create mode 100644 res/img/maximize.svg create mode 100644 res/img/member_chevron.png create mode 100755 res/img/menu.png create mode 100644 res/img/minimise.svg create mode 100644 res/img/minimize.svg create mode 100644 res/img/mod.svg create mode 100644 res/img/network-matrix.svg create mode 100644 res/img/newmessages.png create mode 100644 res/img/newmessages.svg create mode 100644 res/img/notif-active.svg create mode 100644 res/img/notif-slider.svg create mode 100644 res/img/placeholder.png create mode 100644 res/img/plus.svg create mode 100644 res/img/right_search.svg create mode 100644 res/img/scrolldown.svg create mode 100644 res/img/scrollto.svg create mode 100644 res/img/scrollup.svg create mode 100644 res/img/search-button.svg create mode 100644 res/img/search-icon-vector.svg create mode 100644 res/img/search.png create mode 100644 res/img/search.svg create mode 100644 res/img/selected.png create mode 100644 res/img/settings-big.png create mode 100644 res/img/settings-big.svg create mode 100644 res/img/settings.png create mode 100644 res/img/settings.svg create mode 100644 res/img/sound-indicator.svg create mode 100644 res/img/spinner.gif create mode 100644 res/img/stickerpack-placeholder.png create mode 100644 res/img/tick.svg create mode 100644 res/img/trans.png create mode 100644 res/img/typing.png create mode 100644 res/img/upload-big.png create mode 100644 res/img/upload-big.svg create mode 100644 res/img/upload.png create mode 100644 res/img/upload.svg create mode 100644 res/img/video-mute.svg create mode 100644 res/img/video-unmute.svg create mode 100644 res/img/video.png create mode 100644 res/img/voice-mute.svg create mode 100644 res/img/voice-unmute.svg create mode 100644 res/img/voice.png create mode 100644 res/img/voice.svg create mode 100644 res/img/voip-chevron.svg create mode 100644 res/img/voip-mute.png create mode 100644 res/img/voip.png create mode 100644 res/img/warning.png create mode 100644 res/img/warning.svg create mode 100644 res/img/warning2.png create mode 100644 res/img/warning_yellow.svg create mode 100644 res/img/zoom.png diff --git a/res/img/50e2c2.png b/res/img/50e2c2.png new file mode 100644 index 0000000000000000000000000000000000000000..ee0f85589570374f5e1dec95ff7867a6c731f7bf GIT binary patch literal 146 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU1SFZ~=vx6P$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1GCY~;iAr-gYoMq%?FyLTNsC6=qKC0CJ@Yw=}$jcia9u?Xc lp(ECPGzm(5JoK5}9zRXo-e*BT{2x!jlba~f)fL#_S zPKHs^AQEgz+SyGb$33DP^yt73E&12G_cHK3OMa-^$c}1s=c4SIJM-dE*A4_8_Hk`;YXG{Gu5?QpvGbfbfuJcQON*?si?YP6pd}5 zAytQ{01GIu6>t&Zq6X%lEV9L3AGb+ko=dDOdB}N$AsmfH%BY~QcmP$?G$GQUrsV}9 zpNvE9r1>z}S||{jxUnB`pM@Y(bb9QBTe5IEJ3x zgJ6kHc$;4MT`8P&#u0^Wny{1D6&Kgv%2GwR7E_0_xWm}-qKd5{<187n2-IrRs)3yC zxPF*z-k!2-8#lv*JE2RP#FB-M;`<)18ahF$Rx;F*s;YIpTvQEGZV*i`HmamtUT_I> zPXZe91=qXa8kcgjh6o~&nb6pOLcK=J0x&%|_E&hRBa@&CG7YsrR(qLoy%k>O+{&d~ zD9pg@djGlZ#g^!yY`Sb-u~@c04Moq#qPgWC_^Wsr#U`nA(l0+hUD=e-x&)pMw+=tt we|i4xwRHIT^!)7lX?Od^i?iN5{67104M}_M+MV&+@7cqYn)QA1ruyjFUsIba9{>OV literal 0 HcmV?d00001 diff --git a/res/img/80cef4.png b/res/img/80cef4.png new file mode 100644 index 0000000000000000000000000000000000000000..637d03f63cd8258eb5605eb001ac2c51828ec6aa GIT binary patch literal 146 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU1SFZ~=vx6P$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1GCY~;iAr-gYoMq%?FyLTNs4Wtnb&R3^;j;w{k+vHj9u?Xc mp(ECPGzm(5Jo + + + icons_owner + Created with sketchtool. + + + + + + + + + + + + diff --git a/res/img/attach.png b/res/img/attach.png new file mode 100644 index 0000000000000000000000000000000000000000..1bcb70045d457e1b96c03a89b6652c3c720137e5 GIT binary patch literal 369 zcmV-%0gnEOP)S8 zD2f_}0rz*kj^}wVo+3va$H$j^2uKSak7=Ig0D$#ek|d%iE<06KHBGagoTf=t)ono( zMbBP@8Wm$${Y!350zb()-4S(;FBps*d9|bJS>bkyb2_SuazX~t_q8w+Y1HH_H P00000NkvXXu0mjfe{z=) literal 0 HcmV?d00001 diff --git a/res/img/avatar-error.svg b/res/img/avatar-error.svg new file mode 100644 index 0000000000..c5e168944c --- /dev/null +++ b/res/img/avatar-error.svg @@ -0,0 +1,15 @@ + + + + 5EF602F6-A36C-41EE-BAEC-50801DFD5492 + Created with sketchtool. + + + + + + + + + + diff --git a/res/img/button-md-false.png b/res/img/button-md-false.png new file mode 100644 index 0000000000000000000000000000000000000000..6debbccc937a75e1a07a2a36518e221efb696823 GIT binary patch literal 569 zcmV-90>=G`P)Px$^GQTOR5%f>lTAwkQ51&nI5U20n$SW62`sRMghb#f7w+1H`X`irKr45x3;Gkf zOl*-LxR6$YU$_&bjn+a?upCi)&)^-#VcLWT4)@G^&w1vYJ9h*I%VaWQDwVQOybr5Z ztLsv!v=W-lX4>g=mIOiA2UlY(m&>$dv)S&fRx2alv*j%?3ASf0V>k(U=bS}ROol=s zo7?R^#O5b|BO16Tog8|d>sS??{-)E_a0d?M3&o1h=bMbj2|wM09|qjtvDJdyjQE$+*~gd3esw|dY{kdVXplNr-VQtFu;G1gY$g- zdK8I7nw3h0HZ9p~_7z8RVYl1q5~z7Q7aZLr+wHc9v67sE2`IDcCGCQ&us*)}2Ja=8+8&U!HINf2k- zBz2KxnUNcffHbn18KIN|?o`6%&*P7LM6uVb@IRUgmZaP-lh~_%7EU=y00000NkvXX Hu0mjflU)I? literal 0 HcmV?d00001 diff --git a/res/img/button-md-false.svg b/res/img/button-md-false.svg new file mode 100644 index 0000000000..6414933d96 --- /dev/null +++ b/res/img/button-md-false.svg @@ -0,0 +1,29 @@ + + + + D335F9E8-C813-47D7-B1BE-C8DEF2C8214F + Created with sketchtool. + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/button-md-false@2x.png b/res/img/button-md-false@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..497f5385d140cfda7cd24c5b79cf3871a700b017 GIT binary patch literal 1086 zcmV-E1i|}>P)Px&_(?=TR9FesS6@g|VHDqgbz`!J%|BC;>|v;E;Db;?U>5DAmmq?C>q&%q2#O$l zis-?hw+bJkmx_X(5=TBn3`R}d5SdbIMk+e7hat{suDSI)mwlJ-UU% zc&`=!mcwv(c=)iduWwvGH#awAx7$B42fbdeGZ+j^tVxSw$?@$h+}8=iDB945X5jSZipS%F0Fq^qk)eUMwzdqDc?tk}0*y()s}=cdHftdJa#`05oKE!n z{l8MF)Hw={EMM#F?EJ2XPuj z#7|94SzB9MXNj+50l*mmdIwvjk`uzr&(Dvb`5$L8867?H_dr#^5!r&d9iEw)v2}NM ze}L?w(<;5Fp;Ruft*ucxlms7*Mu(f4nqE;%TDTS*xw%#goZ_A8?d?q=`)5g@j}IIs z{Xc0#VZnZEWo2a?+Y<2MaM*|Y_DAN1_`;Q&$&CIBaC-Sz=;MPx6NSv;Rz%Sk_W}Mo zGY*A9Cmaq(l*#msK)_2aO;e>*00N6lYX;3?0sQmj<>gI0vreZo2EBj@dZ9#^ot!EH zM-yGdD0)jxf#wjtGLYHx^6sX9T&CURLpF3-Djp`8Kym;iqRURVM*uyV5bof>-0i`!ZgI77X}nzNr}0@w6yI01q7Z{+`rz{BLDyZ07*qoM6N<$ Ef*aWjwEzGB literal 0 HcmV?d00001 diff --git a/res/img/button-md-false@3x.png b/res/img/button-md-false@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..1184e6b351ec17fb2e1f8cdaa866ea3d81d5cb07 GIT binary patch literal 1548 zcmV+n2J`ueP)Px)#z{m$RA>e5T3t+IMHIfbEzt58HUUzK6=jjlVvQRkAgq56ZcKRa!A%JA6I zqdpj4HmQjTlI)8QMq;eClwXk{!G`xHTO4Om186mfcb`X&JBE;JzI{sNeR zmX?+taddRFv8JZxZ@GXdiUNR=lTZBn>gwvFrqa^VCs|JkjFOTP!DKSAb(a4ets*c%VO_?7AMj->9?;+8@#Hk_78{sKjT3UJ&1ltMzvUJtpYM z3KU(YPknv;T{!s~&p4I_nJAXLRwY1K*?iV@0fig@FgLfix4*_TO6SiDb#-;&bOP(^ z>xP}39f5wB0_jB4^48YYjM?hZ4HQ@ycez||!;o>FwTO;u0B(%OV`%`^h?A>8zy1Av zmZhn_v9V#uR*#;b2!n%z`?IsNFYfN{rsN&~@*M#AM3Yx}6xJ0K@}sM(>mCkO&q$*T zKq#>~^XQ}Iu5|~6ENE+M^C34}L4G+FiB*nTPC%hf91h1fi;IhoWlF4agO0*`&Om{4 z@s5s;e~yBaT5UKqD8s|UWkW+lm0CI;A0NM$FGB3;Ir=!;B3nfN%P*%8^?%_ZAbH&94vadGjDxw*M>YzGH* z(d+eogmceJ9G)r?qU9X`^MNX1j!+;FI0GHiI3$`-3et}ws{i*CeDwDCe7=;=2on<% zmjKv@JOi}Q;L!E?`S~}rv>{nq3^q46eUV6{9NT|E`q9~l_vjia)B#4IysE0|HgZft z_d#O)k=J=PG{(U@?`Z)c*<6A`BT>nY2#pY&VQtL1j%YMgR#y5v z9#1t#iHMc(bM$|iNe$BWYx$QYmCvqtw;`OexM*caXQ(#4aMyyKu?( zE~|(7#imi!RdCKhA;Ty_$RIrdksJmv*5>AB4<%HhVd=ku{_guIP7y)_qvlb)qs50K zTPPF?l2U|hQaeJ}uBIayAQtFKjBYp_7O;m%>Vw?FYV@%(0Onk0XXmeokk0^!o8?iR z0HJ|V`=|y53hx4#gx;p6CINc}wSDm9&O+BZF)Au51e~3CGFoXDF+dl$wzg7i%jVAl z$q~|O!BLc_Xk-&9C3RZuv_4uQC8=9!ZYt4}4LKEZM5&z;ouej6qBfMj=q4cBl`bn# zXf*VC2o!AQ^ir45L%?JU2q`#G(?>644anSygr}Fn9LhL*b~a2- yPPSB6S3eF$MP4m@fSpqgfxljyq5K30b^RY({^*N^6Hc%I0000Px$ok>JNR5%f}Q@=~YP!R4*qDv@tQgBgpu#<=o2mb*jZDSmCaQDZigR9Wpx;VJ_ zCj?Yd(o(nn8C}Iq$0}-)#_!TxcuzVg#0SZD_uakk-Q7z>k|d(hXv`aiF;yyP#c@1r zx7)9xR;%6NfZc+0a~Vz3&NO&CIa8o98jTzcRnr0gv2;aP*Y!ipzAA*+#}o63uy2UZ zVqX&fB=PUeGa76V;v$|qoz4K}0C%wfyu{PDEbFw{Y(}t4wrwYbw9s|v`#$9>Jo&Vg z%E#3B9RxuO60PP>s zCJ3*vCoN}Q|5@tzVAi3$Kk--c6To{Ir=xh^QIf|k#A;$?7aa3#9>-9x!T$7W) zSHPbThw5~WA#VvC^x%`|Ec1*){Uei&w|7h8Fc$WW4VBFgcg+%DVcwCp!bF? Zt#3CFoq7f*3)uhw002ovPDHLkV1lx_+k^lB literal 0 HcmV?d00001 diff --git a/res/img/button-md-true.svg b/res/img/button-md-true.svg new file mode 100644 index 0000000000..2acc4f675c --- /dev/null +++ b/res/img/button-md-true.svg @@ -0,0 +1,14 @@ + + + + 2A63B135-4281-4FBB-A88C-012AE22E9594 + Created with sketchtool. + + + + + + + + + \ No newline at end of file diff --git a/res/img/button-md-true@2x.png b/res/img/button-md-true@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..ad9067f385b2fbb975c6df7a006adab817800751 GIT binary patch literal 906 zcmV;519kj~P)Px&L`g(JR9Fesmpf=vQ5eU2la^>xMT0}ZL8l5na4B}Ex+o}plA(jtpjaq~RK%g9 zwnM>+2t`Fid_ZxK^g(Jae~KP!xe-|ufpCX)}~TWS@w z;4%y&13wlHhtCG<&wHjDc)A8ghHV= zOm>W9Sv?`TsMqT~QVd%6`PaNH;A-;u`T1Fw%QYrI0R5dZ@&h_9y49ezfh$n0t*z$) z99BH^#N6E6E5)zos0ui5n+)~b59rgJ!2Q((EOS`~t{!4TLqi@3q%^*Av95@$XkTAn zlP>>H-ZJpT#l@y*Goa%}$CI02wq4*Ri z6AjR=Ua-^G3rd*5!NG=DEEa_QqU(!!Kty~#-+{@=$waYDWO8p6p3T?-|BP?5=!9C{ zaR~tYL{CpoyU2L)z#IN zOUMZfko=@dW@X@en1$Yk=KjQ(#RLKYFE2pVwYHhrm984#bxhjKH_cJ*hnB4SQj-#M zlm%Zhv#ZnKRHpISV`dj!Rlrp+iQA~zr?7=iBS|gNvz*$n?n_RC)3^gYr0dQ2s)4Iy zOyD+4YE?%$jB{$o#h-;-CTG9M<*2Q$QZCV7*luzWms!LPK%cRi$6&=P9!wHQ87#xc zM25Oayi=3S*l)zWFEZ>RuF}b>7op{ntoWwIlV}8S9DLZ6_e_YZ4 zS98>nz_|~(+FPo*?W_QZd$dHIyRKI7t0^;}KLThr_p?i9383(!*jQ62H85QI3>aT~ gJf4d)GczB41OD$WoQHsRivR!s07*qoM6N<$g6lN16951J literal 0 HcmV?d00001 diff --git a/res/img/button-md-true@3x.png b/res/img/button-md-true@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..d615867dc4604e2f898fb0f15e4e2b19e5bd0bf5 GIT binary patch literal 1201 zcmV;i1Wx;jP)Px(Ye_^wRA>e5noCGjQ5eUaM^>7c^rSWg8AJ<%#%L2E5rMCqXre`i77;`S6>XwG z6c;UeLPgNV$_NApQHK&*v=RhcL_sC40$WHyj~SEH>34>%-VW#FnVCB|dFR66p7XuV z`TqAi-~H|*FE4lG5HLZ&V+n;qp{3*FiAJc0j> zhp)Phj*hQ7nQWmu0*Y{k?KR}}dQWN`BhusbJv}{dHTz9$LSXM19muae`ShzYF33mA3u zzsQqj``ENjN!kyQc#~Gj5{0xQg<|ViQ&ZDoQ-63Dyo|!C-c)`*8JZG8apWG+C2u4ABJYZ0xJ#jh8J?FY0{7SlmXc|LS+l8X-6?IzP_ z+up;*eiNOP7pXGNq-$th_QWd^E3`0exk|^BhQ60=_Yi>hnCe(^L~tAW$F1>PXGcL1 zlQH>B;-#NRtelfgtjcv`C!ZF^$?Zx31(E1FgU&?-OG|Pbl;1NovhY(})kI>|&Yl7T z2a9Nt+S=MpbE&h2!^qs2OHSrz3KS7BH<_$Op3tH3YCiM!69sE^_5f`!yms2m_i~-A zOwSl7OymccjM>NbMsmzka#peI6o3Q(tqYlanP)Q2*rH7)Pge$~%c9X}x2QiXTfty( z^W@}Y1fJ0=O-s*ycB*)@+x*x4-P9kCiI~vD#Kan!_*p=_Gfw$10);SL!tWY8RkKi7 zCH?yb_SWg_5%!|qN$Mafg47}RIg7i}hNP4g!XA>9@~yf;))gckDJuT!oRX=llmkV9 zYz~whC<+7=B=L|HQ_x*Y0*|Qplj)Uf5s(}QkSR!SL{7OQ@!ULY=PPE+%WJ!bpm2@m z>UxDJd0tRZa85+T%oC(|h@v{(ODjcShAxB_@ + + + 01F3F9B2-8F38-4BAF-A345-AECAC3D88E79 + Created with sketchtool. + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/button-text-bold.svg b/res/img/button-text-bold.svg new file mode 100644 index 0000000000..0fd0baa07e --- /dev/null +++ b/res/img/button-text-bold.svg @@ -0,0 +1,17 @@ + + + + 9BC64A5B-F157-43FF-BCC4-02D30CDF520B + Created with sketchtool. + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/button-text-bullet-o-n.svg b/res/img/button-text-bullet-o-n.svg new file mode 100644 index 0000000000..d4a40e889c --- /dev/null +++ b/res/img/button-text-bullet-o-n.svg @@ -0,0 +1,20 @@ + + + + 654917CF-20A4-49B6-B0A1-9875D7B733C8 + Created with sketchtool. + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/button-text-bullet.svg b/res/img/button-text-bullet.svg new file mode 100644 index 0000000000..ae3e640d8e --- /dev/null +++ b/res/img/button-text-bullet.svg @@ -0,0 +1,20 @@ + + + + B7D94619-44BC-4184-A60A-DBC5BB54E5F9 + Created with sketchtool. + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/button-text-code-o-n.svg b/res/img/button-text-code-o-n.svg new file mode 100644 index 0000000000..8d1439c97b --- /dev/null +++ b/res/img/button-text-code-o-n.svg @@ -0,0 +1,25 @@ + + + + B76754AB-42E6-48D2-9443-80CBC0DE02ED + Created with sketchtool. + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/button-text-code.svg b/res/img/button-text-code.svg new file mode 100644 index 0000000000..24026cb709 --- /dev/null +++ b/res/img/button-text-code.svg @@ -0,0 +1,25 @@ + + + + 4CAFF494-61AE-4916-AFE8-D1E62F7CF0DE + Created with sketchtool. + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/button-text-formatting.svg b/res/img/button-text-formatting.svg new file mode 100644 index 0000000000..d697010d40 --- /dev/null +++ b/res/img/button-text-formatting.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + diff --git a/res/img/button-text-italic-o-n.svg b/res/img/button-text-italic-o-n.svg new file mode 100644 index 0000000000..15fe588596 --- /dev/null +++ b/res/img/button-text-italic-o-n.svg @@ -0,0 +1,17 @@ + + + + 116426C2-0B55-480E-92B3-57D4B3ABAB90 + Created with sketchtool. + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/button-text-italic.svg b/res/img/button-text-italic.svg new file mode 100644 index 0000000000..b5722e827b --- /dev/null +++ b/res/img/button-text-italic.svg @@ -0,0 +1,17 @@ + + + + 9FBC844D-96CF-4DCB-B545-FCD23727218B + Created with sketchtool. + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/button-text-numbullet-o-n.svg b/res/img/button-text-numbullet-o-n.svg new file mode 100644 index 0000000000..869a2c2cc2 --- /dev/null +++ b/res/img/button-text-numbullet-o-n.svg @@ -0,0 +1,20 @@ + + + + 294F929B-31AA-4D0C-98B3-9CA96764060D + Created with sketchtool. + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/button-text-numbullet.svg b/res/img/button-text-numbullet.svg new file mode 100644 index 0000000000..8e5b8b87b6 --- /dev/null +++ b/res/img/button-text-numbullet.svg @@ -0,0 +1,20 @@ + + + + F0F58459-A13A-48C5-9332-ABFB96726F05 + Created with sketchtool. + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/button-text-quote-o-n.svg b/res/img/button-text-quote-o-n.svg new file mode 100644 index 0000000000..f8a86125c9 --- /dev/null +++ b/res/img/button-text-quote-o-n.svg @@ -0,0 +1,17 @@ + + + + 3B24B8C7-64BE-4B3E-A748-94DB72E1210F + Created with sketchtool. + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/button-text-quote.svg b/res/img/button-text-quote.svg new file mode 100644 index 0000000000..d70c261f5d --- /dev/null +++ b/res/img/button-text-quote.svg @@ -0,0 +1,17 @@ + + + + BFC0418B-9081-4789-A231-B75953157748 + Created with sketchtool. + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/button-text-strike-o-n.svg b/res/img/button-text-strike-o-n.svg new file mode 100644 index 0000000000..2914fcabe6 --- /dev/null +++ b/res/img/button-text-strike-o-n.svg @@ -0,0 +1,18 @@ + + + + 69B11088-0F3A-4E14-BD9F-4FEF4115E99B + Created with sketchtool. + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/button-text-strike.svg b/res/img/button-text-strike.svg new file mode 100644 index 0000000000..5f262dc350 --- /dev/null +++ b/res/img/button-text-strike.svg @@ -0,0 +1,18 @@ + + + + A34F2223-34C6-46AE-AA47-38EC8984E9B3 + Created with sketchtool. + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/button-text-underline-o-n.svg b/res/img/button-text-underline-o-n.svg new file mode 100644 index 0000000000..870be3ce6a --- /dev/null +++ b/res/img/button-text-underline-o-n.svg @@ -0,0 +1,18 @@ + + + + FD84FF7C-43E4-4312-90AB-5A59AD018377 + Created with sketchtool. + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/button-text-underline.svg b/res/img/button-text-underline.svg new file mode 100644 index 0000000000..26f448539c --- /dev/null +++ b/res/img/button-text-underline.svg @@ -0,0 +1,18 @@ + + + + 13E7EE68-9B16-4A3D-8F9F-31E4BAB7E438 + Created with sketchtool. + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/call.png b/res/img/call.png new file mode 100644 index 0000000000000000000000000000000000000000..a7805e0596bb9af4f3ce0a8debd7eb30c0b079e2 GIT binary patch literal 588 zcmV-S0<-;zP)Px%21!IgR7eeDWB`JS!%GF3`B_65{{Pqf{r?{qNQ_v(%EgIQ#bAzdf(6{P_FnPZJ?anLs`RS>_<2 zMY3fen?Vi)=>?eq4kZ-lU~-s1!3gphrW9!+U^9Sb5z@s1iZfD!5u2ePGtlF|c>hch zW^UvKw=G|1mKqGyeNC4Q3hG@r(>i zuU^r>LWb|07EFx)FLxTnUc?qkRQDm{KL(}0fBxUVW*JC~>T&pw=|2YxGqCi*0jTan zhX4Ow{rk%xi^D$ZCz?NhnNBh?F*r4xnTfSbrn(RNO{4Gq|HrWJD-(BZ!_@{hxKIBx z{G&;>09nv&9JPayf$`dxpQ`1c0-)jQDz^U&46M(Ny#GmcAHsapWfZ;m|3Ak4{}|bG zzWx3?nTd(v$gK4A-z=c|3|PfbT%LleDRA8gvk^%5nnWF0^?%jz!zX`nPqv8p1d?I_ zRi425%n($?AgLvp391u8W}#~gV+{KX6a!lZl4AkY)O-G40aYv1sDM|448;c+L6Y=r aVgLa1(9$0~3Cnc=0000 + + + icons_video + Created with bin/sketchtool. + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/camera.svg b/res/img/camera.svg new file mode 100644 index 0000000000..6519496f78 --- /dev/null +++ b/res/img/camera.svg @@ -0,0 +1,12 @@ + + + + icon_camera + Created with Sketch. + + + + + + + diff --git a/res/img/camera_green.svg b/res/img/camera_green.svg new file mode 100644 index 0000000000..5aae5502cd --- /dev/null +++ b/res/img/camera_green.svg @@ -0,0 +1,15 @@ + + + + + + diff --git a/res/img/cancel-black.png b/res/img/cancel-black.png new file mode 100644 index 0000000000000000000000000000000000000000..87dcfd41a886006ad3763e59174eb56d3797643b GIT binary patch literal 1136 zcmaJ>TWHi+7>+CGTHAFi`cM@NsbCj6lVon0i8C!T$wbFBrA|j26|tG*bSBnZHaX*D zDvPUvu;MPL6}uHt5&Gg?!52lv7x6{Zs-+bwc%csp6>s~xCu3*yVaGsD&iVPi@4ue> z+1<6esbNV2hG9*qHGCR<7rO6{KcIE|Tnk#U7MRS!9-|MIBnx11#mE6XrAc{^29i?# z?H-6?*z7hnlZ9Dv9V;7}S8_34M>AbI7VUIQN$v*_&w;$E$B60cw+LKSV#LOvNQou~ z3hJ5x3-k}-DaH_QPE}5-Zhg1UV*^=81W^jtk{in zh6V7TH{_A25Q8%jFCAo<0Mm~9C^|?|e$r2Qe10}Su>l`G^AO0JrS!3BUYPNPPBEeY zp~;eDsZ{co{9eP#lXN5!At@i}^LY@$W0!R(IUe0^tt#-qmMztUs-feqqLed=Fh-zA zzoejuYsg znJi}k2^v<$Fm_a{*j+H7VHXS&=eSDM@HSDBRoylIQelZAo6>D4=`u+1F#_p$RaIfb zJS_-`kihuE37Sp@6Ev6L{2a}MBVi^K_f@&PAs02E!zx#)aT%&E*BuDWM4owIsXKup zScZmI5@*%=vG8^EX1Ge-SVGCVToMICy6yd@-BlBsA$MCFUUaC9KhV+4TWGki&>J0e zF(y-dJmX9p9HoB}s6}(%eLgGZF8{MEk+YgtnnU}cHSg;DY~zcc5BAXyr|%s*b@Jxj zAHmy;X@4U(R=o77ZTHCZuCZcr>)6ZiHEn)gSpTtb zc*XdF2b(Xx8J;Q+kAO|vx5W1izMr`L_ky7t$B#&lwm0rPHniu(s^G;7gL}vCJeewY zg?0|CJJ^_N9cS>#nSpkKXwZZSQH_ scK>C#WAeZs`tyIEM@P9i@pp@RvA3UQ6_%VYEqDI`sbm*_A>?5hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|8hm3bwJ6}oxF$}kgLQj3#|G7CyF^YauyCMG83 zmzLNn0bL65LT&-v*t}wBFaZNhzap_f-%!s0*lEl2^R8JRMC7?NanVBh8E{;a7Mow;K<}NNShK8=Dj*f=rPR`~= zW^NYF=7tvLFugAM$)&lec_lEtDG0shIQ4=OL~a4lW|!2W%(B!Jx1#)91+d4hGI6`b z1gCjWy(zfeVv19*KF~4xpy)-4ZkP}-4S|^O#0%uWlYeR+FwGYM6ZZwf-~lw}umRpQau|!VqtW)M#68q?qLf&=-_UHTO@8?{mEcVCE!D)IzQ;On@EfO<1m*pxQ@e)c2-BOAlr`8PUuEETZ_l^C9`elF{r5}E*JrIHB% literal 0 HcmV?d00001 diff --git a/res/img/cancel-red.svg b/res/img/cancel-red.svg new file mode 100644 index 0000000000..a72a970b62 --- /dev/null +++ b/res/img/cancel-red.svg @@ -0,0 +1,10 @@ + + + + Slice 1 + Created with Sketch. + + + + + diff --git a/res/img/cancel-small.svg b/res/img/cancel-small.svg new file mode 100644 index 0000000000..e4c8cafc10 --- /dev/null +++ b/res/img/cancel-small.svg @@ -0,0 +1,13 @@ + + + + Line + Line + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/res/img/cancel-white.svg b/res/img/cancel-white.svg new file mode 100644 index 0000000000..65e14c2fbc --- /dev/null +++ b/res/img/cancel-white.svg @@ -0,0 +1,10 @@ + + + + Slice 1 + Created with Sketch. + + + + + \ No newline at end of file diff --git a/res/img/cancel.png b/res/img/cancel.png new file mode 100644 index 0000000000000000000000000000000000000000..2bda8ff5bf06fba1732f30cdec0745d78f3e15a0 GIT binary patch literal 316 zcmV-C0mJ@@P)Px#_DMuRR5%fp)V&JAFc1J>lN3Y{1YaQm!N~`3QJ1za+-@#DgHr}^)<6R-a z=06!ylFNOh$+e_y+rv1H>%Q-Ai}FV5x;|4%-&85JWsL1%;#lZR2;_3y2$NDigb*8; z*m2HRFn(r$1{sFoj&H*-sStAzG$yD3^CB}S0}CP!6v3hh<`L{XjWkVjf@>9cm=Is$ z?dXH`tPeuC)?he@AsDCFg&NdYXva>9xiu>?I}?a~Qg!BoW(XErPMz71gXo>6uzx6s z~A}I`^Y$S#ua!D1N2CS#4GpsRMRn;q1Y!;x0s_VKd{EH-f0pB0^Qt-BgyatQ_ O0000 + + + Slice 1 + Created with Sketch. + + + + + \ No newline at end of file diff --git a/res/img/cancel_green.svg b/res/img/cancel_green.svg new file mode 100644 index 0000000000..2e3d759be2 --- /dev/null +++ b/res/img/cancel_green.svg @@ -0,0 +1,10 @@ + + + + Slice 1 + Created with Sketch. + + + + + \ No newline at end of file diff --git a/res/img/chevron-left.png b/res/img/chevron-left.png new file mode 100644 index 0000000000000000000000000000000000000000..efb0065de97ad17c654930fef97377469dc00406 GIT binary patch literal 14586 zcmeI3Pi)&%9LHY|gVCuH(l!l&geYNz#j?3krO=IY4S^&^lfOz7b(dv?|r|& z-}C4Fi7$S8b>+pG>BpxLLNm)t)iwJ42z@_#`XT!H_0mQqYVeje1BA|;jowq}-S-|t zXzppdRuAj?71eZGX~S~2NV?nds2U;dQr9!gT@nggWZQO1;$L5UDGIh#5?{^flI~T= zj=i++llA?Tnz_Gg7A^5od0OkLG(n4mhR|&_oj~oD#5k`?j+U^ zW6N!aB~gqD^`d%U*ajE82Km^4X?IAK72@>rj@ zdtMp>a=Hpcdq@Otsq@P-P1mQxBIS&R z$29|2yw=oZCkPG4B+Jz@ZAja;rCKIw6mtbBCC@2asjQsOrixi5n=Q{W5o^?hOXrj^IZ;3H!j+I)n1G+-@z{;iTH$KhQ z$?LmOtNQ!4Vrdsj8g=sYW%(Uu^VhKE`Q!|FSGHv9ih zV3Hr$C)eog5a*-~m86PQlamB)BkUMHnct>s;@)<9l6TlRT0q0mKS0wSo{FS(c!rMF z?C}}ZqJvGPtAUQph-X38@UgZ*oIEdC|v1b`=AM4v3_~bk^ zf{vasnJMs(9#3S_O79owtqShns|?R^eIMh@gPuf;5;h$Hhbh1soTo!HhXBCL$={xF8K?%yBUhK>^1FX)t4s zi-`ydI4($o8FO4rL{PwSK^n}M<6 z!CYF?5!!zWp@SO;{qryV{tcnFgwXHT5K<2jy5Qct`pqKM>dV#nTKDI7Zr++f(&^jp zf9w_Ses%TFpH|N6v-y{Wvky04+PL-RhjboI)@I=-~INFUv86A npL~De*Yz_$+<5K7@18`nADHz|4;E)>Vzj)lQvK+KYj6DrGWNav literal 0 HcmV?d00001 diff --git a/res/img/chevron-right.png b/res/img/chevron-right.png new file mode 100644 index 0000000000000000000000000000000000000000..18a4684e4727a9fb3cae66f81165ea4f4aebf69e GIT binary patch literal 14594 zcmeI3Pi)&%9LL`#1|z5l3Gqjqj0Y+cB+qgFHJ+2HOFB|PO4X)Xi-b1Uerc>Gwy~YY zEgaC$kl=(kZD#M-zL7WNw!R@B;L68r6`z2Nj#UUOLeD0 zT4rs}C98W&4SjE0FB;);`ve18tw{W^xEMiHNtZ!me*%TDdIqLa5^R7NhU)dc$}`=j)rFFn6ycUSiVPn>4`q4 zW&5_*vZs_BbWbfz=cHaA)SfurPG@3i&tKS~2>M7TI=#lOL+}dm?5?Ymg&le+CnjCJ zZ#IXMGmRC$w|*jX+@Gil2|#Gqi!2!b9W?%oNI*E zw302r96&jqgYF?Pz}4>}XpAJJyzphmAlvSXWBLZrd&$7Aa>` zJgFJDqP3blVmZg=acEYp=XVzBpaEz z2x7es?FUjo+>h zR>`ZQt@|BqGdh(V&GksQ=St%KrW+h%gHtN>M0;1!^zb|@>*1ClhKfg8hr=2;`!@6c zPGFoL*r(U%wTN}thKf@~s_98QyXp5dm&|X`HF0~pJ~xipQJB9m{4w+Ur%5?qDxmm&LwiynUi?W9Uog zp%HZSjqyx@fAnY~<5qgVKyOv>;9g~Pjt4v8E(gOay32`SI$i|QV8$F56A=_}T#yDc z=D3)Mpn&6oG?+2R#Y6-J92ca)j5#hQA}HXvAPr{BaWN4=0mlVtFk_C3i3kcfE=YqJ zb6iYBP{46P8qApEVj_Y9jtkOY#vB(D5fpG-kOnj6xR{8bfa8KRm@&u2L<9vK7o@?A zIW8t5DB!pt4Q9-7F%dxl#|3FHV~&f72nskZNP`)3Tuekzz;Qtu%$Vb1B7y>r3({c5 z92XN26mVRS1~cZkn24Z&+jnL4g|Fyy zfr4IJsUx)aG(vB@iO{Wo>G$slbtQ!UxPXvy8KKAQ_s)NFmTK1)tMiTE=d0h(C$3A! ztKU6&?yukW9=&n%+Q~~Fee%|WU%d9zhu{8sr1684S-9uZqwij6;CD_v^7`_z*?*3m zZ{7EK>r!R**3DOb2~J(yx%}tL3aZV1?9QMwM?d&G_{sZ`7C?&&OV!WLT)6lj@j=DC literal 0 HcmV?d00001 diff --git a/res/img/chevron.png b/res/img/chevron.png new file mode 100644 index 0000000000000000000000000000000000000000..81236f91bc2fe4b12c890b22b909d6454e67bc7d GIT binary patch literal 14638 zcmeI3U5Fc16vwBaQlkZ{U`u@&rxdo-WG3I6VKQYm*={0cU3OEu`(!6GH@m|oGvmx; zlU*v*53u#2Qc)|?2VaC@wJJVoE54{G2#U~x3JRi9MJ()tupq2=X0pjiHrd-sA8*Je zXYc+0&$;uvADNdqJv}wKE3_}fFwCxEAwPq^_j>WpyYT0SwM*aPue+_nyu&c}JmCH9 zVBR>76{911dCr|HJtnGVJ)&r41w~qQ3#%DMI^41pbqTp_1uf`Cmb-EJQ;yZOEO#tf z5=vGME$W3;8_ljxmDSZHHKTEd<&e}8ae_K>6}DBc8IIV>a(-SB$6hnfvA)Dz%5q~~ zL3XY*&E`xSvB^j(tO}_#o6ba{$#goAeuRw)(IhX#`M3~{#l?gmCSq*+#mONYNw!uM zXYxnd{JuW~3R9nDzo6&15pX5aVO9Fjj<}6~k3pVZ+%UB-zZ9M~-Ui zmaCfv>*ZA{X2Z>LoL8vxYF}5~>J&1ZHakp_Zz&cZjR^c8lcsh&R>Q9OL(^0q)leN7 zu7iEifj(=|bWLZ`98$8=J+v^MlTxWud*FEM^?{`wcVZbMXd@lybjm9h;%AU!Hf$A5 zEaOYrKj`XRz1p3eo=jfP(6OVIKE&qr1U7#u1T!SzYZY@gQe4w6n`TW8R@w9>LN=H4 zR~0)_QdHgWxE_@Fep7eGyZKOFagpq;$Z%8$3#qb@5#xfG6b=bdQ4m0qK-rh0WNLbK zr6)%$S@x{n8|DDY{v3D*X^N}dR2HZOc{Ek5ns!}rWxcK}Al@<-B);1Sl$~`Y=FFOD z<6$8=F7bn!fy-ZOV$pD1#ZXZ(FXM)Yu4`f?o*qr5lz6y08rQ-JA)N{b$8oy#3Nnt=(d3VBeDZaa+e{ol*lDZ}hiXVnCWLr3$)(SLg~@ zxp@8hr`ares<(Bsqo(_(lBL)V^7dSo+uU@WW2|#Zc^-f7ii+x;XR_*T38YDUPiuEr z9cSC7|KAA=@&o(u8qGyyY`39;RK99>6348%O~poI3wTZ3+-?u@_8R*ONWAw8P}6&- zB53WMq0KeBbw(xcU=#6bz#~)qS%^yfmbPx?KtJcrYOUex(=h?R_^9{Uw!-dy>-_ds z*xhgKI*%Hn3(_FQ6c-T@6i{4{1~I0%h=`zo;(|1Y zF~vnh1O*fqq(O`+E+Qf*ptv9nVoY%n5kUdP1!)jtii?N{3Mei}gBVj>L_|73x0zhYbA8 zUlTvvC*S$*8T?=%s}^QT46}NGVNO2BFzXxm`wxa`2n_S*afT6JXP7zdSL0AT&~3&#XCD^Tech^5%STt2&;54s?Bv?3U#cIa*B<@*^p)3so*4gi zgHzTn7A~B4aQ*l52f2~A*cV^9|BJoXKe=)0%87rziZU-q#}e;d|M4mw3san!%3m5k G{_KAu=;Ooy literal 0 HcmV?d00001 diff --git a/res/img/close-white.png b/res/img/close-white.png new file mode 100644 index 0000000000000000000000000000000000000000..d8752ed9fe1036498acf69cd9d5beb2287086b18 GIT binary patch literal 1305 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|I14-?iy0WW zg+Z8+Vb&Z81_tI8nIRD+5xzcF$@#f@i7EL>sd^Q;1whpd3^o;3KxS@gNuokUZcbjY zRfVk*ScMgk4HDK@QUEI{$+lIB@C{IK&M!(;Fx4~BGf=YQQczH^DN0GR3UYCSY6tRc zl`=|73as??%gf94%8m8%i_-NCEiEne4UF`SjC6r2bc-wVN)jt{^NN)rhQQ2mNi9w; z$}A|!%+FH*nVXoDUs__Tqy(}E4xsMLEr45;R}A$P(0}?Bi3R$GdItK~G?iqgA)JSz z3nYV6TWUon4s9SAh&FIwK-_2p3{flJ{FKbJN|(fvR68RBLsMM?3tdCQ5FxocyBTg2d!hP6<>}%WVj*~R z;$A^1k}+RFb^cqaFS2`#&6^$e zB+O_Ei!YhRZhJwz@Ywr~y^{*pF>U9W=Y6X;>!bQg#XSea@2u4Hy*%fq*tQK#@+Px$|4BqaR7efAmN84iKorN5)24&C7nef16rAfObVvwv>FNhiTpS$>E*%{l{0<7; z3!&L`N}=H3VlmJ~I*Sgakoy0(y%3vgl1ezxyx z@JcFYwd=J_(==aUkjGUjl}>pl%M0X%=7D#+U5z!XkVPi- zbcP~YAHvjVp|b0)?$2=?4pR%G3koL!9Y#$iJe8)HB$I4}y08@Ug^0+em1-e01%&K< z{8ZphVw#uPXfzUX3glhL$>DIQbvhk6j9Rh_IeUO2=w^pe^b8No%?Z_5?mSNvaXkzN z0`Q3nR)maf!6&x}n2JF*J#gU)KZ-&NnPdwl3%=)h=!_QM_w%S~WRm^wkKOXQ9*@Ug zcw*nMwKm*JeiXU(yi&r^uv{YIUMPw30pD*X3&@&(H9|7h-yo~?2xo~5Z~!ACCJS_J z7}+VSfz6b88Hbbk%K!!Rq+YN0kbn+hs}`CH1_E_}lUW7P|(a Ts#h8Q00000NkvXXu0mjfRwM*t literal 0 HcmV?d00001 diff --git a/res/img/create-big.svg b/res/img/create-big.svg new file mode 100644 index 0000000000..2450542b63 --- /dev/null +++ b/res/img/create-big.svg @@ -0,0 +1,26 @@ + + + + icons_create_room + Created with sketchtool. + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/create.png b/res/img/create.png new file mode 100644 index 0000000000000000000000000000000000000000..2d6107ac506e8b89ac0a3825907365d846cf4e19 GIT binary patch literal 807 zcmV+?1K9kDP)(RCwC7md$D!Q544~Nx$yJCJ6a z&P>#vg>q-^{hf2~J#+qNN7FRP&Zg7pa5x-~$CJr~q0i^@`~7=+dy1miuHCV40QchJ z;`;h}Fc^eFA;IOj@N{!?6AT6uiNwLdfrTe?2ea9%*=#l%jbt(jA{vd#vTT^MSS&i7 z4(_k6uF~mrDwXnjy^b98`~70E7>PtOnM@!Muswv)XjG|Gy4`LrmkWo(#@E_IYq#5l zLV;iHk;anK)6>h#OT+UA4tNc{*XwC(8Czcs?%n}hLST}%fdMgus5>BG&d$!(I2qHk z0tHYE_1qw5xK*-6+Sq`A0w{*E$agZ5oRPL}5KW=~9&gAn1d*^_SPzhqOn6y>nCcpxhsbbWb)kut!oABiT~^b{_;#_7RaF!uSy4QuE5TA0ck1;zf7xu-yr6#n^5N5G z>tNr$`}lg_q?(q?Wqi1;7kh%w@<(~ewH&zJYU}ICdG*avKJJplMXRd&`4f)?!A*&$ zJpA)0clQrp?cbkQXL@ozdGYcv;o!b5Qb6hP5x=;=mJfNFDao6~`S0%#QdRkd4BmeE}k$^5&e zSX-7wh=#_(*tYPR5Y}s3O#7Yx-gw!!j))y{WZF6sZ>!aMbn9r*{0ilmEN!Fa*R*{H lN`YiZ3B!}a_Wh3l0{{dzLWKWE_s{?U002ovPDHLkV1ng%k_i9+ literal 0 HcmV?d00001 diff --git a/res/img/delete.png b/res/img/delete.png new file mode 100644 index 0000000000000000000000000000000000000000..8ff20a116d4340453072e38604cd8de5c894f30a GIT binary patch literal 1006 zcmaJ=PfXKL7_T^tkfCTehBQ%-B#LAacehOvJx_uxPvBk?SnPYzS2He;il0< zO;8dO!@;vhuaX$!#e*JDkH$npNIY}#rUzfgHas|c==`S*;K>u@zbSlrLyl2gsNs3EfSYCjsho}K5R_bV5mumSudjT7QxtW4+^N=Z z%_u7tav3v@VItQjXo{Mej(pQvf*91{qT{Lb!Rxm)aBP*nkuf;K*I>h$*$CkL#%$Hv zSh8fBp1umEB83pR5St)!m%UJlRJz5h5Ic6WG-!q3C6zubs%Fdq4FwQnm~6`8vJ#MF zhR;Y+TDk%Rj?b{1$ckJ_5S28iqy^CaXp$|k7nF)#Z0903m2P0{D=gb=Hkqc#pkR^Z zWm#r9ffa-liAaU(9yX(t7mjrpbQoHJ<6{STAZ9e{Xcen8sr0Y~*YDDLVS7wuU~FXi zEYEOpOPxT&_?24CMy7Gq}(R@I}ePQijpFE74B|TS-zSf_gN+grX%(dUo zj!D}e6PJWLJN*ytuT1ofzDxYrt0Z4-4wQy(@sFO?K9}F$ySzv3pS7DJKRmGQ?@XNe twp;#k@$v3%d2+;zw)&sYBd7Zk=cpIoM}G;mt)KA=EEQ(;m-*Xw{{X0DIb#3- literal 0 HcmV?d00001 diff --git a/res/img/directory-big.png b/res/img/directory-big.png new file mode 100644 index 0000000000000000000000000000000000000000..03cab69c4a5f53c252f03745a70e53f7ca7f563e GIT binary patch literal 325 zcmV-L0lNN)P)Px#|4BqaR7ef&l`Rg!Fcin>$4Z7I9EJmI3N+yc2sD}_pfD&DNG>op0|-t-vZQNL z{x4x-q+45sSi6!)=J4`Efk7g# z0$yOaMgNzGW)as~E6i@~Z6^Z2E2(IZQh^JM5(6)Zi1(tH&^4fA^IX!mvAw~8fCXni X7jjMdDj9}v00000NkvXXu0mjf2epbS literal 0 HcmV?d00001 diff --git a/res/img/directory-big.svg b/res/img/directory-big.svg new file mode 100644 index 0000000000..5631a2ae3e --- /dev/null +++ b/res/img/directory-big.svg @@ -0,0 +1,22 @@ + + + + icons_directory + Created with sketchtool. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/download.png b/res/img/download.png new file mode 100644 index 0000000000000000000000000000000000000000..1999ebf7ab69c19220af2c469331b2c96c44225b GIT binary patch literal 1041 zcmaJ=PfXKL7_XT@AWlsb|AF#SJb+uBe(GU|8?#37ndNAtiV8es6hraK9`F_9e-|wwWPTUH2UhbqQ zDxAHo?q zLA@*K$YQi0hVdY)gpI156Nx_nNd&z}UOA~p0 zsjQ0zJ$e(2_!1$oAl86y&Doyh%XFPrB6i?rX;2TrWtl!Gs-RAS6mlWpnM6eA5&{rJ zCdv!KkT3{hT$E?II2-38vA8tENkcJk_|YVrYs^SFC3BdI++@0hu_Li;rBY!kaR#}w zY*Z9QmW#2mScF7GyhR&pe#G|r8Vm~bbk}sSiEI!sYDKhwWtvoa(1PVOX>IRtOk`lJ zuQ_a#;ewVLfvWodP|IpYdpHM=>is9NmtS-sn}Z%&aCNe{nZ6*EBc)uZVdUl!nrlpP zvV<`5O2`4JRDEioU)6Ne4x9sZl&VTu+ryfz!>l6HgoiOrLy9NTN-UKTFLzv9`O&)x&W4^(FL!NF(cY_kajYktyVzN~G2h=duzR|;4yr3-Kd(Hk zydF6J + + + Fill 75 + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/e2e-blocked.svg b/res/img/e2e-blocked.svg new file mode 100644 index 0000000000..0ab2c6efbe --- /dev/null +++ b/res/img/e2e-blocked.svg @@ -0,0 +1,12 @@ + + + + 2805649B-D39D-43EA-A357-659EF9B97BA4 + Created with sketchtool. + + + + + + + \ No newline at end of file diff --git a/res/img/e2e-unencrypted.svg b/res/img/e2e-unencrypted.svg new file mode 100644 index 0000000000..1467223638 --- /dev/null +++ b/res/img/e2e-unencrypted.svg @@ -0,0 +1,23 @@ + + + + 16F5F38E-A6A3-472A-BC13-13F0F12876CF + Created with sketchtool. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/e2e-verified.svg b/res/img/e2e-verified.svg new file mode 100644 index 0000000000..b65f50b2b6 --- /dev/null +++ b/res/img/e2e-verified.svg @@ -0,0 +1,12 @@ + + + + 48BF5D32-306C-4B20-88EB-24B1F743CAC9 + Created with sketchtool. + + + + + + + \ No newline at end of file diff --git a/res/img/e2e-warning.svg b/res/img/e2e-warning.svg new file mode 100644 index 0000000000..8a55f199ba --- /dev/null +++ b/res/img/e2e-warning.svg @@ -0,0 +1,12 @@ + + + + CCDDE6F6-B552-48FD-AD54-6939841CA2DD + Created with sketchtool. + + + + + + + \ No newline at end of file diff --git a/res/img/edit.png b/res/img/edit.png new file mode 100644 index 0000000000000000000000000000000000000000..6f373d3f3dc7dfbb4186e4347fad43920bd04279 GIT binary patch literal 460 zcmV;-0WPx$hDk(0R45gVlCf&SP!xv$Tx)RmyQVlu+3ygXZ$ zrL^HmsMqUZu~x1@)$Ad4coqLoFF_9IaN%;hfg% zwLh6me3|*;FsY%IjNlq^Bl`Wme>@&xnr7IDXr|R_1!|}z6Qi@+?S9E9ADhkQk#kBU z5{Sp+@H`K$>tZw-VK^MlZQFiOD;Mr61F(c^m;46@h9Cq + + + + + + + + diff --git a/res/img/edit_green.svg b/res/img/edit_green.svg new file mode 100644 index 0000000000..f7f4c7adcb --- /dev/null +++ b/res/img/edit_green.svg @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/res/img/ellipsis.svg b/res/img/ellipsis.svg new file mode 100644 index 0000000000..d60c844089 --- /dev/null +++ b/res/img/ellipsis.svg @@ -0,0 +1,25 @@ + + + + icons_archive + Created with Sketch. + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/eol.svg b/res/img/eol.svg new file mode 100644 index 0000000000..02d1946cf4 --- /dev/null +++ b/res/img/eol.svg @@ -0,0 +1,16 @@ + + + + icon_eol + Created with sketchtool. + + + + + + + + + + + diff --git a/res/img/f4c371.png b/res/img/f4c371.png new file mode 100644 index 0000000000000000000000000000000000000000..ad3b8f1616197fd5d2ffef804bfef3d24b2d256e GIT binary patch literal 146 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU1SFZ~=vx6P$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1GCY~;iAr-gYoMq%?FyLTNs7*GGI?2%g@Ywz;H@|siKCz>m5)(gQu&X%Q~loCII5dEd>Ao literal 0 HcmV?d00001 diff --git a/res/img/file.png b/res/img/file.png new file mode 100644 index 0000000000000000000000000000000000000000..5904ea8284c972de5257c597bd6f21fdf5b299a6 GIT binary patch literal 482 zcmV<80UiE{P)igf+v4D@2@%_(#a4s7&qarVJkUabL zC%-Pe{Y?c6v;>$pKKhAl2P+e!0uOVjBK!JBzcAIakZOUMD9fqWf9Bu*@%cAVWemv{ zFflS(h_M0@rqqP1->DqQ6y@Ym3q~y%wE$GBFns+@LWASW@Bch3j3ih9EWfUO_(Qw} z*FXG`=V2nj0#_;43-A7%e*K%EKY$8=%7BW2TBy)2!Wx)B?*gl6J~pP2)^r>i761eo Y0MuZqgNcyVI{*Lx07*qoM6N<$g6US=`v3p{ literal 0 HcmV?d00001 diff --git a/res/img/filegrid.png b/res/img/filegrid.png new file mode 100644 index 0000000000000000000000000000000000000000..c2c2799f37542a51ed12e77b570e65f3fb994541 GIT binary patch literal 226 zcmeAS@N?(olHy`uVBq!ia0vp^G9b*s1SJ3FdmIK*k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XT0C7GLn>}1{rUgjo_QD8XZDHUW!=TPNSLFcr~W@@ zhj6M!E5q)E2R<CWT^bT Wt@F59?-ihX7(8A5T-G@yGywo&OHs1` literal 0 HcmV?d00001 diff --git a/res/img/fileicon.png b/res/img/fileicon.png new file mode 100644 index 0000000000000000000000000000000000000000..af018efa6dffa94c5988e7a6e9ca222643699c89 GIT binary patch literal 658 zcmV;D0&V??P)Px%Oi4sRR5%gcRL`ptQ51H5h>cMAdYV0G@!I$z$b9{9A>^WkprWWCEkq&^{|s^A z&aHod4}u6G!Jk32tVM2Yml-MVO+i7W7&@6V_MK=RGxMfr>n@D<-0ytnyXTyHy^IAT zolXn$`TQ!&vfJzR+D4dR$bulesMTsy1O9u-kbopfcMv>sI-N(=YE?24W3kv>MNzE4 zU$xuqZ$>{$8IVA$)f$=!P=MR*=Dc3-5lnwFncO}hLM0$o(df{wd7fvp+3apEmwUHd zE^i@wm)6fx4^Znu3!2#s!*Gd2;!2@V7$N%`@p#;=@>tb4ZFV>uKYP6%QCPpbKc!hd7PrWqzcLF_v0|~vyIigdv)ODP|L8ZRQfb1F slgiofP^%g=%eZt?T*_g+UjIzMFOv=K$8TJ#SpWb407*qoM6N<$f=&xD!T}1{rUgjo_Q;yFf;Fg6$_n@1c=25RnPxt^X=Dp zdzqKLof8iRO*!g1Yp#iNquR2Sg#{Z7lBWLs`27ExX!`=muFJn2%pVyEax?_}|HnV6 zgQ-pGLjR7G#vq@bCGH{yat#aH)EBLBDSVYGW5jwY!%Eh7`C`@oD;9<@Gcd9-JfH8` UxIMA(KF~1?p00i_>zopr0O8zKJpcdz literal 0 HcmV?d00001 diff --git a/res/img/files.png b/res/img/files.png new file mode 100644 index 0000000000000000000000000000000000000000..83932267f8b0bf88c7d594d6ec09be96ec349d72 GIT binary patch literal 503 zcmVPx$u}MThR5%f1WB`JS!%GGK@-PN7GBBtyFf#Ik#8AM$f4^A&Fm<(>MLtFmhjJJp z1~61H{A1k9^q=K;r%BjHbcJQ-mNqdkFmnI<{bx##dE9+;c_xqxKn8RhNA19707!!n z8xOl8kI*qDR+gNKv#V4v3;}t8o9X8XbO~fWGcyy5yQGo5r?kQLe~f=J%g!#+M3!d) zg+YU1;s<0wY-~m*Ms^1=&A?b?yL}9dEGgw@mgvINF~J!4XkJ#XZ#O + + + icons_browse_files + Created with bin/sketchtool. + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/flags/AD.png b/res/img/flags/AD.png new file mode 100644 index 0000000000000000000000000000000000000000..d5d59645fe695b60380c02374a5d2f1cda4dba54 GIT binary patch literal 2584 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 H*ggK=-FTJP literal 0 HcmV?d00001 diff --git a/res/img/flags/AE.png b/res/img/flags/AE.png new file mode 100644 index 0000000000000000000000000000000000000000..05c7418aa4dae20fe103f484d831ae66a6c1c397 GIT binary patch literal 1015 zcmeAS@N?(olHy`uVBq!ia0vp^W*{uU1|;uX-8K(Mv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffzx4R3F27;f?yX%1z zXMsm#F_2CG;}6+R=Yb6N5>H=O_J^!8;>H@%A+_%r7?_@Ux;TbZ+_Hu(Bb6U&OcV{mAFRpxMzxfQ$fB84Yhiw#E1e`b&;Y9w* zM{T*cx8-KP{mR?f962pDa$3;BzwA;{I;S`Fy>r?{}SgBgR z`AehfjC7_9y(zQL7sqek&1e=Co_pin%|FkcF!b>ERNs}9?_yq?7y0SH8DY0Wd-xwb zV7R+JT712I^Jin*>G}3;r!FpCtsQuwIqj0o%hK|ith;x0DigGpO}nalVewRY<@m|N&)D&<=FUH! z6m7k*Efsg=d%fetjP*H8@K&%`>&VF@9Um6Y%jgYS~X2X zGhpQjuawk$K4yhET+8>o>*{|y`>>bX47oGq&#WDfzE~=57pgve@@a$5c{vF=3|j7+ zg>P~KJ$Y)%gSv}mcY(0>K;t9v=ZDOnFP1K@JsNd&b=BJUF5IOLR~h}wyt7|u!I%0@ z^OZ}*9Q0qXu6Px8I7>ppXp@`RA%BTPma^w7w9gek`hM!;g^kB%MZa3{?oup+-wn=Y z<2JYE&(~gu{Ro+3QMg^_|MRIb)^8Zz^h#I%zW)DL&wtTMesF}VY-j+*e%L=Ym%^v( zuYX4*GazdbOC8gZzK9Kli|eNVGl6P}YeY#(Vo9o1a#1RfVlXl=G}kpS)itsRF*3F? tHMBA@&^9o%GBBt(^wbtbLvDUbW?Cg~4V?318-W@aJYD@<);T3K0RX+YvyK1& literal 0 HcmV?d00001 diff --git a/res/img/flags/AF.png b/res/img/flags/AF.png new file mode 100644 index 0000000000000000000000000000000000000000..bc7cef091662f98bb1dfc7abed0152b39f84b3ed GIT binary patch literal 2578 zcmZ{mXHe5?7RLW+AP@*5(n}}`3V~3hgp!16kbdbPM2fTXz>;M385-uB9 zGpY8^1=0DwR6*;^}Z=7Pojim?Hc%s9|*ie-W=@UmkFlf-}Jw!hv8^S~NPFf(Lbgo*I0 z$O_v;Z!xcd2nKkYh}n&~s8HS&!M<->TDdLKo{!CDilw>xS@epEariR$;)#!UPnRW3LAfMA!EK~)74pf9W#QD7 zk+E7~Eo$t7idNH>_RdkbxA*mtc=NLHwNT6-|H0?8eZ#RIfZ-Tcd=bZxTgQ#2i?6202VS#AA_h z3%e}P0YzWM*j>j$#5ZVuK>_GvZl5-{)NNiK&tw+~dmyQr2)dbWs(g2`^PCHE$Lo

    _xpY&rcZ6V+a;-OoEJR8lsQRzu-L#?QGn&p?%Pu^s z_TwICej%XOw)HS>mVN#Q zN0G$0C5Itxa>ExAJjvIUQIkm(jZ2Q0-rX9MQ~Qzat*YP<-$no9&Ge^=X9qh zz^uD3ITEaZJ(;3?l^S~_~kG5aFJNf_ihHmYm11OqN6jYH|_AqbEO3N-EfOa zMn`+G85hgqmZM)}xqM@xV7KNz9?L0T)w3nc4eiZb{B!ZV&#mciH~(}+51+z_+QEmv z^SdcJvw-|rSN1d!^&$J5Enm5~J1TMC1AJVp8AbF;aQC$IfttG4&H%DRd_d2Su zlU)|fR+X}CKV4VVXa9qKBj+WO*8oiZ0Ij^bvTt{w@AXN)w=TPVQa^PPj!hiul(*3 zT%3;-=o}uZ%JTzu3esZ@IH7ZiPn{os$PZ<(&k4!UR`b`UQi;QHG8+1k6G=&`I-68aFuM`J(`|Fy?InYQ@WnFB7DG&>d|4=cN2bAXew(XKmPS!_7#793=1REUCqZ?cpi7}Gv8y_@ zejRT;D>3pyU&J)0R(|Ls_nU$yDYd1lKh~4DJ;m#zw$%dd)Ox6~;wF8S{t*~(xzV~W zW(rvSR7cW*@EgaOgg=7d+{o(1I&ScF6R$iic!{aE%IJN>4De-RAfg9+N$@%3fjJ2K z+wmF7wElSW;-2DH{B7X?v_?lu`KraGaa_gg%DVITjfaSY9n-*rdYzEHW02pHGO6zo z{%X06oH%&$iLDkmqkl{uuraaxHg7zk_$(HhEUZrKM8IT;0wH+wvCT0a{QJ`-HeDqt zFIODx8nrLnfB6+BLXQSW8e6qO8Flq*3U#Su#zktp6YBb1htZfSnD2O8Njst4fXs`t zUcQ3Ay4XayD&cDgfs@*jCaWJ8wG-AXye-}A?Jk7GB^48XQnV#JR=6#V#9UjeP+Gq$tSLKl1s&o0}LlIz)W zMsO@(FNb%mk!4wxC6Kczp3?m&2JArDQYyr2b9yziRb*5>thoJ`7D288hl*T&9d$I2 zCTZ*WXl+9>7NZ+croSJ(+l~>?dBtUfc$qME60ls<`gP0bzn0_Q1|<7P7>qHe2d^J4 zF#XZFP(z1M&ugJx7>{5tCIDr$k~#`~38k!IqpX6tq=ZpL%b}GpXmmv9iq8KCNMujn X>yiIoz(&1FVG00(p}9e&9x?tO>&TqW literal 0 HcmV?d00001 diff --git a/res/img/flags/AG.png b/res/img/flags/AG.png new file mode 100644 index 0000000000000000000000000000000000000000..d48facad47fc07e12478edeaa44ec8fe3d0028e6 GIT binary patch literal 4234 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/AL.png b/res/img/flags/AL.png new file mode 100644 index 0000000000000000000000000000000000000000..883835ffb338e1c31e6de929a958839afc2f6e54 GIT binary patch literal 3094 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 nZ39Cq1A~e~Pi;{&StDnm{r-UW|vF!3@ literal 0 HcmV?d00001 diff --git a/res/img/flags/AO.png b/res/img/flags/AO.png new file mode 100644 index 0000000000000000000000000000000000000000..ae68b12c44d52f81b16f811ed1f8220918844081 GIT binary patch literal 2449 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/AR.png b/res/img/flags/AR.png new file mode 100644 index 0000000000000000000000000000000000000000..8142adfc8361ed9fda4b9a276f5770f2f24fa088 GIT binary patch literal 1666 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/AT.png b/res/img/flags/AT.png new file mode 100644 index 0000000000000000000000000000000000000000..e32414bd6acaf0f4a6ec7f9ace8d4e3907b9f144 GIT binary patch literal 655 zcmeAS@N?(olHy`uVBq!ia0vp^W*{uU1|;uX-8K(Mv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffzx4R3F27;f?yX%1z zXMsm#F_2CG;}6+R=Yb6N5>H=O_J^!8;>H@%A+_%r7#Qn3T^vIyZoR#|(d%%4$gz); zlXgc2zEJS1z*_Z8~e4)rWFNY*$b!DS3&2Co0=s4Bs7eqH``=C^+$Vk4@I zV&vxSp2zm;5LbKg?9H!Mf6Vs&xp7z1%*(eIug<=H*=OIrFH(2szKQwI7p)WTBfmrL zICG)?yJI&u{!_d@anhOH^Nw-*f0`ltihK15hZ{o2-^V6(ZcaXzcr0Lsp-38!_woOS zFD0JpSnB*g^Oa&`{q1twUUso1iuHvBb$6p~#zvO{`FVOzE!4xrzwNwkUH!AbwpaXB z<-&iLuatdUx8q@z82^@~df$Q8$zJpH){K7iL-nWObA*Q=e)}3_|0-S-55;rF0|BNC`-Hr@+wYs|W%TigZW}or8cNDbmt4 zbjMJad%xYg)_vC6=h^4%_4|I-j@8zDMn=p`3;+O`%5z2CJB$9iDDm&k**~bycLKkH zYrp~Edosz@OT4=~hxKz^4FCw>0f4YK0D!%F3flkxZx{eEaI^;2tio%gZBV{#!N*KuJ1R! z^T|I*mp7@|a^G_1_*7&}&;JZ;itmutm#NJ8cUMP>RU8|7in&+D2d^$~~ z)sHwjUc*wO@BiCKnJP}PGyMl$nJpaSi{R##e-j0}LACeu9@=F$0g>fNS43k>!GXv3 zh$REqt~Om>BOfz)EXBWAw5hHsRJ#^onej#(3uCA4BAzJtE3JfGXdLAQ#=JDH(~3i@ zA-cxR1(LVGN(@i0E1e%rUc70Ubf)d{p_pqyJWQCSf7v!d?vy&C?zu_0+5GOS?o-G> z%4Phz{dGO9JmU6aL^BV1dxosD!XkVy^%}?hEn*UL8r`p={rgK@kD~mlj`<7rEaJMh zmhW7?(#VgB*4Avjd$v`XhYYXOaCy`j!+3;qiILrT-_s}#)1-KMKtH)WL6BT*$Wo6~=*A>@T(+lS)4UwRjvp_tA-pIG$oL?JL`M)hTreUFd$;%5HYhypDT+!3$ z8S|LA7;M&7wBZz9{tMNi`L!W#rVwK$$t<6(a9u;*I1 zf4#rm%N(Bf<`QE~vwdywKqE~WBVYlB}LS^ z=&P-dZ8+kwQ+j)333+6F~&U!aP_`!urd)HbCF2ChJiSXWU@U;pOE zDOp=Ks_hd?Lss4vyc6i$XIeor(bEzy=@q(#>1L96

    9tx{;j%xi-5bgXB=KgJj5! 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/AW.png b/res/img/flags/AW.png new file mode 100644 index 0000000000000000000000000000000000000000..6ec178847e27da9ec8ab37750d3eac64a9a89099 GIT binary patch literal 1650 zcmZ{ke>~H99LK*WENVX@Ik6Java-#{IMp`WZEABd`EiFf+x(bBY%}>abSFO!N1YVX z%87oN9Chb9aB->+ybno}bVA^LRcUpT9n7M_egj-L1L+ z0DxVnBzHCUeQKDtdhPG6DON)>h(IR*fHZrTxb5&*=f0bo%*5|03Y z01W_ROaO2^4*-S{g}=EusV}qx4pT^KsX#6!EDmw-0?n<}*eokca;C)8B%(|8G=p=Y zTy9rwAUY7f_EpzJV&c-o0a*|fkuLdH?QL$_hxnYFZWTO?cmH#m56+zY7H+zO^*-?F z4R%VbXj&s>l)j#t_@bc26q3#l5Cg?KVCZ)NfaTcEdBgH@sT4w)6r|2x=D~-$?v&WG z?h;(h3i6bNWpF)8(z(o5PC{b>pNdA#@5TZ^E#Eg3qmHk|w>GkHvR1$j?DpnLHG zq4aTNgjiLmxyWMM4#|nXz;IY2YuXCw*r{#nSr$bD;kJntQTemlRZbDcB7OmN> zbcAYZ_bwgc!SI#5Ded(YhZGm*OirW9ts4xW+=afS1Q6k++lsUS+NCY0vG)boMdVn%)mUoLIB z2N}Um_TP0bKsN-{ZgVYZ$;=_B9F(Jze&&M!y9`4aT=(Zp+Q&7AWG|x4Xm&DE$H6&t@`rFq9Ykm+42tBYurMagrn^S#~@XZZ9s&9yYSH zX|}W!U%tqG!+Rc$i;j!2+jDF<>`9o-Rj)SMMZw07Hj8H3L#<0^(nn%%;>R8MU2TXs-L`)tpcyp{f*#*&|D%mK01it+3~zddPjN3M|I3RPaZvW z^8q=bgdUhNq1bKuf(Atn*~;kctdZzP5S5)hmi{ip%jOCEnH29 z>GV4f%Gm{?N`7CaVwD`rc1d5|7TF#DTG0SBu*1m)T)dL@YztPSj&b!cC*`;~mTQ$m z(JB=iA2jK?0YBF$O@KVBD|j3s`C@zJPuH2Y_6&}7Feom!$Q9v=n)MtIo3sjl429&o zo5T>D@m~>sFwz;U@7|py{*Z?qj!{Ck(eO?p<`F{ggT;;4=@uU`1YsLY|91htKj&!W zt)&9L8N0hh$D{+k&;w~%@M`TBo~pc1u?(8*zRhK2O3w~!?*1spr$oT7L(=Z+MPOS~K#D(itblYKTX#wlkEv!V^N0cmkE*k%5Q&)w{o9 zb!@vg7`{%Y+5)zV`bIHh81uC07{!8gYW@!31XxAC}-c$E$7*$P_z8yDRF0 z9nj%vnUVGEXcYavFe+h^+?jOG-1h-@X;M`h61>H zjPzeDaPCQ7P8%l$2lxp(ljx`=2iA(OOcAmy#GW%2^y~%INLng;<~iz--q+S~*XJa| za_yb9F$;#XH(T_h<2?pGX~%1Wl&i2$+Rqs2qu++*9p8*ZeV17&E3#z8`ZYTGK>jc? z6OJO)k8zpi)$&l^uJI~B#w~PNY=~Y!jO68?$Tegqc7nB5abz>u?Vl=jTUw`||Kfey zRY9Zr|Fz(gz4;s#pX~w8EgFf&IHJ*_`@{SHBZP%> YLIPv{U(mVam!uW|7qTnq7Ll3!H&WB%l>h($ literal 0 HcmV?d00001 diff --git a/res/img/flags/AX.png b/res/img/flags/AX.png new file mode 100644 index 0000000000000000000000000000000000000000..ba269c0453b78330db34c223fd4bf8b4142d12fc GIT binary patch literal 1844 zcmZ{lX*3&n7smg@mISFiVjUE<#!fJ#C`KDvrl_b`LKU&rC>;{2v6QJ&MlEAG)f!dQ znzloVk}{FhK4gkPQzfP7LYYqH{qVkL-gD-j=ic94&hz=^df{9pU?>;>K*HV4`3#?y zf9DYqe&tMcRr4VffjxxX40qK>opjcAhlDHqWtVPyp~T_vCI zH~B_QcW10m${cS#E!vxi9DcW%hO?S}ps!H|6-&Zg(#VnVB8^3%HDr*%nVBcp!lFxK zj?00X*mv?wbun+NdhcZ*qa}9oIyt4BgnQA(EVZ>(j^>@KvE{!1;p~CajK+PXf=wNN z+<3&M4a=s_AZ@|wZjEkU-T%Zp-r*BR!yA=(jC>$%ebGDmceosAs(GwX;PM-@QrU$G zij43@_=lS!2L>LU7F)|~D*kddJ7bu*{4r4SRCy40{;nf0v+`TtWPupZ<5~XDp(oeK zcNBKr@up3w$MCH>`rW-slba6K)73(aEzNPgmC)hRy>QGpc6Z9s(o>L@Z}Ug~hr)WI z(ab~Qz_m{N%-mz_YTs$fGo+l~^?xF_N3vZj^85}(7jGlg!V%Y6Ix2BJgYCk=da4dwt ztZs-bRH|c7=Hrd2U{T&zK!$iz7cxLfp4JAcL+z+f)dSW}p?@0oWTo@~auoPgNAVcW zF;HjWbKyxs*hEbsMBS@_MS3f$p6INO@}$K$i*GD(q`YSuT$e@^ceUa78mh(73Zntf zqF=x1vLCmG)0HLEjbxvj!pTLl)FBb8=p?PJOeCEO5`@T?eoi-U6?~;25r5xUkTq5u zJ_-o7pRTaBB6`UvaQMw8jG*eP?&piBUVeOatx`3_MO$gQISjZ=Z zTMK2gDnGk&Wp|k(yzZ;NyfP*jka`&7a+SFrVV#mHQExH$AThSzh%5+j$OD6=i+d}G z+V$V+_Ip@G^D#|{w6S307Y0RvnN}}H%pI?#3oRB4V93d_R0Kn$l?jfR*=kjE3*Net z4{5!Lm2tB&L&7w4dMnBygh1D?=+7f`1t;`HZ;HxRd{%^MqZ4d7~kT?IXW8 z3b%QE4oruK#2@IELlb)NnwF5pePl8v!-?nJHSGBEjD`PXrkmWyEwi{hU-t_Gy#cwQ zR%ZQEQy7CG=L2~A=3^4hiDkKQ!NDUgGsVY2%avlnm>)Go9{l9<{lyA|hUX5$MZIbW zQ=9dkamRD-B7HkGB8UKCydO&Y1EyXetvAP`RogoRE2v085=ku2=0_&5g2T{p?1k~K ze2XQ-JB+y|)@>~t#PzV*z{?q=K9KX>vgwK;;rhGM^=@p!SVsh6g}mGwpH;{bw(gaq z?_R8Rr*h;xiVJ_?V%FFX2VX3j)22GjoBM2c+teI;-xqA9=(p4xyZRr3(tqv-}4qV+oB_QyKvdai~I;*B}IPK5irqTpHMMb@d z_cs_JJUYC6E8q%yqTW7H{Kor-ExG~(-dfvJ-z;&V8#?+7k?_24Ify?6>peJ0DbIU% zmTh%_)9sh9t;HN2#_dpyGGPtW$BA#Y<#Dh8hb-p8;8a1-iQ4wHlF=%9*#^-TnYd!f zQ(Oq&p?^P4rrk^@9J8H|r<3jiu+MykuQY z|5qi++d8;NWgO@J*>U~{Ihy3+mlPJ9M8t$95cvS6XcH?#w1uImwU4P8#=-<+j@Cz; lV9@B4{#E;b7-C|>BEv8Ly8-%BAcb!L?k+gz2geDSe*rDIAzlCg literal 0 HcmV?d00001 diff --git a/res/img/flags/AZ.png b/res/img/flags/AZ.png new file mode 100644 index 0000000000000000000000000000000000000000..2bf3c746e7a2ac58895a7fcc34128a4fc800e334 GIT binary patch literal 1744 zcmZ{kc{tnY7RP@?LPFeFiXqYHQ@6!1p|p|_1hEuphG-dDnh;}831Uxzwt740W~Wts zCZ;7sT(^yhrPZO=R4fzQl+sp7?X>pg=H7qqbLV;PdCobXbKdv)okrVj%E z0Pf-L;v?tje-{EG?{B0nRdOhW6TArkASh7Xy9}1^Xqvl^Hvpvm6#&>d0I(x}V$T6U zA_f3Hg#ZAq1ORjy6{7F#eqyZ&k834fT9xen5YkYA$Ae!Qb>|R~Q3KPdoP~-Xwm2CJ5Moabgj9rau zjii(g^OKR3v*0stEM23m-S2wq5Eb=bQWXR)WR2<@&3@dVp(5|P+`i`i(r2?9Xn(_lqZuTCE?ry&AvvH4q6ukEcI?kl>nUysaRj9@W9 zr>{jo1}^-jxbm4H~r4PoDu&t>Qo{;I|5e zo(S|S)o=x&s0a#9Tc2EO`iC8fx8OR}t&EgP*3`-GQhi7uJTI|FaE9F)bm0|rs-4H^ zYs^D0OHhVyKm&tuNz2w z@1yqx7iRiz5=h+(^ar-S74W;`M^?iL>G#|4{;(8bX4Nwh@>t*#`_WZfguHSZQ=AqgvusSR5V$rEu|ED?D#w$2)2D$@Yz18>3Mi`*#}OsX10W z9V$N;{ay?9QRFVIJ=9b1xAd)7;iz7 zW`wHu6XlkwdfIC)$+6P#E)p`NONsFS4*1M84$c-+j1WYqh2a zb0;5vx(CsIeY_L9mmn&qB+nayyOj9K!`b@K$=<71l`jFGnw|H{A3iuXJvP0KKBp_$ zJO!*yzHHs`fHB+U6p72r?86^&ec>EHIsuYl&r$l=Iqkg{y15} zVj$b@iVFoRmT7q&aEYI->_IR>CVZeFGXJni;{(TcbCyM*)9vqU1GTRBn*D^SixT3J z&~X9rH~aU5rn19xoIKTzZ_cztwqNm;=Fc$tzZFH^ zHrUeB?ucYKs9B)4PA5ajdQ!nO`iU?}If+x5wYBk6Ia~jnC>+<=RTQbvf6Yyneszo# zXZRtv-Rt|5U!KV31fIX7lnhz6=4HoDHCU_$k;D4w*~x*2#O)Y_p5GN#ABp{O{`pZZ zDy5-iP&Kk|*{$Fap{^~d-3Ii~AhXPGL^0K5bUBfkSGp%PUNZW*wM!b9Cetj|{n5Wf z*dr^MP}z%ysIMW56{URNctg-WJ#_ZyI-7P!Vz$c8iod+rXo=>j=PS({;mmjDIB>)| z{R@7@{Q5f$ELMyCeM&VFUeWMV?T;PXU04)3r*vX9&x2e`s?o}?ah^S*16yocnz7>1 zHcBk-Fo6lIY;@96cKxvjU~U#TtJu}hf(H(QGYG(;R@(@`x{(4<1gN<(W^HH{)BpT| zXizup+4ImemdjqO{DxCwp{D4yrmVzR^y|*7A|bi^>jA@h9S&dB;mBL4`wm&9!=Im< zpF&;R9SNWY2OKZLR<0d)Pa*@+5HZZLU;qp#7AcNVgES|mNtfUlVN~hX`dNbrlm3On zxYEH#djGY#o7=N-H|F*XKQh(-WSs9ER!$6epp9!yNi?~;8#9Ui%+SlsFdQvDOb);b zV|m6LV`FY*OR+kIv$4ckW6Us?I1GmMdX8~^|S literal 0 HcmV?d00001 diff --git a/res/img/flags/BA.png b/res/img/flags/BA.png new file mode 100644 index 0000000000000000000000000000000000000000..3e3ec3fc76744fb24ecdb688d2fbb9c87ee6dd31 GIT binary patch literal 3048 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/BE.png b/res/img/flags/BE.png new file mode 100644 index 0000000000000000000000000000000000000000..742ba9231fee59e91e4779ee9ae379c06f809522 GIT binary patch literal 558 zcmeAS@N?(olHy`uVBq!ia0vp^W*{uU1|;uX-8K(Mv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffzx4R3F27;f?yX%1z zXMsm#F_2CG;}6+R=Yb6N5>H=O_J^!8;>H@%A+_%r7#L+eT^vIyZoR#2sORFyaO`9L znJ|{Qb&r@P>3-#kGQW`_x=2`W!DWkvC!$+smvZdxOp89ud4zl8#@|CsiBpLfwqC6 km4QLUp{KSe8glbfGSez?Yv7z8+X%AK)78&qol`;+0FR=%UjP6A literal 0 HcmV?d00001 diff --git a/res/img/flags/BF.png b/res/img/flags/BF.png new file mode 100644 index 0000000000000000000000000000000000000000..17f9f67d2661b3efaa1f5307b3fa49b3184b08c9 GIT binary patch literal 1596 zcmZ{kc|6k%9LIl?&5=f)usLcJ31f4FMQt-zM#Z8$uDS22xf7e^EU)O$KG7Syfp80CqV#5M0GP z{4*6G;yV4NrA!RT5S%j(02;6E{7wdoXGDO5t1|#3>i_`l5&(P^uV~8v5QhSQ6+ZyL zFaba%ri69MN_>F$JJ}P&6vr2v_B1hMVjRv=#q|3p*CX)5;zlag(b-n&9avq(L|2V; zaSZ^#`i=w~DRJr(FD!CTkb3XNnn`n1D~}-&ML*8bwmq=h^0|M)0#ddeG9R0cZA0qfE9P;RX|8xZ}tKX`T*fP-sg7HNuhR~fLJhI!Eo3e!cV~F#-~>yTFrfxYjMKS zpiKBqmnEkzHMH9nQ&lu|7rwG>9p>Q5nABJ~>EI(lkeL1!RIjW(| zl(Fk%gm@j{hzOR0=Mb5gYkfOX3U&m^jUbvG0n-J>TEl=dme*<+F@TcEf&X<23?n+j^^a<8fb4ZroB>dnnM=&UfA1IcX z;%{5hBc+dxM>V5Ws(s9O=k|W*N|nV~OO}|rpwyNP4XHBgn@XpYMO&zhExj!DGoMmC zYPK`M8VYqb65bX%KY)QeH!WoX2TTdnAsFq`a7%-+C`nc`-_T6-M3abvFfucEn^JKL znt1S}G&wJqN<7YO=K2t~>Ez%sLC6_6}Y26g=CV%VGEj%=G zc@&;u-FtQ<5#G_v+;bg#MXCS0oYv~gops^~%oc}D zh8v~KFSBdFc467&nrdyB#gk6JtAVZ`eCA9Z)TsbHC z_ycP!R6>2qm8!{Hs!>3i7>+?-Ngobf&`?E>&~;6Ts7=A9zkX=3NU{nN2+Hs`V4iqo z-h;^(a*cFoEsiHl!`aiicP~pIBC$m~4!?zQ7+rimb6L4|Fj;SIuB zr25J4U0_@3%qct3$%GNf8}s{R6*!A=eQ|m1T%(4TPNFA-#T2$h^A?8y&lYPA%_(}7 zQd{B4UAy*~=0@jUk$oLZ@;m&mfATDP9QS04RZyv$`%7o|z6ti7epgk8Tg0DKJJ$A0 zY#=!{2orEVNDROjg*Hc`%#g+wBx4hd85(1X(np~&C{*GLf%Sh3QIx>2;H3XI$dr52 P#RkC9)`d`y_e=j9skOTC literal 0 HcmV?d00001 diff --git a/res/img/flags/BG.png b/res/img/flags/BG.png new file mode 100644 index 0000000000000000000000000000000000000000..b01d3ff57b3fc447bb34c257d41842f88d28f05f GIT binary patch literal 659 zcmeAS@N?(olHy`uVBq!ia0vp^W*{uU1|;uX-8K(Mv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffzx4R3F27;f?yX%1z zXMsm#F_2CG;}6+R=Yb6N5>H=O_J^!8;>H@%A+_%r7#N#8T^vIyZoR#s=*{9NaqMIH z`CyyFifjkBb)U`I5Fyg+Ybc?!=%9w0<3s^iB8J=C=0TRr`_gn3o542hM zcI>?kMVU{U&2M}cN{^Vy!=Lhhy=GqL)1b-Aa(135M|cWoQ`H=O_J^!8;>H@%A+_&;mil_SIEGZ*dV9Ox=Sr!}@sH1+ z?{Kb@5v+R9Uw2~VizF+|svp`gu; zmr@qD^d68{Vl?5%v}Tp2x)c4*j~XoA?VJD4LO|K<+N&M4{ofzYe_y-5{QmEn_n&v3 z{~foz)?T4Sz==Z)j zK}FH=jWOmr)?r_tiT_T#dGAwpYqa9WwbQTVL~{vhe)PZdux;YHb(_xpeQ^Im{L7bY zMptv5va*#jhclez*cVX#`pd?D-?z_bI@T>7aey(7-Rg$7T)_zqqdF$O=qMfc1N&6l zc@FrUJIZsQqyD}3`STx+I~;9#<@6$E{{GL8r6dZj?0Qw@@b#wMhNBJp);xb@*}!jZ z?tFLdLGeG5%RWBbpSyqd;yEl?U-G3MSe^g;N#%L$6=y5C9n0h|&u*++wSrM3Yz+%n zg2c1~D_QE>B0ChNGM>nVF=m#0w7nqVcqCW!wOY6b2zp6J=x!T0b zaWy%R&9l$((;?O3Y45jyA2T+4DI40K=c?gYy#?8)vUkiQ=Ao zOP1GQe(j!PKdxO460X&hzVq^UcemJ~vs)(3G1BL`|Dq%NKJzs9T;IU!2Pb9DmwnBe zg3t+y z;eW=dIfDBGgC|bOFq$Of>lU==q=%P@q-Up^vgXAU71dciOI#)slsqVJ(E2t1<)MRo zMU7jt_Ax~q;pFo#y2pHKSyjW*RUva39!0pbHU5^VW#L*eYtz>a#3E5Ft*_`K)q zJ!gT7GT~|G8KaXPwJm9OSlDRCY<2tnH+P{39>Zxuhbs(^xNN#}Lgm;r>DFIXh+KT6 z=c~AQ6kA=2y3~JQS)*Fw8c~vxSdwa$T$Bo=7>o=I&2J4XsQJv<(cc k3=Ap`J+(#Akei>9nO2Eg1LyqMMxX`;Pgg&ebxsLQ05EQE6#xJL literal 0 HcmV?d00001 diff --git a/res/img/flags/BI.png b/res/img/flags/BI.png new file mode 100644 index 0000000000000000000000000000000000000000..21865ac7202606154f011d3298289d0f094d854d GIT binary patch literal 5652 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 GLH`GzuDJ66 literal 0 HcmV?d00001 diff --git a/res/img/flags/BJ.png b/res/img/flags/BJ.png new file mode 100644 index 0000000000000000000000000000000000000000..a7c609143421ba2f6fad3835058166208078c160 GIT binary patch literal 811 zcmeAS@N?(olHy`uVBq!ia0vp^W*{uU1|;uX-8K(Mv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffzx4R3F27;f?yX%1z zXMsm#F_2CG;}6+R=Yb6N5>H=O_J^!8;>H@%A+_%r7?`9yT^vIyZoR#|F$ z{8#H*q|tRJzn1Iw|Awhkj~=bxzr*@y=)C6jKP=68-SuQ<i_P+O-fbYkOtFO0M zF>ZK!T$1gBG7nSyUkzo4iQiVoZrzgjui28#>isH~0}8=!8g_?f{78Kem3Xb5tz6ym zxM;!hyDI6M<96|XubgFeu71N3;jS_byPv+t6e3sHbDA-*sWmC71n+w?>w({l+r$PqBSH_4fwP-qU-Ji#3(57jjN`uk}&-F;8>;4=x7z+9To% zPOf;l-X+3Y`c?f5L$0)*CdtJK$271okM|a>y8hTr2?iv8vO3mG6pDH;4@{E`swJ)w zB`Jv|saDBFsX&Us$iUEC*T7WQ$RfnZ*viz<%EUn1z|hLTpyJR|TNDks`6-!cmAEx< T&W~*bYGCkm^>bP0l+XkKP%T3& literal 0 HcmV?d00001 diff --git a/res/img/flags/BL.png b/res/img/flags/BL.png new file mode 100644 index 0000000000000000000000000000000000000000..6d50a0f544ad14e2da315e53fdeb187d3c8781c6 GIT binary patch literal 566 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 G7WF^05A}cm literal 0 HcmV?d00001 diff --git a/res/img/flags/BN.png b/res/img/flags/BN.png new file mode 100644 index 0000000000000000000000000000000000000000..bc4da8d9a61313d5370d777f1e3e758971581513 GIT binary patch literal 5290 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 X?Eh~de`g(g*#OW~(^IW{U>ElvV(1W5 literal 0 HcmV?d00001 diff --git a/res/img/flags/BO.png b/res/img/flags/BO.png new file mode 100644 index 0000000000000000000000000000000000000000..144b8d32db943675fc1cc9dc41dbaa74d0dd5c44 GIT binary patch literal 668 zcmeAS@N?(olHy`uVBq!ia0vp^W*{uU1|;uX-8K(Mv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffzx4R3F27;f?yX%1z zXMsm#F_2CG;}6+R=Yb6N5>H=O_J^!8;>H@%A+_%r7#O=fT^vIyZoR#2=*1i;()!R^ zSkxy~wX1{gpwmIU2#!g-DU2`Q?;Cbms1ENdn&OEs%wldFWHkW-h7j?lpg zg{+_6i9Gx@?|-=bA!`|?`~)`^pk+W{Ah?q$bJnuVS*h39|LRXt@tmact8}{LTYld5 zt658vV%1}gChfhKv7>n7SI3F`&6RBjZ4M{QOEfrdFeClS^{Sg)vm#Ib+QC>YJh8mo z$3EicZuz@W+qrJ+Y4q zbmU6&*||qdD>vkcZZMAZv5k12bww{G0%)syVytj5|F)e)o44%ExT_V@um5}1oT?26 z3$Dzw-L_723vb|_mc?>9T1U5@TwS_+!Ph0P`JV1lb-N?9{H4RYJBsrTBm5?D#+c`s zq@DS%Xk}ucZD43+U{G=BsV$0z-29Zxv`X9>IOoSUf~@p(^>bP0l+XkK^1b;A literal 0 HcmV?d00001 diff --git a/res/img/flags/BQ.png b/res/img/flags/BQ.png new file mode 100644 index 0000000000000000000000000000000000000000..0897943760ff90d0323d3207b9bde50e08f26c41 GIT binary patch literal 672 zcmeAS@N?(olHy`uVBq!ia0vp^W*{uU1|;uX-8K(Mv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffzx4R3F27;f?yX%1z zXMsm#F_2CG;}6+R=Yb6N5>H=O_J^!8;>H@%A+_%r7#RCKT^vIyZoR#|(3?3?;`qns zciPtZTuCs9jgB>tGv;Le&*Uh^IytoYpn;{5f>b+CmU$9S}IUez?v5$fEDD#px~VUwtLo5+&H|f1SL2 zZ^7-}MNz)hy+6ZOmRP;rW*L7$PGIvwgW~}+k~Pj4iae9xD(?BZ(QXC%QH85=*O~Xe z+*q18e|F}qu&vu0OB1^%Z@qjq`E6lh?2WRL{{`hMY~THhA+G1AdoT5V zvy$_0J858e{95bD&~Iw2Z*y$|L?^lz=fp?YYH%$-vVVF_Jey6sW!oVc=fu8^|M*Ya zEzxnm^|!QkEuoy_%*TmNmj@bBuC;yT;wSMD7Zu6~x$7Mv7z&O&w7 zV@s&lcv_+MJ}h2bf9lIlXlN~X!rk5#Fze>SWBkCdQ!R0gC`m~yNwrEYN(E93Mh1rF zx(24YMiwDP##W|=Rwf4828LD!1{H^%+M;O4%}>cptHiB=bAD_iD0)0y{an^LB{Ts5 Dxuyo8 literal 0 HcmV?d00001 diff --git a/res/img/flags/BR.png b/res/img/flags/BR.png new file mode 100644 index 0000000000000000000000000000000000000000..02784925925e88d859654c73a595e088f5a122df GIT binary patch literal 4852 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/BT.png b/res/img/flags/BT.png new file mode 100644 index 0000000000000000000000000000000000000000..1f031df071cb791f8baec48dbbcc583b2b2ba036 GIT binary patch literal 4879 zcmZ{obx_pNyT-rUG)qW`z=9}9HwXf|bceJcAc%B#?-Bw^3M$PKN(hKFN-Tmi+%veL- z6`&3n9Si_`NG3mf1iRX!?9}h;06_3<0Ki5Az{%AS_74E~2?M~I4FJew005(B&PRiL zR|B}MmYVVvuXL>RDdGyGp6cd4SG4)>+Hp}Fx@r)<8agV7U$7gDVmvHHVcP&ebD^P( zF$$d8%ytT;Hy)48w-_7C)eT^vC5gvnz`&}QTlktNG#aXmG(tjEK{W8kP$@}_Bn*RO zHA3s755iIhVg|7Iir!b904b8T##d%`?4jR0H7Wa(xy<}ekw1oFw?frtt9&jFb7T(Z z43Q`_765^vB>$r!K?Y!fQ@Q}rGo1jHvnRK{+J=ZB&edF56xDy^U6A8( zXCJVfUXsKH8O|aA`5qr3fT!Fc30fVZ+>xBUn`XG66GtFVx79~@qLzhGs&$X0kxFW> zz=^9{0*9X=>41lUL?EkY_KXu1d|}w$1J5g%2Yen`rbTHN#|PlzYhG(ZFQ-qUQPgJM zQ8(s51eik|?!~v4c6Efl%V6V|e~3HIuXMz!3bq^cFM4=t?yW zmFvngbp#t-WgQ7{x1i!qx__#c;ZtlxrJb(wHNZ5_L%upRJU-+WYGu=J8(!>^-ONf5 zF)RjWj7dXLZcBjYsUB&5yJ|Ek8r6dcN7o?ZZ1ZoxQF9_S9TrO=BECYFPE{U`GO)9N z(#&}4$YA+E-$YfSJFm55EyqIP8=kP+W-jZS2O8Bk=qt5&ao^L!sTb$!R~io-PoJK49nhOr~Vfu|83E00zQ~KeU^);sNKu&Z-Z|n zXeT&AFEVd+3q1r=Mm%0+BGxn+iX+Os3lyuZI|qa&X#__|9r@p8{K8A^H2PElMf%D= zYY87s%(DWd0taOV-_`@oxg18Z_gz-qhivp4_$= zY1a7|xg)*$97ttvV)Ca#HMi+g)(S?4l9U4bkL+g;aQEj=(!aw?-!nMXgIxDEDskGW zg$cmgZhQ^`9hY&?H_#dcOS?w;M#M`SUe!aRDO=spILbFoZo+-Yo<~;YQWJc{kwRKi z+d>z)(eSPqW1jRI`$i=2DShQ-17kG3(bWB8a+^B0?n;*qI)|!MFO=!4*)o10=+ShX zu|r47BW~ISg4Oo-#!M@ok0s{_y#cU*g~FN@IO%5W_KEm)WwpDy?yzzjC6M-K6>+@H z+4WkFJYECuuwV^A5NtA#YLfr{%L@WrFx~^;c4;CD&XKR&1$I=Uw*n8S^rxJ{6!T%$ z+^tU!gYYl=Um2pEiu)%TFy>BOMK0yoS&2ilp-0HO4m}}jOgg^y_1hx0`OVpXE1Or2bol+=aJ zE028$yPo>4@zI4C=Y`fpbfSpfdOSYprTNM|;jXbn9iOPS65S{7v^<0MS{J9CZRF0B zW*7G{Ez4#M4cC?3*AGJ`(U+x7c3wI=@}}pl>5lji>-i;eWP_dVI_4&pVVrT387nCD zEfag~(BoG+i$V2nyxCJmZkrOeb(~CK5Hyrwv8-IF;Lmo_zuzX28!QL@6F7bE;*AYv z>YjJI77_?o8qwn=X-{QFx!tuen~j->+fvk#*WV_b4w9=*9G$)p!z4*LpU@9SE<0|M z;iunt{mcjZ+&{0J!2ArU91mD0=f68kbd=LiYfGB*zm~3{BN^}va4_*|@4JZ!JLUWR z@c?*LFdl{eKq1x+*zOT}%^2s0Qckh4n}o_5Nkbos#FN@q2jBviICi9W+_u{XUva4LJ^*Ym z8#t9g-7EEvP6>S=aWmmJA@gtWJ8teMhbgRyhb!#e<=J!zLTNG~rq+5DqM5mEvF$m$ zZT0u-<~RIc%fX{9XMNdp@jDrCL>=>+KVbjIN38nW!BA40mRshr_3Gh@E zhxnzc-|2-drpR#niwf(WmU_Dp?OVkaXj<&oNPnvgTLoNQl#WR*(Mo#)uh^J1bw%c9 zhI87|&FRfBQPL&2T=yPxkL6HOjjBzH8w>jqaJd(AN+yE|OfI~59S-;ne>SwciKY#2?CY$D;KCR3&05&IJX~Vld_DTd(w{JLy_!Ese4kgoEn;@;JE*YS2TBh= z+NZJ`c^B%oL)9V3qtWHfZFhur1pkAKnP-O?#dXQWYb|L7qc_JClSg8y)%Y+j|hC zxs%sa(+DA8jaK41+QZ5p8oFO(yVw}D;doloDsRT#d%iTIPQ>_C*|QKGfJC5_tJm~t zyL0Zo-5JfgFpP58D-FWmee*k(a;BUf%zPAdjR)h+Jq&Aiqc>|en10yGqMYSw=1U%T z!>XPFyw6-2n*bz*)(eJ6H%CBtI%e1R zmzFQtG9U`>H7P*QEj$bm87kg$kW~foFhLjxZAnjoO)A^H0%n&bw$*{GlX(#G>%jz8 zIj4oXPVzy1GI%0;Z7bGU$?4H>4~P|G@(NSss=t}%RnBs60LRXkrq9;i`l zu~6XZA64$Ahr6}#mDR}{Pk&?)q!x8jGs&ZgI;(HKykP?6kSKc4br|#Fk(=7TY?$eZ z|LmzEEzkMcz&~W1JMH}K5$Xm5?~*#S#uyvN`+vCazZmI;oQZ*AK1aV&2_X&LtX4J| zp})D^8ZR}&+e!GoJZG(rKRsp&{Mj!mA6rAWYf~vikkzR4+GZA(&3gKVDS@=c!i>c; zdDz*XFD6n`^Vhs;)ZC8)yc~5p)vfInA;8*hV)%t5fv*Y|Be}C;9eNo105$c%M}ji_ zU1Q5jBWPFoPPjoB=*-IccB#Q!$wTrEnRkEGtvsqdF5Ua{n2}?yU3K9`Q*YtV)>3tKHm;`Rb-4k25x! z+tpwOia`Kj-_S%-{OonQ7~WUR!)FuTTJTesA(vH)wQ< zri^BmgV(M$Y}^OGKgHhuNN7nruweZ=BkF9SA?W#Bbjr#nwxeo>rmRMu^`8`xCy%qa zpJAT2&ItR^VI>54VA9;D-)<9}BtF*wJs)yDB*8SJIoKff(T#6IZc4|pt$*YrCzH%E z3lzQ)$zJj4JdbmSy2{fmPG;`@MZZk12tk9AHX@=RT(85o2DcYoL*|HLI7-8+oo$A? zps5YJ#%T5Z`$bR!w3;Okk{doET(_BEC-WT6)|UCh0?3>iuTD$y$@w$luh;VsQ`PLN z_dBdlsd?UEG^&t}GB0dLBF=1gIr7aAx@X*YaekH(d6FOi;i=6JXoF4`56n<-c^Qd= zUNEWiW5spogzXD*NLoD3zqe6zTBvAMts$?=tnL=M5G(|~j!08QYO=n(A%uNU!|kgB z#opu+XW|hTsR9aiv<4e5C^~u#84Bup_h*5hkdYp3)N;6M)oc$y&v0#gm`t! zi`umk|S&q<{k zY$o)y`;tG-?jl0bw6eC`z%;^(PhjmhwaH(w`t@6SrF^SKeAx|&ArjaAioi__~6xo2G%Bn}H z2!eFl4}l_vqlM2>s{0VW*W-@^alY$x7&@HpZo}my72nP;7?)EawZ2}s2OH?1?05ai z)jwoj^Ck8b!JhDBTvQ%XE~1tMaEWlHuJ>KAXjZSQq*U6zebCoF@Oznx7=6$b2j3d8 zO-v>J46?D9?6zrLd{Q<4+od2RyS94=Oo*9XyK5aMO&#>G=Ccvd zE%2xtr!6*QNyerBSp_hvh$wc6U=LR{_h9Jp1u6@Z2UE+qfa3NN1yGL^{9`Y+2T~t8 zhTZFU^NiKZDPYn8{QGOL1bip6`6*p#pXVBcWAXz?WXYQrFz_-hFoJKae7U#)bUm6N zb$+s0f@|=GRk_y_8B|Gc`aH5_C{T{C_fVdruFiP~TAthFDP|-mwXl&t%Xr#H< zto2TAHep>=isy3Eujv0~F8@hkF1RkJ`TyK4L>jDqxeAAF`Kp-tK7QnDFJtFze+58P zSVT%dSVBNl+DKGPMnXhJT$oQ-L`GOR@bj|V|1!9FJa&2#^#2=3^B>}_41k7;u5y*4 HP2_(8NFwzW literal 0 HcmV?d00001 diff --git a/res/img/flags/BV.png b/res/img/flags/BV.png new file mode 100644 index 0000000000000000000000000000000000000000..aafb0f17761442e115d157c6b3ee29b7c6758645 GIT binary patch literal 1695 zcmZ{kc`zGz8^?bVK|<;#Xe;%uEo((+9E~f7khrR zZn3yHd9Sqe=fsE?zjQ}FWzUG9i0??{J|78KqEtu|lQe?@jGDLju8KI#@!pCwQBt^3mkh%NG*O-sfIqYESRJ2+u{!o~gMRifq z#@G^$+vSv-L^aueLOoGo{W5#=S@E%Q$<-dAlziXGf|HzrkBa?nM%fv*etSrgAUAvO z*&|F6@#I)JSy45`u%WGkLD}%hgrNo-0a;InVIqL2oS}2eRg|&prvjx1IikED4C>S3 zatdM{R*y*{I?!x1flyR=LLczS;~i_u zDFWEVxF;XtZX%!eHED}ecMgqyR%HcKDlff@-ugA|O(R4cJhZuTuY{nWX3;Qc1;$(8 z_f9iRofC9Wzqo>biJ;v|B)f4ic?+H}=vG*ZwtFZmQR zqvz~`@P#Yly0T32NgZ#slRc5bz%2>6ky>Qu+|jqp<+#GODIw7#uNGug1In9rH0qYhk)!ekBp~3kw*0Q~hv(V?>t0;`5JR8p zsrh{?V#oMok_}Q{fAw&mFJvP9;<>YB#|qO1U~#pt8+cn*pj9vMa{~3MDICLIO2x(Nk04(UQeb3(Pi#pOC{@g9@4aZrczlG8Js86rAmwc`3s_Bq>U znn~&I&2rQ#rF*Ee6YzH$Z|TS!9kPqcsH8E?zfS=pz2k7(L6y6v0>P}?JOk7Vt<`tO zLyx4EXx6Vc0>Og)vZ&yaTWaEF^m3I)SW_g;VI@GLc3!;`44$i3?YR!>?G_XqHSN%~ z;TkM=se`yx`F(`r=Fm^s#N60mjTz)EWA!_tfA`w<#9xU2vE;^NbF}1zv&EV4<1ZWA zDk?Mf^gPCCa8A3$?pK2uSvyCAww$gcUTsgWvMK9~UFF;r1e+nob+mTode9GA>hd&> zqbsJxDNwSnA~dkLT!>OF7#g!Wz-^I4>RXSdql^y^mUACIKQ&pGCHA=g&!AvGwp_o? z>B7h$=jMOJz6}^-1`K=u`GSd=pG`ep=WUP|zwJ-fULYQacU(-mvZUwdHcS&-f!*W zCHa*#CrYET`vXce$NQL-hIlW}^@6H@-BEZC|IO14m#>BM50cC2|HvHB9lnABzDWmw zqBpvbmctpjZi4HHLCG5(S@xN@F!CdLbA&y6*gwtxF~;j^8||!n;O3izLPOH`o`o%3 zwXe~7c9_G9{&E!#w0)9~(FlpXV8=vmbgfa&rZb;H;9m-vQKD}~^&)Oj8paH=`t}yj zn@fPWM|G<=Q2Ic)y}Jr~!tAYGqr2)c%5qH=O_J^!8;>H@%A+_%r7#MpzT^vIyZoR#2>wP#tKx#0CxIOGr0I=x5F9$Z-Yu5aZQiyc#yoH&m~ zs=O48=KFr{fBwk=ryczKjdzxqg1iL;0fIf&ihYkQ`Ywl5FWlF;NTX}fgK+zWUzpa0 zEuXA%%kWNlLBPru%e7}R^abjj6Q?aSI2|w}RpX42NSY+q=AH`qv}ZmiMYc?T-MRkF z#2p(J$lPIleamxCfbsX6&V`Bc=jW?0URWl^uQPkg3}Z3zYd7xK#nfE&d%Uml<=V2{ zH;W4s&A+bR{&`=S%=cWg@-y%1^*(&gwLP9Gf4o*!@P1;V>6*6Cmp5mKeM_7MJ)S1={48KYnJbg@qbdIAtt`G`8WY16yTI(b_6iDy*;-IZy7*F%2G=87aC{ra=JC1*`66Y~GCTC*IRdP`(kYX@0Ff`XSFx54( x2r)9YGBva^G0-+Jv@$TLIP}yOMMG|WN@iLmZVjCCV;eyhdb;|#taD0e0s!$+{m=ja literal 0 HcmV?d00001 diff --git a/res/img/flags/BY.png b/res/img/flags/BY.png new file mode 100644 index 0000000000000000000000000000000000000000..ce9de9c9c7c03c3291c7a433963ff87df3b22558 GIT binary patch literal 2023 zcmZ{lc{JNu8^?c*M2f~TT|%wH(5NEzN{xMOgxVTnS8J7tB~3KesMd5*Gg{P;$XI4j zdrMpUK1xwJ5?d^L)@6z7XD6?uNA^1_16T0YKti0NCeEB`yO10SN%B zJ^+Bq1^_rd_pO5gZ-L(rZDr0Q&-Tn35_k~6Tf0T^=<{!EgqjZWI?!kvj0JQSA_dn% zNIJ)Hc|xX*xrsArd~G}ipFxo6+1$-2gogzGAbC|J{{+3DJT}r$h5Sk1|3Cu#N>`8 z;HhK%+#PIlhVA0syw|cBE=MF@mr9ZrWV(qq#ra|oe>Ya~W zLem|v5Y|fEpmFD<2tk5?U&>JM>T#sMDj<1>$cw9+S8$f@<*----@XPSFV%VoBTfVq zHnbREI3%h9BA7dsn@bC1cZlFGsqN)Y3S{Bi!TxMO>v!M6_lhTl8DT&xt%CNs|HJh`F8vy2oLH(Q=69^)p0W(E-235b2)nl4ho! z(k=4sAoUr(t{1jVS1f_jDX;mu$7+79XYN25=dj($X77wYHF zCZajkRLm>iW*d6ty^mlrt>}=UWY+h9(q=&y9U^~8qBpgEHXr^{J=fajA66F&YgESm zBQ1AmS(@3*K&34?g}F|r_q(eo%uX$+I8_!?1{;UM+oEPnm}{Oy`Pt3IT~@I=D2FXw zBRp=8&At2!Uxy`{qA%VWH&9NvC{jFL<*w|#uAeIa<3w%M!%b-|<+%<1rFBP2V^r~>L)EG6iazDyY@N-@p_*o73kmfaijdekk#CcQ7DQA>YVf^GTQIqq zU|1?x8zyPAlA?|Dda|+lhajtlQ9DKB>pu9WKmPW~U*pK*6h%3=iO@X0*|si1rP7g%4fK9}D$JFD%Mp7?~M!)D}*DFR#%0MxF zO!diF{)$^~YU&Sm@dUgdPEU&zcJ2B~q_KV<_FZtf)15SjvLh?sfx{hl$=~T)T`o(S zOUVnhoeYIV<34g1p=dCP*b!Qmu5BblK(qtb2By9SEl<8$%4@tLy5HM5zL_+W7h4ql zRhEwaEh{TQ{&kOr+2#jSF*M{qKe6J^yQIXZ);nk08wVeT>Szs^TJ0Cj_tm$NovIZ7 zKHLACL9~4i3XsIj^Q$0Ojgc^joRxLh-DJ(jBeqOb5!7vW+rcHS*k^$z{-h|($fF#Vv4qNn1}ue3sVYquB_X-Y znF(%^zgG6CfL1p}n-~kuWvYFgxtzj!xwv<*jmpW3TPf>%j8hq25H5s$pMULs9dV#L z_aQ&WX)ulSR$#JkymVZI^0bIkxqV#qr!OQN*&mR$upEvk*yKBpha8 W{C|M}%`=H70BkJm%qvWNDE|dm)vgBs literal 0 HcmV?d00001 diff --git a/res/img/flags/BZ.png b/res/img/flags/BZ.png new file mode 100644 index 0000000000000000000000000000000000000000..33620c3f3147e9dda64cadfc8a6e43f6a26cfbaf GIT binary patch literal 5281 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 Klq(g{*#7`I5(Iew literal 0 HcmV?d00001 diff --git a/res/img/flags/CA.png b/res/img/flags/CA.png new file mode 100644 index 0000000000000000000000000000000000000000..4bbf8b11699889977bf699cfc413f8fb6106538a GIT binary patch literal 2246 zcmZ{lXHb*d7KT5-&?FM2YG}C@P(*_C8bXU0K{`kYAiV^T&^v^#lzXL0RY3*m9+8fO zBS9lYiU}nJEg)dxjSP0I=~j0}B>a z{tgHyYb8&%ma}lo3u%G`faaXz2d*I2Udrv7g$V#eT>yZDWB}M_l@h1`5DEu?Z!Q3! zQ3L=YL8Tq$TC4`=Z8XY&MV5Z*cgC~86LjqsjzyQ>vEipT!b-S8j7>4LEl4KTOz$YK@Nc2IzkdVU-5kvJC~jB6 z`E(stNvDW9IfuobJ_PrsQ5Gj1u?;H8kYN55iNnsYqrAto_e_P{3gQ#3D40iP?DE0! z;NS(pr@GIMheG6X3Wy~sD+C-wE~7w@T3wY%BOq1``0P5vHnIYx{Q01;+ALpJ;v3B? zoYLw%?>^?&M7 zenM*7!3H#q0?5{1rb<&7Jbf8WgcF*4*Yox0L~>4UEqb!AslzpNG}w}4veEaB-)3Oa z!L#*!^6^$olkyb?%`3(?rcX^DEZ0in!2RpkItropNjyxy_L4Q|Zi91(_6!P|73kxJL+u=}Y z*U&L#wApr^=~_r(*S!1Ah5OSlI@et}&b2zczjZ5baCN(d=stB6wdh-DLz2=M{8+xw1L;OT{ z6xEtao@nP8t9XJ)X((tAj__vc&n`v@T#~jLSaWg?jRiG?YZrOgBx*IPdJys=VvSe- zV?mvnu!hq=XQW9J9^T}S<*iY#QGZkZ9NC;!U28cx8jK=|2lXqeYH<{XJI=H9L(^0V zYl|33uA1hWX0ul>0;KN+h|lpxqZs1g4`bdJ)1x-kTyKbSJeHLB1$T^?N(o0|t+7HA zj9LnaD^*OCo#r+}d@T~{JkeMC#M%UoUHzk)b(|7j1?uPR>)3VX@%r4ke40;C{`1!m{ZWyG#8^4L341@7wvM($2Qe%s<+P>O zjTC+cb3;c|9k+CYN}g)xPc2hezsHWqmNop;ze(y2mk4}IW}jnr?)6_gi(E_^0Kt2) zaZvY>k@B1#U2HQbmTi#Kcn7?XiP_qW=@gc$ye{NUYVm*{HT(=mF22g5jEOv>J9oq< zzOOHKI2z7b)K{>vi+iEdLLhu;621D=!xT?mBD-J1nqpI@-eF|%nFE(9fTpMJ3$Da>a6^ z-EGl#dgH`wIr}BTTJC@7+*{(vpDmo_s!_D?(jB_@;B=G!PRnFa(@z&15`nsU4uxCl zpw5+S-t&h}b1FAZb_o}*>@Mx<`l5Z&rO~Iabgr~SFEDo~jcGK}EBUl~W-A?!MPQjc z17)got=p2iTkS(#PWYrg!6u!Or~nVJ`N&?~*_$bgwFB0D%xDUQ8U8I=n0|}f6;s4@ zUsl?70FB53R5nmk&XeEX=;T3IT@$E zQ)uaWbe1WZLDHPnWIZO+;At?Gc|zq)UeX<|^LTX^R7E>=!kFR~;c4S3?2Z}k5)1sO z(Bq~RQct%RFZ7xp>Vi(8opXDDZV^Jl;)zR~%|7w2$tS7WA@`-K}BddBDF}ks$SfmN3Km z)6a((+J(5ghInYW1$(dnT!kyB%E6W8uBusGRn$;c&`^TQ!WA^&@Cd@P_Wu~Lf$lz@ Xk^kSoQ{j}zG62SgrUngqE=hj@W|}Dz literal 0 HcmV?d00001 diff --git a/res/img/flags/CC.png b/res/img/flags/CC.png new file mode 100644 index 0000000000000000000000000000000000000000..fd40fc8a783c2223eb26f17ba01cc40851c82a53 GIT binary patch literal 3728 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 IP_+&F7oFT69RL6T literal 0 HcmV?d00001 diff --git a/res/img/flags/CD.png b/res/img/flags/CD.png new file mode 100644 index 0000000000000000000000000000000000000000..230aacd454fd3c7edd75b5a117b437ba967bab8f GIT binary patch literal 3704 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/CF.png b/res/img/flags/CF.png new file mode 100644 index 0000000000000000000000000000000000000000..c58ed4f7b2d3948a1e0753d40773de5dc5cd2228 GIT binary patch literal 2655 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 Y@QeQc0eG=1i5&pUaMs3ESdXNC18?QJdH?_b literal 0 HcmV?d00001 diff --git a/res/img/flags/CG.png b/res/img/flags/CG.png new file mode 100644 index 0000000000000000000000000000000000000000..6c2441e3e03061a3eefa9c550deaaccd348843d7 GIT binary patch literal 1381 zcmeAS@N?(olHy`uVBq!ia0vp^W*{uU1|;uX-8K(Mv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffzx4R3F27;f?yX%1z zXMsm#F_2CG;}6+R=Yb6N5>H=O_J^!8;>H@%A+_&;mWFt`IEGZ*dV4!ICpcB&z{mfV z&+ls8WREr2J&{9|*|}7_TV>aSDH~myh4y|@Hq?_+Z|f9SQDN!m?mpFeB4P4ookX{t z25|=pDhz!+e14cr%22tS!gcAamL7%-JW0l>;3OJ zaeG)5TLhdqAjGCa9^V=QG(@;sx19SXz4tZ?Q=@}I!kvrmOZPd1hsVZl(@*9L`E%Ox zoQ9OdBg>kEJ_%hN*7DRfk^9-I-+mI#Qhu{4K6c@)13#-CvF>9i=AFM$B;w$tC-I*( z)h;wVs;fC5daY2f zf2Q~tyGZlyOEWLzADs8@fukwc?pN2>1jQfPQU6Fq{lJ^Y%3TLE7AH(w`0gRJS-*dK5_9O3gocgnMj{#P=10T7Iq4o}|FUV~{Kn1e*7i4j z-B`bUlj5uGvk!?1#3q`zhBwZPkI0Jk*!SZRw^{9%)<+AgdjE$_uoL}63fwSe& z_ian2&wPDJ_SGeu_Dz4S*Q8xYzf;!7T>J5PrM=gr6L)2&tqX8F<}BOSzG~U*|8-L; zUaL*4K3J6d<*wwZ+kvOkg-%VjK3G)#WvS|v^oQ)H|6ZIvEnr@&^cy|-+D@H42}ZyE zT|dOBwpd^FCcoO^e78;FK5qBdq}a{q*=Kn&#z3+*)A0YnlrKxK{$ZVb(OmzMJWzU% zS3FQc((pS_w^7zNpmgfdGtH4kzcy)pP3ZJfJo)1EiYv{&_SdiHn*iB+t~6Jwr`DT( zJKEnJdo?=sOKQ}q<;!~Hd$npFp+mv9BtKEiE z)St>O%RaX1Yx~ClE~(^$?N^No<`pf>1U!xO;8Qgx%$#&?;b34c*dS%92 z0o$uZHZ@#}UcYHN@i<}YukvW!1?P8|$@;uoaWdGW+X!UhwFl9+7ynxL@!KuOQsHB( z=19D6`YHTAkmH!qym>;WybPzL_b|#lSd({MHo;7{@*>xvf}_i?|IccDp}qF#L*)cn zjmofGhQD)fpEOkCPw=z7zFot)^2vKQ?vO?Mr8yDVd7|onCX2mW{_?alfJ!md64!{5 zl*E!$tK_0oAjM#0U}&yuV5)0m5n^O)Wol?;VxVncXk}nfapTBfy literal 0 HcmV?d00001 diff --git a/res/img/flags/CH.png b/res/img/flags/CH.png new file mode 100644 index 0000000000000000000000000000000000000000..9fd87167df80850fdb00f8f10a0631b545282cd7 GIT binary patch literal 1500 zcmZ{kc{CJy6vuzIEM+OOgm`5w%OJ|kC^XF2vqV(JUK+BDZAQk>;)x+4YhxQjy=To> z8q0`MGV$y~QPyWm5tArydVjog`s3Ym?)}{5e9!&s-o$gZNMWHvLI40^3lzeELxZ0# zwuckn4%L%6;JspEV*)@;>fRksK2ELZjdHL70Ivc7@fHBzI4$De0E9yTSo8n@nhk(d zaQ;(!IA^fO%L<9$kYihC>9HIL2BTcD9D4lgpD?DqoP#v%qnN; zYYT*lQ`Fc>UK>WjM!M@vI&9TRLeQ(xve{f}~H$PvHv9C;|CX5J4{(pE{-%g){d{8@w>H}QW;=wC zWRgbh)M4W@)s*wBWJ^hdc5YhQWtDlJ)U1bWJ!i^@L9d8o1l0_U89Xsy%w~@87_onu`-}Z4lpW{tFU{x|Z?>Dfswm3_EZ#!PgG3dZLi!8e>BH){i0p}AUyN1`#E$8R zvUYuAE1KN}-&1HVOoaL?m!fmYG%TSfKZmE$;fpeC)GMs+ zOUgW6u|5#Cl5mQb!6gDlvo@896)d-YQjAvtWv8+>7rI%KuCO%}6NXkufF8RjGGm%@ z)cSV74#c)}o-NCk?Xx+sGghL`BuRub2J;@Bv}p4d_ZDyYs7m)MVF5@M(-$0pj!j-U z&C{9L$PFO`?i^x}p35fnY4YEA`*_LRGDY5xkgf0vJ7nJ#dw91=lRvUC9oqI>6G*x) z54FbPc6AvRw$$&|Izt1ya#%p4)97tU(RDMUp7s8)q%EcNdumZZq2f>dn|i-xSYIWD zI+7La7t4kFS?>d{^Yj&RRX5eLWMrn3Be_Ff-K19m<~QgpFGr zr|NQS$yTNZ@Ezxofr(TEsXTx#8+S4DGV3v;Ya?E&W$Lgd&Ngv-`7{{5aII80;PqjV^+MtfFSNnQN<%4eSed|J&qVbI=6W98V#GzTS`dvU;=u*-c# zC#0Znj4SNt<(Q-`LdwWi83()PZgq2^CBJYKly0f`BP2)zGwpnD>4t^r;&vjjf1OX# zfl!MX+)e-O#t{awJMN6eQ9`U-gd3W&Uq#q{+g^+L0Iy{~jEQ;Lqb`0diUxZ>fUWSo z{T2ThCI8@i5A$2K_U5UyP;PW}D%!?}R&!f%?jiNdCP> z=tFPoCb)Y98$00gU2qfy+tkExm bz#t!gKivNd1Pd<5aRk7^%ob5;>Jk4BT0o>6 literal 0 HcmV?d00001 diff --git a/res/img/flags/CI.png b/res/img/flags/CI.png new file mode 100644 index 0000000000000000000000000000000000000000..9741b9b11f0cd0b2b086a59b7864d3d7d1c8582c GIT binary patch literal 568 zcmeAS@N?(olHy`uVBq!ia0vp^W*{uU1|;uX-8K(Mv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffzx4R3F27;f?yX%1z zXMsm#F_2CG;}6+R=Yb6N5>H=O_J^!8;>H@%A+_%r7#P((T^vIyZoR#2=*8?P(e^Ok zWWhnL*bUN`a;6@VUUG_+Db8_=!0astZz+ZT+H$C=Rp5kX(2|>O&p0NEu(cS-DX_3c zUgN*Nd~V{u#CugLKs$h7f#Ad4yqZg=1fBDZ|FXZ+@R-D5$NAU%`CpVh|19x(cS1&c zq{fmx_r4dawodQ2Gr-j+<)_RKx&^zrx3otHwKHASi}1l^i4 z-&{UC=>5)^-tU)|-O=5)JxIf^dab)=c;&42uX~-nnh&NF)%;zu@8SyPgJ%TJ@K8+L z@BOzT`F=0NKMid)jP5+vj-~rAYzK;{mbgZgq$HN4S|t~y0x1R~14DCN15;fiix4AY tD^o)&69a7nLn{M=ibGFrQ8eV{r(~v8;?}@9KeiEMr>Co*%Q~loCIC~k&}#qy literal 0 HcmV?d00001 diff --git a/res/img/flags/CK.png b/res/img/flags/CK.png new file mode 100644 index 0000000000000000000000000000000000000000..6cca35967c1c69a3023e9f26ee4a7bb2427795be GIT binary patch literal 6029 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/CR.png b/res/img/flags/CR.png new file mode 100644 index 0000000000000000000000000000000000000000..b351c67a5300b25bd6f8f1591539a81d2aa28e61 GIT binary patch literal 785 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 X`Go&}gD9KA5Ey_Bkz`R}<`MT_XL`?l literal 0 HcmV?d00001 diff --git a/res/img/flags/CW.png b/res/img/flags/CW.png new file mode 100644 index 0000000000000000000000000000000000000000..e02cacd3dd9d242efe2c96433d9caea5da6ecb93 GIT binary patch literal 1756 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 X`~MeEWSA2!1;9OZJ+(3wY~X(Z<Jrl+fIc0q-I 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/DE.png b/res/img/flags/DE.png new file mode 100644 index 0000000000000000000000000000000000000000..93e269166b550a4a32d7c455171bcbcb0cf33419 GIT binary patch literal 568 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/DM.png b/res/img/flags/DM.png new file mode 100644 index 0000000000000000000000000000000000000000..c3a0e9d102afcb8cfe930bf17f68c7350097040d GIT binary patch literal 2636 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 MX=-ayYvh^qKj3-NhyVZp literal 0 HcmV?d00001 diff --git a/res/img/flags/DO.png b/res/img/flags/DO.png new file mode 100644 index 0000000000000000000000000000000000000000..5c4a004fefe1b0e54c1f5a48159f3c9b3cae1d89 GIT binary patch literal 1682 zcmZ{kc~H~W7RP_tpb#-4A`(!73n~gGtW8+*M0N;BBnXO{1lgnz#SkPKc8wxfUmFW5 zLD>`)kSbMUuu@qfNDX^{009&UOGpT1k*)97_fO|d=iNEye(pVYzH?^I-1%NR?B}7Q zjn)PLK*!6|l?>AEuiT&k?)_aa3P8Xk50VZ7z|Y?!S7-?EjtTQ5lK_Bi1^}s<0I&p> zQsn@UfCYdFDgY4j0KnjE{_6lo@Iiy_V-(0y0stb-%k^O3g+7Ip<4Z{}7R@Xqy~3npFy@4um z2<6fr6C2*H`}Xt-?en|QtbByePcGrz>bb8?)Ca#fY*Iq-@9#~CpI>ZF?degg2ZYLs zNwB5k7X9F>0cn^22`%<;xxr-d98@TM{zpfUNhJ!tG;wVypmp|_qI;3wGAl`(adIq`0xCk*>O@ z@0>_%z4$7ZOM>^dB@Wv6PVZG>%S-94wO7ngK5}cxbO9{ec?rF0*4g>WK~j-%vMzt` zR=u<{=8$)E<2HBwP(dh#X={@0Ze3T#UBCO&zL7D+yk7F7<=b()HXN~It{r(^d!bOl zz8|Wf6D?45qUcOk` zA9OsgO6cw_F2Bn+((D;ftRh)@&T@NSOI|~LFDEY~^HVJxM_x1UPQ$s1yF@N0t~~vX zkKAqYXgs-)SnU<-ttM(4nw*MBuw4J*p=jHUJsFS7JKZ>BOqM4BqE7m^g;~1Y@yVy* z(2WO3EL8N&mM}So0gkgT$|5U+l^8pGXb2YTd}~T$9uh`-BAN3W-W5fNymK_srNvBq zgLS>Ivu%P+-f8?H@lt%zfy{8e6XhoSc9?X=46`}fXw)0ajvi;*-Y;|t9BYvrv((hd zhS-d}5XKVA-7uI9*@63ZBYA%#3o8MqiK2f@%6eP+BPY##hm0- zy6C`=5yNZg4*u-GtmkjF!SYmNN)nn(_Z}qhQRBB)?IYu=rlxE1z3}hp0$y}#uGyu( zMnE{nlZn`ctaejdC6{DSQcl`GkwAUSGf3p=o0Q#r#*Rq(TIgR|Zc;;BKAX-XXTex6 zmoVvkCYd(-a!91NAduu;`b8hAjEnyuI2$|mv#$d8Y zA)%}(=an4Y?)mrU)^sMc$bd9{=<$pNrM{HH+b<1vbyrlj|D>x3gKQtI*cnVPdh>s)XR#8 z76l_5k1^=j2-m}3Q$<cH&}k{l_B(UF4gBNP))9|>Mz~7ca~GmppC30I z7Su|A|1g>3)Ohq?k(@$jO;rHo{y_UnbsUwbJ6R`nXoOTZMez|dkK)%JJ2Rek6a9Uw zE;c)y4q!8IiwVIu-fzA;HQig(nc^}DY0-VOhQJ^{KT&G}Kix!rGf~E%2?^*Z`1ZKB z`n}H%Ux7I^1hpB|Z^4E5LIX_augVnL+TXba`HXVMn-2+4=2aVtp-9|6u@?8oP2uv% zqQ9LFbitm_r?gL0so;9IWu#F=|WBa4=5rGJOBUy literal 0 HcmV?d00001 diff --git a/res/img/flags/DZ.png b/res/img/flags/DZ.png new file mode 100644 index 0000000000000000000000000000000000000000..1589d0cc40c5cff4163d2e8b5dd8eac9d320f904 GIT binary patch literal 2506 zcmZ{mc{J2*8^?cxF&HY#*uvzMZHfk2Bm2Ij3??c=2@P2?_GK&)PYlTxA$bhZm}D$5 znu+MizC|G_LmtKwGPbgPxk3F9?h^K_iC$lDyD9e=@=02vB;L)IOh zRDYT>dfMH#FSQnTXR?pqzJ^(Gxn#K3SLfG)2{J4I-XygpF4?;LH-ZMvT?T|sU2T}bk3?wNFO{;%lIwW zIOF;*1A=aknQF$Ac4ZW%*cQ$4ug!mm_t?;Cqs^^DE9o1b3hLA~=tVXCsQUfAMQ6X? zTFf|91-B-pcy#mB=BjaEz3{9MP-sgs}wh?%8*2EsSy);F>=v+T(#ed_6C!oPOa zL?c{FRCVz}7V4a=%*keWyrbT8{R3xo&!6S_jzHMDEC=hMIG{PB|F{QPPtU%f(A!QW zx1x`%TP}SayEC|RGu-W+eAU%`Z<`efo#WeetsA>|#`Mp_BTn??j71TOh@OApRwt*y z39nC^oQv`xCVWKo81EF~m80}By}9HU!tOSy_S}w)QSWd+KsNq7;EeYDbxXA9M2+ey z_yt_($f(5-{B%ucgpnUnV|tGl^vA3kjT&gXs(m)+K~woI$Yy;uiKsC+ zv_8_KY5qiAFnGsH6P1!O`Za}2t}MEj%#gdiL;Q*KHyFmYg@MYx5>6%sJX~-Y%g z5zaJiz{mB+#U5f;swp$xZ|<)5SWruZ27}@QGu4F)WGR9l@g@Q|e6j$RY$=b4Nt{l= zDqQ3!n@c}Cv)t=srBk8r1e3c&zkJipmb2kS^f^qbLCesL?SH-#5@TjT}oK<^? z+m}kE8ss__A;ZRtw;WwqF2LMOtOQoo0X1P+?)*&sx;;W@Kv>xi-2u*C$vMjjb6%fCYiNcaRnXB zW`ePV=G_U|W7isVRg>5)gXunRO=-HTomGk4tl+C8-1 z$8%dF%$>=yo=ka7!fQx|cj@%T+eu7`1hsX8Iyl|v_gA_KP~oxEqg-XSvxHJEZ_% za1)ii%UfHx%T*MU-*2NNOQv+Mt}t-Ty9JT*TeBr60%>6Dr&v|BW0eHM*3`GN%FxIH zB1qpv7o3-sxlO6thL3MN3v>&NrmW_y2b$y`&0CJzL>qM|+ExE>XH{;6gVY6+K?v0; zx(v*48eBQ8P=C>QWe$f)9qt$OlS;%L7d|Xk!T0}BZ2FxWcm4DWRL6dRVyQ?S?PR~d zC>G@J^bRuaurdBXGN@d)-7gk;=UOl1DsxshHZFkCJ*#&mC~!S8W@I;(M!2z7TxT2g z40#Zfx)VJLlx@PUt|zic%9&R0q7;YTc=6QTLX6a7!c0B0(V*MJO>qbG#kfr+*kFxE z=ZsyrQB#lg9-CEG)FKb5$pOyNYU(akmu4D>Phw#%j;md0w-M`@K!tDk!7c0DJ%d&SVUJ{)% zE=`l}Ac7&fRgN8Y8_Y4y`Rz@774nDn<$ieDC?%n0OS`)kTEi2 zH30QJEO7Z4v$3sd@OgjC1ET^r?91))?Ro;L`A7i#$UYiO&%lsnb1mAn^5YF9SyM0P zosqo|k_dkJ^eMgFr*rh7H;uDb?x@mD@f=WwfaAAN-u%WD5tk-Og+?w*kGXPXU7_acaBM@#G4I39jT_Rg49$|*FmXk u=xM6yokgBPs_7w-5pNg<{|E#G-tfB_`TqmFrB@T!0l?ba!Hi^rN&Gk9#*7RA literal 0 HcmV?d00001 diff --git a/res/img/flags/EC.png b/res/img/flags/EC.png new file mode 100644 index 0000000000000000000000000000000000000000..4c53dead1c596e1f2e427d3bc4db6dc4385a2d45 GIT binary patch literal 2818 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/EH.png b/res/img/flags/EH.png new file mode 100644 index 0000000000000000000000000000000000000000..148be93c083da57f183e96c9c3b8c4cd45e0036f GIT binary patch literal 2687 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 K#&t&SiT?(F(%^>x literal 0 HcmV?d00001 diff --git a/res/img/flags/ER.png b/res/img/flags/ER.png new file mode 100644 index 0000000000000000000000000000000000000000..7cb8441514c3969a8a05c6a861d82f873e9e8881 GIT binary patch literal 4082 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 Dr7z{v literal 0 HcmV?d00001 diff --git a/res/img/flags/ET.png b/res/img/flags/ET.png new file mode 100644 index 0000000000000000000000000000000000000000..7b420f02f4d484ee0d02a55cce74514986675130 GIT binary patch literal 3460 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 Nz?U54E%pje{}YU1q4EF# literal 0 HcmV?d00001 diff --git a/res/img/flags/FJ.png b/res/img/flags/FJ.png new file mode 100644 index 0000000000000000000000000000000000000000..cecc683c9cc928b682c3b48a6534fe2d6c595384 GIT binary patch literal 5060 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 bxjQ~`_W%C_&}>`$WdNX~WvE$p8yo&VabZPD literal 0 HcmV?d00001 diff --git a/res/img/flags/FK.png b/res/img/flags/FK.png new file mode 100644 index 0000000000000000000000000000000000000000..6074fea09c8d84381552b99f71aded7cca8cbbc7 GIT binary patch literal 5273 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/FO.png b/res/img/flags/FO.png new file mode 100644 index 0000000000000000000000000000000000000000..d8fd75c63895c5925d6fd6140cc492b8bdfd4b5c GIT binary patch literal 1715 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/GB.png b/res/img/flags/GB.png new file mode 100644 index 0000000000000000000000000000000000000000..589be70063cdc5e26fcb78a79e4d038a2232c438 GIT binary patch literal 6309 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 bovrL`y#Id#VU|hItpQM0P?P^AYmWIJ0VKIQ literal 0 HcmV?d00001 diff --git a/res/img/flags/GD.png b/res/img/flags/GD.png new file mode 100644 index 0000000000000000000000000000000000000000..babe1e4cc652b87d626e0f87d97168db415f8092 GIT binary patch literal 5753 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/GF.png b/res/img/flags/GF.png new file mode 100644 index 0000000000000000000000000000000000000000..98828a5906186b635ef6cbf154eb1fc0b6d380e4 GIT binary patch literal 2342 zcmZ{mc|6qb7RSG6Fc?PJr)=5xvDQq<*w-`aI8{=Okj#77!i@9smF!R+grYEb9MT zP)^o4!>p&XaO?)k4g~^|GvoRUIw`871al&8 z006hJl_|=JF!gOZ!pUh_{N3h8)CM0%j5Jxv(oMnRz3;7xVEF*23dL7!W2VLDT^@{y z)!nulasBYpqNqdz{Jp*Sr*Xc%bSw_8@<1}?OnZA?W9Zx=n{QEq zu`JJr*`fP)zUMaf>$Lqb+-|+m?xp?MR)O04H_Al|OAOBBp-Vp~dlU0lj$jF$pM%bH znf$6A-QhUI3#ok-ia^W8xw_{n-$m(vzN@!r4!kyt0$xuDNu zs-%=kkUB-f;X62|aNo+BU~f+NGg>6PHvLvI#wbG26EH~-RmZ;Nqu*H}f_04=9Cv?g zCoWJ(Y8i}TCkFlB$>MK2Tz`l9o$d5zhGbB0<{g!eFP29kVL{G!QT_QT_1o*BAY zQ#YUK#&``@H;<0TWk*kTKv5W`v)nF5$=C?2aA4DGGyE{Sml2hAk9Sm4(cZl~m2E8UQm+j> zw@>$n?YJZJ+Km0|q`FDwlDzTS>_o&1`X|G6_~>SV`immCX8Ooc_fpCCwpsy&K-JX+ zl6RdYPW&cP*KRQO$8vePL78?$4*T!7BIh9QAERIpQCiEjN5yYRQzoW;4h3$NCDYAU z3^i2%JC!!A!s^`ix)YRur5dPh@?TaTMn7Df1Ope8ZXk(*buXTDJw>kY$an+p=|2^Wqx$=*F11g}~R z?vLo9?+=U=*rSFp^WAbd9;-9a0*Q*RS_At!*Dm0hjXBLld|f;qg~5-$;0CMAdPFew zFQO;|q#yeG#jOrnwMx6jKB_Acl%twEu$chwwzBouje%D?s)1*lk)9UK48HlLImGj* zPeu{XRdJ$(+{{T?7>(+n;KWyR z-Z^SLOguRSNcuq<)BN^8MK!0ggtsc4QGD335W$q0bPZXFF8|Yyui%K6_LEO?Ymc-T zbw#g;2VMOq+eQ3~%kR9==%h`cRo8@tB}zzZc@> z<7EM7dNlX=OO3@)naFVStn?UMuTSe+?wD)`aYbwMnDnFH;r>uv2|{BdT(V{~wgS7< zv9Y_eN}Ky~YoKbB8vj9l>~i7W3DI_F0D}U3wRolNJ(Bcs3OV|fV@|dEL&j&LYc7_@ zC|E(o5SjURn%A*}4$;f=(EU%rBFNEYY46}^Z?o6<_DrQV=Sx4@VwEQzkxWfU*-sB$ zCAq$!do={P!$jahWP+J^hqAQ$%Tgc(A}^I#Qt%RU`|K$-hUo=u)bumu+lYq!?EPzR zyqMXA(4=Flv`tyQDiuL7lJyli%RFNtqhTpcO1V&|$ij9_B{x?}AI$HRf=Ca&pi=+s zerF{8NO=AGLPfK|>U68GV`BL@QJ}dpERen~AFa!4pMtp?b0W!;ET7z+cr3(E%Mz4?V5o&R1 zYXMu~b2jdr2&J9!h1B=xa-{S*W_=$6rB6J(tH)>FU1zJ-8>c*o&d}cgu%#LN^?=-_ z=Hcao&jVy;Mgp}IPtr3}qqLwjwd0kk?Zb6a+PvoU&~;^B_7=2$%bFnvRUpqzD$j8n zKhOr#!!Qp%_WV7A|2vV(6^}T1KexW##VYx*b_V${Gv_cbe3&=FGsK$(KwArLpsuB- zu6@QyTL+;BN9by)YQYg&T7)-?=l{pxAL!+CJ>vfx!1-6BSq8w$3~lo literal 0 HcmV?d00001 diff --git a/res/img/flags/GG.png b/res/img/flags/GG.png new file mode 100644 index 0000000000000000000000000000000000000000..aec8969b28a0153043202d5fb2f85cdac0871725 GIT binary patch literal 2777 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 O0N7eOS~Qqp(*F&Sc2V^J literal 0 HcmV?d00001 diff --git a/res/img/flags/GI.png b/res/img/flags/GI.png new file mode 100644 index 0000000000000000000000000000000000000000..9aa58327e359b86469c294a44fbb2db4be5b47fa GIT binary patch literal 2750 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 E0Kp*!tpET3 literal 0 HcmV?d00001 diff --git a/res/img/flags/GL.png b/res/img/flags/GL.png new file mode 100644 index 0000000000000000000000000000000000000000..cf1645c2b5d42ddce6f72ccf173e4f989c8f00bc GIT binary patch literal 3101 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 CSHuMX literal 0 HcmV?d00001 diff --git a/res/img/flags/GM.png b/res/img/flags/GM.png new file mode 100644 index 0000000000000000000000000000000000000000..ec374fb3c3347398bc3ed3713ded2b8f18095d56 GIT binary patch literal 709 zcmeAS@N?(olHy`uVBq!ia0vp^W*{uU1|;uX-8K(Mv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffzx4R3F27;f?yX%1z zXMsm#F_2CG;}6+R=Yb6N5>H=O_J^!8;>H@%A+_%r7#O#Bx;TbZ+bMlUECxf_9e{3ae}H(t6gl zVnM!YoIFvlHT9A6+nY!>%3I zO%F`2^5Nh1rSQYg6ScjJ)2=2LZ79>+Cl>!?-!Tr+s}p2$QX;PPuiu%^X|I{D^}Wl| zGD7!$#D3kv`NDN4UrpE`T3obY=G&XQ=cd0aK6HL zIMAYVAsX_Vc44E_jKUnWCv*WF2{cn*C_qxK2GyxyuA9r5N=lXSr z0~VMKC&i`WBI>l7ym^5_swJ)wB`Jv|saDBFsX&Us$iUEC*T7WQ$RfnZ*viz<%EUn1 mz|hLTpyJR|TNDks`6-!cmAEx<&W~*bS?cNP=d#Wzp$P!a#2OX= literal 0 HcmV?d00001 diff --git a/res/img/flags/GN.png b/res/img/flags/GN.png new file mode 100644 index 0000000000000000000000000000000000000000..46874b4d985d0b62ccae3dadde4eb47aec14a8a0 GIT binary patch literal 560 zcmeAS@N?(olHy`uVBq!ia0vp^W*{uU1|;uX-8K(Mv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffzx4R3F27;f?yX%1z zXMsm#F_2CG;}6+R=Yb6N5>H=O_J^!8;>H@%A+_%r7#QU}T^vIyZoR#2=*8?P(e^OE zq%*YZi&?P7O6HeA5geMAmQHZ!+OpI2-6W?yP3#`R{R&2M2i`Qjoz=6nm8EsV8u@+x z*7nBsd%k)A%?APp?L+>|noFkyoy*n#b^nM&a?iu)`H!}Xhg?lCkTc(&Afc71{`Bv0 zx8j$3-spagdNut!|NH4df#0UJZ=Le}tJ)b=Ugt~izLbC7ELW;7`q#i(XUX>IRn>-5 z*X7UOWv;xkYVG#9D@E2F($U}dZ1$u}DVw5X?d`MQWtuc5q;aIRQB1sdtG}}Gy&Kdo z-gb;vU)np?H9vd~6j3d4jVMV;EJ?LWE=mPb3`Pcq=DG%^x<(cuM#fgAhE^s9+6IPJ j1_l*}p4y^l$jwj5OsmALfpdOrBgjrqS3j3^P6tKpd3y zlmVbNndGlE{=b>kR`Zb_00eRa04fpyF8{4in*iV=0svb`0FcQ906LGHRztae2dIsX zhT1>=(}ikV*gp_?XqtNcBl3T1-&tkkUqj%nrKe7?iVvp~<7G4o*#iI?oR*rhk^kJz zJ3oJ;$*HelS2toL3nn|BoZqkuhQhq1mGbHv1wxxeSxRWfp*}ZJmnqcQmbMMpzpU1R65_=_E-9HQ!Esthqv`faA*N zHl%q{OQ#`tf$b(;l||O3mUCgrsIMk39eEzi&O2c{xKmDzhf�KtCKcaXBmRWC^jb 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 Z(LUh+4-n;9p#KE`Ep>ghY87Po{{YiCnsopG literal 0 HcmV?d00001 diff --git a/res/img/flags/GQ.png b/res/img/flags/GQ.png new file mode 100644 index 0000000000000000000000000000000000000000..7fd1015e8beb63cad1471ead7f66ad5fb9083587 GIT binary patch literal 3090 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 a_ymxn{=Y%0l$asCJi literal 0 HcmV?d00001 diff --git a/res/img/flags/GU.png b/res/img/flags/GU.png new file mode 100644 index 0000000000000000000000000000000000000000..8923085d5a0db8a2be8b54506ef3f20c70d55380 GIT binary patch literal 2591 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 RTM{Dxm>F5)UKrq${{@I~p-}(; literal 0 HcmV?d00001 diff --git a/res/img/flags/GW.png b/res/img/flags/GW.png new file mode 100644 index 0000000000000000000000000000000000000000..20c268ce0697234b88e1223c3254d0a5b635c356 GIT binary patch literal 1608 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 T){LvvBLiThZ?0FQOQih^Yq)J7 literal 0 HcmV?d00001 diff --git a/res/img/flags/HM.png b/res/img/flags/HM.png new file mode 100644 index 0000000000000000000000000000000000000000..8d1e143791ff36a8e5bcd8b6c36d875b747d2292 GIT binary patch literal 5229 zcmZ{oWmMGN7Ki^ZLwBcu2sjE1gM>5;rF0|BNC`-Hr@+wYs|W%TigZW}or8cNDbmt4 zbjMJad%xYg)_vC6=h^4%_4|I-j@8zDMn=p`3;+O`%5z2CJB$9iDDm&k**~bycLKkH zYrp~Edosz@OT4=~hxKz^4FCw>0f4YK0D!%F3flkxZx{eEaI^;2tio%gZBV{#!N*KuJ1R! z^T|I*mp7@|a^G_1_*7&}&;JZ;itmutm#NJ8cUMP>RU8|7in&+D2d^$~~ z)sHwjUc*wO@BiCKnJP}PGyMl$nJpaSi{R##e-j0}LACeu9@=F$0g>fNS43k>!GXv3 zh$REqt~Om>BOfz)EXBWAw5hHsRJ#^onej#(3uCA4BAzJtE3JfGXdLAQ#=JDH(~3i@ zA-cxR1(LVGN(@i0E1e%rUc70Ubf)d{p_pqyJWQCSf7v!d?vy&C?zu_0+5GOS?o-G> z%4Phz{dGO9JmU6aL^BV1dxosD!XkVy^%}?hEn*UL8r`p={rgK@kD~mlj`<7rEaJMh zmhW7?(#VgB*4Avjd$v`XhYYXOaCy`j!+3;qiILrT-_s}#)1-KMKtH)WL6BT*$Wo6~=*A>@T(+lS)4UwRjvp_tA-pIG$oL?JL`M)hTreUFd$;%5HYhypDT+!3$ z8S|LA7;M&7wBZz9{tMNi`L!W#rVwK$$t<6(a9u;*I1 zf4#rm%N(Bf<`QE~vwdywKqE~WBVYlB}LS^ z=&P-dZ8+kwQ+j)333+6F~&U!aP_`!urd)HbCF2ChJiSXWU@U;pOE zDOp=Ks_hd?Lss4vyc6i$XIeor(bEzy=@q(#>1L96

    9tx{;j%xi-5bgXB=KgJj5! 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/HN.png b/res/img/flags/HN.png new file mode 100644 index 0000000000000000000000000000000000000000..4cf8c3112c5992d0e50b3c41c82adea4ab294d10 GIT binary patch literal 1644 zcmZ{kdpy(oAIHD;o5|fH_u%aHob(MU`Lsbc?1OR|4 ziHP@?(f(U$KxAD!*vgRs9PR4k3IL5amAAs>Wjl;Y^!EXP3{wDLT?Bv)*%NCX08)_v zut)&_Y#9LP(%5Z&jeDGVk!(;%A^8v#Cglxv zZ4d?ljAa0j4<+GU1JXv8MzXvIq73;f>&ebDIn{__uf9~QoiOZLppD1&`BOb;D~q~I z!>^d;59|7WHR+lgI7;20`mla0#BYXOc2(I2)QvJT0T<-Jw!t`N1>b0WL0$T+V{e5% zor`P8da<6Fg{$0Tz7VaabC!)_%J0Q~mpWnHtLH#6K_#RXOFABR)LKt zL0S5Sa{N4yT7fHwRgTvJdN6VzHtz_lC-jTg`zL=Ds^6?tqPSex^$WP^c4k~VxsG{6 zbZ~z8-gKP#CpOgAq`4G(qJ+>lHlIPz$sX}E?qETow26cyE6k^g?VL8viC90>mtR!S zw;Jj|)IA5AJah8jncndPH`QE(#N3`2?>o%5!w+?;ksDCAVE0C~6{WYwh~3Sa*SvzYPd%`Wc>hOi!xmuU`q z@ryQ2pE+aN@GeWx&xf6=z>(@^wF)h6aHL+|-T~kE%XX{GF{aahFFQj0BFAYd(UV_jxU#@k7)0yNFsX1;iDo-@Am`yt;a_cuOfdB?rBHcppLJ3g3cYQ7pqjBOK! zYu4e!>?yY7Cq|-#2U@ypWf>#TJXrQbuSDmCsO;Sv=5TTUE-l)%ldw|a2B3KbuHyfI zzH=6<-C0s(>nbgj&jbHaq}&Wdh1F=sRBP)ZulwQo2@4D_A5Q5{v*XiBtrH^N=TY6U zv2-q(#*M4}E47nU&vi&xA9lVG{EAV!KcH`Blzn^yfApg*(YHL^(!NW=v-FGwq|t~; zKBGdjVD${)T)#DZ7xfhSS|RfWi&=F;+*?>;#nYF6 zh)rule&fDg*{}7yB}P1d7$$1E?wPMcnnTp)3~q{*cf$|7S4c{2JlC=KOhQ*X;}fk> zyY?V&0rse=FoJA05H{sf(pZe*(pIER<%7r?-<|mW5DY)l9q7#o+lK-pqV=gRaC7B% za&O5umpUFNohDG5_a3Xkwtsc`a8KIM0R2$a+F~qGf=(Nq_;y93Ty^0U%y!Nr1dE>E zk1MzyjbXHxwA-q=2H#z{GHF3h9yoo^W$aV;{c?IXw9|cx<=@+{q?h=)aZLI+QRRZ7 zT;mGll1A(3R_mlnXGZ$PW3;H;Ro9>cdYn1f;qxajBpZrSyaT!}&BZx$E}Z!i6Kc6f zFi3!)O)9;HllG{ZYPl>9Ltt6-FMgN(O#aj7wz+dO5#bI5=~sekZ>%`}FIyK7U(iNE zre})>+jz+CvlS=U*GZE_KC$Q3KVs*2w={`MLm9hAg;#@qvs9p@aQE@o#^ER11YNo9 zH^@)pj!3F^9N*eFzssnZ5Op;FSgkoEoWHn+#)d!78?Txkakh^8&d+4_Hq^5%S5t{W zy$KR($($FSLI_TY3{Q!|QqM%m0HBd52P>qV6&e$Ow!zw=u(n7GBnpc}roEcQeJ4mr ajEp^*{_g_C%46qc0)Rv~gn#Tt$^IL{@9K&G literal 0 HcmV?d00001 diff --git a/res/img/flags/HR.png b/res/img/flags/HR.png new file mode 100644 index 0000000000000000000000000000000000000000..413ceb1586820b1b4aa269c906a88d3aa5ef5887 GIT binary patch literal 2420 zcmZ{mdpy(s9>>2MM(&APxetj7nW-s^NUE`zlKWj^Y-Qz|A-4MU3&;JQT$9UC$Xq5$ zMHIQ;nuW||jZiLgcFupl^LU*12Km9uNG!CTJ4?s7VmnaTnm#N}d;O&;Ss26aYvM0AP#PBK-gWq7DGC+yKBJ0{{-; zbDFN6;|(Almo3bAyeBiR5T z+i zhZKKWl0VJP>hHo}#!ey=WBl*acg620k4Ge2+KHp`WgQ|{%!89k+)K+Kx z2|*isuimGBA#`tPAKcF%NIr*t=7e{>T`bD(F?v*;ETQN}J=o@Mgpy2@LfFm5Y+2cO zsiyR?^|XB;JC$DeeorPN`iptnbUMWG=nj=Se;n`HmRI9^o&Is!upuHs7IPM>d-(J6 zN{>S9d1d38oxDJ6I%|!y@9a#$vpdf!JG`K)Bizhze`VIUxOU$a@N?VbubLR{YFrlnz|}RxMHTnIpk)Z+70%-=P*Y*}hN5BdM+qZv~)RS2&M0=i7ge{jRC56l5+uJo}m- z-fRBqZ);LaFxK*T z3tFv3Z(i(}N^0AYbiqSw%xiH9G5zP0BG0DAOgq8hHwAJib>8dKqN$U+7J~Wl?>mb7 z6lfA*t@|6gMj#@5y-W7#LWp$k79m_|VX8J})e!yRMa1@EJ%co9XqpRtn&u#~SeSWm zQ71ohNF5QFpcinf&7-77z-D&{dtZU?%f0*QSHlG2D|(t=)bCoy}w zJp?1rEmbCT&cVi=T$ru$F}xYbN6vpo|AB^aOEi}zR5RLq2_J&GNHhW~;J4{$OGwH3 zuoKzj?)K8gHQxhgVB5t&hUMche((^~T1s?0X!JC}Q=3vTJ$!oa1idJ#)QR6`s%cH( zG=0vv`MLnfwF9$JDyZHUCw-}|PeM>Gd(owW^cPuiXNG}PlE5j_cG+$b-?El9`CGlE zv_Z?*=0|l+QdNb1X+Kn0S#javcl)1NM8amc5LA)NB^SdMROiwd{;QMpIhCSh%IjlA z&hHPwN(z-*TbI6X*uIA8(ijFwF9ix+4kk&x5DAOi>p1Zx$HS^-iv!v@<|aXs{xFY9 zimZqfrEGIYObSgRz1g$*;v3?xZEu%=N>$)0aFD0R)&m64qYPv;EGTB*jd909Wwewc zoq8Hul~k**Xn|z9$-nsUE$lJS)2%WipeWIUs0L6e=9QgWP7((+62WXY;zc5bLdkUZ z3F+$UdfW9-uhKPZty8`8XlGbgw(Y0qFqj>}4q;4lYgnpp`hgCNCuWd;)~!ckyfCUL zmn$x!^wgy57r>&K`d&v+Z|Wc50QUE`WC=Rq3Evgrd}(pX+{3y15>xY1#U+U_7C-7% z`d2L=#dgY}$>^hC_=wi18q7lro*rsZ%3s7!(Ob{)oI5qJ-KaiQw|<6Yz*>ExSRXNR zo6Vf_xKnelsg)6L*fZg`k|O#-Q4tWwOHw&ni_w?n0Q@GkcE2P2?wQ~D?Hu~A1n|Z% z-+EV-930fmi4usq=|gnTpkLV2J4rcv>X?iYvJn`ye}3pmEq8Mf_as$ zSK565_-b>LC<8oHT@5+TF&gQpYL~$vE|^_FK*rUpteeo^OY@kS&Ro6jfXD2NU-MJ$ zFx{R5u2HR;A6T^$BVyt9Rs<`~!r#}7uK`f#)1!51rS#pLEbqs_Ub6B1y-1CsIWubw zM`1ksOZZmo;-#h0#`A95!E5~$ARuQ(I^zS=NIr

    p`1WDFsQN*wO*r#We=_D~b_c z70^^JkZP>-UmJrz%xDaOzrDi|Wl*MgQz{N)+h`t(mO~J*E7xAsEvP;06@?6DCrN=2 zCiVBDpHr1eCwo;k+m9D+N*lH*Ea7Ox1p){fD1sG6*{!LL5Y|(PfUB>xYs}+J4Uy|d z+h6$2P9E@ADvL#OjLnt88_mVQ7dVoR6H5J2Xk*1jr0QN=?k302 ze*I1SS!+Am z-wz0F;U!c`glD$4mAz^I`?c>X{?Yb12a_c{c!c6zAZo$p_Q786!QKX*x4n4)bahUh zKBWdxF9b-pV0p=*q84d%@Y8Y=2m7^rfxC+ E29JSs1poj5 literal 0 HcmV?d00001 diff --git a/res/img/flags/HT.png b/res/img/flags/HT.png new file mode 100644 index 0000000000000000000000000000000000000000..097abeb434461bc2b49bcf88fad320cb147bded1 GIT binary patch literal 1944 zcmZ{lc|6mPAICpq#@w;wTp~viW6mKrQzQ{1#}HCsj#6W6gh*MaM25VAvCo#RmNzaa|Y z^?r3Z=F?JOE%^Z?4VI}?F>1m6obP^#qD5t<#4|Y~7$}&PKC3Nx z3aO3JEy?+wojX}9B=IqapCTH%i0-%+`9iCiCI{$4WNZmum-O)LJtA2_ll5___+mzkygh3A+)^B4ZDca*zPApFWITy?2U%Egsu6#h2b#S zq^Yx{$T>(3;qqLuQ%eeC)9m3*K8+x%V5Jen?FYLmcFS>o>`R_6J+WqQHQuo&A=@xj z1m8%zwoDErfL#LeukN}D8;5o;pxpVU{C1r3#Ai$*-g@%stUF|@io-D~Ctx;>>Y~%( z(~yut)l#TE{pbR;tK324UU`BMvVUE$3eXOFvhTY5SxK{rvDp*!I_wH>P5NEI#JarD ziH9Tnr-R1N=U&jm?P3XomlY4wvR$uFY+vQ-&h*+ayZ*%@rlbk*CN@ zQUQj-#b|WPG-+V8Ab>r8b|ONYi0)>QPEM{F54_R2u@tfD4KZQ;@>2w zmfuh5sKo6yY;6|40emhnZz}2Xq7Lz%qWb|g=)+ur@W;aFL-011t@od0#e} zXRg_CX{k|^bsVG#4+Vw1vhqw?Zm|2u>Us49YxuC;cNL}>tIZ;#qY`cSz%rv z8Kx$DAfIo|`mN5AJ0|kQd`y5Nv5DGH9xQk@An3zd1H+iPVeQFBIUVT6kgV?xz4(Y%3rb-SJ#s@Zq-1`BfP zyV6?gi@u5ZArb0feeab=tsy*8o%2f7$}5YeZid(?b;9z46k6^;y#~vqum7%Gr#EJg z_Scs|@1!sje>LexJl<~XB-=Z*hx<#ccvDeyTwn8`$#e@a?0UJ#A+% z)wX1h0$vl3;L~~Xm!HF~kUo26q>m;kpeIzHMsenDqV9Ur9U6ll3Og z4$#y39c%!+(DZ6Xp1J1NrNPmnN2zTdx?L&_juNB*6^A`;`s^G`O>U}mIBo%#=vrpV zmf{){uyURUiC!>Nr2=slXfqq;J43vFd}VX;FF%}6j*9Yazxm+lrl&TD@z+E3V0>_F z)(^>QC5@i@d^V}OzPllaTG>*9ZkN+~);-0dmIg?!We+s9c>E_$>EYhKdb2(4U(obN`1`$*!TOFj|IUUpsyG)j>K%OwlilU1|G zxb?qV6ZdC*oSiCKp2A-e_O5Qm8~YdQlxvE;eQh;c>Vnm>;gRtF6YmCmcLj8hX*J{S!1Fu`bGty{38N50JITW`X>;&C$tS*w2>%XEtC#I4WWfX jAa1;yHTgpj5_T~-@aDe@poLx}jsUQ;K4bOL0-Nw3KIe8h literal 0 HcmV?d00001 diff --git a/res/img/flags/HU.png b/res/img/flags/HU.png new file mode 100644 index 0000000000000000000000000000000000000000..23499bf63cc9e96bd7e8f87f2d55aea489537046 GIT binary patch literal 677 zcmeAS@N?(olHy`uVBq!ia0vp^W*{uU1|;uX-8K(Mv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffzx4R3F27;f?yX%1z zXMsm#F_2CG;}6+R=Yb6N5>H=O_J^!8;>H@%A+_%r7#OE`x;TbZ+xNtZ#cbOwYMKF`UW=AAEQ{H)oMt+{ws!IE=OulchctiK%+h145y`93*+mkNNp8YXLWSdp=x%@X- z$6Z$Z+M?Fpc~e8D`0{@9377jiPfVz>zG*5hyEMVV;+kLQiG3YCM;GrbteaY1dD*Yi z4`QWr;nC}Q!>*kackh5AKM7B(bLt>Wt~$( F69ABn1xo+` literal 0 HcmV?d00001 diff --git a/res/img/flags/ID.png b/res/img/flags/ID.png new file mode 100644 index 0000000000000000000000000000000000000000..80200657c63a59c61de32747f4e75322f9e3eb9c GIT binary patch literal 579 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/IM.png b/res/img/flags/IM.png new file mode 100644 index 0000000000000000000000000000000000000000..c777acc490b3bf406825f9ff14762c9c0d20e113 GIT binary patch literal 2533 zcmZ{mXH?VK7RCRBkWd1Nw4fjzh7mELC?hrWCXj##VTeI`l>h+*#UvnAr3?rTphR>K zMXC}QK|q>_R7s>`kd9KM4%HXmw^?t!z1F_Jd+%9$oo{EI6s(;yIw<+q*&wZzrAlbxDLL_7{_%FB<(DDoN0`mF>ihm)K3p-*0s%GA2b z@~oUFM|q3oOEHu4&LKU6jwlHjB>t^C`d?U68`yjF;-@ZH6Oms3tbUpPsRT5E^0>S_ zYV{6`nCt5&Cce#b9%CGC623ZN=g**xKHzw2(ye=0RAp4yaRgYH7tA)}J~xnnc5fV3UB}?dgAf*& zhEnpeQtDx~ur?x9Obm^?Emp#|!^2)VOaCQ_CY%<{!gQp#NJFaI(!Y4K!S5A;OL?In zo#!&-4{&SVM``A4gus1}yqjT#A@7n@RKk3Od#w&G2s+1Z<|(QjwK&fg(6Cp)I%Mf5&uZ+V}M(ulfWt4wixy$RJP zkE^I+{4|P-=Z+V(B7YW6J1b(2#+Hwpt0jx)vi<9rdPmpbe7V=RM~+VjNqrc{O?qVb zr{BnD9n+cI_h;o~B0fbpE`L>(TXSjBchw+U_w;l>;IqwI4mY_@%bVHlx-R_0@rFvO z5x%HkZ5tfy>lIUSlKBT~Ft-s><7?r&vkXl$GLl(5j*$*sI>czjszCCpu53lTJdmp# zc;N|M5TC_+pK&n^UkMdTTA10Y+CLZPmg{)bVnC-f`a7Lh;d$BiB!#_D>h(btd$gze z`-VYcM>aw8>k-VVx4a_45cW1i|Dm2TzpIay=sD$hl}ZDj82ANsB>Y+~cW$XZ_v2;{ zgN>P{Y1wj%m63Ewx=njI@;00r{o>u+3D`Q}n5qVq?;u{k@oJ7C_>=K(a?LuidMR{o z$lbGICT&Zr36U_6hJD){1rlK|8 z{;ebCs<4&2%ZYu>lf5c$Vbq#qlb^mE-?8xy zSr97?It4zCV`X{L-vKjasAwMMy(U{47BHT?+04*#R+ddUiOkgUwoJ`hFN_&ztG;S5gDe6wY#q9-trZ0(y_&95tLfO9c!={26ZXq zw|uE5FsB}!6!{J_Ti_8Gd}4fiy11uQDVylBv+lt2yssd%QuE9P>6PrQGAsbX=8&KM4svo{7q;gnsz z0;|OlO6O_pr@{v~S9oy(N*yH~AnD`7^M)tQf1oPO1Iw@9v*f}KG0uXbkIH^DISyoE z+G~i}_vG!K#2Jif_UQ^H2kh7_#3CLZwr1oZ{5rd(w>Ar@qvfr-%TQZ%QPGB0=>Jkx)Cfa+Q6Z(M*h| z-Y)xu@4n)=;J_|%t}Z8T*0OooTE!2p8nq_ACikulL+6u}CZfJ{?EdKg-qi35vP*1k5%%391MrZ3&oioy#;wl|xt^kh_I}`?}q?6CuN9S~yu}4>_4iOTu%^ zElYW>HCaCzqptMk3X(>kkg9sDHY2$HcZ)!e(|-UBySNCv-rYgY%A-U!b0K?OA$#k1 zhIw-UXrR@#)zD|vG=96Np{a9LT}KP8idNS_qp!8h>i;Vc9OC8g6aD`Ke1!xWCjeNP L*_oCbyT|(wMu^n0Eu`2 zkTU?lQ2+qQSYea@PSs&u_^+PsDym}1tvO8vjo96EmWqu3)lIHU=5iR~GlWFCJlD#v|+{_!*P1D^QHj7?M*9|yYXv>3H zCLXDJVKsDG#5--eagbV3Uz}51HYg~1U`|3@psl$YthwG@h+n}Y%&v*zPACR3ryDdK zF3xwqm3{1;SGFBjo=_yZ5KDTsbUplk5VEWqNxQr6&MWMViL=C*ZTh)S!Z+p5Oi#%{ zrKP9fV)2~w)9)oOY@>WhBt>Gz1Pr@c4q|P`;_ZF_jyXrVo)eVX_>C&~{2<%~H0W*c zXKL>!xQVvL`j(HtzVqbGk}SeGGGfWN#NH_P{$t?0?}8er|F8S)qQQI-2dh3LAIJ4& z8Nl$Hb{W;=n9#w2_4+^OiUg6^9XK_vMF$OXz@aDF>)MqX_-na{c6gg!HGny1HVX;~ zp3-M@Y%HJXRKs5qOyuH1DOuTCsMYuO2I9Uxe)>7{=SC>u#Mw`g%5xExge_U zRcLhE3b?95H1k2x$K*p5YyIQ!HzOI|Fj3RFIVN?uR4Hy+cEY$Zb}_P((PQ3i7slw2 zS*_2tr0K20vhmzab)-zT^7mvRJUzOq@e`)bW;FF5%AfK3bSkHRT722Rj^KIqQkN0p ztuboA_U2i~Ce2+|28&{T{O(-urJeEGV|3O~XDwviFH7{Dmpa-THzL;v@PUzmkvt-N z*zz9JQ^p-Lijq(fi{WK7sAebcQ67s7`mGiDO^1ecT+qIP5-PesGrm6e!Y?yA)<2&>axGs4H3zOyr9biO{;AJY?dZ*S81#SbZoK8Zeq>jf8yR>#>6 zRNU{uG&@aS4`I$hw)zHh>9a%jk;KTO0=Qn0UeWz5#0BJqDBn!EL@uc)O`|_@ORDi! zSbUqcO@ve=$?ccSbPt8}p0S7hE>8JB2=3$*bf|#rf4%hWm#QGXqWq zK*v``moakZ$jRU}SOMj_Wb#Wi)nto&lXMIx?jA-on<@7k)F?dSNEonHS6-P+UicKx zb~c-O|A$*_a_4wWRU^Z%A++HZpu|l^Ke|quL&lJleJ(Vn_0 z17BRdlkeZ_aO7Gyy@}W+uP?O7n?Z>)3rngbfvNE=g%*ol$Y-NBo~OjEKEAEp+WbB! zG_5OkNxJhvSY<@4AWzYJHG@_7j%bgGHRO9S1cwD!&Qww9e#8Ab(&gf(F?W~x%u$iY zG{DK=CV*wf2&Nbee>v>_HbRbrzAhX(QT7qlDt^dxF>>hAcO?`A zN*yPBKofH<-kT+W_GYy=PB@mv*N}wJwIl?^ir<54=vy_Y`@Yts9@ds*Y#5N_fFIPH z9;)E7gT7b30MO7DwV&Lq@euRZ%{IstkrQX~*h5US`>nqgyxPz9gn8TP2`>9{A8!6H z;!=XrW_`$H%Grr|Y)+Z^4=Qj`8xN=K3l3-Ls-E;O2_CeB17Qh~juG*ZDgXq$wVf5- z#)@E1C2V)Jv3A^nx5QgJ;_>W`x6c1#h+!T$^skivZ_p?S;i?RPmxr%=6`67JZ$6Uk AHUIzs literal 0 HcmV?d00001 diff --git a/res/img/flags/IO.png b/res/img/flags/IO.png new file mode 100644 index 0000000000000000000000000000000000000000..1675d8e7dbe93d314073ed5a52598454712b2c39 GIT binary patch literal 8096 zcmZ{pRZyHkx3%8^GPpYg4+NLsK3EbQf+o1T1a}4}K!5}YZo%E%Awh$?ThL(`+~v>r z)qitN)mc@$pWVG{U3Ope`l6=t4jY340{{SQ`S-FP{!!pRg$Mq(uFN)O{R4`Xl(G~6 z)Wl&vn7sJ6r!{;3K^Xvim;eA83IKQij-dMh;LZ&IhsFRPk^%sv&Ka%hV*dtUQ^j|( z|M*Y0GHrqXfbRVMqw7B!|F=%;q{sg?sBZGga;TdxUXt=MQ)>Dn0DwA9URFxeYYD#O zsYbN8baRUM6OS*2_lhNzSSh7DCdw3N-&7i3=XZv|bXwgp>u!dtN--3~ofAp_5gp?_ z9{Tq_ER(VO0e?i>wP#1!{d&b6adv4**73pl%)z-^c7Vz(q{HX(aJEdR%J6?Th%Uvm zaW0$xO8TKmR1+atSNk7*f3NxUh^n04f-|Bhbvb!+RD*zY%`-pdn$dQ%dAO|M>Avwv z8kuE{q#>DcC}*XkKNlJc|d zAxlnD*El*2i@wATUHUAk&MpHeH`KLy^rC%}Xhe}n)OU(A@4mJR zWq&K8B0>pPLU7jk;!<5VtvKG@a#0xFuEUEZamBB&0#gdnL6hTYMHgT;vvUWZ0b^My z8jW|D+}=*jKcy}MBZ;L^Y#>}2HFxLEKL62O_Wk;+BNNSg;m6h7h=@Q$H(Sob;~Yt# zxbtX>#8857d_Zt8;z&fnuRy;&Y$7BnNRcPWuT zHELq3op3R%w12&6=2(oqPi`R>4a<=<5BR2v4lQ%UNYP+Q~t>|@Dg z?OTng#ZjO5-D%KrVDkQl<tjPBcO= z5A|r_wjSp{!_;gNTU&BC*xysixOOIRBQb*9!|)cLKbt(fPI1$E-QFW_ZMIq4-+^Um znTj%aEtSj@_~5aHXI*gQ7*NXS^}GC7QWdqmxz27*XW@3g9L{D}?N&=>zVN~}2G-9^ z8uSPEm4zBdiMYBaV9#LBm39tUvcnWFW<7VSf_n@P|~+{RO=RG6Cd0{?(=%|^k~9d;~LXqtx-qAQ~%6YAca4gk(JKR>uX+MZGc_++uc7s=VA zL=oLMFpUbMx4plYuLEO8B9yXmNxbWTk;D6jF<>csW;J)<8y%+JI?~1)#%B|ZN2|%x zxA>0f=C5UEHqg%h@<_`vhL0<*aLQUA_E}7(hj~qL_Hth4;#oM1tZD9Gs!K4_ftSOKogDb@Q>YL=z9+`u~|iW*0)xdzeFTgt?CON{fa1)P+1KgsARlB!w?NWP@;goYB_uF z(U<2&IjOjvyZjbK4}!{}8AQNZ0$Q{vDKn>!uky=}2|9}zK03^Vn1@&{3DbJB@g%&0 z7<{_T8J5gB{#>E6N*`ZP%$`(zkglN#7{)^cUqPM+<-5 zO5L1^)v>nB@7WY~>4}=HCrJ@Z-HGd84sso>v>ZFaYE$`Y*qDclmF=}L7K!FuQp~aP zDx!YDGno=6k*lx1q*}l(4v|{iHaWw-Zi4Wl994Ro|>ht45}48!JOehnhSBG z+CZI>p`8l?G|%e;=kEW#NfZqfbyD8Cm0Xg@{My8?qY|X1kQR^#_`69bkma!>*C8#~ z)hP53VbH6hTt}uzT0E_8F|}nB1&zUUGzuA$!2rUD)9jutqUFvw(ilO_J#UaO5-?=u1ud)>`>uA?hdCYoT)DNThSQkD^7epy@8=KxkEtM9^l$pcB8mNpdMs8NHAkr=;zV1vzEccNZ!>jDVo?ZikP5qjr!5kEzhZ|`jF)B;%c=QS zw`#%F)KV+vq%V<*v7GV?MDY%@bRuT_Kp(y3T)baf3sncT^qb>ZPQ5Cjd%wg&JWNo` z*DpPXx{^o3q>~vse^^ChVT+_Gpe2ONEQ)ScJ%MPRKEuy=s=qxrA#-+^$Zad2OMEEb zzn(=^>1^qu^P)zfjt(HbqBv_UAr1G4I2&_WKl@~zlJ{BONu2p=cC{=3Q*Lxvl~@p! z&0re)t6)#>a>rNFYZTm%WxuoRHd+prLyV4lnU)zcv&w@ZdureOaC0C{`XDty$So11 zBPr^&ZigGI{U?;3{s^;e<zfH7oDY6+c2kihEA?HOpPEkc4#bB)63Kc&ze8F8q~g>nhJgDo@QqgS(Z2MEGb)kL#W6Fw zY@6XFx)`&g(&h-l#hi~_E5$UZ(vFC9S8G~VuS@5D$^JB@S4SYRFW!}0ivc-Qx5G|o zYjJN7#^U6!XiC2i!mQwVPKG`BagH~X1MQkWuDT47R390TrxJQj(wty;-?%13=-Y#A6>4k@$gzCyZ2C7+S4B9;wZo4DZ zG;8=-n?;h=c22TN)1hUu$s&}+xAht2c%-eo<_k!a{pb?(Kz0_G8I2V9bwXSIV1jjW z%IMM8!hb$DgrpulL~g`#++7eUZj8z^l?voV{#*-6s}2#%4f?3p!5ndsGV6;!)nutu~zRK7~s=EX*_l-T@t8+Zat?%s(k_Q~ez% zs9;&a+CJK&G)M*XBqf30z*(uK2q8>W z&M{3`EBTeSMW+S~Rpmz>U))6qwPb_Av?l4x5&Kw*aH-3QG;MdV^YPj$PYp(K<;cS) zT@>XQJr4n2l%#Xk*DTml1O*;K9H90_BiNFKnDrPzT7T9?V@vL1R0Ezvskp@>fwOg` zA-^%@uOn>9tUziP@PYMXF3587_}-x)XOSPa5V?p~`#jbcdWu&oX{`OA;au$MXn#qz z)a7zy+WO+c)xD0-j?QE?;@TVMME7(-@Dw{AKiFy5li;d-Tb;5BqV`sz>+vU#xh$5d z!5Yw&4sCTj$NwSVz`mW&H_qv*YIlhW&{T)Jlzn4b@Rh z0}nE4H*-Fq5~{r5T_0_2)wK-pE#fO?O`MnMInoDHM%bLGj& z3$M*vQ%0h_m1q8D!oSPQb0YSkq}f;li(L`*X4&CHN+@4{W57!Fa$eHTEaJMCg<=vy z-)gF3>|7;fMHzBm?x(;qccGVOWb>r6CoWU7GCfY+r!IkVq=C#GlXeC)dO}8Cb=S-4 zv`@xN%a99moO!9Gk3ajoi}y7cZ5x9up@+OSEDPAxe|UwEDslYvm#sq%{Jtsz--G9O zs^+`rM+(O)B)Y}rE`D>piS$%{nVf)Bx~GMzXw+SvV8$upgfvZ*m+h`C-RWy$SitZ; zTS2vk80)W(Vtx3Nu$sDP!rk9v=)~`F&w;iecSB1UrhI%?o=&>sH*T9q*fM@2Eexr( zQ>`{-wuA_OYc zyxT7PpT+}8s2+TKYco1kN;4RKg(@!lp!#Cuy8MjZrnwH~9z=-QDLT=$Bma17sDXy> zkh#F{jwOJ(#`AFhK~CCDM1XO(SBOrts1Doj{i-Sr<@c@ymxzpN>CX zH?ZhnHla`M!Um@!@};3>OT#F1Se_n6jqqH&PKUX}HF;us;r)aoyLB2PtA~=rDsRp} zvrYRZGwY`Vvf|ZbL#=p>sSHaRtRF#BvbT^Jx8 z6#Z&i(PxBik>7t^M{B{#-}ZwpclUhdjwhs}Xi-g^oLO3NZ}=XW=%`8v)mXrY3l)sB zpE@V7iqg)!?wJwF_q-68f%7WDl zIh@emHad{pk0ReiuVN;Y4wvW9QSum0ZA9NZIV zA0LuQLT3x!M65OS98s=-L}H>jl>#Rihr^;!E(kg)v@En~W>QFA}Ev zy~4g4{CSQwZRygI!0Rt%U3EBh%VOmhN-yo-qjUmwLHOA!LTEoMG`Z* zvX74TEY3XpPi4*8&Je_hW0(;0xZ-gV42hP2424$SmLWet|p5IuPsf*yk!_ zUvrzyr%c4o=7?ztR#vjC2tWRz-xe_UYS+8A7D|j=-Eo`3k8vrzB3TFH;&vIp^*8(P z8O2S{H_Zyh5W8KypkDnI@VS=&z!Pji|3j6)cwqT7po9WVcl#nCryDDj(=J0rAoHe!Es@gVYw+K- zygU9l;PUlO0C9GXiok`-@*?eY^E#U?&5UmGa6JyxVWnc>F9T4TWvRaYmJOYirtpS* z?Bi{AoSpwl4pdi)@YCAO4Xj#+zxJ#on5ZI4W!~SfB);3oBK_}G))mrOz?_< zkzkT%u=ckrurkUYW~$Y?ZFjP%S}WK4c$#(RWfE%1Gkx@kHT|rUU6NuqO>*{C6vw&D z{^bCuaKG7V#t$SpDPiP$$Xi*H(Y?zY?rGntT7ns|Vd?Ll&>^DBp-<%1^CiZ+X>!hi z4{X!z?#2OsCiGw|F*wIv)jLWlb!P3~qJgiIwsNd0fvZ)udc;O$@49u09%{!$yArCY zmo%sxv%-|}1jn+eL43Leom3FnEgZF}b_L3AzveY3?pnn_#E++mCf7Yld+D6iaQT8t zke_w@WO+4)_U&;xz8J0o7J*NIBewC$&mLwdhR$yvAS}QEi%h$|#byoM&-t>tVn@?? zalWv_8;6ggqE5ArVFhu1zbkd5oe+q1(+j?o$>hTxky!7?=-q#m0T5g!n^DgfYhRpL%wvZ;C5R# z_nV$@>52B<5Rt_>+iuf_aG5OnCA#tco5k!6DX{}7-#1rIN6q_dqkn}4(kM6*myi|(c z3rD>AGhF&^D0g)OCgiO)ug-nY8sVy^TB5Rx+ZP5bVy|%6PLB-@q#E#=iT5>lP_Iy zA0w2=;+Ob)nTRFee|We)henSaJH-$>!=Ex8YE}UkryoQ>@woOQHsrFLod7~@nD-*b zUEYB@zaY#%b@4$I{r*i}{)e46ZWz|v)}0qsG>aeV&dj1XoNsotk_Poon9m9Z2CU*& zSrF=rG{)q{0#XRJqy1;t_kfm@gp!?4A+G=Ko2ALr)QY9^Pxz>w`t3;}rv#rUrNUa0 zs>TD-aTI5)07#}ilr37 z&G?y4!^e38^ZGpfA?Ezg=FJjiq0{4ryOv*%6%BKy{*_7qaZEVHjZIUCQIvRLlPk0` z;gj~htiKi2mFmEi{p=rc&&x znyimRsn1U7OT5x3Z4X!0&izfN+7$2_U$J*+$s0AWSWeQdy*|u2BTmAt{-Jkf>&uUi z0guzT^CsIPIwh#t5!Kot{8J~8ZD!In=vCJ?x|&tl5$4^Q_V(!OzQivKarMd(oo#Ke zmWZIj%3wZw6q~1yebK8XpW!s9A;BA~F$1K8;vhbH&0{1@-x)Y~!n*Pk8eHJ2-LebM z&j(A#MwBRHTTg-~A$W}>Q~#0~O&`DUGLQU^>e?ZmGx$VN@a_%`VperX4S08@sRK-( zTlr7w;PDG{2|cbJl3z&NYnSHtUDK4O=AuwplZs$nm-g zmB=#=>bnpI#E+fAUGAM$D+Vjk{e+#F4}rvy0@saPoIq`a_VJfsqlhD)2TklPNAVO= zBb1ycNCQ!hW#B3@a9L8y)_w5PE@$;!3K6WP5l-j4Hes8eD!8vF;5I7;MlX_-7zqUI z_^!J!4zN9yJhEsu?pHliM(#Sm+|K=j(ePRm(>#+>6_A>Z0kKvdZcx~Gx}O(ja`H+# zsVMoz$i`GUfL+G7iySTz!50hM{zgw)1!*dnOK?wn497SYb#t^&3)zwTEj`~2r2 zwkl_?M!?VpO-j5^OpL7^U5oQBfay-F!rllEIDIs~2j?hz(LpdDsR|*3Dso)tstCD0199 zXKA6W6c%jn6@6<0wWASAUy52PNW_l@;%sM9ud7^wLsQ7=>2G#%=#-YO?XMy_@HV{6 zzvkg76Z>O%IFfETMob*$Z_y02iM-jj?xmpf`K>%G)*yqH*)XOda7~Q#5<@!zW3tF+ zc$b$%+WdC+Flp)8J%j%G!**$&w0*5)#?y=j+Q6^es%wVOQtxyd7$tgc&OdriT#)wxREw5+wv1y&iRDL72J|aBOOyS`a z*1i_lC#b6Xzk}fa9}V9>4?F{6vIWXqQN2q4(rQLGIbAn%6E_PHGZ%}00N!x(2y$@q zbG#AKe8Vfk&m+Re&Bo0m!p-f~yCeQT3=U4_HkRK1w*fudAn2a~ke5@Dt&}zn{(n$C Bq{{#R literal 0 HcmV?d00001 diff --git a/res/img/flags/IQ.png b/res/img/flags/IQ.png new file mode 100644 index 0000000000000000000000000000000000000000..f2c21f7260a8c9b4b132981371f647e949bf9a1f GIT binary patch literal 2119 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 Zdbx-H{|4$phZwQ}(9<&3tWn3r{ukaKYK{N^ literal 0 HcmV?d00001 diff --git a/res/img/flags/IS.png b/res/img/flags/IS.png new file mode 100644 index 0000000000000000000000000000000000000000..5ee3e63c5c2b060713eab402c4f7204d1932c6e1 GIT binary patch literal 1483 zcmZ{kcUaSB5XXOvK#3v{R3IcmC#X z0KldJfP_zGy@fWnA>eYsNS{mYaZtf#4(vCV^Ix zwu)Hh4y`xQ*R=}%v^a9ptSX?lY9?sW=T-#+KJJ=x9+E<9-Q3k z*+ZpD>JNk4htwT967o4={U3!D>#rluJ4kmDGf5?_-J;VwMW@q6r{IGTtn354VqNvp z{Fv_eX2@R9$nNX$EnM01*85%DI8VY8rN2!Lp<158QlbVn~@sf(jZ_YvK;Jdam3!1nHxCWyTaV!>q^0j7C&C> zyg0FaZ7!<=k=93T96?GwKSuclS0|&1h-7W(gNOXv@)Y`X3vIpCvtW1fG41T)vaT*n z1*K)I+~p3q!^O(!6Q+S`N{RRl@{MP2p!Z5L2TvYtzyFy}{O3%f zU_mOiY}GNT!3ge^tSOUIQ^4X4wcHKl7hKv>1v>rds(8h)m8}_`*HfFE-pRRx#@TKQ z+I;>&YVOSf6|ynSoFNv2bL|wQ#yL{3T_ zc~r$O-3(;fYDO0tTJ;ls`2psFFh`khZg-y9U0SB?ZFsbk4yEqv#FOEm9A0KK%vxu^DY`4gR z!O|XCs5#K(^-TguA59f+qr(yFjgdc67*(*nM6$gK8h`%Op+UIZ#DKeJRW7Sx+Q&%T zzTP^da7_=X8F#9O*%)jV*@AVVE6Iv)>uri9H9e9JC^Nqz6Uq2GsEi5o-G@08OX znf_GXxvxUvj*8IX_XOy?O527U%9o()Hp#ZoS|7Xnrhs`Welw-UPLtq62_uCaD>p43 zc;2KL)G>)7`i$#Uz4JIhKBQl>fA&BgrBx2ay2#Dx8TC|R-Zd!7v4EGfU~*;*E+}Vd zz=q|&VOMyrVl6K7bhkgB!+seb(;%)EoLBzHOVmyh#$o56YG3zf3}}LJCWn;^&BgZ? zOw0lvjzQ-~TzzH@ZN2&v-W4gdh4w~iEKtlmGa$*<8gbS<3yZIY%UWjp6n7L}L_@6! zV&$d_kju0Sm9|+t1pArel5P#u`Lo`b#;>zp7fOlz-s?@zI(3e&-~*e38q>`gD4haN z_zA`(<+M-m$bFp~MESus5B<-Di7`sO9@WD F{Q>ydrD*^F literal 0 HcmV?d00001 diff --git a/res/img/flags/IT.png b/res/img/flags/IT.png new file mode 100644 index 0000000000000000000000000000000000000000..53b967be99fa1f77a52054fd8a297ab86c5b0f06 GIT binary patch literal 572 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/JO.png b/res/img/flags/JO.png new file mode 100644 index 0000000000000000000000000000000000000000..8934db7ecafe170f9a832b2b291c3542eb66d666 GIT binary patch literal 2572 zcmZ{mc{J1u8^?cUF=!0gw~$@7VQkkr7=t@;Z57frcCLL=ZrK?ONCa6C3_!e%ER6u5?!mbeS16+wcQ?1S1c19T01!h2fFs5zh6(_;kO1%<4*)tj0Kgxd z_r^w#v0!$?nPC`Yh;Gsv%>Zk#x#LX+@&Ao2KVu4`fQ4FEn!*;KBK#;hVf)BU0AM+` zz!=&8J-MD6X>ac-)ET{*FDT$4V6Ezd^0ZYSy#LvnM}utdaZ1Hi4VC2U4FaS(kewc+#F^!lLOC;W70%J_+cf{`;BV#-Xh6W<(uo?WpFBQZ z{h*IJh}^srwcED2J1uA}$HSIjT>LM5tRu~*?)(x#UiT=Gr@Vh5SX%@U(*1?iwK7+7 zWxp2pTU8H@tr-Gs5@`(F^DfJpL?rGKvqDYC5ua8s$M}Tj>l94Y-IDOFwv;*R($k}< zI)s??WNg&co}8PS9(*qz@`9dLdmnGV%d60JC~c|;Z1YCufF=nUhx#Le?4uUoTy6OW zyzAJJCGVAr?}sYSPiTcUvxivu1I@5+1kc2*@ZWXBXq7m+TVeq2AnCbC!`BnE!G{5!Q@oipgXg@^!$b+<$jGgwSXuws<(a1rJ! z3FqKq#S|CEHaSTpE6(e}+pMF@6+iPc(R=1&*D{r^O|>Vky}5pu*ot4nZ|2xRu$N-j zlj*QIR^|_2Sx7EAeBBIkmtr!HrS-(BKA_xTtB{7E@TL&R@6ucS#Kx6q=`H9_=SjUk z-3-$`oZNC*v<15H=<^t zJt9fqd_XQ3E3NB^@UPw$4Rl~`InbbJf8ziB;E?cC6oij3gRTB#>Uf-OKpR3;X@F2( zoj45*^dH%~Qr2W#6*G;7=l6M;d~wlcUN=-P0EJw>pMIrD{dHhRFRuYO@8$cF4fQSG zW|cyF;G-k=oTx7Q(%_`-qRogx+G*>V5S~Aoph$AId+RI7Y0U8kj1>pBXrs1h2~TRd znd}F7cX&B(HWugdF2Qy->)}0@*RR*HE-7GB+RjyYpR*EYQy6c;Rro!%sWL?yh8j)STd~B6s7gP2rHci*R`T>D~j<0`SJ(w z-B^bWv8x>}T6^xD${FThf4Hmoe2He!VYkFn|9XmPPERU-k7Bjs6rwL^CUZuJIDC1a z^+=GUpVQ)DbzX%3Ltci7wO!8RW}Wk|oee1NXt6rSHm0#{(S!yb)j&8LUrWUqj=+U{ zLCijLK32$8jM!QR>%ELjK@j_>7UgK-+}zm<{JZgC&i#|amXa`&p-K)N?+!#$fC)F( zF|gLaHO%^2u2i5Fm9lW*!s*STIJQepR*k53WLAMQLW=a0q=L@AQ?tuw?D19mkN1Nk zznzUg?b9-%4Z#TB`Y@T{0{({xMa?FGexp6^!jyw3kBHwcEdN|OiaSXAf z3o-3^J$hfZtAgi7Pw<2jce8Q>6JfLU2l~)eZif4yeIEP;KPY;4gqi32)LU2 z2r=OK*ASN^O%O>+6tW$6ta5}OSy8=u8J6K6gz*FrN0|Us9SP;kDkL8TUsPLL%6#>L zYYI1VHX;DHN(y4~b#cnfbq^!xq5`{^`W)ac>IM}O@z*h{;nGe;M;E(@1^~-WAevfN^Q8Ha)T3!Yu(-upA>QlP>js()qujSl}5f_$0Zt!KA zgU7d;?I0JlgN*EYAt!MsEo+6>3{$<%yv>DOcdm`4v+&eqknt)3RvKk-+bVVT_hOVd z`U5y31qq+HgBp5`zm;lV^HGeUzDIKIZ$JqbNtR24VOd2#%I??JUUrEKja9|M-6eSZ z*PlDO5ZeO4t%>F2A9)4x#U?Q#mKmVM@B~R$zV1owv%uG9~i5-%#bcDcZuZ<0)J~vcVRGKP_J>5M3 z6%QLm^Zw7T5wgAI^6J^z(3`yEc*bWW9ctfsvdspC%YWB^b@s%j}AHI&q}?bT2^ t8mc<#NCl*-4ifoy_p<)K3;{tNzFv3!zk#*zMl8bsSeRO2YK-x5{{ec*i(vo& literal 0 HcmV?d00001 diff --git a/res/img/flags/JP.png b/res/img/flags/JP.png new file mode 100644 index 0000000000000000000000000000000000000000..6f92d5236561007f7d1049be4c1e45b1dceab05c GIT binary patch literal 2402 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/KG.png b/res/img/flags/KG.png new file mode 100644 index 0000000000000000000000000000000000000000..56b433c7566a47bd1b7bd635525bf8ba04808896 GIT binary patch literal 3258 zcmZ{mc{J4D|Ht3Vj4_5GWeG8skaes{)Qrd$*~-|5ks)H3ktNFv^+EU`ls;Le4P}>g z28~bI3CYff$`%TfL6-b{e&>Au`2O*Ip7Xkod++N$&$;)U`^PiM#@dvRM~nvm06udw zW4j~j{#ycEN8{9RUH%ck1dJ610IJg9`<{@aH4<-TX9WO}@&G`&3jn)ETa+aL2t@(F zG7bRra{xeum`k@cIBIZtS(+Lj@kqZeF=CGZBbqspj)?pJTK6~VKbkX$*I1lGjm+d=a=;B(@+Ur? z;z7F?l=rV)OHE(iR}opStTk(Px432e)OQS`jkPhpg60OlseGT417u$DS#XNkPU}MZ z-|6@3KfwPnw8-w4BYZIU*|U~8qd7C9g?lp|p!=lH=RYvH%YA6${;$+-yb$-^>(JEt zSN8^DcJ6izRm_Z4Wd!D{mNx#{*|>Q4t9{Ml-$SEg)M@XU!^6`uYBfK246uM+1_ga9 zqV5`_nR$SB`T zH(?fy*e-wyOHDw7CcN2Dbc8`|f`)L-D1(<*j;hbpPzHlH10QeZ@SL1W|K-2FU8Hu8^~x^N~*# zp;aT%1uBqvEQ|AN8tvijCsJ5gcTw4hI0JnqxqvXwNpMRV5u;)MJYkP6-(F0XLk<-b z2Y`Qu>D-%;MDbs5nG*v>7XE@waHUs>;@@ivyr~(f7U|SnvDA8Q%}mY1QCrEP<-!Y%Iw5zpz- zw_KLs6z8dOhaj$wrOAhTA(&g)bn_tSF3X-|a30yPL4I=wHd{pXwmE!$>0S$$D~T(N zbpf`J)pPpK3p91L4{75Z-VFuSWLko&u}01lB`(HD{FG3yP(9GqJ*nzXNVf*`WKKG1 zmwG-uw%~KZk!oo-Z%W(OW?%ZMLF8T07&*LSQ(qTUwgz6@#8lkz0R2%?(CIYWytA9< z2f^*C1%$an7B?6ZXPfyx42AXGbVkUF+|S&@>J zQDxbCsifJ%qXKU&zyvbC9D2D!LXB=h@iK}*MNvVYD0KQk(B{qcmM#DBm}Bn`mwy#F z^m7QdfgfV*+v&&8e8X9l96I+vC1iv+x}oN^?ZSy=;jF!hdgga=L)J}~^)k0n9TVzK zj)|ojKk%|4I*`bz=n=)RTLC?z56hACI%h_Bhi_AJD(1U+(`PtKD#KjEzHe142*aMHs0*_a!b|H=Mypk{5JFiFP@ z1vxEUge*+YG_6bk#Z8IFKRGhAx$Ih3W6yM*LwK30XA$S^s! zUassR95?nQ(#jq5QpWRDqZlW@q?DAFP|b(t{GVY7=wQssT`Wreq3fnM^}%pEo(%o| zNS3FZ4WhxI*q<%Y1Hs^wAPX^rW+d^&tg8{oSDiiaWsT>uwUhtoW#YkNx@nUiGiKC& z#2Gmm%7{7Ht{+9Otel*rDf*8*3m zDE#lq`y2<<=lpGjXrjkpX~Q7xN+83yfUml}-u)X`qiV>1xzH$uw3|f#hJ5?8%>E)y_J0CP1L^mSw32rQz*&p%vQ!wS~=%K1gHH20ru{%G~OKmNaT@V6ef9I8_kc z`Bt=4!%_EUCK|!#kkrV`VLE7>EY51<<#Od+RC?-FE!JqAJe8&BcbVg}=d%EyvA5b7 zf<50nJsgZXwHav3)7smRwQSQmOz8a4zQ=4lu)aEUlKb~(^xBTvY%hK9NqaNR@Y5SS zsaPgsoP|&WIw~UDb@)MAjNZ??FtDkVsF(-T`bR@i7koJ<1y6k`(6FA7zs`$ld+Roi zxZXN!5h_o-$IA(*4*%wMJdi#2H<(h2Ph3J=8GfkA>FsiU*YCRd}#UYrY+fZshJqvGs246YXZu^r){H0j)zc+5h)!D`Q2alNUkkD zv~J7VG&V8WBi%6*>JxG8u`;NXPJiRfle6Og!OsN~$o`FWgKs*@tu)%sr&V?at*ACB zQo2lXk^R_;s})FDB{`KF;(871-#0^unko7NYCeXuv4S;m zfeD;N%-+U<{s^(nuL@rHWM)+LF5J{(;7*L&oG@iT0wy}MPVEOP8I7x{R>`Z3h##m*UCR#l2^9+^d(x-{X8cA_9Q(~Of8M25dTmP)9kH2aF%kZ; z)xbrk^D!Um^gDsmXb-kr5J&B1p#st@V0`rVq)6ngil0sUm%c!Zb7x~x3(mu(%Bh#lBJrx=mMw-AA2 z_}7wwSs$)+Aw8vh4*$fkDt$q3#%}Ghb^6N@7cXt1^My9BfULxGZ~4xU5;IQuW?CtRH+>a_b zR~0yX71~J>;ppgG7)JFg^?)?T zwlIEoxZ!BB(eP{0iZM+Mz9Q&_qe3X>M*Wc>W3Wrmw_LxUG{xsPH zOZN68-_Xa0+&BWDiPAW$iqcWl)N|0(($~?@*G4I$H1tuZ@W1B`|I2VI$lK2+;(r@p S1#Z+M17L1qZCq}Ii~B!iKkrBY literal 0 HcmV?d00001 diff --git a/res/img/flags/KH.png b/res/img/flags/KH.png new file mode 100644 index 0000000000000000000000000000000000000000..e1ddd5f84c1fc14c1be1b3f012bedb3b4e861c82 GIT binary patch literal 2888 zcmZ{mc{tQ-AI5)XnvrG39Ae6Hj5wNXjhzXD$ePAhmeeGr$T4M?m>Fa@WZ#zxEr`kz zgRzt)p~e!jgt3e*N|_9=&L8jfoJq-~@s-ng0 z?ydmzdE|I}?pTFU*V{q?4Ruv z{O0z2p7y*;=;jVHcQbbm5>6*z4)a6*i(~Dt&dtvMmc=5A^y78eZ=r8JI%ex98J)QL z@tAbmaMhY_P|)IH9+u-@|Aj@khkJ`&R=RS?KSP=JQ>tF_}gl=9M=0y9$8roKX@ zbReIBZ0jsP@)fyR6TJ6Uld1yk=t64-^VQUGv5!(RADjA=;W`{++?+H*e(t&xNkQa9 z3aD7ND1ytsp43M&iX{SbnfSW*>P5~oPA}*<%;MCR74`rxZ&Fk{kL!_XHSk1QWH2IH z6eSxT8t+)F*>5vqESMQ=D(-!X{!OGk1XMEW;#8|hexW@Xz^PYc#CI)axNt8>Rqse1 zurkXT2b*WUOZL%chUfA%p1v>0e;bX|f*DD#gJrPn6*1`XusyW@yd{fPh9(K;38Kz8 zK5eI5H@kclI@|PtS|LpI@N{-x&LOaq%hPnp>D|sAYITy_9Q!2IQOWCf#YN9NReiPk zXHuF(O|2DoUtD1&P@L+ultN%0V%(Zf4kk(3}if zjGyU>KKoQ#QA>E|&4N#KRBZFT%7aU>M)>7 zLu*0kML)EJWHwTncO3HilLlzxhaXRTAIK*pB%GOpYApJo{}g7<(MTLYXazmtcq%%F z|B49k=|Z3v#j}qLAeWfm-R3!)wb!4<9gS)mrQ^_3p^;Gg`?tHrk!Np$h($lTO z{$uZu-;Mr6r?@3GD5tK`ye-OkrbhCz2WoW#gEJ~C9bo2WQ{pTZk@4*ZTUso94^C^~ zhc+nUU+8d8Fp8&*;pmfYc|!fL?md?acom3cPyVH`2C>=BU191L@N3LmuO4AFW#%ar zs593iw+n&0dz_x67U_7J1i$Z@!fl7(t)=@Xg}R)S`cGXmlS~}Vvvr7FmbnC?fyEe3 zQ+qGGraCSYzVG#Y^C>l`xUm&FgI|v?1Ye~Bq8M- zpJh+))0Y>CyJM~3NDYGV*ZGb+sOts|^JDG$U&kwbs`E)so{5?`Yp#hDbDRYdWqqkU z=P@>@GVE7WPk?hK1%e}BJx#&i%bG4u!jLCodq<&|m5X*5UC=0Vi(OqR+{!3yql**X!3ntBRL?b=Zt`ei%lzX8k-Dg3@wNzz%v#1R6fsh!Iq``5dagw{mVpX&}e4 zL@;r44ejmJSic<#O>!u+har zNs0%^Wc7|hh+e1u5AdqJeu>CK7*J_zCdDIn7Wqm`5;EaGt=h(<! zKomKu$=3&yJbg{MSIZP_GdKb#aS36MTx~GU%FpSD7bfdh5kSk&Zyqw98q|;(J2K;`sB|Z4k z3)jRjUs^d8`Xd+xlyds#mbHf=cHWR~ky}pM0!36TRcnvu%uLUW9aL2uVld&&vC-zE#=xEbs-`5_l?`+=bbkb zK~WI}om@ph?BLgwao>S+$pUV1_O7V@q`R}^8>Khu7k!eh+L)gRv}jas+->QJcT;Reks6nu$nB^Gh@M3B&P#XQ{U}rb^ z?U_(*A*Mq7rB5dq(a>%KTrK?|Ns6ljh%*NYqn6?NjnUi$sW>ilF@i*F<@ z1JdKt0N>K3drU~I60KPTIDru-ajHGeRy*G0YKb^PDtvODme(YzFWY??P&+0HynPg+ zX&<`F*5gUm#5<&bX_Fi!4wGBu!ll3C61-);*OR%;XkA~@EwTKAoihoO&da~#CGO!m z{#~r literal 0 HcmV?d00001 diff --git a/res/img/flags/KI.png b/res/img/flags/KI.png new file mode 100644 index 0000000000000000000000000000000000000000..8b7c54bc0fd5cb6776c02147df745705114a3a59 GIT binary patch literal 3661 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 F|1T6US`7dI literal 0 HcmV?d00001 diff --git a/res/img/flags/KN.png b/res/img/flags/KN.png new file mode 100644 index 0000000000000000000000000000000000000000..bc6189bed120b39722e2b809bafd3916a6116fb0 GIT binary patch literal 4213 zcmZ{ncTm$ow}yX637tq05D^fhN=G`9P=rVeMS6!IMF^eHV`vIW5d@^8K~bbh4IsTq z6DbO4=p`UcARtKj;`i6RbLYO#oPE#k&Y7LrncbQ51a7FqKzo%I000JP`@u5n`y_Tak%DJRyJ+Tp<32Tt3C;L9sS=|p77-e z-BNpU!+tQG*1rGaQd~<3>VzhT^?4TaEp0j}0VypqZO5ssIUagX(Z0{ZHL^SE`>L}0 zRfpDdXM1+Px~M)_Ry+43vWc1hj|3+~9de=({7?07@W1HJ9J>B1&Bl^D%7f7m|Gik6 zqp+(%kKLmtD?Zuxk_9qRKd4K9+^LKd{X^c*vmOkEjGqijUPsrl;Dy|HVnB25$`&5L zoE~TS3N`9$R9M6F;#Bh-X)_;?21Y7V2g3EPe2pIdgoe)NuP1anV){ab;(LBfGDHzK@ri{b4OPnEUHbJ{u;`+@_+E zEZg;$oAK{G4xfj;Lzu(-hOd-GY zxG*tgDP+y#EQr2r7>kTuvJQtUXB#A@=^b>;fB)vUQvy8pCTvF^f_C%1Z+;R};rlzh zle3}0_ea;&YMoVgCZM#%UvV_{Ry7bPF^0NLzx-*ys~b3+a$$OG_Oh?M(Yx4_*5lk3 zW$g|L0N2wkp(xBgDW^n2>Jj5D(eH+_9&YK%{l!fTy!mW7o+99_m3sbPEQ)`;`$A+> zV%~bi$B06Ww^y0hMl1F)~_v4F;@XU zUdfE_goYRgrasP|^WCkSdWU=tx^bBqrdz%Vn<)XO1Umfkf?X2E(fs1bB=4b<@sW0O z)+VLl*p;FPn0DKHUk+wj0k{4esNmk3%U=vZ;^s-?@@Ni`yNPLNG`c+~eTb4Zf|AB! zl;K6@o{aEagaQ}zqNRc>t;)G~NQtph!{p#i*@$0A!TH&~SamOUZ)2-rUW4cGk=(th z4-90uUaYEJ@hO+dCneUKrwsPyJ;sddiU^vM9V_cx0-@F^y65qI@n%Nx+kr` z>y`m)>Zy%%_fk;xmrtLDJ1DN-x8s8Oz%#>3UpCSgF+6SNp>y*vvKD6l71L3fu(Y7Z z&l~(A+Va5q$ucwyTR0fz;1R??cs>-lz?zNDno!W#^ z9?dWDKC#yiia@C-!Qc9eoVx1yQOaj>)WMi?-bXVw+(mcMsr~eV=w-2+yCJF123WtL zot~V-W)reSOkJ)8cL+FXysIXM_egx}z+njY` zJ?NNanWYK7usWUn!@a7JPbscXH{J>1!ZM6eK`+eDY=}t8n$?jU6)y>Q#LRsIG7$~s zcB;`mKNqQfn#s8L((7j3$(2{HbO`XhYM){lSZvD|Zw0;ekGZs!tO@PF90z|bGAP$& z{q{37bo-N2h?mI+(gj-X4*7A}`gqB|a1wnI{90{LAZ#B{vJhKczBfe zQeBmS2jzo$u;f$a;jYVK=Ty81fUU_wn~pQ@MHb(>Lo9S= zT@KE7@KmL<7%8ES2dBzUAAO^R`c8fsUxd=7?#BY{hVBXUBO`su+jtw0)grQYFJKIx zBZqe4y$_4wp!sM|gVk#Toa@j9wTJ7S)uzuH=dikUSW2Y zF)HVHy#D8UyX}cT{pJON-QALIe@uvtE2kan#3J+XHsH;0Kb5_89K}$@far@%*7xyE3PXDZfiNEWsPp7G+p9Fye%lT!Pi1q>m_FuJ zZf*PgNcX(`ZnfRhV{u+gSB_jnFOZLBxobcV5X5OT*)k5wbg^tUce<{@%Do%NxhCl7 z(JjVwvJ6hE1qW=xxq4hl!_iJ-Ws`y;ailMQ&UMW0=F^}D*(HK(wBoh=Rr8o1xmL)| zj^)1Yq1k!P>Bdq~`pj0M{c{?3**jGpUq^lku7|9=%>R`nDeI zOk;T0c5n#$-snbNUwgoQjFH(v{7{LGX&J_;R{59ZX9-2QzbHK?Szi+li4yW=DA{|e z0p)TQ>a)1>PSc{|;w@?R`9p=#azPwsLd&*0otLYO>0^VMP&w7;Ng7k=>sM+AgGH$? z44$q*X~gT;Rc0%MCd*+V*1>}~Q`)Gv1+}=}(fa3LHnx0ATT02e)|G{GPTPLbxjE@C z5lkG99X$3?`wfDH;Q_{oS0vQhn^4f7hwXmu5Dna(#96HM@kQF4==AZouVYQ$n2s=Hjl&26 zft`z+6}{M%jRX3GM^(tFD+wo+F*>1KHt$yRCV-Jmy7&Hymk^b2n>c<#j$&#mPvoh~ zdPJ^~Z_(7i7&RUQ+;MP8^_D_QT>c0qAs;k z|G6=r1dM_`YZ-f``z0H#F5~pg>u2H+Kc~=8tyL2#jqN zj~8~sY;$_>s}#L5?a{@F9Na#Yb)(==71 zFfMM*i^`bM$LigKJ3LO~!_T^r$Snot;y)Q~Y!%S)GX1aih{2MOTLs_uGQK zhWWgMri^Z9uuzg+Tm>)E_^u4~-IQx*KM8zQ+g(9C6+eJOD2dn5q|qC-)Nlt22aB%u z@BhRu)B7M6@c~q*#q*;t2lG+uSOZVHmvT?l3S2cV^x4rtNbpRexw)xx(f$42QlZ28 zI#6)A!svc2`opmhZ7mUejeB}wulN_``{LC+Ea3(BLxr|bwnhk_dW;KKUwv{)CmS&_ zOq&w_x9KQoNAtY&wCHqgemA?zl(90QxI(jy=Q(YP{X>;Ebz;lrt4ysjWD+QL`tw=N z%qwv}lw3QzJ@_iGHURGAWd_z;QN!4%B3scQunItyoq^^Tq%|kVStuyP@Sk)r{@)qoKCj&CQvL978S~)m=31v2@RhGfeK0 zRTob|0;$HS|1s5ooXh%~=x8*uEw7Sa9HEa3=+X0yeQnc5)})U2p+G`5(2bv;HDUS& z@vSUtn$t}azJ6lMCnHFop*S(9$a|&cUlrcu@6x-j)xan<0AI7xZ5TCXT7dY))x_J< zwrW<^epeEPJ~MVGm%U#YafuTNU3AotZ_9*VB8(Q3YrO1KoM&Bgr{8pDNvlFlykh&B z()G1_DS6r(ateD)i8|_kx^K7wX69fqTC=QymDHWMFfW>CqP=koUPc!y!Nw+Bhr|LU_ zW^1%wt@*k3ZOp2@A+m{*(CL#2ML+K4;If;P$TzvKdt$!nh)BJi-x_YvAGW0!bJr4&V_X3WAJLtKADXBl+vQoX2Z>ll`QMAM{^c`T;RQw3^e0 zy0BASozW=vC~;H0H1O@OSBQm$rL9z5Th36&k4X3+x6M9p2@dX@tVk6N$4@FAIz;yt zH>}p^6oUMGkm{Qpl-JiH=t^!0s}#&w^vC?9GRAn5*@g<#b-spjvg+MRr7bL|pe?7XiFt*@c<0!3)k zu{S*#T+u(sYl#ECY$EgRPC(b=P$4=C*SN)&fw%U2+`tJ*d8P!@k>N*6e1-}`n zZ5in56o^oE@kfvhkdcyB5SO|wE~98BBddH{T3Jp?OiEf=N($AvqV~TEypgURZlV8w U0ZpOZBT@kX(>Bzq&~U{32SV%QEC2ui literal 0 HcmV?d00001 diff --git a/res/img/flags/KP.png b/res/img/flags/KP.png new file mode 100644 index 0000000000000000000000000000000000000000..c92248b9101fa5a4474c6fef5e011bc16652e5bf GIT binary patch literal 2293 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/KR.png b/res/img/flags/KR.png new file mode 100644 index 0000000000000000000000000000000000000000..ab1cb94943f8ab9abdf63a26c8b9d96abfeaa545 GIT binary patch literal 4837 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/KZ.png b/res/img/flags/KZ.png new file mode 100644 index 0000000000000000000000000000000000000000..e10a1255a08b1d59c662f3a0f21bfad58f7e0eac GIT binary patch literal 3466 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/LA.png b/res/img/flags/LA.png new file mode 100644 index 0000000000000000000000000000000000000000..6ad67d425584503b532e66ba2cac366a34b38e63 GIT binary patch literal 2119 zcmZ{ldpy&98^?d!vRTd~hmtvSOU9fU)|^7(E@y?tMoz;TGGbe0Qi>w&rWh)EBI{O^ z!yNKR7(%!mQ!DGvIWni*>wccs^Lm~?p6m6xuJ`x4uGi;!egFGpoN#lL*sZ)9000SR zCwq4x&3>jdR9MH~)f5V`>#U8d4FEjN659$A5%vhYle;SbBxwTx?J@vt2uCzN0K_8! z;7=R?pqT)m5PP@oq?K?14R&#~7g8AOcJ)*t;IU4AWFc{X=VGL7ukZnjb9QxrO^fVT zKJMlvNq0*%;8=_y!E}@rmOcrTFvBv`U$puSo&{H zvsYLS$P*OrV81{&J&+oniSi=^k&ok7pX^`sd&d9PD-k;B~hpm>OUEyK7Xr&#eeNmbXGbNd=j%R(UVQ<~Ewbb|^WrEhPT2L;^i!?j8P z%Q3sgaNg(cDPtWS0qq~pLtc*8jYq%o4n-eGe$mo;L$t~POo!$!#XO;LeC~(uqgRi* z5#c6#k~Wm}TSh_}Gy+(vZ*$trL@go*+#=9YT$w)NCX@DTsFm{V z)bJS5H?R=Tc3{94a%#ZlK%-zUE%4wxsC*+}uB;hS_zV63_SpbQv@P;Gjb)!*9T8X; z1S!`gl>sB2E3)q|Ek4VB0<>epVee5rAnEH67U^?>Ni7$dQX}G00v#k>g5pHq+^1P+ zdxuZ3f+!Bb+^^ZUEWFPq}c#Xz6E z6_^^e3u{V<$0y6c>-MLn4TTY6k@2DCrN zF-M&6r1yrQBK)ONd#Z= z7py40h4I=tADCJPZM`97*bUja<)MgCdfDyAmzz<88X>YwrO)*i%?CAd>) zZ;Uo(*AWQuJ1FTKmCD0U=rZ9^cgC<)gEQBxX)r11b(ipOfu;e;@g%SAVGLMfR8V@5 z#$4vBzZP-Yo-9r0q{t+&@gprpEW^y);;f5wnMj*ilE+qp^WarI9EP@3aX~bx*Hysd zq+h7>>j?74URqPazhX=tOLMKOZJ^NHdj!16$Fe=`+91Uvw@Iwq?#TH3k&0YA zN}{~gb#X~D&TjG3&BIHI(38wfNR_ItQ< zgVN8-W=xQ#fcMex?hOo88r!R|v+J8oA;%=3n;`1rP*SW*I|!BRYdXq`<}S84t+ z%-WC4Q&RY}``@1~Ucnjj3&3T694j`P?yra}LsYvY6m8uNRS{&A4{Fn9jItcRi;(lz zF*k9AON>>+{3ab)D?2O3EKJ?Yf2e((Q}l<1r54p-@WzYWl*;`pu5_guJFKGhZ&9m= zXKgX1_TUUPaOO;=A9W%i!K8|FcH-Q)4dHOJt~Kkj|N!6o5?+V$-YnZH?|R}#9t-lv~Un zfa1PBtOr_;rZ+%vnqATW<|7%XOO&EMkWX(qG<*g;(-6OJGCv>vu5rf`o9se`h?qmA-Q3)4_-HKgsyW@S z6@pzelw&>?XkCYQD>g@QQochD)kgc)-)Ymowpo?(f$}(+JTnka`jUAsW{RP8vdHx{ zOy#@|>Xh8}dDVx4s-HH}$#(ncDsSgmrIl2#|1zk*?dqy!{tnQ_%}Vd38y^#zs#ctX zZyX^gE(DD~7a{~;j5IPgK$;pDTX-6y(56Oc6Qn-U2#rK0wtlky9|19j5FSeT{{nbX R09_~moE_ZkpV;Cq{sq~a$M^sM literal 0 HcmV?d00001 diff --git a/res/img/flags/LB.png b/res/img/flags/LB.png new file mode 100644 index 0000000000000000000000000000000000000000..865df57a42f5044f43d3fe10a850666d612f255f GIT binary patch literal 2537 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 UB<_1B3If0xTPK?eE8nF50Ee7!1poj5 literal 0 HcmV?d00001 diff --git a/res/img/flags/LI.png b/res/img/flags/LI.png new file mode 100644 index 0000000000000000000000000000000000000000..57034d367c4b0548a44aa72be81269870b30b53c GIT binary patch literal 1759 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/LR.png b/res/img/flags/LR.png new file mode 100644 index 0000000000000000000000000000000000000000..46c3b84a92509f9adf6d103e7c273e71044280bc GIT binary patch literal 1903 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 Yf1kMjZ{RC&NrnsnV`PDTY3O$QPau|BA^-pY literal 0 HcmV?d00001 diff --git a/res/img/flags/LT.png b/res/img/flags/LT.png new file mode 100644 index 0000000000000000000000000000000000000000..7740cdc0a09abc9a6a36f2bef086a4d1e5e3a376 GIT binary patch literal 640 zcmeAS@N?(olHy`uVBq!ia0vp^W*{uU1|;uX-8K(Mv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffzx4R3F27;f?yX%1z zXMsm#F_2CG;}6+R=Yb6N5>H=O_J^!8;>H@%A+_%r7#Q-#wsLAL+01oqR+@=|m{ypW+li>R z^M$!r&*ZZMCbNP<-=aEcebzOFj4W4Ku$++1Gx( zE41@?Rta16{y$x>H@=^CA~$rg@r_qEzg|4H5XiezYVK;+{f6gTp=n?G&(_w(+TSnf zFEXAHX*?&9@$oc?ea%G=EPW)|g4+&GDLiLTImu;S?RBTTAlt)t4o>r3{>z9Z?k3Rm z=o@nH{hrlqKN3IZpx(Fq_g+ literal 0 HcmV?d00001 diff --git a/res/img/flags/LU.png b/res/img/flags/LU.png new file mode 100644 index 0000000000000000000000000000000000000000..8f383e674e84347f49327ff69841dadc6401d918 GIT binary patch literal 677 zcmeAS@N?(olHy`uVBq!ia0vp^W*{uU1|;uX-8K(Mv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffzx4R3F27;f?yX%1z zXMsm#F_2CG;}6+R=Yb6N5>H=O_J^!8;>H@%A+_%r7#OE`x;TbZ+l~S*j<3|39$fGgkg?Ku@j}h7sp$>}D|_bD zCJtSx<$JD3vvU_!Km9+uh@*vFZqgiWCZL5t5V7zO_u8%3tT=MmovhA(wmBcH_4}`z zUbxP*)7u^^Udg-udTW$TdJg-c_W?7KHO?4{Jd@xm=4rJ&7V-M(mRBp(Z*LT+d?DL= zsOj&!qVE^Vy#5@~(AjJpIrGG~&l-O^m)^U$BJIzEHB~iP)~ZhHFWt&ocXabl{^&EZ zy}7shIy>%vnq6lzOMZX4~M$2p(c_L|#&+Lo-eNs)J|MDV{v=ipa&%DhzWsI*VfHC(}#)5)y* zv#pR1H=O_J^!8;>H@%A+_%r7#IsYT^vIyZoR#w>+PH<(f;vw zpt^>|1+`5DO-D7J0UwWP?je^J zUdv^l=bSw*&QtXHz*q0xkv|W!RwpX~tpfvx>7Mc~fg-MflQQ@ZU2jt0XgV-s<#~UT z*@+Q)+2@^CMdX-dZGAKEf?Ugf#Tn@w&m@~F+Y;shnREKTrd|JXcJeo!h_@dvbAGF{ zU&C{LOZcHGS^K#O#?jp7pD*9iPMqsyQDt?|%lrE8ui9^?df0mT@0$9itjRb2N%%9q zt?7rlste7}`KiwkndG!-)n1`6?=PR$a5L<p=fS?83{1OU^M^G5&x literal 0 HcmV?d00001 diff --git a/res/img/flags/LY.png b/res/img/flags/LY.png new file mode 100644 index 0000000000000000000000000000000000000000..2884c4c0a9cad4e68c4f07e93d5191e1720e8fbf GIT binary patch literal 1273 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/MD.png b/res/img/flags/MD.png new file mode 100644 index 0000000000000000000000000000000000000000..8e54c2b815f714e64a395c206b3e8a814b4107f7 GIT binary patch literal 2238 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 XG5_DdQR+rMG5{BiF5wys@JasxgAPW$ literal 0 HcmV?d00001 diff --git a/res/img/flags/MF.png b/res/img/flags/MF.png new file mode 100644 index 0000000000000000000000000000000000000000..6d50a0f544ad14e2da315e53fdeb187d3c8781c6 GIT binary patch literal 566 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/MK.png b/res/img/flags/MK.png new file mode 100644 index 0000000000000000000000000000000000000000..84e2e65e766ba023f5a48903812a5988dba7ce26 GIT binary patch literal 5066 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 ba`RI%(<*Um;G7@Z2(r@C)z4*}Q$iB}jbq3l literal 0 HcmV?d00001 diff --git a/res/img/flags/MM.png b/res/img/flags/MM.png new file mode 100644 index 0000000000000000000000000000000000000000..70a03c6b14d65efcaf70611ccaa5ec7415cbcfbe GIT binary patch literal 3123 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 W{=a~&*fEAF01S0ab!xN-vHt~gp%(-I literal 0 HcmV?d00001 diff --git a/res/img/flags/MO.png b/res/img/flags/MO.png new file mode 100644 index 0000000000000000000000000000000000000000..3833d683e7cdccf977da589ef5e83ebf1be96f8d GIT binary patch literal 2994 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 V17Y5)um=M`MNw0sQqD5`e*ueB;w%6F literal 0 HcmV?d00001 diff --git a/res/img/flags/MR.png b/res/img/flags/MR.png new file mode 100644 index 0000000000000000000000000000000000000000..c144de17f7b64a8731fa0d8ebe507fb788251047 GIT binary patch literal 2897 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 F{spdsOC$gQ literal 0 HcmV?d00001 diff --git a/res/img/flags/MS.png b/res/img/flags/MS.png new file mode 100644 index 0000000000000000000000000000000000000000..12217070421ffa3e914ce25d1fe09a97428405bc GIT binary patch literal 4967 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/MT.png b/res/img/flags/MT.png new file mode 100644 index 0000000000000000000000000000000000000000..7963aa618a42abdd533d93b310cb167fc18e1360 GIT binary patch literal 1324 zcmeAS@N?(olHy`uVBq!ia0vp^W*{uU1|;uX-8K(Mv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffzx4R3F27;f?yX%1z zXMsm#F_2CG;}6+R=Yb6N5>H=O_J^!8;>H@%A+_&;mP&iNIEGZ*dV4$8XL7jA@sIB- zPkBc>RBm*V)L+|^dBs;oC$Bi4b7p6CpplTTS!!DJH?f_Con5;mPfp=pS0Y(>`kr{1 zVuDzcxO1ww+l@yZXEqurT~I7cn9yVt#+7+qZ^6OT;%+T8qKeECV`Im^ud`{xw@ zn)8HFu|>d%141lvy1T0J_~VZiHc{@syZ_zaaW`-K?X~}=`TOi(-VviW{WPnC058kS zbOwWh$;<|s-}4z~SQ+n?RakiVAJ>D;dvZ#c%<2~MH>B$PN$vP^>D_z&qfTdv`<`Y>E^vPPY~_MiV)&Im8!D%0uxzB1ym&&ll zao^n#v%!WxIRBQ{8uw>*2)*QWQ zx4?O?mmbfYxAO0_nWHCvmCIJt`T1s_KUaCfLN_fpKgVw?e_R(Yan30ZD)v%S`S;4l zcRiCGn;%1bVbI(@kZFGo{M#@^DtE%CM8VZ*>q;0^!k_JZugAD`V`+M{){jeK^1jl| zZ*JTV_kG9me5-oWwQWovuDtOup0BR?)OA6Kse#;EqZ#f$ycf;QvpMkV!In6#U8&DD zRUO}@Unjj{&Vh{&b{j+*|N0tXcf>B+ck|nsuh$hbzdOKv!0@dqU&SOgJ9efYGkQSo znDl(Z(jASD-IiPNW%<4+n$xwHZDziuxs|`eKcm;zTK-PRD8069`T5eYt8TlO%H3EJ z^x?k2Dpu)h8PgBi0E0K}X2e-8hN>MbJkoK=>`Sb=(*Aw5OuKE%VPd@fOKuQvJ*U^5 zX&z}2C(fK~d6rkiz&>4q#q7n}Dt&?F^4C-yn&&A9M*e!Y;Y7N`W_97><-(R0jc#9; zTK&-9oAPqEa$b5{r^ciMK5k6LlALE!R179hB$9Kz_u0zXd-GHfdD3OdAI|@et&d;i znj!@(IaEtrBT7;dOH!?pi&B9UgOP!uxvqh!u8~EEk+GGjp_Pe&wt=CQfkDNgr?w~> ca`RI%(<*Um;G7@Z2-Lvf>FVdQ&MBb@0G+lzivR!s literal 0 HcmV?d00001 diff --git a/res/img/flags/MU.png b/res/img/flags/MU.png new file mode 100644 index 0000000000000000000000000000000000000000..d5d4d4008dfb8b9e00c2bb9021bdaff6969f6888 GIT binary patch literal 723 zcmeAS@N?(olHy`uVBq!ia0vp^W*{uU1|;uX-8K(Mv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffzx4R3F27;f?yX%1z zXMsm#F_2CG;}6+R=Yb6N5>H=O_J^!8;>H@%A+_%r7#I(Ex;TbZ+nD*{fOl}?q|<;KCitN{-kElox|nr-Yh^1!Qg-s&+o=5L0*z=ci2mNpI6R%-f90= z#pl1m%rj5BT;CZ!I{*Fl+qB@h{)O@aiyRZDL6BjbRUO|8Pn#n7>x{F1-Po~VXZ9`` zksZrB_rF`gwOX`kYe|3goFCePu`fSywDJbrkeJf;L~xx;qjsUpr!8x`HM#{xl)p{D3lU83(ETPgVR?*h8{NYEmId4>Lu8~6m@u1tP>Xw{>gM)x1h zQ~P(yXz|%z?%PZAQXjT}yb=7YP3&sr677$#o2q5p_pDmX;q5+S?x9PDa_+Ao=I&2J4XsQJv<(cc3=Ap`J+(#Akei>9nO2Eg1LyqMMo@Hmy85}Sb4q9e0CDmjWB>pF literal 0 HcmV?d00001 diff --git a/res/img/flags/MV.png b/res/img/flags/MV.png new file mode 100644 index 0000000000000000000000000000000000000000..0f2ecb43896a924d5f46e5b972a58bfd29d37005 GIT binary patch literal 2047 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 DckS{l literal 0 HcmV?d00001 diff --git a/res/img/flags/MX.png b/res/img/flags/MX.png new file mode 100644 index 0000000000000000000000000000000000000000..096cb1111fa1b35a18c0e60d286a5c37fb5a3ca3 GIT binary patch literal 2140 zcmZ{lc{JOJ7RP_~os4}KYqhb2A`!%1l&DyWhDuUOEw$E`L4sOlD5p#@RjS%*r!AeT zSW|mx)l#(+OP>ghrDLrGoxHyD-g)njch9}|bC>h|&=m^Kd?!i|a-BAFLtOWqXOaNfAN5oYCxB&%#FIWIT zlmdWERCx>9oW0=1J3H91$+kn=)-*N*q8xo=*~I>cuVFUB?1C@O31!c>#G@#4R$IX{ zWs5y=cCxefOq|)6B}94BFYAsn`!Q1rr`hf#;NwRBE4j~;xX^84tltlj`KOB3O zc%Rej;rY`s&xnuQ1-rCKhB-Fb&UWrNTZc7fASMvy1E-4 zG(}xw9fnm>6NZxJ4;q7q%3@cD543;zFMm(Toe;DCVeW`lRa%X&j`Xj+YME8XVi51g z56zp-?S3EYT_qEbo0&~_&6cKrQ5BNd@9tCmG`i3au&$y$O%Rd3!Q+EKn*r`kfk=qa z2*1m#k`O9MiRt5iTCyN@DYqoMtKl6ceoL6Qdzv_Y;sq{R-8snWaXe!gIvpR7CJ&1_tzvqWZowzTT;@$*y+5qLgKtBbL=$wqPdm@FxALe;c1(NZz^fsf zrEldPeECr)^?A!FDOHJAyj)_Xg#(alN4t!#yXmKyNlMp*LKW)exK_(@KTa1>V3U^F za+#-8!TH-QE0g;->>bD3J~z7=?%X|v%*#5Gx|Wt?CZ<<_IIGX#8o9TBY0H97eg)Py zE!MrDUUJ~)$FCAWsEJ#8N8ae?nlX$x<2K+`iy*u@SV<;bvuu%ts~+?Rf+)Ql_bmJM z*E#a9s2b^N>%_=T;de7o)T-D^bAw9(B;)SOo4BlUB%N6-!W~AgbMEZoc9Eu@GZXxO)uLO7L}U%N}d!TRS2wK6`+JU>$}&U_$8PdHRyt|1CVtwZ@#E)DL1W>Yp>5oci{CEzn{lb|q&EZc))>>dhg$S3XS}>y~+MHh#UySn`YRZ|_d6*vx#EIdEC$ zNP0%|O~N&-9=cY*^etb;vD-hD6)J+$-chq>$dM<)e2S$YGSahj8AH; zWfB^yp^LonL2I?)j0w_2bpPm7lXj~--kmXY=UBOoU|z1+u5j*xGH5m!?045+;r9&= z4MvT;rn&KAuG4S{u?@daYw?efY~`p<`c|z>soi4Yb|kibZv5gUB*P@JC+-QM?fNy^ z#Z|N$tuaB(t{~#%=<`67sS6D9O;Lk+u1#S|3L%ZL)N#%1ciz7FhvbM-OVD!{;{6kx z1zhK5)lG(v^mPmgw>> zjr6L>{^LD}v50^whwe)qf~eEw(KMZ@_!$+U?To&@J_xAaQ=w`c=^!muQ!AUe}PCz>a&-jC&Sqm2@Ua&H&5#r3q#6GSh3y z$_VYm+wbBFZspJnFJyFlt(Xk0OUvM>1^VrpT?aVb6{>1zee(v=#j|&5X zLHfZL_UHX9UtUD?_)~x9UxI-@+rMlArhIgFJL2!u%l6ZGy}+YA=cxpu68xx}+z~}T zdeMN)juzXLm>LdCsvSiXIq6_OUdS6YYaL`6`}V$g(lM7O_+jwhX!M@5W6VN^Hf_<8 z_W$w2_Pv1c)LX1d?XL%65mS%k3x!Uzh1 m8X%z1#4eh}{|F)?1Fv08`u_rfN`Det065vZ+SS@%)BgtZc-g}M literal 0 HcmV?d00001 diff --git a/res/img/flags/MY.png b/res/img/flags/MY.png new file mode 100644 index 0000000000000000000000000000000000000000..17f18ac51924e8a76856b89a194b741bdbcb9245 GIT binary patch literal 3081 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/MZ.png b/res/img/flags/MZ.png new file mode 100644 index 0000000000000000000000000000000000000000..66be6563c63c40bc14a90eae8ec739981d47fe3d GIT binary patch literal 3367 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/NA.png b/res/img/flags/NA.png new file mode 100644 index 0000000000000000000000000000000000000000..7ecfd317c71654c146f2a3e1fcc702f96bc6a96e GIT binary patch literal 3679 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/NE.png b/res/img/flags/NE.png new file mode 100644 index 0000000000000000000000000000000000000000..d584fa8429e64def9e3d6517b4b215ce237da7ea GIT binary patch literal 1660 zcmZ{kdpr|*AIE=e%VlH=bBJcOIFx2MF?noku9-MEb8I!2Nan#>%cXXaa$Jf-G6$VH zQH!I7BOQw6xFxqHI=QAYxl~R~sU_xpW+FR#zPpUlG)4{c2&O#pzl zmnSJe$#4EH#1>^A8@hK@31~FYmk2;jE_^Kvrrc2xo&ml9r0fBJpALXRdE&nX;1m{s zIR*fDApppP(nkM-%Ey*)9}kj}%8m574**H&!JD6=u> z?&J5n(CTR&2vipwrCZ?ohDf|kvsCY{r?u9j@;p(RG4)KM#bs&5DFLU!d1gtV*^b!t ziP==r^C3<)RT3{N=`D6lB@Ej6{wIynYpwF0&o8GuL~A==Pnh8}jsLSDW#LqAt&>?r zRPTw=dtpe-j?BHGSBkz{b#Qm{Bc<9kGIZUMdt2Y8kqzl$^&4=5umzXlhG6rc05?CY zwXP2iyrL4h;f-Kmh^wFq_;tb60l1D0wl_&wxJbyA6K zc{kM7Ks6Bf z8dk|vv#a@XJ&||x6RM8rv`LvszndgfJo9OlVfs;Dj}FUdm^H5+b~_Xh;QhP|Rn_ZS zrxlqfj%nAC9POZX242fyhCnUCf2em^_qlwSYY(0Ocz+|gh&tI5GaZ8YgPi5Jm$g;l z`X;UpO zHxZy2DZ;p0b~Q?Vb*i2knaeGZcDON8xj_?bET!EqfucHOsaO}*p~%BpRq!#2v+({q zA5ru7zd5{fOKR+#spG{!POy8V?sAE#ybG^!@YYsQlv$Tc7Sri!;R^Cs`|FMvuK8?m zD$0$BSetw=%rAxs+SWFb#~;;H$cH;J2tAdyf(jI}Johsw*k&z=NL}*1sN>2wzOnFN z;^onn*Ut~R9CS>vI0-I2vGIc7o_XyuOk0D0T`qnf*1BmL70|7Z3em4JTWzxHEGsz^ z2^SgkLBT=Uk8`>N%#5RE;I}yqH_PBjJ!5nJ*S3}Z1qvhjE;`lT9Cmm-_mdGV_5oIZ z16EbNvYjyQtiMsUy6NFh%6OHadt&M+R;||)+UEtA&vF}L<5u;=r zd|VFk|4l+4q(E>c&Nqh7(R36lw0S&}`{LW!(v#AFdqYP1553?eTBDz=lvxpW))VD~ z<)%^nnPiiG)kVJv-qQRHgyEHt4^ViZDt`SI#WhlW{>9=3kN@y zAQsfkJYk6b1et1VHNOy4(tCRT)MB7Zc8sH_R0kQ`TKMJct!&D<8}Wmesz(G%#nA^i zzADY(?8F?RR|8*e_V_V?68&V^Smf@Qx;Cs#R!+`*@}dzCo~LXhJ`mbF^)d)Y*#R^G)Hla{hAZMKCdu|ycggsv?_ z+YjVZk7&_HGGZoqW!j0%{Zub+)X-@(dwYwAI&S-03CjplXuqGAt9I#&R51Kt51oI8 zb9);j>*=@<)+R0fP9+-^szSbt7<1ogUGd(G={Mxq?SOb#an<1Eb*%#>JKrWi#B)c! z7;%`(9`(kH&m6riD4F>f-K3UGy(yl~py@TG@30@CbF8W9Phr_ur73l+M6AE4D|3pU zoER9C{)D-`w^1zglunFcld0^;F!nKg1nZa*0Ee|Xun%j$59bhwv&Gxn q;O($hSQ|VRo76h({6B)Y_{f;3#+MB{cU< zg%CM%eCvx!m?Kv+efRtR_xzyjoWuriq~)b(HogAUMhN;Hd*H@d*_v^G;*=EAP?T^=U;qG5 zzm=)66LDs3=6a;l(#if!#&zwGby?X|Ds=obwIu4j5d|xlTO#(G@^Qf@iZa1hMbCwC zt|>}!QipCxiz$2U6wtC|7i*L-BhpER!+Ydrz?3c#UX7 zjq`P1rZpH$Lq^2#dhsI3ykhjKruZNK!53lo2!5`VPA}@%G<58cAoOpcU%4L`TffOV zIT^XE#_y+iv)?S0hl4&6_d<@VEgchnv~PPNI?iiu1npq)I)BB{;YBYa|KqQI;?@}E zO5DVIbCF27`F*g9Qz!|}*(mKco4*~Q@lTQjXU)}kAhXu4V#iz#ze<)hRgDj#+PcnV|IO#+U6y&u7HwcU}MGXiNN{U zTi}ObFmKU`>?VYtA(;ddZLSmh_3L{pnf`YweB5kHu71=}l~^C(@J(`moESwg&#kCF zGG2EGBT4X~Bt0Lt+AyFtr*b=ZK5Q#0RuL^?L4yh(v2U;GO1dqVGPTFs=69Wa^>E=0 z5p^F@UN{fBc9BH=w!9m!#TCzsU?;ht5Rl)!JLkYs(qaa#%})`qt(B(?{cQz5`&Md9 zFd}~AQ~GpJo-t%gJJ9GXB43W|f_Qnp`AJ#z9^`}Qc(cu)OEM_RVhv!tjXY!7SDh_5i1bYT*%_i+-goVs{^N~C^MPYi?`6*E|=Zzarx@@dFR2x z)gom0$Y8Fr?CV45_u2s6x%S(puv6E~Nct5+(hNi@X%0{Bag_Ih<3tYK*I?LZL+ zM_6fTn2uwlbE}~gJ1;+WI2EQ*z7rhHFAe8Ls+dBQ~srRs`mcT0CeF^U7 zm7Q^{t_nJ+o(FeXv(PEaHp$AAtr>y^Q?IxRcX5 z2@ge6_!u`H@ol@&Ok}@z9K^;l^!i+Lwu^p5;kON4Tx zY@)P{HT>Bu97qHk+)C&(j=lI+qh3sMdu2Dhw+S0aSkNeJ#o$D&E5mg)hc%?HKJRF& z$q0}RqU11>7|bOhU7Z?Px(~$Z_PGWROG;-u?`HZuaHIlPG4v#@x$GpAKv+)hR6~(L zf0vRan674bty&|)*EtYX+Aqyzz_B<+zu}vV%-?QTI6t+^Rm=ShEnm!iw)QZRELTaBlLVi^ zSDxI}LWWG#TICfQxsmH%$wBb-Whf$2C^TgCV3#iQyJcR8QK4Xy+HxVa5W9naZMSiy zvTS|xlufKIDsa&9W)^H8p~(SH^dH#Z&2>0AuikFRbz8czC18fX`#d^ply$e2_rh=t zs5$F|TtkK(puk~s_c$%v1KQn<{*l7!AlzfVpC_2S8vBCXFxtRRx)L=zwx&{Oj7zc= zKUaVFZq`0ss9?H=fy9ptaMS*b0*(z~Bz*Olb<%`1t}IjG;p^$C0&~pHKA1MyV(-jbgYP zJ(n)m$W6j*a;ljtrpWI~oI;4ieYyk&PEvKG+bdnWqjNq1yZYy2Z_A)sbwyx2;6N-! zSuw2#`i9owZkpSXZ|}AvTrDx>EZnYO3n9%8fyW>zlbitpm8qQ&^>SwVg3oDbB9*v~ z+pS76Z+DM)c_zu-Z8EQY*dy&fk>TF}QB6+bkPQxyc;hH&!cIBzI5RBH&l~5D@{RIm z15ih*>8K#JRMd5y)HP6AYA8*lGExnNL=wA}4E|#Xi|`8yi2eTt-ZFPG+W=UZ*_l?O Hy^{X{CJl@_ literal 0 HcmV?d00001 diff --git a/res/img/flags/NG.png b/res/img/flags/NG.png new file mode 100644 index 0000000000000000000000000000000000000000..73aee15b3f35f4d032a1998db4d334eb32219315 GIT binary patch literal 563 zcmeAS@N?(olHy`uVBq!ia0vp^W*{uU1|;uX-8K(Mv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffzx4R3F27;f?yX%1z zXMsm#F_2CG;}6+R=Yb6N5>H=O_J^!8;>H@%A+_%r7#Nj2T^vIyZoR!_=*8?P(e^OE z+%?2U@gq|)v%X@J!Yzqyp2_K|F4o!Byb(8VE{RN9%+XZAnQtH-prfR9=v@>mckr=T zyNdZ)ZJN*0@0Fr!@g7#@>&z3XkGK{SVA%LEnfdj75?gN(chIaBPGEDyT* zUqkKqrGKZ7-Fmjy7B2)ROPRy8K$tr#tLc$t``O zu+yu2>Alx)pZ|2(6M!HFmD)cRRypKMQ{B_Mg35>a&A^F^jP? zImDkoriOoi-u@;7^+!Yf2WBogTl32n+Ao1ZswJ)wB`Jv|saDBFsX&Us$iUEC*T7WQ y$RfnZ*viz<%EUn1z|hLTpyJR|TNDks`6-!cmAEx<&W~*bS?cNP=d#Wzp$Pz|O}T*p literal 0 HcmV?d00001 diff --git a/res/img/flags/NI.png b/res/img/flags/NI.png new file mode 100644 index 0000000000000000000000000000000000000000..fd044933e4896c68aff43327a8175533e1f716c4 GIT binary patch literal 1701 zcmZ{kc{Ce(7RP^4M0i?ii?x>6X+u=fSo2U+v?zU+B0(5c%Tpa{sRSXawN)Q6mcf+q zo-I;qm5|rgsFtRbCZ)0Dsi#WQQA^Ru%$aj$=8w7O-ut=B`TleNxcOe^U1g=!qyYf3 z?rzRLB3l15at;7{q7nH$0N0TK z{7wJ>TLFMdLRG)Ft!N<`=HcorqR4ig9%hOFOK=OgCL-Zqu^IFIgs6ZfxqG@m7bG-P zP)6#$85;mdl({?Od{emVytJzq{WMsgHdeW9L1=UJsaU$(91GKQ^`exdOL=~{y`#93 zm*NR;b}cUS65;0*|ZoFd%h_&l98TlT2`%v&}Cy2kB#6kC)z*~hT1 zhhO6@ryuqk_B`57-g{=Zl6*eMOVP#qKORgQKGO7RH3@rv%0^oso5x;Az~ms$*7$d~ zw0drAmf_B?lu=e;R zMxms`yQqnaZ%xfpqBWaw{A4inHraCXafPA{! zVfYrx(QBo!<@U8VR~_Y+eb%`(mkIiFxmO957Bg7++dZld_#4tW(~}We(9R(H6Gq~< zD)hLJ6LFOz+X_)if^Un6Onm$sO~J4HkTBbq${x+@*P5mU9>yfcwdgVqDRJn>^y;!U zYR$7i6%XV4Um{l2j1N#>?J=p(o40qZS2cGX(1}IpF^wl?VbMor78{_OoC`;2Pn-Dx z387Q1e)qD^pif8bPqUWA!*3n=QuF@8=D9yZY*nq z@6*0I#Noh7EUteR3TF^z9=>8Dn59*9k!2<&cYgJ`mqMOkfV&k%DppG@r`B**?^J12 zsEk2gbmlpf)kK_WYkGU!1R+ctTvM2?KW3F>(m2yDSQ`j?E0 z!2w=2-+JypMf7s9YK>xBjaOp+b}+efeXH9N`u90rsn4F0Myt&wUJK>j(%jPTVr+D7 z?Q;krCIu)Wa%Qeun13la>MkXlz${9X3);!99UkH_nY)O$L=*a#1o?`P2W3^Spu>fe zM*;houBPKaWN&GVV_G!7a9)-_^oGX^gMKbo7G`O;uf&Z}0xjv{2tr|VoyEsng}8En z%B_6e=^g)@HD#!~o%x$d@egWZt3ldzrVLZ2GzguPsY`wLs5%5`<Z#j~Q|ii<9C9-0kE3F<@0Ccbn6RNb z$>rd>pRyY$VS76g9Ua9N$k;u)+jyL(pU@~gx2wUH*cM{0T-%|Ou>%(G$%2!IZWt#%k;wJ0VjmX7KxSK# z;Ze~Os)HdV%m_2T{ITe;OwGosfB!4hdmWgDfF;rbZH_!`Zi(@=L}5=`V6Bj*NDC|ynKB}<`yWAU bd_;8QjsGuz)do{U0^sg)-ns32Le@V3egf=% literal 0 HcmV?d00001 diff --git a/res/img/flags/NL.png b/res/img/flags/NL.png new file mode 100644 index 0000000000000000000000000000000000000000..0897943760ff90d0323d3207b9bde50e08f26c41 GIT binary patch literal 672 zcmeAS@N?(olHy`uVBq!ia0vp^W*{uU1|;uX-8K(Mv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffzx4R3F27;f?yX%1z zXMsm#F_2CG;}6+R=Yb6N5>H=O_J^!8;>H@%A+_%r7#RCKT^vIyZoR#|(3?3?;`qns zciPtZTuCs9jgB>tGv;Le&*Uh^IytoYpn;{5f>b+CmU$9S}IUez?v5$fEDD#px~VUwtLo5+&H|f1SL2 zZ^7-}MNz)hy+6ZOmRP;rW*L7$PGIvwgW~}+k~Pj4iae9xD(?BZ(QXC%QH85=*O~Xe z+*q18e|F}qu&vu0OB1^%Z@qjq`E6lh?2WRL{{`hMY~THhA+G1AdoT5V zvy$_0J858e{95bD&~Iw2Z*y$|L?^lz=fp?YYH%$-vVVF_Jey6sW!oVc=fu8^|M*Ya zEzxnm^|!QkEuoy_%*TmNmj@bBuC;yT;wSMD7Zu6~x$7Mv7z&O&w7 zV@s&lcv_+MJ}h2bf9lIlXlN~X!rk5#Fze>SWBkCdQ!R0gC`m~yNwrEYN(E93Mh1rF zx(24YMiwDP##W|=Rwf4828LD!1{H^%+M;O4%}>cptHiB=bAD_iD0)0y{an^LB{Ts5 Dxuyo8 literal 0 HcmV?d00001 diff --git a/res/img/flags/NO.png b/res/img/flags/NO.png new file mode 100644 index 0000000000000000000000000000000000000000..aafb0f17761442e115d157c6b3ee29b7c6758645 GIT binary patch literal 1695 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 ZOQ)d!-$0&kjkqxYTIzagl`7E4{{T|%s-6G< literal 0 HcmV?d00001 diff --git a/res/img/flags/NR.png b/res/img/flags/NR.png new file mode 100644 index 0000000000000000000000000000000000000000..58c2afb228aeac0c04d19788d9ffc67a6b0dd8e3 GIT binary patch literal 1620 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/PA.png b/res/img/flags/PA.png new file mode 100644 index 0000000000000000000000000000000000000000..3515d95d371fc49f62d94d11c8a0f4f41b8941e9 GIT binary patch literal 2285 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/PF.png b/res/img/flags/PF.png new file mode 100644 index 0000000000000000000000000000000000000000..2f33f2574f00952986b822b406ff60549712cd74 GIT binary patch literal 2379 zcmZ{mc{J1u8^?c!84QD~MOA7^a}gUUbw0DzgBnb`8E z`*%t}cy(;B_6ZLH-o{qO08o)Cvg;1!&2XZbtrY-7o&o@RJOKRUt?2Ur5Q+eR1vdad zX90jzKyCy60`CC1VPR^*BQLfuvS>UA2behr^XT?ZuKHp=^BTbrb1SUi6j)a3tn#mR zw^jf^2yJd+Y)2jWb2P%vZdk5)Z6)dx5F7gv{53O( zCAcRSML8JX$vGFiax2{ESszJT=C@1#0aB#6Tuu}c*WxD8Iu^4(MveG8%ndtI%bQLs zE6)#UXb+6FQ@2s5YxP0v^Hp^pIbyiKqO0R|vnQ_!3g`#O{Mg*t=j4D(aW#9Qc zeQ-{VIx(_k2!(7IL&y7BN|cg*fjuFuY0l864B6=%`PeOObz!KO}i4G`6Z1EsGN zpBs+`@=xd$1TzzzF^Fw$OzsfoXHywXc;>a6q{j{3u@Rb`;Nf z%?urP&-|nGH8fms0w`q^@yS0-tdL`>_Z1vmqq5CamRZ97;jF9cTWZXnus56mF_Xf6 z>0#4m1|uwQ9#p4TXMp$;!zcRmr>^xEAi{b&GZUeKvJmSM>8 z>->ukCBA+?--dC3mx1B@9}oqd-&fOWuEUgymddeGd<57JKTv7CRM^NyvGS=`v|Fmj zlicnLtGx&4Vyx3cVV0c-J1Dy3yYT`zIO(awPX0~X_UzVU^h}FUQLrg%H85@?E~thJ z+B_E{81&L!i2iE6P;jTG3#gHe?@Dv<2gJKR*8++Cm&hA5Ez$HgD3Cn!h;`Y=`9|w< zno!mo4Ho}BRMBm?HOe83#NVsXxJZIK>)5NuYtcqMTx~k8Mh%x;1hFHM^9;z6?Ap<$ zwP#KUE14y|lLD0)JKuIaCDw)}(eW`VpJx0Q1im)tQx#u+d<3SlK=-gk@O(_r!*EbQ z(m1F5cS2?slO-!yTEeh=S|53Qra1hATmV3&Y9WPlCCQP7DRk2$t6|w7xc(YPn2RVp zgPIPh=0EHy6E-P{W0rViu8AEZOk7v8it8ewn4Jhx&E-doY)HUlC`GhGR%nk(HR z`nl=8SjT4ljF`_eSIz}@_ z;wU>RXyBevZ-n*SQkxpQKCMwbTi6v-j6D7BvI*fRy^)Wv<~kZS z`~e;DGdX;bUm-Z5E_vK02xTPQ0X1V7HG*3C3zgv#rP0R6g|y2Inq(39!IdgH2m5Lq z^6pNfVavZv#&>#ZH4KsAfwxaK*_}+JLsjuHlK4xe%~q9Iak9~8m=WBGvP^Q#&*hHe zx71*J7nW%DXX9P^%_v^W^d~vG>FcuvN~P(2l0zLNVPB7h@%fjFu1EgMum5px&hrh| zYPS)ZSB-NX@3Bw{!8(O_xQBS6i9wz`09pv-ISqu4hL)b4)>*U;60MC;Lm<%z1hsWm f|9=F26px!;5&vHxoOdmTCjiW`)+Xf`x7dFJiOoV> literal 0 HcmV?d00001 diff --git a/res/img/flags/PG.png b/res/img/flags/PG.png new file mode 100644 index 0000000000000000000000000000000000000000..c796f587c634102586fa2f81fede56571b727b51 GIT binary patch literal 4393 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 QKL`M4EFB3I7UYEg15A>^?*IS* literal 0 HcmV?d00001 diff --git a/res/img/flags/PK.png b/res/img/flags/PK.png new file mode 100644 index 0000000000000000000000000000000000000000..87f4e2f49246e9d96d5bd056ff6c8960cbd9247d GIT binary patch literal 3165 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 UYv7z8+X%AL)78&qol`;+0HOTMdjJ3c literal 0 HcmV?d00001 diff --git a/res/img/flags/PM.png b/res/img/flags/PM.png new file mode 100644 index 0000000000000000000000000000000000000000..b74c396d924b2a6ed92ccda1af761bfc26cfccd4 GIT binary patch literal 8583 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 D84nhx literal 0 HcmV?d00001 diff --git a/res/img/flags/PN.png b/res/img/flags/PN.png new file mode 100644 index 0000000000000000000000000000000000000000..e34c62d598f45963cb6e8fa94d45148be7fa9510 GIT binary patch literal 5945 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

    Wey9xTIcg$?DSP(GcBClqS8Zw0?g&Gs?c!&_%3 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 G!~O$9Te$fE literal 0 HcmV?d00001 diff --git a/res/img/flags/PS.png b/res/img/flags/PS.png new file mode 100644 index 0000000000000000000000000000000000000000..7a0cceec00db13aa85c8e7acb9ab795f3478aedc GIT binary patch literal 2147 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/PT.png b/res/img/flags/PT.png new file mode 100644 index 0000000000000000000000000000000000000000..49e290827c89fb6aaab4b06b34b894009fcd7bc2 GIT binary patch literal 2617 zcmZ{mc{J4PAIG2X7-Jd3T)O7k#}z3{BfBhPH`yk}l2k$xCEJv-j-|$pP*T|mH>rHo(En8Gu+d0H|pI?C?v}_W+P_ z04(|eU~(4#OnA}Lqo(`|gukP`4WInQwPqyoArkIzEQ(LR|HgW#)gb>M6islp6`B#0 z$LOldkrLMU&(sMvmZX^Rm5I=pJ);UeAJ_Vq=M$ANzwRAsfZ`?bdk!G1LUJM>SNjTP zVAZ8{phc9Rjf!a3USb;_mX{F>5#TMPTj}Onw#vWegd=aW)kJN^&O2ZWPc$8l+VMBU zuDo*}rk&-~Zcz05iWd5lHrV;baRb`#qfLrk?!Wr*FU*yBbVShOzt0;WXO^sz&N->& z_66SjrlQ1ZxtvoNdWiC8_ry>~2m=itFK1%2bJS+wwb_@h8Cq5iVQbT# z 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/QA.png b/res/img/flags/QA.png new file mode 100644 index 0000000000000000000000000000000000000000..bb091cc88c2ee7548fc207a5bdb851a5d0149343 GIT binary patch literal 1564 zcmZ{kc~sH~5XXO+fVbHpl|`~WBHpj}WCT@Bas zVgLXs+F>!SRQ^2w)Nxn$?cAmHhUik3mZthuT;Ksj8QV1dsLufVnp4>z7}4p)I;zbY zVGk4d9?VAPIxNH4^w?DocR97FG@MVmE5=EW2$sF`UPddayXQuNt}XFLnbF%Z(W+%{ zmp$2`2r2F=L_)XXod4~jR(vh(kI`_m>-NWLkhfP6RYRe5UdaRgv`yQ8nndA3gSy5^ z`merAputov*vtdIikp7obA#Y^gKJiC!mjwZj1r=C-`c7c^@?}vOaLmCpzjqg6KIqX zMCM6ma5f)5ER4Kpe62K|2!c|qN=i4l2cdWv@u*pS)?xOc>D6ZzDuTPHoAD$$kNSp7 zv!4^Qsv(!@hyR>D9h3RNsD)4#c&7U7epPeQ?!y>dpu^xdQZ6*#6omjAjE|l;BhfU? zYHt06L2k;^OR2RbKyFE1&5iVsXl>SoTx`h|6Cc^Au1}0ks5PHUNtH{feCh3O7@M*v zpP||jn-tS!c^=gVuBdoYrM0xfmYm=XUY*+bRk8ca$sSO*)i8}2P?9wmJFToKyz$mp$x8NJKn#s*($daS>^z&D ztH`%H-y%XU-?Xd?;SeR^z5B;~Ww_6KzeM=7MF+V%wt7wohM88uwL$%2hcbulfba;w6naR1s1FhTc$Z6fW&HKlUH5Ylo}qjF$gW}YfA zMXwlL+R-mjQ6!l~S-sga9N&vqt=41s<&eU7$(UD+tz+pqnlvYlU>eyrZ&3`0_fITW zLk_AiByQ}C&>E6S&eCo-j%9V?CSod3I1xhOGUi9pK*6m^{&vF-Y|i}{P|H5ifa!;X zkTB8`R+4 z(!V!^@2hcg9LTYG)iBgAt9IZ@2X^f-$Yjmd)h~SsR8?9Kb|1fE=7!FR(k~ga^%@D0 zxAc&+OeOZA=EyiZWAyB>`K{>#sX}7ucJO50an|UgLY_q1s6cf`?`M39gg@wsmkkpw zUJXc_5Wyy)Y?bGNn$_s?r^&hZhvJd#?e;?}h)%-vLba{q#s+NTv)G>OekvC_r>vJac4z)2zVs=n>Fl~6o9W&7yFj%vyybQOu-I#}l|lZBF@&x{P6-AJb2>g)A6gd* zoW-X+6~#Kdm9##3S4B0m!iSOiwZ-xHGa#p#zGB%nfhHD{9w&_$a5~o`IWOK9BU!95 zG^^32+#L<-mKjDdS4wcRAD6+obq*1p@|sC_W->?bNZUg7&Lqi>WUyTJ zxMSMG9{aV{DDPa2P-Vv}?22-Xo~xo$osa7{;b6%>Z+c~OUn{m7Z%!5;`OgQ!Is283 zZ@3mVe%-V6$bRXk+(*HAPyz!eK`7FhASnQ2xDiqxj?gzYcQrOaA&gL_@ZaD@C^($T g5gq!6;B-XbDRSKZ3*?J^6Qu&c4(EV@~ literal 0 HcmV?d00001 diff --git a/res/img/flags/RE.png b/res/img/flags/RE.png new file mode 100644 index 0000000000000000000000000000000000000000..6d50a0f544ad14e2da315e53fdeb187d3c8781c6 GIT binary patch literal 566 zcmeAS@N?(olHy`uVBq!ia0vp^W*{uU1|;uX-8K(Mv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffzx4R3F27;f?yX%1z zXMsm#F_2CG;}6+R=Yb6N5>H=O_J^!8;>H@%A+_%r7#LMOT^vIyZoR#|-pj>NqU~e( zkyycIoumjJqZ@lTPbZm3x(Xc8kUp~I;_VH3aR)VEXouPVTDHYHQZ_R2 zHFc$JGZW|i@dVlc1P;oV%B8(Dmrm(eCjaaHlR3rbUV6{}IbZ(5>(J0zexKQzOB+QN zPw(B%z4CIrr2ab3?XSbltILCy@87d!gX&QYr}X*1O@Fj@t7om&&I~;-1 z9RK$I^719$C;$H39H=O_J^!8;>H@%A+_%r7#O8IT^vIyZoR#|FptTQ;n>IZ z(`UEF%$Ttxt%|egA+N!VPRY2&#g^^{A|_ z(mEFO^+M&J30rEbbzki*v9{>%fB*dF`mg)9ovQu1B;X!Tv99dy_DI8tX65HEpYyXS z<=<>D(J7KI)Vp%&zN)i(okQ1N?>_qV=c1j9FS0bvRGcA6F|kkjZ{YQP(u@#q=>BB! z%QtmAeavSKP(ZcBHKHUXu_Vv>Ka*u7#Ulc8d{kcXd4(>85mR? gdTNWJAvZrIGp!Q02G04hjUX#MUHx3vIVCg!0GwUKT>t<8 literal 0 HcmV?d00001 diff --git a/res/img/flags/RS.png b/res/img/flags/RS.png new file mode 100644 index 0000000000000000000000000000000000000000..ebb0f28a7bdf6b76c944ac6808319a7e4cb98945 GIT binary patch literal 3349 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/RU.png b/res/img/flags/RU.png new file mode 100644 index 0000000000000000000000000000000000000000..64532ffa58af755f27404820c7be89cbc260bbbe GIT binary patch literal 662 zcmeAS@N?(olHy`uVBq!ia0vp^W*{uU1|;uX-8K(Mv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffzx4R3F27;f?yX%1z zXMsm#F_2CG;}6+R=Yb6N5>H=O_J^!8;>H@%A+_%r7#LeUT^vIyZoR!>?|s-o=GaH| zuktAcFRtk>oW1(}0Z*1(cJ=LkUEQTIO^&dAF8r&^jir z&^i5}-1Xme*VJ2ne=NA8Dg?9$2p+h6xz1cU?|EgM$U1SUSth=hO?vCT8t4CRQt_Om zQfPbZjqx#wG7$|iM_GG-s(?9DUiSG*7~ls+}ZZI`E&2?oR{|P?kktoZ$Irh#wT6p zTNcwV+`#O4{b^yZan8c)73H?R0(z?tNo_x}D73)4r0>1K`G6Ve8fT2JrO!~S3O@g} zi1~xg%Y`=E^m9DtT7G-{|McqQ*N3M4K6-Y?>#A7_Z^BxywZ_irm+zmoE}hfCJ!*9a z(B{0l&4-sIhloarf7>Zo*yek1QAyO)+y7@hnr0!pamgB+wDT2ke?e`#{>ws+XVaN) znUH{DFn-2fH_iP>b3(-fponUTYeY#(Vo9o1a#1RfVlXl=G}kpS)itsRF*3F?HMBA@ p&^9o%GBBt(^wbtbLvDUbW?Cg~4V?318-W@aJYD@<);T3K0RVE30(<}f literal 0 HcmV?d00001 diff --git a/res/img/flags/RW.png b/res/img/flags/RW.png new file mode 100644 index 0000000000000000000000000000000000000000..64b3cfff04b69bfd82c843aae87f239df697b74a GIT binary patch literal 1695 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/SD.png b/res/img/flags/SD.png new file mode 100644 index 0000000000000000000000000000000000000000..d8711a83d695b5f01815e1733b510fb86e701f61 GIT binary patch literal 2103 zcmZ{ldpy(a8^^yJHpk7e(d1Ah$L17G{KiHi%VB9KHs_o|YayO(2pvR`^Qn>QFxU-y644QKpGDe?W{002mxvd6g! zcjOBIwop>|LDzAnq^#(31h+mq4P=0>Bj%0L+m9 z0G$T_h{&Q=mlJ{k#Mkj8PC!9yVqee%5R0_;xGW&)f4LND(<>;Tlv7T&&;wpSbTmp>kGgT7D9LFx^(10Jeg&pLh|CG6Hh9GZheIzbOt%^C0c;TX+7AeI3+I zew67bp9P*(Jj45)t+14g^oxA((cVm2E5 zUQk7R7nX&_cDNUiw>43ri9_Oy@ zq&_%b$S)DJ{r$U=0yjB^yXFeN_#Z*kBGi52c@kzv`)fgxlGv=uq?*Zx!cc9#>I!NZD~J%x?aZ08-C_T!$r`#xEY_i92EExI z!cHcHaHv7p>(AgtZsm5wE%LM*TqWX2%Ka7C%!p}TA8~lZUCgIgA|c%$^&y0-3?8xn z#@C>aszdxh)ObMDbfvcQK5ey<_U`C*O;0I_f3Zd@)!HIRL&A)h(7cUI5yD2w}WqZG$I*CzKH%}~ni0nFxn2%=U#Ht*qa6GY>o})A}F6+n6 z?{7+OKz;r2&M#!kdb%h=SL=kNW0qZpQ$A!hrl(Gv6T{gaB1*Ny=zA}U8{NW&VHG~~ zN}+V5eYR}I9rRZ!KIg+RD<)&=KHw_1p{)m1WRKSKSJV&=PWd0NO1!*hxbtbbkL{%= zRR6y4OcmF#gfDF2WCmk(Penfm|5&XX^)Ck^s{cr+SnYa+(1ywKxVv&dwEH#GF-`HKmdmDBD>I&75JqSu!Y^H}H=?x4Dc ztE$4Xh)JuZt!b6@;*9y9nkvz)26Jrz2E2I$Z7%38dudv!QXwtqDgV=Ud*ZWNnH@C> zjuUUsPA!&TgB=v5=Igz)zj7i6FZ`-jm9)RDa!*2w$LV`OP-1Znk{vKu|4ln@s=dHeXw)~BVa zST#Vt$JU_Zw{gbAyvmx9##ks%wFnaXtyQg zqSwU7BrF_eshC#xkfd*{oe~KgxBd>zyz&>g1b-{c3v-1{ zV}AM;pwBJnOG*kHd~f>O8*(#)lU3S8#|N^rFwzd85}4I}vjVKO4Ijkp(>y;5OJ2Cv z{tG}AMvsB)LVMF{%aD^;eHF#djOWnDZ`nz$xf_-VUYy~GSmL(;6M7rb5fWVBp8(3_ zvz7sjhuwm58RO&hS8iM*o#yH2zdsKx6DYQ%{dUu2$Y<|xebJO2JULu}_spidN()ie zXX9mnIm-+}vP-;l$^nBwlOBk4U4t0rSfc{wgQiq4dz!yG;H)~YH~Ml|X9&dvs($QW&Eh&Dm#q72a}R7}T|myU;s|p;&HV$q{M#! DldQAM literal 0 HcmV?d00001 diff --git a/res/img/flags/SE.png b/res/img/flags/SE.png new file mode 100644 index 0000000000000000000000000000000000000000..81880931f392086201cb9faf68efda479bcf8df5 GIT binary patch literal 1278 zcmeAS@N?(olHy`uVBq!ia0vp^W*{uU1|;uX-8K(Mv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffzx4R3F27;f?yX%1z zXMsm#F_2CG;}6+R=Yb6N5>H=O_J^!8;>H@%A+_%r7?|IBx;TbZ+ULJC~qNF5JIB}b_r%codrzLui4!LHkrW7n*_P|L% zGgLWGbh2wsc3AJlB_GnnryRV(=a;nn^SbWuerhM5aB^18jIrH+w$-?}{qW!Y#rG|r z-(z$Q6hWX&jx|NAD+7yetKv6gNwzvJNLUO{IQ&qxXA2$^{LknCH{Q8`02!9%Zf+G#ATK3 z4?Q~Wt=zwd@ma(5&ktNTY>qJ$j{d&>BFn)G0r~lR?`CgFKJ_f%po}wXF^}jO!w`ex z2#yeUx@OMhLvM`5E%?f={YhHic=E$CT_(v-A`BdjFD6FaF7JFJc}wHyXFsMHiobPc z)TY@VXM7|2+xhUd(&`mgW(%=S=5vYa2ng7F(}r>CNrU?(ayxRL@8FxGbY9|vxuS0N zvTe);Y0oR-HvjTrxFqAXgaJKHwUUrUoM)}zlxs7K^O!!X}vqjDOd@jtMAzCGU-`$&{_tN&= zo|16svN!L|UynM37VerAojY&0&A`c&k5V3HvuT zKeH;hlA_7rI?eO)|0z4!@7y~u@5b8uyURZs-}k?|+(7R3<3hQHeIINYtdGgeP55@f zai!Twy?|xHKK7Ab2X>Sj{(Et5kA^5}dvriApGTunEPSA4LfAW)U;H8T@RnM2Pt6S`yXc=f=dD53#vtnuAq%Sd> z_PzVKtvfYr@8Xm=nLwp03tz5JyZ4{Bt9-hC`Mkzy()S#;GHg51uDAT_W%YZvF3i)I zA+vM2`<0m!nx^mQi}E~w{3P?%6sL~ucAXl6t4wy9TqqTtkz@5~0sn!%8E5=-^SSnH z-uN>w+s{T>Gb=jqTN0j#N zThY4Z(##d2djc;7%%A7}?T2jW?O%(4ff%#Dg_&pJ^nyF?SQ0KU6<^pd{kG_ue1cZj zA`Lk5YW~5#pn1~OUw6&xfMtPdiEBhjN@7W>RdP`(kYX@0Ff`XSFx54(2r)9YGBva^ qG0-+Jv@$TLIP}yOMMG|WN@iLmZVjCCV;g}Q7(8A5T-G@yGywqTS~f@k literal 0 HcmV?d00001 diff --git a/res/img/flags/SG.png b/res/img/flags/SG.png new file mode 100644 index 0000000000000000000000000000000000000000..6f00e57923a5c9f0c58fa482d3ba6a27eaf514b6 GIT binary patch literal 2210 zcmaKtcR1T?8^?cwsMVOY+tfKnQ6p-PYGQlMQj}7Ai@noILQ81XJoYMTw5nU||9P(P99Ac>n-Mv=U|o0K#AZu;v5+YB>PF z7g*4KQ-k&ab}`b|p^>ITZ9JL==0F465E`9+<+iWZ812FoYG|U%^o>!NPhMQ;*8MG7 zCCyL=aVzpOK7#@vD}3(wQoE;*n<#PjLUQ_ zzHA0+qBleKH=>HacB*@hu_l#@{~PnX^Ih!XlK&`uVulszE&5A+=tWn*H3p?ST0MX5 zLp9JMEQ>yTZuQLp9j)UH>k=_nDMs?<{9k4RfT8OG8k6=|L- zcTS^#e29WVK+9Hlbq%@6ccEYX1Nz=oh6^N&c5P}dRF7Y>@j5i4;7h?V!ZFBodqfrL z5*PkymZ__t_zsg>T#&u7-QIZ)eW~kGAwV)mEJ6p@(q{~x@0n`Vd%2U5d5JTJ@R&J} zI2BBf8%XYD!)Vz2X;%o2C&{E0hIFsBtmQY}_OiU^w?1nIbvhymO=iVq%`URWs{l%no6$ z(nSqnK2bZEUr)Fp7W1_VVUGHiESr5XKB>%5*YZN_4{8?kj3#4N>j%8FlWEaf!8Qwj zZ>jRZK9f@9lPI;=m1;u@+q*oeW>C5i+0P!udQ?rl+aPNj$|F}QPdu!>cHqX5-K*3R z68m#0g0E9mgs5P$Ge$q~phc|029DHPtKU0?p0}0BO~9!51?6&Mk>6E*MAwy{$wkf^ z!}i6ih|$L=N9P}fe0zzG*~c95Fpy9{YM`6ZS6RhMjoWNfz8j= zwG*cpS8D0&uUMiFUbY;va_KJ1RSJ99CZstg6x2xAch%;@IJ%tGj+Y_u!p-dts>Gq^ zwo{fRqCZzJXT)`TQ(JxXAson;10b_FISDbvXd$nP{in{%@Y5NZ>irC`{@T zQ1N(NV#gc$W$LY>BUW?IZhaR5ukFfp92aaXFIjJv-8k5jk0*->sqkX$;;qkvm<0Z?GoSwFR(Gau0V(nlbn^KAdMG zQY9_JRBt(=oYy)!OCluh21+pZA%;~$&>XDE7q!)h8pt|+P;kJAtS??W?1gRrq5nIh zq-A?y2AAYE(w?HZB-79}xP_i70A`!@Up|T0ipWW@H^t((P&(k$`HkcE$mcCd;>hQSsNwfRzJC9 z4{Wx&t`2myDUx!8Gq~OWjf$637|`Q&szD|oN^i4oEMA-N%qE*815Dlt0E;Q>cPpWy<>2 zN^#saWP@9UW$n9P!EummYLNSHLm_aK67}g5Fl;zcq_~>t&4;NN_exAt(NYl?Oi$ZXU#dx-3cZ6>>w zuUK})V(f)kXZK@$LMo4HlkWvsk9=*+@9&1vY?Rq>2c!c)Cy`6KB52bJlONa#&K>nQ zlz{R-V)uHgZ)I}c*oeJoykZKH)p;Y+{o0sML&yYYIcK&**S(|3?3Hw^{ z@R>2bNC*qZiSww!ajoK}^rnZ2WadnwtUKMD+Z7ZYyO1^9!t6~8{$Q>U z(sk-_$a)sH>?}InJlMXWSpzGWO|IM>q)wxfkGh<@{AF9dwvqQ7<`t={bCeg}oV$n1 zg^x@iH6k+q$=9&+t`*$)xMlB;HOsu0&q5lgBHVlYe_)(3#zhIofAK%q59Zaq$@6dQ zq@(GRZMq{I!K}Tsef>wM?(I-F=TLVw*I;)VfNL;0WoekA^fi@R*W}d{<I()Ir`AOqaIJ)-`%fw|ZLOEUn5x~4j{T28Tl11DPo>Hq)$ literal 0 HcmV?d00001 diff --git a/res/img/flags/SH.png b/res/img/flags/SH.png new file mode 100644 index 0000000000000000000000000000000000000000..055dde68bc14c17434eb2759857b8818fbaeae42 GIT binary patch literal 4615 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/SI.png b/res/img/flags/SI.png new file mode 100644 index 0000000000000000000000000000000000000000..96359834069bdbbf4ddfacbc677565d5baf73c2e GIT binary patch literal 1613 zcmZ{kdpOez7{`CJS-I^Qat)DOj$CFtG`6)c!!r|$CT4AzS#qC|a@?xv!km(4(wUG; z9pn~s7b=lNq@;35oES+dx;U%y&-=cg_ws!Ieb0D$xG2eM%L4$Q9kAzh`+13(-C0NyeHz+MOd z8c|o8y|B^)G?3&%kW#93r;#Y)NeneW0J2c^vxt{d5T%ap8+2Fi51chWKd z$YR|H4&DjllBXO`AC_k4%I0wmTaZJPL8HRuFO%q!XcJgl`T|wKAO_sHrJYjXq{(W+4uHjTgU#nCicVF zf@1~8ms(PaOwaxrcU9svPW==`J0N?wy7z}%4b0RUkE@==g;4)~sFsm%O-wqpv2Ymk$;+#F+78q)85Ms+~74}_%Cq4CXo{VZiUMhDeF zAR+n_m8Q5I3wMIL?S>fsY80YsJXX} zVFaCJQ!Y_B@EgH%y<*_O{ybg_=_+IF4o}@AboJ()oQG-IIFo+)vy)B~p?v5!mKLUS z8a}4ARVY`SIn>R<-aO68=eB$;QP$cOLA$CnX43zXaXU>eBUFv@dWRxB$G|eRVPD9G zSU;g7ve^*SH%Dz#6|3ooMub}vxQcnN$F9?LakuU#TEX+lv(q~I;+2jQ-Nb2<|Ni+= z#A<%2DA09g^|JLxwQgKAA5}TFP6c@!b+^t+G1&KIwL3cXjWtp`04LUUa;h+5r@Pb zU-Zje<06KFCPP*-Gj5c?#b)KZ81k(x2%dkVCE`t8Wa8_Ild(HkWP8lEeV9dg@JkiR z=izxK>S1kH&HBfXv(WDF1fchY|;p?r(h1`@A+pcEgW! zJ_OGlFbnr=YOQ=>3+f?KJtWJM^a1pr3KhobrK771(_px@sCqrCv;rNSaw5+w&?=*F zT#mX&{O-u-_9_hHZC-fnpn#t$VD0tK-nu?D9$%T2ZfJ=u3p36LC5!deumUxcWWbVu z65Xp$7#OQ=PPGZ@l6w!}+(0!1{FDfmr8l*%yXFYnz+M2{UEClwgqG)#=f@z`r%(C5iWvN|@)C72C9Jm$+_m^xPpIvyV!m z#iq3*zT@ZCUqzbQG!sfZqM<1E$hkJ{gAL=ggULigq}gWug^kotMa71=;44EmW{sTS zx)-X6Rtx@xUSZrzec@Rcr(2IXOz&<#&CzOgqD{rA6+bRo$IkB1k(rABey&Xs9)t@D zPla$5!cz58_eXg?1N%hQUFMV^&Sg^jRg|zjYQeoSlj=O*p0BZM<5cqW^un5 b!Xtw@A; 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 F2>^841hN1C literal 0 HcmV?d00001 diff --git a/res/img/flags/SM.png b/res/img/flags/SM.png new file mode 100644 index 0000000000000000000000000000000000000000..1af1ca284fdcff936c14d6f4a59e427d026789c4 GIT binary patch literal 3009 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 U0Da;~;R*mtQ#`KnEaBRJ0G45cFaQ7m literal 0 HcmV?d00001 diff --git a/res/img/flags/SR.png b/res/img/flags/SR.png new file mode 100644 index 0000000000000000000000000000000000000000..b072dda835cee73f1c890ba76614664c78aa8c24 GIT binary patch literal 1942 zcmZ{lc{JOJ7RP^tgorI##8Ro+s@ld*2(gtg6jh^^+Lh9X2u(^!ELB}B^`26DO|^Y( zw5n)CisGe~A>-L9weMRSOOLfo=KVA0{qgR(_kQkjzUTgVGhJQm#i0sN006{s4z})m z8vPYgV1E8OSYOJA&^0S(D*&j;7CQ(O=J&{82X|)xxTOIA)HDFt^2xVd8)h;eq6CL4v3v&nH+YfOef$DK!a3VPri7K`^tBW{ zZhz+s({Z*|9^}zAZUVt$4#8gkp3wX49g~3-Iawu@M^Jp|fYNKzLWnA#wKH=V%<&?? zY+l73b0V!h8$dO`CrK?JC?oyzR-WPSp32F*6=^}8^XU=Kj(j<5fhFMfR7CU}e zG2mSrQ-U^)+(}!;Ysg1yZ$n`eQoHB5{vf=bIp!AF;o9*6B!&rf zk!0bwbt>DXGRSU_d;>FlP`?IK6CrGkjhH14&@g4*#GNnpYo%ecD<;E^_DCXTxdpCV zTHT%*pRKu4ujVZN7+}unh=ZM<;vr^(0?n>h@Bf-n(DC%YHqCJ4u2o~hN zkEcKjS~U)ko)M{f2@><8hOS8!6wBi$7ietmW1EQYAE^e zh>HSJ>gO_agd=ahwN?_?b=$$YK~ATOX)1^zi%0UbtFVq6pFG>Blm3ZvTWG1JteYW{ z;b$-ja{@WZ`eB(5IdLEH&t{}^etjaWDp_#erC)&LD&ypIZ51qAj!@o7AF`i`(X zz6~ns@GC&w*t=saD8Tz#5;Hz3GS&1k($>Oj6J{)FwU}DX@YZejFS@PPBop@S%O6}H zXx5XR>sO$y2esP~eO8wa=T+E0QtJ9gPJM&quE;y-yLS6NT0PWEysQI>S5P+jOxB=! zE;c>zBUDV)C4Z<+`F3%ld7uVTg<)0b=ZJR}ZK#M}PU$g>E|>e@SL7`B*0 zZ)CEC7;V~`%Efh}wRFFLp zHyxY{da!`Do@ANL2*iq#hn_cIw-ENGcUztI@&mbaVPC~XLW|fPo(v%UcMxlhl~ik8sznfQQL=)Z%FN48xI(yk_r+! zBn3*2`Bb8HNv6v!udQd6I7CGVE<`pEdFl02n62*50|j{hyECajIJ{Ao=2+y^4CTBm z`UsX))bW}CHmJAooQa}+TuvTh4%_rkGwfP}q`>(`pq_xEHFJrbS!pQks>R(YOu`nO zF;u0NrP90k_Q)_lBine(CNpv0k`#djU24fkji5^@~Twa z0}vzCaUO&tulm9*@hhdA-J__<>0o>pZ>NzBtvtN*BQ162*68Z~>_b&{hV}*J5jveK ztK$>Bt#fKZMJs5(Vf`+4Atu>pL4(Og2v<*XDI#o2+4yX6^tM4|OJF&gXu8Ke^K#=v zVZ^q9qmKU*cW{N^ewLf1@jbWPB>Zn$_n!XkM!Uv|nhFwoz|$yjic^(hz_FF0MEA0h<)4SFQ@F!i#$ z>sfhF!-JE88l|p@pFlIuq-^-HrIzO+qb}31{796odXniIt+yMS31Ex-+YUcuh2~hj zOYZmQGD8}6FDUhPQCeMJ+sU1b`(LEhO4C1dbpNB&H}v}*>&y8C|ESeAFhnS0FQ=vM zdO(_`hM0DdLC+TOp=t>gRmA?R#Y_oGo(h4Cyd#e}gqF>8M;4A|6>gKMs@YnU_Mum< zV{l@CkNtKAKr4x)dthrF5hTez&KK-`B4vtVfB*~egkR;|o!y3tCx=oaq9K+qe= zfDa;y7js$7)&)@g2=#pRa3y@APq;?Aux|~J@{!j6bPm}u=F)jjlQdaZudN`!9R1CA zMwuOx{9Gdrf!jL4S0o;;HQ!t}fJh&>J-qn)`XOR)-p?ImkEhd3Km@&Flvi=%4w`vpdZIZSy0n}hm^#LPnE0*-~%OQsc8i)mYxAh&o0VlG-Ak zH!2^{`BX|XR@tAwqg&BF2O8MDTKnZ#N>?88vBXcggCFbTE7bL!CWBv{t90 zhZ9o#sy=ebn5R7yJuY-9RXJFqh|4#22(GWWM}oSmo)cx?F3Wzu51$UZSGgVj-PD8@ zz8lZf*CToltPCXMR$($8sHYlk0kUnM1~RBfg#dnbyuo%}#%pmd04>kp7^R&K+la&dYHabg|x6 z`J9_fJp5|moe&<~Hn_n1kqNIFn@Kas?tNWDK*jobr{IJ-PWjma+1Ap3c~iiIN+1aCn8 zXfgZ<4GL=y^)e~P> zcR7BensfvkV28!V}`5ae}JX7(!bmpMf&71O>%iJ(>G z>4*L4Pk+snXBDEHv(&;4E+SfVCcfv)ft8H*9pu<@rsNjG+jgq021Cd^-<2Jhym*5~ z@Ohk|31iSO*G)E@cJHs;uA3YRz2xcQ8SYKkaP6ra(dpU@1NF-cLxEOf9Zpe!m^BqP^Qa|< z^O9ACs&<3*pn!`HMu!6UOZ#Y#vV!3&wE^;r54dNRQ`cx<0(S;-ykya-A@Yu>ycg8w zf?y{^(Gu9UyPabp*|4M6*yo9G>H8XKlB4$Y`jZ`vOa6AxwAXrMU*XL95+1Jfk#Wq< zeFc}X$)~5kcrps9VNPmZr@o=81LpasP4F-SESEG1D{(sG28>%H9wcuPpqNWtuUTlP z^)fzOT>5N0aUdZ4*Q#%mx>6XcZ5K8^vUk@BWCfM&9Wf;wU!!Y-l+Vz<)vnB3nIE_L z=I>!O3BsVF)nPud?K8U7j`LR+xT4KB5?0MfTo2sq$$}Sq1MAxRGl}ce{OY1#E;~bo znYo47#mP2>xtfX1mW>YySzJBVRi;5=9pDUuSiJg6TJ+0j3mDr|6-Jw$ z*&@fMUd*!m^-yr)%;baKT42kbp(2y}3^RKJ;>v{*;fbHx){Y7xj4(=~+ZOeNqdQKs zr3mC_j`CU{782@G*fv(oCHKoE)9M1`>J{J>YYTrf^vY4IOq$ju-5b?)K0ol~J_KRJ z3+$Px>pWo3431+uj;YU1vyVu*SJsr3a%tDmZ;;!F@HNuoDu2v_`19Ul2@}3G0UyP| zzS77F$kut^KP>?Tr0WT(!~t7F#7% zCW~b#YQx!b2NRAVD>FeKYJgMr$$1F5Cv=5l3c2CrAsTb%l>Kk)O8+nQrpDwOxl5dp z%pvynHX8=B!N_O$O(QF4X#2e`@G6vWhC;GKaANBi33ny7JxH~vg|=f|!{%A{lMHSV zW@Ghh5aj+x%T;~^&xhn8-WI#pm#QEIbt2ELKwB*`_f%qTdX}HTIx6Z^EJMea2zN^{ z6=h5P#om(2lXSi7+f7NBS#K4{pH-xbyg2&=_h>wApP6MF3)LB$CCAUBu zSmtb390mdnFYD$_RMARAW!T2 zu>=s4-CoWq{R*3D&U3XGwSBjUAgZ>rqyt?q&o;~LlP>zND&h(Wm^N#_W?TmpY~G@e zO~ki_w!h6YM{I7jNwhzO&`U{>|MT{u2M#LaH~8Z^jFj{OC*% z6ieAHrBLFBbM1NCHZv+mE>blr#zrE2Knfy=Y#sK`tvX#SL9_|@NiYt|$)`_2;&o)% zIBT;L48~0o5DK?2{>UOJ!M<1zL`U+eR!3ex6|I|>apd{c`8yn*?j2v>N>anz=Ab6O zB6OZN_gQ1mYBl$-F0oGv9J-jZ#XMKU5AnFi+005X{>V6m&6_H@^O?Kks~4ukN+&xBKtd;F2H!nJIzb9 zNXg(SF6lc-VVHo4^}h0lsiNVrMs37sAkcBqR)Yt0*-hd=MlyclWZ4QQWTiI~*{uDLCHWr?BhWMEbaCYH&!gOAW%y&;URVlN*Ej-9sLQ#Y_ zm+87N*8Yi=^l%EN5+4va8Sx$g+u>xx7E4UFB&?OLgmnk4|KiAROaAcheEH8-6S6O0 zdbgT!m{ebTl!m4K4D9^eUHm*W-F!Wc04So*tI4BPW5@Q?0AZ8545?RWGLPAD0WS1Oe&_st-*cY#^StkKzVA8jKhN{tx3{(A<&oq8006w!R!~P4 zb^i$gPS!dtN{RMbpU`0 z2LQl@0DyQzNrwZ3Rp9jf!xG9OONZv2Ni1+jSb0RT2>&8MezV8RdFp5o!{cZ^7lD&O?jF4bJmYkP|w-nve;q>X7 z!VRJie#oii+>=zZSNPf}dEvm!T}W3$8T5PlpubzsBT;rjP`aOfmOj^z`i{EYwya&w zo#%hRC&-B79XmAIg^}p8w*~I#u(tZ2I*8-W5)b%S4!dYKkk1H;Hs2n#IxN4GsOvM| zKsy>d+@>EG^MY*LoFE-5trTm5JjDnNU9fR7*PrHO<8}1L`28yIXsN>PpVNx|6SJ|o zVQGuZBbRJc!s`ti|WhtwYP{=(_ncf{8XA?-el z{GFe+U(?wYF@py8GiwU)Wk%&;gO^8(=?3OHO4sww?7KA0Q?ZbltvXfWEIVS>yU?p- z@R*`x>mdl#6aULrVnRMESE_cP2SRvU?KNJcLW2{uoWo!7FsE9-*ee6>HD zd?eAAX6$hXyv(D$aIdyi#!OsB4h*JtM@70zR+#Q4M?Pe7AQy$R_@P=H@Rw)-^!+%K zD(*ZJrLFh6XpcVFE<98>X8UxAf8V`9p8abr4nRohrL*K*qc_X#ytsqTQaffFN*hUD z8CgjGhD&Go_5iB%FNA>h!iW?fkI?oLC;sEBW%DneUyu}e+KC{C^6vZh(4p~uPSP}F z1|pifb5`Kz+Lkcs*uY0PKpQmR}Q3f1;NW8>zfl|*<&2z zT*z>?L*VuJv*Ev@e@x(U3`Wty;EQ*bpV%L^%D0LUjQgWeUXaJS1FbG9so@)(4(JI{ z$w*DRl)0PS%)}$*CnSrg;dtQ5pD`c%%U|8KmtM?RGw$N$(Fx~aV|J{|&((WS#$Vv$ zM4-#riVw8(MDmQE@71pdPLE4L(z>LjCDUtOq&! zxoc&ey+vPOI0lq#4Wtz{*TPqy@f`vOTko*9s-)TrHJBP)J&GPBImlVMoso+48r1FF zx;!2Calj%X>W6|kWu6P`4NThryC6QrqkwD0?dM2(Z^h@l5#Hz8jZ<`lf(7gaz|-j$ z9omKOS0K)FyFJ4C^uL?~x?^VAk~Z|&^GMAO>Ena1ASi}jBjMLAOM*)wQY*8hiV8eQ z_ z^j4Ul%y$J+mpSxEwdSkDI0hj_=OkGf1V_aN>50 ztjTUyM_pGR$)hQIKcsw%3F$O%yNm20RpGqcCHE%r^WFs~LC4$fookIh@afIyBT@$L z#`hL6e?*XHAfC z-E?fXK-kwHX?`Z`d%o!PbWx9t^*~CUsv+*{8W+FJSuM2#2GYPSWTm}Zmd%p6^P-aE z(G?e+IcWD_tLux1nGPN7>k+16F(bU$b`ADsxL+fWT+?RwMSj&BF(uiP~XH$9>w zr7*-YP{_X1`MopH)xhD@5`(AD*fE#iuE2u!;A1@of#G{5V?k|YwBoFXJN7%t0{ACa z6o~slPG{aQQ?>+tKTbq@76!6WawoFJVu(qV-}2{yL3-HfC7nRWxUsziauTp;_mZPN zi_62qV3CF^92iph6R#3ZhS%Bx$1Syk29D8i*!B*5yhJ?kuR}`{ zgpH>Wk?ef37vioc*6z{bYE(l~E)cpYYnw@YXhif4UbLU>(h5DMVlK%TUv3WLEfN&X zbM`T5>mP{-)gL@HQApL^-0Jx}l^eQ3=bYGWNIF&8z5H%$H175s=39x{`_`lAty4PY z)P{85SoFhSVHGwV1g#$ybK#8$OI?yGHYr3= zwfn3l=BX&Kwc+giORp^PELrv1+8pC|NlZhL5XcZxHh>?~mlmumu*c0HSS&qrM~4rC zW=ABVSE%4jF20R6A8BXQu%y+3NN0)ojd}9^>w+1%4mBe7sx)yVeUE>u*ih|nDdbRk z(adebupF)U#RDUds@`Sd=Qbh(Lfk=Ywg#3Y#+D@dhbDQ326i#v%LA^s!GU*Q*;m4} zc_uZ)s0NfPIx&}YG~+Vgt~~x6>9zdb*c0Ep?iuOzj#`y7)ubE#*;vFg*__lJbG|PP zCPuIwJShKOm;hc68U;|~oa7~C7z$AKo4nP0Gmpqt2xP}u($eOX;=EAP@>E~SQc$<0 z@!pT)MV}eLTn{g@Bq_q01@PYc=2mFlX1ODEFR2}wf11g$&B>1CbYL1) zMzQMRPK5pk#5Kps+M&SB4R$*#wdJB?E^nuO;L_47WD z@{HrY$l;>g6HidBHY!z+^v%9TDtng5nnV{S5+i#5xne`CqWYqiy!3|fHNGk@Un4&y zeuzrfgGRMpGf~%io~V9EKKO$YvqJvg?bpszvdwMti7?ku%NJ!2@Ph7=YL}vME-}R9Pz-X6#e^cq|MA!RBT<~ zwR!HEovS{1rDW9Wbq>Pm3E}Gi6CNtm`hOtvD26rP2R%R;vX2K*2ST&f9W&xQjkZtm z6xYg0fdZ*mcf#NY|hnRE@6`K1DH zR<0_|grEP-^*bbZ;}9CmN@8MC;`qw9xt!Ia zt*loyeLFL+hXtcvU=1xJ75S8XD@zKM_W!wHtox?oVuVDcUfrib*}v*d-vPaLox=GV z@LlR*A;9mlRm1z;yA@)@;NZPe>`UCQzF#~+qhGBv;!PRxxjA`CV4U-@6VOIIR=4#c z%CknT*M=oivONtL$WTO-BsZ-mO%*)h`gyh#zH_F&k-tdLtnYm~35zPl~jl z?n4tE4}*0KbTYrBh@y4JCPQ~m3f`Sk-c5gcyK;vhm-FFFM5kO=7V=&*tZ)oc;+|tx z-8Y}nnyKEaum0?P-p351qk6^GtIO)-rnlH%I{CJ738vye=jGJuH_&^#OWpO}q zI|%U;Pmg~9xVOZEGG_PuKAY)QwCxoT+ugQ(712k#pxW$f#S4XRHExwlUOR6(E-iSj z8Br=ko?Veh&q;~*EQ`wwtc`4&fM+rvGE9=B-2vh<(j zE-a+A+i0FhNQ%(e~IL5H*-<+ZxYePf<}b+lVhJzXvXi3hm76|`F|lS0u4a`9e^4`kADBp32g zyt7@WLzf?mt`$q-8^-3%qIzmRLQt!S3jc4j<$Lz}c>*J;FM|-tjuxh);}f+%HF5c7 z_llFgB*Jqzo9_sS#p;9(rq9%|>v`_JMR_OZ6)9b)LM6J!0}Hpl{53DJad>HP$Wj~h zy5jcI3q&(i@2(z}Z5dhVC*QI0Wl$_u_~o=!B_3nDr*uOgGmyP|%7rv>XQ@ek^NZ7V zO~>9M*OHVf{^saePy03btDAtTV+YjJj)L=fCce##&#}Xrr1z_pat01`I5NHmJ`=IA z3WG}eX8?`rZ){LiMOL}cp@NKIFE}ekH&g@g#k7hGAq$a zD}5Y#b4I~=1KF0dq_P0HpRr?d5{4``eZ>$OUzok9FdVgVZQlG40s_!Qv96YrCq3%ij=WgPh zCr$+f=|486JDj8k2hc-^K`|jx0Bf9;4HiehTHAVA?ijri@8Y4ueMfN3Q zOG4R_Wr&b9J45!L?>W~w*LD6l_jTRx*Ymue>;CWg=YC{<#Sq3O%mx4e%;>Vd#WBzS zYi{P_Ir^hA`xsDnj2Q+1KE$){-()(zOWe9_VFm!9G5`>H9{_fbSCMl75QqYR1sniq zqyYe&kX3tC>-d4$*~C!)n8(`DtBW`WE8+5W|6}6*%d1`&yN?en0Y+v9EE7zkaAi3W ztFRRS;CN!BkFg4-FO7uUGrN1(wl=t(MNAsaoR;CmzlUBmi>33{ou~Kr4Gih=*mV~1 zmV2-&U$ob#6jT&8Si8j$$1A`?)R!0jr;<17%jpE|8uxTv=SzEk4>ao2=e73xLk>f_ zv}cLkA-c4jm7VbJsmLZA>Ldp<`G2r#9^ z(bDkI$!}BN=3siosUxbEZwkJ+qhR}x$&9N!vi97DM^FU!#JZw7tG?zr>nALa8EV=H zZrc*A#gWy$2?FjuRdRuV8f0h>ORy|tkLB=DBd;yzFZ)K5=qt;Ob%mItJPQ*~*yPz) zXHES{#9iY9_S0m45PCmU^87w;8^m6!t>aH*0X@mClO;1Oab|oM2lN|{{T;3)Nf>86 zRIgxOvTLe{dMd%0A+X^JSgD|=5KNKiOW{MQM{{?yP%kVxA|Lg^=2Zxo?m-h$JKi@C zSsm76xD1OV{*2%$PiJk z#ilsxtE5-WmbQ@we&ze>J@)BukWBu34ZwJ6ZuVZ2z@4kVhJE(;Kd@3Nzl3cp2lmXq z)-9^Sd{s45flbazfA?#U&T~1GYJ(7e%@&vz-nWpTmw!>=Nqg_+#f!Uj^1U7-Ua<8Z zlHxWPc!4%_!kP5ZG@B{Ik=t^Pc`~x5@t$B$b*BS5FXrV@o)~0xg~`UqP!9sNL8683 z76FUvvChhy z{i8=-M-JvIBc~L%8n`N#^K9ySPxRw!R;HhmX*O|IsiZX5(56ie0@f+8!No3a9wQ*r zrK|ZF`dcaX1cjV-N(w_1_TV(ob?a{T;S|8mw0GuF?&;4gC268VE-sJCaAFqYu{rE?s_TSn9VX*<_AHI1oUt`!Y)Pp+sqcg)>JOrnj~G5}kj_(a z294wTm77W7^FIdLToRhjuH6`fZ=r*tCi_dyaC~8eS}(CK`Rded)npQs^ z+vO{is}+%RIoH_6np91uCmNr1Y#8y#WLid0;&k*iL8JXskAV1?k|((zekm0)zCKr$ z_^G>?ewE2wXX*C7x-6k)QG47U(qme-VAGgn7YymkQ`PR-hD3+QHhwJXcIk2VXj9lF zA7<;%yY=Ad4agCW8+?zyu{+x1yysF*eAD|W10Rd>GAyf;JJ&NuypYMyhTrSk*zRh6 zo!9JR53|V9m|BibG2;(oSqPA}Ci1x4EsR4z!^@f>ebagj88?`(r*>e%W zF#ht4YWF@9f~u!ww3vWI!S$Kz4Pe1J%r2T@+C9jQ2;z8JhCvKB7~r<8N82-N>J^Hp zRym5-&8wx}8hTiMNq6(|_Tma`X0IEo1=^LB@YC_+{r<`I#PDCEpZ2qB;6s(c(?l~c zF=IAs!BRq7F^{-h_bYUx>+5PNdiZ7CfITqKTagYUq)g-GhKP^(Un`_pJ3{1EKC!<_ zKrO_KL?PHdAvYhdXR$s{dfxp)2ju-&kXi>we_Dv|846;fA5ssjIo}Ma>;7)Mj0(K# z+e?$=FD(4|^){%rOk}r$!7|(GvodSYV%baE@S?Gjyy?YD*$B!wRAB2Id#% z+jb&uvm6zM<=`_w+cp|+&n|-n#;Fm-8&Uuf_}%I!8*&DjQ#DVYw?Q4YsEgd{1`UZ6 z9pY$?VUhNdazb0|9d#1Su{398%FAbvx&3!z&#$SMXyoj9i_EdhUYsNbJ%z3?B>RWi zat}Ucz&Iaf^(VW|Pvr)W{pb=(Cs6N>&U|`mzF`x`MXe$2`Rl-ny+Jui+OGn3pdCk| zqLbx9?`RnxLo=8$MDn#TfBxjEiuY>J_rAe*`-8+PfBWhrZeGAWdrOk$H)VO#Gy^SZ z8CL=pF*KyC@t~DO#c!OA|Dz1`AoAc1C4w%BDzsk$4HY8@#0Q$FO zm6asy#Et#9l1mDd?ZN;uD~r#rF~`)#lV6CmL22}{2E z^ydUM#6=x3fQ@`MNNkkscaYbD=*ZB)i6$8nAn$rg~&S;a? z>j^q0ja6GemqS>Zw1*7_-7qlf#!LyGn_F0EYXoPj9bivSnL>rOJVBWF0gLqvXOw#= ziybzy-ir0d0J!3HE0Wu0O;qOepcA5XXP}{dtx?6wICAHci5O{nKHmTkC+I(h+PfSy zRt*5zP#RNp_`3(GGI|Wm?xUCW<_O=086?^N7Cb3hpga)mbkahHvA>*K;@R@~)*}|+ zZf4S-RNQ(QA}OF`rNoPlMKIlK_Wd@irra(z?5WLZBQ23!4wfaG5V|X&hWR~_Q$DC*Lj#TKi@XhqVa!a)X!Eo zz!IzY&nlsJOc~!Fl25?(JUg-E&^Oj$6^;_9t3p|v{jcQ3K`k*U-zc<~j=g^9F?nnP z5K^87E;;S$wV^C~({yxEhNuJe>)4gkNQ=D}RQnS`Oz^W(fNHJbG)`RTWmZn{T8qEh zzNcy(A^vLL|Hoky^&V(TN*ZGiS-(>A!G-yUUfh64bI$I�=$Co5EvpO`aoR}e=I%dm|_8f6)aj<8VNybDn&%~~8gh{v6^ zdWy#a(WnhWZiE!K`;)|L2AnLf@{9Zf;3$JHH7_|f;~Dygz^Sn`N#~C^hi=9!mKj{V z9T)`pE>|VpMQuX3V*A2@b4K@j1?B3;Eg5?SKg^{$<8QtyoWA~&qw8#SsiqCGj@(GNQ>gR%^m=^8ZmN^a&@XF4_@&Z3`*1|lyw}diLKf01R}P(!jw0l)OSZ~|Gzd-k=N%P>&-H=O_J^!8;>H@%A+_%r7?@{yx;TbZ+sbvW@lG z-Q}!Hrv!OvLWr2eW7djOy_N=P3T|)qGhG;>q9 zey()wo&#?iUj55Rlv~_d*(3JMFlxqeAm?#KWd5|-$Is|)f9%J&zt8r~jtyVz|BAm+ z&D%d)bAfF2n#AL+tZ`K(&z04SWb!ipAL03@qrkrN#P)=;O_RmpkR|u_&CA>5 z8WsP-XUlSzH5upI&YhL~eDsOC<(tJeeD61KYU|XxZu2<#p)lG#yz#2`r&mpnSC@r% zvq&ZVzCK4#bI#u9udn8Ju)IpHzCK4NGQN0ELV3uNw{Ol)Db-BgcluM`nUDVSJi~9i zHQ(myby@s<-M%f~E^InAgJaKj3zP6AU%H+9!}InW|C)cg_+`}pXOinTbl!gX;@C3& zikUxkWa@TRIv?LQ&22{A(hsW_Wp(@)So^z1l%QP0mm zla4DM@8-*#z?OO9AM4VIt1q##HAixleO#N(Tw739_;i=QvOt%}_9;gmZjC&@KBkbZ zDxCkzSNn;Tdt;{FZ@8bS@?yUY3ul_C|Gnv7%j=Gu5uUhM_P*ATv~Nu!p7Zx`?>S#&)^syvpE=_L8{a=HESv^s z+bgwJEJ*s2cs%|Pr~0AJ0wwmwcP2YnO_EMOuRB&dO+9kz8n3Y4f2wl|d-u40HN4+% z`P;)Jb=jFImbTGPPq(ZW3N8C$e-1V2g3|Hh)W84hFYJ^Jhh_*+)_6MUKLcw~!Oscq zd-{PHSGB}7q9i4;B-JXpC>2OC7#SFv>l&Eq8d-!G8C#heTA3JV8yH#{7*rg3YKx*F bH$NpatrE8e&iS#8Kn)C@u6{1-oD!M<6V4Q% literal 0 HcmV?d00001 diff --git a/res/img/flags/SZ.png b/res/img/flags/SZ.png new file mode 100644 index 0000000000000000000000000000000000000000..2182f4ff9330ebefcb10ab7f31a4ad77b114ab6b GIT binary patch literal 4133 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 tA{|EN%rAz<- literal 0 HcmV?d00001 diff --git a/res/img/flags/TC.png b/res/img/flags/TC.png new file mode 100644 index 0000000000000000000000000000000000000000..3e3e19d4b3cd6794aa2d0f88df3e5d12b263aec9 GIT binary patch literal 4631 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/TF.png b/res/img/flags/TF.png new file mode 100644 index 0000000000000000000000000000000000000000..6d50a0f544ad14e2da315e53fdeb187d3c8781c6 GIT binary patch literal 566 zcmeAS@N?(olHy`uVBq!ia0vp^W*{uU1|;uX-8K(Mv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffzx4R3F27;f?yX%1z zXMsm#F_2CG;}6+R=Yb6N5>H=O_J^!8;>H@%A+_%r7#LMOT^vIyZoR#|-pj>NqU~e( zkyycIoumjJqZ@lTPbZm3x(Xc8kUp~I;_VH3aR)VEXouPVTDHYHQZ_R2 zHFc$JGZW|i@dVlc1P;oV%B8(Dmrm(eCjaaHlR3rbUV6{}IbZ(5>(J0zexKQzOB+QN zPw(B%z4CIrr2ab3?XSbltILCy@87d!gX&QYr}X*1O@Fj@t7om&&I~;-1 z9RK$I^719$C;$H399Mu6yqPX&4QEm-O_XRtQ;t_?JSc(Cq7@p35iEz42>tX6I6`;B>@{NAg z_KsqVqSlR>gSCOT<s5(1a z<{O<#wME)P&7JKpldNS$KbYGZP-R*PZZSRq69u$JiRayAw>n?J{E!c8#xak7$vlXw z)=CnDR@?p6kN+*~%W8j`B+Rk?yAz20Bz+NBAGvl+mKxV8`EKK|FA1sc`K7sUc@&aO zQE$DX)5{L(PXI3N{y|I8vaYdPWMoIVVO%N$T6FMJrfN>Lx$U>vKx(6gk~q)wOlU_B z2q2i9b%2a6$OsiOz-nkjYQEH{2(5N^> zko1y1e!JBgX%Akt57oOV zqGk3mWm^YePr$-TR5%?75MmgBVP?YjD5?X_D6oF!6pN1sgZN%UZ*u$F+D2WO)5@?o%~GWyTe_xC2f&d@QG<|NNV z45{aCDsMM6>e{YI16#9z9v7^W6em>PwLg`?tQIqPgnim9Q8zfdj9_LriydP`uH0Al zrz#M?WE+NIdj9NrJA;gOd1BgW8n~THikJX9i3FubVUVSDR`BT=FzoLAMFq0ul1ku9 zoBzyJx7>_I*owZ`n5O!)CyMeM7cff{;`ce{rb>3059_|qIVkNTZ&#n~XfJE2x?jR3 zB=}9OW6HmfFYL?J)VgI5k9|`~t)1Z_CM&(1g1TI*y>+>JELE1kpI)KfXtaCs=&2%u z$X^icGZr};e~T=eu0*Ivv8)J{lCvg`WwEf4)=^EcYQZ#kbltOdOv>j{*|0c>mgij_ z`MCwP>x#$HHxP*!QGkl!FIzKXlD6ILqjJ*jWe@$qNGhVr0Vx7LGT@YO3 z=t@;-2pkhFz<*V8zwB{}_cyLsl}PTW=mH0_W{UX{V0o2`r_p*u$5#Qe%E=B zZbBu>H|TXqV+zR!^BOncE@?|n<0im+lw8PN=tSZP)m`cP)=t_Nlq&HqsY2Srgp2c(KdRxbR(PmmyGUIS!h@TlT?$; z+#b=uMQkepZgBKmP+y$fuXlvn?v0BY>vqo~rBE)_Ud#k`l2k~vRyZb{CVWx01+Dr zkn{!D@K>bYoY>Fa3dYok@s8v1B-{PP9Fe;L9f0z!f={eOeNA6^uW0a%;c Kn>CsEr2Pl{GJ_NV literal 0 HcmV?d00001 diff --git a/res/img/flags/TH.png b/res/img/flags/TH.png new file mode 100644 index 0000000000000000000000000000000000000000..0c884c329e1e463255364f44f2c4ba4703e567d6 GIT binary patch literal 764 zcmeAS@N?(olHy`uVBq!ia0vp^W*{uU1|;uX-8K(Mv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffzx4R3F27;f?yX%1z zXMsm#F_2CG;}6+R=Yb6N5>H=O_J^!8;>H@%A+_%r7#LrBx;TbZ+^X(-~Ie|8;+$6*2MnlS7Y|U)^2QTs`YSwP4sX<&!U~BdqEKUKjN*X1Hu*y{z2l z{^41*r(++@a}#`i@1lTv=R(c5)2fA7_i#qfxM#T2Ks`%5&VI-8K!?~hr;~~jZ$2q1 z$p)FG-Nn7J{>9wM+}X=-xodu=nASnesa~+;j5(J?m+l-UM#%D?+zFTE2VAv~xqz<7L$~$M)WN@S4MW z%e=kCznm@ZR@4>Esh;!T^^9pZCq3D*_mlj?Z(aR8ufBCfZ!Mpr@!f=LhM;BO_r8;@ zH)p>*nlq_diZv#-YmthY__g!f%WrGG%bZf6%MJ9ho=~q%!TCiE6Ky?imE8a6bws}4 zi6O{oe--C2=7++ffWcuwEpx4Z4O8kDk3~R1)e_f;l9a@fRIB8oR3OD*WMF8nYhbEt yWD#OyY-MU_Wn!RhU}$AvP;uy~EsBQR{FKbJO57Sa=f^gJto3yDb6Mw<&;$S#pf&se literal 0 HcmV?d00001 diff --git a/res/img/flags/TJ.png b/res/img/flags/TJ.png new file mode 100644 index 0000000000000000000000000000000000000000..3c9026fa0f0c4f00dfdbf89162b8c5725949070e GIT binary patch literal 1647 zcmZ{kX*k>I8i(J6AhEPFqLkE@mZnG}2>zC;T7uBiNHs-C(N3KPQ9+q85!IH1V{{y< zV;NmthoX{Z#;&-i*jh?0RZ+E8ijFG5IRBY%{czsvd7k@u-}m}`z0?2U830s}hs$xs)iLR402_N+t7Ub!CvqT9Bow~UMt=0q%{YB22N*m{%}_d|bTIe1 z>wCjJ30-TkIE%}_hjlkcoSl@k3fo%P48)v)8|aC&u8 zpZacZlEAxfd1fhowx=)tleDLx2;q7P`*l@3u;OuQ1Bv-wp5^Lv!x*T@=aKK=QiL_* zj2*lVEf9L?zUPSfCfE;t#`o>_pRSH`)2Jvy2ei$1(DVF@@&*iFKq^O>wkRyKXvUW` z)=nu`PxK6be@h3`rX1I?sG|3?lIZC(isOh8LO`4Ti2OcT#wyfek9UWV9>i+-Rp<8w zAE{-8#O8f-X~YACe8a-OIJM9;% zlC+JADHBPt>E0rQodXj|-DaG1=;HjxSGT%!GdpH$(B_Z)-<)&GDr*}Zd_1GeXJw+x z5gp#YL9dNpuk+nD4n1I+!kC9ByDz8HSa$0oZo{GAGmQr;2HSWrGw6`QsbqQtsqYyz@u zWJs1UF!HfwI+kv@=036i;&bf;d*?49*)b@POUPv z`g{(HYC49`jLlHkr3_X!E*~t`!atZ#dNiHB`nV%uXB@x8JB8h-6hfjie_jx`g-EAV z)Gd)iJ>O2BC~_+i9~D)~wFSIP^1U9u7UN%-)I`uNlcv=wsJwE_CPZ2hhaLOZlA17` zj}Ek4Exj@~Jo+#i&W=8`zni(U(EP4oFdcF0Y*jWocFZrf01DOP(6AJo{9B8EUDo6) zy}})3OPN>py;gi+(7dJ!M@Qi#!(6r!{IBxYd#YZtRm@$R&F>R zb5y?6)LmkKV>+y_Pgm~+5 zAF}$3&nQwqZ{saWLL2l|bs(%`lbeH26P>CMak{$`v7UtP5+V0|1++2wn9yxr{1=FRPmj#%m0sap;!lA=4;#iQFVh#CQLV(I3<%? zKA1TlSM7jmVKln;xPacMU9=N*(qHoZV%EdC(%20^tua%4!OJQ@;BKM$5QrX|Ly_k@ zF#wYi!HBMPY~Sv%ZS}q>dcAm1@7GP+A25xe{qQ6a5G{vXb>7zO4Eb%TUQRr5ehJM+ zu$(x>iVNr#H!;5qs`Bq5!%plDg%bScHf)6W2uSydVYqdQ-kouF`FAV9shXxGq3;7= z!-N=IV`^dUt!4{8?foxHnt6n2r!Klt8`zy!5QW$H+GkkT&5|AEi(N-439JeMEZ;+1 zS0*>?Jof?=dgTHPKqi@6n~|){$TkeJ1!QFoS&~dh<`9W=wROhft3X6lSop<+{~th? Roa4g*;Nj}yQt8Y}`5!=o(?0+J literal 0 HcmV?d00001 diff --git a/res/img/flags/TK.png b/res/img/flags/TK.png new file mode 100644 index 0000000000000000000000000000000000000000..fd605749ea4d64fa780d884cf3659f6c522090b6 GIT binary patch literal 4829 zcmZ{oc{J3I*T+AzGh@xZPa<2^vW5uR!q|;Hdz4+4Au~u{C6p{>8xhl3vLsnz24#;5 zUt5-tT_ii>@q7Mzo^yWhbMAfJ<-GsC=iDTWsXil;7YP6WqoIMW#Tk|U6D;tvJURS6 z{|r!XZ4+$(s7^&4--4a>Xmv0-KE$x9OwIQQ^*m$dLgSCB}tcmw|}qrw{k zPgNRpJu&P_29@#hZrtu3{IcMpS4z;Dm>Uderz1CB}*AlIS5AVfq(r z2Hl^VHO6J!Zt-ab5|&wiLZbJB0Oe({ghY-qGjFJLML?sr^TEsSS|tieh{)Gf1w4$w z-ZZu8J+wP2HM;;*I;7`CTRNG(>Ytm9PrG4=;S}n+64jTVL{Px@(z-6IMzFlgQ@ID7`a%cEE7`gg*!6+$1lvme|dcKup7I9AYWf+ zsw)uphSVR_+k0ze408-4DOxUkX|afeSqgYY!JKmW_-Wou#E|&i-(dNQmpAC;3VNEa z)+jumboiOQ$C8{gHPG50$7|f!&@!o|MbGxpr9|c=|O-On;&1o zz-B})vrbv^MMiR8JPGzx$}tP*JJE@mKu_Eg6V~)4=l){7yl@2(EUIy>pu?nHll~=ee=FLxw-%8FeQd}(q}a=Zuy+wf4k%)O@~Z{0KW~!zO01 z^l}N-ibCJDyT4z@FxI9cens1JM16j5X!sK3n(77Lckt#|(j?-R+k^R&&1tk6p^H5=MTf8AzpKfHp;xq$_SBtjSr*lk)fJfF{A(fax4`(g$F$GH zU!?OZESMx@$8o5(g3fybJ|K%bwlYRr>hzJDBm7+;AYb8V=3TrO zOKJ!T>!QE8Vrx(WR_WnUy@%{7%~V(+G-&!c=`y^Ft_wP1I|%d{Y~I>>BlmG@^Y2}E z>Whu&_7ueFUV~^T_tM*)NJC)GJ;sp+y5q{M2yjDP-&Q?*WAEBs67|^AT_RUZhKsJ92NEqq?B3vAnjWbzkFk}6lq{~|go z)Y?s9+t>Z0_w6@z8=4N;JIwfVYIsLAeZ7tn0t%;|t#HUTP^X1M@;6WxZIxY@XV%EE zRj3BFVk5x^fV!?96S!M}nUX#yxflz1<<;nY$OIV`u;z1Bh#94=qVApWkK}x9W+t{+ zna>og#eVaLLb9IZHo4K`o1TP#(X0}cR#h46X{>njv9Xf>1DCNQy|a6!v|@k+fh^~ijPz- z_)4Nn0oPm{SIKJq^@L+I#^ap`V01GPEMuMi2>RZw{1o$yr!R{bC{+Dqj=JEOI&*az z!t#Jm4g)g#sa_ATMLc7sejVFN{&=o$ydg$ik)kNy7(#>FRr$^*Sr^?hu&5tCLIBxG z0PPTK{I_W4A7#n0e(gPLBMU7ictTrP7&Y3RY?*(v>i4@=43k`-3mZ;mJ zZY9fRASsQdh{r8UAkcTV-_E|Evk5N0TbqM-^O(N%(X+$Hs+z}kDOldopqdC20+N)JRv zackXV1{Qr)1&LjO6k-4QTY4vLS`h5K#pVUv6UxZ9{tesXqqq?%zuQbHyf-9pi0p}& z$9aqR^%0FI`I{>zqkqj3soNPs635Z!0+agzT37jlCL@#jtq{W-np z_k_~{ua_ynvsZ}#L;vsnzb(Ik=qGtxTCyWe9&8wca~bTE2{YG-m!tWSj%74q{2b*x|Y+>5EZq( zVc)G(olaW^kJ5J#7k{tH`DGxaD*Q?jWK2`$ zcinF@t!)j`KG>+A%Ku8&heIW*iN&jx=BI%v$PH^66BHHkjYCySGSJym9!3$*Ne1K^{xjx(voph6lF7k6>uR*K(L@AC{ePzD{NFTdbIhFiGLgE%<(IpEECA zfn`m`7-Pwz#!#@|ZG7C1%1d%gtGzYc=)n8;!u)Cd(8u&QaEn&(T0HWXAWrhiNjbLQ zgNNPe8sG5YDa_vFPKHA}MBR_^{Vu`1WzG<%kUiivz*GQ{mo94U4sS=iH8YIa3yY}u z`F&mK2Yg?YiSkIsrzjup4e4aSiFO5#5gz+FU_M1p{cSyOnA;9YvHCdK0xO@NJds2S znygv;p3^(Qdaxv3b!Oigm&RC0(wsLPe>v{hHn zD2Lcf35_~OrZ2k={Tt@N)O88_c%{+o>^jAr<=Ge!Db=5bv{PSpvX4UoSaG~@5i-> zs_$zzt>J6lk?F4~|56*e1sq4C;*``!1I;!g&DFrl_c3~4t}$`-e_x{rK5g+zo9gyX z##~@|T@26xoyJLE@_7xp=pinl+Tk(uM)Mu_t?hWvHJPd&Y&;(P(D%Vf=VE)tV=Ur= zCRD$c^wd^~kmoOpxrLsyyJ4Kh`mAIZSXl|4OSG8ki?ly+G{Cmwe+x0JA1 z$<8IksmVoQQL0-sa*keIRm^be3v@6Wfy`J ze@XqRjVq|a0{h(zC1$YoPec>uag;Vr(`Nu)A>~@URE}2lF@vwu1BoF3*N2&2txx3_ zfUs+g?yIkp0)G}gC|&fv{%^4C#>OfE@+9?|Vo|0i5kJ*6w$7OEK{rw zK{_J&<7f@lLL`3q)hIn!s8+BTdD&Wsn0!-MXr2lC*%&R#Qwoop?<&Y+co3-IrN>gY1)<~&)&pp_Vr(HlRqBx!3s?tSUt}NckWDl0o(0SNHJ@mw# zC~~&7Jdkkc^~9UodXH96#NQ|(i7ww{jU<~*{NH*TNphd;xT(UUo<~_S#ecOc zsAeVzmicx6>zZp>=E1yVqGmh=KS`$9>=MqekWN&&W&PfU!eh$(g{3HRf7=xp{^t3X zeq>FqJaig^e!hP4Q61j+w9+jAQB?X8T}HJlVm7)qI2Y!GgK)3z7-3=Ja?rE9lIndH_S{1#0x1fX!s_X4H_#z?JEswA;H}k{nu!i%WI5Bt0%e9p%{5 z0*uILfK%#!d!a~enu!4+DSR>h6KAg;(NI0RP>)-oo@(yFo@W3QU6GTLlUI|Ii)dTW_&>4T##p0B)`(Py7-fsGrLw1NS;jVmkWqFsC?buJC4-5wucJ|xL6p)) zSrcY7{48ak#yZ^T{&nxU=f2l0QfGN8QZd{`L_h2 z>~VaksgMmY8fk$9fCfCzE(*e4%XpgES^z+#0svqW0brZGg`ER{FjW9pa0dYGTmTRa zCbZb-vJaphmoFHz$<~%pYaAQg!Df!3Y`XuuR{Rb7*b^A$qJ;@;3L+t@t|)F7vkU<6 zp^L^yyYR8au{gV{S0~@CZk(T;{K$GOfD|^qJfB1JJ!U@N*kdmI8LDt4|3$@Nn*mbZ z?)~TG^vy=hAnyee$Y80ph9HcDP*Nt(Hw<>Zi!@y4){u|mkiD)l9@RJ5C*9SbLMR;4 z_=qN~Z~s~f`_jBYU};57P}-vsdcDr%nJZ-eCrZUHzlc^m{a5x2rquNLR+E2=8@0v6 ziP2#K3t^(wW(%tZNmB0nmA}FM#1Em*@gZkN^|>RQqQJ?A@uS>+#GyNvASNqFxfbY`Agc5dR)* zfpP}83S->pm;GTH};igK}AmL8P^0WY3=5rd@g;xmNl}vJ}xk+ z6<;gO`!&H{pg!ncdc{W0FB4kK2R#ciNNg$=>5V;n(w3V;&E=QjIpTo;=qBB7Ai^{& z#Roo@Nv=@>YZXsPtfM~Vgu1o#^Y_$Dw9iCC68j3pQLH1y^u7K*SKeXoh8*(2bc%Rc zd5sJ;gj$)63%6?#VAnqdkam zCma6bBtlVS9K=O#U>So+Oim4@HfqLuMi6Qvkd`;cD{sd?TI9FAjC>&2=!b@G8jpwH8Twh`9eLPqvifWy;K`K~45~70y_dr$8D2 z99%QKGrSKQiOXjljtaIo4_rxxNVjka4##l#mmZ@rn^*-SdmhtWka@9I3IK8yp znstcNUU#$lkK|9&m9{&%a;P3P(zg3y#077{aw&C*xlH&2Ob9tR5AZ;v& zeDScY;n+`3t?OYU+1R;mlXwGanaj_x(Y81%=8#MOz}}17Ej-baTV`o!wYgM+CJXJp z92!)xDQuiVO>5GFyPTXYBGqu(2S%fnMZ7k8F8W|c?y!=`9&h1;HWwt5XFQr6_)$f7 zV?>x@~>QwpBW-a|9gPa~Oy1S5pMfkdOif+OIn zbH}K2aU=G5;Jx?B)Hn}ko`R7tR4-?+O3?12Q&9R>A1u{tt6i7@=ottAazkba+oPWg zeXJV0VIcj(o39PtQ#0LiJA_A#jvDMvZ@yiXHhjEuYx-@C^&^b-Ow}LN?6*N~ia1c~ zWjCgIV)X&P<-|T8QgX5BeaN2XNWvY)B_Fw7*j zAj1+CI=M9C)7<-W=1(!mv?9L;>Iyh=!qOCw1u426zGGDP&`R%4q=;AG#V9RV$&9Lu z_yjlT&l$H>kkN!&I`qMz`4^yf!mD($AFY0)kbPH$g%@^uORU#tC+MvFr)niimL}K_ z*B;w(;C5k0`a4(iQ4h#ss4kV?UHpkcmlWTS@&3{yQYmYHEpz-B+t2<)%MB+ZJYJ9b z|3)yohVZqqm_H>!(No&r9EZmkE}9aIBp@}cDHs=GQ;XKx)s92GTu-aN997q{7e*@& z%`3%?C)u`QQ6AchSd}n-#Gy^^?zn~{5{=tAH+~#ltMH}-AOuNEkIX4N<(J%=wZX-8 z^)$|E%njwR{a-hPbDxy`QxQ=UXrEB^dI*p%jm}*|!2{-+*>ARxmiO1dwi+upmY0Ft zmWdIRuslZyKF1*>WqCLw9WZUSLD^wfxQkX2$oVF8Vc)f#Y{j#4lH^&lyUN|O*NjJ} z)U;HUR!n5tQKeZ#y+lDg2jm9C9@~hNYJiVUwI%h^93yG2TJV!pLd3W@oZPo8h9*D` z_@xQOASG>M$FcajX6|9xF{Qfer|6*2+-?c?1E~&!%&yE@wpGftuZC4F9OSi-cydnT zz_!KwhDXP&%&T*o!S&Kj_#Zc^&}6h$jRJ1MybfJ_74tM4`pTj$ zh0k}|czs%K#qHM9IM^;akRwW6IpsmQ@1_iKXLgUswEL(^L`wtHwJ@ zH=c*ys2g;xpm3V>ns}xtMALUB0aLQ(yWi#n5nU*$>zfo;5u^((T_Fj$F=sqHB^|2b zGmRy%<8OFqA<}xs@CIoew5xGY4P7^qOQBz(d^UEkIh33W)m?w-_)|B);L5s^&GEyp z{Cw^Qg4XHpsAE}oN!B8UnH{~QN6*qfVbh6UJ9Q9eQNIC0yShj2KBcXNDZO@Ns3*gg>aYnUk8AgGJD(AsN7G(D9& zOI?xVc&s&&;@3I%4|Z)@s1}F~QdUNo{4>0Sk6;wdI~M2_d_HD^Ejsl0BPr-Z=L&y#4I8 zpp|{1Z?=vjy9YB?*ObbY)QQUvr*@M6*>AQs4Cb^_ed1Mr&ryi{kXFSM$Ud*i$v4O2 zDHZ7zy<+x$*MIEMN*<9C_0f@Kqx#R_jUL^VSd6Y2g#%IPo*#5p!#F!2>k!e<%k3d9 zwu^UexnZ|JPCI^BHW*>=>svFtQ^~^J0+JsYSiS$PvvYQ;&hW#7kPg1fkn)dbOAT2J zmUxW#)1~WENV-%oUS;cf8@bsj?jYmJ7hZMZerppBVL#)XLQ(#O8dF^5u!;{VKkyz% z{_;xstq9PnRJS8Xf4Vd38Y9tct?ygM*n`}NTb-qwDu+jA@#jntzj+BS;|gh?4i2b+ zwsEzsQp2R5cM9xuRk9-O!2*q*G`IVemC=drZkV`d$PMoZ$$F6pG7gwZ&Z zd-9Z|V7F5rgL64pC1c=WQdxI$##eI=<-YHETj>bT;nb-sw2{nWoqHNxcb!Gr=YN3_ z0>8x`wNf0Pt+;lRIV@9 zaKhw5m|f#99YOoTx1V=x+^p~8i*R!8BFEg1Ao_f;8DYww6aYxgfEScug<9HWiGHL)dTFH35;`P%3?4DO1W8#4ELSekMJ#Trl0i01)JFBdUP(E|c?u@!N tLQPvk^^~fbwyJ7)*NonO1phR&={c1c~0Gh3I8PXLUgme31|m!iINtqDG5)-FyG~-I?Ee=A75_JZIkjoM-0DoM#4lT2vIQ6aWBFY2Vc_x}xmAgBE&~ zr$_5@uK;#I-A4hyrxePwhmfl~-0`l_eEt)31Q!X?^MHoM=M;Zm5ZP4yHK3w^7Ka~)D` z!oo??M~C63C{4kF8CpsiFV(HSbD4d&13$MA4(r!WTJa zw+ud5+)vBQ&Q*2V@xHA&u?F!_{f}wYvW349@zIXW=3QSel5_4My&Q0lj{(*D;bf-h zo83#`sszvgs3ofkpnpa^?NT(kHA7A=EQ~vE8J@H2nxoCd?i**OK?6z{J4dHd&kF|| z_o#M=FNip2csldKuX6#lfUxL0*w3vVE&Z#cFKV5zBKRZj+#U_5qwiGxudCcX?i z$nQkrr?YK@oTO!&!zb1xhPQSeOz_M2(RD@G8~KHQ+HoMx>K_R4pK*Q(lq(n)B;I_~ zFKjlZ(ze-jr6P4FOjYf?TMMuoo;%!37tDh zP2d*0*A(JjtqU=qr-LEvZM7bHigQ6hPuyNEF`e|zSz}d~8vuvcV-tU%{x$nB2}930 zvvn*f!)aCr3Bgv{*0>seJTgpp&g#yx7x~?J(`s{e`Hyx zrmzcD`Xv30;GgbR!p-CFkg*##c06Xbo_B8!W^0!o>rO$g!6ig=@w>To-{cvg@8cuW ziKIMQmQAsL@R+z=tP6kD^NJ=ix)ci)8h48OI{nS(W~dpe^5G$l^jL?N!Qieoy~mE3 zI69Ccck?1LYd4)ZAD-qnV_hU(*p4WH3;;4(zGcR0-2c>iKD!k$uD+ieGj zs{}FJg=cSQM7e&G_)A)aKVe#efqYjvXb#ls;mO$FY@@ zHSt~NuOwOxt3vNAXJZzy{;1|c5r*eZn-zOQ21ic<327v}<5MSm8S391R_ITu4a}b^ zEcrTSUPf-^ZP8y+(vuw1>dU7}{0Szpj-Oo7MdHObrz+GQ-aJ{OoH`m#ny281RuE(FY*_Efyz%E~T=~@hU79Ubx3cqB- zbWUZ?6O;3?y^biEp5zl5`>q?+KgLn|>9PCD_Q5*ZruPjDm+sc)#Saw31l~CS>Wu^> zxvFUOD14H2*%!RcL%96Ysq*M$oNg+RbS4Ke!*o)3Y)tKOT3t=4u({>bh|QW-pJtVT z#Tk}$=Mn`wWQFqX=cB~bsS;eAg&h0ZONP(1_l(g&3kS$TEBwSTonf;FZHlguc&9ZlBO~W;svo=IcC2-X>2B8`p<1a8QlYA zZ=&H-sREZk4P%SOMd+^?80tJCI^#t&*A5!Ahs-Tm%U^6eNbCP5?uGIXcxzZjXxbQD z=%I=6vs`mo2fNnaatxgi_Ax6qPnJ)0p%Fb?r}$l`f5VZ)MqW+4OHN*00#GjtwkwBy zoXOglU~FN|JMVor;q%a_#4b?ANBjrZxP+S7$I`L~yOLsvy_XV&giAf*&-Uxb`67yQ zK2jEUnD_b}kryZxL7DpPtr1pf{-2EEKY2(kK5{HV;Dz1(Uh?~FK>`gzvP=-B=$IS5B zdl>-c`rttQM1f2?>-0n{!8x*awN)h8>W98kZhY>D8tl7mEV-Lk;JzZ|AFdY3pf-$8 z{FMG9TasD+53af}LV`}_1+_gij8!o{(#c*WsfdiZa)KHB%kk35iph0}f})H_^W84T zYW0-q>DgMsf#wRzW?iu_j2wDWq%S@RamYWZ8)k^{@~TTedeUY%mS(#VMSg<%KpN3> zN1-Y+`%$z7U)^&71HbQxAv((Cg>}IX(K}cd!q;MRJVK+xHGAH$KJtLAvb8YWDMMZm zkAC9zwvcw8?=`jvkUE~D`I_pQ%+ZDusA}A>exa6xH~bW5WpE^Yk2?NjMXXYWie2}t zC5=mM^LFTyPQ79svvEbV-s0GvGCklBfKheH-D2^9n#zY5cf z72=C7LK-hAc#(y1nT7EkoBYP2v_g4qdO zjB|?ZEv!_N0!y|gfl;n6XD3f}37lVqpHoRD&g8(JuSGHL6p{YK51ORX@H`oE;0=!S zkjy%b&T_p=uZ=_xrHc?A^lql9` zMMEKb&PUOh`!mRHid-0W4+5u+H&^us_+ zg*wy$-_ME}*t+SsR*#V6MK=PuMJikJaj6X+nXdR0+;=?h`dfNNk(HB}XW79`C|ZB~ zOM8cP;mi0C2mN4Xq&<#e9_@6`a2cOc8M0Y6L#4=7dn7V4H%Xqi(D4t!^OzsaLisGg zqrqguo^^p?p$sN(_vc1`l!^oQ3TxxNqkrNN9P|XC4nRrE+_zP-SJZHdJX-OMeu+fF zDzVQ%owX+9*EDrG?K+}>iKBIT=J7puIP~Oj)E0DE+n-pv5+&W%)N>@a!!c`kHJ;Zw zA4ZO+(gg;&^{9yjVy(y0fQr~j??T?<>clY?F3=`V$)12o#Sv!gHC4uIx`doetZ#K* zX*2k9A3{x!q%g8O*bz-&*w>f`KuadyNI2TgiR@=~ZowmIy`G-PxOqVVfCGKgEHC;2 z456R$x2k_^(7}d$w4{T7xt+3mI|B^U9@kMe;1$?}i)qXP+oR_s$Hg)#o=x(B@Y zaoT|hEWTuq58%2L_-PA5g^SK2x9Ql|3-R zv3hU)VG(}u(Di=*Q2+-v*vRCwzH*qXFQG5$v3*%tSWYeS`LA}eoJirH*L3jtbz(q|V(SQ0g<(&%^n&-A zzEW6Gn2elxaOWQ9&WDz#(%ACgr^6i*Bh3Z##t!VF^&obi@Bvx4NO5BwT|Q65#Di*< zJJ+{#X&v94HLX#LqI8dh$F15@KlieIHy~r)ur5%7qz!$@+{lHgoyWUzfutri1W06U zom?C<*M1J|Q1wv^I6xH0l1H#D9;_c}pe)QS)AcN3GNMNND|j?&iH3(1@J&n)6mOT!c6;uKh_4~!vf4`|J|j^ks+c^B z{mjkJg{g>p@J>6kJe)hsxcszv&uA_; zOCMSQ6 zt#~UN;lD|PofT&H+vTS9t1Ym_0jhqeLEu(Id*i2G|83V}G7sT+KeqkbHgUdeS<DT#jn^8 zN0xa_212S{!G`tJ@v#+VuOw(ECemz7DI&JD@&d+UWNmSLhoque?Os^+%*M6j#&}qu z`c@lPJHn|T2UgMf``J3+bItd+nLu=;(YW^j%0AaWpm7*#@osy30QgpYCl^%t;aT2j zN^Ha5khD^U{lbGUn$l0}dK4^4m2?!F{yR?W+AhLp51VpyWoUQZo7k_JwpDuFhQ&HQ zvP@T?>YJdORaAinMBr7tAX&}4xq)DmS9lt3*Q2=Q4W_N&_R~0M!Zq+=cXSP`z48l< zchu?Q0?Zg%*?V#Me>HaZ0y=5=9eraO({#0B^80IA_&<8+@1)@9>vRP`T2kt^xFkYc zTFyjTMgbwEa7$8DQc6KmGWgq)^8Yb-p&z+9hy4Er@;sa9D+8ddsi#q)W*_q}U)oDU literal 0 HcmV?d00001 diff --git a/res/img/flags/TN.png b/res/img/flags/TN.png new file mode 100644 index 0000000000000000000000000000000000000000..21c4b98be71f6876be9b7aa3506430f7670e2ca7 GIT binary patch literal 2635 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 IJwn{S0f(l+jQ{`u literal 0 HcmV?d00001 diff --git a/res/img/flags/TO.png b/res/img/flags/TO.png new file mode 100644 index 0000000000000000000000000000000000000000..c828206e35c89ba78ab8ff0ccc1ccaa8639221bd GIT binary patch literal 1618 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 AI{*Lx literal 0 HcmV?d00001 diff --git a/res/img/flags/TT.png b/res/img/flags/TT.png new file mode 100644 index 0000000000000000000000000000000000000000..66d698334bdbd74bc80d180e73d585fdd0ae41ab GIT binary patch literal 5253 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/TV.png b/res/img/flags/TV.png new file mode 100644 index 0000000000000000000000000000000000000000..7a127f51ae3b4a7b80a468b6b5c4ad95a79d1cbb GIT binary patch literal 5915 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/TZ.png b/res/img/flags/TZ.png new file mode 100644 index 0000000000000000000000000000000000000000..7949f65d8aed43e1db20399e2f20311258cdedad GIT binary patch literal 2289 zcmZ{lc{J4T9>>398GBx<=bR@Ef67Ws_<%3~0Ae7{ z!jVhEKOqj~t{+G03%TICh_%B40Q08E4uPM0R`S6)+5te68UVy60l+V=75^0gB9H*E z;0*xid;pLME@*N%&b@%1x3RL|lB+HA<~S~df^n{4TzdZ#E0<0TayJ6upq-__6u-R8 zQFS>d@-o+%1TC;mk>lS#T*cp-JJ`0myuH*M50%DOIi)Aw^^qR-)^IplLM)}aMG*rf zk7No&^1am{O6Z@jo<4)ESd~2{L1m6-TIn++q#rAEzXUS`NCv7k2Rd#j_3|_?51C!5 zOdYFBbD!Skz;X#2=xtHNI|;F?|enO%jb(~LGnvyH{G zQBn+@kD3f}aE$lt-wU>>f;ZzH?PxX}%rgVYQVcWP^L1#p+HP-uXHn+fR8ALr)U$S9 z?NZR_nBhGba$2~_oF&cNFKB7SFMR-!)?~b5R_$Cx^ZxBW_$1k*j@bN{Q@01cw$kdA zLh7C7k50N$o$du8l>u(gun%q}u13V*GiU4S4x8Rqx$L6K++)9nZS{21Y%h+?P6>Cl zE>RQ=VrID)D{JH8C8U1ZYoWsdmpVYa!wGE|EBoEq#T>M%rhX}9Ex%IpmK5F$pyp!Q zV##(9lJb4)eR>&`q;&F5`jrILF6w}Ri+H0})0%XKf<#D-KBUG=_jN9%*!^sH3#6r! zui%?lj}XV4LJb(a$2)-AiNmjv8jtDlWZRaT&!mj(LeC!Vj^A&B6fv^Kww|<>@R^Fu zqN~VY`XRHp3AkbVNEPmy546@b*-@}(zS8Iw=E_z#As4&i?vx)5q8W>}>AKni{td$k zMe#9UY>qb)hCKIPcyU&|Jc?3zcb`L0aQo~f4XF@_U&@k53C5#*_J=Mq9(lbeIbn>p z?!XH^$z?Yg3*z26JGb%++>E?%Kn*k9OHSUWN{MnaQQgy)n4k14=NOz3W^s02Gnl;4 zFWyVSYah`IiWd}@I>IyJHPMk4#jESUdDGg02J2sR&#}AtDB-7j$`9u&BPj3paCX^p zWqpZ#lO8{sMK2BVUb1DSi>X{|-cWa(dXL~vCMk&iG}JB4J2rCI$`#rX_Ne2yH4Cn4 zfau8=WC>Qzm{WK97hu$IFgpzzQTGdWD&AP*dL!iR)Aox^OUb?aw=Xt&B{NYzP5IEr z6$#`#Mk_#j8&|~;9n|XJ!^sC(QEeOe;|m+`W*4n4J3%eZ59FGpB{d z`l-a&a0|-^@TymvC3$REpWdcHPGpY-thIn4rpioT-44lt- zsY2Q!j$S0bd*c$+y^*Zm_T!A;s%*q&?D2xNZPH5C`IVc`-Tp3=sZLi<^=f#$$|gqV z{fwY4TqeRkEYUbkD&oDm|BA%csPvfYYm>AATs3)cU>yp^!7YvQX3Wi-QIaosyp$D5cilIfwc< zqs(oE=H&sIcJ`}!52UBeWqO557=BW}Ua%E5>H7AJVd8m5(<4!04I-!fHu5UI3r4$x zsQNI+JB)kv@cGZmmy^X%Fb-QYeM6QoGnPo-dXz9&rZ~cv=w5RBVvJm$b_vC_Zq<)u zLgSdXV~x7|EMVAKI)tTgrVVDW*3(=)yAcG?TCfYE_e9?J~*lryYlK#GU6 z=`}DbRSrJ1cJs1l1y)mI+lm)RXab#~mg8I7B~uQP_JJF}cH8wq#G!7_Opzg#C-+pM zQChZ(6_Q48$o{nTme<)Q?jk*D!&I)@>h-HiRw#!_dRQP}FmC~R(iyn}1j4m#t&koK z*)^jI*!^-$C~;0?D;D{%RxAa@cxQBTi z?bGJbznlJ6zgMwjH^raY_%OhRy`42~hUjR35J@2OCj5wW6=T=F=1*ITF3XFX{TEiu zIC4H9z}T?YL|!JI1poCJ?(eEhO*Yx0E^_NJljqrG&JbRT5a8DwA(gguw3o!9PZg|h z^++gK!5KqCN4T?oPPyZwQ>av%6W51CTDcl!>yM%QEh7{DJWD^?u>bJ8&ELbXM?8+@ z`s#Ff%}3@b=VK})@?Mx z6a`ARGsLP#At7aC%L7`b+1o>^gt}GRx1IZ|5-?NMqC9Lmi`gLBx16Rik+Gr4Z3q@{ zbYAuw+2g6t6G8;V4SwULfQ1(`|Dym*rwJJt)#dA=x$ld~X@2XX0h#;tCo;8lOuwGa zpNZJC-O-s^IOwxgjA*N9y1bc)S<)PQPzb$XuWL2N*ML_VXR1USY;6-*PL;4vN@uUr zzF=#y6BWJ8m4TKK8rm*J7oxL`ilzv*zO%PY-23X?&g?*n%9F`0qS0ig?ENYT2V<$N zO&Pa!D9zyedGUOLyqNLKp%YB&&`Gh@jogipQbYQ)n{xjDqbH8Pd5wr_TV=GP+}|Hi z4Yza&_a%h;p?yOAxB&E!x<&}30YcB%N$)7yKo_l#)I{o{k;uq)w#k1a1P1x~U%2}J U6NHL968@9`El*k0obXQkH%Q(dH=O_J^!8;>H@%A+_%r7#P((T^vIyZoR!>=y%vb!0n-7 z(=pja3(j_RFh!j^C|JbsYRW=y-?M@iT(&~2o+j%uG@MjiB#RlgB*red_`WvYI&8~g z_0xT4frbM?gTUE%@g2K&f3N-Gm_0ejOVf1!FPZ884!<(xxxo6(YqhGmA8(g_%bPc!zpCwK^cO49jJF>z zR9uK&^l{pc|5lrw%O(CF#%ev-NkBKe*|n`yf3Fn8TL(`3VVE$_;6bbRyD*@LYKdz^ zNlIc#s#S7PDv)9@GB7mPH89mRvIsFUwlX!eGBMCLFtjo-s5tc07DYpDeoAIqC2kFz S^J5!9c6z${xvXR{P9{GpB~gJKBLg$MxE=_(s%K(afE=H%%D08B#wU~>RqP4>i| z27n7#0QgD;074!Bz@rPFdK{Jwz-K9rb~4IpmDHFh12o#{WQ>f||MYyg?HieZ#FAa? zA)i3I;RlR%d9&tZ#xk-U(K~K%wjeRu`-5i3QO4N!v-k`oMZV(pEd#!TJ}t#CGmnEj zW22&Kf6&mQ0^wj>;~E%2`aQ#QRw+=Yd}DW+0YP3TAspdjR5GrvdhXO6IYlohp;GB* z+_~*9B1aoHY50hIi@*b(0jiS4H%0YRuUS*i=6LmUMKSQ5%Bi-u-HrZ%m%6pfy{f+} z_g#czl*MV2-0sQkTjlAs43#{D!&XNwYGeo#Y;|uMK@7=r+Nl*0+<0Hf7aQ-Z6W2pO zp;1HCkZ@D6uOb+lM3rT6R{iMP1X^9=W^teHH=>GGzWGXFr@2+3)NSVEPhHjDXNf9( z4ZR0!rQP46rF;G6_H7>NGqLm<2p~;Y(@a^VeYGOh_U=2*?DIS8!n=IYDb{S`- zW3vLvj1$X)vs~5ry@Xn&jF`!t9~BD&i!?wYjzM=0xG>Y|+5^;yue9sNfJv{MQp5ld zf6P5QGYzlb8hZ!r8)<>N@la)mh^e)y8PKa^=h4u$hat>gD2umts%s3o0d3uS-D}F) zPZ-j2#X9p1g3LoLK$erV?*+mn-=*d{@nB_U|f z^%ksH<2SZe*gfzFE7T0FPM|ZFIYB5#L){f3$R~I24O~UaNTtDW6MQh|JnZ9|Udd76Qc;6s-}lsKD>e+(DO^*g{V1uu3s3fI6euh4nf;kULIB0t4Th}(?{c7EJISS=PXeOAgJpkWtMN|nMF)Bw(=zGm~%Y7wue32yoD75~-Q~tCk z0TG}L&+F4(YllohT2sfmLk{0Xg)FtjOa6oo)H=ADd&_N2B3l%Th2$RjH3MM}F=A5PArn6zHRN)e*l%prqYS(XTgH(LL9DTfy zT{)ic644+raoUU(%+lzs4=|*6mtJ4WP(IJaXmF)n$EJUW96uqj#)S&Se{o!(1>-ZU zj>qXCDRupfBfRCJxgo=a?3tkyE#q|#bW|bdd2{vo+NftU%DRW$t=+C|C!^B4@RM>* z#YO&^QZs?B<^HV@#}d&hjO71{^HiZ=D$0$sas3kf*sS8I#RQ2IG5+j==y@81O6NxQ z&(3e#nmgY4hIL1raY&pn?*e~PmlWFNV}ESiryvp;ibMyI>|1xh+&b^a*&bGNyL=OI z3}Hn$?v&3r#+x$IZl(|8C8A+pbh_GAq!z=u>kZO4&4iq>Fg#|BWQLX12sCEe*TP>j z@>)N)4|%m(uE3{!vULf~S+4@w^e(2mmFnnoo>=zr>oFfG6nx9R@muEtL2CGwtP;0?Q~LZhoKtmp^v;&+{!CQ%~{auAnQloqveRKqhgf%};w+ zd&{0>63i!EqAd|5M0)FIMu6XwFso-r=pAWApT>_!`g=a)qDrw5TBZQs;8d_eZ=l+t z7Ilqw{k5=i+=`2(!qIT)zK2Kh47S_`Hp(k~145m>uQ+=^b5e6WDd?K_wHLqTs~&u- z7)_bR+y)-p@pY6NSpG;?;J~(Bt*-*p?pOB=fXz-EF-C&3Hpb^m%8z)HsHPVbY7 zw)BMfEBuf*U2RWkcxwN9MoE+CT@yQ%X#uG5G}TIq=uuWwbw+KIsL^Ywr@)^dUbV!< zj-g6>=wMl9Oum4HS6ybjcX-!qGrx;`)N>bkT|O*olX0!&fFP1D zoM+Jrk$Nzr=wAe36W&p_cu67S?smcEaP}zK{ literal 0 HcmV?d00001 diff --git a/res/img/flags/US.png b/res/img/flags/US.png new file mode 100644 index 0000000000000000000000000000000000000000..c3a245b767982dac3198f5005ab285b82946b212 GIT binary patch literal 2845 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/UZ.png b/res/img/flags/UZ.png new file mode 100644 index 0000000000000000000000000000000000000000..643b6ae0cf6112a4145592ea3ca7fdfbf498d057 GIT binary patch literal 1745 zcmZ{kc{CgN7RP^NQLzOj6eHSG^l3CAXk(9ECB>krGbJI6ncABYd!#7|hT2A}s+Ov0 zD;3r1Lse3$wY8m6dsQt(mqG2~nU|UW=AHBIx%YnVa=z!>zb?;{?4p1;fB*m}xVbud zOKARAAmNfc@wTa40_czSBzpiF^5k}DFiDRNcJ(F!kf;v;ivz%pWW-tk-~twaPgDR1 zR{%gom$i6VNfz*+lP-=DN^IMqHBAE9XxB66C8Yix%jbx%B!vvajpQWr0j7;IHPrG+ zSponibaS-#VUB$rN%HjZ)fTQSHMjO2LR**-Z%@31L-@QQ!63B{?@`-#RX)(;Y6$*z zrFw4e5M{$Vv7q>b4dP)=U0*{o^-5iD-5%${^9P?yz?^T+JQxeyXF^8QCjGu@vm{M$dAGd9m}4cFr%8A zxz0$%l@_Kvy}@K`1Tyt%;BG~{?p^g}#HX~_rM0inQ%crO?Q*Vja^OoDXIx6I>0?6~fdCAH~G{jAs9#)Yp zDiBdFKkEvgL5F3SpBz^hZSHonSj!w=;+}cahD_GgQ0poLeRS>DgWejbLJh?#uU+&c zxNL!i=pW10(oIqevve#o%oGJz2R7d7m~yFp-)N&a=KQ-$k#H6@)Ah_5@*@8z@LnJ( zP5B>`Rf>z>`?GI8f+u8adSt_bEEkxuDO%L^z1CYwS?rznRslrh9|{D#{F*3;auCnr8g)i==gU}}@>nu;;ujrfoEO_jJ5%)Ddb} zU{-JC0^fF{OhX3Ozm*%XEY2eZUT=!sP%c0lbo=~V8TRw_Y7xYzC&(PcFlOY0+38Xx zyPYFKn!B-&z=&wAmn0Pp*;2O2m#2~+dT?Y05IS?$(Bdur!1S=)80+S%84Hn1!d$y= z9(z_TB{)gv()8)i_q8%1^*lW*X*Wo{Hoc#PsWmb^cQ5@xy6lb36=I~L@1s)f=)QmB z-nH!G>gTu`9temJ?7%Up%NI^>+Ca4sMj6970BJnbG~sT_vU+xvy7?*X#r7tas%uVN zEG^vLh{M>f)P_sPSB=uIQ$ah~YLSsw6`R>(`dwG+wyn7_wQG`rH2 zt&wGy+N=D@-ftO^P?2y%C5oMYD#ruDPuFGY&=u;x9hq`=VRH?##iE6m$d4>_B99`) zd|fm7ha#SX{NaA;nJv%3eefj=ag`wqCICs4BU<8iq9{WHnYI8dl zqYGWVv+PKNMLa%k94ECJqBke>+X;eCk2(+pnFwcy>Tl{MLbBrbh@1C0osBS1k)x^& zoIeD8C-}wTCPW?Sq*E~Yyyobg6eRX(xcRmIP`S9=o)g9;y>qc=shsZp*24?z`d$?O zf_!xqM&9s>A(r&}W6?|RpXQ!kx{KM}6l3SADiA~6(0jCjwWaksYHiH}e~+V@5wxiT zO=I}MwOB!;kN*Wqhcv>^%;3k>@y3hSYhrT~hDNSEr#EF=mSgqt^q`j$)Y{u+jXFKg zH6mi{M5VfaYzD1uNoKpGfN`3g$ipu_qg`)A^Iv>&OkIk`R#clqa)<9ldUI(PR>)T=AQk0zNZ$Klh7*NBr!hhZ z!LcC{036oD0)sWf;Ewy?ObKQt1U%LVYeK+cnNR1e{~?HoqW=_{@c#v}H_oO@1i;OS K?0AnzW&anj(EgSH literal 0 HcmV?d00001 diff --git a/res/img/flags/VA.png b/res/img/flags/VA.png new file mode 100644 index 0000000000000000000000000000000000000000..63a13c0e81272ede252bd979f5f5df7b091dd44c GIT binary patch literal 2211 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 T!4h{0PXJis?66NP2}yqg8uHSq literal 0 HcmV?d00001 diff --git a/res/img/flags/VE.png b/res/img/flags/VE.png new file mode 100644 index 0000000000000000000000000000000000000000..e75e17c9f0406ce7b4656d693174a523a6af2f79 GIT binary patch literal 2157 zcmZ{lX*ApG7Ki^yBrzq%V=9^sXpf;WYfyp|HI*NiT2o^WqJK$ z2iy~u1)EFuHdyz#@x`%Q?gb+%Z&tSwr0s-~?s%VxPH``)XslSESX7^Ld9olr@~*Pf z!V~lHd`(mIkpIP~`R_F~i~nqri}tX6N!XY!rY*7&pNBB9HEt>;j5_iJA|en7Pa30Yb$@yAaT4TO(-QAD#sPQIX{a3D9S`~&T2BqLhALMx7@zrI z;XitxzW0TzpH@Jw+-3y*c%~iCME0A!*Z1AXihdZ87nHS{Rb}?*o&H`J|9H4a(PY9H zue~k7fY$z1enebk?eLyJq3|*@d2$(aC-LvGtpfn{d}VEI9S^%3$91h zVE}X+&v#mQiO25X2yrIZU?2;Umxx@sct88)uVj@`Hp_*m?K_<=!V$g#SEB;jr%lxl zV~cvGx=G>Akz*Tu)83yBQG>7+RThW)B!^W=eeSTn!lzOyGFaBIT!s+ZtK@KUK58yu z=9fim9&$%*M|`eq&YuWD=U&ZkR>U7PeHS);VQWKmf>6G^Vc&1uHcx#8s;-c;?3Jma zXkME!wFW9(KR}r!M#U$({1H}d3MQ8~?2}9Ukex)vYcPp1z=Hp$QVEX74bcX^( zpIU|7P8rqynxZ?tQXT_0@xNG_!$k+ZUHJGMQ+HdLiCxX`v1QTloz<0_bCYNu1c!P-qG4hPYazcCWa{?-$mk=17eDQBJmey-CeS%sxNU2JLZD3vx-rvUk|v zq1=w>3A$$(FgP1K8-uzR2LqKxk#s622c0t|zy($IGIa8pnhxaEK(PjjZ0w6(A&t$S z8{GE|<6GH6bU2r(luWa(Zge2zky3WdPG0q0yT>U~T zVCiV9*GPF5XDQPcJ{&5pz^4455)k<4Z{OuR^3A6Cd9ra@r%K5QHfkz^nQzG z%mNK&?Z7s%MpBxOUopr#w5TQ2n`U%P@0CmQ)bLM`LQZH)QsbI^4x}g-`nYrJ)+5ZP zI{W-^xrdQuEuoR}*CU*3plq1{#BC?BK7Ex`Y8f##`y?O||9ne=1F$1<8${MI#lId% zk~&-_jxVVG8js2*UIrD6GB2S@f8K!`W#pcR9L)%*Oz}N5GaEq3d7`88CAUX4<4>ho zVqmGtIbp(i{)6K8=KPzx#e1C5h?~FfpYm(^{Av{#3UP9oY96X8TeO0w-7t1-hn~!D z1ZvYcg#afNnx+1u{2x!JNy8IQG$6D9X&%MOwGV@r%8Zji-_Vev&`LC?=9&w9KC*>m z-QHfs-&5`!YCq9q=nI%{?v$*}q8MZ47?Ue#2w|7b&bYRu{tC!=hlY6Gm;& zt1|M62)zzuNvwf~Q;P6sISJQ!##1TGu0Agn z8G^@t@?8d5#^C8x8|uj0h&5Ube21J9J{ilif@}v$hy~?TulV>$?@EbFyXs&7V(}=< ztDfiZd6M#b^(L*B4!DO*!J55~hT?#F?;NPy+A&QKd%ufrV+|20^pVP-*6zGxgf>jq zKZ*(DdDM-(XdS-?Mm@-YW1mUCHab|H-^EQtQN1wakzh}c2(Ow5IZQ3bmT zmiJ#FSG?F?c0DqJ>-gN5A z4+UMKPteHI%zpMUm?XHSAXOQrZDo3R7qZ$dEwbwuMQa6X$&1-RY6t8}T;!`Aj>=h4 zQ0Qrjyh>u z>N%eVARGxithY!QEEK&CKf{HEe5Vf;FT9?y@9YRiF-sj4B(otJ;S-UV)&cmonHJy{ z=Cg@Gf4i(}OPfoD72b-?+g{3?+&ARToU0f_h@l&P)|0*{|Bq_~=3(;u={;_~dml{q zu6zAWW&*KU?7&0Z3WU;z2eSm~Rg1!TM-d580T}-q0RjMeXkBA%w4t`1iMyUY#!wey pfYwCoV$kTgPOkZX1+Ik=g9GFLe?X+nCrJ~YREwO07#zW~aG%ZUI0 literal 0 HcmV?d00001 diff --git a/res/img/flags/VG.png b/res/img/flags/VG.png new file mode 100644 index 0000000000000000000000000000000000000000..46f93cad1ec1b088f474e004c924e00157c9969c GIT binary patch literal 5427 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/VI.png b/res/img/flags/VI.png new file mode 100644 index 0000000000000000000000000000000000000000..8c849a733e369c9b9d61964899fd7cad8659090c GIT binary patch literal 5938 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/VN.png b/res/img/flags/VN.png new file mode 100644 index 0000000000000000000000000000000000000000..6ea2122f9d1dd9e5aefef30ba4c28c5b943ca5e9 GIT binary patch literal 2304 zcmZ{mX;jjS7RCP{Y8VzyWs-`QQpzEaG&L1)!ZC++QA9`JHq2+TRb$;S5PqLO}um07)xLGbbT+ z|66b|VV@dnx+?_aGSQ9*0JUj*w<)5+9qDQ5WCs9IssKP^0>DqJ9(~ z`2cV*prF;!P-uvG*pSSG6zVV2ws;|+0hZ3eLc0H5YgCgF;UFGjWoIt_QS|UZ92!B6 zT@_wdt;~qzi1#aZq65fdiv9S->9)w4$gIV5CR7e2Q{2rY`GRrXG()lpd!H9L8>TrX zCGMdq%lW92T?)HFAj*3@C^SiwQZT?-wBejP zcM4Z{Y5XWAL^;t@8V;DGJb~&IA12MGEHeO1DO!3Xp?_!F|Dz zoHyT6@Ld+eMUnC_s%fzbh%O4PBk@S3qe3G*u(gw-n5eg4u0hz}054&xa6^RK>@hL!7f6u(?h9e)vA#bW6;%Z3 z>DvRy!0^7n!HAxw|+8=e>M`-dqVD_5`_I_ zNalAUPf5A5NQ~+@t{Tn0-`t3%mUX}yzVSg(Y_(@)@s~SNf9@n4KOvHIOYWYCodDVG z`qSXgpL=Ey74GI>$vTL7a>-Ccq>`DXd%Qk8<&~!HQRS5OTr+QJdBowZ9JBP@u&RT3 z#NGL@tU3wCAi2=4*pD@ceN7`>2wjGR2ERa~BpHJZdaDtF(?1cyNVXY9;1YE_(%tY? zkmE6cBDt*gh6p>WIuuN}K1Cn1sZLwl$*jy^B6{HqQ0INxrR(9J;7q%LM?S9N8PEg^ zPks3hckZhX6UOy_Ku;y>=N|Mj8t|GpR=Y>TchLNsSas{82HSCP02H~wE)VAAn$EX4 zXMJN{U%EV)ZBMri>Ck#jG*n(|j)7%Yq~rQxDwSKjgMI9M_UvwP()SZ#(1DBvH*QJSP<-w_$2k>fe2juQu>7i@-o?!N1}35i_8Y+>U#)e=m{r#w&V0`4EjQ)W zH$iMvd`O;KyppawLu+Y=VO0~5O`CB{^zw#yj{$d5P80>Yr5BR!T*dJ~q228fFez}aM)ZHS^wxqBho^Q~uxz?kdA7KerICcfl0S9;Zk8eqCUBs~L1 zH-M%sT;g-e-gy#KTT*X0Ax&WwuZPFi`RjGfdv^7~ZldFar$Wa~1C$D+=Gsn+(l zsVOVRuBni9&KM(p93$twsN-C{{_wrqHtL&RbE2E?t8)>8C%8IkMO}w5^BBqnarUBa zuk}d8uN!!TDya8ldC@jJ#qZ?_Rt`KyANApoST3)_`U9?nKbEO8{v|+Xe()M!-~Cz0 zCpG$m;uRai)w{sPq}q&xE#r}tC!RHu*tckt`6Re2=*h&Ha23d;c2J>;dk9raTHR>w zf-J`2N5d#$mDp-W3>LXCW?j2HXr zfmj;w?#A9x{f~1gitbF^0w*xdV?lO~j^=Af(o#j_*6O2iyE>2OZoY0|Nth*rZ__*) zndQhwDT5xU*-|-4I3(2d=G3ieSIx>;R!6E>P$SmV7L+-3?ddfU=9a z=2p41z;Mp9Rao;D>GZ_FmW9!?lMii@aewJnP%gsW)MzF8o z4`n6Y-UU+6{@_}edQS+yfukYj=R>?GA>Ia_LEb_D+8FF9O^lAFwjNmMIEhim mU=1*si02DN{}Z_8@8x?b^8W{*MHlJ90AOW)#;nT3o$((KF%y*l literal 0 HcmV?d00001 diff --git a/res/img/flags/VU.png b/res/img/flags/VU.png new file mode 100644 index 0000000000000000000000000000000000000000..bad3ba4d46e6b5983023a6897f243374d13fd598 GIT binary patch literal 4080 zcmZ{nWl+@b*T%oJuq-7F(jmR%0)m7r-6_2*(zU?S-AD*Ok&s5|#RUYUyAh=usUNL$ zDE;t%-aY@B=bAa^bDwkOnz?80xnG<&y4osWB6=bK0KjUhO8O6!_)n1GKjfw9uXzu^ zwO7zm0Dzig&h(bQ|HhHC;^@PH0Hvk{BUr;@q!E3}U>JM|03<7FN(zR4 z3;WsrhDOtOopReb&%#+))`5>!Ag#yTVw~GpoPDgZ-BWQHFG>n7pNa>XImVOQlC*X6 zzYrjb&aw9xVbp^VXnG72GBzgqO8Va40o^q7fmO4IO+mS%W|dx}vezx6%iCUmo(H}R zi}`Q$<0$anr{w-e0=z2JKgC}e+**$o5D}U z{9m!X?2p41Cod9Pa>P1$RQ}ohI^k?|Z_phuJ)%5w52i`iD#rN3`Fj4HDqL&)z+@H|{#d`tdhH{wV$( z)A%&*tfpfX1=uNPP7quEjC{LKv6GpOeYK$O+%fkcREZP8&Y&EVO^kfb>)JlMSUo5s z)u@hB_TuYYfeY;X^X#PVT3XR#-__m_xNTh*a`byfR_-&zjJx}(=}zu+1tb!>~|S7Wjd+QDD7xcxGfSl ztCh3a{HS$OcA}^O{{8E^WrKB0h|jkTW^5Ka+o3BjJtU^2R(t4QUDr6ql5B$hHxnu+ zJi5=~le$5@${t!p1%x-ya*p3o*U3WVDr+AEs$@-&cxLqnh?Z+|mpGl4SHG}Qe^)Jg z=HfO9_~f2T6V-lwd)qyYYh+#K$%w_*lhCr27qJ|kJ~jgPy9J{!Z)_WLb{JiA36^I! z3a`B3kN&Y6JT8!+Vu*Sc=e%Arrx-2Ikkx8k_zofkbJNz)wMv=X!QEBSHlNxZ@`-6;YZ{Reb0H9!?Wa9O`@a- zq?1!g_Vn#dd?IsLW65#j`E@=DFw(wn()W%%_^hn+EuSQp=FbP;22sW@xs_;%h!2OO zyLy}qp6yyKtHtt~oz;saXcp4h;x}GLmkh8TH~#3ceSdoq-=1e`Uu$XHx;_W#!QDxg zZ#RXn*b7cm@HHsP1bXrHsCG1&27nH^hR*BJbktMeNBWN>My%=GpnRNyYt8u{IHa|d zx%>5;>{Z!%TOodHdRf(eDeSk5`` zS6hkl2czHqB9fuX`}1FWk36r*T9KIVWRQ^ zuZeFQagEJ(AyCM}=af%o0vLRN;&4VCNZEF7sO^16NMto%F2$Jv+-*Hd8qCi;6LzQD1^o>_}H<{pamOGH0n_CCZR`W^ifD1w+QElaYiQ zaq3!{rg?OUo;Bp5RyNCf3z-Rzk==tDOLTW7j-cNT!2Qo+j%T1O9d>IK*4g}|f`pC; zh(cwY)!`RjJQ3Snwt#VV3Vsx+ z{8Ysmg?DJ?3H|8{_n;yXr)G3pH%9=w8cPnu7M*HCks-f3n3IK)hxiC?(ji`spj7vv z&_b|eTW-F`qpL>W%FoQWzXE>9ZG_;vRkm;L1>t)#wS9UlTDV)zB|NM@*n+Z;^#e6q zGE=#HAW~V(Gb>S!5V2TRSJBOQ_F~RJuV9TX_|EMw?JEKp)W;G(#Pl;8s*RN|bj2`G zBU56%hqceY+S5C$!PNnlW1T6|dBmG|@M~Rf5x}t;cf~Bz$w;efc?WixW+aSYt$VEL zF)bK#Z8BQs)~!LK#Q)ZHiEfdwER)CnC9LT4+bIf9Y2nzfo3;8o96Gr@BZRp5RPzSr z-jhrD&9;W2nY-b9`bi{Ju$>TU5qxFu?LiEzBr8T7V6f30uB=sIKMGIbw34W|GR8{= zUnrLcz{(O#wDw{>IR#}_f*!hUN5|C7xhZrVqTkvHtlaO`GS^S51z%fxE!M{)Pd$qB z%f-cr4A?C52(A$&Ao+!4x$gk`M9)*#V;g(wl53Mk*O!V-kj?k6O6)Hy+Q``1x)WoB zq8fMGZNlyK`~LJ){V_$nWK;6Au&6LkA#+P^w%E!c(~%jk%X`NeMJD&X!pbPF>y4}@ zu{td0q$CGM!|Iosfh1S_lX=31pql-b++3RGyTjM}_t_dxzZfh3_J!-|-h;Erpn{vo z1G)Hx&uA7j&eysh5UjuX_de}kAzwXSfje~p2Se%S91NYZOXB9dF$U<`>k4n)3A~M& zb3=-?-e_htdb<#T`l`~b%tUaa0qJd@|0@lA0#NMpNMV5;(nn%@o+!*c_^A1LXEUK7%2?80UR%4=*uenFRTtp5|-d54eh57GRwe3g)65iI*Q^Ane z-cpuDOt|Qu)Wd=)q#B?jykk1Pn%kO=t9#yzyW_fdknp_P3;llkAiZ_3676_TpQJLci%?J%6R<0zv@!l!bxSjSF$#k_*FCBwM7eCjM zDO$K}wyDRhHh;I$R;7cuy?l^I zr~Bnl#X!`K9;YNM|8}(nb6@qZ+&)EU9%R;w%Y$|!Wm|n7AtCB^R%F?836BRBU%)h&uV#1C)$|ss zMnJ$@iKBlBKxyeDk$L09URlbPC_2*VHYTAl*RaI?malV`hO;(FP)-%J{Icz`CWbVVy^F3O&2q)87gBVc_)Ee`(P|Fyx&v^$Pd zsZYR)84Jqj?cOLhm;IMG0ym9+^lK+l2yUxGxrfd!1rQ&9gW1!Js(<_L?qI0DfK_?5 z?1)5)s>vwas_2a-z#>F8zUXU2(%}!S3y-wJy(NBnPYV2uC^2Xz%M4T7v@KX>eFl?# zM`qEAnp=l-j;)a&Zke+>_Qep+Nc^!|JGEY5GncqYlHfMsH*C0!I zehUTyQ8nxzt)7;F3Hz(81qku%&HQOx;%Dg;w&!cTe^ReHj7zP^(HhqNq03O})V+yr z1Ivee{ES=uEwBg)_!mxLg)znh)rHu)R6UU)GodnnXpFhkf4sk@z||MU9t(H!{jmi= zYQ#)SjT8==X)`Bzn%kY(WK7#kvI_Yqm0x$1ZFTd}ysDsfi-P@Y+-jPGcd_YY-H*M4 zvmrKC4=OkErIhS$QJQwed;3Pb-SayhMSQkoJ61KSJ{QMjSZs(&{!TrBD2#y;8(He| z`3T{zc2AKOHB?^AkU7yX((`1hb0WCLbHR-?(U1u4BR`djIW5QzUHQ~+Sgmunn;F1V z@+06=BT{I@x});NG4)gRIt&XaEaRkMLsTD;>L}Pnj!KoJ(`=YQ?-1~!<&&+kb{%%B#uzNe+WDx#T#V`K@J@${E><<;|} zH{P*M_|>@cCs^nk?{dKQlVLNdPgnIJ0o}#JT>}zej^ed zC-`=q_ce_^t6E9zLhmm*Sz({Q9(6b^UCp$)xERDryx`b&kRLX2K?CTzH%b7fc>qCJ zcJZOeMm{%LRzavbCxUP`BTuLtaWTtjFW3zGs&vT|1!!q6#s|PlO-w6Q?aX2h0kIx45)G|+w z+3A>!ZDqzd{eKZ3M?mqTi(@P{BIqvY~BMNFG`>2t8Sbf+*h|!F1j<(0#?$rzfCxkwDgY4|5Ro(# v5tSAfmKKBXL4>6t5WntC+5cm3b${(>=l}m32=gt&9}IvROj`+~2#@$5>%ogi literal 0 HcmV?d00001 diff --git a/res/img/flags/WF.png b/res/img/flags/WF.png new file mode 100644 index 0000000000000000000000000000000000000000..d94359dcc403087d1c34a19bc5960553d4215e3c GIT binary patch literal 2509 zcmZ{mS5(tm7RLXOkkAPrHz*yI5=BE$N0M({ z^>4!~n(-KAZOu9*Trgd6}6?*PCq>xno603k>Kn8O1A z`Y`~&1E>vGwO9=Z!NgFHMV5Z!8e>`D3NW&}#UlP+Uh&rLXBE(3V^e+THx6;Qih`JB z^fCZ&HW}+-EyJ0Mxsk!gK1p=wgt<%ogF_W^2V6B7CnGN-4H1jCjUx{eOax6&K783! z(5@fMR4Kai2>nv4M``jC_w@WIfb5aQ)HFJs&ie#er~1orb-LO z-}}kv{nf15+}NzS9rH_VJ8U_RL-@ay7J-d&y1W0kq7>)%48+9z-h5dMO)A}}8Xm_! z(au$KigsXd$v8r?;WIQh9AoB>UlP8PL!pgZMGi#r;5XBSF6s4Wt_X5wTb~x~vhxU`rQx570IlAkm`Mg3_yIYfDp3vdweUm9a}0?pE5&v@ ztAA+%x?$O0{EHYg(j5k9HVcD@^y@bk9buHdYlgA|*BNBgL&MF_n>Iw*7&ECBf?gRT zp;;0l|3dLk#l*B);*dmCsxic8RA1o78=;jRjv$TB zQ%+5>Y@Hqx$`csr5oRx1!b47WmDp4s{OHK|p|V>_hFiR?hrj<5h*4a+Xqbp@i!{^v9XhF(Qp&2mdoZ1GZGaZu42pH z-JbhKRfkWcue${)aHz{Ij zZoW-k`tX;*f<);^cF=%8vo71ZM;23^+1`s1I6>GqtfA*Q_4SS4DA7xa|auAJ|_ z?67klrXqV7nI@1<&5XSMjFcHzeI-T*=DT35s@B=|vSj55F-oek{$k+72g!TY%l^WS zYKx7rI+S&aThR8{Z`f;%q*BCzobL?o*R&uZ0Xo7Gjbc-<8Mn9>_tt5#I23qxKedbK zD%SB*7I7+lL{sO$NAe*d>>t&b(DW~^s^*6h5@d^Wic-Y;+xmNnt<{a|nPzmEg(bn1 zq72=to#`6IZOkeup#TyMewAl;HwjKUJ-^fm=8JnT&>=O;GhW%sF3N>P-w!tD~XLDwSREmjd4{HV==nd2A)Ow_n4}iHivEeW)To2b6TR)*9ee@^HkR!OlLC0(E(1 zHV96gTCQlKV;n}52fl>_TxvY$`MZ45ArIw0`rbTMb3f_>Z$LvwGBC0rB@4B8I^$F-{$$Gaw^)o*F*m`9JA z{c45Vez{ddx~Lc9ek62+mi>$+<`f3yVl-9-04Pb4kn1{OBpeUc4jaRoR{$V-SsmMe1 z6aDDR-9ZRI6ZD&}(s91@V=)S9)3n@wiL3qF0knwD)ntFwUYR||EP9hpIRYGcc+0}! ziMiWS8Fhkj>k|`?8)-R5o6LCT*%tR5fm)l63;B8cNi(MiL^{*wBTqrr{IfH{ugm4x zi~2}me%%uZeC(;i9Nk79f7G7!GLy5-JSBOhlWp^ga&vR^iSY9HOS2l2c~64eZ3Q?} zm|k{6V7>F7xjvu6S8P$XQU~*UJR14al0OJL-;NMIFoQ{_&+o#C)+zWdHd}y@9G$S}IMAk3n`g%rWH6ZTPn{Iih}awwh#y_t zK`+E`E}>Biw(lnfQXlv<;+6qHEMgZUyD*f5*d8kvj0;LNmgjKM_@dMJ9=ofP^Zmv#Zqaw z&{M$vJI5hA$}qRU6uRH*ev)iv)*dLNt|#dT_-JvqG+F|Pzy;{+V90?<3l?&cWI`wi zugW<>kK=d;!@;Gx`W(T17M$t~1!eI7D}y^t(n{4503|DH|Dt3CnYIFA%XbFToU|RU zKKPL>rt5O-tlrF51P0&?ARi4=n#KMsG)BiD9>-loUT!@h`U20#`|n*_IO2J*eNfuQ z_#aKle>?)t7+T?&TjB3mUz^jx`nJKY&cSYImmoJ502ESLO$m8X38ij{QbAu-Mqfal nK`Nt>$ndu5OaBq@^>_7jzy1FMTu&TGtN>uFZ>IN37a#XeEC_yv literal 0 HcmV?d00001 diff --git a/res/img/flags/WS.png b/res/img/flags/WS.png new file mode 100644 index 0000000000000000000000000000000000000000..f8b80e5ba9b9fe5406e44779270b460cf1103c26 GIT binary patch literal 1896 zcmZ{ldpr~R8^^!fY`Kjlm*iURblL3W)-bY@@sp*whUS_}Wyy)wFvP*+Qu$e@xg?=b zyxO7MCP&dxh)~nnmcwx=!*Rb%zx~dCySD;#9a3yrZJff)^rZ}z4Zk`LV0CsXm&EVv`l%~7{Yzvbh# z{uv!&_K;QXYo2eTbt!kXkDu80$I_VX+DEKhM$q2xpVPmmuL;+-#7W$df_B|MhaUW6 zGM{I^b=CS#P6iE&kO4ZCkn6WG;|2q!^@o>T7eW=ziUMFS*2YTZak7rI{d!Zjf&&m#b;|-JqFqs5VqPv$U5`uFa7h;n}eoqoO>UbspWa;Bw30m2+&GX&aIw zD{A7(mgrl*7^%@m0J$nAMkI1CrLsIv41iXft5VU#Kz_B;K3f zUmOZin3~C4jwA4euq_{*F2!;Z-zb++qTM6C!8rcNF9tFu*zj5tKw9sALXz%Ydv86J z{-lIuyOYFN!wz7pG0EEZ)_%oYt_t2U@w=X0b8wD>KkQ5WX{|VOfF1 zq2E14XC1T-+(s>XwYPe&GZ#kTYPlvdOLX1W-O%VC4J?!f?$_z9w&0Wb?2`;GS;&wxZCn@2?mo0}Jlv>vk`uU-;=0^E;GTVR8H#G)6Dq^2cyx*-*Z2lY1u2j{i$EMKf zq*qDE)z)Xp{$hoNNfmKBU5CD~g3T*A3laJm#;5RVzpSv`bL^d-Beopd+)9T92 _ z@W8su5SMqvF{5~@c0;vi?r*(!(A_aFKOy@r&)$rJRQS~tb=HUdmTh~Lx|C(25{apg z?|xxj72e6WT(ujdnJxVIDF*kkBW=WfQdYQy>#_qkGnvaALSGr|eg^D4On{PeI`F}D zPNP^8v}M)-{oNotESH*gzEFc;VVr6<=Zh{knCZQwK=+<(D=CI=t!XE%)XJs$;W~YV z78n1r(j|Vrq?%0*30$S;D^B=5W33aYeakx*nzTeU|zt4k2O(_1bEI&BG(0 z33CU-=-BhBd*+)L*Q7yp_UPtEw5h5v1e$rK;^i@lQ5;`u`_P*sug|bNp}m#gda!dp z3@$M3_i{SJ@c=FfjE?^alW0@_S6A?8YMHoUN)Yv zGM&)^I7h-QKQxTs+_8+z)AJCtf5Nrsq;S0_?lZcKh@!J8a)tjYS6;r`+N&%K3E98|~Y_db~JdD$SDcGdsP^ZbG2|IqvBd zyU#~y#zfJb+u>3g$$U~HhMIQYWXf4xXKFBr9E_6xiCUYDgCCj#<*Su-Rf*7gmj7W8 zkPxZeVO3}Q_J&V4C8r*z1r#$33ftzo@!2$X65KOw$iv$K`Q{QiJT z?)i3}SYt^Yn=U$adXMDSF^D7h#DxaMh1rC}hDiX-(HP4^=%a_st;ptBo1++;AJArK lj13x{&^c-Qo!~-DXk_@+|1Xd!4M>p)0FiLg>9Hdv^*;+PN|*ou literal 0 HcmV?d00001 diff --git a/res/img/flags/YE.png b/res/img/flags/YE.png new file mode 100644 index 0000000000000000000000000000000000000000..8b9bbd894287185442024a68bb649179c4d5e309 GIT binary patch literal 652 zcmeAS@N?(olHy`uVBq!ia0vp^W*{uU1|;uX-8K(Mv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffzx4R3F27;f?yX%1z zXMsm#F_2CG;}6+R=Yb6N5>H=O_J^!8;>H@%A+_%r7#OQPT^vIyZoR#=(Tmwp;Mm8= z#lBpIO^m0N@7`n;{KT}(H}|D>#O>&3nl-Hxl(ycTy1e(!+_J8nSJ-U1wI}+9sqjqx z`+t_Unv8MH(X(x$j6h3(AY@0Wy++p}jjm-E^GwVfmC0}H^?y`mcRgP=|8?HVkG#fhx)&wRB_0!i8tt3_Vjj%?`@PX`cPu1`7`*l| z{Hocy%J*sGH=u}WiEBhjN@7W>RdP`(kYX@0Ff`XSFx54(2r)9YGBva^G0-+Jv@$TL hIP}yOMMG|WN@iLmZVjCCV;ezsdb;|#taD0e0syWm{80b^ literal 0 HcmV?d00001 diff --git a/res/img/flags/YT.png b/res/img/flags/YT.png new file mode 100644 index 0000000000000000000000000000000000000000..328879361e55f4d681b310181a772c9c8a1f37fb GIT binary patch literal 5735 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 Z>k#<=HxT4lMgR>UHKkXIRr0SR{{xsjNj3lg literal 0 HcmV?d00001 diff --git a/res/img/flags/ZA.png b/res/img/flags/ZA.png new file mode 100644 index 0000000000000000000000000000000000000000..7f0a52d3b2408b0facabc7bd6462be3002926b28 GIT binary patch literal 3595 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 literal 0 HcmV?d00001 diff --git a/res/img/flags/ZM.png b/res/img/flags/ZM.png new file mode 100644 index 0000000000000000000000000000000000000000..87adc3afaa254cff5938f9ef55d49cb7d8c83e2e GIT binary patch literal 1787 zcmb7_e>~Is9>>3R>#qCHz4wp%$9+9M@Avcl- zU)NL@004czV?HM}bp9F!TQzxffM2G;mh)Z#UI5ULzio{O*7O#nVsf!CkA@npU|U%l=unQGp=ucQub7YZmS_qH z%`dazEc zMMZ&n@12ujp8RZ^J9~C`!VR*3UH4w8;tVUF6!nEwihWEGIzvAulftE1s-67i$rBah z%A&F1?om0y;TOjq{^oVGa%GKb&naQBs6y)0hVn+lulxM|ecoq4SEUtAU*+&b8$V6y zmwuJ$#^Lgo^)WBT>P@G*I*6LI2HV0A<`zGi=EJ+};=#Sq-rug+B;(1(7h<*`PHGLN z7>vq-D*91@^?Hp8)M+6{%E29wUvv5EOp=;KNR}b(r!JAFC>L zKbEgqJg6-J2xcv#J5SfxLl*q2u>4*!kMv#tm#AmTH@=ieQj*6l$Lg9bKlxuR&*8&T z3E4a$4{UX$*Zg8B=5B4&U>iGR{=E#cYy9Q5Fs4q4t(mL&Td6epuw!YVMB78vd%Guq zO)j>zdwA-}^0~Voew>vY!V_KNa$tnrNr&92OreRX?M(s5s{TWy*3|J-xg}*NYdJjm zLsKt@xDKv-(^(mAJ$q5LX!(L&m^78+DIZt~e(EvRr@3q}AIBm?aUoLm5J?C1YOjfF zEXB|oHM#Mwoj4l-D{&)Gw$#<3~S$BiW?nETu!VP9x} z9zM{=V9Bfsd4hOwu4{Y3{-LsVVByz!AWMIHcERclf$mGqv1JIPXY>_XGfo98r?~!Z zW#!D&PzK_Z^4i0Yk&T#}7EHm<*-m(KQ{q3C=N(AX_?yiNtC{>kPm{~x6>}q#HGK}T zT^ujpEv5 zW+dOgreB&Ac2qqs`hyEoMN?PUf~zh5SV!ZRXIe~9!dDLvEx%3Lqn5I2SQj@YGjX0K z6z!)=?e5D=ku$FkUhiDiIk*k}F=}+NJyxW}eUu>k+w&N~SxTtj>KcExNKm*|yi5-N zroRxslTUflP)|2bkR{+(Tr+E-`Q!4eX4?hSN_J0T9(s{f-PJR(_8|~0Yo`YaYE(uw z#5ujCmji!#*U?tzmsg*xtKx_7 zS_mxBqply?_^ogf+IS_g*78}{L>@BpzU#)Ao-R)8lBV_Ua&2v>mjNQLSUl0KA~Vd+ zlXrtIfm`;tz4%m6Iy<@PsC+)JAD550wx(FWp7|My%{6MX#+FVHLd)BBTyC6LO+qM0 zN3I8_le`yEM)&ZF$Ar1T$kPXSrW~zWyZ;a7E^5T0S3Z3If4r~zo`F<9TwC8;bx7003-eriOMjs{Kw* z2HHA5*-}IU-5otkJpicBU_EiCr=3M_nc7(bK!g+k;1U7gm{!7V06+*F0JhKofXD*? zKL4lfwwkmH29K*IhBVT2WY7^y1GB%WV-St#e{#=9pG4a*2Af$LF)q^!@hQs)+DGrw z+Lp}>_3W{;l-Y3S>llHa{l&KRc~gcvUFZ;*zwX!N(ZOY6f-gYJm@qpY%%V7=0VN3v!vVoH}QB8P

    S zoSp%7Vk(l&;Eni_RFbwkdcgVzv=8ZO4yEI8rfl7wW0dQbO;-`rZMFK^P{Xh(R;8@1 z%OcAU@;RRtT^Gwg(4N5tsfejAvLWHtlSDd^)IRlHisp%n8&fk2jHQSUnY$CI(!$jg z>5hsd+R0pW)gId8wf|E6wEQwdcbG$HH?-|y>*abv5U)gu_ zTGK^(#rmtACNl=u?e$?22RLKxbYMsuXbT!^1eIBR17&_Luq>Zwnw2~daqhbJtRUaf zAy~yCuY)Eex+2v>cK|1xX_}Z!uWF`RpsAN)e?zd{AkHTn43`)8Ff)zaSfhMySeAJ+ z`#qa}(nsy`BOM&U_xj+dvR*!cnt55Y^sQHFoK(m!m4c+&(3Zza9E(@`E~&BxM=8{T z;5Od$IUf6pxQUw)!aZMOR)%3F2|}N?mwH4|pTt9l+(<-@kLh6-Tj@)U@yDrty@bxj z3~k6nP3pP@tFBj2wSMy}FUz#(z%!^z*S)!}7!DtQ4q`mLvVT^t(bW>^!ZIQF@!Fg0 z9hTMn%~L7q`0tUv?N(;^r>xHt7NZ0UOpG-T1~{>Q8*fxUJ`f%6xN4KTF6Q|GdGXAP z)8S$-9= zshcm^tI37Ewq6PF{F2K*F;F23@~pG^C3p|L77$`I-YtDfxTELxW_gnguA}@MUP|#@ zN;!z`{yGXK<#ZgDKTEu5%?LYRpLETkh0j-$Irjc?&b?wf3~Y#j7*mNVZ_n3e@X}!{ z0uVNY(OBYK|LXgDDom|Mcl6~^mtc01` z^*=aQCVUkBWOa|YROK*oUEew8r%~frl-T8Y|H#rKK7H;Mrzkb=QqJs6$-xJfA#<`< ze7wD9<@z_cK=1yBcn>Nyx3rvY^7|1*axSSQANKl>E0cX#o7R?odWs(IvO0{)g2xA| zrW@o-pi&H`y7is1nM|*j!vZRgnP0yT)AB+wT^4cI3yhTsK0l8PR#I`=ScsZ}f6#L7 z%pXo3UgL2@cT5l_W}z!7x44#C+wKKbaYPB!$)l%T>k#sTBQTt!pIY8`obEj7u*oTA zmS`9jayvWB1trCUfo@CpkCjCC-G0b<6vWjxU%(Q8`FnA;{SwcL{_@Mnrw55c92Wd* zp{~i0kvO_-G5ycHWwo)sshn$~BOUro?lsUo3l*gX$NNSCVCp zZg3`$r>QYT1u0}kUNl+)B;o3NW0O8d#|5Ge1yidzEYz{_+`c!5l`;}@{z zuCF?nD{>#6VX8i;QKDuJEuY)iQV~T-j--cSF(Cp?V<{s}-TZ6PZAY_E{MY>kJjL_% z6k%^+SUmFwSG5*?ay;P?bIATeG4b-g1PM&hus9K((jZi5-T1gRk!U3C=b8_yhK<$< ztbsw#YM)sbv!7#VZvRZ?x&P(HAi<#NQF@1>3vdGYt@>mvFcr|@wF*DrY91eq5) zy*Qjjt-xMWQ636GVhzjygou~L}y1O2!C#s>5^e5?)*^BN}%etVy8#R z`lzPZ_kV3c1$1&3;|RX1RTXU|7L#e^ta&dKX78SMZbU_r;qI$Xu2~Te-4_h=G0+XF z?9nmSbUXj)qptHFFGp3-eCjkm6y$P>A9#kXbtFir#A_e6c-adJlZ) ztS7zQ?OWY4FTFuboRlDZNo#!Ll1_J#`G^PQ&>*Lv##n06A%*{f>j{8aD+%N2bUHpu z$%|PZX22{VGUcfqft*7ti0#T>12fO-Nxi!%ZpweotsqI88f@lI8eCH74k8D*#2NK7 zlI9rKd)}A4k-ml0LngS<{&Mmsl`tG7q|!Oqx2v7~b8s78i7iiNs&xIw72)B9Fqb^9VIge*+mtO9b*(} zkP+pm>_eb06r`emiN1*qn3`D2vV761h9449)Y4zW`7Z5=45;qux~q_*`JgPjFtx_FkTX;l8+B!|C|A_hD*-9X7&0){a>Jjtv zbUmCkZT^!CHbMn^x(8zrw*oOV07`I0bp^Ppf|7>4k}^V75upN?hbtoBaBSbI)_)m% b{XD&HhyQ;AbFoVt%>bAgSsB*qqvQV#KZ+Yf literal 0 HcmV?d00001 diff --git a/res/img/fullscreen.svg b/res/img/fullscreen.svg new file mode 100644 index 0000000000..e333abb6fb --- /dev/null +++ b/res/img/fullscreen.svg @@ -0,0 +1,23 @@ + + + + Zoom + Created with Sketch. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/hangup.svg b/res/img/hangup.svg new file mode 100644 index 0000000000..be038d2b30 --- /dev/null +++ b/res/img/hangup.svg @@ -0,0 +1,15 @@ + + + + Fill 72 + Path 98 + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/res/img/hide.png b/res/img/hide.png new file mode 100644 index 0000000000000000000000000000000000000000..c5aaf0dd0def9ce594a1bb8d9538aebba69039b4 GIT binary patch literal 1165 zcmeAS@N?(olHy`uVBq!ia0vp^JU}eM!3HFEez+qDq$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~;1FfeOmhD4M^`1)8S=jZArg4F0$^BXQ!4Z zB&DWj=GiK}-@RW+Av48RDcsc8z_-9TH6zobswg$M$}c3jDm&RSMakYy!KT6rXh3di zNuokUZcbjYRfVk**jy_h8zii+qySb@l5ML5aa4qFfP!;=QL2Keo|$g4ftk62xuu?= zskym{xsHO7fuX6sfw8`^fv%CUm5G6siID;nC;@FNN=dT{a&d#&1?1T(Wt5Z@Sn2DR zmzV368|&p4rRy77T3YHG80i}s=>k>g7FXt#Bv$C=6)VF`a7isrF3Kz@$;{7F0GXJW zlwVq6s|0i@#0$9vaAWg|p}_t>Y?v6r%cH>i<3s!W`lI|dzdyGJHK8w{LbHf?@!Vkhi=F7Z?pTS$v^3$U_#=DsgD!V z(vtqPhaNuo-2T6O-B0c_+k}#n3nnF{ACdHmmizak{^8$zwh3JPlHb~oDdliQG=F`5 z|9?#OyZ=9`{-2g-3tR9?f%Tl|sy{jtBOX7zyng?q)9?RPe0+60o^8Q>38g7J=cw$Q z@%=Fuj~bg0<4ZrK)0b1&wIc=DnadkJli&V*&%3|j(t;&|tB#yJd+^MU-X}-g?>_OJ dD#I?2z)->P;j;4DFi?TR;OXk;vd$@?2>>$Ip6UPq literal 0 HcmV?d00001 diff --git a/res/img/icon-address-delete.svg b/res/img/icon-address-delete.svg new file mode 100644 index 0000000000..1289d5aafc --- /dev/null +++ b/res/img/icon-address-delete.svg @@ -0,0 +1,15 @@ + + + + 943783E9-DBD7-4D4E-BAC9-35437C17C2C4 + Created with sketchtool. + + + + + + + + + + diff --git a/res/img/icon-call.svg b/res/img/icon-call.svg new file mode 100644 index 0000000000..0ca5c29e9d --- /dev/null +++ b/res/img/icon-call.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/res/img/icon-context-delete.svg b/res/img/icon-context-delete.svg new file mode 100644 index 0000000000..fba9fa117b --- /dev/null +++ b/res/img/icon-context-delete.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/res/img/icon-context-fave-on.svg b/res/img/icon-context-fave-on.svg new file mode 100644 index 0000000000..2ae172d8eb --- /dev/null +++ b/res/img/icon-context-fave-on.svg @@ -0,0 +1,15 @@ + + + + DAE17B64-40B5-478A-8E8D-97AD1A6E25C8 + Created with sketchtool. + + + + + + + + + + diff --git a/res/img/icon-context-fave.svg b/res/img/icon-context-fave.svg new file mode 100644 index 0000000000..451e1849c8 --- /dev/null +++ b/res/img/icon-context-fave.svg @@ -0,0 +1,15 @@ + + + + 8A6E1837-F0F1-432E-A0DA-6F3741F71EBF + Created with sketchtool. + + + + + + + + + + diff --git a/res/img/icon-context-low-on.svg b/res/img/icon-context-low-on.svg new file mode 100644 index 0000000000..7578c6335c --- /dev/null +++ b/res/img/icon-context-low-on.svg @@ -0,0 +1,15 @@ + + + + CD51482C-F2D4-4F63-AF9E-86513F9AF87F + Created with sketchtool. + + + + + + + + + + diff --git a/res/img/icon-context-low.svg b/res/img/icon-context-low.svg new file mode 100644 index 0000000000..663f3ca9eb --- /dev/null +++ b/res/img/icon-context-low.svg @@ -0,0 +1,15 @@ + + + + B160345F-40D3-4BE6-A860-6D04BF223EF7 + Created with sketchtool. + + + + + + + + + + diff --git a/res/img/icon-context-mute-mentions.svg b/res/img/icon-context-mute-mentions.svg new file mode 100644 index 0000000000..3693b7a82a --- /dev/null +++ b/res/img/icon-context-mute-mentions.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/res/img/icon-context-mute-off-copy.svg b/res/img/icon-context-mute-off-copy.svg new file mode 100644 index 0000000000..861f2975de --- /dev/null +++ b/res/img/icon-context-mute-off-copy.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/res/img/icon-context-mute-off.svg b/res/img/icon-context-mute-off.svg new file mode 100644 index 0000000000..d801823b5d --- /dev/null +++ b/res/img/icon-context-mute-off.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/res/img/icon-context-mute.svg b/res/img/icon-context-mute.svg new file mode 100644 index 0000000000..f53b868a76 --- /dev/null +++ b/res/img/icon-context-mute.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/res/img/icon-delete-pink.svg b/res/img/icon-delete-pink.svg new file mode 100644 index 0000000000..aafa87f1b2 --- /dev/null +++ b/res/img/icon-delete-pink.svg @@ -0,0 +1,19 @@ + + + + + + + + + + diff --git a/res/img/icon-email-user.svg b/res/img/icon-email-user.svg new file mode 100644 index 0000000000..2d41e06f98 --- /dev/null +++ b/res/img/icon-email-user.svg @@ -0,0 +1,17 @@ + + + + 6F488856-F8EF-479C-9747-AB6E0945C7DE + Created with sketchtool. + + + + + + + + + + + + diff --git a/res/img/icon-invite-people.svg b/res/img/icon-invite-people.svg new file mode 100644 index 0000000000..f13a03ed70 --- /dev/null +++ b/res/img/icon-invite-people.svg @@ -0,0 +1,24 @@ + + + + 9BA71BF4-DC4F-42D2-B2D0-9EAE0F7F8D45 + Created with sketchtool. + + + + + + + + + + + + + + + + + + + diff --git a/res/img/icon-mx-user.svg b/res/img/icon-mx-user.svg new file mode 100644 index 0000000000..5780277f38 --- /dev/null +++ b/res/img/icon-mx-user.svg @@ -0,0 +1,15 @@ + + + + + + + + diff --git a/res/img/icon-return.svg b/res/img/icon-return.svg new file mode 100644 index 0000000000..80da0f82aa --- /dev/null +++ b/res/img/icon-return.svg @@ -0,0 +1,18 @@ + + + + B542A09B-DBBF-41D4-A5FD-D05EE1E6BBC4 + Created with sketchtool. + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/icon-text-cancel.svg b/res/img/icon-text-cancel.svg new file mode 100644 index 0000000000..ce28d128aa --- /dev/null +++ b/res/img/icon-text-cancel.svg @@ -0,0 +1,15 @@ + + + + 28D80248-63BA-4A5F-9216-4CFE72784BAC + Created with sketchtool. + + + + + + + + + + \ No newline at end of file diff --git a/res/img/icon_context_delete.svg b/res/img/icon_context_delete.svg new file mode 100644 index 0000000000..896b94ad13 --- /dev/null +++ b/res/img/icon_context_delete.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/res/img/icon_context_fave.svg b/res/img/icon_context_fave.svg new file mode 100644 index 0000000000..da7b14a1f4 --- /dev/null +++ b/res/img/icon_context_fave.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/res/img/icon_context_fave_on.svg b/res/img/icon_context_fave_on.svg new file mode 100644 index 0000000000..e22e92d36e --- /dev/null +++ b/res/img/icon_context_fave_on.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/img/icon_context_low.svg b/res/img/icon_context_low.svg new file mode 100644 index 0000000000..ea579ef4c5 --- /dev/null +++ b/res/img/icon_context_low.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/res/img/icon_context_low_on.svg b/res/img/icon_context_low_on.svg new file mode 100644 index 0000000000..28300f9a74 --- /dev/null +++ b/res/img/icon_context_low_on.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/img/icon_context_message.svg b/res/img/icon_context_message.svg new file mode 100644 index 0000000000..f2ceccfa78 --- /dev/null +++ b/res/img/icon_context_message.svg @@ -0,0 +1,15 @@ + + + + ED5D3E59-2561-4AC1-9B43-82FBC51767FC + Created with sketchtool. + + + + + + + + + + diff --git a/res/img/icon_context_message_dark.svg b/res/img/icon_context_message_dark.svg new file mode 100644 index 0000000000..b4336cc377 --- /dev/null +++ b/res/img/icon_context_message_dark.svg @@ -0,0 +1,15 @@ + + + + ED5D3E59-2561-4AC1-9B43-82FBC51767FC + Created with sketchtool. + + + + + + + + + + diff --git a/res/img/icon_context_person.svg b/res/img/icon_context_person.svg new file mode 100644 index 0000000000..fff019d377 --- /dev/null +++ b/res/img/icon_context_person.svg @@ -0,0 +1,85 @@ + + + + + + image/svg+xml + + 81230A28-D944-4572-B5DB-C03CAA2B1FCA + + + + + + 81230A28-D944-4572-B5DB-C03CAA2B1FCA + Created with sketchtool. + + + + + + + + + + diff --git a/res/img/icon_context_person_on.svg b/res/img/icon_context_person_on.svg new file mode 100644 index 0000000000..362944332d --- /dev/null +++ b/res/img/icon_context_person_on.svg @@ -0,0 +1,85 @@ + + + + + + image/svg+xml + + 81230A28-D944-4572-B5DB-C03CAA2B1FCA + + + + + + 81230A28-D944-4572-B5DB-C03CAA2B1FCA + Created with sketchtool. + + + + + + + + + + diff --git a/res/img/icon_copy_message.svg b/res/img/icon_copy_message.svg new file mode 100644 index 0000000000..8d8887bb22 --- /dev/null +++ b/res/img/icon_copy_message.svg @@ -0,0 +1,86 @@ + + + + + + image/svg+xml + + ED5D3E59-2561-4AC1-9B43-82FBC51767FC + + + + + + ED5D3E59-2561-4AC1-9B43-82FBC51767FC + Created with sketchtool. + + + + + + + + + diff --git a/res/img/icon_copy_message_dark.svg b/res/img/icon_copy_message_dark.svg new file mode 100644 index 0000000000..b81e617d8c --- /dev/null +++ b/res/img/icon_copy_message_dark.svg @@ -0,0 +1,77 @@ + + + + + + image/svg+xml + + ED5D3E59-2561-4AC1-9B43-82FBC51767FC + + + + + + ED5D3E59-2561-4AC1-9B43-82FBC51767FC + Created with sketchtool. + + + + + + + diff --git a/res/img/icon_person.svg b/res/img/icon_person.svg new file mode 100644 index 0000000000..4be70df0db --- /dev/null +++ b/res/img/icon_person.svg @@ -0,0 +1,23 @@ + + + + 815EF7DE-169A-4322-AE2A-B65CBE91DCED + Created with sketchtool. + + + + + + + + + + + + + + + + + + diff --git a/res/img/icons-apps-active.svg b/res/img/icons-apps-active.svg new file mode 100644 index 0000000000..ea222d0511 --- /dev/null +++ b/res/img/icons-apps-active.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/res/img/icons-apps.svg b/res/img/icons-apps.svg new file mode 100644 index 0000000000..affd8e6408 --- /dev/null +++ b/res/img/icons-apps.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + diff --git a/res/img/icons-close-button.svg b/res/img/icons-close-button.svg new file mode 100644 index 0000000000..f960d73a3c --- /dev/null +++ b/res/img/icons-close-button.svg @@ -0,0 +1,15 @@ + + + + 206C270A-EB00-48E4-8CC3-5D403C59177C + Created with sketchtool. + + + + + + + + + + diff --git a/res/img/icons-close.svg b/res/img/icons-close.svg new file mode 100644 index 0000000000..453b51082f --- /dev/null +++ b/res/img/icons-close.svg @@ -0,0 +1,23 @@ + + + + +icons_create_room +Created with sketchtool. + + + + + + + + + + + + + + diff --git a/res/img/icons-create-room.svg b/res/img/icons-create-room.svg new file mode 100644 index 0000000000..252bd2df3b --- /dev/null +++ b/res/img/icons-create-room.svg @@ -0,0 +1,18 @@ + + + + 0F9BCC43-B3A7-4C9F-8E34-1F38194362C2 + Created with sketchtool. + + + + + + + + + + + + + diff --git a/res/img/icons-directory.svg b/res/img/icons-directory.svg new file mode 100644 index 0000000000..2688b84713 --- /dev/null +++ b/res/img/icons-directory.svg @@ -0,0 +1,24 @@ + + + + icons_directory + Created with Sketch. + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/icons-files.svg b/res/img/icons-files.svg new file mode 100644 index 0000000000..97ba4228e3 --- /dev/null +++ b/res/img/icons-files.svg @@ -0,0 +1,29 @@ + + + + 7C98C075-AB4D-45A3-85F9-CCD46F84DA7F + Created with sketchtool. + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/icons-groups.svg b/res/img/icons-groups.svg new file mode 100644 index 0000000000..8f89ba83c4 --- /dev/null +++ b/res/img/icons-groups.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + diff --git a/res/img/icons-hide-apps.svg b/res/img/icons-hide-apps.svg new file mode 100644 index 0000000000..b622e97f71 --- /dev/null +++ b/res/img/icons-hide-apps.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/img/icons-hide-stickers.svg b/res/img/icons-hide-stickers.svg new file mode 100644 index 0000000000..f28e8646e6 --- /dev/null +++ b/res/img/icons-hide-stickers.svg @@ -0,0 +1,16 @@ + + + + + + + + + diff --git a/res/img/icons-home.svg b/res/img/icons-home.svg new file mode 100644 index 0000000000..eb5484c883 --- /dev/null +++ b/res/img/icons-home.svg @@ -0,0 +1,27 @@ + + + + + + 81230A28-D944-4572-B5DB-C03CAA2B1FCA + Created with sketchtool. + + + + + + + + + + + + + + + + + diff --git a/res/img/icons-notifications.svg b/res/img/icons-notifications.svg new file mode 100644 index 0000000000..66a49d6c0c --- /dev/null +++ b/res/img/icons-notifications.svg @@ -0,0 +1,19 @@ + + + + 5E723325-BD0B-454D-BE25-638AF09A97AC + Created with sketchtool. + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/icons-people.svg b/res/img/icons-people.svg new file mode 100644 index 0000000000..8854506127 --- /dev/null +++ b/res/img/icons-people.svg @@ -0,0 +1,22 @@ + + + + 81230A28-D944-4572-B5DB-C03CAA2B1FCA + Created with sketchtool. + + + + + + + + + + + + + + + + + diff --git a/res/img/icons-pin.svg b/res/img/icons-pin.svg new file mode 100644 index 0000000000..a6fbf13baa --- /dev/null +++ b/res/img/icons-pin.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/res/img/icons-room-add.svg b/res/img/icons-room-add.svg new file mode 100644 index 0000000000..fc0ab750b6 --- /dev/null +++ b/res/img/icons-room-add.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + diff --git a/res/img/icons-room.svg b/res/img/icons-room.svg new file mode 100644 index 0000000000..d2abb21301 --- /dev/null +++ b/res/img/icons-room.svg @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/res/img/icons-search-copy.svg b/res/img/icons-search-copy.svg new file mode 100644 index 0000000000..b026718b84 --- /dev/null +++ b/res/img/icons-search-copy.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/res/img/icons-search.svg b/res/img/icons-search.svg new file mode 100644 index 0000000000..d85709e66c --- /dev/null +++ b/res/img/icons-search.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/res/img/icons-settings-room.svg b/res/img/icons-settings-room.svg new file mode 100644 index 0000000000..117d134c95 --- /dev/null +++ b/res/img/icons-settings-room.svg @@ -0,0 +1,15 @@ + + + + 69011392-CE9D-4404-A85C-A8548C5D850B + Created with sketchtool. + + + + + + + + + + diff --git a/res/img/icons-settings.svg b/res/img/icons-settings.svg new file mode 100644 index 0000000000..3ca2b655f4 --- /dev/null +++ b/res/img/icons-settings.svg @@ -0,0 +1,15 @@ + + + + 4D42A2A7-7430-4D4F-A0A2-E19278CF66E3 + Created with sketchtool. + + + + + + + + + + diff --git a/res/img/icons-show-apps.svg b/res/img/icons-show-apps.svg new file mode 100644 index 0000000000..3438157301 --- /dev/null +++ b/res/img/icons-show-apps.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/img/icons-show-stickers.svg b/res/img/icons-show-stickers.svg new file mode 100644 index 0000000000..26779a3940 --- /dev/null +++ b/res/img/icons-show-stickers.svg @@ -0,0 +1,16 @@ + + + + + + + + + diff --git a/res/img/icons-upload.svg b/res/img/icons-upload.svg new file mode 100644 index 0000000000..b0101e87a0 --- /dev/null +++ b/res/img/icons-upload.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/res/img/icons-video.svg b/res/img/icons-video.svg new file mode 100644 index 0000000000..d367f49609 --- /dev/null +++ b/res/img/icons-video.svg @@ -0,0 +1,20 @@ + + + + 05D354CE-86A7-4B6F-B9BE-F1CEBBD81B21 + Created with sketchtool. + + + + + + + + + + + + + + + diff --git a/res/img/icons_ellipsis.svg b/res/img/icons_ellipsis.svg new file mode 100644 index 0000000000..ba600ccacc --- /dev/null +++ b/res/img/icons_ellipsis.svg @@ -0,0 +1 @@ + diff --git a/res/img/icons_global.svg b/res/img/icons_global.svg new file mode 100644 index 0000000000..6c07d3c48e --- /dev/null +++ b/res/img/icons_global.svg @@ -0,0 +1,19 @@ + + + + icons_global copy 4 + Created with Sketch. + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/info.png b/res/img/info.png new file mode 100644 index 0000000000000000000000000000000000000000..699fd64e013954b01bca869c67ce3868eb82338b GIT binary patch literal 660 zcmV;F0&D$=P)-bA>~pwRsOBqVpKY)2 z+h?7%zqK`zB)vToKi-~CKSS%Ke zMs+&zi|+UPX0zF7G{WI2#=frHb5cx8-vA=LuA&;xAR+s8UgoKqU~s z2{@}tVS2qj5{cYXvXDR}5WoP=PVgWgIa}5f-BhE|2n1xx-v%TmlSv?e1LKj83qS&u zKmdQofgcxu1S)|*Fc`$&Rcibm5Dp2ANFd;FIPd_W&)g5fA^F(mK2;IDiSBW2mSD5l z)y76R0`sf@0000 + + + + + + + + + + + + + + + + + + diff --git a/res/img/list-close.png b/res/img/list-close.png new file mode 100644 index 0000000000000000000000000000000000000000..82b322f9d4e5b93eff00e47263effa03721c2271 GIT binary patch literal 1033 zcmaJ=J8aWH7n;T~ekG1;t7%E>q>Y55D2>z%2ypCcW3_%@Uy0iR z6^5enSWrP7VL)O)2v`|-gbJ$83^1au6$}hWAeD2Pqzo;V&Ug3g|GxkGAGcC0j7NI< zdN2%&#7T|v~E`co;TGQPy(vHaCHNWU|49- zC|6)bxgct`NveSl>6;EhW7x=;@2J`=fOr+m7*>k-{`w7p8+wYE;uKnOBv3OZ7F{s8 zSSV|Yvznk2W25+pFCqdHKo$4RIm;9M6w%}r(K#?v1m1LkvngU%R7EM`lI;SVBa<vggo zCvA6zVgx~;XqIBx81jgD3l>!UnB@($8D!vTuHit#w(x*at=jW2MIfcSDVR=&*790q zLItCI)u9-Y4pM46D$4&|O|#?e!4lZhyDzaLH-QD)SbYzhI}jTTgz2EjGH{J+K+n0hi8m7$jeWFm znFPZLxr6yySbZNYO>CN`57a^-F;vjrf7;zPp&1H}o#927&iDfh&Af|-yK%X98$FDA zUQU<&uhl<0J7XcPt2gxE-P0SZp@;YHY@Rt}2 + + + +Slice 1 +Created with Sketch. + + + + diff --git a/res/img/list-open.png b/res/img/list-open.png new file mode 100644 index 0000000000000000000000000000000000000000..f8c8063197c28dc79c0fb91e15c82ae45241f565 GIT binary patch literal 1059 zcmaJ=O=#0l9FGjg92U_DviZR?lTpDY>9+~1Tbnd%rP)eXu!0BE9mK;xP&_C&(9NUsG8lLj4|?z@%$Kh1JXixS@4Y|&-|zqRdrR5L2~Yn} zKS2(peAQ22rwrrp*~tm2F7GRkH{|T9->O2W55s)+QV!h#s$& zFQ9^y;S^J+WY>qP=@v#4#OPSfl9dWXpa@Hv5hH)Rc}oIKjgi;F5+hkWENiK{4X5jq zd8J-aSd|>R0!C{bCeR_0K~0}E9Ih54o4g!8yJngMO&3&&k^4y%q%7b~8-g$u@hMCs z3Zg9K4@aY+=p_(f{9&32(m}=-2y!8Y3k5*yBXKlao#AqV*ouX3F|v%1#nE)NTBWK% z%Ct+gpJiE^3DALn4}18Wc>~EcpWzI*83gDkwq_yCG=R$}7tJ{oBXOqtCFoX%)^J*F z!VRNqvPJtT#x1GsC`tc!)%A|IgL3d7-+vN2`FRV{Ip~;kwt@#YGwg=4INpXbGVQ!+ z&bGUlEt|-6%BBT)zS%Y4m1IRTT;s(iN|Ly=;UL*iU|NWgn1|9dl?x|A{xB;FQ9c>* z`;%cdEJoQVBSbF8`CuX-wy}b#%<0fTZLE5LO?Jh)g3v7-S%9{78>*sh>Y!OTr*+RI z(Uq@-RlDcHcg4~;8QLB1U*m3@u!h`YN4)sbkv}xB=4~wQ!!N%K;D@oA7UKEZPVx8N z-dGRkef=tPJhfW_ME%z@X5+E7wtH-2`KU_V=-ql)@eZ70*N;LHOszl72y5pzvm>N$ zWG6dvV&Sfrf09}e78V1mtJ^<^uHJ7j{HfgMcN61hrhGl|MfU5~_sn)^CEs&oNL+3R wgW~gsa9UhxTo@ETjz93cFM;ce4PyMxAtLvU?ETR9>5= + + + +Slice 1 +Created with Sketch. + + + + diff --git a/res/img/maximise.svg b/res/img/maximise.svg new file mode 100644 index 0000000000..79c6c0ab8b --- /dev/null +++ b/res/img/maximise.svg @@ -0,0 +1,19 @@ + + + +minimise +Created with sketchtool. + + + + + + + + + + + + diff --git a/res/img/maximize.svg b/res/img/maximize.svg new file mode 100644 index 0000000000..4f9e10191f --- /dev/null +++ b/res/img/maximize.svg @@ -0,0 +1,9 @@ + + + + + + diff --git a/res/img/member_chevron.png b/res/img/member_chevron.png new file mode 100644 index 0000000000000000000000000000000000000000..cbbd289dcf4a780581a0227433a1a9278c34bc49 GIT binary patch literal 271 zcmV+q0r38bP)Px#$w@>(R2Ug!V1NQ`ZEZFf8<}PTa+r*bjTf@BvtQ8B(Gf?M1hE+n4Go={n3(o} zIRF3uzy9mjFUKoauDk^CL4f(iix>ALB_$bwzyXLwnVFfrg@uLJyn6NOD_8-Dc>etP z0bGihK?*lf=Qk`cdh}%26<*2oYoLAxPgg&ebxsLQ0F0g{u>b%7 literal 0 HcmV?d00001 diff --git a/res/img/minimise.svg b/res/img/minimise.svg new file mode 100644 index 0000000000..491756b15a --- /dev/null +++ b/res/img/minimise.svg @@ -0,0 +1,18 @@ + + + + minimise + Created with sketchtool. + + + + + + + + + + + + + diff --git a/res/img/minimize.svg b/res/img/minimize.svg new file mode 100644 index 0000000000..410b0bc08e --- /dev/null +++ b/res/img/minimize.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/res/img/mod.svg b/res/img/mod.svg new file mode 100644 index 0000000000..847baf98f9 --- /dev/null +++ b/res/img/mod.svg @@ -0,0 +1,16 @@ + + + + icons_admin + Created with sketchtool. + + + + + + + + + + + diff --git a/res/img/network-matrix.svg b/res/img/network-matrix.svg new file mode 100644 index 0000000000..bb8278ae39 --- /dev/null +++ b/res/img/network-matrix.svg @@ -0,0 +1,14 @@ + + + + + + + diff --git a/res/img/newmessages.png b/res/img/newmessages.png new file mode 100644 index 0000000000000000000000000000000000000000..a22156ab214514fe3be87b85415fc8ad9ade86d7 GIT binary patch literal 590 zcmV-U0Px%2uVaiR7efARy!|5K^Q%=60Zauu~A4g3Z+D&Q3@d>qOc0AMi3IcsQdtl#9KjY zLntWt2kKQw6e22(ct6H>=FaZA+}XVz_au`$d*{37d^7VsRv`~G2I_#4Za{U&Xb{u5 zHNOJ%xr_tgX;)$U(nX_!7Bq&1NX^OGkUWcmY;y1Po6I*vY*t}ig#Gv?Amm*_x+SB+ zZ(8V=z7>&#i0pl~jD7y0k(>l#sh^XRg$~719!HKfy93X2lEWvOGYvg^2i|)!J23+G z%+tT~JV@9aS0nGlddmw9apv>Az<65_~|0qP_6mTQi3RIT5*Q+I123p+fvOADUj|-SOkL0i%1gA;3yCIoE|eDo`x8K0qsO#!D&$MRtCSrl zSjHdgZ7mvE5rL%BmJ1X~jR7}zz~EW|a(4eDU+cVt?1K}`@ z$3$l~4{ZIGoBWdq9h}be0(xVPh?5K=ZJ8AD)U||*UX_tA2CYxDF}7?lzJBcSS+k(W cfBbFv0K)*Cq8-F~hyVZp07*qoM6N<$g1{I5)Bpeg literal 0 HcmV?d00001 diff --git a/res/img/newmessages.svg b/res/img/newmessages.svg new file mode 100644 index 0000000000..a2ffca9020 --- /dev/null +++ b/res/img/newmessages.svg @@ -0,0 +1,15 @@ + + + + icon_newmessages + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/res/img/notif-active.svg b/res/img/notif-active.svg new file mode 100644 index 0000000000..9eb279f851 --- /dev/null +++ b/res/img/notif-active.svg @@ -0,0 +1,20 @@ + + + + E15782FC-B5FA-472A-AE12-CFFF484E7253 + Created with sketchtool. + + + + + + + + + + + + + + + diff --git a/res/img/notif-slider.svg b/res/img/notif-slider.svg new file mode 100644 index 0000000000..55fa06d11a --- /dev/null +++ b/res/img/notif-slider.svg @@ -0,0 +1,22 @@ + + + + 16CB4618-0BD3-4568-BB20-FC56EBC46046 + Created with sketchtool. + + + + + + + + + + + + + + + + + diff --git a/res/img/placeholder.png b/res/img/placeholder.png new file mode 100644 index 0000000000000000000000000000000000000000..7da32f259c1a90d721dfc9abc4ad427ab9e7c5bf GIT binary patch literal 394 zcmV;50d@X~P)ntlanzq{fbCjfCT%hE_`W?6RRV+Y`~D2n@8z07%@=Tuia0Fgm_4E7hI zgjnH=q~EA_vkiP0O6pa0H)#llu-yUw)TKgXy8 + + + Line + Line + Created with Sketch. + + + + + + + + diff --git a/res/img/right_search.svg b/res/img/right_search.svg new file mode 100644 index 0000000000..b430a6be19 --- /dev/null +++ b/res/img/right_search.svg @@ -0,0 +1,17 @@ + + + + right_search + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/scrolldown.svg b/res/img/scrolldown.svg new file mode 100644 index 0000000000..d6599c5fc7 --- /dev/null +++ b/res/img/scrolldown.svg @@ -0,0 +1,15 @@ + + + + icon_newmessages + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/res/img/scrollto.svg b/res/img/scrollto.svg new file mode 100644 index 0000000000..75df053a68 --- /dev/null +++ b/res/img/scrollto.svg @@ -0,0 +1,21 @@ + + + + Slice 1 + Created with Sketch. + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/scrollup.svg b/res/img/scrollup.svg new file mode 100644 index 0000000000..1692f2a6c0 --- /dev/null +++ b/res/img/scrollup.svg @@ -0,0 +1,91 @@ + + + + + + image/svg+xml + + + + + + + icon_newmessages + Created with Sketch. + + + + + + + + + + diff --git a/res/img/search-button.svg b/res/img/search-button.svg new file mode 100644 index 0000000000..f4808842ff --- /dev/null +++ b/res/img/search-button.svg @@ -0,0 +1,15 @@ + + + + icon_search + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/res/img/search-icon-vector.svg b/res/img/search-icon-vector.svg new file mode 100644 index 0000000000..5780277f38 --- /dev/null +++ b/res/img/search-icon-vector.svg @@ -0,0 +1,15 @@ + + + + + + + + diff --git a/res/img/search.png b/res/img/search.png new file mode 100644 index 0000000000000000000000000000000000000000..2f98d2904822b67ecfd0096434d22d17443c7e03 GIT binary patch literal 742 zcmVPx%ph-kQR5%f(R7*%zQ54<#oa^T)BqiF%iDeX7U}YK-hYn0$GZ6pnHp!sxo z2MtoRiL)rACTC*r*u3SyG~6?UqYZ%@g(#pH7$%w3gak1~ z0P7iWBLI2Gg4=ER70>KBPVus-x8GL|fZM=Qoh^BlL$TtzKxd9bQGqOaTXvV;iskL= zCDW$_E=Ou=tv~yVimSJS2Bzw zwdS0jL&Of0c%re-pJF$%$09vN?hpbeF72%vwi9mg#a*T2h};Wk6}V{xKwKsfymb>e z;;e=MVY?%zL4iO?3_Rr~aKaTCWHx(|VAotwZ3mvNM+yTG+)g|7OTcGi9P z=R<~N1`7V@mLaCq>|o?myg~m~H&HCk2JBN|9*D)GYjJr`O;{k_0kW!0-Cj|`ZLaU{ z&eLC)#fF@A)9C60H18~X0?aSxS0&VY16>>3#7zUfTmz|+Kwd+lQ%wQi5hv~PHI0xB zFS?HlprcIqNMDFy$uqBs;yoneGlT*8sBp7x{?Cfk8x>l(8|U%VBEzfZo)JHorhX=V zj9*M6(7Av=Em2wps5o02r0SPSF~X!E4o-eue3+S@OmmCjv%30BQ{k&J&8PvS(ER%~ zSE4uaH`AY+tvH!%irL_nGD)xr4Q^KoP9k7N(w9)1dGO4_Kbb~%Y<%uJMgk9^pmqw& z0{x2$zr9PTT`E*m^tW?!ZuvbT_9J1Pf%0i2KVj{s{r`2+=ph>Vy0bv2Y6ci@?HTF# Y4jDfV9bl4!EC2ui07*qoM6N<$g2TyJ%K!iX literal 0 HcmV?d00001 diff --git a/res/img/search.svg b/res/img/search.svg new file mode 100644 index 0000000000..bd4cd9200c --- /dev/null +++ b/res/img/search.svg @@ -0,0 +1,17 @@ + + + + icons_search + Created with bin/sketchtool. + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/selected.png b/res/img/selected.png new file mode 100644 index 0000000000000000000000000000000000000000..8931cba75ff298fb0cee26b0d8ea1f7377f3fa7b GIT binary patch literal 995 zcmaJ=J#5oJ6h5`6LY2B9q_S|hODi=#+lk}E#4T+up^ny`Q_?s9&6#JTnOZ zn5wN{EB*6#`s4)v{(SQ2PkLaL7F(rl*0m!7mR!0GmezkpjH%R zRnv0XJX9oEMN$@JrHqo*bCRA@VE++#w8(Ai7OwVV@slBR7z=fTy4|kW&5ATyM{==P zM3RCOCBr>3@pi!MBoo9l0|rcDC-Oq((Ez55_8Q${hQO5`q~M1`+92+ii5Cndc8FwA zN>ds*n&$sqeShd3Gm9MRJ(f6bZifU}B&J)D!yDJ0NkfHtIU+WrQIpcmK@}Sv%4po7 zAuN}BRfDsp?RY_Ioa>=XQ?CUvvjd0Jupw|B(eqrrA{DW;Bx#zQ#j;#c3prWCg(_Cm zTy+^23Ii;r&X!LCHo&@v*uqF`IuL%yBV!VIH;7w}s1JLI>)vQB>PWsm)*Y=SKN5?$ z7?ig6NV^9nK11ntIK2EY9Dfq_%Q_{F$f!%NNN^Zk#{rog#VuNyBu`4jj4 z;#Xk*uC?&^tu@__-#_>=HvjU-`u6ah{q@6K=fvEdvBMSK+CRSs#=-Z~XRm?_`CsX^ Nt5xdw>GHLk{{SlNH*o*} literal 0 HcmV?d00001 diff --git a/res/img/settings-big.png b/res/img/settings-big.png new file mode 100644 index 0000000000000000000000000000000000000000..cb2e0a62d06f155ee89c02f6d5ca202fbda19e2e GIT binary patch literal 810 zcmV+_1J(SAP)Px%c#KELZq(h~PlY)!TMF+J| za41Ct>!2Vgg5cmJRtL4k=3|l|u9Xf-o1g)$pyCG-Bux{4C+6PVywJopUbsE~dp`c> z+BmSwrcy;7-^!6%Z*ZWiw=Tc z1YDp}8#%%3HGRP!v0X+=kyEy9dx_~njwcd{`^r}*pz>3YOew=gr6ggDrc$Y=0?a!Y z7DcCnB4zi-6^~BfcDpaK<)6y1Q3?51kH>RK#k&+(TwMI&_xp3)K}S2`4$jQY%`GTi zy#rA|zF8R@a+%6T(H)Rk!^;kz>T-2;wa3(3u~;l3JU?(urPX>>kQ561_%Qs|bzuPwSq6uO&CXTegf>IkQe*kMBNIQ42xY_-SNBo{{r zUa0`5Y-Ov(+6{N$B={d|Tei`P2z&op_Et8D!Cr9%gTWWb1-APRxeK|~BxHTa=krbH z^ZDPVUM`t_zlUy%si$E+vrfP@Ls#BzIDal}1j1WpKn+WqPGYOx2e=v3R9Zav_9c8{)cP89D)mnKh2*uje}c!u3SC>&Gsa%e@JOLSINSfP-9C0eqhM zjP*eR8oCAjC*~OX8Rk)ZJVMG_bd}?|D_Dk3Ad74^J5Q4LkZ&j8G>#b(zYPQeduV`t z;$w^?_8VgF>+5??%wB9aO>*&V`X=+A!XxxD^&nYRFX}*jueHKW|mI{*Lx07*qoM6N<$f}6>B?EnA( literal 0 HcmV?d00001 diff --git a/res/img/settings-big.svg b/res/img/settings-big.svg new file mode 100644 index 0000000000..c9587d58c2 --- /dev/null +++ b/res/img/settings-big.svg @@ -0,0 +1,18 @@ + + + + icons_settings + Created with sketchtool. + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/settings.png b/res/img/settings.png new file mode 100644 index 0000000000000000000000000000000000000000..264b3c9bc3fae654afde7a755cb424cbf46debef GIT binary patch literal 391 zcmV;20eJq2P)Px$K}keGR45gNk-EhQJIJUjxGK3z*Cb}m0Q0cEsQ5#=2rL~j+zak6OKH#)47;H?;+p>iZI6dg8O1v z`Pv_GhMnhh-nNtm|7rb6(WFMbq!5mb*~#iNsk{;ExBvkiP}IM&BiOqSigJ%;oE-F( zA69FHQeay`;O#-CG*gUQCjP!dZ$&0@!_2PC*h`Ge`$V(`!0jmdST_8}I~h>EYfL#q lsw<;orf|A8>vj!~*B3OzZD + + + icon_settings_small + Created with bin/sketchtool. + + + + + + + \ No newline at end of file diff --git a/res/img/sound-indicator.svg b/res/img/sound-indicator.svg new file mode 100644 index 0000000000..9b8de53d81 --- /dev/null +++ b/res/img/sound-indicator.svg @@ -0,0 +1,17 @@ + + + + sound_indicator + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/spinner.gif b/res/img/spinner.gif new file mode 100644 index 0000000000000000000000000000000000000000..ab4871214b14361e4491cd549bb05a7e49a190ac GIT binary patch literal 34411 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 literal 0 HcmV?d00001 diff --git a/res/img/stickerpack-placeholder.png b/res/img/stickerpack-placeholder.png new file mode 100644 index 0000000000000000000000000000000000000000..7980114438527db8e140b9ff0bcd80a7fd8282f2 GIT binary patch literal 31995 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 + + + icon_tick + Created with sketchtool. + + + + + + + diff --git a/res/img/trans.png b/res/img/trans.png new file mode 100644 index 0000000000000000000000000000000000000000..8ba2310a063039172ff652a857f7f4ce80fa7f39 GIT binary patch literal 959 zcmaJ=O^ee&7!K~GEEdF*3c`>@SixkHv}u~qxMY*o4VY586?@z?nYN)#CMHvx_M+=; z!Gqq#A0Q$g^yERWp1k`5yn2=Ouui&d*Ml`MnVFaOdET#QPFl@-#qAs048s)d1FKE< zEBPv1qW>2!hZVYAC-p8l#C(3s2MKy-m+6_8g(sk}@9u9do z_u;cJrf7z#?Pam+jSvAnGzcP{{rTxL3j$wfAIgs4#3mXB2lE6S&YK-?KJrwb-Mb5F znMMghL|l-C<0#cKon7#1^qiX^3l=V9q_gKqb)6P4ae{!%S2$0oC_qtpQC5_)atBC) zC_|wHO9CgAw6dU;C9wQh8ZGhrTH9(YW6_(=4he}h2&dC2KP~Y%89-50RVYYMk~r$Y zrL%~*85gBHD+UXtUJ}G4z!At9-5#D0ou!$cmk`El+9+MNi8c&oZVW|U$V*x|I?n%H z!*K1Lk~X@?_n*XRXBH#aMk$^o9vxhNCl3{CW`bOTlMcq?RTo=BOmI5HF)+%9kB~h%))w&@YWy3P1sv%pVw8C20 zn}jGLE3AKkH8x^%L4+}lY@sB0jQmD|L$D}Z3pVGXY~)*F{mr>lH)0`82Ik}aYuqan z)lhz1iUf(R}1{rUgj{%``D4^Oj9k5$2y#>IRxr4LpxyUSX< zIuOX-XH}45J)t$C^=rCarIC^Gd8Up3|NotRE#=gH*~oqGzPL|%BJKNQTkzFJg~O7P z5-A5{I$SqhnIiu$Q$R%bz`Lu$25g&F>h>EybE_`JFd1T*0xN^U0frATPF@pQo*f6e OjKR~@&t;ucLK6TpLRvfk literal 0 HcmV?d00001 diff --git a/res/img/upload-big.png b/res/img/upload-big.png new file mode 100644 index 0000000000000000000000000000000000000000..c11c0c452deddeb183e61f53918e6870b4a8fca5 GIT binary patch literal 1669 zcmV;027394P)Px*KS@MERA>e5ntyB)RUE+Idw1Q|b3P(TxXiBev|dp8)~JRh%3 zJOGN;BMF}*l>cR;q0AYt(SZJY=l2cwrf5v8EQ#n?gQ2`7&=$*`u!u6y`hxNw5()YM zhDs78-UgmW^G!BO@q_vpGK5NKl8*G9i$OPP74x*p+oaE9#vFRy*oDl9(xP>?#`&>0Ah9S7Mn}hMb(GRfrt@*pqOSY>)J!?v01;j= z7&}Z>byyw~4*aYG;8D!sw!(_Lu5PY@Vm!s@u#~d8Xp`!&evn~sHvw=iD}Pp8=F)lZ zenK#wu+DL?+%KbedsMItBpt4`0G!VXf?-9kwySRoMRYWDi6u}4!+hlQC}9~14_6fc z&tV0jc$qsrh5r;Lj$tPI!Q}!KBJxCRWCm48EP@LGxCAaNJX_Z9q^|7{;q+d|Au zmGyDi^f+JxATL5@IRNv!3@bc3XWI@6v(vaq(kkJUz>8ZVG!FsB~B0-R{cx}&>p4-7b%1i)iNbV2G$T_+s}9Q^8h|eV@J7S1@k?*Ho!K4tyO4)Q zeCg0w^u+j_v=Q!>j^A5hDw)XaJQ7$x@HGGyMy2VWgewQ?eEpEMg-y_lUmi34vZ=MH zkN{~yVU6~t*)To5Em5i2Tu||OCATEJjA83)15k@H5oD{Gec~zu%fV zHh00-5YbAX6H46>)7R?r7ax>!y4g^1(M!c5c%bY4_PjKddZzl^fiZION_A1gvbkBC zJ^VOE*tdm-mHj>V*3iXR*Iw>+7=b; zDmb_!BeV9hfR7AFfUj zmc0~1bm%mAC}c*U5B?=0I%`vYr7fIMx%zGS%R9Tpd&OX(g|$PU&(?7GbgjK{nw-2` zog%EB=t{t{F9HC1g?hX*8}chI$r)3sgT0osTXfBXCq6MCi?cXHYL)Z??TWDOe$))c z&%mVqEi9mm%rh#l1(ajC190!P_RFt=&8=`<1iOvV+EHA{u>JKcqU*gbqe;SX9^_8sxBtOld5D4S4N|Ly^{;OeC0q@Ye*lhdtQafQfAB6SLmy}s`O z)N>Q3WrFnBEjbAsRJQeyRNt9EoF-LKH`)$OfTMtvj|$5>c+N$?5i`(wV`~#i^w&r6 z(AWHI)uv{6p7DC5g`6n)w(D?Ut?qYSF#}7I8_w0POB!;te(D=nn4SLs0qRLaZB)O4 P00000NkvXXu0mjfFq$ce literal 0 HcmV?d00001 diff --git a/res/img/upload-big.svg b/res/img/upload-big.svg new file mode 100644 index 0000000000..6099c2e976 --- /dev/null +++ b/res/img/upload-big.svg @@ -0,0 +1,19 @@ + + + + icons_upload_drop + Created with bin/sketchtool. + + + + + + + + + + + + + + diff --git a/res/img/upload.png b/res/img/upload.png new file mode 100644 index 0000000000000000000000000000000000000000..7457bcd0f1380362c431cab9ffc85a3e1d242e29 GIT binary patch literal 713 zcmV;)0yh1LP)Px%gGod|R5%gURBuRAQ4~Mt?mZ`S=Csy7A#m#tLWP=E1eH-xK?oK`wq=DyN(Fsz zYuJ|&^dYAN5d=Xe>`O?9AY@@t&?H^t_U`T8YVh`anqNEcc=!B% zzw_hV`_8)vJUq`k^A$55LV&e^m?yA|pmat~k(Mi)YsWM2zX|>^fM%c=B20RDwfyj; zR_Gq;ybORjG?}{5x}|PR%M;OoFz{_U+N)*}8EEBPX9P;y( zmQd#g1CjQwDBHQeu%w4#s?i%fMz zj-(g!y>n$#;@#v&A(7TEDy(W)vnR|5Iqr#emHr0jD^7D8Ek%z9zYN!hzm5VS1_AHR zmgM9QoT+aL``e_nQ14w6tTC*zRp)P8Vv8`wCO#*=mr|s1TKn)r)HbGk%AeEZM1Om> zH7_d&$SRwn9aV_H4K^W?uiTlOvT&u;{!)K!e8O)$W9=KwG1EN4LW|^D~ z-&xE|*&$#sK^eQi5JypggZ%6GT|*tU|1@z$+LxPT=@}Qse2+$)2$&Q_E#;2>WD552 z#;-TU0;jb`nVq0)=fmgsl{p&0>!oV(wF*asDatNBS9Ucn))@!ut8fl*Ogy^LT2c3w z6CN#@*@>22VE&(&AW*iD9TBRqN$;C>i=KEYfdk0sB|T1H2+WdVBrYL=k!fPw%CTOp z_~v%UH;#q0xXAg)uVlci(>OIQ8K&5M#SG1^*j7k+8;fqSno`lPMQIV`AO#b?+#Cv$w{00000NkvXXu0mjfId@az literal 0 HcmV?d00001 diff --git a/res/img/upload.svg b/res/img/upload.svg new file mode 100644 index 0000000000..039014a2f3 --- /dev/null +++ b/res/img/upload.svg @@ -0,0 +1,19 @@ + + + + icons_upload + Created with bin/sketchtool. + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/video-mute.svg b/res/img/video-mute.svg new file mode 100644 index 0000000000..6de60ba39b --- /dev/null +++ b/res/img/video-mute.svg @@ -0,0 +1,17 @@ + + + + icons_video copy + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/video-unmute.svg b/res/img/video-unmute.svg new file mode 100644 index 0000000000..a6c6c3b681 --- /dev/null +++ b/res/img/video-unmute.svg @@ -0,0 +1,18 @@ + + + + icons_video copy + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/video.png b/res/img/video.png new file mode 100644 index 0000000000000000000000000000000000000000..2a788f6fa47f1338fabef245a737cda1d0377d89 GIT binary patch literal 514 zcmV+d0{#7oP)d7)lm$T3XWjg6AjG02z{1VSNYH|>zyDwR@aMw2 zKWXZmcYJtkNgkt6KG&wu-$|GN6&Z@416DnAQ~4=4xEzWtqe?K>MYql*;lvU@+j{rQjL z0}8=|&wm%*`4OSWF2MzI^r08O(c^#;08CM9AN=%{WrLUw1phH3nG$gE-ERdRCS^Wm ze5r^M@c8RLSso?=$&?cC>)(HNW=0xXAk5D6`ujf`TA(My0xUCr{QXZW3uL&NEks$D z-u?OKAJh&;>RJE8+AcVK=YwKxK4L2{&=v@%MYYt4G~1Z+5=d=lj>@q7NACC5oSh4WLF|A z0M<>wlmIN>fsP{5?LfsqEkKQfqskm@wv1XpE&vEH08)$A)rqLp1^@s607*qoM6N<$ Eg3xa3E&u=k literal 0 HcmV?d00001 diff --git a/res/img/voice-mute.svg b/res/img/voice-mute.svg new file mode 100644 index 0000000000..336641078e --- /dev/null +++ b/res/img/voice-mute.svg @@ -0,0 +1,14 @@ + + + + Audio + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/res/img/voice-unmute.svg b/res/img/voice-unmute.svg new file mode 100644 index 0000000000..0d7e6f429f --- /dev/null +++ b/res/img/voice-unmute.svg @@ -0,0 +1,15 @@ + + + + Audio + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/res/img/voice.png b/res/img/voice.png new file mode 100644 index 0000000000000000000000000000000000000000..5ba765b0f45e9a35a684c175d85627cf7d3e335b GIT binary patch literal 856 zcmV-e1E>6nP)^!@8X_13^p13SqhafbC$a7rt?<0Kl?Iy4hbW&SsExPZe~8yV z8ZuqoN*60Xjto}_0acZKoyp1;At0nZx#|(w2t+-rrbF>a1d@$&@Kh2M3Zaz=KHUTnNAP{)q}39SKoX9z^AOj=Pa?7{ zIR_B}ZW`U16tcyO00|NSN!P<+D*}cEciMD$PwR57u-;@$Iueh7i$7mV=+QLGCcgM< z!NA9kUT7H<%{KUhYaXUX< z7K6V5{I1l&x>^I#VMr`sf}xot);V2m0J6)mBDIGdN9wbRHiyZmmLMO2G`i%pk;k=? z57M4v0ddCwI&Ol^C}$!t7v|?3?A!;4SNNWzeDZ@&@9(v&Pd~WEl8{)z5glOt8$%CX zXv#VDWfl=bpp>3~FN5#c&L^Gb=gmWjEA`-XZS#)OG3BFVqz;tAlsxxFnER{JapGSs z1UBuOays{{$sP>aBBjir1Z6`Z5@%{ + + + icon_voice + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/res/img/voip-chevron.svg b/res/img/voip-chevron.svg new file mode 100644 index 0000000000..5f7cbe7153 --- /dev/null +++ b/res/img/voip-chevron.svg @@ -0,0 +1,12 @@ + + + + Triangle 1 + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/res/img/voip-mute.png b/res/img/voip-mute.png new file mode 100644 index 0000000000000000000000000000000000000000..a16d1001e5778aa10fab9bfaae24082e9267fe6b GIT binary patch literal 903 zcmV;219<$2P)QAt0009fNkl?FQBahITPKj%167p zA&D`_**N1{C&xOzt9AYBj+zggGzsd`Tze81J^Xaa_ACYfVcYz;DJ#2rE^q*#sp$4U z$tP1zS9dm$Mc*#9-yY{D$N2xwZ>=Rk24{Tx=4$M_c(x$YKvbzI2jS)D0PtZ^e6th_ zWQm~}U!-jEa$Uch>s|y$Ha&{vP+dIcAWO@l^_H1%x_fJaotP#)9Jg6|nkE{0RkygU z91i`Xr=NrMmRYXrjg1})ZfXH(Al!eWCj_hixSwPbNy>24gpS5-jzBuhMApEZiJdSiE&3i}0UZ1B&@v}FbpF=q`M4SO*Y*ZjY2Z%^g zIaKEgf-?XB&w{*z4l+%zq6b89XH%Ze@tlLNOihu2*{|+?O>qYAOmy0&4Il$ekY>;< zWQnHf3@$}_PvCyv)w2chVyHhOUCQ!}mMOS6bb?ZrKd7k>CdDsXsv&7%Q_lF-$P2{$ ztD!k#Z)EsyHFYA(hfZ*QQv9$XZDi*P;^xyhXJe4*L|Lip@7LvAU_XhpCYbI$asA}F z9Lk3^{eIrMTa_(ES;59_REDZ;GiKvlU^gUPUx_c3+wEo}G9bZ?)!5;%S~nvWJCWsQd@GXlQ&lZR+IQK-WA?a> zDWzghFQuXRz(odIZF7AkK9%K_T}1$&pK`r}C{dp#hiy|1<;PS1E|ViJj_oUR(Zd5q z@A(2n@ZDN6TM!%8+u`*BW*2B zXME9TCj-4?%aQu}k7l){zN$27kVT2U`mo=%E)f0QG#83?-sO20zkJZdzG!QL3q?CU dO<#l0?=!n`xSy>aQ~Lk_002ovPDHLkV1lG(qs{;T literal 0 HcmV?d00001 diff --git a/res/img/voip.png b/res/img/voip.png new file mode 100644 index 0000000000000000000000000000000000000000..e8f05bcc377931d95c8f8e5374f7089218841c07 GIT binary patch literal 709 zcmV;$0y_PPP)pnrU4#H^*uqKIoXD8{0cZ(* zXW7rC@WiN@GJ#fVUHxQDjMzAxxBCEaYq5KD$e73&zpT%cgM6A&vEq+o{C24!ZDhYk zCp(wpvun~djH`fNjk&IDp>qG#n9lhU%sNE48$RQCxpcq1Q0T~lI8AZu$ z&jBJI%Y$<8>XVGuh|p}VCdutW-YyOrJImnpXL;>d3Rs9N5`^Fj19<6>{k$f2oPhxh z00uaQEV9ZelZ`R75n>Yk+eIdg#^_M#uMTwm7%4{rmRRFuy&!G5`*yjW-Q>I6^{k0H?G3QAJn?C&&4{4}m9s!dPjkhpS>b zZ!LT3o0g2-wClN=SZJs#MVrD=a~|X{WTDhywW~804Fikj&)pUOa?u%!rf8da@UkwR zRV68X)Io~d@HIzp9ZYkePEM#-i;kPZL<48ZQ}@fkJ`;%ODc2;fo>nDQ-gV&o0gH0# z&(N=THL-EAV3(S*qu7}&-x!~LYj#9Y#`+$S=JOv$k82g1?QAQ1j=0-7K}k?aT|*jfFV3$P7s7 rblL0kZH#4`s5+ao{^`Hz7XbzUlE!y4)*4tA00000NkvXXu0mjfM=wK% literal 0 HcmV?d00001 diff --git a/res/img/warning.png b/res/img/warning.png new file mode 100644 index 0000000000000000000000000000000000000000..c5553530a8478d549139c265bec0492be4252d7e GIT binary patch literal 1478 zcmeAS@N?(olHy`uVBq!ia0vp^G9b*s1SJ3FdmIK*k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m^Cs(B1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxOgGuU%v{0TQqR!T z+}y-mN5ROz&{W^RSl`${*T~q)#K6kLNC66zfVLH-q*(>IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD$Tv3bSNU;+l1ennz|zM-B0$V)JVzP|XC=H|jx7ncO3BHWAB;NpiyW)Z+ZoqGVvir744~DzI`cN=+=uFAB-e&w+(vKt_H^esM;Afr7I$IMft0d=ry1 z^FV@{U|qhxR-SpqC5d^-sh%#jNH{644~kx-=!OXa(-4RWPrN`5Jo%^Q0n>aD zFma1kbOSRMlZmH`V@SoVBpvJhJ&m^-Ivd#<)Y>))EcW>FFMR$zYo-4Eu|Z^M_G=T(ulw@9=XP`oBy9V)^U}-jB9dCgUnk#t z7oO2{Pxzg|pa1^*7S0oXZ*<7AkBO&hj>7D9wa2z}MmS&X+Z)>WE2QD!%aXR*yF7n? z321&_`F+N}KgxG6{QqyOcCWS2LZaeeVAWH`7X42zcHg{}t|Fba;qTHfYxQ3&dh@1W z+37dGbMF72l%VnXeZ2#}kVjU2{cXKEm!^ectLJgq{&qCjdQ-pV$lrJ3fo+>=|2{VP z&baCZKU+@NhWg*HO`bCbwlTeR_j{Z0q4D88^*41et`Tb_yALW%kOv{8%&YoW=rS<2-?3-3HEBi%f%=l*@Q`w=(e5Pog@VkdP zOKq0jOa9lb9Q=B!k%f`Lo8x*b>mIHBw6eVXY|DjME*SxyFHyD1#^)Emwebp@P3Jh+g7)u-(A(AhdCzZNo%t5_|I$>B zu9+`$rhn_tKDX2F&V{-8FQ4yvGkjYH@4aIz4h@V9Yt2rEe*eW<3@TYYUHx3vIVCg! E0HiWF6951J literal 0 HcmV?d00001 diff --git a/res/img/warning.svg b/res/img/warning.svg new file mode 100644 index 0000000000..b9a96a88e5 --- /dev/null +++ b/res/img/warning.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/img/warning2.png b/res/img/warning2.png new file mode 100644 index 0000000000000000000000000000000000000000..db0fd4a897de34f13f949afd4f3c73a6c48f3b4e GIT binary patch literal 1420 zcmeAS@N?(olHy`uVBq!ia0vp^av;pX1SGcvS$+jlk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m^Cs(B1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxOgGuU%v{0TQqR!T z+}y-mN5ROz&{W^RSl`${*T~q)#K6kLNC66zfVLH-q*(>IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD$Tv3bSNU;+l1ennz|zM-B0$V)JVzP|XC=H|jx7ncO3BHWAB;NpiyW)Z+ZoqGVvir744~DzI`cN=+=uFAB-e&w+(vKt_H^esM;Afr7I$IMft0d=ry1 z^FV@{U|qhxR-SpqC5d^-sh%#jN= z1y1vzdQ)(_#S*7peV}9XLD7p8-7q0w8Uiuli5JL$C;!wuV45!iCT{(x|F0Ps7=L-X zIEGZ*dNa*d$2m~s_SoMzdN8xUwIh7pTfGyvAAD)s&8vFh%JCDgmwn`zK21^9%rB|YEW#l1 z$EpyYChZuxj8-xE2}P2hCOh@oY9IdJvM{`F<3F+8JZ7fXc3)KI=U=((=JUy-zU^z~ zRK53@I7^~RKKf8su{zuK`YySvj~~2RJ!z5B+i#V3ezq=_XU>@W)MNVL=6j(JGrp?n z>Ubf@n;VF)s zit7I71I~VM-hTGrca1ftdfz^JFp0bNT|-*?%{V9h-3%pR%VZfemhaSxzssQ3!*YL8 z0AJ1>;oA6YH&?xb*}H^%C+#qr5fbt0K!KRx+ADSIA|K@^vuu79^d!|`R@);PrCIAD zqm+ezec;M|qLs6)ReHPKwx55tY!OnvbvD>+_Tt(T(G&d>kDU58^B&K9`I8|gR*kC< z%vzWD$VR|bpnJdSl5HF_U+%X(CVg6As)4TEZtWEpy1waH6hCl1aaFz5$x$tf>tc-N j2bcf*ZI3#|u}Uyh-(Gi7sw~YCR6csT`njxgN@xNAYH|*X literal 0 HcmV?d00001 diff --git a/res/img/warning_yellow.svg b/res/img/warning_yellow.svg new file mode 100644 index 0000000000..4d227517d2 --- /dev/null +++ b/res/img/warning_yellow.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/img/zoom.png b/res/img/zoom.png new file mode 100644 index 0000000000000000000000000000000000000000..f05ea959b44b239bbe35095ded0502b5989aa239 GIT binary patch literal 1288 zcmV+j1^4=iP)Px(!bwCyR9Fekna_{gL=?y0IEj-crDRL@2V&bEkT~!|?H^Ey8wUhZ;eZ5J{sCGJ zoVan}(((_$1q3&!S_z3tJyfkYAyGs*Y=20!$+p|gcD?B)j(@}%-q*=^ovoemI^B{d zMIMjmz4!6V_|3eDpq%peBj;7KNT&@$ye))S9t`9X2|65_leEe8Yf{Q4*I)Jebm6VV z%H2G!#9oyCTH9Wzn&xLh&?l@nUo#C+Er;65rNJ!aPzbR7(Y|%0!=jAZf!1?5;08N%GUz=E^@$RG9Ek+}d=% zx@&oz9$S6Z0-LZ6AIz|~xBk7+IB?r?FWqbV+kP;3)@+eI*oF`Ig3k$^HTFnAVYTDi z1O5c}Ti^q};4@QCqRa7C&jU`qJbc0DXt>9EYwQLe1m?wl4y%INeTC0(PBKFrDw>=K zC1$DKSUy;&SN0e};s&QFI~13L3&HM&;?_^y=(rX-HJL|>|U!V1CT-}N~Br^)xX zd(oq7Yp(pQ=|=au0@^}HN!*sIQ&%v61xx@8yQE^8XRtzK3BuPOd1Seg-g(80UQky+ zTj)SnCtv^zmQ=J20lDsDEMGe1>uVluv7-$hBFp6kH=}HE+o29avJIVpWwhRtfn5nJ z%c3-{bika&?_xb11yd7pJ*1GXl~h-E%xTY2n!{;=!YY7V4b zZ)|vDk1QvU->ukkldox#*5=P$wvzP01UBLbezEQLliFzO(g2`1>6z9rH)uP32{r?p z%_0wY9;ug&#No!AQ^PvPZSn~AmtZq^m07|~UQv(_dpjS^11@9E<%I(am_jye)2CfH z0EwTH*XvRIS5Bbf#gOkl%Td=;sot_N>gJ41-J zX>iKUB*@*ilurB#Ca@Vusz-Ti{P|Pmi}zi+ygFP*b#O{K3G(u)OPAP|PQV1VA~OCv zmfPaI_4uUq82h;@Z|Pth3;*t6O>-EBJi>Ext}N(iY;TyPha8%v1-3AFajNCe4{5+_=W)T)a(E8ITI@)S`Zy1{Rz`z*Y$8c;0zr{79;G0?0Z;s^QkP$8)qr z&t-uF16XiG0^Km=>cdu=;M4&}BkKGnT7+jcX^Iw5WKlRPdC&>EdE;VQuVkr*PxuCd%IFgHW;$^n z5zo}oM>NE-?v$<0`bV}uxYF1TI{P`?uniyZ1)t2I4Zpz|;bQ ycBYSj Date: Thu, 12 Apr 2018 00:25:36 +0100 Subject: [PATCH 0761/1160] move default ringtones over from riot-web --- res/media/busy.mp3 | Bin 0 -> 24834 bytes res/media/busy.ogg | Bin 0 -> 13960 bytes res/media/callend.mp3 | Bin 0 -> 12971 bytes res/media/callend.ogg | Bin 0 -> 13932 bytes res/media/message.mp3 | Bin 0 -> 12627 bytes res/media/message.ogg | Bin 0 -> 23440 bytes res/media/ring.mp3 | Bin 0 -> 36119 bytes res/media/ring.ogg | Bin 0 -> 66715 bytes res/media/ringback.mp3 | Bin 0 -> 18398 bytes res/media/ringback.ogg | Bin 0 -> 8352 bytes 10 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 res/media/busy.mp3 create mode 100644 res/media/busy.ogg create mode 100644 res/media/callend.mp3 create mode 100644 res/media/callend.ogg create mode 100644 res/media/message.mp3 create mode 100644 res/media/message.ogg create mode 100644 res/media/ring.mp3 create mode 100644 res/media/ring.ogg create mode 100644 res/media/ringback.mp3 create mode 100644 res/media/ringback.ogg diff --git a/res/media/busy.mp3 b/res/media/busy.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..fec27ba4c5952980bf43e83fc52203af300b02a2 GIT binary patch literal 24834 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 SilT;wre%NUE71uW2mTk^o?EH_ literal 0 HcmV?d00001 diff --git a/res/media/callend.mp3 b/res/media/callend.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..50c34e56401d25f33db5fdf41c1fb1d223ff6cdd GIT binary patch literal 12971 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 YUFWf)L3S_z;CWn-{-am?|3CTv0)`V=SpWb4 literal 0 HcmV?d00001 diff --git a/res/media/callend.ogg b/res/media/callend.ogg new file mode 100644 index 0000000000000000000000000000000000000000..927ce1f6340a6d9c65bcb03d244b6c3346060443 GIT binary patch literal 13932 zcmd6Nc|6qL`{~%J!Eg}`;bbOVv@3jQQ5LY zvJ{~bO6tC+&-b_7*S){{d)?Rl=e}R>IdhihJm);?dCoIq;^k!l;NV}6e`VY(rRwVQ z^(l-G79MoT)hCqF0n==td;x&({O7w3Wq_mV271VJY`gjDo1-W}%QiTTHpg{#C${@eLkLy44SRfFb56<61RXs2; zC@j#;Lo3kzBpcN0atY@Xic{4N3i8(oy25Yd;qK!CL;N%AxW@Sl(1u`u)6G&$JKy}3 z{!OmXY-#O$*DU>;mGK-Jy2YVv7PU%~MSczK5BcNK+!m%{h8o~%K~WsxHGJlkAfgH{;Fq`bmok*1GPZz~F| zf0&!=cB>YbrN1iVZm6LvmXM`STWMjep(~#|VJ^lSYHseUz6LF+(aIms7)#EuqU@7| zMRT{HfGGgzZ>zOqsjI-(?682UnSwJ0?ClBcvc1XmQw66Y!QPpzbP zMcuEC()U8CIxa+;6M`#vu%hm(Fah;(Jg8Fgm3$7>1eaIz0wl+w+K3Va^0%lvS{)i} zOu<~XyJ8opaTKblaaCUp)u8nK2i!mGf#_A|R7eb|=GVPj9>b}XRnetEu^IyWFFT<@iYciKglg*G{^RWnRnf`T)Pvp!hC^=*P1vo*a~$j^Jmz)- zT#km%?S;MD3tO5@aIwwx_@CZ?NQWrFqc!OMA*7Pi?WOc8;kK#9zmdrgEl4usc^)F9 zb4h3*OG59qoWXsS;nylgJDO%}Mz1ZktZ`a%545JUjV5tM(>N>JhYq%_0n-x!PPqZ^ z_M-mN8^-&WL|p*ZbkizylPh%7mK3vuV5I`}0B}*X36or|n6{*wC8U>Ip;xkOTjuFo z7xs`p}L@0H3<=$Coel~wr?F@-Jb9mN0cmHeyV832$oc?L3h zAO+WhDzLxYg=_&1f*JZUAf<;i{$Dhj>_7~47(@JL0RSK+^vqmBCsa-^+tT2nrO`u6 z19mGDtN-qiH+n5+1Tj_^vN}L=O?|q|FCZ+uJdf@{-!73B5qRh*K%JR2FHOT9S0Yo! zaA{s+2_44=G3^M@geZT(--izESJJ7y&7!nggUjY#<*7_F_Y!-a=Q@nZnKExk4NWuG zX)Monl{giiZJt{D0@4;Z5A>0Uhqg}*%m9d&))lK@b4^jIE;^qgwwf23D80fHnx?c$ zz?qA$7U7KbdpV(Iby29fvS?1IvA$?2q#uA5`p}n>GuUC+B7j%VQZe}|XO=Bz!lq?` zb1;*0nEa|TzGG-%r8;J5WnmRCZE0njt1>F5`r6WJRL*J~YC^svSIcTV;B{Eo49;pU zH(+MZ!JZ@B%qn2c(qZO|)#R?j^lp^xM3~!G6|3)tuftSd<2=U00_?*a9QF(?a*ZZ) zJYI(d%;b1DT=tmWlYfnKcx~k|jdPd|_ppBCV7nXjIxOK`j)#-Ahb?Eg!(M{@WX>|q zVb0pa`pgAr)P6EyaU#qmU&X`*;hkZIM&CdwZ$2uBniClA&6HzWej~i~9#%Eh)tH zgF2`wKGSn=z3bbru4akyjh{WfLp{xJTcu~a0wubGd4~Mf2c_4$%v!^)IYpqJeZz%0 zT=8`1+YQ4l=_p1ILZXFHM9VseEfqKk$1B1>y3oxsciS?IZ7wFcYOSNpyMtKaQ&sCz z;$v6fRZ!(q*CJLxl<+C=u`BT`D5%b_@-86y6;w4OSBVW(`3|=D6trw~v;=e#{b$O2 z{xSu@>pE@dRt7@;5`1qDUsQv;I>#vmfMwWQjm0;@XeCz5O>*^%zq0xf1 z+A7gxsHdv2piX?Ks_t!zPhG2jU0pzD-Nw(Bfb|Y&CjoU;rwZ$QDVSR%W;#woyP{w& zSk143w&7n;chbJ3x`2XtzYfCu>1K)FU(CL5>wF3*m`@c}i4PG2 z4!YI{TLSCq{2|Qiluh~%b!`pSZT=1Ua&9rO{wKN?3C6Ka>I?17yfMfUl4?4UH z{T;}-vex`v+}Cucf>)@5dPqckBEw2%*& zf$RiQ!CeoiYfLV{-pa~e!DzhI15!cArMk!&O+!{RVKn|Az&1C)rPX5*0)FISzZ*80 z6XrA-wKVB5x6;w_d8noFpsxOB>*hgE@H%lD1psF-0CZBN3~byjEFcN;3Mnor(sZfj zBTBTTW`jzr{O%*_bOJdqmFNVrv!K50Y?)R5>@0ISsAfkmkezMrhX8<05%OD81hIRH z6m5awEdhvIvVr(n=KHqAO|JyvYHeNXXWiV@n`J(br0k)ds@gi@`g*}XJ?oz!{`~Ff z=#VTZtF5bB?`R=HLa8I3>}=UshbndJgG7mgp1Ka=Nru|@7g-( z$!uKjko?sn&7cDV3rHq_MJP0+1)Ixp*m(Er1AZ!im!c7fLu=3o#Alf63sh!9@txEH zbgVjSaAD-!wE$WaV#s;13d))L_u&0s3*G-};D0-#_Wy+He>>y<3jO~Fz&ZaltNvf; zLxGIsV2}~{Z-p@ipxClXmg)aj|L$ft$1S| zkRNJpcMAfNU9G5KvmaKvVQzlw-b#VrX2pXGenk0IJG*-M$)eEV_6Hn(L?{Xm9g>C$ zDDLC@SMY}b3v!A8&o|Yq+@m*UD)F%(mZN9$vt0ve4+D^rTUHA-Qw|F?-O%{B$VIfe>g z@r?B+ir7*S92Db(LJ&MpF2Q^xUOi1col$+zOqNl@P-!gR)!0{--6BH?U5sPl@>QR9 zl%a>bH$UJfQKLEeG5Z>HNzzadoAeTmOt5Mu5g536R$wG5&3H|akw?(&Y{N@ZT_itu zpw*z$K*!qfU|~o_#l=L?`R({)MFb1WPyCd~3NU~L$gBuJP_UrBxsB9Mo?2MjhC)Q> z;Q;#pD5~L;l2*heB&B5J6cm+J{{3o)$K(G(VWAR_|L5{XYW&*;D3>=1Ao@#qgEH^& z6X7=27kLHw_(DBAym@(#^9Q)NIC351x5GVQOk+gDt=`n`^wFQc1|`;m=H@;rO~82ca0svC!bvX2KX#zYyQKJL zuJrxduKhW^K}h*w1~arue)YrQ6rQU{m(W3#5uFjwKbK=e#H39r!`e*No^7~;g26yk z*2c5lu)>Kx&Dzh#`ywGSB%}nueBpcrzzrVMS#P1QtM=g51c4ewTk~}v1~g}TJ>2GI z``#O!%}JVglYMNr9QUJpb+Se1?(4DQ$GJ!z_*n-y72)YAcs3Hy`)9L~HhDmiWohxe z1@!`w4F!1lPCBs*g)GPYR4VgYMn5`OX4K_b$fgFu3e+D=`(bPZRoG7=z?*}6sW15H zhXG;n%k84y-O)n#<@|h@O@kwg5dnh&*bnFfCxa46GsHG$*89ROSTK3pp~)@5C?g zs1@1d0g0(?1~e;4A^0}cKI;PYX%K!ee?_3Zdg;-R!aWU|{>`Iz`(y#0Mv@*RHJ`^a zCBQK>!Cd5b^RRw6D72&nh~VWR6SW!DfEO?R)E`Elo6}M1pmWenTly0849|o|yr<&N zSg1ze=0>Fm-{7M4~=Bn}{-=sYu`jrqTEoRscx=3tcx%k36TP-x-UizQ#_V+1aCp+!Yc3 zg1`R=0DM*p@jv!hU@F`gu)uMF{$2a-^vd#=KAm4j-^{d`_ZGn(aKAyOAwly~H3b1~ z6l?+^y0HI>0j9x$ATUAbpWbP73_Qbpao**77m+wJgt&T7fRd~Ez9lztBE-f8I}q_8;@j z7zI=;Tnkx%;IajKn853;3|Gl#m-em~0onXaV>l)EB zvkz}j(?`-+h=mkL^w5Ao6F`f=VStno6P}h891TW8Y`2H)smtA@0 zeBi4H8bEt`q50`1lM6kfKA0-@r?a>}0^B4N+`IEd1uM8A9OEqxgP*xWonlPy-3%C0 zs3RL`=mB!*EdI{`8t+HyDPUNDNdQksct43B-Z+j9HEm@Kr3;?Ow~X4}k5khFAGtFZ zY$1hBNSt#>&@fvpu)G9F^e?U__ycEoU`kDeSOE561pn+x9|EA>j(lHaWdrD@rqZdq zXb5B&n*^!xBP?S933lJAxy&?G@BY;G`+4-0=SH;o!y7-ZAAY~q4X`w4g1x5-u^6@p z#h%ft8|#YZbS&%RKC(Dky!EjMYY1exQ$QZ3EpiQj4?{Fw^sJ=((i!UO7=UtK^k?CR zMSyGTr`_j&U1s+>vXHRw_NynsiS(!k{V9Szerr9nS_H4X&4fJS96C|p^dLhZ;6BgW zy;k7<@icDsS9f-?_cl$T-7jYPXJALWynFqFQ&|AGHuq6*^z=P`GrCNE^7qe+A2o9#pPcL-@G@hz0N|F{-E&5hXXsVPq6+rX;tYg|~tCsIQ zc`h#NUBzc2d*uGB?%zkFgN--TZzh8E5Qc5IA(_#<1})L8lfSumZP~x-`g{_xBmh|k zQ2s_fq?OXZCHM|BV1KUZe8oWoC_m2j0sB9O|-w=w1C1s$lwHC#nTl zbf?In`3<$7+YDtv7q03okF9>@KyCKyBR$F-9HHM=W1yeVDi6d7JM)7>-hls$9&t&5~Q>3%p~eI1c|z&^To3Ni#ER2 z>(UIWZ4=@CFRIPjRJOWxnKr>3v50<%a63e_Q%aGqAFZ^d9kphEEo^i40~}3a37SPgn={VN>piI zc)^csT?`DzM@EvbM*v+?S~IeZ_SLBjJWzWX{;mAwbG!AOJJ)xfzg@fETmEjSM@M2a zjtg%AuzXa2{*vMpzZC{Ovb4C_Ox=X!p=p5;dZBaB9rAqmQv5fD`)3FfN)%v;3Wa@zm5u#daJff z*?0+t1b$e_(C(oXlY&aeXQp#E_P0>S@=@m;?~bs3q7FxKo3xV}+ zEGj4mOFE`!aP%8>D}aY0X*knFBnr$E7Gfq-)A3u#H5p)9j5p#XdppC)0K)#g+Hm5c z!a>zI)DBZ&f*f^AtUR7jhNTAj00fh2ZE!fC>v%>C)_>g% z-w0DiXMo>YCLrU1o63_D>cVS)`gbSa;5F1gllEcNP`%>o-h z_W^9&W-AIWOU_HX^ZptgMgp|a@dNx(D1n&WF$rS?@T@~taJiukNismAw~EPhNP^l& zawyz}LpcI;b@KH&-D{8BdFC^-)%?Sh&;B!~qc={N1^<~7*pM%?S(F4o)&q zQ8H}+Pj3-&lSbu*p#(P&N}XhViW!k7X@c|+Ucz}QU3z266)L zPv74%md)+!JGcB`ojRQ57R@e2Z_Zf3(2-i=>T;$IIfP*7NC4D>mj*>Z*XWCKbr>E% zXEB*gbbwkJypaP*{JNz+dECx$Q!rm({QYu%Q13YN=d(lIUg_>5;A{+y^H~~@+bE8= z(9 zlo$lzaTz}VHqdfXC0y%F%34=!J#Zlg>X|(T=|Q9u{n5#}dpN zvaU{r?-iL{PQ6L6eF7IL9?)pH03~vrBN>7Wnb5r z=ia)G<#@|AH_-r^GghUf_N=dL{v7k>5p0eCvK=;b6RU{C?;;*Lz*vZ{JdOmLw)oz1 z&SCfrnm-?wDk;~HrHe-z0tj{WRzd5hd+`RF_uf6!qK5d==SwmcgiS$i;2ESPkAHmT zInt|9+T%iiZfpP~g~A!z(q1*D!2zPaJlI(y-}+@xi@GO_yVWm)j1VEPHS?*EVJs@3 z%dTYoa;8H~{b|v6MhsqCH=^ApYB(Q`7Etj&eELvmyM`6f<^yjOaJ{)`KxcKJL zyG{qq_aT3r)!>W>Zik0oLX9p#fz1~(!VPZU?zm7u&Fx_(Ji_AJM1E$RRmdr;QCxi}Q$dE-YL*i+}cI{i`j$cug4taKFXpSDOS=-*@z!N`KdR znAE!zHqOdHV4=qzrvgvKWljd?MQyWh(Cn6iZ4^IbwXrG;C)pV-Jm&f|Vfa|)=xe4K z&F=@CB@vf-*P4g51q_S}zGFw`g=s}OW_U8P2lqm2s1jPY*0De2zvN+QkzL&LX~)L{ zpNF;Y^ZhDG>s8r2?pZ4^1+$@8UY2}H172muSqVpvOE~XhfrWfONWFxb$i`Z~QN;lA z_FO8n9(y;hXnTtJqktMd=cy~xm1v>M{gvKtGr!ErM2`xl9Khonm6v2#{Js;vG&ceI z3~vz4t#+U@tR2?)u_7w=H_z2fye!F>@K@=;y?C<(ZhF$`ZF+wcbam(FFC)F2h*i3% zcjS&x-U+gh|1_>Joo1UgW!CU}Y>0v6ZPJE-^odQw{^WZGZE=}HIvB;f0xw~2#!a5X zEiivp(0AfS2afthvR1+AuvB~~#{-=fvqrx*pZ(9wM{f2_I$h$h!8C&%ia-Y!32@CQ z-$$T13JyA-R|fTF-)d`VxFH*43En*e(IQ2JRF-9JmQ6S1cY=L z-Z|AJp_s{8Y|v$qJsA3>3Wfw{_v8;&3aEJor3hU4{xeUE^6>DrM|p#s>%8CYk2%fp zo^j{PtC+h#5MwgCyKcAd6JCDrw9vR^*~2V>$Zf~7e_@Wq0po<&3Ug@;HeAo}z~ zVyom*$dj@k-Ko)iBh(+FXOGW@@tc*wrq0|U4C15q%vztJlj^qVRZvW#QlQoS2LM@J zcj4gUx_}nd;eObsaB^6Wuw>ADtIJuRoN!O2KF{zQIR(#~g*7@0dEO`H80~fqjve9A z7yltPcz;lvv;hTT(Vw0Sj}|QZK8fA!X8g@_kU4M|p(>r2=uXRlXAEyZo}k}YJ)wDH z7|+p6RT%pWUF$}(13Ogl1Q{E`7F5ltt~S&1eM`*U>{^kyhL~(g!v;T$rnddb*i7`G z3UcwG+!ge06@%jGRh#JK5i_QA&1(_NW3lS^%f54q7n&}C(?Ce=ZB)vnFYRSjLcuR0PAShkl+9i5p7LxXf}o0LQ#zyVYgK)H=Q6;4!S^Ph=0sU zJmg&$`D`C!`Yt0ziJbpl`D370PtH?6Onmhf_OE4dR;O<`(9&mg>4v^=m+o1ExM@A_ zOd(J*Ft>Zvs6Fy=%a_}~6pVC7((nE$uH>e;rumCm{PeT(RNe2zn;l}rwo!x>queLS zn;d{{_YMcZGz@UgJ5Vp;mdg1ICBwZs9}2Zb3SQVrkCHMxCHK@N`Ld}xr(~w5KY8)( zE6s>li*6L}NCpU(C_;+X8`yHqh3zB-0mdSL>0bkMdrw2M{U51M7`_; zJ77bT1UG^qYz|t8N>y+X1}V!8kB51)<3eye;ZGwxB142*qxRDg;}6SoqP*(E#D`2; z@lP*e9n@#lq-#eqg=g&Fyf@80QT*Fbv~p5N^PQq$bw(5yW3u)nWL^KtoHN&vX{Rt%BF7 zewSx+?y7!&BR86NUWi1a{uRJ}4@3>$DQRdY)*MoAT{}iTZ0o+*cyB6(hH&Pho+;P< zD^D|8c~b-%8iD$>lM;9JDwGA@c_&Y;!ta-w;iw@OcAluVH!$S&eeRL;Yt7M?`h<3C zi*1FEF1<_!3&I}njL-l4ZXYt7#x)nZA77Md$9Cf)(Z;xsMeBZW_>cwPJZ1UJ2K(d1 zxcy!xJ_;a&UZyuwE+sL!R`J*aR=6VM3Lulq-gcn|16) zz#NoPbh-dDyv;|NABcWCEc9c?gSJ{U2^zszt*>7C-U~f!)t)1ma2Y1YmO3}%zXeSyMiodJAxgSBZ#>I#Y z%8R$EfdghNEeDhvuI?#vuc5wqBvEfMY_)5r3N z<|i6s6CP+bE9i{89Y2wI3y`E)a9c3V}ELWM$5__wjK_`F_x5 zR5L7?getsgaYF>x2bWM$dfoTn#LeeLacLwp zybu#ekL@_|wPFc9>fFY6)bA34mxXDiP2yO5=wq47OdqfLu=d@G!~(T}Lz|V7T6?GX z3A?mC#{Q+>7a9fDd?=KgTJjft(Gu*iZ|fwn*?=B*O!5G?MMnpfS@jDIt>hbbrnaup z=1fhFZU@!;KJ8AVKC|*+t&6WKN}>9~ARjW{UiPDtu(y(UprH2c=luDvO__vOjCroy z$Q!?LU5AWSr{x=nY8sN+B&KVL3lE=nWz7ET4nO4z@g#5qZUR#R#u$w^z4ab;GPcbX zZk7B|tD5ig;*X~y1nryJ7cUPb3ALe5oMKt5J5eV(ru~L!v^OkG6Cygp`cikeBDIl=A6b-5R!mAvw2rcIw6 z5m5JR_~bTwkB(UEJ&>fap>X!$^W~eDwfs&A*SGtQc*b|d#(VF4xitT>>06E59pUr} zI<>YLw-%t5fB58qr1Vf&tzIb`72okgfqTyP7=e5FVhuboM=?P>p#^UgQ&n@mr(Gcv zJ>Z1Mr4_+9wjvsdT?vnmS$<0vug!8-OzbTw+*{|n`Yz6M z&>|+d>Wvhy5qw6Zx#K}CaISDqp)5yyS?kTzQKZHX*(Flh?fer41aV&%WfUkGYK@o*p>z8FW~8; z&IdCrcchD|`T6e@NO#^;8`3OX5+zq9F2-pf<(Rwr4=+aEdDWPXsN}!B$Uv55!TTfc zi(3M6jZ|+t5do+c6Z7v26-9WYOuZU$cWmHv)AmOfJDds6+kbRU;-#dk)Ju^|s?=VA zF+6VXZUO!EF?GxGO-(19RGbQ#rb`4ZrFGe$cKlG9G z`;C+z62|^|r|O@+)z+mE9sYThv5B4M#BmNNo6~<7mK_tezFwJYhT-C~Up^DZ)C$A9 z7CW;bzCH?Yckz+XS3jS<$%ZNM>6BgfzxPO(zs8il&|qTvx2K!9;qHxrqY-ySIfvTm zZ#0Z}|BAA9V&obM`#xTzXjh&K3qRYgPu1U3KP~}m zMQ^rXmqHx(s%Odq;0DT%u)O6hS)p!@QxA<_x%XSm@YFbs8Vs@7rAx9QO3$6U;HNZ~ z!{xx9uR8Y>Ve*>zGjdnE$iGzf@(q&`RoBzfF>Zp7ll=nxzi-<=0MU>xtR%2Op=37Q-m^C+)Po{)-|~%wb)Ad?W6^s z7A{EYzQ} zQv`GO8x7Ikg^ect;E=&o6b1P8^5WSeR;d~Vm3Ag9xtAQUR~CKRxs*8ultwK+$mWw+ z=|7FTg{?a1jOFko9w+$P6vrF>-0%wT%dcCEgrQ7wd|#^uPF$7tGO+kl%Ur?vMo8j> zIHJ@@Lc(xX{tf%LNJ$a*=f~+A;3#0@*dJy5O$1HNQ2Rw~_ogvnR5oip5V)XJM;Fzjbn|=G;eLC+c-Kf+>#>Ea`owkh`|$kU1@UMMZGS>oAqT` zv;qud6n*q<= zKP>8QT{F4AX?5Y4^2R7u`R>PwP(J(8LSA|y09WgO@_9X>5asCt#fDo5cn$!k^)xL> z>3_0^pRAJFbT|ahinGNk*3Yz&Y+n1%yjz&3y4E?#CdgzZf8|3^(ZS=?=k$cO_SsAK z>)Wp#70_mjrhTUFa*dC9II%mD!2_|a2l!`-1PeQ3z`_mbWK_|5 zr7xaQ#n32@@ry4K3}g|+r5--TUFY%V$s1lvsk21RZ@wM6cfuxqZ^%2(Ikkx88nHI8 zFi|x__oU(v(P}E{rr)PTyDg+X>L&4>Q7#_|Xg+&J)p&Ph+R7v?mj-s0A<#N|@d=w+ zVe?8u@5y9gb`-S@Q0tF+xz1jPN2)lcOW0rlUbxof0;ai=2mSd~oWc60ufg^T9ruSK zBuX#YZ}rn)kmn(R=qSEkH#@iCY3#`|inf;GjZ5nG6B!*4 z@9fAC5Os-@Iq;G`D-xxy^ss%j4W*$olvG&UEGej0CR`6tKMweskU*@MTno`WWL zy;wnU{u4~;3+qW=m;OZ7F|Vj-ZB1C1u<&z@C=MW(!?Wk4*^^gCm_5o(HJSxQGO5(a88AEt zh2y*jRH!LZc@rB}FcS#b#`dFr_5BG|ExPOV?oZ9(Lf!c*`ENJdFEG}XXNe@$GGQRVQ~$UGak3@MCb9`gzmGKadK#yC};Gh#~0;=co|EPJht1m zOd?eKWx4=~h5zOIQ7eeWyUA(yik??w>Pwu0J(oa2qu?<0_m8#gw^gLS54)xo%vf!&Y({IdV} zi(DJjB;u-2r^?ac8YI|;{%ZA}-?V;W)qAdnq0qLP7IE~FR|Uu_iSK`{o9tzb<%nkU z%^&nV&HUy5E4hfk22+BGt zcg`5WjZZxNwL1C5VRv2T zqkB_HrM2qaa49-(k)I|Hwr2`NGi3Ix^RBA4RdieFCAcpc0VimR}L_OtgwM)0z8U2*6fBi5bjDBw0=tVaO`tIXJf-B#rbFV7aUR}6Rk;IFw*uJih| z*VOUCz|@oSV&f?z+FpLv8T-Z>c~067uhWm*vb=Qifx6m^#aJi!cC}^u-4!fOf`xH` zn?QhU=5VhjNFR0#zxdLM9eYrond5F^E0m9WmMA}Z_1g0y-*Cl_LD%{>-KM;+9})9@ z5s&+@+#UWNlHQ&`SLwAl5R{BeI=>A>Y(O3r_h=WKl-|Ic31hiUDbmC4q>)`Ally{vY{F=#NC;eO9bDT=v-igs&7h z+Pc=WwNKuD)xcLBny<|DL|EI7_LID`E8Nf&Gy`SAVhk;1N`q4eP=J2zvc%w_ze{?- LM6ir(Ko0y5xc4|N literal 0 HcmV?d00001 diff --git a/res/media/message.mp3 b/res/media/message.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..b87eeda7c2d720ea6d59bd1743642fba0cced0d2 GIT binary patch literal 12627 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 RyzU1B0G`*Y@c$<=^j{Ryx)=Ze literal 0 HcmV?d00001 diff --git a/res/media/message.ogg b/res/media/message.ogg new file mode 100644 index 0000000000000000000000000000000000000000..adc74437d023de4da296d17ab83985a9a21a8f3d GIT binary patch literal 23440 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 B=9~Zk literal 0 HcmV?d00001 diff --git a/res/media/ring.mp3 b/res/media/ring.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..36200cd89d5969b57cf75965e7b7701a7c001e14 GIT binary patch literal 36119 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 literal 0 HcmV?d00001 diff --git a/res/media/ring.ogg b/res/media/ring.ogg new file mode 100644 index 0000000000000000000000000000000000000000..708213bfaca2f520c2c3b10bc6b7a53574a909ba GIT binary patch literal 66715 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 literal 0 HcmV?d00001 diff --git a/res/media/ringback.mp3 b/res/media/ringback.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..6ee34bf3953c5ec94dfecce2fa5bfc6756ed4732 GIT binary patch literal 18398 zcmch;cT`hf&@OyZfY3uVASIB1G$AylDFG>=N>xyhUKEk4VkPvB^d`Mm6;Kf@fPnNO zpn|9%y$MPY0m=DJ@ORg@-nH)i_uXq5kd-}o&dluDGtW%)wB(Thb@5o3n`=WqSpfiH z=y1bTQ9=5IytFJq0RZ=jE!21XkEM6b)eHIq9rVv10CZmhwDgS3tZdvEUOoXKkz?Xg z(gcMQ%BrW-wRA}OhG$JJ&s*DEvUhg7?BVIXCeN)s~!xH9a%%B{-~qj zum_Z5tOtPiT|w3!I4t(XUAP7~Mc`whLj<(|fTaA7$uFkQdSVvtF5^%S*Ph=aC(!?- zVGDiSg3+eSZ}=N<6~_`6_^YCmmDdZ5&sPvp-3uxZAG*v9*dSpJWN=@u9TCz+7UAXp z1pvdyqM*U6CToaalqC%>yQEYD-x$MxM~s{3j{@^ z(QDM)@XpK+XU+^o(KrMpA(hF6h(@wAB9UxNw}>CrMXI&*GyW4#X{O{szfDjGvAhng zzmkVtE1NK?Bibbp{hv-VYye}xvdPOh5t)uhRfXdkq{Yk@cEf7?)j4+MG5}2Qma;<;va>C6nP(K^b~qC4~bj^_tZ7Rcb6Yl zcfgW`Lt}q3E1|U7969nQ`uvL9^cY853gC-KM3)83$;xIq2%Y5VeE#v~KPMc0Vh{I_Vh}1Dmd`dxUq&gnMtG~;OlEz2iU2msh*j590N{a*h z%Ui}4+R%hINrOxuzA(K6!M$dX(sy>+g^w-+ZR6-yktG(6s&FplR6R+10VM|HM;Ou! z(HjCknKi<~`Bhw6rIO??{zIR+g|VlVx+C9$o+>bBrn(#!@h((|7cwjPGxa%Zj|I1WHm!F+?%cq_=7A8|2uDpC$ugcYjKA}{Q$vzwMs5_jQ<-K9k$wArMgG_ zuirZ#(Md~mIw3sIt6^b3%0m0`(bWs#(MnRsSj>YxpzM?rpBDAP3mU(zSO*qV(h8Bm(pejxp@va)ecE^!CAL`f&DNaR6>eAW9sMjKs zhmSMIzaUN^sk5=ZHoeD3<4}_bzWj!c%VBltOj~7j|WOZ&ii^R6D!BRMp*2}aUi_>sn zNrw8s_`?qb8%7Y!8oHZQa4I34HbUG~mm5VEQ58pIia)n5%g!LBazQv*Ve9P@;W#;g zjVxzZ&kkqGO0mJc2^_`z+)vdUadM+-b&SR2oj64PdpNMh{fq{r93@q7*T&a?!i-KS*tS$ zr9hkCinzB_a5^EKu_EkLms>&#w@&^vnIaUE(+Q_rj0nsv$+8mmy%s*h(eydvCRg1c zX_WYdiNEr5Z+}l*#h}}rvEJFWQue%!uE=jDa(rKw4BM^Lg{PYVZU`mrLgX9=%O5*BBEC~XU4I4dIE1a(wD+}lso?q%#TCu=`gC8`K|8PvETTxQU&q1PI8*z&-kg|pervDL)j1~m zWduWK{}zGBZkdLYTbyA(dtB@J^q7*wm=NzIgPohH>NvP>@TrtAzQbO5Fl&dXo%TAvgdu-3$!R;zw27MMP&T z6iBFw3&p`8mqTE1IMisTypg932hFTJp@sVleL@GpgT@bKFN&a79%7NI6PQ`TWOW{j zq)ciPn8@k`RLg1T=R*R2Yb3!Xa$F&n`MB~~89x+unQ)9|1c^RMhx{H~u9^rhB%Wq+ zTwuC@;p5sbZLlu-u0;Vi1HC|SWHBG+`Meu<8DIpwJQAqjoI>822=OvQF83!42Ls&` zLYa8odh%%IzXG+KlJ*YPe6&1IU}zU?0_K5-_5;aqo$tzV_qI|x9DlZVO_BY=0h%Nx zZig!3+hO8nN@kdFW>|61)>GDEd&xwMHNSqMRg->diJ3}M`nk{Gn;&3_G!unTT@qo! z%gaUXHBe&m`E5-1>$)Oil8Duhtt0V7HoZchbCqf1RB&DZJ@ynI>+Wo89eP=@n&-Ik z^9!4{4@oIclET>q60$5v5~TO&l-gt9Xx56U4}jpfnKg3#8|573(*0)eV_x%WjVupq zz%f*Hy6{tjB0f_?Zme)^Vi-O5nV|A#-0yQR8amo_(HkJxyxVoCYw8QdZ8zk>Sj zhuZ40h==7ym%GY(xNaezq&aMzO*&fTOX#M$oE3mlb5W8~>qM^!=Zm4Ee4-VK4C;nI zJTkWNkLY_5IC9)0B;=paYfTaJy8-Eqwr4x(Ev*{(iC;FP-oG{dC>YiymPCpWBndd@ zzn3$3A3S4X|FbUT1p2<2-kuC-xBbcQP{7@LM(6ppWeJviag;FjmF!&eT z+5H3|*|%F;d2LN<{IZ6C`=W`ax|%3^L}iM36fFwqWa?zV1h+B>oe?)gU4I)6v-dDi z%o?}-1)%lZ3ywtr?Ba7F4VhvodI zaNX2m9XK(C)gxuYZcu#>RBMI~))5_?YErjKT#Cg^WElpo%xQT{aX`xZ*ZUL_!!NR_ zEO9e2R67GJA;QSbuHk?+857*tSl)ElJW{pS~<0YVKT8vqA?bR-ZIEFYfAemM+-v3*Qw{!0}{UDJPG z<+(VA&R^w@=72>JEl4*^&{I#Isx}pcSR)zV$*|JH>pT2r0uIMb3NG`<(W8(ZrY$v3 z9j7YpHlj0*YSpU9AGka+I@M>E$IIaO`QIQo4DNrDw7o)J^DUI9r13wM7_W*|l*@5G z)z|WIj@Id2zztuS-N1u~R1|xc4N})!UTileu9{0I#V8F+aGEH5pGBY&-bGc=XvIE~ zRxmM{X&>##nCI3oPajR?kMErM{`1e>(*i*{`K-GyhL9uI1b4nC0rfJv2aWa_v`SQP z!H7;~ETlM($gg-iGLRY2h_pupX>SS7(2mhHZlN7nxFd0GlV^t(}piAK&3?LsLiprCz(n}08ji|zN>#@WrY}@ zw%J-|U4fSS5W{K}=#SEn zLk-BYg_CcCO<*nT1ZJ`#l=r?R1cl8hTEzvZouoel42c+cPtm}j0tam#Wok0g?YY69 zw*Z2lz?a}&AK;A&#Y$u#i53`^{MHOLWIZoO#3JvvjDnzm>lqS=??FE?7-_O{2$4Tx z)bIr7P6PAVz(d1NEXw)^$P(*iKM>@z$_QDasv+IQm6Ol)m>btshhuSt zSM_p-+?Zg_82SVy`0y8QL`wz@Qo2Uuh9Gosnn7?^P*l#rrq``a{e;oTZ$fdLrCeBu zvO;QbI^i<$IrK5i0NLLezLYZk&X|*q#%|dr3-VM*anT{2BuPHjeI$941{VZ6CxBHT z2#T-x#^yT@budpkQ*>hqKuVlm7{2cTHqMX(eUypT9tm$bifP@=X=P`T&-fs12W^4; zu96U7-`d8(^pNS6IzggWiE#0YwQNi4H~|YN5D-KTB$?eF#d{H3<@xl0{4em;Z&H#a zqsV3>fk9`#NXTB%Xi;(;Z8$;m)`bc#8PQ1=In2nR?aID@)6EPvzx>!g>>xJhSE-vZ<;*Q8+Q(ki_(!>WsTcO%)&d`L3vyY|wv_%n9f~~w)4Y1_sNG&fJE{B^eF4(oYaF~gAZWHVq(%-pC&s2+)@Zv)&BCQ}@-WSpFumC~XDeT*aS zF(m0G_<10uE!XB9tnZy~LRY)R5Kqh7J=MQM?WXtvO}6aTK$@`@Ls)f-DquCmVeDl; z7KMzlz3lmj`UD4os}#PC53=5OyB$Jwkpq|L3AOtSZ_1k)|8Wt?f1aB`1T3Q zKVdR{{@X~>M7WQSh>T@0Vdw*Xa&#GxGsctJ-C3eW>3E<6u}&G>%~Sm*At#nF5M**f z?5Bn~TQ;iR)yA*r>@3X;y%K;!^wIjkkf>xB4r!j$%IrzCY6qgzUj#$V(7zyYK~Sl$ z_9OkI+_m=MUtZICzN}_@rgo;9_e1KeT?O&;nSRmS$`#b2dIMpHD z)v_GC1n_RGN2@QZqp%J%!AbT(us(Yun3VfSV_{La6E_|G7rpxckQSSxFv<0Uz@T-8z^-wcz(5QmuoDp{TTHBF%aLs8 z*Q4iuQtK3|;=Us~k^fw7CsbGiDsA?!9ZXKl^{LUbYh?bh^4Yl+Ib~)#BE-I1=E&U` zlz=4W!=3UG83|Yyr59q?X^ESe(Y%m%tFLHppKr9208e#W5(J3%2}0z0f~*FCa2{Su zSREOX+cXY4$);&f$RSUlXh|&y*lLS8+`Gk$c8j$yf!0vkEHOIM$c~EYZ$AiDjZncY z!|Af2C`TnpLLKKIaNB!#dw2in?)_pZZjk}JTMPl4mI%PU6%E+5ousuH71zrDdG~It z6QK2$5820{q0l159!n4ZQgu`!`b+KYWB@8FCZLa~@315w07U|##S95Evu6kywP(k! z*^|zr?A^mT?P}_FU_AtQRo`I~x0(-)i!i+rSi{~YOV~34NM^LT$1JRAfaTx~& z2gwQuQ+YY)SW*>1eYFGMH?3%B5xFyv`2>s*Ac+yn$7MtUA0KKOu=8xST4D6CO4)jM zog5r;`bwqlV)#f5j8Bj40oR^q#XS1<0DvW2MGF%omGHK1IG5#%-ZX7kS%gj|7k~X% z@Swr>62uou`Sw?p01se50tz4~$jkCFD0By^0Vk-6n@2z%cX(FULmf4!90`)~1YjTB z%b@heAk&`vl`nt7g$iTzW%1(Cyq>K1EV|L`k}~eEr785F$M8Up9k^i!0y-Q55r#G- z!sXHSjW*wEV+$vQSgZv=AfwuFz=yAw6@X`!hra$={)5=Rr1-FLi-lbuua)y+D7po4c-Pu0YSSK+`yu>AD zxK6)f_=BB+<@Ho4=2r|!89EqjTEa{Bq3)i1NjRS{EcT*B$JW;QM;~JJhwSA!!k@Z7 ze>J)Ed81_f^QQBBg-i74cCb5Ny?^_~eO>32XZbLNVzcVG>BkQfclVYK)IY6$(@H=6 z*QC=8!-hV?z~byI92FnV@-~*|(B%-_{WP2qxS*@iMKB6}s)dA)oI{y7k>k+??IQFM zDn=&?oR6UZnB>do2P0~G2cD3%4wiQyZ;O{+WJw}KT*;P?th)X?({M>Z9w{|lZs(Mr*9lV$TYTH zC_IkOpPla$3$qg{gS3`Tb-8gkeXOVAqp41zh6iF?eInw~vx4uTI1rbP`NaOH#GHtOF>T!-Kof zzQE;=YgENG11JSAX{lG8s6RsXc&N0gX6|~(Sj6aE>R3Lf@g-8@Dv~K$NfcRv5JE7+ z*z04EQ{z!i5lYxF@+V(k{!dnps_u>dq zlWa;oi559B*ku#cHrSgU2yLXizP4H;(S%+&-LoqEF45A;P|W@A_o1LLRI9rniVCg` z&<$gS-4h{mB>SGZuu8X-%Z)FnnYqj;enQU82*YlFd;(RW-@d0C(N6n%x>-&M= zwnIC!aPdVq?=ZhxPz z*=PS~l8%sc(~pk0u97QDQm&(paj=gDwDT_hUYr$jA%+~h*$Eu{ms~#KrK#Y05S?HD z6@^p9f-OLSckB(VMJvyFjA!|h+GiU82qTZG+|xgOMmK#f>#=JM2%gn#sx@3&Ysj(9 zjt*7ula1iCOdLGbt>LI&~p;S+J%gAzrD}`j553s4_emdoGs(FX* z&{e!Zul3Hr#+T{5US4F6-z6u-`h0{e4 zxJ;ku%M$40LUoQG4tQYt2~2> zP1%K5g3=sP6b&4|cE-LGOS`MX91|03)t+v$7HYA~j>(LAMgoB6?_FebJ@oZ^Uf(>p z2mZF(AJz_ZJ<{}y-~Z<6LJw_WrB+?}Fs|4_7yBh-#(S#bz5zNvpn?@y6*- zZ(ZlvBOK>iGT`(=@`=~B-0qghc?`vh9jQaSQbOMF)c z#>$0-iQIL(OTLI{(IG6Nq{Jr_0|4;xZy#>Yrrocf+w%KF1sL}NT<7tNhmJ_552Y6GR(FB# zPeAKR$Qf1}sq+D7G)J@>VN*(l>T(N!ZiOIpSgWG2MU&3xOdnqT_y&GcjF}hT)|W~B z^J|U16bKc?t?VKw(`2T&e?wSi1p6a?aWN_Mq&%m5Qx}qclrZsxk66Tap)FP{JebQF zqO5380HANL=xZ$#ZkAWS^Kl%cQtyGy;Qr08>(6dY+~=2jSKG9b-ZpZFtw9^1$af>V zofY^f;BivXMetY}T<)LZNF~@kh+T^OT`V|@j`C)IjT^XyV?fF=|3q>=w><9bwtM1I zHsTF*O6S&|TU@sk>e}Xi;D$k(=&~zCC`Y>bSu-%xoe>jaBuBwHH8c#dEm#+gpfo0n z%E64Y_i!s4=kJ8fQFRW2Gwa~3zsFzi`suShETQXvlpH6E=Q0z%b&61HTc`VUoc@m& zX}+6Q`jJfR6L&RxU7Q;~2r#io3ksRBrWmUd@*NYt+f8$AJde zRI@{4>y$6~HBYYWQdRL6lumI@OJ6k8kw6+VBikgdJXd}tki~4@^ogY03hzds;Vp8V zM-|JgVE%wq?AH3J?cBfSYj4*27eGO1{{nc?V`q1K()yKfQ%KBemXM|Mx!e+6^F}09 zaccm*Depl(#2IoF<^6;LNz$<1_p6UzbZzl5NuMw}`s$Chv3?lb$%kNGPMRai6>(*) z$*7HfEBWyes_ntLZ-cH`BDQ;+lEt&*5cyAaW>5;eDmmgv1`48E(-2g9USg=KpN?vRrM6H z)Ibsi6i$gjifebB$W*Q;92Z`meIRzrjav`EYn&{QER2mM$LR@OEz5rIG1%N|_Y4G| z?g<-esk;RvyK7Ww4z1nb($Ncx)KK8mGPNpiQ|>8M`UP`S&2Wf?3hUNR^C&j7%Ox^$ zW@}6l)F)8NcRJy|`)Rq$Nm`DY;1TetxTM)Pw zN>RQ71P(}JDx-bG@X@@8u3zCbDA%u^iehRuZ9aTv@Gs@kk&Qd*$&gs?r1v%N%ruMK zdX)=xT2AARc?La2MYBss@zhIoS;D)tT(tC4k47ufnH0B{)#;Km$B!^=Q|x;0U57a9 z!)5-o-O@VN`Ra1;55w73e}Z-l8!fxK-{z>vRffY1eGVYaVX09razh9L7v@tHO!}e?r%TK@>ql|GI=C z%%lk}yx89-X)a~6E5Dw%vQN#j4qhJI2f^3-*LDUIV*iXgRq16!Pogjze(lM{X#C%h zm?Nl%v=z8Lf_=q9+aqYdV%gsp-*307J^T5evM6&Dw~A|R0}Qj`Dvl)|462}I zYgGP9{U*4su6`)JQ$29A_qAOAuy$ejrpr^yBWJ>g{1AwxB&`Vf{M1Nv@G%uSaYYH| z)O*RMtlp)m%iOw0jQ62bDbbmmwoXG{1`)TR&(ZT;_C+%KG8l!EaK%w zoI4J|;n_x!j-dt9(`i(2-^nCJfjx*rk6bU9!b2`6zysgFW4uewL{=)b*jPT`8`+-w zOSgQf`SE|x4qX;=K`>mDo4w!NJE^4Si?A!3h2qy|neSL!Nv z@!yQnXXAs~`UJ?Vx?hE$C}$9KqzJlLGkyFb3Ab2IyhVg{VXZCyTEKd4D$ixdThA@9 zIqUB42T~EP{@7RlleUnzp7m`)U^t_HAgFw$D&$%GLuH)j(OF|vl;78LbPAVCa9@i0 zZPS@7g*>d=i9keF)xdeby-T#gcKX2S_0T0DVfDmcQ{WmyPK# z`I{fW#~+3VD_1N_zmoi2oY_@mt@R^C)e;NgqI`Y!k+q?bt@29w!BG(Hlbur4!Azf+ zWwz-Q7T&W*I1x$PENlS=h&49r4??T-3SsipGDu9{A%_Q0(&+>UU8OE6J1( zq-G@CMU&YOIAqRs2EGiE<>=}YA%SFMNd?arhVy-&g)^s9hL7RY!ToE$ch@CVpRf0| z%k5|Me`)|m!Oyn_f@TW`L_5>&Nka ze?J+MPHd3n?Dg7>N#{7P=9!0uPW@&O&N*e4M4SdZIwrp!*$v2B{hLqS4(_zCsOTsb zbX{qZuuQm|8abQb?z{B~|BxB@^(QH0YF$(l+x-@Mn4!;+=?a*sbyt)E-VTp035ZtI z?g`>l^ZTru!mpg5=xm{t5ZP_x%D<#fPy&;{_ybsRIfRtm)HIH7|In*hBwYp+9 zwArJfN}6Fx&yr|Mru}d#Bs4}-A(OOdi7v%vVO3bnNIeC>?HwD;#;uHwn+68AK7 z=HE+NjoYp&{Prg6TGp3=m3OF6GEk&d99!jE_JnHHS+cI@Q5Z4QBTA|`56UwGemA`< zJAUG{z{QLEV^DImF$cb>61aFxujeF}mRwX>L#4EBYN4K9d{IDxyL(qGVVZa%gcD=Z z>YCk&3h8#{$YfD>(m39Q|}Fetka##s)bHctp7lX(Nel%-Q?b&y`%mbYn1c$yUAi(I-c3bC!!C`U@9MiRy-sC@Vdl@Bzfvm1JuDsk+E zuuSEVe$wz~(ww4vUYgf=g(&{t*4KdoEeEc#n7{n1D8tr$ULakYWKVwi2HL-p3)P15q!4MdXnS zlF06!3wYB&%Xdx9R9}t;SKl!!Q4etLss*ArsR&h0+2kbP51y4eByI zkYh+GThZxq-&o&RfD)308@UcpC`S{Ha*-ut{` zMO#<|yZcbBx(evc2|y`{M-+3>7ulZcNHuG-cZ|+b8MSW=D?e$jX^;_Kt{QPM$eS0 zxOsrimXU_4IPoIrtQPo~_@7~mm+~o`ON)-@M7`qcds1`u;`ZIg8|M3mmQe?H)~mP1 z4wk&Yz9qHtZI5?zww^G-55-5#i0zUO=|#7Sdes%;9*N?jCd~ZBHYs=Cgt>_99REK# z!$c)`uyY_|z8O1rML9s5vzFmSk~?8!{%Qx0U$10&n$lZ^s~L$8IjGG``qTl4XGrt z{`r-g6r}r}>c+vk`XM@q#<_X(-DI-*^rzq4Yp% z;=V;2ow}+1|GfG@M zfhj2|xwq+RGbQ3W*`xIw0PJ;fv}C#bv%Xh#j+6>;d$f3;_iZ_4UbuqkLSMu%)4tG~l3PW2x<~cXpfYce*U@1*LA%@5Tba2?$B&mBEy^bmj zXlW^FQo9MZnoKhsmNV;eTls8+;wNa_V#UkTs=laBB3d!S>Ix^wc4Dj!07gRsRANm3GkoQcs4vtcq znLeE~b^6e|=;pY<=lfwX-Ce`sJI=~JzdM6YQ2_HIOrxmdDev(!J%;6`$HhWOC05WR zzG|I$b?Ia}ImQp9u!1Wopv>tCj)%E^$7WtU&;O1bVx%3-4s*U@Pur?>I7l)}ruE)E zydJdif_Ny(aVbgE+IQ4ijhhi&i<@YtthbHFo}E9N+uB(O*`loEt4Gc^pD=NZbyq5f zc2q{V1|rUiq($sHbA>;lb%{j_M@NHJk}A{@dodCfZjpz`N9&tQ=FF|<%~&&ZVkTc=kuH|{aH z7^a8xh~6=BMhl;?*Y*&*bk-$<`PC~f((eko1WmatA&B__E}IVcqZ(v9ss_73sOSQr z>t+zV`sdS=Nzun%HOJqMa~eLX5uFvH9e!|CJmzh2_2HBYL}*$bIphraiUrFd&0THS zf1-%L+9dTSOm_TwRr^5XfX~96Np;@6gFtX!L{-ADe%Vsh*uIqerqX%tA|+o!{#85{ zHWtz{s!GGR*gA%l_2HPoF`kMh>zG2!A){-R+r`Yg&fR-<9S8lp%nzX&!NB^XX#KN4r8$}7>nHtwia}QmPOyb8u;5=GUc!)Gi^;TP!T5w_= z$&kXv7m2F$ej;9-y9GR~IlZDzePHm^3#R`w1N6FfC(t@i-R0=XdBw_+ zsml-H-Li82&$Y!^o+?K$^T8Spqa2wO#P_!ax*pKDJSfWfsGP3eD+dhkh61OY(AQuN~2!P;Ac-&DYh5Uz!pjHYJA?*a2ySd!*ON3;hX(GSOQ zbFYPGrLh+{Dqmq`W@nQ658N|hsP5`**(tDt*j674lMK^m*YsP4J6UDJpUId{oB*_~ zrr+OGKInOHzwVG2+NHelIJ;aWHJe@}&_IjgQoVrocD=?K8Xfdrb5TXILaEgIOpR=f zFrFSQgk&PqaE*WNlzR2%V52`IkE*#1^@EqqpImouKK5c5(0T56x&k>C)A}er_rcHz z{D@k7kb74-G}T6EUnc9tVfTp;X((EJct6}uxTe-Gd*h;zgH-|ofr24&mk2P=+bbOq zi35T)k1J1^^(~vuJMwfU*z7oUIml8n)lMZG?E`A8zvM+Z^t`A#BQ%Vp)UCSCayyARiaEkru zArm|Upx6#GlE_sY)*DhBSClSLqA0o%##dLzhGK6)RcOuLJl(fz-TV0EVM6z39gKJ+ zz5L^D&b-d+IN2+VDh8}eXEwvE85KyTH~TE-db#C)~1HE4(l9=ez96gtG96kFSG z_^~PGSOsrkUhjzp@ORmz>sl}S!X&GrYPBMwDx%}h=_Zy(OC&#OW06uK6q``3x&+W4 z=Q|*WF_M25VW|YpQihVK5BA4`cY(%+4?a|cGZhQa)R5||&ng?F6yM$TqojZ%b9dvl zth9kM z=AX=16re+Exo-3=MN2MSf(HBSrlWAuAcOr)M>Gyoq;pdfxB$&VQ0p!fk1+M_g4#9^ zxB?$etW}~jF%)ed9Cp=LjG!eSS2tiYzdx56D0ApDn+-ePr}Mz*32EaTIq{L#%6C`Y zi>z!~WMkD9WVuIKTgY|2f<#!!(G%8Pr^}F+4KHicU;%;R&pdL)HY@LaAJ~mk!^r`N zn^?H}^~<}ge#Np)6~4D`<=o%!-w%(zWD^qJQd2^;Dm4kF(hyaVAoY5P@^N{u`1739 zhSO87%&S4VJlS6_D@^M(K(}`EDlg$t^ViKaW=`*o=e=F!Sf!&XFu| zPKjL-Nl9&ODHxol6Nya2l9cJ2kO2S;IoYPlt^tt?GJA6}s)5vQ((k|taP#ll54%?a z7eqCu#=@WLZ|Nj4$6ui4jCOC?XTCk@2l*7uRkm`yjjz1dX z6tXbL+d1-mbjLJFe&E3+E!Kv;i(u)8z`C z42Mub6Dz)tDSy!C=Mu4XJ5G_=hTuS&`U*C`o%_*zG&b>d#X#va$JVHucj%MT%D4w; zc5OPWVQA9miPmS~3}=!{-BSwwX^x~VbV!mM!9y7dRO&l4xCz_Gi?MV#NjfS3lEsN1 z44cyIRF`8mz=ib*=wqOg@Ss8U-VHaq@Cw<{tv}CC`}HZ<)E7UU`x&*Ns7QBIy6z0A zPyAU$6yMd_wb!LWB~JnF`ITcU$DIe7EI(6o8p=zr_^)r~c79klbxZR#c3!v5mQkFW zRYumDzn@@11~2YIleN@l9O}F9KBT#p6|6nA$C?|%AK{XI(!In;Z9iqRB9QVVC=e1y zZPEBms2SNB)mWxFxqlB+hI{r3eEj*H{6q63S~m)5z^2E>QqRhr|FbY*nihp*Wa{?d zyTk2ZY2?iL6cC46p-qoU?j6}gLt0!frlU206S zyiR=H?lHLB7k2TU)!>#^Qr`{Xmj%%S^R624zAkTSqFxOiCDNU*au2KqWzf{&bDn+Y^c zO^tG-ZTw;X7flT$nLey!q3N((g(nFcjv>O+N@KPWOmHum=D`zC9S5y#3lYTv{aIn{ zRP+o$~G7|9H~ zgs(!I-grR{Iww`6884vPm{l%Di0&|rOlHB>^j-^MXA^r))|MRq>Q@?deT{PT;P45- zNvLG~`RC8}OufgCbz^a)RFAMtMY%KHr0KlI?=_(Jk!e-fvDTxmR5> z+kD|(d1IGD%p;=|;;p8V(((BeQh4@#s5ecmrn?(?ccFqc@>kK}9QvxDRutY$G%B3! zXu^h~;}_-{ww#+i(9pJtZ)HBez@^@hmB{VYE6`ZP--S1B%~vw{jYmCrd)+j?VkBhw zQ5a38J8^t|;#XC^jY(-}nHilV0f6yhS4mRWfL5oQO_-_6>Lj>(XXVaIfhzN^u-y1^ zP5BD0l-v39LRvJKOKW`#rVc*NXmct!h?WZzI1IsiMbtdgCwrD)|8xZz8q8@a`DXIX zO!J$P^#A7Z4}NXmuSmV2D3_EM$D?@4h*!0%vLv;PL#zo?nP^Im;$wpc2RqNcEH##@ zMT{oM$VbyV9GfxW$arYEv{>v9Naw~z&~G+Z|E1XdZEhHD?yc>Lj&{>Jqsqg#fDaSN z*1DE%mV`WmY5f%|8cDS(6oMrbMMEihRjDWxt=3mEniTn+ZY?Kfusr}YSe zuHb#0OLqhOH!mn#qoc2UmaV^aIV(krdqY(4>TM_1(1c{8cJqQ?+8hcmXheBoVelTU z4*(6;ZD_B8Y~_3^`c$4me=5npk(T+3TB zr@ivj|3VfB>;kjFX2rgGwdzXDibP^!2%~*vmNn%df3S^V+R`ZMaq{QV|F#Q+Ud-k6M@L==R0r-2#D<)(u zaY<0L#(zjLw%zAOuC>$Z_JgSjY>+5}lYdG0VY-Cq>ObTmTJ~^I!zlyX`@!GG3ISzs2Tjo zsp`7yGw$?>cNq(=aoWGgA1?H1ppW1&<5~fCWd31WryNY~tgn9anYeh#Gwb~=53hR^ z<@P-EnN~LBps03_)~vUg8-tb*RdEXdY3cAdL>?3iLd`huB4I{}OAE$H&e};pt%yoB zR6zI6rT@paHiO_vPzr3nCRX$AVSr+t`;Iub;hYX@kq_R1hF^T1UoKVjfio9|?BIsk zG+7Pul&Ja(pVnpN_Ir_H z7Hh&@AJ1$k8b5sqj!aiWZ9aHF{a_V8dtPwx)Q>^V zF@=xqBPD_~chT$*{U;=znwBURI{V5eB95aAP4$Act%OCR#MMT`cr>Hj(~aOB1TE1M z!~O9!Tre>xOaj%@i3Yx#zxLN}?(Ygh--MOi{@7Q`rxh1(3OyDw~=qV zfHXijIZ-}0>Q+Gd;|aH$)Sy+k0&@0{^3C;2m zAYM*a7MkUQE>_-R!6%T*^(1o*C^ zAUOwnO_P%SpQ|RD7xMHP-?`)9FWSr;&m+zftJs>d&e{gBDP)?P{cEuTx&^FIzsn#> z4KG0L>K9FTkqYZb&R3!@o?>#2aMsEo12Gqpd#dF8b{~KG6bOkwt3G&eZpWwJ{7Y%m zXY)zz{K^Dt1KjlYFAlU~T6ZqI2otUpVWEtd@n*Eg5T%Bl_TJeuiramZT zffD%6D`I-Xb#(qmhm(1dW%`By99hkvQ9>|H0*@%C zH-b|>bzn|L`5OOj3^fsk%+fpwW#|iE55yYBqN2{#+-?*R*N}U!Fkv|Ya1))=Hx~{Y>>OEpI_w5+-LWpJL4|4kB~kWgEcH1P}*b@i6<(HI=qUJ zcqh1YUyyG7zjoJTAQ*TMKYG)5 zc0kIT^s57(&8jskhMv~P_lubYSCQ8EomvqeNv*^^kt~VItPCsw%(uc233W?uQbDxg zCZh1ArUjUWX1?|{G*dqOk72wXjoLN)W5o7pX(GuzxZK2n7G*5Zm42r|>BPj5r|n8sAGc4TeB!ku2Hd>f=m6dEoS9rI4KxhEvo?zA1>#yzf# zbW2@|`_t}rUVHcA*b1KG&41sN%AcGz&o2jX*baOKTA{vB=mC3MPSp*6gUPg0?U(L+ zTpj>Tre_T^#+rQ4)#x`)U5DAGNn@t!v33Mpz!8)KOAm|*ROqxy+1r#MW3@!60;IE93 zfCmw25TXo3LdAm8h4~{foDrZRIy8a6A7q6EneTnZM&R>2@B4W_??3O&b~xw0?(4d* zpWpjBuyD!8UE!xH3USO<;2>sb2tO{qXP4v4s@p$e=he z^z_C}7Y7^S`RFl?HY|sO$YCost@icx68m}iczaXpUC}pgee8x+aT{kLVk{!g@TZ8p zbqOnn`7p-tZ`YvNixCS34zZCQZyu0+AG&9vD#z!|11qyb_Z&{Q4+=h{vWqD9Z!26| z`Nb(-I@d8m>cKc5%akQdjLo9%xbs6Mt8FFjhhn)gAz!!Vul*pf)+wD+APe*OCP%h6 zh&3@{pU3$eS!fV*vf5hGlSw_sIRP_Rcvb|~|3#Dbt; z-@I0thqFp1OAPEmTL#tg(m6ZySy7apI)dw1V+m3K?%raDy?FZ0N*tyE&^5x$yTZ&@ z{j+03?2SuM1h@dYWV?|4cHe#`nE$yUFzgXEnOk&J-fOJRZafx z2UQpRx(ii%H?H=HN9zhzwrQ(9hVP2L=?Yw{rRFa9A4z-rO$W5D;AB@|;*3@_XMeKH zKhf(vx|?*rDH6Iqb0_R_T?k0w{iKcdt)8@~$d~n)`d*uzQfb zfetfvzI}uj{K===9p>&%xKzsQ`1G70e%waO@_CykqVTXLuF490lajofUskyBvd2*kZgeLiQpFMQt!mCZ z_1~Y1s(^Vpb3)MPWLV=5VGAcjwd5*dTH`tfl2*LDspDzNou?`H+A>zi^Ww&QhD}G7 zklY~Fupx&XVz2mgYd)3+na$*(4Rwp0&c7{~w^8tIwkYId@%$43-!%t>|2k)pU3hck z+$HL{9Vh4B$O&&#hu=^~$xkWdwMjQxla}Wt-Fdoo)F;K+XksuxPjF^w@ZQqk%zJ*> z0<4%{0WguuCgI*s{W9+bXA45|N<)h7%S%=#maW;MJ&GHb5Y!TC2n+6dl->0xx$9r@ zYG_H^(vq^oD&fJJzPhUa>EmTg@GJoRey4BuJD~&*K{uGuyQmg$NFH}F3ne|uc$19_ ze?<;eTw{z50D!mPoJ=%NB@W4noPR1Z{8Z%p2~i89{-@y^-YgDBj-8CE4s^O! zheZJCKEWQPb}RS!A1R!@&!anEwbQ4|NtNl}tx?N7y9?C|Lcei9k4FksGKqVxYC))b zG0G2MqOVo4K5GI-6apET9kB3;cu|gcq21gFwPKN2(e@;u<=3!?s9Dz{qavb`ZbU}O z^8&7lXEjGgT@^>Qphtuqd2^#$lA2Re+SO4Vc}eY06*2ak7DXj>L@L^6MzswnZVYUd zx2D8C35fbFtT|;?vpTLNB`GFFp?De=kr&>U8`qqY)Serscqi`0Q{QH_qB$z=hFWoB zQ{0l%3i-g+=9G*(xpB*v#K|2tDV}D;wB_DcD>|0MEt$C(QDfRNI$Kj#90*t#g(NGk ziWN&z6w8+=+FE^^b12C-A{FvYNU~x{YsytICAocuVo4q)c}ZSMhZ-%8lm8yIWFSS} zmfP8y)Hzep_B2X9kb$U_-TkoZ&C?>A&=)O|-c-+Our9+pSTascAZ0(S* zUj9yIr-S5d|GjeU@q<-U#vKt^oqgDM;l$9HntfG$Lt6Cc+1~J3-7jA z+I3oOQoZ)UU`EeHj$ECBWkaE4QWM5F6cf`hSXSBpq&y^bfkci+_k3+ z2^SqK(_YT&KA=UCd-oKrHA+srsZA)LBu_n9=Gj=4G<2r#a?N_Jb{&%3M=80k@yz4P z+DAqMjcU|PZLfLUSW`J}q5>(yA3^va2KLv`^5CapZ%Yo-p>A*~)?uG&zct?Z*7 z9}QL|_tklSS+j0PTRB)arM+%L-?a9Dt#eQcM))SRqdGw;I1q=Xu8EUkqM~AEgtyej zp%g@rxY#9sPEw$q3&Va z|3vt=9OeI=sDI1xzY_odU~%q$cGdsIK1;~jn+#c7%$XUCl5F3iP>&0RX3~YM^aHeLdUt85UCej>yJWHtKI6Ef z;9#wQ-8 zmh^CC`~17nrjs(LM;1SldQ@|RjykBQI!VtmQc>fivX&T|ZKgBoxKYJWrIgMM6`~8G zrgJ6K#dt?uWTD1Kc5#jrz1eK10YP#qUM;lykYP_1Cu%`Rr#y|UDLpVV@FPy(e_p{1Vg+$`L^}}}+t06ar~B>x^j8Ws5s|$-shZi?yMl?7`mK=XMb{!+)hM7&Oc&oW8ZGE%E*J zMkN4>-a5WU-ucGWU*0=?u#H5`)9v2dC*Ij!cd%#Xt)D-^7t5FN%7P`{R^zUyuQS4~5S#D3#$DjABcH~uTwlR@OUG{N+zYx8i=uo6% z?t5Rab~NKzXoqV+(jI6OH3QT%_^EBU9t$J`tUGp!%W<>n(n5Le-6={ zdK}vKMc+I7>PuoQ( z+`cErZ?lZ%^#AskotZzU$`C3B}JN^!|4&P3mt6`w^+nK)!kZsabt6 zT>Xe<_Wdg=!yF&$N{iHY@1i4Xc;MepqsYhVi9;6#Er!`6kDJLvU^p8FjAV(|GJ`dJ zabI7BdvD!e_qRp^f5(^eA3y!`(E|lm`0##B%=2h`_VVxMes$qa>@Q~no^9w| zeq}EH-kttm9(C@)M5;e0zw}wh+yz&zcNEk|Z=UMX9u5VUo~;pWtAA-`sDE?_QtPOc z7iPdX%Db3NFi3T@qD#*niOG+i2fG(EDI=ud@sAp#AEmymSbIa=Om^?}8TC&3Xo!c?##tKiF4&u|*a zfA)T_N^XxHzQf6v6v8^y;{^-cPW~|IiP6b+3n%WaxT~NwK8llUe|zGc1)u!1L2}Xa z!pvjx^w`_|Tem``q$semHm`E>`DLH2Y1=eq&1C%==FOY8Tk46TN$+o`5kYo9AoBsL zyRdt5V(8q!b6;Bd#i8S`39`TZ>Z{Gbrm_g7L5!Py@)4T_<_sWzNyI@K-1Mu9DNSN7 z*eA;vBRNdWm;xZJ`B{p=ncig&>xpGffbPN#3%HIN&zT@8=_A3)uW~+ej8WsO(Mb51S;(8>i?J$D!M86+aq#28pvd>MDeDMv00Y5Bx zZy46mR>}>_M$Gs0TlC}K7(m?dM1MKbUvons(@TZx5aO?SU+JrRda-2$qjCqrk$-P4 zL-8rPK>3fkm{yqh+`(*xE_}Vw{ksT%PcMP{RG*Rf=r+633{u0Ro@|b(kmX)32EjNU z-xAV|XNy%>Rp6tu`Cpy+q$#64<%2@iUqh$2FiEzH4$pb`+7Fus1|a{!&Fo#=%I9ad zJ^$<3P@DUe0^hZHFnk2*mJWx3I)W%b7dM{xe5#8pA00rhd}nkD@tyh9am44lpgEok zx^qE?jx*1N@8ZmNLC;uHAq}!{C;4?PmveruYrg5I8&*-bq@b zL)#D&Ea_HC3#hi$Z>NK8KAFiJUAbB*E07saGQ!wAj7>5EbU$KjGddWH9~Gw#cl73i zNCN@!Trf<1k*rC>C1A&qLaH5LfW?n3ZNT#h3`@-iwI1VWK=UFuMp|dVWDt2{sbCXN zvR_aRW2kj>x?T^O@i3mir5bGX0!u6d{~6%|351*k-43&9X3f=P215WGt1QS@lXMt^ zN|9K)2E@8F28Y~bp@%H;{8-S$`IsFK7jPD~kOBvy_vyZmepOZACDhgLO0)F&KU_^P7wZyjlwM@fr-B3DIH*dx5ND>Ot>8(6V^IswQCM z#4vIfTQYVq^&XHV29YEhcp-Y=yui=JZ_>cZRyRk7>&8PWjMt2DUy#sF2%1=&kb+bI zLM5I$HZ8b2=)wIE#*>4KE*+G(xZfndz#Kas*fw4(~JQ|e6 z2;CVHq#H4tHr8|om&{<(NqWC6VyA0p_G8J#+?BW+X%VJefm?ze8!rTQ{%G6NJ<-0L z9@1JLh@~0=ags4wH56Cu5R<$})97%a2Ge6!n6p_vm3O2x1K$r423YYr`B*i{umUU2 z7y%GO2evafi-ZIXg)IzTAhW`RVAZd~IV_T{$IJ(@F{innc0ppWP1OKq*lrOIwj$x^ zy-_0pm_4tU7K}m{pAXK;7rf5c!4MIjfuR_BNH&U^Al}Sw42xZmkejM(z%j7rSQ;=5 zt!K1fA{ihc0&yM9K1+A+Yx=+RD1l4{oCO31nlv_>WCruhn;TURnqWDHrt2kfJ@mj` zOqXT`lHqj1xcONm9S64_4aO#zFBStq#Dg#ls>wNs-^yjIT?hf=Nv8g5+#8#Zql;nI zFpSf6NFX&R7^jZ4_I-?^DF~d6FwUdU9K9>JqE`s?gQi_v_~`Xv7}Y1ax*RMX9X6yt zJ;2~gU}}#Y)fw}K#KnAIf6yzY9Zuc>xLkZW}{ak8D?%1RPhXf zw0u2jQBC4%u<;HY<2tRBXLuO|y6KobX>H{K8T2txL*@qq9zfF7&RO8d1F73sGDiOf z2L_kGQuPEz(A-9f35t+UkX`BE{WY#vgKaQaNyrQ)X))R~KGpp}Ik*6312~&xBQPIL zk1Xcm5=@D4EI|;~4>(D`j*ne{(dpiu7>8urXs%&I8p6`C{Dczwo}N$Qy4koGaPEsZ z%1ebmfT{&|4JH6V@Q83q{i8vAO*EWD*q^1rtcW#O7-_B;v*#rw$_aY`k;X_R83<`c zZ;o)ZhGeG_Ox+34qx|M!j%J)Qx8_P9*?JV&U{tLH-aiu9;j9+gvBJ=_CJnHDZ;W6@ zo1_oN6`g%T4nz}P1Ugqsk)V;pHOJiwY=Vhbb+llxRN}0W&`@LwNdh5^d<;EYlA+wr zL}fWvyp*Rb!5A7$Q>~!|C^6j5>>87F7RIPH1fr_>4QvIFmRXv z5Ra7&I0qKe$Xz5GID!BO7~?f5YXVqmFq{GOR55`%7AwXJd$R&bb{1G#LI492a1!ia zzzYV>K#hp^espv&1#CSQHnM|BJ1%Z(F91d=LC`b^kDP6z%{!R0h7dt~fDUJo*2+z! zwZKd^c~)Zq67)KxL8ps1=7t1~GJuNPb_-{ijByBzOVHG*pj>L?H#HZ=z|!nV2HO_3 zW<)G5f@rmQ1LOYag^cSAA20}-t>z_y)&qi3@)63ju&tPK2d>*;O~`Zz=1_k)+P_$F z5T9<}12&E%E^r|k_UI`6J3hl@gW2g5KmvzA7qrVFm9#MLZ!{34#wtvt#2j^W)LU7j z5HHK`ST^smuC&?9>SkPTr&JKKBk|0$u5IX_TGzubG>zva(o z6@{p;UP<1HxmkHMzO_<*qUp|Xqy6+Tx|!g1V)b{Z-)?9e9n|f<4lQ|Je9VY{1p&+KXp52V8ZE-REQf$;{(FZhn^R literal 0 HcmV?d00001 From 1c7ff85a4c3aced5f5d54c995b1df6359a6f36cd Mon Sep 17 00:00:00 2001 From: RainSlide Date: Thu, 12 Apr 2018 10:31:02 +0000 Subject: [PATCH 0762/1160] Translated using Weblate (Chinese (Simplified)) Currently translated at 79.8% (807 of 1011 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hans/ --- src/i18n/strings/zh_Hans.json | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index c7e67319ef..76394d5eb1 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -37,7 +37,7 @@ "Export E2E room keys": "导出聊天室的端到端加密密钥", "Failed to ban user": "封禁用户失败", "Failed to change password. Is your password correct?": "修改密码失败。确认原密码输入正确吗?", - "Failed to forget room %(errCode)s": "无法忘记聊天室 %(errCode)s", + "Failed to forget room %(errCode)s": "忘记聊天室失败,错误代码: %(errCode)s", "Failed to join room": "无法加入聊天室", "Failed to kick": "踢人失败", "Failed to leave room": "无法离开聊天室", @@ -85,8 +85,8 @@ "Report it": "报告", "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.": "重设密码会导致所有设备上的端到端加密密钥被重置,使得加密的聊天记录不可读,除非你事先导出密钥,修改密码后再导入。此问题将来会得到改善。.", "Return to login screen": "返回登录页面", - "Riot does not have permission to send you notifications - please check your browser settings": "Riot 未被允许向你推送消息 - 请检查浏览器设置", - "Riot was not given permission to send notifications - please try again": "Riot 未被允许推送消息通知 - 请重试", + "Riot does not have permission to send you notifications - please check your browser settings": "Riot 没有通知发送权限 - 请检查您的浏览器设置", + "Riot was not given permission to send notifications - please try again": "Riot 没有通知发送权限 - 请重试", "riot-web version:": "riot-网页版:", "Room %(roomId)s not visible": "聊天室 %(roomId)s 已隐藏", "Room Colour": "聊天室颜色", @@ -256,7 +256,7 @@ "Missing user_id in request": "请求中没有 user_id", "Mobile phone number": "手机号码", "Mobile phone number (optional)": "手机号码 (可选)", - "Moderator": "管理员", + "Moderator": "协管员", "Mute": "静音", "Name": "姓名", "Never send encrypted messages to unverified devices from this device": "不要从此设备向未验证的设备发送消息", @@ -281,8 +281,8 @@ "Cancel": "取消", "Create new room": "创建新聊天室", "Custom Server Options": "自定义服务器选项", - "Dismiss": "设为已读", - "powered by Matrix": "由 Matrix 提供", + "Dismiss": "标记为已读", + "powered by Matrix": "由 Matrix 驱动", "Remove": "移除", "Room directory": "聊天室目录", "Start chat": "开始聊天", @@ -756,7 +756,7 @@ "Which rooms would you like to add to this community?": "您想把哪个聊天室添加到这个社区中?", "Add rooms to the community": "添加聊天室到社区", "Add to community": "添加到社区", - "Failed to invite users to community": "添加用户到社区失败", + "Failed to invite users to community": "邀请用户到社区失败", "Message Replies": "消息回复", "Disable Peer-to-Peer for 1:1 calls": "在1:1通话中禁用点到点", "Enable inline URL previews by default": "默认启用自动网址预览", @@ -803,5 +803,11 @@ "Failed to set direct chat tag": "无法设定私聊标签", "Failed to remove tag %(tagName)s from room": "移除聊天室标签 %(tagName)s 失败", "Failed to add tag %(tagName)s to room": "无法为聊天室新增标签 %(tagName)s", - "Submit debug logs": "提交调试日志" + "Submit debug logs": "提交调试日志", + "Show these rooms to non-members on the community page and room list?": "在社区页面与聊天室列表上对非社区成员显示这些聊天室?", + "Failed to invite users to %(groupId)s": "邀请用户到 %(groupId)s 失败", + "Failed to invite the following users to %(groupId)s:": "邀请下列用户到 %(groupId)s 失败:", + "Failed to add the following rooms to %(groupId)s:": "添加以下聊天室到 %(groupId)s 失败:", + "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "你似乎没有将此邮箱地址同在此主服务器上的任何一个 Matrix 账号相关联。", + "Restricted": "受限用户" } From 5f2d9b6c54a13850671674abcefada936ada6b6f Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 11 Apr 2018 18:20:40 +0100 Subject: [PATCH 0763/1160] Null check stylesheet href As commented Fixes https://github.com/vector-im/riot-web/issues/6489 --- src/Tinter.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Tinter.js b/src/Tinter.js index 7667e6d912..75a65412a4 100644 --- a/src/Tinter.js +++ b/src/Tinter.js @@ -326,7 +326,9 @@ class Tinter { // Vector Green as any other colour. // --matthew - if (ss.href && !ss.href.match(new RegExp('/theme-' + this.theme + '.css$'))) continue; + // stylesheets we don't have permission to access (eg. ones from extensions) have a null + // href and will throw exceptions if we try to access their rules. + if (!ss.href || !ss.href.match(new RegExp('/theme-' + this.theme + '.css$'))) continue; if (ss.disabled) continue; if (!ss.cssRules) continue; From 760f21b1d90a89cfae77a86e21c8469134487bc2 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 11 Apr 2018 18:31:54 +0100 Subject: [PATCH 0764/1160] Put Tinter loop body in a try/catch So whatever other random ways this process fails in don't cause it to take out the whole app. --- src/Tinter.js | 96 ++++++++++++++++++++++++++++----------------------- 1 file changed, 52 insertions(+), 44 deletions(-) diff --git a/src/Tinter.js b/src/Tinter.js index 75a65412a4..d24a4c3e74 100644 --- a/src/Tinter.js +++ b/src/Tinter.js @@ -298,58 +298,66 @@ class Tinter { for (let i = 0; i < document.styleSheets.length; i++) { const ss = document.styleSheets[i]; - if (!ss) continue; // well done safari >:( - // Chromium apparently sometimes returns null here; unsure why. - // see $14534907369972FRXBx:matrix.org in HQ - // ...ah, it's because there's a third party extension like - // privacybadger inserting its own stylesheet in there with a - // resource:// URI or something which results in a XSS error. - // See also #vector:matrix.org/$145357669685386ebCfr:matrix.org - // ...except some browsers apparently return stylesheets without - // hrefs, which we have no choice but ignore right now + try { + if (!ss) continue; // well done safari >:( + // Chromium apparently sometimes returns null here; unsure why. + // see $14534907369972FRXBx:matrix.org in HQ + // ...ah, it's because there's a third party extension like + // privacybadger inserting its own stylesheet in there with a + // resource:// URI or something which results in a XSS error. + // See also #vector:matrix.org/$145357669685386ebCfr:matrix.org + // ...except some browsers apparently return stylesheets without + // hrefs, which we have no choice but ignore right now - // XXX seriously? we are hardcoding the name of vector's CSS file in - // here? - // - // Why do we need to limit it to vector's CSS file anyway - if there - // are other CSS files affecting the doc don't we want to apply the - // same transformations to them? - // - // Iterating through the CSS looking for matches to hack on feels - // pretty horrible anyway. And what if the application skin doesn't use - // Vector Green as its primary color? - // --richvdh + // XXX seriously? we are hardcoding the name of vector's CSS file in + // here? + // + // Why do we need to limit it to vector's CSS file anyway - if there + // are other CSS files affecting the doc don't we want to apply the + // same transformations to them? + // + // Iterating through the CSS looking for matches to hack on feels + // pretty horrible anyway. And what if the application skin doesn't use + // Vector Green as its primary color? + // --richvdh - // Yes, tinting assumes that you are using the Riot skin for now. - // The right solution will be to move the CSS over to react-sdk. - // And yes, the default assets for the base skin might as well use - // Vector Green as any other colour. - // --matthew + // Yes, tinting assumes that you are using the Riot skin for now. + // The right solution will be to move the CSS over to react-sdk. + // And yes, the default assets for the base skin might as well use + // Vector Green as any other colour. + // --matthew - // stylesheets we don't have permission to access (eg. ones from extensions) have a null - // href and will throw exceptions if we try to access their rules. - if (!ss.href || !ss.href.match(new RegExp('/theme-' + this.theme + '.css$'))) continue; - if (ss.disabled) continue; - if (!ss.cssRules) continue; + // stylesheets we don't have permission to access (eg. ones from extensions) have a null + // href and will throw exceptions if we try to access their rules. + if (!ss.href || !ss.href.match(new RegExp('/theme-' + this.theme + '.css$'))) continue; + if (ss.disabled) continue; + if (!ss.cssRules) continue; - if (DEBUG) console.debug("calcCssFixups checking " + ss.cssRules.length + " rules for " + ss.href); + if (DEBUG) console.debug("calcCssFixups checking " + ss.cssRules.length + " rules for " + ss.href); - for (let j = 0; j < ss.cssRules.length; j++) { - const rule = ss.cssRules[j]; - if (!rule.style) continue; - if (rule.selectorText && rule.selectorText.match(/#mx_theme/)) continue; - for (let k = 0; k < this.cssAttrs.length; k++) { - const attr = this.cssAttrs[k]; - for (let l = 0; l < this.keyRgb.length; l++) { - if (rule.style[attr] === this.keyRgb[l]) { - this.cssFixups[this.theme].push({ - style: rule.style, - attr: attr, - index: l, - }); + for (let j = 0; j < ss.cssRules.length; j++) { + const rule = ss.cssRules[j]; + if (!rule.style) continue; + if (rule.selectorText && rule.selectorText.match(/#mx_theme/)) continue; + for (let k = 0; k < this.cssAttrs.length; k++) { + const attr = this.cssAttrs[k]; + for (let l = 0; l < this.keyRgb.length; l++) { + if (rule.style[attr] === this.keyRgb[l]) { + this.cssFixups[this.theme].push({ + style: rule.style, + attr: attr, + index: l, + }); + } } } } + } catch (e) { + // Catch any random exceptions that happen here: all sorts of things can go + // wrong with this (nulls, SecurityErrors) and mostly it's for other + // stylesheets that we don't want to proces anyway. We should not propagate an + // exception out since this will cause the app to fail to start. + console.log("Failed to calculate CSS fixups for a stylesheet: " + ss.href, e); } } if (DEBUG) { From 91a41392b4b62bee073df5e1f8f67ad3c7279d47 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 25 Dec 2017 14:25:13 -0700 Subject: [PATCH 0765/1160] Remove presence management The feature is incredibly buggy and doesn't work as expected due to server behaviour and client interaction. One of the major problems is the constantly confused presence state - this is caused by the mobile apps conflicting on the state of the web app, causing it to consider the user offline or online (and rarely away) depending on how riot-android/ios is behaving at the time. This reverts two PRs: * https://github.com/matrix-org/matrix-react-sdk/pull/1620 * https://github.com/matrix-org/matrix-react-sdk/pull/1482 The changes to the context menu positioning were not reverted as they are useful outside of presence management. Signed-off-by: Travis Ralston --- src/MatrixClientPeg.js | 1 - src/Presence.js | 36 +--- .../views/avatars/MemberPresenceAvatar.js | 169 ------------------ src/components/views/rooms/MessageComposer.js | 4 +- src/i18n/strings/en_EN.json | 1 + 5 files changed, 6 insertions(+), 205 deletions(-) delete mode 100644 src/components/views/avatars/MemberPresenceAvatar.js diff --git a/src/MatrixClientPeg.js b/src/MatrixClientPeg.js index 99841c986e..9d86a62de4 100644 --- a/src/MatrixClientPeg.js +++ b/src/MatrixClientPeg.js @@ -98,7 +98,6 @@ class MatrixClientPeg { const opts = utils.deepCopy(this.opts); // the react sdk doesn't work without this, so don't allow opts.pendingEventOrdering = "detached"; - opts.disablePresence = true; // we do this manually try { const promise = this.matrixClient.store.startup(); diff --git a/src/Presence.js b/src/Presence.js index fd9bcf516d..9367fe35cd 100644 --- a/src/Presence.js +++ b/src/Presence.js @@ -57,27 +57,13 @@ class Presence { return this.state; } - /** - * Get the current status message. - * @returns {String} the status message, may be null - */ - getStatusMessage() { - return this.statusMessage; - } - /** * Set the presence state. * If the state has changed, the Home Server will be notified. * @param {string} newState the new presence state (see PRESENCE enum) - * @param {String} statusMessage an optional status message for the presence - * @param {boolean} maintain true to have this status maintained by this tracker */ - setState(newState, statusMessage=null, maintain=false) { - if (this.maintain) { - // Don't update presence if we're maintaining a particular status - return; - } - if (newState === this.state && statusMessage === this.statusMessage) { + setState(newState) { + if (newState === this.state) { return; } if (PRESENCE_STATES.indexOf(newState) === -1) { @@ -87,37 +73,21 @@ class Presence { return; } const old_state = this.state; - const old_message = this.statusMessage; this.state = newState; - this.statusMessage = statusMessage; - this.maintain = maintain; if (MatrixClientPeg.get().isGuest()) { return; // don't try to set presence when a guest; it won't work. } - const updateContent = { - presence: this.state, - status_msg: this.statusMessage ? this.statusMessage : '', - }; - const self = this; - MatrixClientPeg.get().setPresence(updateContent).done(function() { + MatrixClientPeg.get().setPresence(this.state).done(function() { console.log("Presence: %s", newState); - - // We have to dispatch because the js-sdk is unreliable at telling us about our own presence - dis.dispatch({action: "self_presence_updated", statusInfo: updateContent}); }, function(err) { console.error("Failed to set presence: %s", err); self.state = old_state; - self.statusMessage = old_message; }); } - stopMaintainingStatus() { - this.maintain = false; - } - /** * Callback called when the user made no action on the page for UNAVAILABLE_TIME ms. * @private diff --git a/src/components/views/avatars/MemberPresenceAvatar.js b/src/components/views/avatars/MemberPresenceAvatar.js deleted file mode 100644 index aa6def00ae..0000000000 --- a/src/components/views/avatars/MemberPresenceAvatar.js +++ /dev/null @@ -1,169 +0,0 @@ -/* - Copyright 2017 Travis Ralston - - 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. - */ - -'use strict'; - -import React from "react"; -import PropTypes from 'prop-types'; -import * as sdk from "../../../index"; -import MatrixClientPeg from "../../../MatrixClientPeg"; -import AccessibleButton from '../elements/AccessibleButton'; -import Presence from "../../../Presence"; -import dispatcher from "../../../dispatcher"; -import * as ContextualMenu from "../../structures/ContextualMenu"; -import SettingsStore from "../../../settings/SettingsStore"; - -// This is an avatar with presence information and controls on it. -module.exports = React.createClass({ - displayName: 'MemberPresenceAvatar', - - propTypes: { - member: PropTypes.object.isRequired, - width: PropTypes.number, - height: PropTypes.number, - resizeMethod: PropTypes.string, - }, - - getDefaultProps: function() { - return { - width: 40, - height: 40, - resizeMethod: 'crop', - }; - }, - - getInitialState: function() { - let presenceState = null; - let presenceMessage = null; - - // RoomMembers do not necessarily have a user. - if (this.props.member.user) { - presenceState = this.props.member.user.presence; - presenceMessage = this.props.member.user.presenceStatusMsg; - } - - return { - status: presenceState, - message: presenceMessage, - }; - }, - - componentWillMount: function() { - MatrixClientPeg.get().on("User.presence", this.onUserPresence); - this.dispatcherRef = dispatcher.register(this.onAction); - }, - - componentWillUnmount: function() { - if (MatrixClientPeg.get()) { - MatrixClientPeg.get().removeListener("User.presence", this.onUserPresence); - } - dispatcher.unregister(this.dispatcherRef); - }, - - onAction: function(payload) { - if (payload.action !== "self_presence_updated") return; - if (this.props.member.userId !== MatrixClientPeg.get().getUserId()) return; - this.setState({ - status: payload.statusInfo.presence, - message: payload.statusInfo.status_msg, - }); - }, - - onUserPresence: function(event, user) { - if (user.userId !== MatrixClientPeg.get().getUserId()) return; - this.setState({ - status: user.presence, - message: user.presenceStatusMsg, - }); - }, - - onStatusChange: function(newStatus) { - Presence.stopMaintainingStatus(); - if (newStatus === "online") { - Presence.setState(newStatus); - } else Presence.setState(newStatus, null, true); - }, - - onClick: function(e) { - const PresenceContextMenu = sdk.getComponent('context_menus.PresenceContextMenu'); - const elementRect = e.target.getBoundingClientRect(); - - // The window X and Y offsets are to adjust position when zoomed in to page - const x = (elementRect.left + window.pageXOffset) - (elementRect.width / 2) + 3; - const chevronOffset = 12; - let y = elementRect.top + (elementRect.height / 2) + window.pageYOffset; - y = y - (chevronOffset + 4); // where 4 is 1/4 the height of the chevron - - ContextualMenu.createMenu(PresenceContextMenu, { - chevronOffset: chevronOffset, - chevronFace: 'bottom', - left: x, - top: y, - menuWidth: 125, - currentStatus: this.state.status, - onChange: this.onStatusChange, - }); - - e.stopPropagation(); - - // XXX NB the following assumes that user is non-null, which is not valid - // const presenceState = this.props.member.user.presence; - // const presenceLastActiveAgo = this.props.member.user.lastActiveAgo; - // const presenceLastTs = this.props.member.user.lastPresenceTs; - // const presenceCurrentlyActive = this.props.member.user.currentlyActive; - // const presenceMessage = this.props.member.user.presenceStatusMsg; - }, - - render: function() { - const MemberAvatar = sdk.getComponent("avatars.MemberAvatar"); - - let onClickFn = null; - if (this.props.member.userId === MatrixClientPeg.get().getUserId()) { - onClickFn = this.onClick; - } - - const avatarNode = ( - - ); - let statusNode = ( - - ); - - // LABS: Disable presence management functions for now - // Also disable the presence information if there's no status information - if (!SettingsStore.isFeatureEnabled("feature_presence_management") || !this.state.status) { - statusNode = null; - onClickFn = null; - } - - let avatar = ( -

    - ); - if (onClickFn) { - avatar = ( - - { avatarNode } - { statusNode } - - ); - } - return avatar; - }, -}); diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 6ad033fa0c..7a55df11e0 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -251,7 +251,7 @@ export default class MessageComposer extends React.Component { render() { const me = this.props.room.getMember(MatrixClientPeg.get().credentials.userId); const uploadInputStyle = {display: 'none'}; - const MemberPresenceAvatar = sdk.getComponent('avatars.MemberPresenceAvatar'); + const MemberAvatar = sdk.getComponent('avatars.MemberAvatar'); const TintableSvg = sdk.getComponent("elements.TintableSvg"); const MessageComposerInput = sdk.getComponent("rooms.MessageComposerInput"); @@ -259,7 +259,7 @@ export default class MessageComposer extends React.Component { controls.push(
    - +
    , ); diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 84a65fa3cf..73a97e28e4 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -170,6 +170,7 @@ "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s widget modified by %(senderName)s", "%(widgetName)s widget added by %(senderName)s": "%(widgetName)s widget added by %(senderName)s", "%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s widget removed by %(senderName)s", + "Message Pinning": "Message Pinning", "%(displayName)s is typing": "%(displayName)s is typing", "%(names)s and %(count)s others are typing|other": "%(names)s and %(count)s others are typing", "%(names)s and %(count)s others are typing|one": "%(names)s and one other is typing", From 3f069af0670c4df445d8e833c9a96d3ed09315d3 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 25 Dec 2017 14:33:46 -0700 Subject: [PATCH 0766/1160] Also remove the setting Signed-off-by: Travis Ralston --- src/settings/Settings.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/settings/Settings.js b/src/settings/Settings.js index e33aed1a6c..c88a68302f 100644 --- a/src/settings/Settings.js +++ b/src/settings/Settings.js @@ -88,12 +88,6 @@ export const SETTINGS = { supportedLevels: LEVELS_FEATURE, default: false, }, - "feature_presence_management": { - isFeature: true, - displayName: _td("Presence Management"), - supportedLevels: LEVELS_FEATURE, - default: false, - }, "MessageComposerInput.dontSuggestEmoji": { supportedLevels: LEVELS_ACCOUNT_SETTINGS, displayName: _td('Disable Emoji suggestions while typing'), From f38bb1f2c2b5b0f459dcffcc7baf0d373dfe296b Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 12 Apr 2018 12:40:33 +0100 Subject: [PATCH 0767/1160] Bump js-sdk --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 95c899fedc..d17e1ae42d 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "isomorphic-fetch": "^2.2.1", "linkifyjs": "^2.1.3", "lodash": "^4.13.1", - "matrix-js-sdk": "0.10.0", + "matrix-js-sdk": "0.10.1", "optimist": "^0.6.1", "prop-types": "^15.5.8", "querystring": "^0.2.0", From 4a1d0fc8ab91e0ca2345acb5e0e5418f5992805c Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 12 Apr 2018 12:50:51 +0100 Subject: [PATCH 0768/1160] Prepare changelog for v0.12.2 --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a74351aa69..1196b05599 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,16 @@ +Changes in [0.12.2](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.12.2) (2018-04-12) +===================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.12.1...v0.12.2) + + * Null check stylesheet href + [\#1835](https://github.com/matrix-org/matrix-react-sdk/pull/1835) + * Remove the presence management labs feature + Changes in [0.12.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.12.1) (2018-04-11) ===================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.12.0...v0.12.1) + * Use correct js-sdk version Changes in [0.12.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.12.0) (2018-04-11) ===================================================================================================== From c06fc31bb2ef5fc4468431a77348e017870b882b Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 12 Apr 2018 12:50:52 +0100 Subject: [PATCH 0769/1160] v0.12.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d17e1ae42d..1f28622712 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.12.1", + "version": "0.12.2", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From 7ae1b37b569c9083d069aeac32259eaafdddcbc5 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Thu, 12 Apr 2018 20:25:08 +0100 Subject: [PATCH 0770/1160] add notif UTs --- test/notifications/ContentRules-test.js | 117 ++++++++++++++++++ .../notifications/PushRuleVectorState-test.js | 62 ++++++++++ 2 files changed, 179 insertions(+) create mode 100644 test/notifications/ContentRules-test.js create mode 100644 test/notifications/PushRuleVectorState-test.js diff --git a/test/notifications/ContentRules-test.js b/test/notifications/ContentRules-test.js new file mode 100644 index 0000000000..c1cdc40a8b --- /dev/null +++ b/test/notifications/ContentRules-test.js @@ -0,0 +1,117 @@ +/* +Copyright 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +var notifications = require('../../../src/notifications'); + +var ContentRules = notifications.ContentRules; +var PushRuleVectorState = notifications.PushRuleVectorState; + +var expect = require('expect'); +var test_utils = require('../../test-utils'); + +var NORMAL_RULE = { + actions: [ + "notify", + { set_tweak: "highlight", value: false }, + ], + enabled: true, + pattern: "vdh2", + rule_id: "vdh2", +}; + +var LOUD_RULE = { + actions: [ + "notify", + { set_tweak: "highlight" }, + { set_tweak: "sound", value: "default" }, + ], + enabled: true, + pattern: "vdh2", + rule_id: "vdh2", +}; + +var USERNAME_RULE = { + actions: [ + "notify", + { set_tweak: "sound", value: "default" }, + { set_tweak: "highlight" }, + ], + default: true, + enabled: true, + pattern: "richvdh", + rule_id: ".m.rule.contains_user_name", +}; + + + +describe("ContentRules", function() { + beforeEach(function() { + test_utils.beforeEach(this); + }); + + describe("parseContentRules", function() { + it("should handle there being no keyword rules", function() { + var rules = { 'global': { 'content': [ + USERNAME_RULE, + ]}}; + var parsed = ContentRules.parseContentRules(rules); + expect(parsed.rules).toEqual([]); + expect(parsed.vectorState).toEqual(PushRuleVectorState.ON); + expect(parsed.externalRules).toEqual([]); + }); + + it("should parse regular keyword notifications", function() { + var rules = { 'global': { 'content': [ + NORMAL_RULE, + USERNAME_RULE, + ]}}; + + var parsed = ContentRules.parseContentRules(rules); + expect(parsed.rules.length).toEqual(1); + expect(parsed.rules[0]).toEqual(NORMAL_RULE); + expect(parsed.vectorState).toEqual(PushRuleVectorState.ON); + expect(parsed.externalRules).toEqual([]); + }); + + it("should parse loud keyword notifications", function() { + var rules = { 'global': { 'content': [ + LOUD_RULE, + USERNAME_RULE, + ]}}; + + var parsed = ContentRules.parseContentRules(rules); + expect(parsed.rules.length).toEqual(1); + expect(parsed.rules[0]).toEqual(LOUD_RULE); + expect(parsed.vectorState).toEqual(PushRuleVectorState.LOUD); + expect(parsed.externalRules).toEqual([]); + }); + + it("should parse mixed keyword notifications", function() { + var rules = { 'global': { 'content': [ + LOUD_RULE, + NORMAL_RULE, + USERNAME_RULE, + ]}}; + + var parsed = ContentRules.parseContentRules(rules); + expect(parsed.rules.length).toEqual(1); + expect(parsed.rules[0]).toEqual(LOUD_RULE); + expect(parsed.vectorState).toEqual(PushRuleVectorState.LOUD); + expect(parsed.externalRules.length).toEqual(1); + expect(parsed.externalRules[0]).toEqual(NORMAL_RULE); + }); + }); +}); diff --git a/test/notifications/PushRuleVectorState-test.js b/test/notifications/PushRuleVectorState-test.js new file mode 100644 index 0000000000..68e7044f60 --- /dev/null +++ b/test/notifications/PushRuleVectorState-test.js @@ -0,0 +1,62 @@ +/* +Copyright 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +var notifications = require('../../../src/notifications'); + +var prvs = notifications.PushRuleVectorState; + +var expect = require('expect'); + +describe("PushRuleVectorState", function() { + describe("contentRuleVectorStateKind", function() { + it("should understand normal notifications", function () { + var rule = { + actions: [ + "notify", + ], + }; + + expect(prvs.contentRuleVectorStateKind(rule)). + toEqual(prvs.ON); + }); + + it("should handle loud notifications", function () { + var rule = { + actions: [ + "notify", + { set_tweak: "highlight", value: true }, + { set_tweak: "sound", value: "default" }, + ] + }; + + expect(prvs.contentRuleVectorStateKind(rule)). + toEqual(prvs.LOUD); + }); + + it("should understand missing highlight.value", function () { + var rule = { + actions: [ + "notify", + { set_tweak: "highlight" }, + { set_tweak: "sound", value: "default" }, + ] + }; + + expect(prvs.contentRuleVectorStateKind(rule)). + toEqual(prvs.LOUD); + }); + }); +}); From cc904be3791f98554489fd56a3896296238be37b Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Thu, 12 Apr 2018 20:27:16 +0100 Subject: [PATCH 0771/1160] add NVL --- header | 1 + 1 file changed, 1 insertion(+) diff --git a/header b/header index beee1ebe89..33b7fb9e80 100644 --- a/header +++ b/header @@ -1,6 +1,7 @@ /* Copyright 2015, 2016 OpenMarket Ltd Copyright 2017 Vector Creations Ltd +Copyright 2017, 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From 40a67ca8fecfedb81333a911d9a5619f1bd76e95 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Fri, 13 Apr 2018 00:43:44 +0100 Subject: [PATCH 0772/1160] point imports at the new locations --- scripts/fixup-imports.pl | 27 +++++++++++++++++++ src/components/structures/BottomLeftMenu.js | 6 ++--- .../structures/CompatibilityPage.js | 2 +- src/components/structures/HomePage.js | 4 +-- src/components/structures/LeftPanel.js | 8 +++--- src/components/structures/LoginBox.js | 10 +++---- src/components/structures/RightPanel.js | 18 ++++++------- src/components/structures/RoomDirectory.js | 12 ++++----- src/components/structures/RoomSubList.js | 20 +++++++------- src/components/structures/SearchBox.js | 12 ++++----- .../views/context_menus/MessageContextMenu.js | 18 ++++++------- .../context_menus/PresenceContextMenu.js | 4 +-- .../context_menus/RoomTileContextMenu.js | 18 ++++++------- .../views/context_menus/TagTileContextMenu.js | 10 +++---- .../views/dialogs/BugReportDialog.js | 8 +++--- .../views/dialogs/ChangelogDialog.js | 4 +-- .../views/dialogs/DevtoolsDialog.js | 6 ++--- .../views/dialogs/SetPasswordDialog.js | 6 ++--- .../views/directory/NetworkDropdown.js | 2 +- src/components/views/elements/ImageView.js | 12 ++++----- src/components/views/globals/MatrixToolbar.js | 6 ++--- src/components/views/globals/NewVersionBar.js | 8 +++--- .../views/globals/PasswordNagBar.js | 8 +++--- .../views/globals/UpdateCheckBar.js | 6 ++--- .../views/messages/DateSeparator.js | 4 +-- .../views/messages/MessageTimestamp.js | 2 +- src/components/views/rooms/DNDRoomTile.js | 2 +- src/components/views/rooms/RoomTooltip.js | 2 +- src/components/views/rooms/SearchBar.js | 8 +++--- .../views/settings/IntegrationsManager.js | 6 ++--- .../views/settings/Notifications.js | 12 ++++----- .../VectorPushRulesDefinitions.js | 2 +- 32 files changed, 150 insertions(+), 123 deletions(-) create mode 100755 scripts/fixup-imports.pl diff --git a/scripts/fixup-imports.pl b/scripts/fixup-imports.pl new file mode 100755 index 0000000000..3929ab88c9 --- /dev/null +++ b/scripts/fixup-imports.pl @@ -0,0 +1,27 @@ +#!/usr/bin/perl -pi + +# pass in a list of filenames whose imports should be fixed up to be relative +# to matrix-react-sdk rather than vector-web. +# filenames must be relative to src/ - e.g. ./components/moo/Moo.js + +# run with something like: +# sierra:src matthew$ grep -ril 'require(.matrix-react-sdk' . | xargs ../scripts/fixup-imports.pl +# sierra:src matthew$ grep -ril 'import.*matrix-react-sdk' . | xargs ../scripts/fixup-imports.pl + +# e.g. turning: +# var rate_limited_func = require('matrix-react-sdk/lib/ratelimitedfunc'); +# +# into: +# const rate_limited_func = require('../../ratelimitedfunc'); +# +# ...if the current file is two levels deep inside lib. + +$depth = () = $ARGV =~ m#/#g; +$depth--; +$prefix = $depth > 0 ? ('../' x $depth) : './'; + +s/= require\(['"]matrix-react-sdk\/lib\/(.*?)['"]\)/= require('$prefix$1')/; +s/= require\(['"]matrix-react-sdk['"]\)/= require('${prefix}index')/; + +s/^(import .* from )['"]matrix-react-sdk\/lib\/(.*?)['"]/$1'$prefix$2'/; +s/^(import .* from )['"]matrix-react-sdk['"]/$1'${prefix}index'/; diff --git a/src/components/structures/BottomLeftMenu.js b/src/components/structures/BottomLeftMenu.js index 3271d5aeab..d289ca5da1 100644 --- a/src/components/structures/BottomLeftMenu.js +++ b/src/components/structures/BottomLeftMenu.js @@ -17,11 +17,11 @@ limitations under the License. import React from 'react'; import ReactDOM from 'react-dom'; -import sdk from 'matrix-react-sdk'; -import dis from 'matrix-react-sdk/lib/dispatcher'; +import sdk from '../../index'; +import dis from '../../dispatcher'; import Velocity from 'velocity-vector'; import 'velocity-vector/velocity.ui'; -import SettingsStore from "matrix-react-sdk/lib/settings/SettingsStore"; +import SettingsStore from '../../settings/SettingsStore'; const CALLOUT_ANIM_DURATION = 1000; diff --git a/src/components/structures/CompatibilityPage.js b/src/components/structures/CompatibilityPage.js index 10806f4ffa..4cbaab3dfa 100644 --- a/src/components/structures/CompatibilityPage.js +++ b/src/components/structures/CompatibilityPage.js @@ -17,7 +17,7 @@ limitations under the License. 'use strict'; var React = require('react'); -import { _t } from 'matrix-react-sdk/lib/languageHandler'; +import { _t } from '../../languageHandler'; module.exports = React.createClass({ displayName: 'CompatibilityPage', diff --git a/src/components/structures/HomePage.js b/src/components/structures/HomePage.js index c46ceeba7b..27a0b6bf49 100644 --- a/src/components/structures/HomePage.js +++ b/src/components/structures/HomePage.js @@ -19,9 +19,9 @@ limitations under the License. import React from 'react'; import request from 'browser-request'; -import { _t } from 'matrix-react-sdk/lib/languageHandler'; +import { _t } from '../../languageHandler'; import sanitizeHtml from 'sanitize-html'; -import sdk from 'matrix-react-sdk/lib'; +import sdk from '../../index'; module.exports = React.createClass({ displayName: 'HomePage', diff --git a/src/components/structures/LeftPanel.js b/src/components/structures/LeftPanel.js index 0fc3e0259b..5acceb1009 100644 --- a/src/components/structures/LeftPanel.js +++ b/src/components/structures/LeftPanel.js @@ -20,12 +20,12 @@ import React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import { MatrixClient } from 'matrix-js-sdk'; -import { KeyCode } from 'matrix-react-sdk/lib/Keyboard'; -import sdk from 'matrix-react-sdk'; -import dis from 'matrix-react-sdk/lib/dispatcher'; +import { KeyCode } from '../../Keyboard'; +import sdk from '../../index'; +import dis from '../../dispatcher'; import VectorConferenceHandler from '../../VectorConferenceHandler'; -import SettingsStore from 'matrix-react-sdk/lib/settings/SettingsStore'; +import SettingsStore from '../../settings/SettingsStore'; var LeftPanel = React.createClass({ diff --git a/src/components/structures/LoginBox.js b/src/components/structures/LoginBox.js index 7cacc14e8a..a9ea1f95c6 100644 --- a/src/components/structures/LoginBox.js +++ b/src/components/structures/LoginBox.js @@ -17,11 +17,11 @@ limitations under the License. 'use strict'; var React = require('react'); -import { _t } from 'matrix-react-sdk/lib/languageHandler'; -var sdk = require('matrix-react-sdk') -var dis = require('matrix-react-sdk/lib/dispatcher'); -var rate_limited_func = require('matrix-react-sdk/lib/ratelimitedfunc'); -var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton'); +import { _t } from '../../languageHandler'; +var sdk = require('../../index') +var dis = require('../../dispatcher'); +var rate_limited_func = require('../../ratelimitedfunc'); +var AccessibleButton = require('../../components/views/elements/AccessibleButton'); module.exports = React.createClass({ displayName: 'LoginBox', diff --git a/src/components/structures/RightPanel.js b/src/components/structures/RightPanel.js index 39463a6700..ca1e331d15 100644 --- a/src/components/structures/RightPanel.js +++ b/src/components/structures/RightPanel.js @@ -19,17 +19,17 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; -import { _t } from 'matrix-react-sdk/lib/languageHandler'; -import sdk from 'matrix-react-sdk'; -import dis from 'matrix-react-sdk/lib/dispatcher'; +import { _t } from '../../languageHandler'; +import sdk from '../../index'; +import dis from '../../dispatcher'; import { MatrixClient } from 'matrix-js-sdk'; -import Analytics from 'matrix-react-sdk/lib/Analytics'; -import RateLimitedFunc from 'matrix-react-sdk/lib/ratelimitedfunc'; -import AccessibleButton from 'matrix-react-sdk/lib/components/views/elements/AccessibleButton'; -import { showGroupInviteDialog, showGroupAddRoomDialog } from 'matrix-react-sdk/lib/GroupAddressPicker'; -import GroupStoreCache from 'matrix-react-sdk/lib/stores/GroupStoreCache'; +import Analytics from '../../Analytics'; +import RateLimitedFunc from '../../ratelimitedfunc'; +import AccessibleButton from '../../components/views/elements/AccessibleButton'; +import { showGroupInviteDialog, showGroupAddRoomDialog } from '../../GroupAddressPicker'; +import GroupStoreCache from '../../stores/GroupStoreCache'; -import { formatCount } from 'matrix-react-sdk/lib/utils/FormattingUtils'; +import { formatCount } from '../../utils/FormattingUtils'; class HeaderButton extends React.Component { constructor() { diff --git a/src/components/structures/RoomDirectory.js b/src/components/structures/RoomDirectory.js index 126ae40401..76360383d6 100644 --- a/src/components/structures/RoomDirectory.js +++ b/src/components/structures/RoomDirectory.js @@ -18,19 +18,19 @@ limitations under the License. var React = require('react'); -var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg'); +var MatrixClientPeg = require('../../MatrixClientPeg'); var ContentRepo = require("matrix-js-sdk").ContentRepo; -var Modal = require('matrix-react-sdk/lib/Modal'); -var sdk = require('matrix-react-sdk'); -var dis = require('matrix-react-sdk/lib/dispatcher'); +var Modal = require('../../Modal'); +var sdk = require('../../index'); +var dis = require('../../dispatcher'); var linkify = require('linkifyjs'); var linkifyString = require('linkifyjs/string'); -var linkifyMatrix = require('matrix-react-sdk/lib/linkify-matrix'); +var linkifyMatrix = require('../../linkify-matrix'); var sanitizeHtml = require('sanitize-html'); import Promise from 'bluebird'; -import { _t } from 'matrix-react-sdk/lib/languageHandler'; +import { _t } from '../../languageHandler'; import {instanceForInstanceId, protocolNameForInstanceId} from '../../utils/DirectoryUtils'; diff --git a/src/components/structures/RoomSubList.js b/src/components/structures/RoomSubList.js index ed092d94ad..fb82ee067b 100644 --- a/src/components/structures/RoomSubList.js +++ b/src/components/structures/RoomSubList.js @@ -20,17 +20,17 @@ limitations under the License. var React = require('react'); var ReactDOM = require('react-dom'); var classNames = require('classnames'); -var sdk = require('matrix-react-sdk'); +var sdk = require('../../index'); import { Droppable } from 'react-beautiful-dnd'; -import { _t } from 'matrix-react-sdk/lib/languageHandler'; -var dis = require('matrix-react-sdk/lib/dispatcher'); -var Unread = require('matrix-react-sdk/lib/Unread'); -var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg'); -var RoomNotifs = require('matrix-react-sdk/lib/RoomNotifs'); -var FormattingUtils = require('matrix-react-sdk/lib/utils/FormattingUtils'); -var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton'); -import Modal from 'matrix-react-sdk/lib/Modal'; -import { KeyCode } from 'matrix-react-sdk/lib/Keyboard'; +import { _t } from '../../languageHandler'; +var dis = require('../../dispatcher'); +var Unread = require('../../Unread'); +var MatrixClientPeg = require('../../MatrixClientPeg'); +var RoomNotifs = require('../../RoomNotifs'); +var FormattingUtils = require('../../utils/FormattingUtils'); +var AccessibleButton = require('../../components/views/elements/AccessibleButton'); +import Modal from '../../Modal'; +import { KeyCode } from '../../Keyboard'; // turn this on for drop & drag console debugging galore diff --git a/src/components/structures/SearchBox.js b/src/components/structures/SearchBox.js index 2d6e6ae04c..459df3bd26 100644 --- a/src/components/structures/SearchBox.js +++ b/src/components/structures/SearchBox.js @@ -17,12 +17,12 @@ limitations under the License. 'use strict'; import React from 'react'; -import { _t } from 'matrix-react-sdk/lib/languageHandler'; -import { KeyCode } from 'matrix-react-sdk/lib/Keyboard'; -import sdk from 'matrix-react-sdk'; -import dis from 'matrix-react-sdk/lib/dispatcher'; -import rate_limited_func from 'matrix-react-sdk/lib/ratelimitedfunc'; -import AccessibleButton from 'matrix-react-sdk/lib/components/views/elements/AccessibleButton'; +import { _t } from '../../languageHandler'; +import { KeyCode } from '../../Keyboard'; +import sdk from '../../index'; +import dis from '../../dispatcher'; +import rate_limited_func from '../../ratelimitedfunc'; +import AccessibleButton from '../../components/views/elements/AccessibleButton'; module.exports = React.createClass({ displayName: 'SearchBox', diff --git a/src/components/views/context_menus/MessageContextMenu.js b/src/components/views/context_menus/MessageContextMenu.js index 11f14f367e..860d94ea0e 100644 --- a/src/components/views/context_menus/MessageContextMenu.js +++ b/src/components/views/context_menus/MessageContextMenu.js @@ -19,15 +19,15 @@ limitations under the License. import React from 'react'; -import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg'; -import dis from 'matrix-react-sdk/lib/dispatcher'; -import sdk from 'matrix-react-sdk'; -import { _t } from 'matrix-react-sdk/lib/languageHandler'; -import Modal from 'matrix-react-sdk/lib/Modal'; -import Resend from "matrix-react-sdk/lib/Resend"; -import SettingsStore from "matrix-react-sdk/lib/settings/SettingsStore"; -import {makeEventPermalink} from 'matrix-react-sdk/lib/matrix-to'; -import { isUrlPermitted } from 'matrix-react-sdk/lib/HtmlUtils'; +import MatrixClientPeg from '../../../MatrixClientPeg'; +import dis from '../../../dispatcher'; +import sdk from '../../../index'; +import { _t } from '../../../languageHandler'; +import Modal from '../../../Modal'; +import Resend from '../../../Resend'; +import SettingsStore from '../../../settings/SettingsStore'; +import {makeEventPermalink} from '../../../matrix-to'; +import { isUrlPermitted } from '../../../HtmlUtils'; module.exports = React.createClass({ displayName: 'MessageContextMenu', diff --git a/src/components/views/context_menus/PresenceContextMenu.js b/src/components/views/context_menus/PresenceContextMenu.js index 3a3dc2fa47..9b10598511 100644 --- a/src/components/views/context_menus/PresenceContextMenu.js +++ b/src/components/views/context_menus/PresenceContextMenu.js @@ -15,8 +15,8 @@ limitations under the License. */ import React from 'react'; -import { _t, _td } from 'matrix-react-sdk/lib/languageHandler'; -import sdk from 'matrix-react-sdk'; +import { _t, _td } from '../../../languageHandler'; +import sdk from '../../../index'; const STATUS_LABELS = { "online": _td("Online"), diff --git a/src/components/views/context_menus/RoomTileContextMenu.js b/src/components/views/context_menus/RoomTileContextMenu.js index 06eb347d6c..77f71fa8fa 100644 --- a/src/components/views/context_menus/RoomTileContextMenu.js +++ b/src/components/views/context_menus/RoomTileContextMenu.js @@ -21,15 +21,15 @@ import Promise from 'bluebird'; import React from 'react'; import classNames from 'classnames'; import PropTypes from 'prop-types'; -import sdk from 'matrix-react-sdk'; -import { _t, _td } from 'matrix-react-sdk/lib/languageHandler'; -import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg'; -import dis from 'matrix-react-sdk/lib/dispatcher'; -import DMRoomMap from 'matrix-react-sdk/lib/utils/DMRoomMap'; -import * as Rooms from 'matrix-react-sdk/lib/Rooms'; -import * as RoomNotifs from 'matrix-react-sdk/lib/RoomNotifs'; -import Modal from 'matrix-react-sdk/lib/Modal'; -import RoomListActions from 'matrix-react-sdk/lib/actions/RoomListActions'; +import sdk from '../../../index'; +import { _t, _td } from '../../../languageHandler'; +import MatrixClientPeg from '../../../MatrixClientPeg'; +import dis from '../../../dispatcher'; +import DMRoomMap from '../../../utils/DMRoomMap'; +import * as Rooms from '../../../Rooms'; +import * as RoomNotifs from '../../../RoomNotifs'; +import Modal from '../../../Modal'; +import RoomListActions from '../../../actions/RoomListActions'; module.exports = React.createClass({ displayName: 'RoomTileContextMenu', diff --git a/src/components/views/context_menus/TagTileContextMenu.js b/src/components/views/context_menus/TagTileContextMenu.js index 576e8485a8..32f5365b82 100644 --- a/src/components/views/context_menus/TagTileContextMenu.js +++ b/src/components/views/context_menus/TagTileContextMenu.js @@ -16,11 +16,11 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; -import { _t } from 'matrix-react-sdk/lib/languageHandler'; -import dis from 'matrix-react-sdk/lib/dispatcher'; -import TagOrderActions from 'matrix-react-sdk/lib/actions/TagOrderActions'; -import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg'; -import sdk from 'matrix-react-sdk/lib/index'; +import { _t } from '../../../languageHandler'; +import dis from '../../../dispatcher'; +import TagOrderActions from '../../../actions/TagOrderActions'; +import MatrixClientPeg from '../../../MatrixClientPeg'; +import sdk from '../../../index'; export default class TagTileContextMenu extends React.Component { static propTypes = { diff --git a/src/components/views/dialogs/BugReportDialog.js b/src/components/views/dialogs/BugReportDialog.js index 95b5a6a068..8a35c1748c 100644 --- a/src/components/views/dialogs/BugReportDialog.js +++ b/src/components/views/dialogs/BugReportDialog.js @@ -15,10 +15,10 @@ limitations under the License. */ import React from 'react'; -import sdk from 'matrix-react-sdk'; -import SdkConfig from 'matrix-react-sdk/lib/SdkConfig'; -import Modal from 'matrix-react-sdk/lib/Modal'; -import { _t } from 'matrix-react-sdk/lib/languageHandler'; +import sdk from '../../../index'; +import SdkConfig from '../../../SdkConfig'; +import Modal from '../../../Modal'; +import { _t } from '../../../languageHandler'; export default class BugReportDialog extends React.Component { constructor(props, context) { diff --git a/src/components/views/dialogs/ChangelogDialog.js b/src/components/views/dialogs/ChangelogDialog.js index 92aeadf8c8..e71fcdb624 100644 --- a/src/components/views/dialogs/ChangelogDialog.js +++ b/src/components/views/dialogs/ChangelogDialog.js @@ -15,9 +15,9 @@ */ import React from 'react'; -import sdk from 'matrix-react-sdk'; +import sdk from '../../../index'; import request from 'browser-request'; -import { _t } from 'matrix-react-sdk/lib/languageHandler'; +import { _t } from '../../../languageHandler'; const REPOS = ['vector-im/riot-web', 'matrix-org/matrix-react-sdk', 'matrix-org/matrix-js-sdk']; diff --git a/src/components/views/dialogs/DevtoolsDialog.js b/src/components/views/dialogs/DevtoolsDialog.js index 3ce1dfe7d4..1d3c8ecc09 100644 --- a/src/components/views/dialogs/DevtoolsDialog.js +++ b/src/components/views/dialogs/DevtoolsDialog.js @@ -16,10 +16,10 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; -import sdk from 'matrix-react-sdk'; +import sdk from '../../../index'; import SyntaxHighlight from '../elements/SyntaxHighlight'; -import { _t } from 'matrix-react-sdk/lib/languageHandler'; -import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg'; +import { _t } from '../../../languageHandler'; +import MatrixClientPeg from '../../../MatrixClientPeg'; class DevtoolsComponent extends React.Component { static contextTypes = { diff --git a/src/components/views/dialogs/SetPasswordDialog.js b/src/components/views/dialogs/SetPasswordDialog.js index b82d03468c..31c4ad7a3f 100644 --- a/src/components/views/dialogs/SetPasswordDialog.js +++ b/src/components/views/dialogs/SetPasswordDialog.js @@ -15,9 +15,9 @@ limitations under the License. */ import React from 'react'; -import sdk from 'matrix-react-sdk'; -import { _t } from 'matrix-react-sdk/lib/languageHandler'; -import Modal from 'matrix-react-sdk/lib/Modal'; +import sdk from '../../../index'; +import { _t } from '../../../languageHandler'; +import Modal from '../../../Modal'; const WarmFuzzy = function(props) { const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); diff --git a/src/components/views/directory/NetworkDropdown.js b/src/components/views/directory/NetworkDropdown.js index 9c19cdbced..b45bd286f2 100644 --- a/src/components/views/directory/NetworkDropdown.js +++ b/src/components/views/directory/NetworkDropdown.js @@ -15,7 +15,7 @@ limitations under the License. */ import React from 'react'; -import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg'; +import MatrixClientPeg from '../../../MatrixClientPeg'; import {instanceForInstanceId} from '../../../utils/DirectoryUtils'; const DEFAULT_ICON_URL = "img/network-matrix.svg"; diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index d1a34d02df..f3ad5a9696 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -18,14 +18,14 @@ limitations under the License. var React = require('react'); -var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg'); +var MatrixClientPeg = require('../../../MatrixClientPeg'); -import {formatDate} from 'matrix-react-sdk/lib/DateUtils'; +import {formatDate} from '../../../DateUtils'; var filesize = require('filesize'); -var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton'); -const Modal = require('matrix-react-sdk/lib/Modal'); -const sdk = require('matrix-react-sdk'); -import { _t } from 'matrix-react-sdk/lib/languageHandler'; +var AccessibleButton = require('../../../components/views/elements/AccessibleButton'); +const Modal = require('../../../Modal'); +const sdk = require('../../../index'); +import { _t } from '../../../languageHandler'; module.exports = React.createClass({ displayName: 'ImageView', diff --git a/src/components/views/globals/MatrixToolbar.js b/src/components/views/globals/MatrixToolbar.js index 06bfa36e9e..f85a30bcdf 100644 --- a/src/components/views/globals/MatrixToolbar.js +++ b/src/components/views/globals/MatrixToolbar.js @@ -17,9 +17,9 @@ limitations under the License. 'use strict'; import React from 'react'; -import { _t } from 'matrix-react-sdk/lib/languageHandler'; -import Notifier from 'matrix-react-sdk/lib/Notifier'; -import AccessibleButton from 'matrix-react-sdk/lib/components/views/elements/AccessibleButton'; +import { _t } from '../../../languageHandler'; +import Notifier from '../../../Notifier'; +import AccessibleButton from '../../../components/views/elements/AccessibleButton'; module.exports = React.createClass({ displayName: 'MatrixToolbar', diff --git a/src/components/views/globals/NewVersionBar.js b/src/components/views/globals/NewVersionBar.js index 2aedf39204..527df5f864 100644 --- a/src/components/views/globals/NewVersionBar.js +++ b/src/components/views/globals/NewVersionBar.js @@ -17,10 +17,10 @@ limitations under the License. 'use strict'; import React from 'react'; -import sdk from 'matrix-react-sdk'; -import Modal from 'matrix-react-sdk/lib/Modal'; -import PlatformPeg from 'matrix-react-sdk/lib/PlatformPeg'; -import { _t } from 'matrix-react-sdk/lib/languageHandler'; +import sdk from '../../../index'; +import Modal from '../../../Modal'; +import PlatformPeg from '../../../PlatformPeg'; +import { _t } from '../../../languageHandler'; /** * Check a version string is compatible with the Changelog diff --git a/src/components/views/globals/PasswordNagBar.js b/src/components/views/globals/PasswordNagBar.js index a04d48e0c5..93f4fe06e5 100644 --- a/src/components/views/globals/PasswordNagBar.js +++ b/src/components/views/globals/PasswordNagBar.js @@ -17,10 +17,10 @@ limitations under the License. 'use strict'; import React from 'react'; -import sdk from 'matrix-react-sdk'; -import Modal from 'matrix-react-sdk/lib/Modal'; -import dis from 'matrix-react-sdk/lib/dispatcher'; -import { _t } from 'matrix-react-sdk/lib/languageHandler'; +import sdk from '../../../index'; +import Modal from '../../../Modal'; +import dis from '../../../dispatcher'; +import { _t } from '../../../languageHandler'; export default React.createClass({ onUpdateClicked: function() { diff --git a/src/components/views/globals/UpdateCheckBar.js b/src/components/views/globals/UpdateCheckBar.js index 926ccbcccf..b169054c5c 100644 --- a/src/components/views/globals/UpdateCheckBar.js +++ b/src/components/views/globals/UpdateCheckBar.js @@ -17,10 +17,10 @@ limitations under the License. 'use strict'; import React from 'react'; -import { _t } from 'matrix-react-sdk/lib/languageHandler'; -import PlatformPeg from 'matrix-react-sdk/lib/PlatformPeg'; +import { _t } from '../../../languageHandler'; +import PlatformPeg from '../../../PlatformPeg'; import {updateCheckStatusEnum} from '../../../vector/platform/VectorBasePlatform'; -import AccessibleButton from 'matrix-react-sdk/lib/components/views/elements/AccessibleButton'; +import AccessibleButton from '../../../components/views/elements/AccessibleButton'; const doneStatuses = [ updateCheckStatusEnum.ERROR, diff --git a/src/components/views/messages/DateSeparator.js b/src/components/views/messages/DateSeparator.js index 2e081bc69b..a0ea704502 100644 --- a/src/components/views/messages/DateSeparator.js +++ b/src/components/views/messages/DateSeparator.js @@ -17,8 +17,8 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; -import { _t } from 'matrix-react-sdk/lib/languageHandler'; -import {formatFullDateNoTime} from 'matrix-react-sdk/lib/DateUtils'; +import { _t } from '../../../languageHandler'; +import {formatFullDateNoTime} from '../../../DateUtils'; function getdaysArray() { return [ diff --git a/src/components/views/messages/MessageTimestamp.js b/src/components/views/messages/MessageTimestamp.js index 6d43306708..0bbb3f631e 100644 --- a/src/components/views/messages/MessageTimestamp.js +++ b/src/components/views/messages/MessageTimestamp.js @@ -17,7 +17,7 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; -import {formatFullDate, formatTime} from 'matrix-react-sdk/lib/DateUtils'; +import {formatFullDate, formatTime} from '../../../DateUtils'; export default class MessageTimestamp extends React.Component { static propTypes = { diff --git a/src/components/views/rooms/DNDRoomTile.js b/src/components/views/rooms/DNDRoomTile.js index d32ecbbb1d..69c2f979ed 100644 --- a/src/components/views/rooms/DNDRoomTile.js +++ b/src/components/views/rooms/DNDRoomTile.js @@ -16,7 +16,7 @@ limitations under the License. import React from 'react'; import { Draggable } from 'react-beautiful-dnd'; -import RoomTile from 'matrix-react-sdk/lib/components/views/rooms/RoomTile'; +import RoomTile from '../../../components/views/rooms/RoomTile'; import classNames from 'classnames'; diff --git a/src/components/views/rooms/RoomTooltip.js b/src/components/views/rooms/RoomTooltip.js index 39d8958d5e..b17f54ef3c 100644 --- a/src/components/views/rooms/RoomTooltip.js +++ b/src/components/views/rooms/RoomTooltip.js @@ -18,7 +18,7 @@ limitations under the License. var React = require('react'); var ReactDOM = require('react-dom'); -var dis = require('matrix-react-sdk/lib/dispatcher'); +var dis = require('../../../dispatcher'); import classNames from 'classnames'; const MIN_TOOLTIP_HEIGHT = 25; diff --git a/src/components/views/rooms/SearchBar.js b/src/components/views/rooms/SearchBar.js index 26bf81e428..a196c5b78d 100644 --- a/src/components/views/rooms/SearchBar.js +++ b/src/components/views/rooms/SearchBar.js @@ -17,11 +17,11 @@ limitations under the License. 'use strict'; var React = require('react'); -var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg'); -var sdk = require('matrix-react-sdk'); +var MatrixClientPeg = require('../../../MatrixClientPeg'); +var sdk = require('../../../index'); var classNames = require('classnames'); -var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton'); -import { _t } from "matrix-react-sdk/lib/languageHandler"; +var AccessibleButton = require('../../../components/views/elements/AccessibleButton'); +import { _t } from '../../../languageHandler'; module.exports = React.createClass({ displayName: 'SearchBar', diff --git a/src/components/views/settings/IntegrationsManager.js b/src/components/views/settings/IntegrationsManager.js index 4a2482f686..29ae4af93d 100644 --- a/src/components/views/settings/IntegrationsManager.js +++ b/src/components/views/settings/IntegrationsManager.js @@ -17,9 +17,9 @@ limitations under the License. 'use strict'; var React = require('react'); -var sdk = require('matrix-react-sdk'); -var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg'); -var dis = require('matrix-react-sdk/lib/dispatcher'); +var sdk = require('../../../index'); +var MatrixClientPeg = require('../../../MatrixClientPeg'); +var dis = require('../../../dispatcher'); module.exports = React.createClass({ displayName: 'IntegrationsManager', diff --git a/src/components/views/settings/Notifications.js b/src/components/views/settings/Notifications.js index be03b4d70a..39774778e1 100644 --- a/src/components/views/settings/Notifications.js +++ b/src/components/views/settings/Notifications.js @@ -16,12 +16,12 @@ limitations under the License. import React from 'react'; import Promise from 'bluebird'; -import sdk from 'matrix-react-sdk'; -import { _t } from 'matrix-react-sdk/lib/languageHandler'; -import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg'; -import UserSettingsStore from 'matrix-react-sdk/lib/UserSettingsStore'; -import SettingsStore, {SettingLevel} from "matrix-react-sdk/lib/settings/SettingsStore"; -import Modal from 'matrix-react-sdk/lib/Modal'; +import sdk from '../../../index'; +import { _t } from '../../../languageHandler'; +import MatrixClientPeg from '../../../MatrixClientPeg'; +import UserSettingsStore from '../../../UserSettingsStore'; +import SettingsStore, {SettingLevel} from '../../../settings/SettingsStore'; +import Modal from '../../../Modal'; import { NotificationUtils, VectorPushRulesDefinitions, diff --git a/src/notifications/VectorPushRulesDefinitions.js b/src/notifications/VectorPushRulesDefinitions.js index 6f72164265..47e5d56f46 100644 --- a/src/notifications/VectorPushRulesDefinitions.js +++ b/src/notifications/VectorPushRulesDefinitions.js @@ -16,7 +16,7 @@ limitations under the License. 'use strict'; -import { _td } from 'matrix-react-sdk/lib/languageHandler'; +import { _td } from '../languageHandler'; var StandardActions = require('./StandardActions'); var PushRuleVectorState = require('./PushRuleVectorState'); From 5d03eabb15be7520372c87f08aa3de49533ba810 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Fri, 13 Apr 2018 00:54:41 +0100 Subject: [PATCH 0773/1160] rethemedex --- res/css/_base.scss | 182 -------------------------------- res/css/_components.scss | 218 +++++++++++++++++++-------------------- res/css/rethemendex.sh | 3 +- 3 files changed, 110 insertions(+), 293 deletions(-) delete mode 100644 res/css/_base.scss diff --git a/res/css/_base.scss b/res/css/_base.scss deleted file mode 100644 index 51d2f70f78..0000000000 --- a/res/css/_base.scss +++ /dev/null @@ -1,182 +0,0 @@ -/* Open Sans lacks combining diacritics, so these will fall through - to the next font. Helevetica's diacritics however do not combine - nicely with Open Sans (on OSX, at least) and result in a huge - horizontal mess. Arial empirically gets it right, hence prioritising - Arial here. */ -$font-family: 'Open Sans', Arial, Helvetica, Sans-Serif; - -// typical text (dark-on-white in light skin) -$primary-fg-color: #454545; -$primary-bg-color: #ffffff; - -// used for dialog box text -$light-fg-color: #747474; - -// used for focusing form controls -$focus-bg-color: #dddddd; - -// button UI (white-on-green in light skin) -$accent-fg-color: #ffffff; -$accent-color: #76CFA6; - -$selection-fg-color: $primary-bg-color; - -$focus-brightness: 125%; - -// red warning colour -$warning-color: #ff0064; -$mention-user-pill-bg-color: #ff0064; -$other-user-pill-bg-color: rgba(0, 0, 0, 0.1); - -// pinned events indicator -$pinned-unread-color: #ff0064; // $warning-color -$pinned-color: #888; - -// informational plinth -$info-plinth-bg-color: #f7f7f7; -$info-plinth-fg-color: #888; - -$preview-bar-bg-color: #f7f7f7; - -// left-panel style muted accent color -$secondary-accent-color: #eaf5f0; -$tertiary-accent-color: #d3efe1; - -// used by RoomDirectory permissions -$plinth-bg-color: $secondary-accent-color; - -// used by RoomDropTarget -$droptarget-bg-color: rgba(255,255,255,0.5); - -// used by AddressSelector -$selected-color: $secondary-accent-color; - -// selected for hoverover & selected event tiles -$event-selected-color: #f7f7f7; - -// used for the hairline dividers in RoomView -$primary-hairline-color: #e5e5e5; - -// used for the border of input text fields -$input-border-color: #f0f0f0; - -// apart from login forms, which have stronger border -$strong-input-border-color: #c7c7c7; - -// used for UserSettings EditableText -$input-underline-color: rgba(151, 151, 151, 0.5); -$input-fg-color: rgba(74, 74, 74, 0.9); - -// context menus -$menu-border-color: rgba(187, 187, 187, 0.5); -$menu-bg-color: #f6f6f6; - -$avatar-initial-color: #ffffff; -$avatar-bg-color: #ffffff; - -$h3-color: #3d3b39; - -$dialog-background-bg-color: #e9e9e9; -$lightbox-background-bg-color: #000; - -$greyed-fg-color: #888; - -$neutral-badge-color: #dbdbdb; - -$preview-widget-bar-color: #ddd; -$preview-widget-fg-color: $greyed-fg-color; - -$blockquote-bar-color: #ddd; -$blockquote-fg-color: #777; - -$settings-grey-fg-color: #a2a2a2; - -$voip-decline-color: #f48080; -$voip-accept-color: #80f480; - -$rte-bg-color: #e9e9e9; -$rte-code-bg-color: rgba(0, 0, 0, 0.04); -$rte-room-pill-color: #aaa; - -// ******************** - -$roomtile-name-color: rgba(69, 69, 69, 0.8); -$roomtile-selected-bg-color: rgba(255, 255, 255, 0.8); -$roomtile-focused-bg-color: rgba(255, 255, 255, 0.9); - -$roomtile-transparent-focused-color: rgba(0, 0, 0, 0.1); - -$roomsublist-background: rgba(0, 0, 0, 0.05); -$roomsublist-label-fg-color: $h3-color; -$roomsublist-label-bg-color: $tertiary-accent-color; -$roomsublist-chevron-color: $accent-color; - -$panel-divider-color: rgba(118, 207, 166, 0.2); - -// ******************** - -$widget-menu-bar-bg-color: $tertiary-accent-color; - -// ******************** - -// event tile lifecycle -$event-encrypting-color: #abddbc; -$event-sending-color: #ddd; -$event-notsent-color: #f44; - -// event redaction -$event-redacted-fg-color: #e2e2e2; -$event-redacted-border-color: #cccccc; - -// event timestamp -$event-timestamp-color: #acacac; - -$edit-button-url: "../../img/icon_context_message.svg"; -$copy-button-url: "../../img/icon_copy_message.svg"; - -// e2e -$e2e-verified-color: #76cfa5; // N.B. *NOT* the same as $accent-color -$e2e-unverified-color: #e8bf37; -$e2e-warning-color: #ba6363; - -// presence -$presence-online: #60de00; -$presence-unavailable: #deb800; -$presence-offline: #b7b7b7; - -/*** ImageView ***/ -$lightbox-bg-color: #454545; -$lightbox-fg-color: #ffffff; -$lightbox-border-color: #ffffff; - -// unused? -$progressbar-color: #000; - -// ***** Mixins! ***** - -@define-mixin mx_DialogButton { - /* align images in buttons (eg spinners) */ - vertical-align: middle; - border: 0px; - border-radius: 36px; - font-family: $font-family; - font-size: 14px; - color: $accent-fg-color; - background-color: $accent-color; - width: auto; - padding: 7px; - padding-left: 1.5em; - padding-right: 1.5em; - cursor: pointer; - display: inline-block; - outline: none; -} - -@define-mixin mx_DialogButton_hover { -} - -@define-mixin mx_DialogButton_small { - @mixin mx_DialogButton; - font-size: 15px; - padding: 0px 1.5em 0px 1.5em; -} diff --git a/res/css/_components.scss b/res/css/_components.scss index 0bcc48c3b8..b62c08f763 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -1,111 +1,111 @@ // autogenerated by rethemendex.sh @import "./_common.scss"; -@import "./matrix-react-sdk/structures/_ContextualMenu.scss"; -@import "./matrix-react-sdk/structures/_CreateRoom.scss"; -@import "./matrix-react-sdk/structures/_FilePanel.scss"; -@import "./matrix-react-sdk/structures/_GroupView.scss"; -@import "./matrix-react-sdk/structures/_LoginBox.scss"; -@import "./matrix-react-sdk/structures/_MatrixChat.scss"; -@import "./matrix-react-sdk/structures/_MyGroups.scss"; -@import "./matrix-react-sdk/structures/_NotificationPanel.scss"; -@import "./matrix-react-sdk/structures/_RoomStatusBar.scss"; -@import "./matrix-react-sdk/structures/_RoomView.scss"; -@import "./matrix-react-sdk/structures/_SearchBox.scss"; -@import "./matrix-react-sdk/structures/_TagPanel.scss"; -@import "./matrix-react-sdk/structures/_UploadBar.scss"; -@import "./matrix-react-sdk/structures/_UserSettings.scss"; -@import "./matrix-react-sdk/structures/login/_Login.scss"; -@import "./matrix-react-sdk/views/avatars/_BaseAvatar.scss"; -@import "./matrix-react-sdk/views/avatars/_MemberPresenceAvatar.scss"; -@import "./matrix-react-sdk/views/dialogs/_BugReportDialog.scss"; -@import "./matrix-react-sdk/views/dialogs/_ChatCreateOrReuseChatDialog.scss"; -@import "./matrix-react-sdk/views/dialogs/_ChatInviteDialog.scss"; -@import "./matrix-react-sdk/views/dialogs/_ConfirmUserActionDialog.scss"; -@import "./matrix-react-sdk/views/dialogs/_CreateGroupDialog.scss"; -@import "./matrix-react-sdk/views/dialogs/_CreateRoomDialog.scss"; -@import "./matrix-react-sdk/views/dialogs/_EncryptedEventDialog.scss"; -@import "./matrix-react-sdk/views/dialogs/_GroupAddressPicker.scss"; -@import "./matrix-react-sdk/views/dialogs/_QuestionDialog.scss"; -@import "./matrix-react-sdk/views/dialogs/_SetMxIdDialog.scss"; -@import "./matrix-react-sdk/views/dialogs/_UnknownDeviceDialog.scss"; -@import "./matrix-react-sdk/views/elements/_AccessibleButton.scss"; -@import "./matrix-react-sdk/views/elements/_AddressSelector.scss"; -@import "./matrix-react-sdk/views/elements/_AddressTile.scss"; -@import "./matrix-react-sdk/views/elements/_DirectorySearchBox.scss"; -@import "./matrix-react-sdk/views/elements/_Dropdown.scss"; -@import "./matrix-react-sdk/views/elements/_EditableItemList.scss"; -@import "./matrix-react-sdk/views/elements/_MemberEventListSummary.scss"; -@import "./matrix-react-sdk/views/elements/_ProgressBar.scss"; -@import "./matrix-react-sdk/views/elements/_Quote.scss"; -@import "./matrix-react-sdk/views/elements/_RichText.scss"; -@import "./matrix-react-sdk/views/elements/_RoleButton.scss"; -@import "./matrix-react-sdk/views/elements/_ToolTipButton.scss"; -@import "./matrix-react-sdk/views/groups/_GroupPublicityToggle.scss"; -@import "./matrix-react-sdk/views/groups/_GroupRoomList.scss"; -@import "./matrix-react-sdk/views/groups/_GroupUserSettings.scss"; -@import "./matrix-react-sdk/views/login/_InteractiveAuthEntryComponents.scss"; -@import "./matrix-react-sdk/views/login/_ServerConfig.scss"; -@import "./matrix-react-sdk/views/messages/_MEmoteBody.scss"; -@import "./matrix-react-sdk/views/messages/_MFileBody.scss"; -@import "./matrix-react-sdk/views/messages/_MImageBody.scss"; -@import "./matrix-react-sdk/views/messages/_MStickerBody.scss"; -@import "./matrix-react-sdk/views/messages/_MNoticeBody.scss"; -@import "./matrix-react-sdk/views/messages/_MTextBody.scss"; -@import "./matrix-react-sdk/views/messages/_RoomAvatarEvent.scss"; -@import "./matrix-react-sdk/views/messages/_TextualEvent.scss"; -@import "./matrix-react-sdk/views/messages/_UnknownBody.scss"; -@import "./matrix-react-sdk/views/rooms/_AppsDrawer.scss"; -@import "./matrix-react-sdk/views/rooms/_Autocomplete.scss"; -@import "./matrix-react-sdk/views/rooms/_EntityTile.scss"; -@import "./matrix-react-sdk/views/rooms/_EventTile.scss"; -@import "./matrix-react-sdk/views/rooms/_LinkPreviewWidget.scss"; -@import "./matrix-react-sdk/views/rooms/_MemberDeviceInfo.scss"; -@import "./matrix-react-sdk/views/rooms/_MemberInfo.scss"; -@import "./matrix-react-sdk/views/rooms/_MemberList.scss"; -@import "./matrix-react-sdk/views/rooms/_MessageComposer.scss"; -@import "./matrix-react-sdk/views/rooms/_Stickers.scss"; -@import "./matrix-react-sdk/views/rooms/_PinnedEventTile.scss"; -@import "./matrix-react-sdk/views/rooms/_PinnedEventsPanel.scss"; -@import "./matrix-react-sdk/views/rooms/_PresenceLabel.scss"; -@import "./matrix-react-sdk/views/rooms/_QuotePreview.scss"; -@import "./matrix-react-sdk/views/rooms/_RoomHeader.scss"; -@import "./matrix-react-sdk/views/rooms/_RoomList.scss"; -@import "./matrix-react-sdk/views/rooms/_RoomPreviewBar.scss"; -@import "./matrix-react-sdk/views/rooms/_RoomSettings.scss"; -@import "./matrix-react-sdk/views/rooms/_RoomTile.scss"; -@import "./matrix-react-sdk/views/rooms/_SearchableEntityList.scss"; -@import "./matrix-react-sdk/views/rooms/_TopUnreadMessagesBar.scss"; -@import "./matrix-react-sdk/views/settings/_DevicesPanel.scss"; -@import "./matrix-react-sdk/views/settings/_IntegrationsManager.scss"; -@import "./matrix-react-sdk/views/voip/_CallView.scss"; -@import "./matrix-react-sdk/views/voip/_IncomingCallbox.scss"; -@import "./matrix-react-sdk/views/voip/_VideoView.scss"; -@import "./vector-web/_fonts.scss"; -@import "./vector-web/structures/_CompatibilityPage.scss"; -@import "./vector-web/structures/_HomePage.scss"; -@import "./vector-web/structures/_LeftPanel.scss"; -@import "./vector-web/structures/_RightPanel.scss"; -@import "./vector-web/structures/_RoomDirectory.scss"; -@import "./vector-web/structures/_RoomSubList.scss"; -@import "./vector-web/structures/_ViewSource.scss"; -@import "./vector-web/views/context_menus/_MessageContextMenu.scss"; -@import "./vector-web/views/context_menus/_PresenceContextMenuOption.scss"; -@import "./vector-web/views/context_menus/_RoomTileContextMenu.scss"; -@import "./vector-web/views/context_menus/_TagTileContextMenu.scss"; -@import "./vector-web/views/dialogs/_ChangelogDialog.scss"; -@import "./vector-web/views/dialogs/_DevtoolsDialog.scss"; -@import "./vector-web/views/dialogs/_SetEmailDialog.scss"; -@import "./vector-web/views/dialogs/_SetPasswordDialog.scss"; -@import "./vector-web/views/directory/_NetworkDropdown.scss"; -@import "./vector-web/views/elements/_ImageView.scss"; -@import "./vector-web/views/elements/_InlineSpinner.scss"; -@import "./vector-web/views/elements/_Spinner.scss"; -@import "./vector-web/views/elements/_SyntaxHighlight.scss"; -@import "./vector-web/views/globals/_MatrixToolbar.scss"; -@import "./vector-web/views/messages/_DateSeparator.scss"; -@import "./vector-web/views/messages/_MessageTimestamp.scss"; -@import "./vector-web/views/messages/_SenderProfile.scss"; -@import "./vector-web/views/rooms/_RoomDropTarget.scss"; -@import "./vector-web/views/rooms/_RoomTooltip.scss"; -@import "./vector-web/views/rooms/_SearchBar.scss"; -@import "./vector-web/views/settings/_Notifications.scss"; +@import "./_fonts.scss"; +@import "./structures/_CompatibilityPage.scss"; +@import "./structures/_ContextualMenu.scss"; +@import "./structures/_CreateRoom.scss"; +@import "./structures/_FilePanel.scss"; +@import "./structures/_GroupView.scss"; +@import "./structures/_HomePage.scss"; +@import "./structures/_LeftPanel.scss"; +@import "./structures/_LoginBox.scss"; +@import "./structures/_MatrixChat.scss"; +@import "./structures/_MyGroups.scss"; +@import "./structures/_NotificationPanel.scss"; +@import "./structures/_RightPanel.scss"; +@import "./structures/_RoomDirectory.scss"; +@import "./structures/_RoomStatusBar.scss"; +@import "./structures/_RoomSubList.scss"; +@import "./structures/_RoomView.scss"; +@import "./structures/_SearchBox.scss"; +@import "./structures/_TagPanel.scss"; +@import "./structures/_UploadBar.scss"; +@import "./structures/_UserSettings.scss"; +@import "./structures/_ViewSource.scss"; +@import "./structures/login/_Login.scss"; +@import "./views/avatars/_BaseAvatar.scss"; +@import "./views/avatars/_MemberPresenceAvatar.scss"; +@import "./views/context_menus/_MessageContextMenu.scss"; +@import "./views/context_menus/_PresenceContextMenuOption.scss"; +@import "./views/context_menus/_RoomTileContextMenu.scss"; +@import "./views/context_menus/_TagTileContextMenu.scss"; +@import "./views/dialogs/_BugReportDialog.scss"; +@import "./views/dialogs/_ChangelogDialog.scss"; +@import "./views/dialogs/_ChatCreateOrReuseChatDialog.scss"; +@import "./views/dialogs/_ChatInviteDialog.scss"; +@import "./views/dialogs/_ConfirmUserActionDialog.scss"; +@import "./views/dialogs/_CreateGroupDialog.scss"; +@import "./views/dialogs/_CreateRoomDialog.scss"; +@import "./views/dialogs/_DevtoolsDialog.scss"; +@import "./views/dialogs/_EncryptedEventDialog.scss"; +@import "./views/dialogs/_GroupAddressPicker.scss"; +@import "./views/dialogs/_QuestionDialog.scss"; +@import "./views/dialogs/_SetEmailDialog.scss"; +@import "./views/dialogs/_SetMxIdDialog.scss"; +@import "./views/dialogs/_SetPasswordDialog.scss"; +@import "./views/dialogs/_UnknownDeviceDialog.scss"; +@import "./views/directory/_NetworkDropdown.scss"; +@import "./views/elements/_AccessibleButton.scss"; +@import "./views/elements/_AddressSelector.scss"; +@import "./views/elements/_AddressTile.scss"; +@import "./views/elements/_DirectorySearchBox.scss"; +@import "./views/elements/_Dropdown.scss"; +@import "./views/elements/_EditableItemList.scss"; +@import "./views/elements/_ImageView.scss"; +@import "./views/elements/_InlineSpinner.scss"; +@import "./views/elements/_MemberEventListSummary.scss"; +@import "./views/elements/_ProgressBar.scss"; +@import "./views/elements/_Quote.scss"; +@import "./views/elements/_RichText.scss"; +@import "./views/elements/_RoleButton.scss"; +@import "./views/elements/_Spinner.scss"; +@import "./views/elements/_SyntaxHighlight.scss"; +@import "./views/elements/_ToolTipButton.scss"; +@import "./views/globals/_MatrixToolbar.scss"; +@import "./views/groups/_GroupPublicityToggle.scss"; +@import "./views/groups/_GroupRoomList.scss"; +@import "./views/groups/_GroupUserSettings.scss"; +@import "./views/login/_InteractiveAuthEntryComponents.scss"; +@import "./views/login/_ServerConfig.scss"; +@import "./views/messages/_DateSeparator.scss"; +@import "./views/messages/_MEmoteBody.scss"; +@import "./views/messages/_MFileBody.scss"; +@import "./views/messages/_MImageBody.scss"; +@import "./views/messages/_MNoticeBody.scss"; +@import "./views/messages/_MStickerBody.scss"; +@import "./views/messages/_MTextBody.scss"; +@import "./views/messages/_MessageTimestamp.scss"; +@import "./views/messages/_RoomAvatarEvent.scss"; +@import "./views/messages/_SenderProfile.scss"; +@import "./views/messages/_TextualEvent.scss"; +@import "./views/messages/_UnknownBody.scss"; +@import "./views/rooms/_AppsDrawer.scss"; +@import "./views/rooms/_Autocomplete.scss"; +@import "./views/rooms/_EntityTile.scss"; +@import "./views/rooms/_EventTile.scss"; +@import "./views/rooms/_LinkPreviewWidget.scss"; +@import "./views/rooms/_MemberDeviceInfo.scss"; +@import "./views/rooms/_MemberInfo.scss"; +@import "./views/rooms/_MemberList.scss"; +@import "./views/rooms/_MessageComposer.scss"; +@import "./views/rooms/_PinnedEventTile.scss"; +@import "./views/rooms/_PinnedEventsPanel.scss"; +@import "./views/rooms/_PresenceLabel.scss"; +@import "./views/rooms/_QuotePreview.scss"; +@import "./views/rooms/_RoomDropTarget.scss"; +@import "./views/rooms/_RoomHeader.scss"; +@import "./views/rooms/_RoomList.scss"; +@import "./views/rooms/_RoomPreviewBar.scss"; +@import "./views/rooms/_RoomSettings.scss"; +@import "./views/rooms/_RoomTile.scss"; +@import "./views/rooms/_RoomTooltip.scss"; +@import "./views/rooms/_SearchBar.scss"; +@import "./views/rooms/_SearchableEntityList.scss"; +@import "./views/rooms/_Stickers.scss"; +@import "./views/rooms/_TopUnreadMessagesBar.scss"; +@import "./views/settings/_DevicesPanel.scss"; +@import "./views/settings/_IntegrationsManager.scss"; +@import "./views/settings/_Notifications.scss"; +@import "./views/voip/_CallView.scss"; +@import "./views/voip/_IncomingCallbox.scss"; +@import "./views/voip/_VideoView.scss"; diff --git a/res/css/rethemendex.sh b/res/css/rethemendex.sh index a7d9a657ac..f2e60a1e46 100755 --- a/res/css/rethemendex.sh +++ b/res/css/rethemendex.sh @@ -5,8 +5,7 @@ cd `dirname $0` { echo "// autogenerated by rethemendex.sh" - find . \! \( -path ./themes -prune \) -iname _\*.scss | - fgrep -v _components.scss | LC_ALL=C sort | + find . -iname _\*.scss | fgrep -v _components.scss | LC_ALL=C sort | while read i; do echo "@import \"$i\";" done From 5f3e4444d0c979150aec12e864b40a817f9c0b3b Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Fri, 13 Apr 2018 01:25:34 +0100 Subject: [PATCH 0774/1160] fix theme paths --- res/themes/dark/css/dark.scss | 4 +- res/themes/light/css/_base.scss | 182 ++++++++++++++++++++++++++++++++ res/themes/light/css/light.scss | 2 +- 3 files changed, 185 insertions(+), 3 deletions(-) create mode 100644 res/themes/light/css/_base.scss diff --git a/res/themes/dark/css/dark.scss b/res/themes/dark/css/dark.scss index 5a37d0368e..f7e78c86c3 100644 --- a/res/themes/dark/css/dark.scss +++ b/res/themes/dark/css/dark.scss @@ -1,3 +1,3 @@ -@import "_base.scss"; +@import "../../light/css/_base.scss"; @import "_dark.scss"; -@import "../_components.scss"; +@import "../../../../res/css/_components.scss"; \ No newline at end of file diff --git a/res/themes/light/css/_base.scss b/res/themes/light/css/_base.scss new file mode 100644 index 0000000000..51d2f70f78 --- /dev/null +++ b/res/themes/light/css/_base.scss @@ -0,0 +1,182 @@ +/* Open Sans lacks combining diacritics, so these will fall through + to the next font. Helevetica's diacritics however do not combine + nicely with Open Sans (on OSX, at least) and result in a huge + horizontal mess. Arial empirically gets it right, hence prioritising + Arial here. */ +$font-family: 'Open Sans', Arial, Helvetica, Sans-Serif; + +// typical text (dark-on-white in light skin) +$primary-fg-color: #454545; +$primary-bg-color: #ffffff; + +// used for dialog box text +$light-fg-color: #747474; + +// used for focusing form controls +$focus-bg-color: #dddddd; + +// button UI (white-on-green in light skin) +$accent-fg-color: #ffffff; +$accent-color: #76CFA6; + +$selection-fg-color: $primary-bg-color; + +$focus-brightness: 125%; + +// red warning colour +$warning-color: #ff0064; +$mention-user-pill-bg-color: #ff0064; +$other-user-pill-bg-color: rgba(0, 0, 0, 0.1); + +// pinned events indicator +$pinned-unread-color: #ff0064; // $warning-color +$pinned-color: #888; + +// informational plinth +$info-plinth-bg-color: #f7f7f7; +$info-plinth-fg-color: #888; + +$preview-bar-bg-color: #f7f7f7; + +// left-panel style muted accent color +$secondary-accent-color: #eaf5f0; +$tertiary-accent-color: #d3efe1; + +// used by RoomDirectory permissions +$plinth-bg-color: $secondary-accent-color; + +// used by RoomDropTarget +$droptarget-bg-color: rgba(255,255,255,0.5); + +// used by AddressSelector +$selected-color: $secondary-accent-color; + +// selected for hoverover & selected event tiles +$event-selected-color: #f7f7f7; + +// used for the hairline dividers in RoomView +$primary-hairline-color: #e5e5e5; + +// used for the border of input text fields +$input-border-color: #f0f0f0; + +// apart from login forms, which have stronger border +$strong-input-border-color: #c7c7c7; + +// used for UserSettings EditableText +$input-underline-color: rgba(151, 151, 151, 0.5); +$input-fg-color: rgba(74, 74, 74, 0.9); + +// context menus +$menu-border-color: rgba(187, 187, 187, 0.5); +$menu-bg-color: #f6f6f6; + +$avatar-initial-color: #ffffff; +$avatar-bg-color: #ffffff; + +$h3-color: #3d3b39; + +$dialog-background-bg-color: #e9e9e9; +$lightbox-background-bg-color: #000; + +$greyed-fg-color: #888; + +$neutral-badge-color: #dbdbdb; + +$preview-widget-bar-color: #ddd; +$preview-widget-fg-color: $greyed-fg-color; + +$blockquote-bar-color: #ddd; +$blockquote-fg-color: #777; + +$settings-grey-fg-color: #a2a2a2; + +$voip-decline-color: #f48080; +$voip-accept-color: #80f480; + +$rte-bg-color: #e9e9e9; +$rte-code-bg-color: rgba(0, 0, 0, 0.04); +$rte-room-pill-color: #aaa; + +// ******************** + +$roomtile-name-color: rgba(69, 69, 69, 0.8); +$roomtile-selected-bg-color: rgba(255, 255, 255, 0.8); +$roomtile-focused-bg-color: rgba(255, 255, 255, 0.9); + +$roomtile-transparent-focused-color: rgba(0, 0, 0, 0.1); + +$roomsublist-background: rgba(0, 0, 0, 0.05); +$roomsublist-label-fg-color: $h3-color; +$roomsublist-label-bg-color: $tertiary-accent-color; +$roomsublist-chevron-color: $accent-color; + +$panel-divider-color: rgba(118, 207, 166, 0.2); + +// ******************** + +$widget-menu-bar-bg-color: $tertiary-accent-color; + +// ******************** + +// event tile lifecycle +$event-encrypting-color: #abddbc; +$event-sending-color: #ddd; +$event-notsent-color: #f44; + +// event redaction +$event-redacted-fg-color: #e2e2e2; +$event-redacted-border-color: #cccccc; + +// event timestamp +$event-timestamp-color: #acacac; + +$edit-button-url: "../../img/icon_context_message.svg"; +$copy-button-url: "../../img/icon_copy_message.svg"; + +// e2e +$e2e-verified-color: #76cfa5; // N.B. *NOT* the same as $accent-color +$e2e-unverified-color: #e8bf37; +$e2e-warning-color: #ba6363; + +// presence +$presence-online: #60de00; +$presence-unavailable: #deb800; +$presence-offline: #b7b7b7; + +/*** ImageView ***/ +$lightbox-bg-color: #454545; +$lightbox-fg-color: #ffffff; +$lightbox-border-color: #ffffff; + +// unused? +$progressbar-color: #000; + +// ***** Mixins! ***** + +@define-mixin mx_DialogButton { + /* align images in buttons (eg spinners) */ + vertical-align: middle; + border: 0px; + border-radius: 36px; + font-family: $font-family; + font-size: 14px; + color: $accent-fg-color; + background-color: $accent-color; + width: auto; + padding: 7px; + padding-left: 1.5em; + padding-right: 1.5em; + cursor: pointer; + display: inline-block; + outline: none; +} + +@define-mixin mx_DialogButton_hover { +} + +@define-mixin mx_DialogButton_small { + @mixin mx_DialogButton; + font-size: 15px; + padding: 0px 1.5em 0px 1.5em; +} diff --git a/res/themes/light/css/light.scss b/res/themes/light/css/light.scss index ea0f93d5a3..e2c553f30d 100644 --- a/res/themes/light/css/light.scss +++ b/res/themes/light/css/light.scss @@ -1,2 +1,2 @@ @import "_base.scss"; -@import "../_components.scss"; \ No newline at end of file +@import "../../../../res/css/_components.scss"; \ No newline at end of file From 0336d99b9ec680219e956b382e599cbac52b4889 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Fri, 13 Apr 2018 01:29:24 +0100 Subject: [PATCH 0775/1160] move VectorConferenceHandler over and use getUpdateCheckStatusEnum via field rather than export --- src/VectorConferenceHandler.js | 138 ++++++++++++++++++ .../views/globals/UpdateCheckBar.js | 20 ++- 2 files changed, 150 insertions(+), 8 deletions(-) create mode 100644 src/VectorConferenceHandler.js diff --git a/src/VectorConferenceHandler.js b/src/VectorConferenceHandler.js new file mode 100644 index 0000000000..19081726b2 --- /dev/null +++ b/src/VectorConferenceHandler.js @@ -0,0 +1,138 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +"use strict"; + +import Promise from 'bluebird'; +var Matrix = require("matrix-js-sdk"); +var Room = Matrix.Room; +var CallHandler = require('./CallHandler'); + +// FIXME: this is Riot (Vector) specific code, but will be removed shortly when +// we switch over to jitsi entirely for video conferencing. + +// FIXME: This currently forces Vector to try to hit the matrix.org AS for conferencing. +// This is bad because it prevents people running their own ASes from being used. +// This isn't permanent and will be customisable in the future: see the proposal +// at docs/conferencing.md for more info. +var USER_PREFIX = "fs_"; +var DOMAIN = "matrix.org"; + +function ConferenceCall(matrixClient, groupChatRoomId) { + this.client = matrixClient; + this.groupRoomId = groupChatRoomId; + this.confUserId = module.exports.getConferenceUserIdForRoom(this.groupRoomId); +} + +ConferenceCall.prototype.setup = function() { + var self = this; + return this._joinConferenceUser().then(function() { + return self._getConferenceUserRoom(); + }).then(function(room) { + // return a call for *this* room to be placed. We also tack on + // confUserId to speed up lookups (else we'd need to loop every room + // looking for a 1:1 room with this conf user ID!) + var call = Matrix.createNewMatrixCall(self.client, room.roomId); + call.confUserId = self.confUserId; + call.groupRoomId = self.groupRoomId; + return call; + }); +}; + +ConferenceCall.prototype._joinConferenceUser = function() { + // Make sure the conference user is in the group chat room + var groupRoom = this.client.getRoom(this.groupRoomId); + if (!groupRoom) { + return Promise.reject("Bad group room ID"); + } + var member = groupRoom.getMember(this.confUserId); + if (member && member.membership === "join") { + return Promise.resolve(); + } + return this.client.invite(this.groupRoomId, this.confUserId); +}; + +ConferenceCall.prototype._getConferenceUserRoom = function() { + // Use an existing 1:1 with the conference user; else make one + var rooms = this.client.getRooms(); + var confRoom = null; + for (var i = 0; i < rooms.length; i++) { + var confUser = rooms[i].getMember(this.confUserId); + if (confUser && confUser.membership === "join" && + rooms[i].getJoinedMembers().length === 2) { + confRoom = rooms[i]; + break; + } + } + if (confRoom) { + return Promise.resolve(confRoom); + } + return this.client.createRoom({ + preset: "private_chat", + invite: [this.confUserId] + }).then(function(res) { + return new Room(res.room_id); + }); +}; + +/** + * Check if this user ID is in fact a conference bot. + * @param {string} userId The user ID to check. + * @return {boolean} True if it is a conference bot. + */ +module.exports.isConferenceUser = function(userId) { + if (userId.indexOf("@" + USER_PREFIX) !== 0) { + return false; + } + var base64part = userId.split(":")[0].substring(1 + USER_PREFIX.length); + if (base64part) { + var decoded = new Buffer(base64part, "base64").toString(); + // ! $STUFF : $STUFF + return /^!.+:.+/.test(decoded); + } + return false; +}; + +module.exports.getConferenceUserIdForRoom = function(roomId) { + // abuse browserify's core node Buffer support (strip padding ='s) + var base64RoomId = new Buffer(roomId).toString("base64").replace(/=/g, ""); + return "@" + USER_PREFIX + base64RoomId + ":" + DOMAIN; +}; + +module.exports.createNewMatrixCall = function(client, roomId) { + var confCall = new ConferenceCall( + client, roomId + ); + return confCall.setup(); +}; + +module.exports.getConferenceCallForRoom = function(roomId) { + // search for a conference 1:1 call for this group chat room ID + var activeCall = CallHandler.getAnyActiveCall(); + if (activeCall && activeCall.confUserId) { + var thisRoomConfUserId = module.exports.getConferenceUserIdForRoom( + roomId + ); + if (thisRoomConfUserId === activeCall.confUserId) { + return activeCall; + } + } + return null; +}; + +module.exports.ConferenceCall = ConferenceCall; + +module.exports.slot = 'conference'; diff --git a/src/components/views/globals/UpdateCheckBar.js b/src/components/views/globals/UpdateCheckBar.js index b169054c5c..4397b3313e 100644 --- a/src/components/views/globals/UpdateCheckBar.js +++ b/src/components/views/globals/UpdateCheckBar.js @@ -19,14 +19,8 @@ limitations under the License. import React from 'react'; import { _t } from '../../../languageHandler'; import PlatformPeg from '../../../PlatformPeg'; -import {updateCheckStatusEnum} from '../../../vector/platform/VectorBasePlatform'; import AccessibleButton from '../../../components/views/elements/AccessibleButton'; -const doneStatuses = [ - updateCheckStatusEnum.ERROR, - updateCheckStatusEnum.NOTAVAILABLE, -]; - export default React.createClass({ propTypes: { status: React.PropTypes.oneOf(Object.values(updateCheckStatusEnum)).isRequired, @@ -42,6 +36,7 @@ export default React.createClass({ }, getStatusText: function() { + const updateCheckStatusEnum = PlatformPeg.get().getUpdateCheckStatusEnum(); switch(this.props.status) { case updateCheckStatusEnum.ERROR: return _t('Error encountered (%(errorDetail)s).', { errorDetail: this.props.detail }); @@ -52,8 +47,7 @@ export default React.createClass({ case updateCheckStatusEnum.DOWNLOADING: return _t('Downloading update...'); } - } - , + }, hideToolbar: function() { PlatformPeg.get().stopUpdateCheck(); @@ -63,6 +57,16 @@ export default React.createClass({ const message = this.getStatusText(); const warning = _t('Warning'); + if (!'getUpdateCheckStatusEnum' in PlatformPeg.get()) { + return
    ; + } + + const updateCheckStatusEnum = PlatformPeg.get().getUpdateCheckStatusEnum(); + const doneStatuses = [ + updateCheckStatusEnum.ERROR, + updateCheckStatusEnum.NOTAVAILABLE, + ]; + let image; if (doneStatuses.includes(this.props.status)) { image = {warning}/; From efe466ef752ed2c30fb41fb74c0f6a565e1862ec Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Fri, 13 Apr 2018 01:34:16 +0100 Subject: [PATCH 0776/1160] move rageshake to sdk --- src/rageshake/rageshake.js | 474 ++++++++++++++++++++++++++++++ src/rageshake/submit-rageshake.js | 126 ++++++++ 2 files changed, 600 insertions(+) create mode 100644 src/rageshake/rageshake.js create mode 100644 src/rageshake/submit-rageshake.js diff --git a/src/rageshake/rageshake.js b/src/rageshake/rageshake.js new file mode 100644 index 0000000000..11e19a709e --- /dev/null +++ b/src/rageshake/rageshake.js @@ -0,0 +1,474 @@ +/* +Copyright 2017 OpenMarket Ltd +Copyright 2018 New Vector Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import Promise from 'bluebird'; + +// This module contains all the code needed to log the console, persist it to +// disk and submit bug reports. Rationale is as follows: +// - Monkey-patching the console is preferable to having a log library because +// we can catch logs by other libraries more easily, without having to all +// depend on the same log framework / pass the logger around. +// - We use IndexedDB to persists logs because it has generous disk space +// limits compared to local storage. IndexedDB does not work in incognito +// mode, in which case this module will not be able to write logs to disk. +// However, the logs will still be stored in-memory, so can still be +// submitted in a bug report should the user wish to: we can also store more +// logs in-memory than in local storage, which does work in incognito mode. +// We also need to handle the case where there are 2+ tabs. Each JS runtime +// generates a random string which serves as the "ID" for that tab/session. +// These IDs are stored along with the log lines. +// - Bug reports are sent as a POST over HTTPS: it purposefully does not use +// Matrix as bug reports may be made when Matrix is not responsive (which may +// be the cause of the bug). We send the most recent N MB of UTF-8 log data, +// starting with the most recent, which we know because the "ID"s are +// actually timestamps. We then purge the remaining logs. We also do this +// purge on startup to prevent logs from accumulating. + +// the frequency with which we flush to indexeddb +const FLUSH_RATE_MS = 30 * 1000; + +// the length of log data we keep in indexeddb (and include in the reports) +const MAX_LOG_SIZE = 1024 * 1024 * 1; // 1 MB + +// A class which monkey-patches the global console and stores log lines. +class ConsoleLogger { + constructor() { + this.logs = ""; + } + + monkeyPatch(consoleObj) { + // Monkey-patch console logging + const consoleFunctionsToLevels = { + log: "I", + info: "I", + warn: "W", + error: "E", + }; + Object.keys(consoleFunctionsToLevels).forEach((fnName) => { + const level = consoleFunctionsToLevels[fnName]; + let originalFn = consoleObj[fnName].bind(consoleObj); + consoleObj[fnName] = (...args) => { + this.log(level, ...args); + originalFn(...args); + } + }); + } + + log(level, ...args) { + // We don't know what locale the user may be running so use ISO strings + const ts = new Date().toISOString(); + // Some browsers support string formatting which we're not doing here + // so the lines are a little more ugly but easy to implement / quick to + // run. + // Example line: + // 2017-01-18T11:23:53.214Z W Failed to set badge count + const line = `${ts} ${level} ${args.join(' ')}\n`; + // Using + really is the quickest way in JS + // http://jsperf.com/concat-vs-plus-vs-join + this.logs += line; + } + + /** + * Retrieve log lines to flush to disk. + * @param {boolean} keepLogs True to not delete logs after flushing. + * @return {string} \n delimited log lines to flush. + */ + flush(keepLogs) { + // The ConsoleLogger doesn't care how these end up on disk, it just + // flushes them to the caller. + if (keepLogs) { + return this.logs; + } + const logsToFlush = this.logs; + this.logs = ""; + return logsToFlush; + } +} + +// A class which stores log lines in an IndexedDB instance. +class IndexedDBLogStore { + constructor(indexedDB, logger) { + this.indexedDB = indexedDB; + this.logger = logger; + this.id = "instance-" + Math.random() + Date.now(); + this.index = 0; + this.db = null; + this.flushPromise = null; + // set if flush() is called whilst one is ongoing + this.flushAgainPromise = null; + } + + /** + * @return {Promise} Resolves when the store is ready. + */ + connect() { + let req = this.indexedDB.open("logs"); + return new Promise((resolve, reject) => { + req.onsuccess = (event) => { + this.db = event.target.result; + // Periodically flush logs to local storage / indexeddb + setInterval(this.flush.bind(this), FLUSH_RATE_MS); + resolve(); + }; + + req.onerror = (event) => { + const err = ( + "Failed to open log database: " + event.target.errorCode + ); + console.error(err); + reject(new Error(err)); + }; + + // First time: Setup the object store + req.onupgradeneeded = (event) => { + const db = event.target.result; + const logObjStore = db.createObjectStore("logs", { + keyPath: ["id", "index"] + }); + // Keys in the database look like: [ "instance-148938490", 0 ] + // Later on we need to query everything based on an instance id. + // In order to do this, we need to set up indexes "id". + logObjStore.createIndex("id", "id", { unique: false }); + + logObjStore.add( + this._generateLogEntry( + new Date() + " ::: Log database was created." + ) + ); + + const lastModifiedStore = db.createObjectStore("logslastmod", { + keyPath: "id", + }); + lastModifiedStore.add(this._generateLastModifiedTime()); + } + }); + } + + /** + * Flush logs to disk. + * + * There are guards to protect against race conditions in order to ensure + * that all previous flushes have completed before the most recent flush. + * Consider without guards: + * - A calls flush() periodically. + * - B calls flush() and wants to send logs immediately afterwards. + * - If B doesn't wait for A's flush to complete, B will be missing the + * contents of A's flush. + * To protect against this, we set 'flushPromise' when a flush is ongoing. + * Subsequent calls to flush() during this period will chain another flush, + * then keep returning that same chained flush. + * + * This guarantees that we will always eventually do a flush when flush() is + * called. + * + * @return {Promise} Resolved when the logs have been flushed. + */ + flush() { + // check if a flush() operation is ongoing + if (this.flushPromise && this.flushPromise.isPending()) { + if (this.flushAgainPromise && this.flushAgainPromise.isPending()) { + // this is the 3rd+ time we've called flush() : return the same + // promise. + return this.flushAgainPromise; + } + // queue up a flush to occur immediately after the pending one + // completes. + this.flushAgainPromise = this.flushPromise.then(() => { + return this.flush(); + }); + return this.flushAgainPromise; + } + // there is no flush promise or there was but it has finished, so do + // a brand new one, destroying the chain which may have been built up. + this.flushPromise = new Promise((resolve, reject) => { + if (!this.db) { + // not connected yet or user rejected access for us to r/w to + // the db. + reject(new Error("No connected database")); + return; + } + const lines = this.logger.flush(); + if (lines.length === 0) { + resolve(); + return; + } + let txn = this.db.transaction(["logs", "logslastmod"], "readwrite"); + let objStore = txn.objectStore("logs"); + txn.oncomplete = (event) => { + resolve(); + }; + txn.onerror = (event) => { + console.error( + "Failed to flush logs : ", event + ); + reject( + new Error("Failed to write logs: " + event.target.errorCode) + ); + } + objStore.add(this._generateLogEntry(lines)); + let lastModStore = txn.objectStore("logslastmod"); + lastModStore.put(this._generateLastModifiedTime()); + }); + return this.flushPromise; + } + + /** + * Consume the most recent logs and return them. Older logs which are not + * returned are deleted at the same time, so this can be called at startup + * to do house-keeping to keep the logs from growing too large. + * + * @return {Promise} Resolves to an array of objects. The array is + * sorted in time (oldest first) based on when the log file was created (the + * log ID). The objects have said log ID in an "id" field and "lines" which + * is a big string with all the new-line delimited logs. + */ + async consume() { + const db = this.db; + + // Returns: a string representing the concatenated logs for this ID. + function fetchLogs(id) { + const o = db.transaction("logs", "readonly").objectStore("logs"); + return selectQuery(o.index("id"), IDBKeyRange.only(id), + (cursor) => { + return { + lines: cursor.value.lines, + index: cursor.value.index, + } + }).then((linesArray) => { + // We have been storing logs periodically, so string them all + // together *in order of index* now + linesArray.sort((a, b) => { + return a.index - b.index; + }) + return linesArray.map((l) => l.lines).join(""); + }); + } + + // Returns: A sorted array of log IDs. (newest first) + function fetchLogIds() { + // To gather all the log IDs, query for all records in logslastmod. + const o = db.transaction("logslastmod", "readonly").objectStore( + "logslastmod" + ); + return selectQuery(o, undefined, (cursor) => { + return { + id: cursor.value.id, + ts: cursor.value.ts, + }; + }).then((res) => { + // Sort IDs by timestamp (newest first) + return res.sort((a, b) => { + return b.ts - a.ts; + }).map((a) => a.id); + }); + } + + function deleteLogs(id) { + return new Promise((resolve, reject) => { + const txn = db.transaction( + ["logs", "logslastmod"], "readwrite" + ); + const o = txn.objectStore("logs"); + // only load the key path, not the data which may be huge + const query = o.index("id").openKeyCursor(IDBKeyRange.only(id)); + query.onsuccess = (event) => { + const cursor = event.target.result; + if (!cursor) { + return; + } + o.delete(cursor.primaryKey); + cursor.continue(); + } + txn.oncomplete = () => { + resolve(); + }; + txn.onerror = (event) => { + reject( + new Error( + "Failed to delete logs for " + + `'${id}' : ${event.target.errorCode}` + ) + ); + }; + // delete last modified entries + const lastModStore = txn.objectStore("logslastmod"); + lastModStore.delete(id); + }); + } + + let allLogIds = await fetchLogIds(); + let removeLogIds = []; + let logs = []; + let size = 0; + for (let i = 0; i < allLogIds.length; i++) { + let lines = await fetchLogs(allLogIds[i]); + + // always include at least one log file, but only include + // subsequent ones if they won't take us over the MAX_LOG_SIZE + if (i > 0 && size + lines.length > MAX_LOG_SIZE) { + // the remaining log IDs should be removed. If we go out of + // bounds this is just [] + // + // XXX: there's nothing stopping the current session exceeding + // MAX_LOG_SIZE. We ought to think about culling it. + removeLogIds = allLogIds.slice(i + 1); + break; + } + + logs.push({ + lines: lines, + id: allLogIds[i], + }); + size += lines.length; + } + if (removeLogIds.length > 0) { + console.log("Removing logs: ", removeLogIds); + // Don't await this because it's non-fatal if we can't clean up + // logs. + Promise.all(removeLogIds.map((id) => deleteLogs(id))).then(() => { + console.log(`Removed ${removeLogIds.length} old logs.`); + }, (err) => { + console.error(err); + }) + } + return logs; + } + + _generateLogEntry(lines) { + return { + id: this.id, + lines: lines, + index: this.index++ + }; + } + + _generateLastModifiedTime() { + return { + id: this.id, + ts: Date.now(), + }; + } +} + +/** + * Helper method to collect results from a Cursor and promiseify it. + * @param {ObjectStore|Index} store The store to perform openCursor on. + * @param {IDBKeyRange=} keyRange Optional key range to apply on the cursor. + * @param {Function} resultMapper A function which is repeatedly called with a + * Cursor. + * Return the data you want to keep. + * @return {Promise} Resolves to an array of whatever you returned from + * resultMapper. + */ +function selectQuery(store, keyRange, resultMapper) { + const query = store.openCursor(keyRange); + return new Promise((resolve, reject) => { + let results = []; + query.onerror = (event) => { + reject(new Error("Query failed: " + event.target.errorCode)); + }; + // collect results + query.onsuccess = (event) => { + const cursor = event.target.result; + if (!cursor) { + resolve(results); + return; // end of results + } + results.push(resultMapper(cursor)); + cursor.continue(); + } + }); +} + + +let store = null; +let logger = null; +let initPromise = null; +module.exports = { + + /** + * Configure rage shaking support for sending bug reports. + * Modifies globals. + * @return {Promise} Resolves when set up. + */ + init: function() { + if (initPromise) { + return initPromise; + } + logger = new ConsoleLogger(); + logger.monkeyPatch(window.console); + + // just *accessing* indexedDB throws an exception in firefox with + // indexeddb disabled. + let indexedDB; + try { + indexedDB = window.indexedDB; + } catch(e) {} + + if (indexedDB) { + store = new IndexedDBLogStore(indexedDB, logger); + initPromise = store.connect(); + return initPromise; + } + initPromise = Promise.resolve(); + return initPromise; + }, + + flush: function() { + if (!store) { + return; + } + store.flush(); + }, + + /** + * Clean up old logs. + * @return Promise Resolves if cleaned logs. + */ + cleanup: async function() { + if (!store) { + return; + } + await store.consume(); + }, + + /** + * Get a recent snapshot of the logs, ready for attaching to a bug report + * + * @return {Array<{lines: string, id, string}>} list of log data + */ + getLogsForReport: async function() { + if (!logger) { + throw new Error( + "No console logger, did you forget to call init()?" + ); + } + // If in incognito mode, store is null, but we still want bug report + // sending to work going off the in-memory console logs. + if (store) { + // flush most recent logs + await store.flush(); + return await store.consume(); + } + else { + return [{ + lines: logger.flush(true), + id: "-", + }]; + } + }, +}; diff --git a/src/rageshake/submit-rageshake.js b/src/rageshake/submit-rageshake.js new file mode 100644 index 0000000000..086cf25d00 --- /dev/null +++ b/src/rageshake/submit-rageshake.js @@ -0,0 +1,126 @@ +/* +Copyright 2017 OpenMarket Ltd +Copyright 2018 New Vector Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +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 pako from 'pako'; +import Promise from 'bluebird'; + +import MatrixClientPeg from '../MatrixClientPeg'; +import PlatformPeg from '../PlatformPeg'; +import { _t } from '../languageHandler'; + +import rageshake from './rageshake' + + +// polyfill textencoder if necessary +import * as TextEncodingUtf8 from 'text-encoding-utf-8'; +let TextEncoder = window.TextEncoder; +if (!TextEncoder) { + TextEncoder = TextEncodingUtf8.TextEncoder; +} + +/** + * Send a bug report. + * + * @param {string} bugReportEndpoint HTTP url to send the report to + * + * @param {object} opts optional dictionary of options + * + * @param {string} opts.userText Any additional user input. + * + * @param {boolean} opts.sendLogs True to send logs + * + * @param {function(string)} opts.progressCallback Callback to call with progress updates + * + * @return {Promise} Resolved when the bug report is sent. + */ +export default async function sendBugReport(bugReportEndpoint, opts) { + if (!bugReportEndpoint) { + throw new Error("No bug report endpoint has been set."); + } + + opts = opts || {}; + const progressCallback = opts.progressCallback || (() => {}); + + progressCallback(_t("Collecting app version information")); + let version = "UNKNOWN"; + try { + version = await PlatformPeg.get().getAppVersion(); + } + catch (err) {} // PlatformPeg already logs this. + + let userAgent = "UNKNOWN"; + if (window.navigator && window.navigator.userAgent) { + userAgent = window.navigator.userAgent; + } + + const client = MatrixClientPeg.get(); + + console.log("Sending bug report."); + + const body = new FormData(); + body.append('text', opts.userText || "User did not supply any additional text."); + body.append('app', 'riot-web'); + body.append('version', version); + body.append('user_agent', userAgent); + + if (client) { + body.append('user_id', client.credentials.userId); + body.append('device_id', client.deviceId); + } + + if (opts.sendLogs) { + progressCallback(_t("Collecting logs")); + const logs = await rageshake.getLogsForReport(); + for (let entry of logs) { + // encode as UTF-8 + const buf = new TextEncoder().encode(entry.lines); + + // compress + const compressed = pako.gzip(buf); + + body.append('compressed-log', new Blob([compressed]), entry.id); + } + } + + progressCallback(_t("Uploading report")); + await _submitReport(bugReportEndpoint, body, progressCallback); +} + +function _submitReport(endpoint, body, progressCallback) { + const deferred = Promise.defer(); + + const req = new XMLHttpRequest(); + req.open("POST", endpoint); + req.timeout = 5 * 60 * 1000; + req.onreadystatechange = function() { + if (req.readyState === XMLHttpRequest.LOADING) { + progressCallback(_t("Waiting for response from server")); + } else if (req.readyState === XMLHttpRequest.DONE) { + on_done(); + } + }; + req.send(body); + return deferred.promise; + + function on_done() { + if (req.status < 200 || req.status >= 400) { + deferred.reject(new Error(`HTTP ${req.status}`)); + return; + } + deferred.resolve(); + } +} From 13765632e946fc7bf75ff5d53c51caab2ac7861c Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Fri, 13 Apr 2018 01:36:41 +0100 Subject: [PATCH 0777/1160] use new rageshake location --- src/components/views/dialogs/BugReportDialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/dialogs/BugReportDialog.js b/src/components/views/dialogs/BugReportDialog.js index 8a35c1748c..3c10919ecf 100644 --- a/src/components/views/dialogs/BugReportDialog.js +++ b/src/components/views/dialogs/BugReportDialog.js @@ -56,7 +56,7 @@ export default class BugReportDialog extends React.Component { this.setState({ busy: true, progress: null, err: null }); this._sendProgressCallback(_t("Preparing to send logs")); - require(['../../../vector/submit-rageshake'], (s) => { + require(['../../../rageshake/submit-rageshake'], (s) => { s(SdkConfig.get().bug_report_endpoint_url, { userText, sendLogs: true, From ce74099698dfe6ee5768ed5b852069367781a46a Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 13 Apr 2018 10:44:37 +0100 Subject: [PATCH 0778/1160] Null check node before we pass it to velocity As presumably sometimes the node wasn't actually in the DOM for whatever reason, so don't propagate exceptions out into the app. Should fix https://github.com/vector-im/riot-web/issues/6515 --- src/Velociraptor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Velociraptor.js b/src/Velociraptor.js index af4e6dcb60..6a4666305c 100644 --- a/src/Velociraptor.js +++ b/src/Velociraptor.js @@ -147,7 +147,7 @@ module.exports = React.createClass({ // creating/destroying large numbers of elements" // (https://github.com/julianshapiro/velocity/issues/47) const domNode = ReactDom.findDOMNode(this.nodes[k]); - Velocity.Utilities.removeData(domNode); + if (domNode) Velocity.Utilities.removeData(domNode); } this.nodes[k] = node; }, From acf8ea1a659baff7a20950287ed16008dab8a0ff Mon Sep 17 00:00:00 2001 From: RainSlide Date: Fri, 13 Apr 2018 08:28:54 +0000 Subject: [PATCH 0779/1160] Translated using Weblate (Chinese (Simplified)) Currently translated at 81.0% (819 of 1011 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hans/ --- src/i18n/strings/zh_Hans.json | 42 ++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index 76394d5eb1..c03b463b02 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -15,7 +15,7 @@ "Devices will not yet be able to decrypt history from before they joined the room": "新加入聊天室的设备不能解密加入之前的聊天记录", "Direct chats": "私聊", "Disinvite": "取消邀请", - "Display name": "显示名称", + "Display name": "昵称", "Displays action": "显示操作", "Don't send typing notifications": "不要发送我的打字状态", "Download %(text)s": "下载 %(text)s", @@ -405,7 +405,7 @@ "Level:": "级别:", "Local addresses for this room:": "这个聊天室的本地地址:", "New passwords must match each other.": "新密码必须互相匹配。", - "Power level must be positive integer.": "特权级别必须是正整数。", + "Power level must be positive integer.": "权限级别必须是正整数。", "Reason: %(reasonText)s": "原因: %(reasonText)s", "Revoke Moderator": "撤销主持人", "Revoke widget access": "撤销小部件的访问", @@ -426,8 +426,8 @@ "This room": "这个聊天室", "This room is not accessible by remote Matrix servers": "这个聊天室无法被远程 Matrix 服务器访问", "This room's internal ID is": "这个聊天室的内部 ID 是", - "Turn Markdown off": "关闭 Markdown", - "Turn Markdown on": "打开 Markdown", + "Turn Markdown off": "禁用 Markdown", + "Turn Markdown on": "启用 Markdown", "Unable to create widget.": "无法创建小部件。", "Unban": "解除封禁", "Unable to capture screen": "无法录制屏幕", @@ -468,7 +468,7 @@ "%(senderName)s requested a VoIP conference.": "%(senderName)s 请求一个 VoIP 会议。", "Seen by %(userName)s at %(dateTime)s": "在 %(dateTime)s 被 %(userName)s 看到", "Show Apps": "显示应用", - "Tagged as: ": "标记为:", + "Tagged as: ": "标记为: ", "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "验证码将发送到+%(msisdn)s,请输入接收到的验证码", "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s 接受了 %(displayName)s 的邀请。", "Active call (%(roomName)s)": "%(roomName)s 的呼叫", @@ -490,12 +490,12 @@ "Refer a friend to Riot:": "介绍朋友加入Riot:", "%(roomName)s is not accessible at this time.": "%(roomName)s 此时无法访问。", "Start authentication": "开始认证", - "The maximum permitted number of widgets have already been added to this room.": "小部件的最大允许数量已经添加到这个房间了。", + "The maximum permitted number of widgets have already been added to this room.": "小部件的最大允许数量已经添加到这个聊天室了。", "The phone number entered looks invalid": "输入的电话号码看起来无效", "The remote side failed to pick up": "远端未能接收到", "This Home Server does not support login using email address.": "HS不支持使用电子邮件地址登陆。", "This invitation was sent to an email address which is not associated with this account:": "此邀请被发送到与此帐户不相关的电子邮件地址:", - "This room is not recognised.": "这个房间未匹配。", + "This room is not recognised.": "无法识别此聊天室。", "To get started, please pick a username!": "请点击用户名!", "Unable to add email address": "无法添加电子邮件地址", "Automatically replace plain text Emoji": "文字、表情自动转换", @@ -536,7 +536,7 @@ "Error decrypting audio": "解密音频时出错", "Error decrypting image": "解密图像时出错", "Error decrypting video": "解密视频时出错", - " (unsupported)": "(不支持)", + " (unsupported)": " (不支持)", "Updates": "更新", "Check for update": "检查更新", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s 移除了聊天室头像。", @@ -604,7 +604,7 @@ "Unknown devices": "未知设备", "Unknown Address": "未知地址", "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s 删除了他们的昵称 (%(oldDisplayName)s).", - "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "你提供的签名密钥和你从 %(userId)s 的设备 (deviceId)s 收到的签名密钥匹配。设备被标记为已验证。", + "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "你提供的签名密钥和你从 %(userId)s 的设备 %(deviceId)s 收到的签名密钥匹配。设备被标记为已验证。", "These are experimental features that may break in unexpected ways": "这些是可能以意外的方式坏掉的实验性的特性", "The visibility of existing history will be unchanged": "现有历史记录的可见性不会被改变", "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s 打开了端到端加密 (算法 %(algorithm)s).", @@ -662,7 +662,7 @@ "Disable Emoji suggestions while typing": "禁用打字时Emoji建议", "Use compact timeline layout": "使用紧凑的时间线布局", "Hide avatar changes": "隐藏头像修改", - "Hide display name changes": "隐藏显示名称的修改", + "Hide display name changes": "隐藏昵称的修改", "Disable big emoji in chat": "禁用聊天中的大Emoji", "Never send encrypted messages to unverified devices in this room from this device": "在这个聊天室永不从这个设备发送加密消息到未验证的设备", "Enable URL previews for this room (only affects you)": "在这个聊天室启用 URL 预览(只影响你)", @@ -764,10 +764,10 @@ "Kick this user?": "踢出这个用户?", "Unban this user?": "解除这个用户的封禁?", "Ban this user?": "封紧这个用户?", - "Send an encrypted reply…": "发送一条加密的回复...", - "Send a reply (unencrypted)…": "发送一条回复(未加密)...", - "Send an encrypted message…": "发送一条加密消息…", - "Send a message (unencrypted)…": "发送一条消息 (未加密)…", + "Send an encrypted reply…": "发送加密的回复…", + "Send a reply (unencrypted)…": "发送回复(未加密)…", + "Send an encrypted message…": "发送加密消息…", + "Send a message (unencrypted)…": "发送消息 (未加密)…", "Replying": "正在回复", "Community Invites": "社区邀请", "You are trying to access a room.": "你正在尝试访问一个聊天室。", @@ -809,5 +809,17 @@ "Failed to invite the following users to %(groupId)s:": "邀请下列用户到 %(groupId)s 失败:", "Failed to add the following rooms to %(groupId)s:": "添加以下聊天室到 %(groupId)s 失败:", "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "你似乎没有将此邮箱地址同在此主服务器上的任何一个 Matrix 账号相关联。", - "Restricted": "受限用户" + "Restricted": "受限用户", + "To use it, just wait for autocomplete results to load and tab through them.": "若要使用自动补全,只要等待自动补全结果加载完成,按 Tab 键切换即可。", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s 将他们的昵称修改成了 %(displayName)s 。", + "Hide avatars in user and room mentions": "隐藏头像", + "Disable Community Filter Panel": "停用社区面板", + "Opt out of analytics": "禁用开发数据上传", + "Stickerpack": "贴图集", + "Sticker Messages": "贴图消息", + "You don't currently have any stickerpacks enabled": "您目前没有启用任何贴图集", + "Click": "点击", + "here": "这里", + "to add some!": "以添加一些贴图集!", + "Add a stickerpack": "添加贴图集" } From a90bd6cd4f077b78912d180936bc5871464130b1 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 13 Apr 2018 12:28:58 +0100 Subject: [PATCH 0780/1160] Allow collapsing ReplyThread from MessageContextMenu Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 14 ++++++++++++-- src/components/views/rooms/EventTile.js | 12 ++++++++---- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index de6ff46610..6796e2bcc7 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -52,6 +52,8 @@ export default class ReplyThread extends React.Component { }; this.onQuoteClick = this.onQuoteClick.bind(this); + this.canCollapse = this.canCollapse.bind(this); + this.collapse = this.collapse.bind(this); } componentWillMount() { @@ -64,6 +66,14 @@ export default class ReplyThread extends React.Component { this.unmounted = true; } + canCollapse() { + return this.state.events.length > 1; + } + + collapse() { + this.initialize(); + } + async initialize() { const {parentEv} = this.props; const inReplyTo = ReplyThread.getInReplyTo(parentEv); @@ -227,11 +237,11 @@ export default class ReplyThread extends React.Component { }; } - static getQuote(parentEv, onWidgetLoad) { + static getThread(parentEv, onWidgetLoad, ref) { if (!SettingsStore.isFeatureEnabled("feature_rich_quoting") || !ReplyThread.getInReplyTo(parentEv)) { return
    ; } - return ; + return ; } render() { diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index c754f7ceeb..50c0e29ed4 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -18,7 +18,7 @@ limitations under the License. 'use strict'; -import Reply from "../elements/ReplyThread"; +import ReplyThread from "../elements/ReplyThread"; const React = require('react'); import PropTypes from 'prop-types'; @@ -302,12 +302,16 @@ module.exports = withMatrixClient(React.createClass({ const x = buttonRect.right + window.pageXOffset; const y = (buttonRect.top + (buttonRect.height / 2) + window.pageYOffset) - 19; const self = this; + + const {tile, replyThread} = this.refs; + ContextualMenu.createMenu(MessageContextMenu, { chevronOffset: 10, mxEvent: this.props.mxEvent, left: x, top: y, - eventTileOps: this.refs.tile && this.refs.tile.getEventTileOps ? this.refs.tile.getEventTileOps() : undefined, + eventTileOps: tile && tile.getEventTileOps ? tile.getEventTileOps() : undefined, + collapseReplyThread: replyThread && replyThread.canCollapse() ? replyThread.collapse : undefined, onFinished: function() { self.setState({menu: false}); }, @@ -662,7 +666,7 @@ module.exports = withMatrixClient(React.createClass({ { this._renderE2EPadlock() } { this.props.tileShape === 'reply_preview' - && Reply.getQuote(this.props.mxEvent, this.props.onWidgetLoad) + && ReplyThread.getThread(this.props.mxEvent, this.props.onWidgetLoad, 'replyThread') } { this._renderE2EPadlock() } - { Reply.getQuote(this.props.mxEvent, this.props.onWidgetLoad) } + { ReplyThread.getThread(this.props.mxEvent, this.props.onWidgetLoad, 'replyThread') } Date: Fri, 13 Apr 2018 16:49:59 +0100 Subject: [PATCH 0781/1160] fix paths and updateCheckStatusEnum --- src/components/views/globals/UpdateCheckBar.js | 2 +- src/components/views/login/CountryDropdown.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/globals/UpdateCheckBar.js b/src/components/views/globals/UpdateCheckBar.js index 4397b3313e..db01746340 100644 --- a/src/components/views/globals/UpdateCheckBar.js +++ b/src/components/views/globals/UpdateCheckBar.js @@ -23,7 +23,7 @@ import AccessibleButton from '../../../components/views/elements/AccessibleButto export default React.createClass({ propTypes: { - status: React.PropTypes.oneOf(Object.values(updateCheckStatusEnum)).isRequired, + status: React.PropTypes.string, // oneOf(Object.values(updateCheckStatusEnum)).isRequired, // Currently for error detail but will be usable for download progress // once that is a thing that squirrel passes through electron. detail: React.PropTypes.string, diff --git a/src/components/views/login/CountryDropdown.js b/src/components/views/login/CountryDropdown.js index 3fd28e32d2..8c4467bb99 100644 --- a/src/components/views/login/CountryDropdown.js +++ b/src/components/views/login/CountryDropdown.js @@ -70,7 +70,7 @@ export default class CountryDropdown extends React.Component { } _flagImgForIso2(iso2) { - return ; + return ; } _getShortOption(iso2) { From 33632aaae61d43a91c5848ffd9c3fcda701addf8 Mon Sep 17 00:00:00 2001 From: Xose M Date: Sun, 15 Apr 2018 19:13:06 +0000 Subject: [PATCH 0782/1160] Translated using Weblate (Galician) Currently translated at 100.0% (1011 of 1011 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/gl/ --- src/i18n/strings/gl.json | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/gl.json b/src/i18n/strings/gl.json index bc86593fc4..8151f253b6 100644 --- a/src/i18n/strings/gl.json +++ b/src/i18n/strings/gl.json @@ -1003,5 +1003,17 @@ "Debug Logs Submission": "Envío de rexistro de depuración", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Si enviou un reporte de fallo a través de GitHub, os informes poden axudarnos a examinar o problema. Os informes de fallo conteñen datos do uso do aplicativo incluíndo o seu nome de usuaria, os IDs ou alcumes das salas e grupos que visitou e os nomes de usuaria de outras personas. Non conteñen mensaxes.", "Submit debug logs": "Enviar informes de depuración", - "Opens the Developer Tools dialog": "Abre o cadro de Ferramentas de Desenvolvedoras" + "Opens the Developer Tools dialog": "Abre o cadro de Ferramentas de Desenvolvedoras", + "Stickerpack": "Peganitas", + "Sticker Messages": "Mensaxes pegadas", + "You don't currently have any stickerpacks enabled": "Non ten paquetes de pegatinas habilitados", + "Click": "Clicar", + "here": "aquí", + "to add some!": "engada algún!", + "Add a stickerpack": "Engadir un paquete de pegatinas", + "Hide Stickers": "Agochar pegatinas", + "Show Stickers": "Mostrar pegatinas", + "Manage sticker packs": "Xestionar os paquetes de pegatinas", + "Who can join this community?": "Quén pode unirse a esta comunidade?", + "Everyone": "Todo o mundo" } From a30fdaf293979d04220e308556a658a881dc8314 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 15 Apr 2018 23:00:38 +0100 Subject: [PATCH 0783/1160] copy all the i18n over from vector-web via copy-i18n.py --- src/i18n/strings/ar.json | 51 +++++++- src/i18n/strings/be.json | 76 +++++++++++- src/i18n/strings/bg.json | 200 +++++++++++++++++++++++++++++- src/i18n/strings/ca.json | 204 ++++++++++++++++++++++++++++++- src/i18n/strings/cs.json | 200 +++++++++++++++++++++++++++++- src/i18n/strings/da.json | 194 ++++++++++++++++++++++++++++- src/i18n/strings/de_DE.json | 204 ++++++++++++++++++++++++++++++- src/i18n/strings/el.json | 177 ++++++++++++++++++++++++++- src/i18n/strings/en_EN.json | 192 ++++++++++++++++++++++++++++- src/i18n/strings/en_US.json | 180 ++++++++++++++++++++++++++- src/i18n/strings/eo.json | 198 +++++++++++++++++++++++++++++- src/i18n/strings/es.json | 212 +++++++++++++++++++++++++++++++- src/i18n/strings/eu.json | 203 ++++++++++++++++++++++++++++++- src/i18n/strings/fa.json | 191 ++++++++++++++++++++++++++++- src/i18n/strings/fi.json | 200 +++++++++++++++++++++++++++++- src/i18n/strings/fr.json | 197 +++++++++++++++++++++++++++++- src/i18n/strings/gl.json | 204 ++++++++++++++++++++++++++++++- src/i18n/strings/he.json | 205 ++++++++++++++++++++++++++++++- src/i18n/strings/hu.json | 204 ++++++++++++++++++++++++++++++- src/i18n/strings/id.json | 192 ++++++++++++++++++++++++++++- src/i18n/strings/it.json | 204 ++++++++++++++++++++++++++++++- src/i18n/strings/ja.json | 68 ++++++++++- src/i18n/strings/ko.json | 185 +++++++++++++++++++++++++++- src/i18n/strings/lt.json | 223 +++++++++++++++++++++++++++++++++- src/i18n/strings/lv.json | 203 ++++++++++++++++++++++++++++++- src/i18n/strings/ml.json | 179 ++++++++++++++++++++++++++- src/i18n/strings/nb_NO.json | 111 ++++++++++++++++- src/i18n/strings/nl.json | 196 +++++++++++++++++++++++++++++- src/i18n/strings/pl.json | 214 +++++++++++++++++++++++++++++++- src/i18n/strings/pt.json | 191 ++++++++++++++++++++++++++++- src/i18n/strings/pt_BR.json | 197 +++++++++++++++++++++++++++++- src/i18n/strings/ru.json | 204 ++++++++++++++++++++++++++++++- src/i18n/strings/sk.json | 202 +++++++++++++++++++++++++++++- src/i18n/strings/sq.json | 221 ++++++++++++++++++++++++++++++++- src/i18n/strings/sr.json | 193 ++++++++++++++++++++++++++++- src/i18n/strings/sv.json | 186 +++++++++++++++++++++++++++- src/i18n/strings/te.json | 107 +++++++++++++++- src/i18n/strings/th.json | 177 ++++++++++++++++++++++++++- src/i18n/strings/tr.json | 170 +++++++++++++++++++++++++- src/i18n/strings/uk.json | 208 ++++++++++++++++++++++++++++++- src/i18n/strings/zh_Hans.json | 204 ++++++++++++++++++++++++++++++- src/i18n/strings/zh_Hant.json | 204 ++++++++++++++++++++++++++++++- 42 files changed, 7689 insertions(+), 42 deletions(-) diff --git a/src/i18n/strings/ar.json b/src/i18n/strings/ar.json index f7f674cf9a..f26a9850b4 100644 --- a/src/i18n/strings/ar.json +++ b/src/i18n/strings/ar.json @@ -23,5 +23,54 @@ "Your homeserver's URL": "عنوان خادوم المنزل", "Your identity server's URL": "عنوان خادوم التعريف", "Analytics": "التحاليل", - "The information being sent to us to help make Riot.im better includes:": "تحتوي المعلومات التي تُرسل إلينا للمساعدة بتحسين جودة Riot.im الآتي:" + "The information being sent to us to help make Riot.im better includes:": "تحتوي المعلومات التي تُرسل إلينا للمساعدة بتحسين جودة Riot.im الآتي:", + "Couldn't find a matching Matrix room": "لا يمكن إيجاد غرفة مايتركس متطابقة", + "Unavailable": "غير متوفر", + "A new version of Riot is available.": "هناك نسخة جديدة مِن رايوت متوفرة.", + "Safari and Opera work too.": "متصفح سافاري و متصفح أوبرا يعملان أيضاً.", + "All Rooms": "كل الغُرف", + "All messages": "كل الرسائل", + "All notifications are currently disabled for all targets.": "كل التنبيهات غير مفعلة حالياً للجميع.", + "Direct Chat": "دردشة مباشرة", + "Please set a password!": "يرجى تعيين كلمة مرور !", + "You have successfully set a password!": "تم تعيين كلمة السر بنجاح !", + "Riot is not supported on mobile web. Install the app?": "رايوت غير مدعوم في وضعية الويب على الهاتف. هل تريد تثبيت التطبيق ؟", + "Report a bug": "الإبلاغ عن عِلّة", + "Can't update user notification settings": "لا يمكن تحديث إعدادات الإشعارات الخاصة بالمستخدم", + "Explore Room State": "إكتشاف حالة الغرفة", + "All messages (noisy)": "كل الرسائل (صوت مرتفع)", + "Update": "تحديث", + "What's New": "آخِر المُستجدّات", + "Describe your problem here.": "صِف مشكلتك هنا.", + "Toolbox": "علبة الأدوات", + "Add an email address above to configure email notifications": "أضف بريداً إلكترونياً أعلاه من أجل ضبط الإشعارات عبر البريد الإلكتروني", + "Collecting logs": "تجميع السجلات", + "No update available.": "لا يوجد هناك أي تحديث.", + "An error occurred whilst saving your email notification preferences.": "حدث خطأ ما أثناء عملية حفظ إعدادات الإشعارات عبر البريد الإلكتروني.", + "Bug report sent": "تم إرسال تقرير الأخطاء", + "Collecting app version information": "تجميع المعلومات حول نسخة التطبيق", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "إلغاء مُعرف الغرفة %(alias)s وحذف %(name)s من الدليل؟", + "Changelog": "سِجل التغييرات", + "Send Account Data": "إرسال بيانات الحساب", + "Waiting for response from server": "في انتظار الرد مِن الخادوم", + "This will allow you to return to your account after signing out, and sign in on other devices.": "سيسمح لك هذا بالعودة إلى حسابك بعد الخروج، وتسجيل الدخول على الأجهزة الأخرى.", + "Directory": "الدليل", + "Send logs": "إرسال السِجلات", + "Download this file": "تنزيل هذا الملف", + "Unknown device": "جهاز مجهول", + "Thank you!": "شكرًا !", + "Advanced notification settings": "الإعدادات المتقدمة للإشعارات", + "Call invitation": "دعوة لمحادثة", + "delete the alias.": "إلغاء المُعرف.", + "Riot Desktop on %(platformName)s": "الواجهة المكتبية لرايوت على %(platformName)s", + "Developer Tools": "أدوات التطوير", + "Downloading update...": "عملية تنزيل التحديث جارية …", + "State Key": "مفتاح الحالة", + "Back": "العودة", + "What's new?": "ما الجديد ؟", + "You have successfully set a password and an email address!": "لقد قمت بتعيين كلمة سرية و إدخال عنوان للبريد الإلكتروني بنجاح !", + "Cancel Sending": "إلغاء الإرسال", + "Collapse panel": "طي الجدول", + "Set Password": "تعيين كلمة سرية", + "Checking for an update...": "البحث عن تحديث …" } diff --git a/src/i18n/strings/be.json b/src/i18n/strings/be.json index 0967ef424b..7e79f5d355 100644 --- a/src/i18n/strings/be.json +++ b/src/i18n/strings/be.json @@ -1 +1,75 @@ -{} +{ + "Couldn't find a matching Matrix room": "Не атрымалася знайсці адпаведны пакой Matrix", + "Enable audible notifications in web client": "Ўключыць гукавыя апавяшчэнні ў вэб-кліенце", + "All messages (noisy)": "Усе паведамленні (гучна)", + "Reject": "Адхіліць", + "Failed to forget room %(errCode)s": "Не атрымалася забыць пакой %(errCode)s", + "Failed to update keywords": "Не атрымалася абнавіць ключавыя словы", + "All messages": "Усе паведамленні", + "All notifications are currently disabled for all targets.": "Усе апавяшчэнні ў цяперашні час адключаныя для ўсіх мэтаў.", + "Fetching third party location failed": "Не ўдалося атрымаць месцазнаходжанне трэцяга боку", + "Guests can join": "Госці могуць далучыцца", + "Enable them now": "Уключыць іх зараз", + "Notification targets": "Мэты апавяшчэння", + "Failed to set direct chat tag": "Не ўдалося ўсталяваць тэг прамога чата", + "Failed to get protocol list from Home Server": "Не ўдалося атрымаць спіс пратаколаў ад хатняга сервера", + "Failed to set Direct Message status of room": "Не ўдалося ўсталяваць статут прамога паведамлення пакою", + "Favourite": "Улюбёнае", + "Quote": "Цытата", + "Dismiss": "Aдхіліць", + "Remove from Directory": "Выдалiць з каталога", + "Cancel Sending": "Адмяніць адпраўку", + "Failed to add tag %(tagName)s to room": "Не атрымалася дадаць %(tagName)s ў пакоі", + "Close": "Зачыніць", + "Notifications": "Апавяшчэнні", + "Low Priority": "Нізкі прыярытэт", + "Riot does not know how to join a room on this network": "Riot не ведае, як увайсці ў пакой у гэтай сетке", + "Members": "Удзельнікі", + "Can't update user notification settings": "Немагчыма абнавіць налады апавяшчэнняў карыстальніка", + "Add an email address above to configure email notifications": "Дадайце адрас электроннай пошты вышэй, каб наладзіць апавяшчэнні", + "Failed to change settings": "Не атрымалася змяніць налады", + "Noisy": "Шумна", + "Resend": "Паўторна", + "On": "Уключыць", + "Permalink": "Пастаянная спасылка", + "remove %(name)s from the directory.": "выдаліць %(name)s з каталога.", + "Off": "Выключыць", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Выдаліць псеўданім пакоя %(alias)s і выдаліць %(name)s з каталога?", + "Filter room names": "Фільтр iмёнаў пакояў", + "Invite to this room": "Запрасіць у гэты пакой", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Апавяшчэнні па наступных ключавых словах прытрымліваюцца правілаў, якія не могуць быць адлюстраваны тут:", + "#example": "#прыклад", + "Mentions only": "Толькі згадкі", + "Failed to get public room list": "Не ўдалося атрымаць спіс агульных пакояў", + "Remove": "Выдалiць", + "Failed to remove tag %(tagName)s from room": "Не ўдалося выдаліць %(tagName)s з пакоя", + "Leave": "Пакінуць", + "Enable notifications for this account": "Ўключыць апавяшчэнні для гэтага ўліковага запісу", + "Enable desktop notifications": "Ўключыць апавяшчэнні на працоўным стале", + "Error": "Памылка", + "Directory": "Каталог", + "No rooms to show": "Няма пакояў для паказу", + "Download this file": "Спампаваць гэты файл", + "Search for a room": "Пошук па пакоі", + "Operation failed": "Не атрымалася выканаць аперацыю", + "delete the alias.": "выдаліць псеўданім.", + "Forget": "Забыць", + "Mute": "Без гуку", + "Error saving email notification preferences": "Памылка захавання налад апавяшчэнняў па электроннай пошце", + "Enter keywords separated by a comma:": "Калі ласка, увядзіце ключавыя словы, падзеленыя коскамі:", + "The Home Server may be too old to support third party networks": "Хатні сервер можа быць занадта стары для падтрымкі іншых сетак", + "powered by Matrix": "працуе на Matrix", + "Custom Server Options": "Карыстальніцкія параметры сервера", + "Remove %(name)s from the directory?": "Выдаліць %(name)s з каталога?", + "Notify me for anything else": "Паведаміць мне што-небудзь яшчэ", + "Source URL": "URL-адрас крыніцы", + "Enable email notifications": "Ўключыць паведамлення па электроннай пошце", + "Files": "Файлы", + "Keywords": "Ключавыя словы", + "Direct Chat": "Прамы чат", + "An error occurred whilst saving your email notification preferences.": "Адбылася памылка падчас захавання налады апавяшчэнняў па электроннай пошце.", + "Room not found": "Пакой не знойдзены", + "Notify for all other messages/rooms": "Апавяшчаць для ўсіх іншых паведамленняў/пакояў", + "There are advanced notifications which are not shown here": "Ёсць пашыраныя апавяшчэння, якія не паказаныя тут", + "The server may be unavailable or overloaded": "Сервер можа быць недаступны ці перагружаны" +} diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 8111329bef..4ebe205eb8 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -1006,5 +1006,203 @@ "Unable to leave community": "Неуспешно напускане на общността", "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Промени направени по името и аватара на вашата общност може да не се отразят при другите потребители за до 30 минути.", "Join this community": "Присъединете се в тази общност", - "Leave this community": "Напуснете тази общност" + "Leave this community": "Напуснете тази общност", + "Fetching third party location failed": "Неуспешно извличане на адреса на стаята от друга мрежа", + "A new version of Riot is available.": "Налична е нова версия на Riot.", + "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk чат", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Моля, опишете грешката. Какво направихте? Какво очаквахте да стане? Какво стана всъщност?", + "Couldn't load home page": "Неуспешно зареждане на началната страница", + "Send Account Data": "Изпращане на Account Data", + "All notifications are currently disabled for all targets.": "В момента известията са изключени за всички цели.", + "Uploading report": "Качване на доклада", + "Sunday": "Неделя", + "Notification targets": "Устройства, получаващи известия", + "Today": "Днес", + "Files": "Файлове", + "Report a bug": "Докладвай за грешка", + "Implementing VR services with Matrix": "Внедряване на VR услуги с Matrix", + "You are not receiving desktop notifications": "Не получавате известия на работния плот", + "Friday": "Петък", + "Update": "Актуализиране", + "You need to be using HTTPS to place a screen-sharing call.": "Трябва да използвате HTTPS, за да споделите екрана си.", + "Unable to fetch notification target list": "Неуспешно извличане на списък с устройства получаващи известия", + "Add an email address above to configure email notifications": "За конфигурация на имейл известия добавете имейл адрес по-горе.", + "Expand panel": "Разшири панела", + "On": "Включено", + "%(count)s Members|other": "%(count)s Членове", + "Filter room names": "Филтрирай стаи по име", + "Changelog": "Списък на промените", + "Running Matrix services": "Хостинг на Matrix услуги", + "Waiting for response from server": "Изчакване на отговор от сървъра", + "Uploaded on %(date)s by %(user)s": "Качено на %(date)s от %(user)s", + "Send Custom Event": "Изпрати потребителско събитие", + "Failed to send report: ": "Неуспешно изпращане на доклада: ", + "Unknown device": "Непознато устройство", + "Advanced notification settings": "Разширени настройки за известяване", + "Failed to send logs: ": "Неуспешно изпращане на логове: ", + "delete the alias.": "изтрий псевдонима.", + "To return to your account in future you need to set a password": "За да се върнете в профила си в бъдеще, трябва да зададете парола", + "Forget": "Забрави", + "Riot/Web & Desktop chat": "Riot/Web & Desktop чат", + "Hide panel": "Скриване на панела", + "You cannot delete this image. (%(code)s)": "Не можете да изтриете тази снимка. (%(code)s)", + "Cancel Sending": "Откажи изпращането", + "This Room": "В тази стая", + "Get started with some tips from Riot Bot!": "Започнете с някои съвети от Riot Bot!", + "The Home Server may be too old to support third party networks": "Home сървърът може да е твърде стар, за да поддържа работа с други мрежи", + "Resend": "Изпрати отново", + "Room not found": "Стаята не е намерена", + "Downloading update...": "Сваляне на нова версия...", + "Messages in one-to-one chats": "Съобщения в индивидуални чатове", + "Contributing code to Matrix and Riot": "Допринасяне с код към Matrix и Riot", + "Unavailable": "Не е наличен", + "Community-run support for Synapse": "Поддръжка за Synapse от общността", + "View Decrypted Source": "Прегледай разшифрования източник", + "Failed to update keywords": "Грешка при обновяване на ключови думи", + "Notes:": "Бележки:", + "remove %(name)s from the directory.": "премахване %(name)s от директорията.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Известия за следните ключови думи изпълняват правила, които не могат да бъдат показани тук:", + "Safari and Opera work too.": "Safari и Opera са други алтернативи.", + "Please set a password!": "Моля, въведете парола!", + "You have successfully set a password!": "Вие успешно зададохте парола!", + "Chat with Riot Bot": "Чат с Riot Bot", + "Support for those using, running and writing other bridges": "Поддръжка за тези, които използват, работят и пишат Matrix мостове", + "Admin support for Dendrite": "Административна поддръжка за Dendrite", + "Explore Room State": "Преглед на състоянието на стаята", + "Source URL": "URL на източника", + "Messages sent by bot": "Съобщения изпратени от бот", + "Filter results": "Филтриране на резултати", + "Members": "Членове", + "No update available.": "Няма нова версия.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "В Matrix съществуват много стаи, свързани към вече съществуващи мрежи (Slack, IRC, Gitter и т.н.) или независими такива. Разгледайте директорията!", + "Noisy": "Шумно", + "Failed to get protocol list from Home Server": "Неуспешно получаване на списък с протоколи от Home сървър", + "Collecting app version information": "Събиране на информация за версията на приложението", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Изтриване на псевдонима %(alias)s на стаята и премахване на %(name)s от директорията?", + "Co-ordination for Riot/Web translators": "Координация за преводачи на Riot/Web", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Това ще Ви позволи да се върнете в профила си след излизане от него, и да влезете от други устройства.", + "Dev chat for the Dendrite dev team": "Чат за разработващия екип на Dendrite", + "Design and implementation of E2E in Matrix": "Разработване и внедряване на E2E шифроване в Matrix", + "Enable notifications for this account": "Включване на известия за този профил", + "Directory": "Директория", + "Invite to this community": "Покани в тази общност", + "Search for a room": "Търсене на стая", + "Search…": "Търсене…", + "Messages containing keywords": "Съобщения, съдържащи ключови думи", + "Error saving email notification preferences": "Грешка при запазване на настройките за имейл известяване", + "Tuesday": "Вторник", + "Enter keywords separated by a comma:": "Ключови думи разделени чрез запетая:", + "Forward Message": "Препрати съобщението", + "You have successfully set a password and an email address!": "Вие успешно зададохте парола и имейл адрес!", + "Remove %(name)s from the directory?": "Премахване на %(name)s от директорията?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot използва много разширени браузър харектеристики, някои от които не са налични или са все още експериментални в настоящия Ви браузър.", + "Developer Tools": "Инструменти за разработчика", + "Preparing to send logs": "Подготовка за изпращане на логове", + "Explore Account Data": "Преглед на данните от профила", + "All messages (noisy)": "Всички съобщения (шумно)", + "Away": "Отсъстващ", + "Saturday": "Събота", + "Remember, you can always set an email address in user settings if you change your mind.": "Ако си промените мнението, винаги може да зададете имейл адрес в настройки на потребителя.", + "Direct Chat": "Директен чат", + "The server may be unavailable or overloaded": "Сървърът не е наличен или е претоварен", + "Reject": "Отхвърли", + "Riot is not supported on mobile web. Install the app?": "Riot не поддържа мобилен уеб браузър. Инсталиране на приложението?", + "Discussion of all things Matrix!": "Дискусия за всичко свързано с Matrix!", + "Failed to set Direct Message status of room": "Неуспешно настройване на стаята като Директен чат", + "Monday": "Понеделник", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "За да се диагностицират проблемите, логовете от този клиент ще бъдат изпратени с този доклад за грешки. Ако предпочитате да изпратите само текста по-горе, моля, премахнете отметката:", + "Remove from Directory": "Премахни от директорията", + "Enable them now": "Включете ги сега", + "Messages containing my user name": "Съобщения, съдържащи моето потребителско име", + "Describe your problem here.": "Опишете своя проблем тук.", + "Toolbox": "Инструменти", + "Collecting logs": "Събиране на логове", + "more": "още", + "GitHub issue link:": "Линк към GitHub issue:", + "Failed to get public room list": "Неуспешно получаване на списък с публични стаи", + "You must specify an event type!": "Трябва да укажате тип на събитието", + "(HTTP status %(httpStatus)s)": "(HTTP статус %(httpStatus)s)", + "All Rooms": "Във всички стаи", + "Please install Chrome or Firefox for the best experience.": "Моля, инсталирайте Chrome или Firefox за най-добро преживяване.", + "Wednesday": "Сряда", + "Quote": "Цитирай", + "Send logs": "Изпращане на логове", + "All messages": "Всички съобщения", + "Implementing VoIP services with Matrix": "Внедряване на VoIP услуги с Matrix", + "Dev chat for the Riot/Web dev team": "Чат за разработващия екип на Riot/Web", + "Call invitation": "Покана за разговор", + "Riot Desktop on %(platformName)s": "Riot Desktop под %(platformName)s", + "Messages containing my display name": "Съобщения, съдържащи моя псевдоним", + "State Key": "State ключ", + "Failed to send custom event.": "Неуспешно изпращане на потребителско събитие.", + "What's new?": "Какво ново?", + "Discussion of the Identity Service API": "Дискусия върху API услугата за самоличност", + "Support for those using and running matrix-appservice-irc": "Поддръжка за използващите и работещите с matrix-appservice-irc", + "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk чат", + "Notify me for anything else": "Извести ме за всичко останало", + "When I'm invited to a room": "Когато ме поканят в стая", + "Keywords": "Ключови думи", + "Click here to create a GitHub issue.": "Натиснете тук, за да създадете GitHub issue.", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Може да използвате опциите за друг сървър, за да влезете в други Matrix сървъри като посочите различен Home сървър.
    Това Ви позволява да използвате Riot със съществуващ Matrix профил на различен Home сървър.

    Възможно е и да зададете друг сървър за самоличност. В този случай обаче няма да бъде възможно да поканите други потребители по имейл адрес, както и самите Вие няма да можете да бъдете поканени по имейл адрес.", + "Can't update user notification settings": "Неуспешно обновяване на потребителски настройки за известяване", + "Notify for all other messages/rooms": "Извести ме за всички други съобщения/стаи", + "Unable to look up room ID from server": "Стая с такъв идентификатор не е намерена на сървъра", + "Couldn't find a matching Matrix room": "Не успяхме да намерим съответната Matrix стая", + "Bug report sent": "Докладът за грешки е изпратен", + "Loading bug report module": "Зареждане на модул за докладване на проблем", + "Invite to this room": "Покани в тази стая", + "You cannot delete this message. (%(code)s)": "Това съобщение не може да бъде изтрито. (%(code)s)", + "Thursday": "Четвъртък", + "I understand the risks and wish to continue": "Разбирам рисковете и желая да продължа", + "Logs sent": "Логовете са изпратени", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s в %(browserName)s под %(osName)s", + "Back": "Назад", + "Reply": "Отговори", + "Show message in desktop notification": "Показване на съдържание в известията на работния плот", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Логовете за дебъгване съдържат данни за използване на приложението, включващи потребителското Ви име, идентификаторите или псевдонимите на стаите или групите, които сте посетили, и потребителските имена на други потребители. Те не съдържат съобщения.", + "Unhide Preview": "Покажи отново прегледа", + "Announcements about Synapse releases": "Обявления за нови версии на Synapse", + "Search the room directory": "Търсене в директорията със стаи", + "Please describe the bug and/or send logs.": "Моля, опишете проблема и/или изпратете логове.", + "Unable to join network": "Неуспешно присъединяване към мрежата", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Възможна конфигурация на настройките за известия в клиент, различен от Riot. Не могат да бъдат променени в Riot, но важат въпреки това", + "Sorry, your browser is not able to run Riot.": "За жалост, Вашият браузър не може да пусне Riot.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Децентрализиран, шифрован чат и колаборация базирани на [matrix]", + "Building services on Matrix": "Разработка на услуги в Matrix", + "Messages in group chats": "Съобщения в групови чатове", + "Yesterday": "Вчера", + "Error encountered (%(errorDetail)s).": "Възникна грешка (%(errorDetail)s).", + "Event Type": "Вид на събитие", + "Low Priority": "Нисък приоритет", + "What's New": "Какво ново", + "Set Password": "Задаване на парола", + "Appear Offline": "Показване като офлайн", + "Support for those using the Matrix spec": "Поддръжка за използващите Matrix спецификацията", + "An error occurred whilst saving your email notification preferences.": "Възникна грешка при запазване на настройките за имейл известяване.", + "Enable audible notifications in web client": "Включване на звукови известия в уеб клиент", + "Permalink": "Permalink", + "Welcome to Riot.im": "Добре дошли в Riot.im", + "Off": "Изключено", + "Riot does not know how to join a room on this network": "Riot не знае как да се присъедини към стая от тази мрежа", + "Mentions only": "Само при споменаване", + "You can now return to your account after signing out, and sign in on other devices.": "Вече можете да се върнете в профила си след излизане от него и да влезете от други устройства.", + "Enable desktop notifications": "Включване на известия на работния плот", + "Enable email notifications": "Активиране на имейл известия", + "Login": "Вход", + "Download this file": "Изтегли този файл", + "Pin Message": "Закачи съобщението", + "Failed to change settings": "Неуспешна промяна на настройки", + "View Community": "Прегледай общността", + "%(count)s Members|one": "%(count)s Член", + "Event sent!": "Събитието е изпратено!", + "View Source": "Прегледай източника", + "Matrix technical discussions": "Технически дискусии в Matrix", + "Event Content": "Съдържание на събитието", + "Thank you!": "Благодарим!", + "#example": "#пример", + "Collapse panel": "Свий панела", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "С текущия Ви браузър, изглеждането и усещането на приложението може да бъде неточно, и някои или всички от функциите може да не функционират,работят......... Ако искате може да продължите така или иначе, но сте сами по отношение на евентуалните проблеми, които може да срещнете!", + "Checking for an update...": "Проверяване за нова версия...", + "General discussion about Matrix and Riot": "Обща дискусия относно Matrix и Riot", + "There are advanced notifications which are not shown here": "Съществуват разширени настройки за известия, които не са показани тук" } diff --git a/src/i18n/strings/ca.json b/src/i18n/strings/ca.json index 8f9da794b6..5ce387ecdc 100644 --- a/src/i18n/strings/ca.json +++ b/src/i18n/strings/ca.json @@ -882,5 +882,207 @@ "Your language of choice": "El teu idioma preferit", "Which officially provided instance you are using, if any": "Quina instància oficial estàs utilitzant, si escau", "Whether or not you're using the Richtext mode of the Rich Text Editor": "Si estàs utilitzant el mode Richtext del Rich Text Editor o no", - "The information being sent to us to help make Riot.im better includes:": "La informació enviada a Riot.im per ajudar-nos a millorar inclou:" + "The information being sent to us to help make Riot.im better includes:": "La informació enviada a Riot.im per ajudar-nos a millorar inclou:", + "Fetching third party location failed": "S'ha produït un error en obtenir la ubicació de tercers", + "A new version of Riot is available.": "Hi ha una nova versió del Riot disponible.", + "Riot/Android & matrix-android-sdk chat": "Riot/Android & Xat matrix-android-sdk", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Si us plau, descriviu l'error. Què heu fet, què esperàveu que passes i què sembla haver passat?", + "Couldn't load home page": "No s'ha pogut carregar la pàgina d'inici", + "Send Account Data": "Envia les dades del compte", + "Advanced notification settings": "Paràmetres avançats de notificacions", + "Uploading report": "S'està enviant l'informe", + "Sunday": "Diumenge", + "Failed to add tag %(tagName)s to room": "No s'ha pogut afegir l'etiqueta %(tagName)s a la sala", + "Notification targets": "Objectius de les notificacions", + "Failed to set direct chat tag": "No s'ha pogut establir l'etiqueta del xat directe", + "Today": "Avui", + "Files": "Fitxers", + "Report a bug": "Informa d'una errada", + "Implementing VR services with Matrix": "Implementació de serveis VR amb Matrix", + "You are not receiving desktop notifications": "No esteu rebent notificacions d'escriptori", + "Friday": "Divendres", + "Update": "Actualització", + "You need to be using HTTPS to place a screen-sharing call.": "Heu d'utilitzar HTTPS per poder fer una trucada amb pantalla compartida.", + "What's New": "Novetats", + "Add an email address above to configure email notifications": "Afegiu més amunt un correu electrònic per a configurar les notificacions", + "Expand panel": "Expandeix el panel", + "On": "Engegat", + "%(count)s Members|other": "%(count)s membres", + "Filter room names": "Filtra els noms de les sales", + "Changelog": "Registre de canvis", + "Running Matrix services": "Serveis de Matrix en marxa", + "Waiting for response from server": "S'està esperant una resposta del servidor", + "Uploaded on %(date)s by %(user)s": "Pujat el %(date)s per l'usuari %(user)s", + "Send Custom Event": "Envia els esdeveniments personalitzats", + "Failed to send report: ": "No s'ha pogut enviar l'informe ", + "Unknown device": "Dispositiu desconegut", + "All notifications are currently disabled for all targets.": "Actualment totes les notificacions estan inhabilitades per a tots els objectius.", + "Failed to send logs: ": "No s'han pogut enviar els logs: ", + "delete the alias.": "esborra l'alies.", + "To return to your account in future you need to set a password": "Per poder tornar al vostre compte en un futur, heu de set a password", + "Forget": "Oblida", + "#example": "#exemple", + "Riot/Web & Desktop chat": "Riot/Web & Xat d'escriptori", + "Hide panel": "Amaga el panel", + "You cannot delete this image. (%(code)s)": "No podeu eliminar aquesta imatge. (%(code)s)", + "Cancel Sending": "Cancel·la l'enviament", + "This Room": "Aquesta sala", + "Get started with some tips from Riot Bot!": "Comenceu amb alguns consells de Riot Bot!", + "The Home Server may be too old to support third party networks": "El servidor local pot ser massa antic per a ser compatible amb xarxes de tercers", + "Resend": "Reenvia", + "Room not found": "No s'ha trobat la sala", + "Messages containing my display name": "Missatges que contenen el meu nom visible", + "Messages in one-to-one chats": "Missatges en xats un a un", + "Contributing code to Matrix and Riot": "Contribuir amb codi a Matrix i Riot", + "Unavailable": "No disponible", + "Community-run support for Synapse": "Suport de la comunitat per a Synapse", + "Error saving email notification preferences": "No s'han pogut desar les preferències de les notificacions a causa d'un error", + "View Decrypted Source": "Mostra el codi desencriptat", + "Failed to update keywords": "No s'han pogut actualitzar les paraules clau", + "Notes:": "Notes:", + "remove %(name)s from the directory.": "elimina %(name)s del directori.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Les notificacions sobre les següents paraules clau segueixen regles que no es poden mostrar aquí:", + "Safari and Opera work too.": "Safari i Opera també fan la feina.", + "Please set a password!": "Si us plau, establiu una contrasenya", + "You have successfully set a password!": "Heu establert correctament la contrasenya", + "Chat with Riot Bot": "Conversa amb el Bot de Riot", + "Support for those using, running and writing other bridges": "Suport per a aquells que utilitzen, executen i escriuen altres ponts", + "Admin support for Dendrite": "Suport dels administrador per a Dendrite", + "An error occurred whilst saving your email notification preferences.": "S'ha produït un error en desar les vostres preferències de notificació per correu electrònic.", + "Explore Room State": "Esbrina els estats de les sales", + "Source URL": "URL origen", + "Messages sent by bot": "Missatges enviats pel bot", + "Filter results": "Resultats del filtre", + "Members": "Membres", + "No update available.": "No hi ha cap actualització disponible.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Ja existeixen moltes sales a Matrix vinculades a xarxes existents (Slack, IRC, Gitter, etc.) o independents. Feu un cop d'ull al directori!", + "Noisy": "Sorollós", + "Failed to get protocol list from Home Server": "No s'ha pogut obtenir la llista de protocols del servidor local", + "Collecting app version information": "S'està recollint la informació de la versió de l'aplicació", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Voleu esborrar de la sala l'alies %(alias)s i retirar %(name)s del directori?", + "Co-ordination for Riot/Web translators": "Coordinació per a traductors de Riot/Web", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Això farà possible que pugueu tronar al vostre compte des de qualsevol dispositiu.", + "Dev chat for the Dendrite dev team": "Xat de l'equip Dendrite per a desenvolupadors", + "Design and implementation of E2E in Matrix": "Disseny i implementació de l'E2E a Matrix", + "Enable notifications for this account": "Habilita les notificacions per aquest compte", + "Directory": "Directori", + "Invite to this community": "Convida a aquesta comunitat", + "Search for a room": "Busca una sala", + "Search…": "Cerca…", + "Messages containing keywords": "Missatges que contenen keywords", + "When I'm invited to a room": "Quan sóc convidat a una sala", + "Tuesday": "Dimarts", + "Enter keywords separated by a comma:": "Introduïu les paraules clau separades per una coma:", + "Forward Message": "Reenvia el missatge", + "Remove %(name)s from the directory?": "Voleu retirar %(name)s del directori?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot utilitza moltes funcions avançades del navegador, algunes de les quals no estan disponibles o són experimentals al vostre navegador actual.", + "Developer Tools": "Eines de desenvolupador", + "Preparing to send logs": "Preparant l'enviament de logs", + "Explore Account Data": "Explora les dades del compte", + "Remove from Directory": "Elimina del directori", + "Away": "Absent", + "Saturday": "Dissabte", + "Remember, you can always set an email address in user settings if you change your mind.": "Recordeu-ho, si canvieu d'idea, sempre podreu establir una adreça de correu electrònic a las vostra configuració d'usuari.", + "Direct Chat": "Xat directe", + "The server may be unavailable or overloaded": "El servidor pot no estar disponible o sobrecarregat", + "Reject": "Rebutja", + "Riot is not supported on mobile web. Install the app?": "Riot no és compatible amb la web per a mòbils. Voleu instal·lar l'aplicació per a mòbils?", + "Discussion of all things Matrix!": "Debats sobre qualsevol cosa de Matrix!", + "Failed to set Direct Message status of room": "No s'ha pogut establir l'estat del missatge directe de la sala", + "Monday": "Dilluns", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Amb aquest informe d'error, alguns registres d'aquesta aplicació s'enviaran també per tal de fer un diagnostic del problema. Si preferiu enviar només el text anterior, desseleccioneu:", + "All messages (noisy)": "Tots els missatges (sorollós)", + "Enable them now": "Habilita-ho ara", + "Messages containing my user name": "Missatges que contenen el meu nom d'usuari", + "Describe your problem here.": "Descriu aquí el teu problema.", + "Toolbox": "Caixa d'eines", + "Collecting logs": "S'estan recopilant els registres", + "more": "més", + "GitHub issue link:": "Enllaç de l'issue de GitHub:", + "Failed to get public room list": "No s'ha pogut obtenir el llistat de sales públiques", + "You must specify an event type!": "Heu d'especificar un tipus d'esdeveniment", + "(HTTP status %(httpStatus)s)": "(Estat de l´HTTP %(httpStatus)s)", + "All Rooms": "Totes les sales", + "State Key": "Clau d'estat", + "Please install Chrome or Firefox for the best experience.": "Si us plau, instal·leu Chrome or Firefox per gaudir d'una millor experiència.", + "Wednesday": "Dimecres", + "Send logs": "Envia els registres", + "All messages": "Tots els missatges", + "Implementing VoIP services with Matrix": "Implementació de serveis VoIP amb Matrix", + "Dev chat for the Riot/Web dev team": "Xat de l'equip de desenvolupadors Riot/Web per a desenvolupadors", + "Call invitation": "Invitació de trucada", + "Riot Desktop on %(platformName)s": "Riot d'escriptori per a %(platformName)s", + "Downloading update...": "Descarregant l'actualització...", + "You have successfully set a password and an email address!": "Heu establert correctament la vostra contrasenya i l'adreça de correu electrònic", + "Failed to send custom event.": "No s'ha pogut enviar l'esdeveniment personalitzat.", + "What's new?": "Què hi ha de nou?", + "Discussion of the Identity Service API": "Debat sobre l'API Identity Service", + "Support for those using and running matrix-appservice-irc": "Suport per a aquells que utilitzen i executen matrix-appservice-irc", + "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & Xat de matrix-ios-sdk", + "Notify me for anything else": "Notifica'm per a qualsevol altra cosa", + "View Source": "Mostra el codi", + "Keywords": "Paraules clau", + "Click here to create a GitHub issue.": "Clica aquí per crear una issue a GitHub.", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Podeu utilitzar opcions de servidor personalitzades per iniciar sessió en altres servidors Matrix especificant una URL diferent a la del servidor principal.
    Això us permet utilitzar Riot amb un compte de Matrix existent en un servidor d'origen diferent.

    També podeu establir un servidor d'identitat personalitzat, però no podreu convidar o ser convidat per correu electrònic.", + "Can't update user notification settings": "No es poden actualitzar els paràmetres de les notificacions de l'usuari", + "Notify for all other messages/rooms": "Notifica per a tots els altres missatges o sales", + "Unable to look up room ID from server": "No s'ha pogut cercar l'ID de la sala en el servidor", + "Couldn't find a matching Matrix room": "No s'ha pogut trobar una sala de Matrix que coincideixi", + "Bug report sent": "S'ha enviat l'informe d'error", + "Safari and Opera work too.": "També funcionen el Safari i l'Opera.", + "Loading bug report module": "S'està carregant l'informe del modul", + "Invite to this room": "Convida a aquesta sala", + "You cannot delete this message. (%(code)s)": "No podeu eliminar aquest missatge. (%(code)s)", + "Thursday": "Dijous", + "I understand the risks and wish to continue": "Entenc el riscos i desitjo continuar", + "Logs sent": "Logs enviats", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s via %(browserName)s per a %(osName)s", + "Back": "Enrere", + "Reply": "Respon", + "Show message in desktop notification": "Mostra els missatges amb notificacions d'escriptori", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Els logs de depuració contenen dades d'ús de l'aplicació que inclouen el teu nom d'usuari, les IDs o pseudònims de les sales o grups que has visitat i els noms d'usuari d'altres usuaris. No contenen missatges.", + "Unhide Preview": "Mostra la previsualització", + "Announcements about Synapse releases": "Anuncis sobre llançaments de Synapse", + "Search the room directory": "Cerqueu el directori de sales", + "Please describe the bug and/or send logs.": "Si us plau, descriviu l'error i/o envia els registres.", + "Unable to join network": "No s'ha pogut unir-se a la xarxa", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "És possible que els hàgiu configurat en un client diferent de Riot. No podeu modificar-los amb Riot, però encara s'apliquen", + "Sorry, your browser is not able to run Riot.": "Disculpeu, el seu navegador not pot executar Riot.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Xat descentralitzat, encriptat & col·laboració amb tecnologia de [matrix]", + "Quote": "Cita", + "Messages in group chats": "Missatges en xats de grup", + "Yesterday": "Ahir", + "Error encountered (%(errorDetail)s).": "S'ha trobat un error (%(errorDetail)s).", + "Login": "Inicia sessió", + "Low Priority": "Baixa prioritat", + "Unable to fetch notification target list": "No s'ha pogut obtenir la llista d'objectius de les notificacions", + "Appear Offline": "Apareix sense connexió", + "Support for those using the Matrix spec": "Suport per a aquells que utilitzen l'especificació Matrix", + "Set Password": "Establiu una contrasenya", + "Enable audible notifications in web client": "Habilita les notificacions d'àudio al client web", + "Permalink": "Enllaç permanent", + "Welcome to Riot.im": "Benvingut a Riot.im", + "Off": "Apagat", + "Riot does not know how to join a room on this network": "El Riot no sap com unir-se a una sala en aquesta xarxa", + "Mentions only": "Només mencions", + "Failed to remove tag %(tagName)s from room": "No s'ha pogut esborrar l'etiqueta %(tagName)s de la sala", + "You can now return to your account after signing out, and sign in on other devices.": "Ara podreu tornar a entrar al vostre compte des de altres dispositius.", + "Enable desktop notifications": "Habilita les notificacions d'escriptori", + "Enable email notifications": "Habilita les notificacions per correu electrònic", + "Event Type": "Tipus d'esdeveniment", + "Download this file": "Descarrega aquest fitxer", + "Pin Message": "Enganxa el missatge", + "Failed to change settings": "No s'han pogut modificar els paràmetres", + "View Community": "Mira la communitat", + "%(count)s Members|one": "%(count)s membre", + "Event sent!": "S'ha enviat l'esdeveniment", + "Matrix technical discussions": "Debats tècnics sobre Matrix", + "Event Content": "Contingut de l'esdeveniment", + "Thank you!": "Gràcies!", + "Building services on Matrix": "Construir serveis a Matrix", + "Collapse panel": "Col·lapsa el tauler", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Amb el vostre navegador actual, l'aparença de l'aplicació pot ser completament incorrecta i algunes o totes les funcions poden no funcionar correctament. Si voleu provar-ho de totes maneres, podeu continuar, però esteu sols pel que fa als problemes que pugueu trobar!", + "Checking for an update...": "Comprovant si hi ha actualitzacions...", + "General discussion about Matrix and Riot": "Debat general sobre Matrix i Riot", + "There are advanced notifications which are not shown here": "Hi ha notificacions avançades que no es mostren aquí" } diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index 4267954d4c..5a4d2afe7e 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -948,5 +948,203 @@ "expand": "rozbalit", "Old cryptography data detected": "Nalezeny starší šifrované datové zprávy", "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Nalezeny datové zprávy ze starší verze Riot. Důsledkem bude, že E2E šifrování nebude ve starší verzi Riot správně fungovat. Šifrované zprávy ze starší verze nemusí být čitelné v nové verzi. Může dojít i k selhání zasílaní zpráv s touto verzí Riot. Pokud zaznamenáte některý z uvedených problému, odhlaste se a přihlaste znovu. Pro zachování historie zpráv exportujte a znovu importujte vaše klíče.", - "Warning": "Upozornění" + "Warning": "Upozornění", + "Fetching third party location failed": "Nepodařilo se zjistit umístění třetí strany", + "A new version of Riot is available.": "Je dostupná nová verze Riotu.", + "Riot/Android & matrix-android-sdk chat": "Riot/Android a matrix-android-sdk chat", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Prosím popište chybu. Co jste dělal/a? Co jste čekal/a, že se stane? Co se stalo?", + "I understand the risks and wish to continue": "Rozumím rizikům a přeji si pokračovat", + "Couldn't load home page": "Nepodařilo se nahrát úvodní stránku", + "Send Account Data": "Poslat data o účtu", + "Advanced notification settings": "Pokročilé nastavení upozornění", + "Uploading report": "Nahrávám hlášení", + "Sunday": "Neděle", + "Messages sent by bot": "Zprávy poslané robotem", + "Notification targets": "Cíle upozornění", + "Failed to set direct chat tag": "Nepodařilo se nastavit štítek přímého chatu", + "Today": "Dnes", + "Files": "Soubory", + "Report a bug": "Nahlásit chybu", + "Implementing VR services with Matrix": "Implementace VR služeb v Matrixu", + "You are not receiving desktop notifications": "Nedostáváte upozornění na desktopu", + "Friday": "Pátek", + "Update": "Aktualizace", + "You need to be using HTTPS to place a screen-sharing call.": "Pro uskutečnění hovoru se sdílením obrazovky musíte používat HTTPS.", + "What's New": "Co je nového", + "Add an email address above to configure email notifications": "Abyste mohli nastavovat e-mailová upozornění, musíte uvést svoji e-mailovou adresu v kolonce výše", + "Expand panel": "Rozbalit panel", + "On": "Zapnout", + "%(count)s Members|other": "%(count)s Členů", + "Filter room names": "Filtrovat místnosti dle názvu", + "Changelog": "Seznam změn", + "Running Matrix services": "Provozování Matrix služeb", + "Waiting for response from server": "Čekám na odezvu ze serveru", + "Send Custom Event": "Odeslat vlastní událost", + "Failed to send report: ": "Nepodařilo se odeslat hlášení: ", + "Unknown device": "Neznámé zařízení", + "All notifications are currently disabled for all targets.": "Veškeré notifikace jsou aktuálně pro všechny cíle vypnuty.", + "delete the alias.": "smazat alias.", + "To return to your account in future you need to set a password": "Abyste se mohli ke svému účtu v budoucnu vrátit, musíte si nastavit heslo", + "Forget": "Zapomenout", + "Riot/Web & Desktop chat": "Riot/Web a Desktop chat", + "Hide panel": "Skrýt panel", + "You cannot delete this image. (%(code)s)": "Tento obrázek nemůžete smazat. (%(code)s)", + "Cancel Sending": "Zrušit odesílání", + "This Room": "Tato místnost", + "The Home Server may be too old to support third party networks": "Tento domovský server může být příliš zastaralý na to, aby podporoval sítě třetích stran", + "Noisy": "Hlučný", + "Room not found": "Místnost nenalezena", + "Messages containing my display name": "Zprávy obsahující mé zobrazované jméno", + "Remember, you can always set an email address in user settings if you change your mind.": "Vězte, že kdybyste si to rozmysleli, e-mailovou adresu můžete kdykoliv doplnit v uživatelském nastavení.", + "Contributing code to Matrix and Riot": "Přispívaní kódem do Matrixu a Riotu", + "Unavailable": "Nedostupné", + "Community-run support for Synapse": "Komunitou řízená podpora pro Synapse", + "Error saving email notification preferences": "Chyba při ukládání nastavení e-mailových upozornění", + "View Decrypted Source": "Zobrazit dešifrovaný zdroj", + "Failed to update keywords": "Nepodařilo se aktualizovat klíčová slova", + "remove %(name)s from the directory.": "odebrat %(name)s z adresáře.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Upozornění na následující klíčová slova se řídí pravidly, která zde nelze zobrazit:", + "Safari and Opera work too.": "Safari a Opera fungují taky.", + "Please set a password!": "Prosím nastavte si heslo!", + "You have successfully set a password!": "Úspěšně jste si nastavili heslo!", + "Chat with Riot Bot": "Chatujte s Riot Botem", + "Support for those using, running and writing other bridges": "Podpora pro ty, kteří používají, provozují nebo vyvíjejí ostatní můstky", + "Admin support for Dendrite": "Správcovská podpora pro Dendrite", + "Explore Room State": "Prohlížet stav místnosti", + "Source URL": "Zdrojová URL", + "Failed to add tag %(tagName)s to room": "Nepodařilo se přidat štítek %(tagName)s k místnosti", + "Filter results": "Filtrovat výsledky", + "Members": "Členové", + "No update available.": "Není dostupná žádná aktualizace.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "V Matrixu je spousta samostatných, nebo s jinými sítěmi (Slack, IRC, Gitter aj.) propojených místností. Prohlédněte si jejich adresář!", + "Resend": "Poslat znovu", + "Failed to get protocol list from Home Server": "Z domovského serveru se nepodařilo získat seznam protokolů", + "Collecting app version information": "Sbírání informací o verzi aplikace", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Smazat alias místnosti %(alias)s a odstranit %(name)s z adresáře?", + "customServer_text": "Ve vlastních serverových volbách se můžete přihlásit na ostatní Matrix servery, a to tak, že určíte URL jiného domovského serveru.
    To znamená, že můžete používat Riot s již existujícím Matrix účtem na jiném domovském serveru.

    Taky můžete nastavit vlastní server identity, pak ale nebudete moci zvát ostatní nebo naopak být ostatními zván prostřednictvím e-mailové adresy.", + "Co-ordination for Riot/Web translators": "Součinnost překladatelů Riot/Web", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Toto vám umožní vrátit se po odhlášení ke svému účtu a používat jej na ostatních zařízeních.", + "Dev chat for the Dendrite dev team": "Chat vývojového týmu Dendrite", + "Keywords": "Klíčová slova", + "Enable notifications for this account": "Zapnout upozornění na tomto účtu", + "Directory": "Adresář", + "Invite to this community": "Pozvat do této komunity", + "Search for a room": "Hledat místnost", + "Messages containing keywords": "Zprávy obsahující klíčová slova", + "View Source": "Zobrazit zdroj", + "Tuesday": "Úterý", + "Enter keywords separated by a comma:": "Vložte klíčová slova oddělená čárkou:", + "Forward Message": "Přeposlat zprávu", + "You have successfully set a password and an email address!": "Úspěšně jste si nastavili heslo a e-mailovou adresu!", + "Remove %(name)s from the directory?": "Odebrat %(name)s z adresáře?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot používá mnoho pokročilých funkcí, z nichž některé jsou ve vašem současném prohlížeči nedostupné nebo experimentální.", + "Developer Tools": "Nástroje pro vývojáře", + "Enable desktop notifications": "Zapnout upozornění na ploše", + "Explore Account Data": "Prozkoumat data o účtu", + "Remove from Directory": "Odebrat z adresáře", + "Away": "Pryč", + "Saturday": "Sobota", + "Messages in one-to-one chats": "Zprávy v individuálních chatech", + "Direct Chat": "Přímý chat", + "The server may be unavailable or overloaded": "Server může být nedostupný nebo přetížený", + "Reject": "Odmítnout", + "Riot is not supported on mobile web. Install the app?": "Riot není podporovaný na mobilním webu. Nainstalovat aplikaci?", + "Discussion of all things Matrix!": "Diskuse o všem okolo Matrixu!", + "Failed to set Direct Message status of room": "Nepodařilo se přiřadit místnosti status Přímé zprávy", + "Monday": "Pondělí", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Kvůli diagnostice budou spolu s tímto hlášením o chybě odeslány i záznamy z klienta. Chcete-li odeslat pouze text výše, prosím odškrtněte:", + "Send Custom State Event": "Poslat vlastní stavovou událost", + "All messages (noisy)": "Všechny zprávy (hlasitě)", + "Enable them now": "Povolit nyní", + "Messages containing my user name": "Zprávy obsahující mé uživatelské jméno", + "Describe your problem here.": "Popište zde svůj problém.", + "Toolbox": "Sada nástrojů", + "Collecting logs": "Sbírání logů", + "more": "více", + "Bug report sent": "Hlášení o chybě bylo odesláno", + "You must specify an event type!": "Musíte určit typ události!", + "(HTTP status %(httpStatus)s)": "(HTTP status %(httpStatus)s)", + "Invite to this room": "Pozvat do této místnosti", + "Please install Chrome or Firefox for the best experience.": "Pro nejlepší zážitek si prosím nainstalujte Chrome nebo Firefox.", + "Failed to get public room list": "Nepodařilo se získat seznam veřejných místností", + "Send logs": "Odeslat záznamy", + "All messages": "Všechny zprávy", + "Implementing VoIP services with Matrix": "Implementace VoIP služeb v Matrixu", + "Dev chat for the Riot/Web dev team": "Chat vývojového týmu Riot/Web", + "Call invitation": "Pozvánka k hovoru", + "Riot Desktop on %(platformName)s": "Riot Desktop na %(platformName)s", + "Downloading update...": "Stahování aktualizace...", + "State Key": "Stavový klíč", + "Failed to send custom event.": "Nepodařilo se odeslat vlastní událost.", + "What's new?": "Co je nového?", + "Discussion of the Identity Service API": "Diskuze o API služby identity", + "Support for those using and running matrix-appservice-irc": "Podpora pro používání matrix-appservice-irc", + "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS a matrix-ios-sdk chat", + "Notify me for anything else": "Upozorni mě na cokoliv jiného", + "When I'm invited to a room": "Pokud jsem pozván do místnosti", + "Design and implementation of E2E in Matrix": "Návrh a implementace E2E v Matrixu", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Přes vlastní serverové volby se můžete přihlásit k dalším Matrix serverům tak, že zadáte jinou adresu domovského serveru.
    Díky tomu můžete v Riotu používat Matrix účet z jiného domovského serveru.

    Můžete nastavit i vlastní server identity, ale pak už nebudete moci zvát ani být zván/a skrze e-mailovou adresu.", + "Can't update user notification settings": "Nelze aktualizovat uživatelské nastavení upozornění", + "Notify for all other messages/rooms": "Upozorni na všechny ostatní zprávy/místnosti", + "Unable to look up room ID from server": "Nelze získat ID místnosti ze serveru", + "Couldn't find a matching Matrix room": "Odpovídající Matrix místost nenalezena", + "Support for those using the Matrix spec": "Podpora pro uživatele Matrix specifikace", + "Safari and Opera work too.": "Safari a Opera fungují také.", + "Loading bug report module": "Nahrává se modul nahlašování chyb", + "All Rooms": "Všechny místnosti", + "You cannot delete this message. (%(code)s)": "Tuto zprávu nemůžete smazat. (%(code)s)", + "Thursday": "Čtvrtek", + "Search…": "Vyhledat…", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s přes %(browserName)s na %(osName)s", + "Back": "Zpět", + "Failed to change settings": "Nepodařilo se změnit nastavení", + "Reply": "Odpovědět", + "Show message in desktop notification": "Zobrazovat zprávu v upozornění na ploše", + "Unhide Preview": "Zobrazit náhled", + "Announcements about Synapse releases": "Oznámení o vydáních Synapse", + "Search the room directory": "Prohledat adresář místností", + "Please describe the bug and/or send logs.": "Prosím popište chybu a/nebo pošlete záznamy.", + "Unable to join network": "Nelze se připojit k síti", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Snad jste je nastavili v jiném klientu než Riot. V Riotu je nemůžete upravit, ale přesto platí", + "Sorry, your browser is not able to run Riot.": "Omlouváme se, váš prohlížeč není schopný spustit Riot.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Decentralizovaný, šifrovaný chat a spolupráce na platformě [matrix]", + "Uploaded on %(date)s by %(user)s": "Nahráno %(date)s uživatelem %(user)s", + "Messages in group chats": "Zprávy ve skupinových chatech", + "Yesterday": "Včera", + "Error encountered (%(errorDetail)s).": "Nastala chyba (%(errorDetail)s).", + "Login": "Přihlásit", + "Low Priority": "Nízká priorita", + "Riot does not know how to join a room on this network": "Riot neví, jak vstoupit do místosti na této síti", + "Set Password": "Nastavit heslo", + "Appear Offline": "Jevit se offline", + "Get started with some tips from Riot Bot!": "Začněte s radami od Riot Bota!", + "An error occurred whilst saving your email notification preferences.": "Při ukládání nastavení e-mailových upozornění nastala chyba.", + "Enable audible notifications in web client": "Povolit zvuková upozornění ve webové aplikaci", + "Permalink": "Trvalý odkaz", + "Welcome to Riot.im": "Vítá vás Riot.im", + "Off": "Vypnout", + "#example": "#příklad", + "Mentions only": "Pouze zmínky", + "Failed to remove tag %(tagName)s from room": "Nepodařilo se odstranit štítek %(tagName)s z místnosti", + "Wednesday": "Středa", + "You can now return to your account after signing out, and sign in on other devices.": "Nyní se můžete ke svému účtu vrátit i po odhlášení a používat jej na ostatních zařízeních.", + "Please install Chrome or Firefox for the best experience.": "Prosím nainstalujte si Chrome nebo Firefox pro nejlepší zážitek.", + "Enable email notifications": "Zapnout upozornění přes e-mail", + "Event Type": "Typ události", + "Download this file": "Stáhnout tento soubor", + "Pin Message": "Připíchnout zprávu", + "Thank you!": "Děkujeme vám!", + "View Community": "Zobrazit Komunitu", + "%(count)s Members|one": "%(count)s Člen", + "Event sent!": "Událost odeslána!", + "Matrix technical discussions": "Technické diskuse o Matrixu", + "Building services on Matrix": "Stavění služeb na Matrixu", + "Event Content": "Obsah události", + "Unable to fetch notification target list": "Nepodařilo se získat seznam cílů upozornění", + "Quote": "Citace", + "Collapse panel": "Sbalit panel", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Vzhled a chování aplikace může být ve vašem aktuální prohlížeči nesprávné a některé nebo všechny funkce mohou být chybné. Chcete-li i přes to pokračovat, nebudeme vám bránit, ale se všemi problémy, na které narazíte, si musíte poradit sami!", + "Checking for an update...": "Kontrola aktualizací...", + "General discussion about Matrix and Riot": "Obecná diskuse o Matrixu a Riotu", + "There are advanced notifications which are not shown here": "Jsou k dispozici pokročilá upozornění, která zde nejsou zobrazena" } diff --git a/src/i18n/strings/da.json b/src/i18n/strings/da.json index dbcc9fbb2c..f47550afca 100644 --- a/src/i18n/strings/da.json +++ b/src/i18n/strings/da.json @@ -242,5 +242,197 @@ "(unknown failure: %(reason)s)": "(ukendt fejl: %(reason)s)", "%(senderName)s ended the call.": "%(senderName)s afsluttede opkaldet.", "%(senderName)s placed a %(callType)s call.": "%(senderName)s startede et %(callType)s opkald.", - "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s inviterede %(targetDisplayName)s til rummet." + "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s inviterede %(targetDisplayName)s til rummet.", + "Fetching third party location failed": "Hentning af tredjeparts placering mislykkedes", + "A new version of Riot is available.": "En ny version a Riot er tilgængelig.", + "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk chat", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Beskriv venlist fejlen. Hvad gjorde du? Hvad forventede du ville ske? Hvad skete rent faktisk?", + "Couldn't load home page": "Kunne ikke indlæse startsiden", + "Send Account Data": "Send Konto Data", + "All notifications are currently disabled for all targets.": "Alle meddelelser er for øjeblikket deaktiveret for alle mål.", + "Uploading report": "Uploader rapport", + "Sunday": "Søndag", + "Messages sent by bot": "Beskeder sendt af en bot", + "Notification targets": "Meddelelsesmål", + "Failed to set direct chat tag": "Kunne ikke markere rummet som direkte chat", + "Today": "I dag", + "Files": "Filer", + "Report a bug": "Rapportér en fejl", + "Implementing VR services with Matrix": "Implementering af VR tjenester med Matrix", + "You are not receiving desktop notifications": "Du modtager ikke skrivebordsmeddelelser", + "Friday": "Fredag", + "Update": "Opdater", + "You need to be using HTTPS to place a screen-sharing call.": "Du skal bruge HTTPS for at lave skærm-delings-opkald.", + "What's New": "Hvad er nyt", + "Add an email address above to configure email notifications": "Tilføj en emailadresse ovenfor for at konfigurere e-mail-underretninger", + "Expand panel": "Udvid panel", + "On": "Tændt", + "Filter room names": "Filtrér rumnavne", + "Changelog": "Ændringslog", + "Running Matrix services": "Drift af Matrix tjenester", + "Waiting for response from server": "Venter på svar fra server", + "Uploaded on %(date)s by %(user)s": "Uploadet den %(date)s af %(user)s", + "Send Custom Event": "Send Brugerdefineret Begivenhed", + "Failed to send report: ": "Kunne ikke sende rapport: ", + "Off": "Slukket", + "Unknown device": "Ukendt enhed", + "Advanced notification settings": "Avancerede notifikationsindstillinger", + "delete the alias.": "Slet aliaset.", + "To return to your account in future you need to set a password": "For at komme ind på din konto i fremtiden skal du indstille et password", + "Forget": "Glem", + "#example": "#eksempel", + "Riot/Web & Desktop chat": "Riot/Web- & Desktopchat", + "Hide panel": "Gem panel", + "You cannot delete this image. (%(code)s)": "Du kan ikke slette dette billede. (%(code)s)", + "Cancel Sending": "Stop Forsendelse", + "Warning": "Advarsel", + "This Room": "Dette rum", + "The Home Server may be too old to support third party networks": "Hjemmeserveren kan være for gammel til at understøtte tredjepartsnetværk", + "All messages (loud)": "Alle beskeder (høj)", + "Room not found": "Rummet ikke fundet", + "Messages containing my display name": "Beskeder der indeholder mit viste navn", + "Messages in one-to-one chats": "Beskeder i en-til-en chats", + "Contributing code to Matrix and Riot": "Biddrag med kode til Matrix og Riot", + "Unavailable": "Utilgængelig", + "Community-run support for Synapse": "Fællesskabsstyret hjælp til Synapse", + "Error saving email notification preferences": "Fejl ved at gemme e-mail-underretningsindstillinger", + "View Decrypted Source": "Se Dekrypteret Kilde", + "Failed to update keywords": "Kunne ikke opdatere søgeord", + "remove %(name)s from the directory.": "fjern %(name)s fra kataloget.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Meddelelser om følgende søgeord følger regler, der ikke kan vises her:", + "Safari and Opera work too.": "Safari og Opera virker også.", + "Please set a password!": "Indstil venligst et password!", + "You have successfully set a password!": "Du har succesfuldt indstillet et password!", + "Chat with Riot Bot": "Chat med Riot Bot", + "Support for those using, running and writing other bridges": "Hjælp til dem der bruger, driver og skriver andre bridges", + "Admin support for Dendrite": "Adminstrationshjælp til Dendrite", + "An error occurred whilst saving your email notification preferences.": "Der opstod en fejl under opbevaring af dine e-mail-underretningsindstillinger.", + "Explore Room State": "Udforsk Rum Tilstand", + "Source URL": "Kilde URL", + "Failed to add tag %(tagName)s to room": "Kunne ikke tilføje tag(s): %(tagName)s til rummet", + "Filter results": "Filtrér resultater", + "Members": "Medlemmer", + "No update available.": "Ingen opdatering tilgængelig.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Masser af rum ekistere allerede i Matrix, forbundet til eksisterende netværk (Slack, IRC, Gitter osv.) eller selvstændige. Tjek kataloget ud!", + "Noisy": "Støjende", + "Failed to get protocol list from Home Server": "Kunne ikke få protokolliste fra Home Server", + "Collecting app version information": "Indsamler app versionsoplysninger", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Slet rumaliaset %(alias)s og fjern %(name)s fra kataloget?", + "Co-ordination for Riot/Web translators": "Co-ordination af Riot/Web oversættere", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Dette vil tillade dig at vende tilbage til din konto efter at have logget ud og at logge ind på andre enheder.", + "Dev chat for the Dendrite dev team": "Udviklerchat til Dendrite udviklerholdet", + "Keywords": "Søgeord", + "Enable notifications for this account": "Aktivér underretninger for dette brugernavn", + "Directory": "Rum katalog", + "Invite to this community": "Inviter til dette fællesskab", + "Search for a room": "Søg efter et rum", + "Search…": "Søg…", + "Messages containing keywords": "Beskeder der indeholder keywords", + "When I'm invited to a room": "Når jeg bliver inviteret til et rum", + "Tuesday": "Tirsdag", + "Enter keywords separated by a comma:": "Indtast søgeord adskilt af et komma:", + "Forward Message": "Videresend Besked", + "Remove %(name)s from the directory?": "Fjern %(name)s fra kataloget?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot bruger mange avancerede browser funktioner, hvoraf nogle af dem ikke er tilgængelige eller er eksperimentelle i din browser.", + "Event sent!": "Begivenhed sendt!", + "Explore Account Data": "Udforsk Konto Data", + "Away": "Ikke til stede", + "Saturday": "Lørdag", + "Remember, you can always set an email address in user settings if you change your mind.": "Husk, du kan altid indstille en emailadresse i dine bruger indstillinger hvis du ombestemmer dig.", + "Direct Chat": "Personlig Chat", + "The server may be unavailable or overloaded": "Serveren kan være utilgængelig eller overbelastet", + "Reject": "Afvis", + "Riot is not supported on mobile web. Install the app?": "Riot understøtter ikke mobilhjemmesider. Vil du installere app'en?", + "Discussion of all things Matrix!": "Diskussion om alt der har med Matrix at gøre!", + "Failed to set Direct Message status of room": "Kunne ikke indstille Direkte Beskedstatus for rummet", + "Monday": "Mandag", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "For at diagnosticere problemer vil logs fra denne klient blive sendt sammen med fejlrapporten. Hvis du vil foretrække kun at sende teksten foroven, bedes du fjerne fluebenet:", + "Remove from Directory": "Fjern fra Katalog", + "Enable them now": "Aktivér dem nu", + "Messages containing my user name": "Beskeder der indeholder mit brugernavn", + "Describe your problem here.": "Beskriv dit problem her.", + "Toolbox": "Værktøjer", + "Collecting logs": "Indsamler logfiler", + "more": "mere", + "Support for those using the Matrix spec": "Hjælp til dem der anvender Matrix speciffikationen", + "You must specify an event type!": "Du skal angive en begivenhedstype!", + "(HTTP status %(httpStatus)s)": "(HTTP tilstand %(httpStatus)s)", + "Invite to this room": "Inviter til dette rum", + "State Key": "Tilstandsnøgle", + "Please install Chrome or Firefox for the best experience.": "Installer venligst Chrome eller Firefox for den bedste oplevelse.", + "Failed to get public room list": "Kunne ikke få offentlig rumliste", + "Send": "Send", + "Send logs": "Send logs", + "All messages": "Alle beskeder", + "Implementing VoIP services with Matrix": "Implementering af VoIP tjenester med Matrix", + "Dev chat for the Riot/Web dev team": "Udviklerchat til Riot/Web udviklerholdet", + "Call invitation": "Opkalds invitation", + "Riot Desktop on %(platformName)s": "Riot Desktop på %(platformName)s", + "Downloading update...": "Downloader opdatering...", + "You have successfully set a password and an email address!": "Du har succesfuldt indstillet et password og en emailadresse!", + "Failed to send custom event.": "Kunne ikke sende brugerdefinerede begivenhed.", + "What's new?": "Hvad er nyt?", + "Discussion of the Identity Service API": "Diskussion af Identity Service API'en", + "Support for those using and running matrix-appservice-irc": "Hjælp til dem der bruger og kører matrix-appservice-irc", + "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk chat", + "Notify me for anything else": "Underret mig om noget andet", + "View Source": "Se Kilde", + "Design and implementation of E2E in Matrix": "Design og implementering af E2E i Matrix", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Du kan bruge de brugerdefinerede server indstillinger til at logge ind på andre Matrix servere ved at skrive en anden Home Server adresse.
    Dette tillader dig at bruge Riot med en eksisterende Matrix konto på en anden home server.

    Du kan også indstille en brugerdefineret identity server men så vil du ikke kunne invitere brugere ved hjælp af deres emailadresse eller selv blive inviteret med emailadresse.", + "Can't update user notification settings": "Kan ikke opdatere brugermeddelelsesindstillinger", + "Notify for all other messages/rooms": "Underret om alle andre meddelelser / rum", + "Unable to look up room ID from server": "Kunne ikke slå rum-id op på server", + "Couldn't find a matching Matrix room": "Kunne ikke finde et matchende Matrix-rum", + "Bug report sent": "Fejl rapporteret", + "Loading bug report module": "Indlæser fejlrepporterings modul", + "All Rooms": "Alle rum", + "You cannot delete this message. (%(code)s)": "Du kan ikke slette denne besked. (%(code)s)", + "Thursday": "Torsdag", + "I understand the risks and wish to continue": "Jeg forstår risikoen og ønsker at fortsætte", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s via %(browserName)s på %(osName)s", + "Back": "Tilbage", + "Show message in desktop notification": "Vis besked i skrivebordsnotifikation", + "Unhide Preview": "Vis Forhåndsvisning", + "Announcements about Synapse releases": "Announceringer om Synapse udgivelser", + "Search the room directory": "Søg i rumkataloget", + "Please describe the bug and/or send logs.": "Beskriv venligst fejlen og/eller send logs.", + "Unable to join network": "Kan ikke forbinde til netværket", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Du har muligvis konfigureret dem i en anden klient end Riot. Du kan ikke tune dem i Riot, men de gælder stadig", + "Sorry, your browser is not able to run Riot.": "Beklager, din browser kan ikke køre Riot.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Decentraliseret, krypteret chat & samarbejde baseret på [matrix]", + "Quote": "Citat", + "Messages in group chats": "Beskeder i gruppechats", + "Yesterday": "I går", + "Error encountered (%(errorDetail)s).": "En fejl er opstået (%(errorDetail)s).", + "Event Type": "Begivenhedstype", + "Low Priority": "Lav prioritet", + "Unable to fetch notification target list": "Kan ikke hente meddelelsesmålliste", + "Appear Offline": "Fremstå Offline", + "Get started with some tips from Riot Bot!": "Kom godt i gang med nogle tips fra Riot Bot!", + "Set Password": "Indstil Password", + "Enable audible notifications in web client": "Aktivér hørbare underretninger i webklienten", + "Permalink": "Permanent link", + "Welcome to Riot.im": "Velkommen til Riot.im", + "Resend": "Send igen", + "Riot does not know how to join a room on this network": "Riot ved ikke, hvordan man kan deltage i et rum på dette netværk", + "Mentions only": "Kun nævninger", + "Failed to remove tag %(tagName)s from room": "Kunne ikke fjerne tag(s): %(tagName)s fra rummet", + "Wednesday": "Onsdag", + "You can now return to your account after signing out, and sign in on other devices.": "Du kan nu vende tilbage til din konto efter at have logget ud og logge ind på andre enheder.", + "Enable desktop notifications": "Aktivér desktop meddelelser", + "Enable email notifications": "Aktivér e-mail-underretninger", + "Login": "Log ind", + "Download this file": "Download denne fil", + "Pin Message": "Fasthold Besked", + "Failed to change settings": "Kunne ikke ændre indstillinger", + "Developer Tools": "Udviklingsværktøjer", + "Matrix technical discussions": "Matrix tekniske diskussioner", + "Event Content": "Begivenhedsindhold", + "Thank you!": "Tak!", + "Building services on Matrix": "Bygning af tjenester på Matrix", + "Collapse panel": "Slå panel sammen", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Med din nuværnde broser kan udseendet og fornemmelsen af programmet være helt forkert og nogle funktioner virker måske ikke. Hvis du alligevel vil prøve så kan du fortsætte, men det er på egen risiko!", + "Checking for an update...": "Checker om der er en opdatering...", + "General discussion about Matrix and Riot": "Generel diskussion om Matrix og Riot", + "There are advanced notifications which are not shown here": "Der er avancerede meddelelser, som ikke vises her" } diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index e67c9fcaaa..b28cfdce1c 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -1003,5 +1003,207 @@ "Unable to leave community": "Community konnte nicht verlassen werden", "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Änderungen am Namen und Bild deiner Community werden evtl. erst nach 30 Minuten von anderen Nutzern gesehen werden.", "Join this community": "Community beitreten", - "Leave this community": "Community verlassen" + "Leave this community": "Community verlassen", + "Fetching third party location failed": "Das Abrufen des Drittanbieterstandorts ist fehlgeschlagen", + "A new version of Riot is available.": "Eine neue Version von Riot ist verfügbar.", + "Riot/Android & matrix-android-sdk chat": "Riot-Android & matrix-android-sdk-Chat", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Bitte den Softwarefehler (vorzugsweise auf Englisch) beschreiben. Was hast du gemacht? Was sollte passieren? Was ist tatsächlich passiert?", + "Couldn't load home page": "Startseite konnte nicht geladen werden", + "Send Account Data": "Benutzerkonto-Daten senden", + "All notifications are currently disabled for all targets.": "Aktuell sind alle Benachrichtigungen für alle Ziele deaktiviert.", + "Uploading report": "Lade Bericht hoch", + "Sunday": "Sonntag", + "Notification targets": "Benachrichtigungsziele", + "Today": "Heute", + "Files": "Dateien", + "Report a bug": "Einen Softwarefehler melden", + "Implementing VR services with Matrix": "Implementierung von VR-Diensten mit Matrix", + "You are not receiving desktop notifications": "Du erhältst keine Desktop-Benachrichtigungen", + "Friday": "Freitag", + "Update": "Aktualisieren", + "You need to be using HTTPS to place a screen-sharing call.": "Du musst HTTPS nutzen um einen Anruf mit Bildschirmfreigabe durchzuführen.", + "What's New": "Was ist neu", + "Add an email address above to configure email notifications": "Füge oben eine E-Mail-Adresse hinzu, um die E-Mail-Benachrichtigungseinstellungen zu konfigurieren", + "Expand panel": "Panel ausklappen", + "On": "An", + "%(count)s Members|other": "%(count)s Mitglieder", + "Filter room names": "Raum-Namen filtern", + "Changelog": "Änderungsprotokoll", + "Running Matrix services": "Matrix-Dienste betreiben", + "Waiting for response from server": "Auf Antwort vom Server warten", + "Send Custom Event": "Benutzerdefiniertes Event senden", + "Failed to send report: ": "Senden des Reports fehlgeschlagen: ", + "Unknown device": "Unbekanntes Gerät", + "Advanced notification settings": "Erweiterte Benachrichtigungs-Einstellungen", + "Failed to send logs: ": "Senden von Logs fehlgeschlagen: ", + "delete the alias.": "Lösche den Alias.", + "To return to your account in future you need to set a password": "Um in Zukunft auf dein Benutzerkonto zugreifen zu können, musst du ein Passwort setzen", + "Forget": "Entfernen", + "#example": "#Beispiel", + "Riot/Web & Desktop chat": "Riot/Web & Desktop-Chat", + "Hide panel": "Panel verbergen", + "You cannot delete this image. (%(code)s)": "Das Bild kann nicht gelöscht werden. (%(code)s)", + "Cancel Sending": "Senden abbrechen", + "This Room": "In diesem Raum", + "The Home Server may be too old to support third party networks": "Der Home-Server ist eventuell zu alt, um Drittanbieter-Netzwerke zu unterstützen", + "Resend": "Erneut senden", + "Room not found": "Raum nicht gefunden", + "Messages containing my display name": "Nachrichten, die meinen Anzeigenamen enthalten", + "Messages in one-to-one chats": "Nachrichten in Einzel-Chats", + "Contributing code to Matrix and Riot": "Code zu Matrix und Riot beitragen", + "Unavailable": "Nicht verfügbar", + "Community-run support for Synapse": "Support für Synapse von der Community", + "View Decrypted Source": "Entschlüsselten Quellcode ansehen", + "Failed to update keywords": "Schlüsselwörter konnten nicht aktualisiert werden", + "Notes:": "Notizen:", + "remove %(name)s from the directory.": "entferne %(name)s aus dem Verzeichnis.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Die Benachrichtigungen zu den folgenden Schlüsselwörtern folgen Regeln, die hier nicht angezeigt werden können:", + "Safari and Opera work too.": "Safari und Opera sind weitere Alternativen.", + "Please set a password!": "Bitte setze ein Passwort!", + "You have successfully set a password!": "Du hast erfolgreich ein Passwort gesetzt!", + "Chat with Riot Bot": "Mit dem Riot-Bot chatten", + "Support for those using, running and writing other bridges": "Unterstützung für die, die andere Matrix-Bridges nutzen, betreiben oder entwickeln", + "Admin support for Dendrite": "Admin-Unterstützung für Dendrite", + "An error occurred whilst saving your email notification preferences.": "Beim Speichern deiner E-Mail-Benachrichtigungseinstellungen ist ein Fehler aufgetreten.", + "Explore Room State": "Raum-Status erkunden", + "Source URL": "Quell-URL", + "Messages sent by bot": "Nachrichten von Bots", + "Filter results": "Ergebnisse filtern", + "Members": "Mitglieder", + "No update available.": "Kein Update verfügbar.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Im Matrix-Netzwerk existieren bereits jetzt zahlreiche Räume, die entweder mit bekannten Netzwerken wie Slack, IRC, Gitter, usw. verknüpft sind oder auch komplett eigenständig betrieben werden. Einen genauen Überblick erhältst du im Raum-Verzeichnis!", + "Noisy": "Laut", + "Failed to get protocol list from Home Server": "Fehler beim Abrufen der Protokoll-Liste vom Home-Server", + "Collecting app version information": "App-Versionsinformationen werden abgerufen", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Soll der Raum-Alias %(alias)s gelöscht und der %(name)s aus dem Verzeichnis entfernt werden?", + "customServer_text": "Du kannst die erweiterten Server-Optionen nutzen, um dich auf anderen Matrix-Servern anzumelden, indem du eine andere Heimserver-URL eingibst.
    Dies ermöglicht es dir, Riot mit einem bereits existierenden Matrix-Konto auf einem anderen Heimserver zu nutzen.

    Du kannst auch einen benutzerdefinierten Identitäts-Server eingeben, allerdings wirst du dann nicht in der Lage sein, andere Benutzer per E-Mail-Adresse einzuladen oder selbst Einladungen per E-Mail-Adresse zu erhalten.", + "Co-ordination for Riot/Web translators": "Koordination für Riot/Web-Übersetzer", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Dies erlaubt dir, dich wieder an deinem Konto anzumelden, nachdem du dich abgemeldet hast.", + "Dev chat for the Dendrite dev team": "Entwickler-Chat für das Dendrite-Entwickler-Team", + "Keywords": "Schlüsselwörter", + "Enable notifications for this account": "Benachrichtigungen für dieses Benutzerkonto aktivieren", + "Directory": "Raum-Verzeichnis", + "Invite to this community": "In diese Community einladen", + "Failed to get public room list": "Die Liste der öffentlichen Räume konnte nicht geladen werden", + "Messages containing keywords": "Nachrichten, die Schlüsselwörter enthalten", + "Error saving email notification preferences": "Fehler beim Speichern der E-Mail-Benachrichtigungseinstellungen", + "Tuesday": "Dienstag", + "Enter keywords separated by a comma:": "Schlüsselwörter kommagetrennt eingeben:", + "Forward Message": "Nachricht weiterleiten", + "You have successfully set a password and an email address!": "Du hast erfolgreich ein Passwort und eine E-Mail-Adresse gesetzt!", + "Remove %(name)s from the directory?": "Soll der Raum %(name)s aus dem Verzeichnis entfernt werden?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot nutzt zahlreiche fortgeschrittene Browser-Funktionen, die teilweise in deinem aktuell verwendeten Browser noch nicht verfügbar sind oder sich noch im experimentellen Status befinden.", + "Developer Tools": "Entwicklerwerkzeuge", + "Preparing to send logs": "Senden von Logs wird vorbereitet", + "Enable desktop notifications": "Desktop-Benachrichtigungen aktivieren", + "Remember, you can always set an email address in user settings if you change your mind.": "Vergiss nicht, dass du in den Benutzereinstellungen jederzeit eine E-Mail-Adresse setzen kannst, wenn du deine Meinung änderst.", + "Explore Account Data": "Benutzerkonto-Daten analysieren", + "All messages (noisy)": "Alle Nachrichten (laut)", + "Away": "Abwesend", + "Saturday": "Samstag", + "I understand the risks and wish to continue": "Ich verstehe das Risiko und möchte fortfahren", + "Direct Chat": "Direkt-Chat", + "The server may be unavailable or overloaded": "Der Server ist vermutlich nicht erreichbar oder überlastet", + "Reject": "Ablehnen", + "Riot is not supported on mobile web. Install the app?": "Riot wird im mobilen Web nicht unterstützt. App installieren?", + "Discussion of all things Matrix!": "\"Diskussion über alle Dinge\"-Matrix!", + "Failed to set Direct Message status of room": "Konnte den direkten Benachrichtigungsstatus nicht setzen", + "Monday": "Montag", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Zur Diagnose von Softwareproblemen werden mit diesem Fehlerbericht auch Log-Dateien übermittelt. Wenn nur der oben eingegebene Text übermittelt werden soll, bitte die nachfolgende Auswahl entsprechend abwählen:", + "Send Custom State Event": "Benutzerdefiniertes Status-Event senden", + "Remove from Directory": "Aus dem Raum-Verzeichnis entfernen", + "Enable them now": "Aktiviere diese jetzt", + "Messages containing my user name": "Nachrichten, die meinen Benutzernamen enthalten", + "Describe your problem here.": "Beschreibe dein Problem hier.", + "Toolbox": "Werkzeugkasten", + "Collecting logs": "Protokolle werden abgerufen", + "more": "mehr", + "GitHub issue link:": "Link des GitHub-Problems:", + "Bug report sent": "Fehlerbericht wurde gesendet", + "You must specify an event type!": "Du musst einen Event-Typ spezifizieren!", + "(HTTP status %(httpStatus)s)": "(HTTP-Status %(httpStatus)s)", + "Invite to this room": "In diesen Raum einladen", + "Please install Chrome or Firefox for the best experience.": "Bitte installiere Chrome oder Firefox für ein optimales Anwendungsergebnis.", + "Wednesday": "Mittwoch", + "You cannot delete this message. (%(code)s)": "Diese Nachricht kann nicht gelöscht werden. (%(code)s)", + "Quote": "Zitat", + "Send logs": "Logdateien übermitteln", + "All messages": "Alle Nachrichten", + "Implementing VoIP services with Matrix": "Implementierung von VoIP-Diensten mit Matrix", + "Dev chat for the Riot/Web dev team": "Entwickler-Chat für das Riot/Web-Entwickler-Team", + "Call invitation": "Anruf-Einladung", + "Riot Desktop on %(platformName)s": "Riot Desktop auf %(platformName)s", + "Downloading update...": "Update wird heruntergeladen...", + "State Key": "Status-Schlüssel", + "Failed to send custom event.": "Senden des benutzerdefinierten Events fehlgeschlagen.", + "What's new?": "Was ist neu?", + "Discussion of the Identity Service API": "Diskussion der Identitätsdienst-API", + "Support for those using and running matrix-appservice-irc": "Unterstützung für die, die \"matrix-appservice-irc\" betreiben und nutzen", + "Riot/iOS & matrix-ios-sdk chat": "Riot-iOS & \"matrix-ios-sdk\"-Chat", + "Notify me for anything else": "Über alles andere benachrichtigen", + "When I'm invited to a room": "Wenn ich in einen Raum eingeladen werde", + "Design and implementation of E2E in Matrix": "Design und Implementierung von Ende-zu-Ende-Verschlüsselung in Matrix", + "Click here to create a GitHub issue.": "Klicke hier um ein GithHub-Problem zu erstellen.", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Die benutzerdefinierten Server-Einstellungen kannst du verwenden, um dich auf anderen Matrix-Servern anzumelden, indem du eine abweichende Heimserver-URL eingibst.
    Somit ist es möglich, Riot mit einem bereits bestehendem Matrix-Benutzerkonto auf einem anderen Heimserver zu verwenden.

    Außerdem kannst du einen benutzerdefinierten Identitätsserver eingeben. Allerdings kannst du in diesem Fall Benutzer nicht mehr per E-Mail-Adresse einladen und auch selbst nicht mehr per E-Mail-Adresse eingeladen werden.", + "Can't update user notification settings": "Benachrichtigungs-Einstellungen des Benutzers konnten nicht aktualisiert werden", + "Notify for all other messages/rooms": "Benachrichtigungen für alle anderen Mitteilungen/Räume aktivieren", + "Unable to look up room ID from server": "Es ist nicht möglich, die Raum-ID auf dem Server nachzuschlagen", + "Couldn't find a matching Matrix room": "Konnte keinen entsprechenden Matrix-Raum finden", + "Support for those using the Matrix spec": "Unterstützung für die Nutzer der Matrix-Spezification", + "Safari and Opera work too.": "Safari und Opera funktionieren ebenfalls.", + "Loading bug report module": "Lade Fehlerbericht-Modul", + "All Rooms": "In allen Räumen", + "Search for a room": "Nach einem Raum suchen", + "Thursday": "Donnerstag", + "Search…": "Suchen…", + "Logs sent": "Logs gesendet", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s via %(browserName)s auf %(osName)s", + "Back": "Zurück", + "Reply": "Antworten", + "Show message in desktop notification": "Nachricht in der Desktop-Benachrichtigung anzeigen", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Fehlerberichte enthalten Anwendungsdaten wie deinen Nutzernamen, Raum- und Gruppen-ID's und Aliase die du besucht hast sowie Nutzernamen anderer Nutzer. Sie enthalten keine Nachrichten.", + "Unhide Preview": "Vorschau wieder anzeigen", + "Announcements about Synapse releases": "Ankündigungen über Synapse-Versionen", + "Search the room directory": "Raum-Verzeichnis durchsuchen", + "Please describe the bug and/or send logs.": "Bitte den Fehler beschreiben und/oder Log-Dateien übermitteln.", + "Unable to join network": "Es ist nicht möglich, dem Netzwerk beizutreten", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Du hast sie eventuell auf einem anderen Matrix-Client und nicht in Riot konfiguriert. Sie können in Riot nicht verändert werden, gelten aber trotzdem", + "Sorry, your browser is not able to run Riot.": "Es tut uns leid, aber dein Browser kann Riot nicht ausführen.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Dezentrale, verschlüsselte Chat- & Kollaborationslösung unterstützt von [matrix]", + "Building services on Matrix": "Dienste für Matrix entwickeln", + "Messages in group chats": "Nachrichten in Gruppen-Chats", + "Yesterday": "Gestern", + "Error encountered (%(errorDetail)s).": "Es ist ein Fehler aufgetreten (%(errorDetail)s).", + "Login": "Anmeldung", + "Low Priority": "Niedrige Priorität", + "Unable to fetch notification target list": "Liste der Benachrichtigungsempfänger konnte nicht abgerufen werden", + "Appear Offline": "Als offline anzeigen", + "Get started with some tips from Riot Bot!": "Lass Dir vom Riot-Bot eine Einführung geben!", + "Set Password": "Passwort einrichten", + "Enable audible notifications in web client": "Audio-Benachrichtigungen im Web-Client aktivieren", + "Permalink": "Permanenter Link", + "Welcome to Riot.im": "Willkommen bei Riot.im", + "Off": "Aus", + "Riot does not know how to join a room on this network": "Riot weiß nicht, wie es einem Raum auf diesem Netzwerk beitreten soll", + "Mentions only": "Nur, wenn du erwähnt wirst", + "You can now return to your account after signing out, and sign in on other devices.": "Du kannst nun zu deinem Benutzerkonto zurückkehren, nachdem du dich abgemeldet hast. Anschließend kannst du dich an anderen Geräten anmelden.", + "Please install Chrome or Firefox for the best experience.": "Bitte installiere Chrome oder Firefox für die beste Erfahrung.", + "Enable email notifications": "E-Mail-Benachrichtigungen aktivieren", + "Event Type": "Event-Typ", + "Download this file": "Datei herunterladen", + "Pin Message": "Nachricht anheften", + "Failed to change settings": "Einstellungen konnten nicht geändert werden", + "View Community": "Community ansehen", + "%(count)s Members|one": "%(count)s Mitglied", + "Event sent!": "Event gesendet!", + "View Source": "Quellcode ansehen", + "Matrix technical discussions": "Technische Diskussion über Matrix", + "Event Content": "Event-Inhalt", + "Thank you!": "Danke!", + "Uploaded on %(date)s by %(user)s": "Hochgeladen: %(date)s von %(user)s", + "Collapse panel": "Panel einklappen", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "In deinem aktuell verwendeten Browser können Aussehen und Handhabung der Anwendung unter Umständen noch komplett fehlerhaft sein, so dass einige bzw. im Extremfall alle Funktionen nicht zur Verfügung stehen. Du kannst es trotzdem versuchen und fortfahren, bist dabei aber bezüglich aller auftretenden Probleme auf dich allein gestellt!", + "Checking for an update...": "Nach Updates suchen...", + "General discussion about Matrix and Riot": "Allgemeine Diskussion über Matrix und Riot", + "There are advanced notifications which are not shown here": "Es existieren erweiterte Benachrichtigungen, welche hier nicht angezeigt werden" } diff --git a/src/i18n/strings/el.json b/src/i18n/strings/el.json index ab16f215bc..726b81ac9b 100644 --- a/src/i18n/strings/el.json +++ b/src/i18n/strings/el.json @@ -643,5 +643,180 @@ "Your unverified device '%(displayName)s' is requesting encryption keys.": "Η ανεπιβεβαίωτη συσκευή σας '%(displayName)s' ζητά κλειδιά κρυπτογράφησης.", "Encryption key request": "Αίτημα κλειδιού κρυπτογράφησης", "Updates": "Ενημερώσεις", - "Check for update": "Έλεγχος για ενημέρωση" + "Check for update": "Έλεγχος για ενημέρωση", + "Fetching third party location failed": "Η λήψη τοποθεσίας απέτυχε", + "A new version of Riot is available.": "Μία νέα έκδοση του Riot είναι διαθέσιμη.", + "Riot/Android & matrix-android-sdk chat": "Συζήτηση για το Riot/Android & matrix-android-sdk", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Παρακαλούμε περιγράψτε το σφάλμα. Τι κάνατε; Τι περιμένατε να συμβεί; Τι έγινε τελικά;", + "All notifications are currently disabled for all targets.": "Όλες οι ειδοποιήσεις είναι προς το παρόν απενεργοποιημένες για όλες τις συσκευές.", + "Uploading report": "Αποστολή αναφοράς", + "Sunday": "Κυριακή", + "Guests can join": "Επισκέπτες μπορούν να συνδεθούν", + "Failed to add tag %(tagName)s to room": "Δεν ήταν δυνατή η προσθήκη της ετικέτας %(tagName)s στο δωμάτιο", + "Notification targets": "Στόχοι ειδοποιήσεων", + "Failed to set direct chat tag": "Δεν ήταν δυνατός ο χαρακτηρισμός της συνομιλίας ως 1-προς-1", + "Today": "Σήμερα", + "Files": "Αρχεία", + "Report a bug": "Αναφορά σφάλματος", + "Implementing VR services with Matrix": "Υλοποίηση υπηρεσίων VR με το Matrix", + "You are not receiving desktop notifications": "Δεν λαμβάνετε ειδοποιήσεις στην επιφάνεια εργασίας", + "Friday": "Παρασκευή", + "Update": "Ενημέρωση", + "You need to be using HTTPS to place a screen-sharing call.": "Απαιτείται η χρήση HTTPS για το διαμοιρασμό της επιφάνειας εργασίας μέσω κλήσης.", + "Riot does not know how to join a room on this network": "To Riot δεν γνωρίζει πως να συνδεθεί σε δωμάτια που ανήκουν σ' αυτό το δίκτυο", + "Add an email address above to configure email notifications": "Προσθέστε μια διεύθυνση ηλεκτρονικής αλληλογραφίας στο παραπάνω πεδίο, για να έχετε τη δυνατότητα να λαμβάνετε ειδοποιήσεις", + "Expand panel": "Μεγιστοποίηση καρτέλας", + "On": "Ενεργό", + "Filter room names": "Φιλτράρισμα δωματίων", + "Changelog": "Αλλαγές", + "Running Matrix services": "Χρησιμοποιώντας τις υπηρεσίες του Matrix", + "Waiting for response from server": "Αναμονή απάντησης από τον διακομιστή", + "Leave": "Αποχώρηση", + "Uploaded on %(date)s by %(user)s": "Απεστάλη στις %(date)s από %(user)s", + "Failed to send report: ": "Δεν ήταν δυνατή η αποστολή της αναφοράς: ", + "Unknown device": "Άγνωστη συσκευή", + "Advanced notification settings": "Προχωρημένες ρυθμίσεις ειδοποιήσεων", + "delete the alias.": "διέγραψε το ψευδώνυμο.", + "To return to your account in future you need to set a password": "Για να επιστρέψετε στον λογαριασμό σας μελλοντικα πρέπει να ορίσετε έναν κωδικό πρόσβασης", + "Forget": "Παράλειψη", + "World readable": "Εμφανές σε όλους", + "Riot/Web & Desktop chat": "Συζήτηση για το Riot/Web & Desktop", + "Hide panel": "Απόκρυψη καρτέλας", + "You cannot delete this image. (%(code)s)": "Δεν μπορείτε να διαγράψετε αυτή την εικόνα. (%(code)s)", + "Cancel Sending": "Ακύρωση αποστολής", + "Warning": "Προειδοποίηση", + "This Room": "Στο δωμάτιο", + "The Home Server may be too old to support third party networks": "Ο διακομιστής μπορεί να είναι αρκετά παλιός για να υποστηρίζει δίκτυα τρίτων", + "Resend": "Αποστολή ξανά", + "Room not found": "Το δωμάτιο δεν βρέθηκε", + "Messages containing my display name": "Μηνύματα που περιέχουν το όνομα μου", + "Messages in one-to-one chats": "Μηνύματα σε 1-προς-1 συνομιλίες", + "Contributing code to Matrix and Riot": "Συνεισφορά κώδικα στο Matrix και Riot", + "Unavailable": "Μη διαθέσιμο", + "Community-run support for Synapse": "Κοινοτική υποστήριξη για το Synapse", + "View Decrypted Source": "Προβολή του αποκρυπτογραφημένου κώδικα", + "Send": "Αποστολή", + "remove %(name)s from the directory.": "αφαίρεση του %(name)s από το ευρετήριο.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Οι ειδοποιήσεις για τις επόμενες λέξεις κλειδία ακολουθούν κανόνες που δεν είναι δυνατόν να εμφανιστούν εδώ:", + "Please set a password!": "Παρακαλούμε ορίστε έναν κωδικό πρόσβασης!", + "You have successfully set a password!": "Ο κωδικός πρόσβασης ορίστηκε επιτυχώς!", + "Chat with Riot Bot": "Συνομιλία με το Riot Bot", + "Support for those using, running and writing other bridges": "Υποστήριξη για τους χρήστες που χρησιμοποιούν ή αναπτύσσουν εφαρμογές ενσωμάτωσης για το Matrix", + "Admin support for Dendrite": "Υποστήριξη διαχειριστή για το Dendrite", + "An error occurred whilst saving your email notification preferences.": "Ένα σφάλμα προέκυψε κατά την αποθήκευση των ρυθμίσεων σας.", + "Source URL": "Πηγαίο URL", + "Messages sent by bot": "Μηνύματα από bots", + "Members": "Μέλη", + "No update available.": "Δεν υπάρχει διαθέσιμη ενημέρωση.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Αρκετά δωμάτια υπάρχουν ήδη στο Matrix, συνδεδεμένα σε υπάρχοντα δίκτυα (Slack, IRC, Gitter κ.λπ) ή αυτόνομα. Ρίξτε μια ματιά στο ευρετήριο!", + "Noisy": "Δυνατά", + "Failed to get protocol list from Home Server": "Δεν ήταν δυνατή η εύρεση των διαθέσιμων πρωτοκόλλων από το διακομιστή", + "Collecting app version information": "Συγκέντρωση πληροφοριών σχετικά με την έκδοση της εφαρμογής", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Διαγραφή του ψευδώνυμου %(alias)s και αφαίρεση του %(name)s από το ευρετήριο;", + "customServer_text": "Μπορείτε να χρησιμοποιήσετε τις προσαρμοσμένες ρυθμίσεις για να εισέλθετε σε άλλους διακομιστές Matrix επιλέγοντας μια διαφορετική διεύθυνση για το διακομιστή.
    Αυτό σας επιτρέπει να χρησιμοποιήσετε την εφαρμογή Riot με έναν υπάρχοντα λογαριασμό σε διαφορετικό διακομιστή.

    Επίσης μπορείτε να επιλέξετε ένα διαφορετικό διακομιστή ταυτότητας αλλά δεν θα έχετε τη δυνατότητα να προσκαλέσετε άλλους χρήστες ή να σας προσκαλέσουν μέσω μηνυμάτων ηλεκτρονικής αλληλογραφίας.", + "Co-ordination for Riot/Web translators": "Συντονισμός για μεταφραστές του Riot/Web", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Αυτό θα σας επιτρέψει να επιστρέψετε στον λογαριασμό σας αφού αποσυνδεθείτε και συνδεθείτε από άλλες συσκευές.", + "Dev chat for the Dendrite dev team": "Συζήτηση με την ομάδα ανάπτυξης του Dendrite", + "Keywords": "Λέξεις κλειδιά", + "Enable notifications for this account": "Ενεργοποίηση ειδοποιήσεων για τον λογαριασμό", + "Directory": "Ευρετήριο", + "Search for a room": "Αναζήτηση δωματίου", + "Messages containing keywords": "Μηνύματα που περιέχουν λέξεις κλειδιά", + "Error saving email notification preferences": "Σφάλμα κατά την αποθήκευση των προτιμήσεων", + "Tuesday": "Τρίτη", + "Enter keywords separated by a comma:": "Προσθέστε λέξεις κλειδιά χωρισμένες με κόμμα:", + "I understand the risks and wish to continue": "Κατανοώ του κινδύνους και επιθυμώ να συνεχίσω", + "Remove %(name)s from the directory?": "Αφαίρεση του %(name)s από το ευρετήριο;", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Το Riot χρησιμοποιεί αρκετά προχωρημένα χαρακτηριστικά των περιηγητών Ιστού, ορισμένα από τα οποία δεν είναι διαθέσιμα ή είναι σε πειραματικό στάδιο στον περιηγητή σας.", + "Please install Chrome or Firefox for the best experience.": "Παρακαλούμε εγκαταστήστε έναν από τους περιηγητές Chrome ή Firefox για την καλύτερη δυνατή εμπειρία.", + "Unnamed room": "Ανώνυμο δωμάτιο", + "Remove from Directory": "Αφαίρεση από το ευρετήριο", + "Saturday": "Σάββατο", + "Remember, you can always set an email address in user settings if you change your mind.": "Να θυμάστε ότι μπορείτε πάντα να ορίσετε μια διεύθυνση ηλεκτρονικής αλληλογραφίας στις ρυθμίσεις χρήστη αν αλλάξετε γνώμη.", + "Direct Chat": "Απευθείας συνομιλία", + "The server may be unavailable or overloaded": "Ο διακομιστής είναι μη διαθέσιμος ή υπερφορτωμένος", + "Reject": "Απόρριψη", + "Riot is not supported on mobile web. Install the app?": "Το Riot δεν υποστηρίζεται από περιηγητές κινητών. Θέλετε να εγκαταστήσετε την εφαρμογή;", + "Discussion of all things Matrix!": "Συζήτηση για όλα τα πράγματα του Matrix!", + "Failed to set Direct Message status of room": "Δεν ήταν δυνατός ο ορισμός της κατάστασης Direct Message του δωματίου", + "Monday": "Δευτέρα", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Προκειμένου να διαγνωστούν προβλήματα, τα αρχεία καταγραφής από αυτόν τον πελάτη θα σταλούν με αυτήν την αναφορά σφάλματος. Αν προτιμάτε να στείλετε μόνο το παραπάνω κείμενο, απενεργοποιήστε:", + "All messages (noisy)": "Όλα τα μηνύματα (δυνατά)", + "Enable them now": "Ενεργοποίηση", + "Forward Message": "Προώθηση", + "Describe your problem here.": "Περιγράψτε το πρόβλημα σας εδώ.", + "Messages containing my user name": "Μηνύματα που περιέχουν το ψευδώνυμο μου", + "Collecting logs": "Συγκέντρωση πληροφοριών", + "more": "περισσότερα", + "Failed to get public room list": "Δεν ήταν δυνατή η λήψη της λίστας με τα δημόσια δωμάτια", + "(HTTP status %(httpStatus)s)": "(Κατάσταση HTTP %(httpStatus)s)", + "All Rooms": "Όλα τα δωμάτια", + "Wednesday": "Τετάρτη", + "Failed to update keywords": "Οι λέξεις κλειδιά δεν ενημερώθηκαν", + "Send logs": "Αποστολή πληροφοριών", + "All messages": "Όλα τα μηνύματα", + "Implementing VoIP services with Matrix": "Υλοποίηση υπηρεσίων VoIP με το Matrix", + "Dev chat for the Riot/Web dev team": "Συζήτηση με την ομάδα ανάπτυξης του Riot/Web", + "Call invitation": "Πρόσκληση σε κλήση", + "Riot Desktop on %(platformName)s": "Riot Desktop σε %(platformName)s", + "Downloading update...": "Γίνεται λήψη της ενημέρωσης...", + "You have successfully set a password and an email address!": "Ο κωδικός πρόσβασης και η διεύθυνση ηλεκτρονικής αλληλογραφίας ορίστηκαν επιτυχώς!", + "What's new?": "Τι νέο υπάρχει;", + "Discussion of the Identity Service API": "Συζήτηση σχετικά με το Identity Service API", + "Support for those using and running matrix-appservice-irc": "Υποστήριξη για τους χρήστες που χρησιμοποιούν το matrix-appservice-irc", + "Riot/iOS & matrix-ios-sdk chat": "Συζήτηση για το Riot/iOS & matrix-ios-sdk", + "Notify me for anything else": "Ειδοποίηση για οτιδήποτε άλλο", + "When I'm invited to a room": "Όταν με προσκαλούν σ' ένα δωμάτιο", + "Design and implementation of E2E in Matrix": "Σχεδιασμός και υλοποίηση του E2E στο Matrix", + "Can't update user notification settings": "Δεν είναι δυνατή η ενημέρωση των ρυθμίσεων ειδοποίησης χρήστη", + "Notify for all other messages/rooms": "Ειδοποίηση για όλα τα υπόλοιπα μηνύματα/δωμάτια", + "Unable to look up room ID from server": "Δεν είναι δυνατή η εύρεση του ID για το δωμάτιο", + "Couldn't find a matching Matrix room": "Δεν βρέθηκε κάποιο δωμάτιο", + "Support for those using the Matrix spec": "Υποστήριξη για τους χρήστες που χρησιμοποιούν το Matrix spec", + "Safari and Opera work too.": "Safari και Opera λειτουργούν επίσης.", + "Loading bug report module": "Φόρτωση μονάδας αναφοράς σφαλμάτων", + "Invite to this room": "Πρόσκληση σε αυτό το δωμάτιο", + "You cannot delete this message. (%(code)s)": "Δεν μπορείτε να διαγράψετε αυτό το μήνυμα. (%(code)s)", + "Thursday": "Πέμπτη", + "Search…": "Αναζήτηση…", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s μέσω %(browserName)s σε %(osName)s", + "Unhide Preview": "Προεπισκόπηση", + "Announcements about Synapse releases": "Ανακοινώσεις σχετικά με τις εκδόσεις του Synapse", + "Search the room directory": "Αναζήτηση του ευρετηρίου δωματίων", + "Please describe the bug and/or send logs.": "Παρακαλούμε περιγράψτε το σφάλμα και/ή στείλτε πληροφορίες σχετικά με την εφαρμογή.", + "Unable to join network": "Δεν είναι δυνατή η σύνδεση στο δίκτυο", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Ισως να έχετε κάνει τις ρυθμίσεις σε άλλη εφαρμογή εκτός του Riot. Δεν μπορείτε να τις αλλάξετε μέσω του Riot αλλά ισχύουν κανονικά", + "Sorry, your browser is not able to run Riot.": "Λυπούμαστε, αλλά ο περιηγητές σας δεν υποστηρίζεται από το Riot.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Αποκεντρωμένη, κρυπτογραφημένη συνομιλία & συνεργασία με τη βοήθεια του [matrix]", + "Building services on Matrix": "Ανάπτυξη υπηρεσιών στο Matrix", + "Messages in group chats": "Μηνύματα σε ομαδικές συνομιλίες", + "Yesterday": "Χθές", + "Error encountered (%(errorDetail)s).": "Παρουσιάστηκε σφάλμα (%(errorDetail)s).", + "Low Priority": "Χαμηλή προτεραιότητα", + "What's New": "Τι νέο υπάρχει", + "Get started with some tips from Riot Bot!": "Ξεκινήστε με μερικές συμβουλές από το Riot Bot!", + "Set Password": "Ορισμός κωδικού πρόσβασης", + "Enable audible notifications in web client": "Ενεργοποίηση ηχητικών ειδοποιήσεων", + "Permalink": "Μόνιμος σύνδεσμος", + "Welcome to Riot.im": "Καλώς ήλθατε στο Riot.im", + "Off": "Ανενεργό", + "#example": "#παράδειγμα", + "Mentions only": "Μόνο αναφορές", + "Failed to remove tag %(tagName)s from room": "Δεν ήταν δυνατή η διαγραφή της ετικέτας %(tagName)s από το δωμάτιο", + "You can now return to your account after signing out, and sign in on other devices.": "Μπορείτε να επιστρέψετε στον λογαριασμό σας αφού αποσυνδεθείτε και συνδεθείτε από άλλες συσκευές.", + "Enable desktop notifications": "Ενεργοποίηση ειδοποιήσεων στην επιφάνεια εργασίας", + "Enable email notifications": "Ενεργοποίηση ειδοποιήσεων μέσω μηνυμάτων ηλ. αλληλογραφίας", + "Login": "Σύνδεση", + "No rooms to show": "Δεν υπάρχουν δωμάτια για εμφάνιση", + "Download this file": "Λήψη αρχείου", + "Failed to change settings": "Δεν ήταν δυνατή η αλλαγή των ρυθμίσεων", + "View Source": "Προβολή κώδικα", + "Matrix technical discussions": "Τεχνικές συζητήσεις σχετικά με το Matrix", + "Unable to fetch notification target list": "Δεν ήταν δυνατή η εύρεση στόχων για τις ειδοποιήσεις", + "Quote": "Παράθεση", + "Collapse panel": "Ελαχιστοποίηση καρτέλας", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Με τον τρέχον περιηγητή, η εμφάνιση και η αίσθηση της εφαρμογής ενδέχεται να είναι εντελώς εσφαλμένη και ορισμένες ή όλες οι λειτουργίες ενδέχεται να μην λειτουργούν. Εάν θέλετε να το δοκιμάσετε ούτως ή άλλως μπορείτε να συνεχίσετε, αλλά είστε μόνοι σας σε ό, τι αφορά τα προβλήματα που μπορεί να αντιμετωπίσετε!", + "Checking for an update...": "Γίνεται έλεγχος για ενημέρωση...", + "General discussion about Matrix and Riot": "Γενική συζήτηση σχετικά με Matrix και Riot", + "There are advanced notifications which are not shown here": "Υπάρχουν προχωρημένες ειδοποιήσεις οι οποίες δεν εμφανίζονται εδώ" } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 5deefc546b..df15766ae1 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1009,5 +1009,195 @@ "Import": "Import", "Failed to set direct chat tag": "Failed to set direct chat tag", "Failed to remove tag %(tagName)s from room": "Failed to remove tag %(tagName)s from room", - "Failed to add tag %(tagName)s to room": "Failed to add tag %(tagName)s to room" + "Failed to add tag %(tagName)s to room": "Failed to add tag %(tagName)s to room", + "Fetching third party location failed": "Fetching third party location failed", + "A new version of Riot is available.": "A new version of Riot is available.", + "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk chat", + "Couldn't load home page": "Couldn't load home page", + "Send Account Data": "Send Account Data", + "All notifications are currently disabled for all targets.": "All notifications are currently disabled for all targets.", + "Uploading report": "Uploading report", + "Sunday": "Sunday", + "Notification targets": "Notification targets", + "Today": "Today", + "Files": "Files", + "Implementing VR services with Matrix": "Implementing VR services with Matrix", + "You are not receiving desktop notifications": "You are not receiving desktop notifications", + "Friday": "Friday", + "Update": "Update", + "You need to be using HTTPS to place a screen-sharing call.": "You need to be using HTTPS to place a screen-sharing call.", + "Unable to fetch notification target list": "Unable to fetch notification target list", + "Add an email address above to configure email notifications": "Add an email address above to configure email notifications", + "Expand panel": "Expand panel", + "On": "On", + "%(count)s Members|other": "%(count)s Members", + "Filter room names": "Filter room names", + "Changelog": "Changelog", + "Running Matrix services": "Running Matrix services", + "Waiting for response from server": "Waiting for response from server", + "Uploaded on %(date)s by %(user)s": "Uploaded on %(date)s by %(user)s", + "Send Custom Event": "Send Custom Event", + "Unknown device": "Unknown device", + "Advanced notification settings": "Advanced notification settings", + "Failed to send logs: ": "Failed to send logs: ", + "delete the alias.": "delete the alias.", + "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", + "Forget": "Forget", + "Riot/Web & Desktop chat": "Riot/Web & Desktop chat", + "Hide panel": "Hide panel", + "You cannot delete this image. (%(code)s)": "You cannot delete this image. (%(code)s)", + "Cancel Sending": "Cancel Sending", + "This Room": "This Room", + "The Home Server may be too old to support third party networks": "The Home Server may be too old to support third party networks", + "Resend": "Resend", + "Room not found": "Room not found", + "Downloading update...": "Downloading update...", + "Messages in one-to-one chats": "Messages in one-to-one chats", + "Contributing code to Matrix and Riot": "Contributing code to Matrix and Riot", + "Unavailable": "Unavailable", + "Community-run support for Synapse": "Community-run support for Synapse", + "View Decrypted Source": "View Decrypted Source", + "Failed to update keywords": "Failed to update keywords", + "Notes:": "Notes:", + "remove %(name)s from the directory.": "remove %(name)s from the directory.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Notifications on the following keywords follow rules which can’t be displayed here:", + "Safari and Opera work too.": "Safari and Opera work too.", + "Please set a password!": "Please set a password!", + "You have successfully set a password!": "You have successfully set a password!", + "Chat with Riot Bot": "Chat with Riot Bot", + "Support for those using, running and writing other bridges": "Support for those using, running and writing other bridges", + "Admin support for Dendrite": "Admin support for Dendrite", + "Explore Room State": "Explore Room State", + "Source URL": "Source URL", + "Messages sent by bot": "Messages sent by bot", + "Filter results": "Filter results", + "Members": "Members", + "No update available.": "No update available.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!", + "Noisy": "Noisy", + "Failed to get protocol list from Home Server": "Failed to get protocol list from Home Server", + "Collecting app version information": "Collecting app version information", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Delete the room alias %(alias)s and remove %(name)s from the directory?", + "Discussion of all things Matrix!": "Discussion of all things Matrix!", + "Co-ordination for Riot/Web translators": "Co-ordination for Riot/Web translators", + "This will allow you to return to your account after signing out, and sign in on other devices.": "This will allow you to return to your account after signing out, and sign in on other devices.", + "Dev chat for the Dendrite dev team": "Dev chat for the Dendrite dev team", + "Design and implementation of E2E in Matrix": "Design and implementation of E2E in Matrix", + "Enable notifications for this account": "Enable notifications for this account", + "Directory": "Directory", + "Invite to this community": "Invite to this community", + "Failed to get public room list": "Failed to get public room list", + "Search…": "Search…", + "Messages containing keywords": "Messages containing keywords", + "When I'm invited to a room": "When I'm invited to a room", + "Tuesday": "Tuesday", + "Enter keywords separated by a comma:": "Enter keywords separated by a comma:", + "Forward Message": "Forward Message", + "Remove %(name)s from the directory?": "Remove %(name)s from the directory?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.", + "Event sent!": "Event sent!", + "Preparing to send logs": "Preparing to send logs", + "Explore Account Data": "Explore Account Data", + "All messages (noisy)": "All messages (noisy)", + "Away": "Away", + "Saturday": "Saturday", + "Remember, you can always set an email address in user settings if you change your mind.": "Remember, you can always set an email address in user settings if you change your mind.", + "Direct Chat": "Direct Chat", + "The server may be unavailable or overloaded": "The server may be unavailable or overloaded", + "Reject": "Reject", + "Riot is not supported on mobile web. Install the app?": "Riot is not supported on mobile web. Install the app?", + "Error saving email notification preferences": "Error saving email notification preferences", + "Failed to set Direct Message status of room": "Failed to set Direct Message status of room", + "Monday": "Monday", + "Remove from Directory": "Remove from Directory", + "Enable them now": "Enable them now", + "Messages containing my user name": "Messages containing my user name", + "Toolbox": "Toolbox", + "Collecting logs": "Collecting logs", + "more": "more", + "GitHub issue link:": "GitHub issue link:", + "Search for a room": "Search for a room", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.", + "(HTTP status %(httpStatus)s)": "(HTTP status %(httpStatus)s)", + "All Rooms": "All Rooms", + "State Key": "State Key", + "Please install Chrome or Firefox for the best experience.": "Please install Chrome or Firefox for the best experience.", + "Wednesday": "Wednesday", + "Quote": "Quote", + "Send logs": "Send logs", + "All messages": "All messages", + "Implementing VoIP services with Matrix": "Implementing VoIP services with Matrix", + "Dev chat for the Riot/Web dev team": "Dev chat for the Riot/Web dev team", + "Call invitation": "Call invitation", + "Riot Desktop on %(platformName)s": "Riot Desktop on %(platformName)s", + "Messages containing my display name": "Messages containing my display name", + "You have successfully set a password and an email address!": "You have successfully set a password and an email address!", + "Failed to send custom event.": "Failed to send custom event.", + "What's new?": "What's new?", + "Discussion of the Identity Service API": "Discussion of the Identity Service API", + "Support for those using and running matrix-appservice-irc": "Support for those using and running matrix-appservice-irc", + "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk chat", + "Notify me for anything else": "Notify me for anything else", + "View Source": "View Source", + "Keywords": "Keywords", + "Click here to create a GitHub issue.": "Click here to create a GitHub issue.", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.", + "Can't update user notification settings": "Can't update user notification settings", + "Notify for all other messages/rooms": "Notify for all other messages/rooms", + "Unable to look up room ID from server": "Unable to look up room ID from server", + "Couldn't find a matching Matrix room": "Couldn't find a matching Matrix room", + "Support for those using the Matrix spec": "Support for those using the Matrix spec", + "Invite to this room": "Invite to this room", + "You cannot delete this message. (%(code)s)": "You cannot delete this message. (%(code)s)", + "Thursday": "Thursday", + "I understand the risks and wish to continue": "I understand the risks and wish to continue", + "Logs sent": "Logs sent", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s via %(browserName)s on %(osName)s", + "Back": "Back", + "Reply": "Reply", + "Show message in desktop notification": "Show message in desktop notification", + "You must specify an event type!": "You must specify an event type!", + "Unhide Preview": "Unhide Preview", + "Announcements about Synapse releases": "Announcements about Synapse releases", + "Search the room directory": "Search the room directory", + "Unable to join network": "Unable to join network", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply", + "Sorry, your browser is not able to run Riot.": "Sorry, your browser is not able to run Riot.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Decentralised, encrypted chat & collaboration powered by [matrix]", + "Building services on Matrix": "Building services on Matrix", + "Messages in group chats": "Messages in group chats", + "Yesterday": "Yesterday", + "Error encountered (%(errorDetail)s).": "Error encountered (%(errorDetail)s).", + "Event Type": "Event Type", + "Low Priority": "Low Priority", + "What's New": "What's New", + "Set Password": "Set Password", + "Appear Offline": "Appear Offline", + "Get started with some tips from Riot Bot!": "Get started with some tips from Riot Bot!", + "An error occurred whilst saving your email notification preferences.": "An error occurred whilst saving your email notification preferences.", + "Enable audible notifications in web client": "Enable audible notifications in web client", + "Permalink": "Permalink", + "Welcome to Riot.im": "Welcome to Riot.im", + "Off": "Off", + "Riot does not know how to join a room on this network": "Riot does not know how to join a room on this network", + "Mentions only": "Mentions only", + "You can now return to your account after signing out, and sign in on other devices.": "You can now return to your account after signing out, and sign in on other devices.", + "Enable desktop notifications": "Enable desktop notifications", + "Enable email notifications": "Enable email notifications", + "Login": "Login", + "Download this file": "Download this file", + "Pin Message": "Pin Message", + "Failed to change settings": "Failed to change settings", + "View Community": "View Community", + "%(count)s Members|one": "%(count)s Member", + "Developer Tools": "Developer Tools", + "General discussion about Matrix and Riot": "General discussion about Matrix and Riot", + "Event Content": "Event Content", + "Thank you!": "Thank you!", + "#example": "#example", + "Collapse panel": "Collapse panel", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!", + "Checking for an update...": "Checking for an update...", + "Matrix technical discussions": "Matrix technical discussions", + "There are advanced notifications which are not shown here": "There are advanced notifications which are not shown here" } diff --git a/src/i18n/strings/en_US.json b/src/i18n/strings/en_US.json index 2ce5cb541b..0c9bfdf881 100644 --- a/src/i18n/strings/en_US.json +++ b/src/i18n/strings/en_US.json @@ -710,5 +710,183 @@ "%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s widget removed by %(senderName)s", "Robot check is currently unavailable on desktop - please use a web browser": "Robot check is currently unavailable on desktop - please use a web browser", "Verifies a user, device, and pubkey tuple": "Verifies a user, device, and pubkey tuple", - "%(senderName)s changed the pinned messages for the room.": "%(senderName)s changed the pinned messages for the room." + "%(senderName)s changed the pinned messages for the room.": "%(senderName)s changed the pinned messages for the room.", + "Fetching third party location failed": "Fetching third party location failed", + "A new version of Riot is available.": "A new version of Riot is available.", + "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk chat", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Please describe the bug. What did you do? What did you expect to happen? What actually happened?", + "Couldn't load home page": "Couldn't load home page", + "All notifications are currently disabled for all targets.": "All notifications are currently disabled for all targets.", + "Uploading report": "Uploading report", + "Sunday": "Sunday", + "Guests can join": "Guests can join", + "Messages sent by bot": "Messages sent by bot", + "Notification targets": "Notification targets", + "Failed to set direct chat tag": "Failed to set direct chat tag", + "Today": "Today", + "Failed to get protocol list from Home Server": "Failed to get protocol list from Home Server", + "Report a bug": "Report a bug", + "Implementing VR services with Matrix": "Implementing VR services with Matrix", + "You are not receiving desktop notifications": "You are not receiving desktop notifications", + "Friday": "Friday", + "Update": "Update", + "You need to be using HTTPS to place a screen-sharing call.": "You need to be using HTTPS to place a screen-sharing call.", + "What's New": "What's New", + "Add an email address above to configure email notifications": "Add an email address above to configure email notifications", + "Expand panel": "Expand panel", + "On": "On", + "Filter room names": "Filter room names", + "Changelog": "Changelog", + "Running Matrix services": "Running Matrix services", + "Waiting for response from server": "Waiting for response from server", + "Leave": "Leave", + "Failed to send report: ": "Failed to send report: ", + "Unknown device": "Unknown device", + "Advanced notification settings": "Advanced notification settings", + "delete the alias.": "delete the alias.", + "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", + "Forget": "Forget", + "World readable": "World readable", + "#example": "#example", + "Riot/Web & Desktop chat": "Riot/Web & Desktop chat", + "Hide panel": "Hide panel", + "You cannot delete this image. (%(code)s)": "You cannot delete this image. (%(code)s)", + "Cancel Sending": "Cancel Sending", + "Warning": "Warning", + "This Room": "This Room", + "The Home Server may be too old to support third party networks": "The Home Server may be too old to support third party networks", + "Noisy": "Noisy", + "Room not found": "Room not found", + "Messages containing my display name": "Messages containing my display name", + "Messages in one-to-one chats": "Messages in one-to-one chats", + "Contributing code to Matrix and Riot": "Contributing code to Matrix and Riot", + "Unavailable": "Unavailable", + "Community-run support for Synapse": "Community-run support for Synapse", + "View Decrypted Source": "View Decrypted Source", + "Failed to update keywords": "Failed to update keywords", + "remove %(name)s from the directory.": "remove %(name)s from the directory.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Notifications on the following keywords follow rules which can’t be displayed here:", + "Please set a password!": "Please set a password!", + "You have successfully set a password!": "You have successfully set a password!", + "Chat with Riot Bot": "Chat with Riot Bot", + "Support for those using, running and writing other bridges": "Support for those using, running and writing other bridges", + "Admin support for Dendrite": "Admin support for Dendrite", + "An error occurred whilst saving your email notification preferences.": "An error occurred while saving your email notification preferences.", + "Source URL": "Source URL", + "Failed to add tag %(tagName)s to room": "Failed to add tag %(tagName)s to room", + "Members": "Members", + "No update available.": "No update available.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!", + "Resend": "Resend", + "Files": "Files", + "Collecting app version information": "Collecting app version information", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Delete the room alias %(alias)s and remove %(name)s from the directory?", + "customServer_text": "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.", + "Co-ordination for Riot/Web translators": "Co-ordination for Riot/Web translators", + "This will allow you to return to your account after signing out, and sign in on other devices.": "This will allow you to return to your account after signing out, and sign in on other devices.", + "Dev chat for the Dendrite dev team": "Dev chat for the Dendrite dev team", + "Keywords": "Keywords", + "Unpin Message": "Unpin Message", + "Enable notifications for this account": "Enable notifications for this account", + "Directory": "Directory", + "Failed to get public room list": "Failed to get public room list", + "Messages containing keywords": "Messages containing keywords", + "Error saving email notification preferences": "Error saving email notification preferences", + "Tuesday": "Tuesday", + "Enter keywords separated by a comma:": "Enter keywords separated by a comma:", + "Search…": "Search…", + "Remove %(name)s from the directory?": "Remove %(name)s from the directory?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.", + "Enable desktop notifications": "Enable desktop notifications", + "Unnamed room": "Unnamed room", + "Remember, you can always set an email address in user settings if you change your mind.": "Remember, you can always set an email address in user settings if you change your mind.", + "All messages (noisy)": "All messages (noisy)", + "Saturday": "Saturday", + "I understand the risks and wish to continue": "I understand the risks and wish to continue", + "Direct Chat": "Direct Chat", + "The server may be unavailable or overloaded": "The server may be unavailable or overloaded", + "Reject": "Reject", + "Riot is not supported on mobile web. Install the app?": "Riot is not supported on mobile web. Install the app?", + "Discussion of all things Matrix!": "Discussion of all things Matrix!", + "Failed to set Direct Message status of room": "Failed to set Direct Message status of room", + "Monday": "Monday", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please uncheck:", + "Remove from Directory": "Remove from Directory", + "Enable them now": "Enable them now", + "Messages containing my user name": "Messages containing my user name", + "Describe your problem here.": "Describe your problem here.", + "Collecting logs": "Collecting logs", + "more": "more", + "Search for a room": "Search for a room", + "(HTTP status %(httpStatus)s)": "(HTTP status %(httpStatus)s)", + "All Rooms": "All Rooms", + "Wednesday": "Wednesday", + "Quote": "Quote", + "Send": "Send", + "Send logs": "Send logs", + "All messages": "All messages", + "Implementing VoIP services with Matrix": "Implementing VoIP services with Matrix", + "Dev chat for the Riot/Web dev team": "Dev chat for the Riot/Web dev team", + "Call invitation": "Call invitation", + "Riot Desktop on %(platformName)s": "Riot Desktop on %(platformName)s", + "Downloading update...": "Downloading update...", + "You have successfully set a password and an email address!": "You have successfully set a password and an email address!", + "What's new?": "What's new?", + "Discussion of the Identity Service API": "Discussion of the Identity Service API", + "Support for those using and running matrix-appservice-irc": "Support for those using and running matrix-appservice-irc", + "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk chat", + "Notify me for anything else": "Notify me for anything else", + "When I'm invited to a room": "When I'm invited to a room", + "Design and implementation of E2E in Matrix": "Design and implementation of E2E in Matrix", + "Can't update user notification settings": "Can't update user notification settings", + "Notify for all other messages/rooms": "Notify for all other messages/rooms", + "Unable to look up room ID from server": "Unable to look up room ID from server", + "Couldn't find a matching Matrix room": "Couldn't find a matching Matrix room", + "Support for those using the Matrix spec": "Support for those using the Matrix spec", + "Safari and Opera work too.": "Safari and Opera work too.", + "Loading bug report module": "Loading bug report module", + "Invite to this room": "Invite to this room", + "You cannot delete this message. (%(code)s)": "You cannot delete this message. (%(code)s)", + "Thursday": "Thursday", + "Forward Message": "Forward Message", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s via %(browserName)s on %(osName)s", + "Unhide Preview": "Unhide Preview", + "Announcements about Synapse releases": "Announcements about Synapse releases", + "Search the room directory": "Search the room directory", + "Please describe the bug and/or send logs.": "Please describe the bug and/or send logs.", + "Unable to join network": "Unable to join network", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply", + "Sorry, your browser is not able to run Riot.": "Sorry, your browser is not able to run Riot.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Decentralised, encrypted chat & collaboration powered by [matrix]", + "Uploaded on %(date)s by %(user)s": "Uploaded on %(date)s by %(user)s", + "Messages in group chats": "Messages in group chats", + "Yesterday": "Yesterday", + "Error encountered (%(errorDetail)s).": "Error encountered (%(errorDetail)s).", + "Low Priority": "Low Priority", + "Unable to fetch notification target list": "Unable to fetch notification target list", + "Get started with some tips from Riot Bot!": "Get started with some tips from Riot Bot!", + "Set Password": "Set Password", + "Enable audible notifications in web client": "Enable audible notifications in web client", + "Permalink": "Permalink", + "Welcome to Riot.im": "Welcome to Riot.im", + "Off": "Off", + "Riot does not know how to join a room on this network": "Riot does not know how to join a room on this network", + "Mentions only": "Mentions only", + "Failed to remove tag %(tagName)s from room": "Failed to remove tag %(tagName)s from room", + "You can now return to your account after signing out, and sign in on other devices.": "You can now return to your account after signing out, and sign in on other devices.", + "Please install Chrome or Firefox for the best experience.": "Please install Chrome or Firefox for the best experience.", + "Enable email notifications": "Enable email notifications", + "Login": "Login", + "No rooms to show": "No rooms to show", + "Download this file": "Download this file", + "Pin Message": "Pin Message", + "Failed to change settings": "Failed to change settings", + "View Source": "View Source", + "Matrix technical discussions": "Matrix technical discussions", + "Building services on Matrix": "Building services on Matrix", + "Collapse panel": "Collapse panel", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!", + "Checking for an update...": "Checking for an update...", + "General discussion about Matrix and Riot": "General discussion about Matrix and Riot", + "There are advanced notifications which are not shown here": "There are advanced notifications which are not shown here" } diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index f40b9c711f..31c3bc57ad 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -963,5 +963,201 @@ "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Kiam ĉi tiu paĝo enhavas identigeblajn informojn, ekzemple ĉambron, uzantan aŭ grupan identigilon, ĝi sendiĝas al la servilo sen tiuj.", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(day)s %(monthName)s %(fullYear)s", "Disable Community Filter Panel": "Malŝalti komunuman filtran breton", - "Failed to add tag %(tagName)s to room": "Malsukcesis aldoni etikedon %(tagName)s al ĉambro" + "Failed to add tag %(tagName)s to room": "Malsukcesis aldoni etikedon %(tagName)s al ĉambro", + "Fetching third party location failed": "Malsukcesis trovi lokon de ekstera liveranto", + "A new version of Riot is available.": "Nova versio de Riot haveblas.", + "Riot/Android & matrix-android-sdk chat": "Babilado pri Riot ĉe Android kaj matrix-android-sdk", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Bonvolu priskribi la cimon. Kion vi faris? Kion vi atendis? Kio fakte okazis?", + "I understand the risks and wish to continue": "Mi komprenas la riskojn kaj volas daŭrigi", + "Couldn't load home page": "Malsukcesis enlegi hejmpaĝon", + "Send Account Data": "Sendi kontajn informojn", + "Advanced notification settings": "Specialaj agordoj de sciigoj", + "Uploading report": "Alŝutante raporton", + "Sunday": "Dimanĉo", + "Notification targets": "Celoj de sciigoj", + "Failed to set direct chat tag": "Malsukcesis agordi la etikedon de rekta babilo", + "Today": "Hodiaŭ", + "Files": "Dosieroj", + "Report a bug": "Raporti cimon", + "Implementing VR services with Matrix": "Realigado de VR-servoj en Matrix", + "You are not receiving desktop notifications": "Vi ne ricevadas sciigojn labortablajn", + "Friday": "Vendredo", + "Update": "Ĝisdatigi", + "You need to be using HTTPS to place a screen-sharing call.": "Vi devas uzi HTTPS por ekranvidadi.", + "What's New": "Kio novas", + "Add an email address above to configure email notifications": "Aldonu retadreson supre por agordi retpoŝtajn sciigojn", + "Expand panel": "Etendi panelon", + "On": "Ek", + "%(count)s Members|other": "%(count)s Membroj", + "Filter room names": "Filtri nomojn de ĉambroj", + "Changelog": "Protokolo de ŝanĝoj", + "Running Matrix services": "Funkciigado de servoj de Matrix", + "Waiting for response from server": "Atendante respondon el la servilo", + "Send Custom Event": "Sendi propran okazon", + "Failed to send report: ": "Malsukcesis sendi raporton: ", + "Unknown device": "Nekonata aparato", + "All notifications are currently disabled for all targets.": "Ĉiuj sciigoj nun estas malŝaltitaj por ĉiuj aparatoj.", + "delete the alias.": "forigi la kromnomon.", + "To return to your account in future you need to set a password": "Por reveni al via konto estonte, vi devas agordi pasvorton", + "Forget": "Forgesi", + "#example": "#ekzemplo", + "Riot/Web & Desktop chat": "Babilado pri Riot ĉe reto kaj labortablo", + "Hide panel": "Kaŝi panelon", + "You cannot delete this image. (%(code)s)": "Vi ne povas forigi tiun ĉi bildon. (%(code)s)", + "Cancel Sending": "Nuligi sendon", + "This Room": "Ĉi tiu ĉambro", + "The Home Server may be too old to support third party networks": "La hejmservilo povas esti tro malnova por subteni retojn de eksteraj liverantoj", + "Noisy": "Brua", + "Room not found": "Ĉambro ne troviĝis", + "Messages containing my display name": "Mesaĝoj enhavantaj mian vidigan nomon", + "Messages in one-to-one chats": "Mesaĝoj en duopaj babiloj", + "Contributing code to Matrix and Riot": "Kontribuado de kodo al Matrix kaj Riot", + "Unavailable": "Nedisponebla", + "Community-run support for Synapse": "Komunuma subtenado de Synapse", + "View Decrypted Source": "Vidi malĉifritan fonton", + "Failed to update keywords": "Malsukcesis ĝisdatigi la ŝlosilvortojn", + "remove %(name)s from the directory.": "forigi %(name)s de la ujo.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "La sciigoj de la jenaj ŝlosilvortoj sekvas regulojn kiuj ne povas esti montrataj ĉi tie:", + "Safari and Opera work too.": "Ankaŭ Safario kaj Opero funkcias.", + "Please set a password!": "Bonvolu agordi pasvorton!", + "You have successfully set a password!": "Vi sukcese agordis pasvorton!", + "Chat with Riot Bot": "Babilu kun la roboto Riot Bot", + "Support for those using, running and writing other bridges": "Subteno por tiuj, kiuj uzas, funkciigas, aŭ evoluigas aliajn pontojn", + "Admin support for Dendrite": "Administra subtenado por Dendrite", + "An error occurred whilst saving your email notification preferences.": "Eraro okazis dum konservado de agordoj pri retpoŝtaj sciigoj.", + "Explore Room State": "Esplori staton de ĉambro", + "Source URL": "Fonta URL", + "Messages sent by bot": "Mesaĝoj senditaj per roboto", + "Filter results": "Filtri rezultojn", + "Members": "Anoj", + "No update available.": "Neniuj ĝisdatigoj haveblas.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Multaj ĉambroj jam ekzistas en Matrix; kaj sendependaj, kaj ligitaj kun jamaj retoj (Slock, IRC, Gitter, ktp.). Rigardu la ĉambrujon!", + "Resend": "Resendi", + "Failed to get protocol list from Home Server": "Malsukcesis akiri liston de protokoloj el la hejmservilo", + "Collecting app version information": "Kolektanta informon pri versio de la aplikaĵo", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Ĉu forigi la ĉambran kromnomon %(alias)s kaj forigi %(name)s de la ujo?", + "customServer_text": "Vi povas uzi opciojn personigitajn de la servilo por ensaluti en aliajn servilojn Matrix specifante alian adreson URL-an de alia servilo Home.
    Tio permesas al vi uzi Riot per ekzistanta konto en alia Home servilo.

    Vi povas ankaŭ agordi servilon identecan personigita, sed ne eblos inviti uzantojn pere de retpoŝtadreso, aŭ esti invitita pere de retpoŝtadreso vi mem.", + "Co-ordination for Riot/Web translators": "Kunordigado por tradukistoj de Riot ĉe reto", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Tio ĉi permesos al vi reveni al via konto post adiaŭo, kaj saluti kun alia aparato.", + "Dev chat for the Dendrite dev team": "Babilado por la programista skipo de Dendrite", + "Design and implementation of E2E in Matrix": "Fasonado kaj realigado de ĝiscela ĉifrado en Matrix", + "Enable notifications for this account": "Ŝalti sciigojn por tiu ĉi konto", + "Directory": "Dosierujo", + "Invite to this community": "Inviti al tiu ĉi komunumo", + "Failed to get public room list": "Malsukcesis akiri liston de publikaj ĉambroj", + "Messages containing keywords": "Mesaĝoj enhavantaj ŝlosilovortojn", + "Error saving email notification preferences": "Eraro konservante agordojn pri retpoŝtaj sciigoj", + "Tuesday": "Mardo", + "Enter keywords separated by a comma:": "Entajpu ŝlosilvortojn apartigitajn per komoj:", + "Search…": "Serĉi…", + "You have successfully set a password and an email address!": "Vi sukcese agordis pasvorton kaj retpoŝtadreson!", + "Remove %(name)s from the directory?": "Ĉu forigi %(name)s de la ujo?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot uzas multajn specialajn funkciojn, el kiuj kelkaj ne disponeblas aŭ estas eksperimentaj en via nuna foliumilo.", + "Event sent!": "Okazo sendiĝis!", + "Please install Chrome or Firefox for the best experience.": "Bonvolu instali \"Chrome\"\"Firefox\" por la plej bona sperto.", + "Explore Account Data": "Esplori kontajn datumojn", + "All messages (noisy)": "Ĉiuj mesaĝoj (lauta)", + "Away": "Foresta", + "Saturday": "Sabato", + "Remember, you can always set an email address in user settings if you change your mind.": "Memoru: vi ĉiam povas agordi retpoŝtadreson en viaj agordoj por uzantoj.", + "Direct Chat": "Rekta babilo", + "The server may be unavailable or overloaded": "La servilo povas esti nedisponebla aŭ troŝarĝita", + "Reject": "Rifuzi", + "Riot is not supported on mobile web. Install the app?": "Riot ne estas subtenata sur poŝkomputila reto. Ĉu instali la aplikaĵon?", + "Discussion of all things Matrix!": "Diskutado pri ĉio rilata al Matrix!", + "Failed to set Direct Message status of room": "Malsukcesis agordi staton de rekta mesaĝo al la ĉambro", + "Monday": "Lundo", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Por diagnozi problemojn, protokoloj el tiu ĉi kliento sendiĝos kune kun tiu ĉi raporto de eraro. Se vi preferas sendi nur la supran tekston, bonvolu malŝalti:", + "Remove from Directory": "Forigi de ujo", + "Enable them now": "Ŝalti ilin nun", + "Messages containing my user name": "Mesaĝoj enhavantaj mian salutnomon", + "Describe your problem here.": "Priskribu vian problemon ĉi tie.", + "Toolbox": "Ilaro", + "Collecting logs": "Kolektante protokolon", + "more": "pli", + "Bug report sent": "Cimraporto sendiĝis", + "You must specify an event type!": "Vi devas specifi tipon de okazo!", + "(HTTP status %(httpStatus)s)": "(stato de HTTP %(httpStatus)s)", + "Invite to this room": "Inviti al ĉi tiu ĉambro", + "Please install Chrome or Firefox for the best experience.": "Bonvolu instali ĤromonFajrovulpon por plej bona sperto.", + "Wednesday": "Merkredo", + "You cannot delete this message. (%(code)s)": "Vi ne povas forigi tiun ĉi mesaĝon. (%(code)s)", + "Quote": "Citi", + "Send logs": "Sendi protokolojn", + "All messages": "Ĉiuj mesaĝoj", + "Implementing VoIP services with Matrix": "Realigado de VoIP-servoj en Matrix", + "Dev chat for the Riot/Web dev team": "Babilado por la programista skipo de Riot ĉe reto", + "Call invitation": "Invito al voko", + "Riot Desktop on %(platformName)s": "Riot Labortablo sur %(platformName)s", + "Downloading update...": "Elŝutanta ĝisdatigon…", + "State Key": "Stata ŝlosilo", + "Failed to send custom event.": "Malsukcesis sendi propran okazon.", + "What's new?": "Kio novas?", + "Discussion of the Identity Service API": "Diskutado pri API de la identiga servo", + "Support for those using and running matrix-appservice-irc": "Subteno por tiuj, kiuj uzas kaj funkciigas matrix-appservice-irc", + "Riot/iOS & matrix-ios-sdk chat": "Babilado pri Riot ĉe iOS kaj matrix-ios-sdk", + "Notify me for anything else": "Sciigu min pri ĉio alia", + "When I'm invited to a room": "Kiam mi estas invitita al ĉambro", + "Keywords": "Ŝlosilvortoj", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Vi povas uzi proprajn servilajn elektojn por saluti aliajn servilojn de Matrix, per specifo de alia hejmservila URL.
    Tio permesas al vi uzi klienton Riot kun jama konto de Matrix en alia hejmservilo.

    Vi ankaŭ povas agordi propran identigan servilon, sed vi ne povos inviti uzantojn per retpoŝtadreso, aŭ esti invitata per retpoŝtadreso mem.", + "Can't update user notification settings": "Agordoj de sciigoj al uzanto ne ĝisdatigeblas", + "Notify for all other messages/rooms": "Sciigu min por ĉiu alia babilejo", + "Unable to look up room ID from server": "Ĉambra identigaĵo ne akireblas de la servilo", + "Couldn't find a matching Matrix room": "Malsukcesis trovi kongruan ĉambron en Matrix", + "Support for those using the Matrix spec": "Subteno por tiuj, kiuj uzas la specifaĵon de Matrix", + "Safari and Opera work too.": "Safari kaj Opera ankaŭ funkcias.", + "Loading bug report module": "Enleganta cimraportan modulon", + "All Rooms": "Ĉiuj babilejoj", + "Search for a room": "Serĉi ĉambron", + "Thursday": "Ĵaŭdo", + "Forward Message": "Plusendi mesaĝon", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s per %(browserName)s je %(osName)s", + "Back": "Reen", + "Failed to change settings": "Malsukcesis ŝanĝi la agordojn", + "Reply": "Respondi", + "Show message in desktop notification": "Montradi mesaĝojn en labortablaj sciigoj", + "Unhide Preview": "Malkaŝi antaŭrigardon", + "Announcements about Synapse releases": "Anoncoj pri eldonoj de Synapse", + "Search the room directory": "Serĉi en la ĉambrujo", + "Please describe the bug and/or send logs.": "Bonvolu priskribi la cimon kaj/aŭ sendi protokolojn.", + "Unable to join network": "Malsukcesis konektiĝi al la reto", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Vi eble agordis ilin en alia kliento. Vi ne povas agordi ilin en Riot, sed ili ankoraŭ validas", + "Sorry, your browser is not able to run Riot.": "Pardonu, via foliumilo ne kapablas funkciigi klienton Riot.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Malcentra, ĉifrita babilado & kunlaboro povigita de [matrix]", + "Uploaded on %(date)s by %(user)s": "Alŝutita je %(date)s de %(user)s", + "Messages in group chats": "Mesaĝoj en grupaj babiloj", + "Yesterday": "Hieraŭ", + "Error encountered (%(errorDetail)s).": "Eraro okazis (%(errorDetail)s).", + "Login": "Saluti", + "Low Priority": "Malalta prioritato", + "Unable to fetch notification target list": "Malsukcesis akiri la liston de celoj por sciigoj", + "Appear Offline": "Montriĝi kiel eksterreta", + "Get started with some tips from Riot Bot!": "Komencu kun kelkaj sugestoj de la roboto Riot Bot!", + "Set Password": "Agordi pasvorton", + "Enable audible notifications in web client": "Ŝalti aŭdeblajn sciigojn en la retkliento", + "Permalink": "Konstanta ligilo", + "Welcome to Riot.im": "Bonvenu al Riot.im", + "Off": "For", + "Riot does not know how to join a room on this network": "Riot ne scias aliĝi al ĉambroj en tiu ĉi reto", + "Mentions only": "Nur mencioj", + "Failed to remove tag %(tagName)s from room": "Malsukcesis forigi etikedon %(tagName)s el la ĉambro", + "You can now return to your account after signing out, and sign in on other devices.": "Vi nun rajtas reveni al via konto post adiaŭo, kaj saluti per ĝi kun aliaj aparatoj.", + "Enable desktop notifications": "Ŝalti labortablajn sciigojn", + "Enable email notifications": "Ŝalti retpoŝtajn sciigojn", + "Event Type": "Tipo de okazo", + "Download this file": "Elŝuti ĉi tiun dosieron", + "Pin Message": "Fiksi mesaĝon", + "Thank you!": "Dankon!", + "View Community": "Vidi Komunumon", + "%(count)s Members|one": "%(count)s Membro", + "Developer Tools": "Evoluigiloj", + "View Source": "Vidi fonton", + "Matrix technical discussions": "Teĥnikaj diskutoj pri Matrix", + "Event Content": "Enhavo de okazo", + "Building services on Matrix": "Konstruado de servoj sur Matrix", + "Collapse panel": "Maletendi panelon", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Kun via nuna foliumilo, la aspekto kaj funkciado de la aplikaĵo povas esti tute malĝusta, kaj kelkaj aŭ ĉiu funkcioj eble ne tute funkcios. Se vi tamen volas provi, vi povas daŭrigi, sed vi ricevos nenian subtenon se vi renkontos problemojn!", + "Checking for an update...": "Serĉanta ĝisdatigojn…", + "General discussion about Matrix and Riot": "Ĝenerala diskutado pri Matrix kaj Riot", + "There are advanced notifications which are not shown here": "Ekzistas specialaj sciigoj, kiuj ne montriĝas ĉi tie" } diff --git a/src/i18n/strings/es.json b/src/i18n/strings/es.json index 0241d6a0cc..0e03b0ecf3 100644 --- a/src/i18n/strings/es.json +++ b/src/i18n/strings/es.json @@ -587,5 +587,215 @@ "Invite new community members": "Invita nuevos miembros de la comunidad", "Name or matrix ID": "Nombre o ID de matrix", "Invite to Community": "Invitar a la comunidad", - "Which rooms would you like to add to this community?": "¿Qué salas deseas añadir a esta comunidad?" + "Which rooms would you like to add to this community?": "¿Qué salas deseas añadir a esta comunidad?", + "Fetching third party location failed": "Falló la obtención de la ubicación de un tercero", + "A new version of Riot is available.": "Una nueva versión de Riot está disponible.", + "Riot/Android & matrix-android-sdk chat": "Conversaciones sobre Riot/Android & matrix-android-sdk", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Por favor describa el error. ¿Qué acción ejecutó? ¿Cuál era el resultado que esperaba? ¿Que pasó realmente?", + "I understand the risks and wish to continue": "Entiendo los riesgos y deseo continuar", + "Couldn't load home page": "No se puede cargar la página principal", + "Send Account Data": "Enviar Datos de la Cuenta", + "Advanced notification settings": "Configuración avanzada de notificaciones", + "Uploading report": "Enviando informe", + "Sunday": "Domingo", + "Guests can join": "Los invitados se pueden unir", + "Failed to add tag %(tagName)s to room": "Error al añadir la etiqueta %(tagName)s a la sala", + "Notification targets": "Objetivos de notificación", + "Failed to set direct chat tag": "Error al establecer la etiqueta de chat directo", + "Today": "Hoy", + "Files": "Archivos", + "Report a bug": "Informar de un fallo", + "Implementing VR services with Matrix": "Implementación de servicios VR con Matrix", + "You are not receiving desktop notifications": "No estás recibiendo notificaciones de escritorio", + "Friday": "Viernes", + "Update": "Actualizar", + "You need to be using HTTPS to place a screen-sharing call.": "Debes usar HTTPS para hacer una llamada con pantalla compartida.", + "What's New": "Novedades", + "Add an email address above to configure email notifications": "Añade una dirección de correo arriba para configurar las notificaciones por correo", + "Expand panel": "Expandir panel", + "On": "Encendido", + "%(count)s Members|other": "%(count)s miembros", + "Filter room names": "Filtrar los nombres de las salas", + "Changelog": "Registro de cambios", + "Running Matrix services": "Ejecutando servicios de Matrix", + "Waiting for response from server": "Esperando una respuesta del servidor", + "Leave": "Salir", + "Uploaded on %(date)s by %(user)s": "Subido el %(date)s por %(user)s", + "Send Custom Event": "Enviar Evento Personalizado", + "Failed to send report: ": "Error al enviar informe: ", + "Unknown device": "Dispositivo desconocido", + "All notifications are currently disabled for all targets.": "Las notificaciones estan desactivadas para todos los objetivos.", + "Failed to send logs: ": "Error al enviar registros: ", + "delete the alias.": "borrar el alias.", + "To return to your account in future you need to set a password": "Para regresar a tu cuenta en el futuro debes establecer una contraseña", + "Forget": "Olvidar", + "World readable": "Legible por todo el mundo", + "Riot/Web & Desktop chat": "Conversaciones de Riot/Web & Desktop", + "Hide panel": "Ocultar panel", + "You cannot delete this image. (%(code)s)": "No puedes eliminar esta imagen. (%(code)s)", + "Cancel Sending": "Cancelar envío", + "This Room": "Esta sala", + "The Home Server may be too old to support third party networks": "El Home Server puede ser demasiado antiguo para soportar redes de terceros", + "Resend": "Reenviar", + "Room not found": "Sala no encontrada", + "Messages containing my display name": "Mensajes que contienen mi nombre", + "Messages in one-to-one chats": "Mensajes en chats uno a uno", + "Contributing code to Matrix and Riot": "Contribuciones de código para Matrix y Riot", + "Unavailable": "No disponible", + "Community-run support for Synapse": "Soporte comunitario de Synapse", + "View Decrypted Source": "Ver Fuente Descifrada", + "Failed to update keywords": "Error al actualizar las palabras clave", + "Notes:": "Notas:", + "remove %(name)s from the directory.": "retirar %(name)s del directorio.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Las notificaciones de las siguientes palabras clave siguen reglas que no se pueden mostrar aquí:", + "Safari and Opera work too.": "Safari y Opera también funcionan.", + "Please set a password!": "¡Por favor establece una contraseña!", + "You have successfully set a password!": "¡Has establecido una nueva contraseña!", + "Chat with Riot Bot": "Conversar con el Bot de Riot", + "Support for those using, running and writing other bridges": "Soporte para usuarios, administradores y desarrolladores de otros puentes", + "Admin support for Dendrite": "Soporte administrativo para Dendrite", + "An error occurred whilst saving your email notification preferences.": "Se ha producido un error al guardar las preferencias de notificación por email.", + "Explore Room State": "Explorar Estado de la Sala", + "Source URL": "URL de Origen", + "Messages sent by bot": "Mensajes enviados por bot", + "Filter results": "Filtrar resultados", + "Members": "Miembros", + "No update available.": "No hay actualizaciones disponibles.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Muchas salas ya están disponibles en Matrix, enlazadas a redes existentes (Slack, IRC, Gitter, etc) o independientes. ¡Revisa el directorio!", + "Noisy": "Ruidoso", + "Failed to get protocol list from Home Server": "Error al obtener la lista de protocolos desde el Home Server", + "Collecting app version information": "Recolectando información de la versión de la aplicación", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "¿Borrar el alias de la sala %(alias)s y eliminar %(name)s del directorio?", + "customServer_text": "Puedes utilizar las opciones de servidor personalizadas para iniciar sesión en otros servidores Matrix especificando una URL de Home server distinta.
    Esto te permite usar Riot con una cuenta Matrix existente en un Home server distinto.

    También puedes configurar un servidor de identidad personalizado, pero no podrás ni invitar usuarios ni ser invitado a través de tu dirección de correo electrónico.", + "Co-ordination for Riot/Web translators": "Coordinación para traductores de Riot/Web", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Esto te permitirá regresar a tu cuenta después de cerrar sesión, así como iniciar sesión en otros dispositivos.", + "Dev chat for the Dendrite dev team": "Conversaciones del equipo de desarrollo de Dendrite", + "Keywords": "Palabras clave", + "Enable notifications for this account": "Habilitar notificaciones para esta cuenta", + "Directory": "Directorio", + "Invite to this community": "Invitar a esta comunidad", + "Search for a room": "Buscar sala", + "Messages containing keywords": "Mensajes que contienen palabras clave", + "Error saving email notification preferences": "Error al guardar las preferencias de notificación por email", + "Tuesday": "Martes", + "Enter keywords separated by a comma:": "Introduzca palabras clave separadas por una coma:", + "Search…": "Buscar…", + "You have successfully set a password and an email address!": "¡Has establecido una nueva contraseña y dirección de correo electrónico!", + "Remove %(name)s from the directory?": "¿Retirar %(name)s del directorio?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot usa muchas características avanzadas del navegador, algunas de las cuales no están disponibles en su navegador actual.", + "Event sent!": "Evento enviado!", + "Preparing to send logs": "Preparando para enviar registros", + "Enable desktop notifications": "Habilitar notificaciones de escritorio", + "Unnamed room": "Sala sin nombre", + "Explore Account Data": "Explorar Datos de la Cuenta", + "Remove from Directory": "Retirar del Directorio", + "Away": "Ausente", + "Saturday": "Sábado", + "Remember, you can always set an email address in user settings if you change your mind.": "Recuerda que si es necesario puedes establecer una dirección de email en las preferencias de usuario.", + "Direct Chat": "Conversación directa", + "The server may be unavailable or overloaded": "El servidor puede estar no disponible o sobrecargado", + "Reject": "Rechazar", + "Riot is not supported on mobile web. Install the app?": "Riot no está soportado en navegadores Web móviles. ¿Quieres instalar la aplicación?", + "Discussion of all things Matrix!": "¡Discusión sobre todas las cosas de Matrix!", + "Failed to set Direct Message status of room": "No se pudo establecer el estado de Mensaje Directo de la sala", + "Monday": "Lunes", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Para diagnosticar los problemas, los registros de este cliente serán enviados adjuntos a este informe de fallo. Si quisieras enviar el texto anterior solamente, entonces desmarca:", + "All messages (noisy)": "Todos los mensajes (ruidoso)", + "Enable them now": "Habilitarlos ahora", + "Messages containing my user name": "Mensajes que contienen mi nombre de usuario", + "Describe your problem here.": "Describe el problema aquí.", + "Toolbox": "Caja de Herramientas", + "Collecting logs": "Recolectando registros", + "more": "más", + "GitHub issue link:": "Enlace de incidencia en GitHub:", + "Bug report sent": "Informe de fallo enviado", + "You must specify an event type!": "Debes especificar un tipo de evento!", + "(HTTP status %(httpStatus)s)": "(estado HTTP %(httpStatus)s)", + "Invite to this room": "Invitar a esta sala", + "Please install Chrome or Firefox for the best experience.": "Por favor instala Chrome o Firefox para una experiencia óptima.", + "Failed to get public room list": "No se pudo obtener la lista de salas públicas", + "Send": "Enviar", + "Send logs": "Enviar registros", + "All messages": "Todos los mensajes", + "Implementing VoIP services with Matrix": "Implementación de servicios VoIP con Matrix", + "Dev chat for the Riot/Web dev team": "Conversaciones del equipo de desarrollo de Riot/Web", + "Call invitation": "Invitación a la llamada", + "Thank you!": "¡Gracias!", + "Riot Desktop on %(platformName)s": "Riot Desktop en %(platformName)s", + "Downloading update...": "Descargando actualizaciones...", + "State Key": "Clave de estado", + "Failed to send custom event.": "Ha fallado el envio del evento personalizado.", + "What's new?": "¿Qué hay de nuevo?", + "Discussion of the Identity Service API": "Discusión sobre el API de Identity Service", + "Support for those using and running matrix-appservice-irc": "Soporte para aquellos que usan o administran matrix-appservice-irc", + "Riot/iOS & matrix-ios-sdk chat": "Conversaciones sobre Riot/iOS & matrix-ios-sdk", + "Notify me for anything else": "Notificarme para cualquier otra cosa", + "When I'm invited to a room": "Cuando estoy invitado a una sala", + "Design and implementation of E2E in Matrix": "Diseño e implementación de E2E en Matrix", + "Click here to create a GitHub issue.": "Haz click aquí para crear una incidencia en Github.", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Puedes usar las opciones del servidor personalizado para acceder a otros servidores Matrix especificando su URL.
    Esto te permite usar Riot con una cuenta Matrix existente en un servidor doméstico distinto.

    También puedes establecer un servidor de identidad personalizado pero no podrás invitar a otros usuarios usando su dirección de correo electrónico, y tampoco ser invitado por el tuyo.", + "Can't update user notification settings": "No se puede actualizar la configuración de notificaciones del usuario", + "Notify for all other messages/rooms": "Notificar para todos los demás mensajes/salas", + "Unable to look up room ID from server": "No se puede buscar el ID de la sala desde el servidor", + "Couldn't find a matching Matrix room": "No se encontró una sala Matrix que coincida", + "Support for those using the Matrix spec": "Soporte para usuarios de la especificación de Matrix", + "Safari and Opera work too.": "Safari y Opera también funcionan.", + "Loading bug report module": "Cargando módulo de reporte de errores", + "All Rooms": "Todas las salas", + "You cannot delete this message. (%(code)s)": "No puedes eliminar este mensaje. (%(code)s)", + "Thursday": "Jueves", + "Forward Message": "Reenviar mensaje", + "Logs sent": "Registros enviados", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s via %(browserName)s en %(osName)s", + "Back": "Atrás", + "Reply": "Responder", + "Show message in desktop notification": "Mostrar mensaje en la notificación del escritorio", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Los registros de depuración contienen datos de uso de la aplicación como nombre de usuario, ID o alias de las salas o grupos que hayas visitado (y nombres de usuario de otros usuarios). No contienen mensajes.", + "Unhide Preview": "Mostrar Vista Previa", + "Announcements about Synapse releases": "Anuncios de lanzamientos de Synapse", + "Search the room directory": "Buscar en el directorio de salas", + "Please describe the bug and/or send logs.": "Por favor describe el error y/o envía los registros.", + "Unable to join network": "No se puede unir a la red", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Es posible que los hayas configurado en un cliente que no sea Riot. No puedes ajustarlos en Riot, pero todavía se aplican", + "Sorry, your browser is not able to run Riot.": "¡Lo sentimos! Su navegador no puede ejecutar Riot.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Conversaciones cifradas y descentralizadas & colaboración con el poder de [matrix]", + "Building services on Matrix": "Construyendo servicios con Matrix", + "Messages in group chats": "Mensajes en chats de grupo", + "Yesterday": "Ayer", + "Error encountered (%(errorDetail)s).": "Error encontrado (%(errorDetail)s).", + "Login": "Iniciar sesión", + "Low Priority": "Baja Prioridad", + "Riot does not know how to join a room on this network": "Riot no sabe cómo unirse a una sala en esta red", + "Appear Offline": "Mostrarse Desconectado", + "Get started with some tips from Riot Bot!": "¡Comenzar con algunos consejos de Riot Bot!", + "Set Password": "Establecer contraseña", + "Enable audible notifications in web client": "Habilitar notificaciones audibles en el cliente web", + "Permalink": "Enlace permanente", + "Welcome to Riot.im": "Bienvenido a Riot.im", + "Off": "Apagado", + "#example": "#ejemplo", + "Mentions only": "Sólo menciones", + "Failed to remove tag %(tagName)s from room": "Error al eliminar la etiqueta %(tagName)s de la sala", + "Wednesday": "Miércoles", + "You can now return to your account after signing out, and sign in on other devices.": "Ahora puedes regresar a tu cuenta después de cerrar tu sesión, e iniciar sesión en otros dispositivos.", + "Please install Chrome or Firefox for the best experience.": "Por favor instale Google Chrome o Mozilla Firefox para una mejor experiencia.", + "Enable email notifications": "Habilitar notificaciones por email", + "Event Type": "Tipo de Evento", + "No rooms to show": "Sin salas para mostrar", + "Download this file": "Descargar este archivo", + "Pin Message": "Marcar Mensaje", + "Failed to change settings": "Error al cambiar la configuración", + "View Community": "Ver la comunidad", + "%(count)s Members|one": "%(count)s miembro", + "Developer Tools": "Herramientas de Desarrollo", + "View Source": "Ver Fuente", + "Matrix technical discussions": "Discusiones técnicas sobre Matrix", + "Event Content": "Contenido del Evento", + "Unable to fetch notification target list": "No se puede obtener la lista de objetivos de notificación", + "Quote": "Citar", + "Collapse panel": "Colapsar panel", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "En su navegador actual, la apariencia y comportamiento de la aplicación puede ser completamente incorrecta, y algunas de las características podrían no funcionar. Si aún desea probarlo puede continuar, pero ¡no podremos ofrecer soporte por cualquier problema que pudiese tener!", + "Checking for an update...": "Comprobando actualizaciones...", + "General discussion about Matrix and Riot": "Discusión general sobre Matrix y Riot", + "There are advanced notifications which are not shown here": "Hay notificaciones avanzadas que no se muestran aquí" } diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index 276baab771..2c02b2f313 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -1003,5 +1003,206 @@ "Unable to leave community": "Ezinezkoa komunitatetik ateratzea", "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Zure komunitatearen izen eta abatarari egindako aldaketak 30 minutu behar ditzakete beste erabiltzaileek ikusi arte.", "Join this community": "Elkartu komunitate honetara", - "Leave this community": "Atera komunitate honetatik" + "Leave this community": "Atera komunitate honetatik", + "Fetching third party location failed": "Huts egin du hirugarrengoen kokalekua eskuratzean", + "A new version of Riot is available.": "Riot bertsio berri bat dago eskuragarri.", + "Riot/Android & matrix-android-sdk chat": "Riot/Android eta matrix-android-sdk txata", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Deskribatu akatsa. Zer egin duzu? Zer gertatuko zela uste zenuen? Zer gertatu da?", + "Couldn't load home page": "Ezin izan da hasiera orria kargatu", + "Send Account Data": "Bidali kontuaren datuak", + "All notifications are currently disabled for all targets.": "Une honetan jakinarazpen guztiak helburu guztietarako desgaituta daude.", + "Uploading report": "Igoera txostena", + "Sunday": "Igandea", + "Notification targets": "Jakinarazpenen helburuak", + "Today": "Gaur", + "Failed to get protocol list from Home Server": "Huts egin du protokoloen zerrenda hasiera zerbitzaritik jasotzean", + "Report a bug": "Eman akats baten berri", + "Implementing VR services with Matrix": "VR zerbitzuak inplementatzea Matrix erabilita", + "You are not receiving desktop notifications": "Ez dituzu mahaigaineko jakinarazpenak jasotzen", + "Friday": "Ostirala", + "Update": "Eguneratu", + "You need to be using HTTPS to place a screen-sharing call.": "HTTPS erabili behar duzu sekretuak partekatzeko dei bat ezartzeko.", + "What's New": "Zer dago berri", + "Add an email address above to configure email notifications": "Gehitu e-mail helbide bat goian e-mail bidezko jakinarazpenak konfiguratzeko", + "Expand panel": "Hedatu panela", + "On": "Bai", + "%(count)s Members|other": "%(count)s kide", + "Filter room names": "Iragazi gelen izenak", + "Changelog": "Aldaketa-egunkaria", + "Running Matrix services": "Matrix zerbitzuak exekutatzea", + "Waiting for response from server": "Zerbitzariaren erantzunaren zain", + "Send Custom Event": "Bidali gertaera pertsonalizatua", + "Failed to send report: ": "Huts egin du txostena bidaltzean: ", + "Unknown device": "Gailu ezezaguna", + "Advanced notification settings": "Jakinarazpen aurreratuen ezarpenak", + "Failed to send logs: ": "Huts egin du egunkariak bidaltzean: ", + "delete the alias.": "ezabatu ezizena.", + "To return to your account in future you need to set a password": "Etorkizunean kontura itzuli ahal izateko pasahitz bat ezarri behar duzu", + "Forget": "Ahaztu", + "#example": "#adibidea", + "Riot/Web & Desktop chat": "Riot/Web eta mahaigaineko txata", + "Hide panel": "Ezkutatu panela", + "You cannot delete this image. (%(code)s)": "Ezin duzu irudi hau ezabatu. (%(code)s)", + "Cancel Sending": "Utzi bidaltzeari", + "This Room": "Gela hau", + "The Home Server may be too old to support third party networks": "Hasiera zerbitzaria zaharregia izan daiteke hirugarrengoen sarean onartzeko", + "Noisy": "Zaratatsua", + "Error saving email notification preferences": "Errorea e-mail jakinarazpenen hobespenak gordetzean", + "Messages containing my display name": "Nire pantaila-izena duten mezuak", + "Messages in one-to-one chats": "Biren arteko txatetako mezuak", + "Contributing code to Matrix and Riot": "Kodearekin lagundu Matrix eta Riot", + "Unavailable": "Eskuraezina", + "Community-run support for Synapse": "Synapse-rako laguntza komunitatea", + "View Decrypted Source": "Ikusi deszifratutako iturria", + "Failed to update keywords": "Huts egin du hitz gakoak eguneratzean", + "Notes:": "Oharrak:", + "remove %(name)s from the directory.": "kendu %(name)s direktoriotik.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Hitz gako hauen jakinarazpenak hemen bistaratu ezin daitezkeen arauak jarraitzen dituzte:", + "Safari and Opera work too.": "Safari eta Opera badabiltza ere.", + "Please set a password!": "Ezarri pasahitza mesedez!", + "You have successfully set a password!": "Ongi ezarri duzu pasahitza!", + "Chat with Riot Bot": "Txateatu Riot botarekin", + "Support for those using, running and writing other bridges": "Bestelako zubiak erabili, exekutatu eta idazten dituztenentzako laguntza", + "Admin support for Dendrite": "Dendrite kudeatzaileentzako laguntza", + "An error occurred whilst saving your email notification preferences.": "Errore bat gertatu da zure e-mail bidezko jakinarazpenen hobespenak gordetzean.", + "Explore Room State": "Miatu gelaren egoera", + "Source URL": "Iturriaren URLa", + "Messages sent by bot": "Botak bidalitako mezuak", + "Filter results": "Iragazi emaitzak", + "Members": "Kideak", + "No update available.": "Ez dago eguneraketarik eskuragarri.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Badauden sareetara lotutako gela ugari daude Matrixen (Slack, IRC, Gitter eta abar), baita independienteak. Begiratu direktorioa!", + "Resend": "Birbidali", + "Files": "Fitxategiak", + "Collecting app version information": "Aplikazioaren bertsio-informazioa biltzen", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Ezabatu gelaren %(alias)s ezizena eta kendu %(name)s direktoriotik?", + "customServer_text": "Zerbitzari pertsonalizatuaren aukerak erabili ditzakezu beste hasiera zerbitzari baten URLa jarrita beste Matrix zerbitzarietan saioa hasteko.
    Honek oraingo Matrix kontuarekin Riot beste hasiera zerbitzari batean erabiltzea ahalbidetzen dizu.

    Identitate zerbitzari pertsonalizatu bat jar dezakezu ere baina ezin izango dituzu erabiltzaileak bere e-mail helbidea erabilita gonbidatu, edo besteek zu gonbidatu zure e-mail helbidea erabilita.", + "Co-ordination for Riot/Web translators": "Riot/Web itzultzaileen arteko koordinazioa", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Honek zure kontura itzultzea ahalbidetuko dizu, beste gailuetan saioa amaitu eta berriro hasi eta gero.", + "Dev chat for the Dendrite dev team": "Dendrite garapen taldearen txata", + "Keywords": "Hitz gakoak", + "Enable notifications for this account": "Gaitu jakinarazpenak kontu honetarako", + "Directory": "Direktorioa", + "Invite to this community": "Gonbidatu komunitate honetara", + "Failed to get public room list": "Huts egin du gela publikoen zerrenda jasotzean", + "Messages containing keywords": "Hitz gakoak dituzten mezuak", + "Room not found": "Ez da gela aurkitu", + "Tuesday": "Asteartea", + "Enter keywords separated by a comma:": "Idatzi hitz gakoak koma bidez banatuta:", + "Forward Message": "Birbidali mezua", + "You have successfully set a password and an email address!": "Ondo ezarri dituzu pasahitza eta e-mail helbidea!", + "Remove %(name)s from the directory?": "Kendu %(name)s direktoriotik?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riotek nabigatzaileen ezaugarri aurreratu ugari erabiltzen ditu, hauetako batzuk ez daude erabilgarri edo esperimentalak dira zure oraingo nabigatzailean.", + "Event sent!": "Gertaera bidalita!", + "Preparing to send logs": "Egunkariak bidaltzeko prestatzen", + "Enable desktop notifications": "Gaitu mahaigaineko jakinarazpenak", + "Remember, you can always set an email address in user settings if you change your mind.": "Gogoratu, e-mail helbide bat ezarri dezakezu erabiltzaile-ezarpenetan iritzia aldatzen baduzu.", + "Explore Account Data": "Miatu kantuaren datuak", + "All messages (noisy)": "Mezu guztiak (ozen)", + "Away": "Teklatutik at", + "Saturday": "Larunbata", + "I understand the risks and wish to continue": "Arriskua ulertzen dut eta jarraitu nahi dut", + "Direct Chat": "Txat zuzena", + "The server may be unavailable or overloaded": "Zerbitzaria eskuraezin edo gainezka egon daiteke", + "Reject": "Baztertu", + "Riot is not supported on mobile web. Install the app?": "Riotek ez du euskarririk mugikorrentzako webean. Instalatu aplikazioa?", + "Discussion of all things Matrix!": "Matrix-ekin zerikusia duen guztiari buruzko eztabaida!", + "Failed to set Direct Message status of room": "Huts egin du Mezu Zuzena egoera gelan ezartzean", + "Monday": "Astelehena", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Arazoak diagnostikatzeko, bezero honen egunkariak bidaliko dira arazte-txosten honekin. Testua besterik ez baduzu bidali nahi, desmarkatu:", + "Remove from Directory": "Kendu direktoriotik", + "Enable them now": "Gaitu orain", + "Messages containing my user name": "Nire erabiltzaile-izena duten mezuak", + "Describe your problem here.": "Azaldu zure arazoa hemen.", + "Toolbox": "Tresna-kutxa", + "Collecting logs": "Egunkariak biltzen", + "more": "gehiago", + "GitHub issue link:": "Arazoaren esteka GitHuben:", + "Bug report sent": "Arazte-txostena bidali da", + "You must specify an event type!": "Gertaera mota bat zehaztu behar duzu!", + "(HTTP status %(httpStatus)s)": "(HTTP egoera %(httpStatus)s)", + "All Rooms": "Gela guztiak", + "Please install Chrome or Firefox for the best experience.": "Instalatu Chrome edo Firefox esperientzia onena izateko.", + "Wednesday": "Asteazkena", + "You cannot delete this message. (%(code)s)": "Ezin duzu mezu hau ezabatu. (%(code)s)", + "Quote": "Aipua", + "Send logs": "Bidali egunkariak", + "All messages": "Mezu guztiak", + "Implementing VoIP services with Matrix": "VoIP zerbitzuak inplementatzea Matrix erabilita", + "Dev chat for the Riot/Web dev team": "Riot/web garapen taldearen txata", + "Call invitation": "Dei gonbidapena", + "Riot Desktop on %(platformName)s": "Riot Desktop %(platformName)s plataforman", + "Downloading update...": "Eguneraketa deskargatzen...", + "State Key": "Egoera gakoa", + "Failed to send custom event.": "Huts egin du gertaera pertsonalizatua bidaltzean.", + "What's new?": "Zer dago berri?", + "Discussion of the Identity Service API": "Identitate zerbitzuaren APIari buruzko eztabaida", + "Support for those using and running matrix-appservice-irc": "matrix-appservice-irc exekutatu edo erabiltzen dutenentzako laguntza", + "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS eta matrix-ios-sdk txata", + "Notify me for anything else": "Jakinarazi beste edozer", + "When I'm invited to a room": "Gela batetara gonbidatzen nautenean", + "Design and implementation of E2E in Matrix": "Matrix-en E2E diseinu eta inplementazioa", + "Click here to create a GitHub issue.": "Egin klik hemen GitHub-en arazoaren berri emateko.", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Zerbitzari pertsonalizatuaren aukerak erabili ditzakezu beste Matrix zerbitzarietan saioa hasteko, han beste hasiera-zerbitzari baten URLa sartuz.
    Horrela Riot aurretik duzun kontu batekin erabili dezakezu beste hasiera-zerbitzari batean.

    Identitate-zerbitzari pertsonalizatu bat ezarri dezakezu ere, baina orduan ezin izango dituzu erabiltzaileak e-mail helbidea erabiliz gonbidatu, edo ezin izan izango zaituzte zu e-mail helbidea erabiliz gonbidatu.", + "Can't update user notification settings": "Ezin dira erabiltzailearen jakinarazpenen ezarpenak eguneratu", + "Notify for all other messages/rooms": "Jakinarazi beste mezu/gela guztiak", + "Unable to look up room ID from server": "Ezin izan da gelaren IDa zerbitzarian bilatu", + "Couldn't find a matching Matrix room": "Ezin izan da bat datorren Matrix gela bat aurkitu", + "Support for those using the Matrix spec": "Matrix espezifikazioa darabilenentzako laguntza", + "Safari and Opera work too.": "Safari eta Opera badabiltza ere.", + "Loading bug report module": "Arazte-txosten modulua kargatzen", + "Invite to this room": "Gonbidatu gela honetara", + "Search for a room": "Bilatu gela bat", + "Thursday": "Osteguna", + "Search…": "Bilatu…", + "Logs sent": "Egunkariak bidalita", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s %(browserName)s bidez %(osName)s ostalarian", + "Back": "Atzera", + "Reply": "Erantzun", + "Show message in desktop notification": "Erakutsi mezua mahaigaineko jakinarazpenean", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Arazte-egunkariek aplikazioak darabilen datuak dauzkate, zure erabiltzaile izena barne, bisitatu dituzun gelen ID-ak edo ezizenak eta beste erabiltzaileen izenak. Ez dute mezurik.", + "Unhide Preview": "Ez ezkutatu aurrebista", + "Announcements about Synapse releases": "Synapse bertsio berrien iragarkiak", + "Search the room directory": "Bilatu gelen direktorioa", + "Please describe the bug and/or send logs.": "Deskribatu akatsa eta/edo bidali egunkariak.", + "Unable to join network": "Ezin izan da sarera elkartu", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Agian Riot ez beste bezero batean konfiguratu dituzu. Ezin dituzu Riot bidez doitu, baina aplikagarriak dira", + "Sorry, your browser is not able to run Riot.": "Zure nabigatzaileak ez du Riot erabiltzeko gaitasunik.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Deszentralizatutako eta zifratutako txat eta elkarlana [matrix] sareari esker", + "Uploaded on %(date)s by %(user)s": "%(user)s erabiltzaileak %(date)s (e)an igota", + "Messages in group chats": "Talde txatetako mezuak", + "Yesterday": "Atzo", + "Error encountered (%(errorDetail)s).": "Errorea aurkitu da (%(errorDetail)s).", + "Login": "Hasi saioa", + "Low Priority": "Lehentasun baxua", + "Unable to fetch notification target list": "Ezin izan da jakinarazpen helburuen zerrenda eskuratu", + "Appear Offline": "Agertu deskonektatuta", + "Get started with some tips from Riot Bot!": "Hasi Riot botaren aholku batzuekin!", + "Set Password": "Ezarri pasahitza", + "Enable audible notifications in web client": "Gaitu jakinarazpen entzungarriak web bezeroan", + "Permalink": "Esteka iraunkorra", + "Welcome to Riot.im": "Ongi etorri Riot.im mezularitzara", + "Off": "Ez", + "Riot does not know how to join a room on this network": "Riotek ez daki nola elkartu gela batetara sare honetan", + "Mentions only": "Aipamenak besterik ez", + "You can now return to your account after signing out, and sign in on other devices.": "Zure kontura itzuli zaitezke beste gailuetan saioa amaitu eta berriro hastean.", + "Please install Chrome or Firefox for the best experience.": "Instalatu Chrome edo Firefox esperientzia on baterako.", + "Enable email notifications": "Gaitu e-mail bidezko jakinarazpenak", + "Event Type": "Gertaera mota", + "Download this file": "Deskargatu fitxategi hau", + "Pin Message": "Finkatu mezua", + "Failed to change settings": "Huts egin du ezarpenak aldatzean", + "View Community": "Ikusi komunitatea", + "%(count)s Members|one": "Kide %(count)s", + "Developer Tools": "Garatzaile-tresnak", + "View Source": "Ikusi iturria", + "Matrix technical discussions": "Matrix buruzko eztabaida teknikoak", + "Event Content": "Gertaeraren edukia", + "Thank you!": "Eskerrik asko!", + "Building services on Matrix": "Matrix-en gaineko zerbitzuak eraikitzea", + "Collapse panel": "Tolestu panela", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Zure oraingo nabigatzailearekin aplikazioaren itxura eta portaera guztiz okerra izan daiteke, eta funtzio batzuk ez dira ibiliko. Hala ere aurrera jarraitu dezakezu saiatu nahi baduzu, baina zure erantzukizunaren menpe geratzen dira aurkitu ditzakezun arazoak!", + "Checking for an update...": "Eguneraketarik dagoen egiaztatzen...", + "General discussion about Matrix and Riot": "Matrix eta Riot-i buruzko eztabaida orokorra", + "There are advanced notifications which are not shown here": "Hemen erakusten ez diren jakinarazpen aurreratuak daude" } diff --git a/src/i18n/strings/fa.json b/src/i18n/strings/fa.json index 0967ef424b..a5501d1246 100644 --- a/src/i18n/strings/fa.json +++ b/src/i18n/strings/fa.json @@ -1 +1,190 @@ -{} +{ + "Fetching third party location failed": "تطبیق اطلاعات از منابع‌ دسته سوم با شکست مواجه شد", + "Messages in one-to-one chats": "پیام‌های درون چت‌های یک‌به‌یک", + "A new version of Riot is available.": "نسخه‌ی جدید از رایوت موجود است.", + "Riot/Android & matrix-android-sdk chat": "رایوت/اندروید & چت در مورد matrix-android-sdk", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "لطفا باگ را دقیقا تشریح کنید. چه کار کردید؟ انتظار داشتید چه اتفاقی بیفتد؟ دقیقا چه اتفاقی افتاد؟", + "Advanced notification settings": "تنظیمات پیشرفته برای آگاه‌سازی‌ها", + "Uploading report": "در حال بارگذاری گزارش", + "Sunday": "یکشنبه", + "Guests can join": "میهمان‌ها می‌توانند بپیوندند", + "Messages sent by bot": "پیام‌های ارسال شده توسط ربات", + "Notification targets": "هدف‌های آگاه‌سازی", + "Failed to set direct chat tag": "تنظیم تگ برای چت مستقیم موفقیت‌آمیز نبود", + "Today": "امروز", + "Files": "فایل‌ها", + "Report a bug": "باگ‌ها را گزارش کنید", + "Implementing VR services with Matrix": "پیاده‌سازی سرویس‌های VR با ماتریکس", + "You are not receiving desktop notifications": "شما آگاه‌سازی‌های دسکتاپ را دریافت نمی‌کنید", + "Friday": "آدینه", + "Update": "به‌روزرسانی", + "Notifications": "آگاه‌سازی‌ها", + "You need to be using HTTPS to place a screen-sharing call.": "شما باید از ارتباط امن HTTPS برای به‌راه‌اندازی یک چتِ شامل به اشتراک‌گذاری صفحه‌ی کامیپوتر استفاده کنید.", + "What's New": "تازه‌ها", + "Add an email address above to configure email notifications": "آدرس ایمیلتان را به بالا بیفزایید تا بتوانید آگاه‌سازی با ایمیل را مدیریت کنید", + "Expand panel": "پنل را بگشا", + "On": "روشن", + "Filter room names": "جستجو در گپ‌ها", + "Changelog": "تغییراتِ به‌وجودآمده", + "Running Matrix services": "اجرای سرویس‌های ماتریکسی", + "Waiting for response from server": "در انتظار پاسخی از سمت سرور", + "Leave": "خروج", + "OK": "باشه", + "Failed to send report: ": "فرستادن گزارش موفقیت‌آمیز نبود: ", + "Unknown device": "دستگاه ناشناخته", + "All notifications are currently disabled for all targets.": "همه‌ی آگاه‌سازی‌ها برای تمام هدف‌ها غیرفعال‌اند.", + "Operation failed": "عملیات شکست خورد", + "delete the alias.": "نام مستعار را پاک کن.", + "To return to your account in future you need to set a password": "برای بازگشتِ دوباره به اکانتان در آینده نیاز به ثبت یک پسورد دارید", + "Forget": "فراموش کن", + "World readable": "خواندن جهانی", + "Mute": "سکوت", + "Riot/Web & Desktop chat": "رایوت/وب & چت دسکتاپ", + "Hide panel": "پنل را پنهان کن", + "You cannot delete this image. (%(code)s)": "شما نمی‌توانید این تصویر را پاک کنید. (%(code)s)", + "Cancel Sending": "فرستادن را لغو کن", + "Warning": "هشدار", + "This Room": "این گپ", + "Resend": "بازفرست", + "Error saving email notification preferences": "خطا در ذخیره‌سازی ترجیحات آگاهسازی با ایمیل", + "Downloading update...": "در حال بارگیریِ به‌روزرسانی...", + "#example": "#نمونه", + "Remember, you can always set an email address in user settings if you change your mind.": "به خاطر داشته باشید که اگر نظرتان عوض شد می‌توانید از بخش تنظیمات یک ایمیل را به اکانتتان متصل کنید.", + "Contributing code to Matrix and Riot": "کمک به برنامه‌نویسی در ماتریکس و رایوت", + "Unavailable": "غیرقابل‌دسترسی", + "Community-run support for Synapse": "پشتیبانی سیناپس اداره‌شده توسط جامعه‌ی کاربری", + "View Decrypted Source": "دیدن منبع رمزگشایی شده", + "Failed to update keywords": "به‌روزرسانی کلیدواژه‌ها موفقیت‌آمیز نبود", + "remove %(name)s from the directory.": "%(name)s را از فهرست گپ‌ها حذف کن", + "Please set a password!": "لطفا یک پسورد اختیار کنید!", + "powered by Matrix": "قدرت‌یافته از ماتریکس", + "You have successfully set a password!": "شما با موفقیت رمزتان را انتخاب کردید!", + "Chat with Riot Bot": "با رایوت‌بات چت کنید", + "Support for those using, running and writing other bridges": "پشتیبانی برای آنان که یک پل را استفاده اجرا کرده و یا می‌نویسند", + "Admin support for Dendrite": "پشتیبانی ادمین برای Dendrite", + "Favourite": "علاقه‌مندی‌ها", + "All Rooms": "همه‌ی گپ‌ها", + "Source URL": "آدرس مبدا", + "Failed to add tag %(tagName)s to room": "در افزودن تگ %(tagName)s موفقیت‌آمیز نبود", + "Members": "اعضا", + "No update available.": "هیچ به روزرسانی جدیدی موجود نیست.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "بسیاری از گپ‌گاه‌های موجود در فهرستِ گپ‌ها به شبکه‌های موجود(اسلک، آی‌آر‌سی، گلیتر و...) متصل و یا مستقل‌اند؛ به آنها نگاهی بیندازید!", + "Noisy": "پرسروصدا", + "Failed to get protocol list from Home Server": "دریافت لیست پروتکل‌ها از کارگزار مبدا موفقیت‌آمیز نبود", + "Collecting app version information": "درحال جمع‌آوری اطلاعات نسخه‌ی برنامه", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "آیا مطمئنید که می‌خواهید نام مستعار گپ %(alias)s را پاک و %(name)s را از فهرست حذف کنید؟", + "Co-ordination for Riot/Web translators": "هماهنگی برای مترجمان رایوت/وب", + "This will allow you to return to your account after signing out, and sign in on other devices.": "این به شما اجازه خواهد داد که پس از خروج به اکانت خود بازگردید و از سایر دستگاه‌ها وارد شوید.", + "Dev chat for the Dendrite dev team": "چت توسعه‌دهندگان برای تیم Dendrite", + "Cancel": "لغو", + "Enable notifications for this account": "آگاه سازی با رایانامه را برای این اکانت فعال کن", + "Directory": "فهرست گپ‌گاه‌ها", + "Failed to get public room list": "گرفتن لیست گپ‌گاه‌های عمومی موفقیت‌آمیز نبود", + "Messages containing keywords": "پیا‌م‌های دارای این کلیدواژه‌ها ", + "Room not found": "گپ یافت نشد", + "Tuesday": "سه‌شنبه", + "Enter keywords separated by a comma:": "کلیدواژه‌ها را وارد کنید؛ از کاما(,) برای جدا کردن آنها از یکدیگر استفاده کنید:", + "Forward Message": "هدایت پیام", + "Remove %(name)s from the directory?": "آیا مطمئنید می‌خواهید %(name)s را از فهرست گپ‌ها حذف کنید؟", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "رایوت از بسیاری از ویژگی‌های پیشرفته در مروگرها استفاده می‌کند، برخی از این ویژگی‌ها در مرورگر کنونی شما موجود نیستند و یا در حالت آزمایشی قرار دارند.", + "Please install Chrome or Firefox for the best experience.": "لطفا برای بهترین تجربه‌ی کاربری ازکروم یا فایرفاکس استفاده کنید", + "Unnamed room": "گپ نام‌گذاری نشده", + "Dismiss": "نادیده بگیر", + "Remove from Directory": "از فهرستِ گپ‌ها حذف کن", + "Saturday": "شنبه", + "I understand the risks and wish to continue": "از خطرات این کار آگاهم و مایلم که ادامه بدهم", + "Direct Chat": "چت مستقیم", + "The server may be unavailable or overloaded": "این سرور ممکن است ناموجود یا بسیار شلوغ باشد", + "Reject": "پس زدن", + "Riot is not supported on mobile web. Install the app?": "رایوت در موبایل‌ها پشتیبانی نمیشود؛ تمایلی دارید که اپ را نصب کنید؟", + "Discussion of all things Matrix!": "بحث درمورد تمام چیز‌های مربوط به ماتریکس!", + "Failed to set Direct Message status of room": "تنظیم حالت پیام مستقیم برای گپ موفقیت‌آمیز نبود", + "Monday": "دوشنبه", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "برای بهبود و رفع مشکلات، گزارش‌هایی از این کارخواه به عنوان مستنداتی از یک باگ ارسال خوهند شد. اگر ترجیح می‌دهید که فقط متن بالا ارسال شود لطفا تیک را بردارید", + "All messages (noisy)": "همه‌ی پیام‌ها(بلند)", + "Enable them now": "همین حالا فعالشان کن", + "Messages containing my user name": "پیام‌های شامل نامِ کاربری من", + "Describe your problem here.": "مشکلتان را در اینجا توضیح دهید.", + "Collecting logs": "درحال جمع‌آوری گزارش‌ها", + "more": "بیشتر", + "Search for a room": "جستجوی برای یک گپ", + "Search": "جستجو", + "(HTTP status %(httpStatus)s)": "(HTTP وضعیت %(httpStatus)s)", + "Failed to forget room %(errCode)s": "فراموش کردن گپ‌گاه %(errCode)s موفقیت‌آمیز نبود", + "Wednesday": "چهارشنبه", + "Quote": "گفتآورد", + "Send": "ارسال", + "Error": "خطا", + "Send logs": "ارسال گزارش‌ها", + "All messages": "همه‌ی پیام‌ها", + "unknown error code": "کد خطای ناشناخته", + "Implementing VoIP services with Matrix": "پیاده‌سازی سرویس‌های VoIP با ماتریکس", + "Dev chat for the Riot/Web dev team": "چت توسعه‌دهندگان برای تیم رایوت/وب", + "Call invitation": "دعوت به تماس", + "Riot Desktop on %(platformName)s": "رایوت دسکتاپ بر %(platformName)s", + "Messages containing my display name": "پیام‌های حاوی نمای‌نامِ من", + "You have successfully set a password and an email address!": "تخصیص ایمیل و پسوردتان با موفقیت انجام شد!", + "What's new?": "تازه‌ها", + "Discussion of the Identity Service API": "بحث درمورد API سرویس هویت", + "Support for those using and running matrix-appservice-irc": "پشتیبانی برای کسانی که matrix-appservice-irc را اجرا و استفاده می‌کنند", + "Riot/iOS & matrix-ios-sdk chat": "رایوت/آی‌او‌اس & چت در مورد matrix-ios-sdk", + "Notify me for anything else": "مرا برای هرچیز دیگری باخبر کن", + "When I'm invited to a room": "وقتی من به گپی دعوت میشوم", + "Design and implementation of E2E in Matrix": "طراحی و پیاده‌سازی رمزگذاری E2E در ماتریکس", + "Close": "بستن", + "Can't update user notification settings": "امکان به‌روزرسانی تنظیمات آگاه‌سازی کاربر وجود ندارد", + "Notify for all other messages/rooms": "برای همه‌ی پیام‌ها/گپ‌های دیگر آگاه‌سازی کن", + "Couldn't find a matching Matrix room": "گپ‌گاه مورد نظر در ماتریکس یافت نشد", + "Support for those using the Matrix spec": "پشتیبانی برای آنان که از مستندات ماتریکس استفاده می‌کنند", + "Safari and Opera work too.": "سافاری و اپرا نیز کار می‌کنند.", + "Loading bug report module": "درحال بارگذاری و اجرای ماژولِ گزارش باگ", + "Invite to this room": "دعوت به این گپ", + "You cannot delete this message. (%(code)s)": "شما نمی‌توانید این پیام را پاک کنید. (%(code)s)", + "Thursday": "پنج‌شنبه", + "Search…": "جستجو…", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s از طریق %(browserName)s بر %(osName)s", + "Unhide Preview": "پیش‌نمایش را نمایان کن", + "Announcements about Synapse releases": "اطلاعیه‌ها درباره‌ی نسخه‌ها و انتشار سیناپس", + "Search the room directory": "در فهرست گپ‌ها جستجو کنید", + "Please describe the bug and/or send logs.": "لطفا باگ را توصیف کنید و یا گزارش‌ها را بفرستید", + "Unable to join network": "خطا در ورود به شبکه", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "ممکن است شما این تنظیمات را در کارخواهی به جز رایوت اعمال کرده باشید. شما نمی‌توانید انها را تغییر دهید اما آنها همچنان تاثیر خود را دارند", + "Sorry, your browser is not able to run Riot.": "متاسفانه مرورگر شما نمی‌تواند رایوت را اجرا کند.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "چت مرکزگریز و رمزنگاری‌شده & ارائه‌ای از ماتریکس", + "Uploaded on %(date)s by %(user)s": "آپلود شده در تاریخ %(date)s توسط %(user)s", + "Messages in group chats": "پیام‌های درون چت‌های گروهی", + "Yesterday": "دیروز", + "Error encountered (%(errorDetail)s).": "خطای رخ داده (%(errorDetail)s).", + "Keywords": "کلیدواژه‌ها", + "Low Priority": "کم اهمیت", + "Unable to fetch notification target list": "ناتوانی در تطبیق لیست آگاه‌سازی‌های هدف", + "Set Password": "پسوردتان را انتخاب کنید", + "Get started with some tips from Riot Bot!": "با کمی راهنمایی از رایوت‌بات شروع کنید!", + "An error occurred whilst saving your email notification preferences.": "خطایی در حین ذخیره‌ی ترجیجات شما درباره‌ی رایانامه رخ داد.", + "Enable audible notifications in web client": "آگاه‌سازی صدادار را در کارگزار وب فعال کن", + "Permalink": "پایاپیوند", + "Welcome to Riot.im": "به Riot.im خوش‌آمدید", + "Off": "خاموش", + "Riot does not know how to join a room on this network": "رایوت از چگونگی ورود به یک گپ در این شبکه اطلاعی ندارد", + "Mentions only": "فقط نام‌بردن‌ها", + "Failed to remove tag %(tagName)s from room": "خطا در حذف کلیدواژه‌ی %(tagName)s از گپ", + "Remove": "حذف کن", + "You can now return to your account after signing out, and sign in on other devices.": "اکنون می‌توانید پس از خروج به اکانتتان بازگردید و با دستگاه‌های دیگری وارد شوید.", + "Continue": "ادامه", + "Enable desktop notifications": "آگاه‌سازی دسکتاپ را فعال کن", + "Enable email notifications": "آگاه‌سازی با رایانامه را فعال کن", + "Login": "ورود", + "No rooms to show": "هیچ گپی برای نشان دادن موجود نیست", + "Download this file": "بارگیری کن", + "Failed to change settings": "تغییر تنظیمات موفقیت‌آمیز نبود", + "Failed to change password. Is your password correct?": "خطا در تغییر گذرواژه. آیا از درستی گذرواژه‌تان اطمینان دارید؟", + "View Source": "دیدن منبع", + "Matrix technical discussions": "بحث‌های فنی درباره‌ی ماتریکس", + "Custom Server Options": "تنظیمات سفارشی برای سرور", + "Building services on Matrix": "ساخت سرویس بر روی ماتریکس", + "Collapse panel": "پنل را ببند", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "با مرورگر کنونی شما، ظاهر و حس استفاده از برنامه ممکن است کاملا اشتباه باشد و برخی یا همه‌ی ویژگی‌ها ممکن است کار نکنند. می‌توانید به استفاده ادامه دهید اما مسئولیت هر مشکلی که به آن بربخورید بر عهده‌ی خودتان است!", + "Checking for an update...": "درحال بررسی به‌روزرسانی‌ها...", + "General discussion about Matrix and Riot": "بحث‌های کلی درمورد ماتریکس و رایوت", + "There are advanced notifications which are not shown here": "آگاه‌سازی‌های پیشرفته‌ای هستند که در اینجا نشان داده نشده‌اند" +} diff --git a/src/i18n/strings/fi.json b/src/i18n/strings/fi.json index ae12f57e28..fe2e493d19 100644 --- a/src/i18n/strings/fi.json +++ b/src/i18n/strings/fi.json @@ -935,5 +935,203 @@ "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Jos avain täsmää, valitse painike alla. Jos avain ei täsmää, niin joku muu salakuuntelee laitetta ja haluat todennäköisesti painaa estopainiketta.", "Old cryptography data detected": "Vanhat salaustiedot havaittu", "Warning": "Varoitus", - "Access Token:": "Pääsykoodi:" + "Access Token:": "Pääsykoodi:", + "Fetching third party location failed": "Kolmannen osapuolen paikan haku epäonnistui", + "A new version of Riot is available.": "Uusi Riot-versio on saatavilla.", + "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk -keskustelu", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Ole hyvä ja kuvaile virhe. Mitä teit? Mitä oletit tapahtuvan? Mitä itse asiassa tapahtui?", + "Couldn't load home page": "Kotisivun lataus epäonnistui", + "Send Account Data": "Lähetä tilin tiedot", + "All notifications are currently disabled for all targets.": "Kaikki ilmoitukset on kytketty pois kaikilta kohteilta.", + "Uploading report": "Ladataan raporttia", + "Sunday": "Sunnuntai", + "Failed to add tag %(tagName)s to room": "Tagin %(tagName)s lisäämineen huoneelle ei onnistunut", + "Notification targets": "Ilmoituksen kohteet", + "Failed to set direct chat tag": "Suoran viestittelyn tagin asettaminen epäonnistui", + "Today": "Tänään", + "Files": "Tiedostot", + "Report a bug": "Ilmoita ongelmasta", + "Implementing VR services with Matrix": "VR-palvelujen implementointi Matrixin avulla", + "You are not receiving desktop notifications": "Et vastaanota työpöytäilmoituksia", + "Friday": "Perjantai", + "Update": "Päivitä", + "You need to be using HTTPS to place a screen-sharing call.": "Sinun täytyy käyttää HTTPS -yhteyttä, jotta voit jakaa ruudun.", + "What's New": "Mikä on uutta", + "Add an email address above to configure email notifications": "Lisää sähköpostiosoite yllä saadaksesi ilmoituksia sähköpostiisi", + "Expand panel": "Avaa paneeli", + "On": "Päällä", + "%(count)s Members|other": "%(count)s jäsentä", + "Filter room names": "Suodata", + "Changelog": "Muutosloki", + "Running Matrix services": "Matrix-palvelujen ylläpito", + "Waiting for response from server": "Odotetaan vastausta palvelimelta", + "Send Custom Event": "Lähetä kustomoitu tapahtuma", + "Failed to send report: ": "Raportin lähettäminen epäonnistui: ", + "Unknown device": "Tuntematon laite", + "Advanced notification settings": "Lisäasetukset ilmoituksille", + "delete the alias.": "poista alias.", + "To return to your account in future you need to set a password": "Voidaksesi tulevaisuudessa palata tilillesi sinut pitää asettaa salasana", + "Forget": "Unohda", + "#example": "#esimerkki", + "Riot/Web & Desktop chat": "Riot/Web & Työpöytä-keskustelu", + "Hide panel": "Piilota paneeli", + "You cannot delete this image. (%(code)s)": "Et voi poistaa tätä kuvaa. (%(code)s)", + "Cancel Sending": "Peruuta lähetys", + "This Room": "Tämä huone", + "The Home Server may be too old to support third party networks": "Kotipalvelin saattaa olla liian vanha tukeakseen kolmannen osapuolen verkkoja", + "Noisy": "Äänekäs", + "Room not found": "Huonetta ei löytynyt", + "Downloading update...": "Ladataan päivitystä...", + "Messages in one-to-one chats": "Viestit henkilökohtaisissa keskusteluissa", + "Contributing code to Matrix and Riot": "Osallistu kehitystyöhön", + "Unavailable": "Ei saatavilla", + "Community-run support for Synapse": "Yhteisön tarjoama Synapse-tuki", + "Error saving email notification preferences": "Virhe tallennettaessa sähköposti-ilmoitusasetuksia", + "View Decrypted Source": "Näytä purettu lähdekoodi", + "Failed to update keywords": "Avainsanojen päivittäminen epäonnistui", + "Welcome to Riot.im": "Tervetuloa Riot.im -palveluun", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Seuraaviin avainsanoihin liittyvät ilmoitukset seuraavat sääntöjä joita ei voida näyttää tässä:", + "Safari and Opera work too.": "Safari ja Opera ovat myös tuettuja.", + "Please set a password!": "Ole hyvä ja aseta salasana!", + "You have successfully set a password!": "Olet onnistuneesti asettanut salasanan!", + "Chat with Riot Bot": "Keskustele Riot Botin kanssa", + "Support for those using, running and writing other bridges": "Tuki niille jotka käyttävät, ajavat ja ohjelmoivat muita siltoja", + "Admin support for Dendrite": "Dendrite ylläpitotuki", + "Explore Room State": "Huoneen tila", + "Source URL": "Lähde URL", + "Messages sent by bot": "Bottien lähettämät viestit", + "Filter results": "Suodata", + "Members": "Jäsenet", + "No update available.": "Ei päivityksiä saatavilla.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Matrixissa on olemassa monia huoneita, jotka on linkitetty olemassa oleviin verkkoihin (Slack, IRC, Gitter yms.). Tutustu hakemistoon!", + "Resend": "Lähetä uudelleen", + "Failed to get protocol list from Home Server": "Protokollalistan hakeminen Kotipalvelimelta ei onnistunut", + "Collecting app version information": "Haetaan versiotietoja", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Poista huonetunnus %(alias)s ja poista %(name)s hakemistosta?", + "customServer_text": "Voit käyttää palvelinasetuksia muille Matrix-palvelimille kirjautumiseen asettamalla oman kotipalvelinosoitteen.
    Näin voit käyttää Riotia toisella kotipalvelimella sijaitsevan Matrix-käyttäjän kanssa.

    Voit myös asettaa oman tunnistautumispalvelimen, mutta sinua ei voi kutsua etkä voi kutsua muita sähköpostiosoitteella.", + "Co-ordination for Riot/Web translators": "Riot/Web kääntäjien koordinointi", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Tämä mahdollistaa sinut palamaan tilillesi uloskirjautumisen jälkeen sekä kirjautumaan muilla laitteilla.", + "Dev chat for the Dendrite dev team": "Kehittäjäkeskustelu Dendrite kehitystiimille", + "Keywords": "Avainsanat", + "Enable notifications for this account": "Ota käyttöön ilmoitukset tälle tilille", + "Directory": "Hakemisto", + "Invite to this community": "Kutsu käyttäjiä", + "Search for a room": "Hae huonetta", + "Messages containing keywords": "Avainsanoja sisältävät viestit", + "View Source": "Näytä lähde", + "Tuesday": "Tiistai", + "Enter keywords separated by a comma:": "Anna avainsanat eroteltuna pilkuin:", + "Search…": "Haku…", + "You have successfully set a password and an email address!": "Olet onnistuneesti asettanut salasanan ja sähköpostiosoitteen!", + "Remove %(name)s from the directory?": "Poista %(name)s hakemistosta?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot käyttää monia selainominaisuuksia, joista osa selaimesi ei tue tai ne ovat kokeellisia.", + "Developer Tools": "Kehitystila", + "Enable desktop notifications": "Ota käyttöön työpöytäilmoitukset", + "Explore Account Data": "Tilitiedot", + "All messages (noisy)": "Kaikki viestit (äänekkäästi)", + "Away": "Poissa", + "Saturday": "Lauantai", + "Remember, you can always set an email address in user settings if you change your mind.": "Muista että voit aina asettaa sähköpostiosoitteen käyttäjäasetuksista jos muutat mielesi.", + "Direct Chat": "Suora viestittely", + "The server may be unavailable or overloaded": "Palvelin saattaa olla saavuttamaton tai ylikuormitettu", + "Reject": "Hylkää", + "Riot is not supported on mobile web. Install the app?": "Riot ei tue laitettasi. Asenna mobiilisovellus?", + "Discussion of all things Matrix!": "Keskustelu kaikesta Matrixiin liittyvästä!", + "Failed to set Direct Message status of room": "Huoneen suoran viestittelyn tilan asettaminen epäonnistui", + "Monday": "Maanantai", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Diagnoosin helpottamiseksi lokitietoja tältä laitteelta lähetetään tämän bugiraportin mukana. Poista ruksi jos haluat lätettää vain ylläolevan tekstin:", + "Send Custom State Event": "Lähetä kustomoitu tilatapahtuma", + "Remove from Directory": "Poista hakemistosta", + "Enable them now": "Ota käyttöön nyt", + "Forward Message": "Edelleenlähetä viesti", + "Describe your problem here.": "Kuvaa ongelmasi tähän.", + "Messages containing my user name": "Viestit joissa mainitaan käyttäjänimeni", + "Toolbox": "Työkalut", + "Collecting logs": "Haetaan lokitietoja", + "more": "lisää", + "Bug report sent": "Virheraportti lähetetty", + "You must specify an event type!": "Sinun on määritettävä tapahtuman tyyppi!", + "(HTTP status %(httpStatus)s)": "(HTTP tila %(httpStatus)s)", + "All Rooms": "Kaikki huoneet", + "Please install Chrome or Firefox for the best experience.": "Asenna Chrome tai Firefox parhaan käyttökokemuksen saavuttamiseksi.", + "Failed to get public room list": "Julkisten huoneiden listan hakeminen epäonnistui", + "Quote": "Lainaa", + "Send logs": "Lähetä lokit", + "All messages": "Kaikki viestit", + "Implementing VoIP services with Matrix": "VoIP-palvelujen implementointi Matrixin avulla", + "Dev chat for the Riot/Web dev team": "Kehittäjäkeskustelu Riot/Web kehitystiimille", + "Call invitation": "Puhelukutsu", + "Riot Desktop on %(platformName)s": "Riot Desktop %(platformName)s", + "Messages containing my display name": "Viestit joissa mainitaan nimimerkkini", + "State Key": "Tila-avain", + "Failed to send custom event.": "Kustomoidun tapahtuman lähettäminen epäonnistui.", + "What's new?": "Mikä on uutta?", + "Discussion of the Identity Service API": "Keskustelu Identity Service rajapinnasta", + "Support for those using and running matrix-appservice-irc": "Tuki niille jotka käyttävät ja ajavat matrix-appservice-irc", + "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk -keskustelu", + "Notify me for anything else": "Ilmoita minulle kaikesta muusta", + "When I'm invited to a room": "Kun minut kutsutaan huoneeseen", + "Design and implementation of E2E in Matrix": "Matrix päästä-päähän salauksen suunnittelu ja implementointi", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Voit käyttää edistyksellisiä asetuksia kirjautuaksesi muille Matrix palvelimille, määrittelemällä kotipalvelimen URL-osoitteen.
    Tämän avulla voit käyttää Riot:ia olemassa olevalla toisen Matrix palvelimen käyttäjätilillä.

    Voit myös asettaa valinnaisen identiteettipalvelimen, mutta et voi kutsua käyttäjiä sähköpostiosoitteella tai tulla kutsutuksi.", + "Can't update user notification settings": "Käyttäjän ilmoitusasetusten päivittäminen epäonnistui", + "Notify for all other messages/rooms": "Ilmoita kaikista muista viesteistä/huoneista", + "Unable to look up room ID from server": "Huone-ID:n haku palvelimelta epäonnistui", + "Couldn't find a matching Matrix room": "Vastaavaa Matrix-huonetta ei löytynyt", + "Support for those using the Matrix spec": "Tuki Matrix-spesifikaation käyttäjille", + "Safari and Opera work too.": "Safari ja Opera toimivat myös.", + "Loading bug report module": "Ladataan bugiraportointimoduuli", + "Invite to this room": "Kutsu käyttäjiä", + "You cannot delete this message. (%(code)s)": "Et voi poistaa tätä viestiä. (%(code)s)", + "Thursday": "Torstai", + "I understand the risks and wish to continue": "Ymmärrän riskit ja haluan jatkaa", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s %(browserName)s %(osName)s", + "Back": "Takaisin", + "Reply": "Vastaa", + "Show message in desktop notification": "Näytä viestit ilmoituskeskuksessa", + "Unhide Preview": "Näytä ennakkokatselu", + "Announcements about Synapse releases": "Ilmoitukset uusista Synapse-julkaisuista", + "Search the room directory": "Hae hakemistosta", + "Please describe the bug and/or send logs.": "Ole hyvä ja kuvaile virhe sekä/tai lähetä lokitiedot.", + "Unable to join network": "Verkkoon liittyminen epäonnistui", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Olet saattanut muuttaa niitä toisessa asiakasohjelmassa kuin Riot. Et voi muuttaa niitä Riotissa mutta ne pätevät kuitenkin", + "Sorry, your browser is not able to run Riot.": "Valitettavasti Riot ei toimi selaimessasi.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Salattua ja vikasietoista viestintää Matrix -teknologialla", + "Uploaded on %(date)s by %(user)s": "Ladattu %(date)s käyttäjän %(user)s toimesta", + "Messages in group chats": "Viestit ryhmäkeskusteluissa", + "Yesterday": "Eilen", + "Error encountered (%(errorDetail)s).": "Virhe: %(errorDetail)s.", + "Login": "Kirjaudu sisään", + "Low Priority": "Matala prioriteetti", + "Unable to fetch notification target list": "Ilmoituskohdelistan haku epäonnistui", + "Set Password": "Aseta salasana", + "Appear Offline": "Offline-tila", + "Get started with some tips from Riot Bot!": "Aloita Riot Botin vinkkien avulla!", + "An error occurred whilst saving your email notification preferences.": "Sähköposti-ilmoitusasetuksia tallettaessa tapahtui virhe.", + "Enable audible notifications in web client": "Ota käyttöön äänelliset ilmoitukset", + "Permalink": "Pysyvä linkki", + "remove %(name)s from the directory.": "poista %(name)s hakemistosta.", + "Off": "Pois päältä", + "Riot does not know how to join a room on this network": "Riot ei tiedä miten liittya huoneeseen tässä verkossa", + "Mentions only": "Vain maininnat", + "Failed to remove tag %(tagName)s from room": "Tagin %(tagName)s poistaminen huoneelta epäonnistui", + "Wednesday": "Keskiviikko", + "You can now return to your account after signing out, and sign in on other devices.": "Voit nyt palata tilillesi kirjauduttua ulos, sekä kirjautua muilla laitteilla.", + "Please install Chrome or Firefox for the best experience.": "Ole hyvä ja asenna Chrome tai Firefox parhaan kokemuksen saavuttamiseksi.", + "Enable email notifications": "Ota käyttöön sähköposti-ilmoitukset", + "Event Type": "Tapahtuman tyyppi", + "Download this file": "Lataa tiedosto", + "Pin Message": "Kiinnitä viesti", + "Failed to change settings": "Asetusten muuttaminen epäonnistui", + "View Community": "Näytä yhteisö", + "%(count)s Members|one": "%(count)s jäsen", + "Event sent!": "Tapahtuma lähetetty!", + "Matrix technical discussions": "Tekniset keskustelut", + "Event Content": "Tapahtuman sisältö", + "Thank you!": "Kiitos!", + "Building services on Matrix": "Palveluiden rakentaminen Matrixin avulla", + "Collapse panel": "Piilota paneeli", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Nykyisellä selaimellasi ohjelman ulkonäkö voi olla aivan virheellinen, ja jotkut ominaisuudet eivät saata toimia. Voit jatkaa jos haluat kokeilla mutta et voi odottaa saavasi apua mahdollisesti ilmeneviin ongelmiin!", + "Checking for an update...": "Tarkistetaan päivityksen saatavuutta...", + "General discussion about Matrix and Riot": "Matrix- ja Riot keskustelut", + "There are advanced notifications which are not shown here": "On kehittyneitä ilmoituksia joita ei näytetä tässä" } diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 25cfc6cc82..d30c4e6a71 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -1015,5 +1015,200 @@ "Show Stickers": "Afficher les stickers", "Manage sticker packs": "Gérer les packs de stickers", "Who can join this community?": "Qui peut rejoindre cette communauté ?", - "Everyone": "Tout le monde" + "Everyone": "Tout le monde", + "Fetching third party location failed": "Échec de la récupération de la localisation tierce", + "A new version of Riot is available.": "Une nouvelle version de Riot est disponible.", + "Riot/Android & matrix-android-sdk chat": "Discussions sur Riot/Android & matrix-android-sdk", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Veuillez décrire l'erreur. Qu'avez-vous fait ? Quel était le comportement attendu ? Que s'est-il réellement passé ?", + "Couldn't load home page": "Impossible de charger la page d'accueil", + "Send Account Data": "Envoyer les données du compte", + "All notifications are currently disabled for all targets.": "Toutes les notifications sont désactivées pour tous les appareils.", + "Uploading report": "Envoi du rapport", + "Sunday": "Dimanche", + "Notification targets": "Appareils recevant les notifications", + "Today": "Aujourd'hui", + "Files": "Fichiers", + "Report a bug": "Signaler un problème", + "Implementing VR services with Matrix": "Implémentation de services de réalité virtuelle avec Matrix", + "You are not receiving desktop notifications": "Vous ne recevez pas les notifications sur votre bureau", + "Friday": "Vendredi", + "Update": "Mettre à jour", + "You need to be using HTTPS to place a screen-sharing call.": "Vous devez utiliser HTTPS pour effectuer un appel en partage d’écran.", + "What's New": "Nouveautés", + "Add an email address above to configure email notifications": "Ajouter une adresse e-mail pour la configuration des notifications par e-mail", + "Expand panel": "Dévoiler le panneau", + "On": "Activé", + "%(count)s Members|other": "%(count)s membres", + "Filter room names": "Filtrer les salons par nom", + "Changelog": "Journal des modifications", + "Running Matrix services": "Exécution de services Matrix", + "Waiting for response from server": "En attente d’une réponse du serveur", + "Send Custom Event": "Envoyer l'événement personnalisé", + "Failed to send report: ": "Échec de l’envoi du rapport : ", + "Unknown device": "Appareil inconnu", + "Advanced notification settings": "Paramètres de notification avancés", + "delete the alias.": "supprimer l'alias.", + "To return to your account in future you need to set a password": "Pour pouvoir retrouver votre compte dans le futur, vous devez définir un mot de passe", + "Forget": "Oublier", + "#example": "#exemple", + "Riot/Web & Desktop chat": "Discussions sur Riot/Web & Bureau", + "Hide panel": "Cacher le panneau", + "You cannot delete this image. (%(code)s)": "Vous ne pouvez pas supprimer cette image. (%(code)s)", + "Cancel Sending": "Annuler l'envoi", + "This Room": "Ce salon", + "The Home Server may be too old to support third party networks": "Le serveur d'accueil semble trop ancien pour supporter des réseaux tiers", + "Noisy": "Bruyant", + "Room not found": "Salon non trouvé", + "Messages containing my display name": "Messages contenant mon nom affiché", + "Messages in one-to-one chats": "Messages dans les discussions directes", + "Contributing code to Matrix and Riot": "Contribuer du code à Matrix et Riot", + "Unavailable": "Indisponible", + "Community-run support for Synapse": "Support communautaire sur Synapse", + "View Decrypted Source": "Voir la source déchiffrée", + "Failed to update keywords": "Échec dans la mise à jour des mots-clés", + "remove %(name)s from the directory.": "supprimer %(name)s du répertoire.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Les notifications pour les mots-clés suivant répondent à des critères qui ne peuvent pas être affichés ici :", + "Safari and Opera work too.": "Safari et Opera fonctionnent également.", + "Please set a password!": "Veuillez définir un mot de passe !", + "You have successfully set a password!": "Vous avez défini un mot de passe avec succès !", + "Chat with Riot Bot": "Discussion avec Riot Bot", + "Support for those using, running and writing other bridges": "Support pour les utilisateurs, administrateurs et développeurs d'autres passerelles", + "Admin support for Dendrite": "Support admin pour Dendrite", + "An error occurred whilst saving your email notification preferences.": "Une erreur est survenue lors de la sauvegarde de vos préférences de notification par e-mail.", + "Explore Room State": "Parcourir l'état du salon", + "Source URL": "URL de la source", + "Messages sent by bot": "Messages envoyés par des robots", + "Filter results": "Filtrer les résultats", + "Members": "Membres", + "No update available.": "Aucune mise à jour disponible.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "De nombreux salons existent déjà dans Matrix, liés à des réseaux existants (Slack, IRC, Gitter etc) ou indépendants. Jetez un œil au répertoire !", + "Resend": "Renvoyer", + "Failed to get protocol list from Home Server": "Échec lors de la récupération de la liste sur le serveur", + "Collecting app version information": "Récupération des informations de version de l’application", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Supprimer l'alias %(alias)s du salon et supprimer %(name)s du répertoire ?", + "customServer_text": "Vous pouvez utiliser les options de serveur personnalisées pour vous connecter à d'autres serveurs Matrix, en spécifiant une adresse de serveur d'accueil différente.
    Cela permet d'utiliser Riot avec un compte Matrix existant sur un serveur d'accueil différent.

    Vous pouvez aussi indiquer un serveur d'identité personnalisé mais vous ne pourrez pas inviter d'utilisateurs par e-mail ou être invité par e-mail.", + "Co-ordination for Riot/Web translators": "Coordination des traducteurs de Riot/Web", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Cela vous permettra de retourner sur votre compte après vous être déconnecté, et de vous identifier sur d'autres appareils.", + "Dev chat for the Dendrite dev team": "Discussion pour l'équipe de développeurs de Dendrite", + "Keywords": "Mots-clés", + "Enable notifications for this account": "Activer les notifications pour ce compte", + "Directory": "Répertoire", + "Invite to this community": "Inviter à cette communauté", + "Failed to get public room list": "Échec lors de la récupération de la liste des salons publics", + "Messages containing keywords": "Messages contenant des mots-clés", + "Error saving email notification preferences": "Erreur lors de la sauvegarde des préférences de notification par e-mail", + "Tuesday": "Mardi", + "Enter keywords separated by a comma:": "Entrez les mots-clés séparés par une virgule :", + "Search…": "Rechercher…", + "You have successfully set a password and an email address!": "Vous avez défini un mot de passe et une adresse e-mail avec succès !", + "Remove %(name)s from the directory?": "Supprimer %(name)s du répertoire ?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot utilise de nombreuses fonctionnalités avancées du navigateur, certaines ne sont pas disponibles ou expérimentales dans votre navigateur actuel.", + "Developer Tools": "Outils de développement", + "Enable desktop notifications": "Activer les notifications de bureau", + "Remember, you can always set an email address in user settings if you change your mind.": "Souvenez-vous que vous pourrez toujours définir une adresse e-mail dans les paramètres de l'utilisateur si vous changez d’avis.", + "Explore Account Data": "Explorer les données du compte", + "Remove from Directory": "Supprimer du répertoire", + "Away": "Absent", + "Saturday": "Samedi", + "I understand the risks and wish to continue": "Je comprends les risques et souhaite continuer", + "Direct Chat": "Discussion directe", + "The server may be unavailable or overloaded": "Le serveur est indisponible ou surchargé", + "Reject": "Rejeter", + "Riot is not supported on mobile web. Install the app?": "Riot n’est pas supporté sur les appareils mobiles. Installer l’application ?", + "Discussion of all things Matrix!": "Discussion sur tout ce qui concerne Matrix !", + "Failed to set Direct Message status of room": "Échec du réglage de l'état du salon en Discussion directe", + "Monday": "Lundi", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Afin de diagnostiquer les problèmes, les journaux de ce client vont être envoyés avec ce rapport d’erreur. Si vous préférez n'envoyer que le texte ci-dessus, décochez la case :", + "Send Custom State Event": "Envoyer l'événement d'état personnalisé", + "All messages (noisy)": "Tous les messages (fort)", + "Enable them now": "Les activer maintenant", + "Messages containing my user name": "Message contenant mon nom d'utilisateur", + "Describe your problem here.": "Décrivez votre problème ici.", + "Toolbox": "Boîte à outils", + "Collecting logs": "Récupération des journaux", + "more": "plus", + "Bug report sent": "Rapport d'erreur envoyé", + "You must specify an event type!": "Vous devez spécifier un type d'événement !", + "(HTTP status %(httpStatus)s)": "(état HTTP %(httpStatus)s)", + "Invite to this room": "Inviter dans ce salon", + "Please install Chrome or Firefox for the best experience.": "Veuillez installer Chrome ou Firefox pour une expérience optimale.", + "Wednesday": "Mercredi", + "You cannot delete this message. (%(code)s)": "Vous ne pouvez pas supprimer ce message. (%(code)s)", + "Quote": "Citer", + "Send logs": "Envoyer les journaux", + "All messages": "Tous les messages", + "Implementing VoIP services with Matrix": "Implémentation de services de voix sur IP avec Matrix", + "Dev chat for the Riot/Web dev team": "Discussions de l'équipe de développeurs de Riot/Web", + "Call invitation": "Appel entrant", + "Riot Desktop on %(platformName)s": "Version bureau de Riot sur %(platformName)s", + "Downloading update...": "Mise à jour en cours de téléchargement...", + "State Key": "Clé d'état", + "Failed to send custom event.": "Échec de l'envoi de l'événement personnalisé.", + "What's new?": "Nouveautés ?", + "Discussion of the Identity Service API": "Discussion sur l’API du Service Identité", + "Support for those using and running matrix-appservice-irc": "Support pour ceux qui utilisent et exécutent matrix-appservice-irc", + "Riot/iOS & matrix-ios-sdk chat": "Discussions sur Riot/iOS & matrix-ios-sdk", + "Notify me for anything else": "Me notifier pour tout le reste", + "View Source": "Voir la source", + "Design and implementation of E2E in Matrix": "Définition et implémentation du chiffrement de bout en bout dans Matrix", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Vous pouvez utiliser les options de serveur personnalisé pour vous connecter à d'autres serveurs Matrix en précisant un serveur d'accueil différent.
    Cela vous permet d'utiliser Riot avec un compte Matrix existant sur un autre serveur d'accueil.

    Vous pouvez aussi renseigner un serveur d'identité personnalisé mais vous ne pourrez pas inviter d'utilisateurs avec leur adresse e-mail, ou être invité avec votre adresse e-mail.", + "Can't update user notification settings": "Impossible de mettre à jour les paramètres de notification de l'utilisateur", + "Notify for all other messages/rooms": "Me notifier pour tous les autres messages/salons", + "Unable to look up room ID from server": "Impossible de récupérer l'ID du salon sur le serveur", + "Couldn't find a matching Matrix room": "Impossible de trouver un salon Matrix correspondant", + "Support for those using the Matrix spec": "Support pour les utilisateurs de la spécification de Matrix", + "Safari and Opera work too.": "Safari et Opera fonctionnent aussi.", + "Loading bug report module": "Chargement du module de rapport d’erreur", + "All Rooms": "Tous les salons", + "Search for a room": "Rechercher un salon", + "Thursday": "Jeudi", + "Forward Message": "Transférer le message", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s dans %(browserName)s sous %(osName)s", + "Back": "Retour", + "Reply": "Répondre", + "Show message in desktop notification": "Afficher le message dans les notifications de bureau", + "Unhide Preview": "Dévoiler l'aperçu", + "Announcements about Synapse releases": "Communiqués sur les nouvelles versions de Synapse", + "Search the room directory": "Rechercher dans le répertoire de salons", + "Please describe the bug and/or send logs.": "Veuillez décrire le problème et/ou envoyer les journaux.", + "Unable to join network": "Impossible de rejoindre le réseau", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Vous les avez probablement configurées dans un autre client que Riot. Vous ne pouvez pas les configurer dans Riot mais elles s'appliquent quand même", + "Sorry, your browser is not able to run Riot.": "Désolé, Riot n'est pas supporté par votre navigateur.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Discussion & collaboration décentralisées et chiffrées, propulsées par [matrix]", + "Uploaded on %(date)s by %(user)s": "Téléchargé le %(date)s par %(user)s", + "Messages in group chats": "Messages dans les discussions de groupe", + "Yesterday": "Hier", + "Error encountered (%(errorDetail)s).": "Erreur rencontrée (%(errorDetail)s).", + "Login": "Connexion", + "Low Priority": "Priorité basse", + "Unable to fetch notification target list": "Impossible de récupérer la liste des appareils recevant les notifications", + "Appear Offline": "Apparaître Hors ligne", + "Get started with some tips from Riot Bot!": "Démarrer avec quelques astuces de Riot Bot !", + "Set Password": "Définir un mot de passe", + "Enable audible notifications in web client": "Activer les notifications sonores pour le client web", + "Permalink": "Permalien", + "Welcome to Riot.im": "Bienvenue sur Riot.im", + "Off": "Désactivé", + "Riot does not know how to join a room on this network": "Riot ne peut pas joindre un salon sur ce réseau", + "Mentions only": "Seulement les mentions", + "You can now return to your account after signing out, and sign in on other devices.": "Vous pouvez maintenant revenir sur votre compte après vous être déconnecté, et vous identifier sur d'autres appareils.", + "Please install Chrome or Firefox for the best experience.": "Veuillez installer Chrome ou Firefox pour une expérience optimale.", + "Enable email notifications": "Activer les notifications par e-mail", + "Event Type": "Type d'événement", + "Download this file": "Télécharger ce fichier", + "Pin Message": "Épingler le message", + "Failed to change settings": "Échec de la mise à jour des paramètres", + "View Community": "Voir la communauté", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Depuis votre navigateur actuel, le visuel et le ressenti de l'application pourraient être complètement erronés, et certaines fonctionnalités pourraient ne pas être supportées. Vous pouvez continuer malgré tout, mais vous n'aurez aucune aide si vous rencontrez des problèmes !", + "%(count)s Members|one": "%(count)s membre", + "Event sent!": "Événement envoyé !", + "Matrix technical discussions": "Discussions techniques sur Matrix", + "Event Content": "Contenu de l'événement", + "Thank you!": "Merci !", + "Building services on Matrix": "Développement de services sur Matrix", + "Collapse panel": "Cacher le panneau", + "When I'm invited to a room": "Quand je suis invité dans un salon", + "Checking for an update...": "Recherche de mise à jour...", + "General discussion about Matrix and Riot": "Discussion générale sur Matrix et Riot", + "There are advanced notifications which are not shown here": "Il existe une configuration avancée des notifications qui ne peut être affichée ici" } diff --git a/src/i18n/strings/gl.json b/src/i18n/strings/gl.json index bc86593fc4..e0b94e5fcd 100644 --- a/src/i18n/strings/gl.json +++ b/src/i18n/strings/gl.json @@ -1003,5 +1003,207 @@ "Debug Logs Submission": "Envío de rexistro de depuración", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Si enviou un reporte de fallo a través de GitHub, os informes poden axudarnos a examinar o problema. Os informes de fallo conteñen datos do uso do aplicativo incluíndo o seu nome de usuaria, os IDs ou alcumes das salas e grupos que visitou e os nomes de usuaria de outras personas. Non conteñen mensaxes.", "Submit debug logs": "Enviar informes de depuración", - "Opens the Developer Tools dialog": "Abre o cadro de Ferramentas de Desenvolvedoras" + "Opens the Developer Tools dialog": "Abre o cadro de Ferramentas de Desenvolvedoras", + "Fetching third party location failed": "Fallo ao obter a localización de terceiros", + "A new version of Riot is available.": "Está dispoñible unha nova versión de Riot.", + "Riot/Android & matrix-android-sdk chat": "Chat para Riot/Android & matrix-android-sdk", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Por favor describa a incidencia. Que estaba a facer? Que tiña que pasar? Que aconteceu en realidade?", + "Couldn't load home page": "Non se cargou a páxina de inicio", + "Send Account Data": "Enviar datos da conta", + "All notifications are currently disabled for all targets.": "Todas as notificacións están deshabilitadas para todos os destinos.", + "Uploading report": "Informe da subida", + "Sunday": "Domingo", + "Notification targets": "Obxetivos das notificacións", + "Today": "Hoxe", + "Failed to get protocol list from Home Server": "Fallo ao obter a lista de protocolo desde o servidor", + "Report a bug": "Informar de un fallo", + "Implementing VR services with Matrix": "Implementando servizos de RV con Matrix", + "You are not receiving desktop notifications": "Non está a recibir notificacións de escritorio", + "Friday": "Venres", + "Update": "Actualizar", + "You need to be using HTTPS to place a screen-sharing call.": "Precisa utilizar HTTPS para establecer unha chamada de pantalla compartida.", + "What's New": "Qué hai de novo", + "Add an email address above to configure email notifications": "Engada un enderezo de correo electrónico para configurar as notificacións", + "Expand panel": "Expandir panel", + "On": "On", + "%(count)s Members|other": "%(count)s Membros", + "Filter room names": "Filtrar nomes de sala", + "Changelog": "Rexistro de cambios", + "Running Matrix services": "Servizos correndo sobre Matrix", + "Waiting for response from server": "Agardando pola resposta do servidor", + "Send Custom Event": "Enviar evento personalizado", + "Failed to send report: ": "Fallo no envío do informe: ", + "Unknown device": "Dispositivo descoñecido", + "Advanced notification settings": "Axustes avanzados de notificación", + "Failed to send logs: ": "Fallo ao enviar os informes: ", + "delete the alias.": "borrar alcume.", + "To return to your account in future you need to set a password": "Para voltar a súa conta no futuro debe establecer un contrasinal>/u>", + "Forget": "Esquecer", + "#example": "#exemplo", + "Riot/Web & Desktop chat": "Riot/Web & chat de Escritorio", + "Hide panel": "Agochar panel", + "You cannot delete this image. (%(code)s)": "Non pode eliminar esta imaxe. (%(code)s)", + "Cancel Sending": "Cancelar o envío", + "This Room": "Esta sala", + "The Home Server may be too old to support third party networks": "O servidor de inicio podería ser demasiando antigo como para aceptar redes de terceiros", + "Noisy": "Ruidoso", + "Error saving email notification preferences": "Fallo ao cargar os axustes de notificacións", + "Messages containing my display name": "Mensaxes que conteñen o meu nome público", + "Messages in one-to-one chats": "Mensaxes en chats un-a-un", + "Contributing code to Matrix and Riot": "Contribuíndo ao código en Matrix e Riot", + "Unavailable": "Non dispoñible", + "Community-run support for Synapse": "Axuda da comunidade para Synapse", + "View Decrypted Source": "Ver a fonte descifrada", + "Failed to update keywords": "Fallo ao actualizar as palabras chave", + "Notes:": "Notas:", + "remove %(name)s from the directory.": "eliminar %(name)s do directorio.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Notificacións das reglas de seguimento das seguintes palabras que non se mostrarán aquí:", + "Safari and Opera work too.": "Safari e Opera tamén funcionan.", + "Please set a password!": "Por favor estableza un contrasinal!", + "You have successfully set a password!": "Mudou con éxito o seu contrasinal!", + "Chat with Riot Bot": "Chat co Bot de Riot", + "Support for those using, running and writing other bridges": "Axuda para que utiliza, executa e desenvolve outras pontes", + "Admin support for Dendrite": "Axuda administrador para Dendrite", + "An error occurred whilst saving your email notification preferences.": "Algo fallou mentras se gardaban as súas preferencias de notificaicón.", + "Explore Room State": "Explorar estado da sala", + "Search for a room": "Buscar unha sala", + "Source URL": "URL fonte", + "Messages sent by bot": "Mensaxes enviadas por bot", + "Filter results": "Filtrar resultados", + "Members": "Membresía", + "No update available.": "Sen actualizacións.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Xa existen multitude de salas en Matrix, ligadas a redes existentes (Slack, IRC, Gitter etc) ou independentes. Busque no directorio!", + "Resend": "Voltar a enviar", + "Files": "Ficheiros", + "Collecting app version information": "Obtendo información sobre a versión da app", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Eliminar o alcume da sala %(alias)s e borrar %(name)s do directorio?", + "customServer_text": "Pode utilizar os axustes do servidor personalizado para conectarse a outros servidores Matrix indicando un URL de Inicio do servidor.
    Esto permítelle utilizar Riot con unha conta existente de Matrix nun servidor diferente.

    Tamén pode establecer un servidor personalizado de identidade mais non poderá invitar a usuarias a través de enderezos de correo ou ser vostede invitada do mesmo xeito.", + "Co-ordination for Riot/Web translators": "Coordinación para tradutores de Riot/Web", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Esto permitiralle voltar a súa conta tras desconectarse, e conectarse en outros dispositivos.", + "Dev chat for the Dendrite dev team": "Chat para o equipo de desenvolvemento de Dendrite", + "Keywords": "Palabras chave", + "Enable notifications for this account": "Habilitar notificacións para esta conta", + "Directory": "Directorio", + "Invite to this community": "Convidar a esta comunidade", + "Failed to get public room list": "Fallo ao obter a lista de salas públicas", + "Messages containing keywords": "Mensaxes que conteñen palabras chave", + "Room not found": "Non se atopou a sala", + "Tuesday": "Martes", + "Enter keywords separated by a comma:": "Introduza palabras chave separadas por vírgulas:", + "Search…": "Buscar…", + "Remove %(name)s from the directory?": "Eliminar %(name)s do directorio?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot utiliza características avanzadas do navegador, algunhas das cales non están dispoñibles ou son experimentales no seu navegador actual.", + "Developer Tools": "Ferramentas para desenvolver", + "Preparing to send logs": "Preparándose para enviar informe", + "Enable desktop notifications": "Habilitar notificacións de escritorio", + "Remember, you can always set an email address in user settings if you change your mind.": "Lembre, sempre poderá poñer un enderezo de correo nos axustes de usuario si cambia de idea.", + "Explore Account Data": "Explorar datos da conta", + "All messages (noisy)": "Todas as mensaxes (alto)", + "Away": "Fóra", + "Saturday": "Sábado", + "I understand the risks and wish to continue": "Entendos os riscos e desexo continuar", + "Direct Chat": "Chat directo", + "The server may be unavailable or overloaded": "O servidor podería non estar dispoñible ou sobrecargado", + "Reject": "Rexeitar", + "Riot is not supported on mobile web. Install the app?": "Riot no se pode executar na web móbil. Instalar a app?", + "Discussion of all things Matrix!": "Conversa sobre to o relativo a Matrix!", + "Failed to set Direct Message status of room": "Fallo ao establecer o estado Mensaxe Directa da sala", + "Monday": "Luns", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Para poder diagnosticar o problema, os rexistros de este cliente enviaranse neste informe de fallo. Si prefire enviar só o texto superior, desmarque:", + "Send Custom State Event": "Enviar evento de estado personalizado", + "Remove from Directory": "Eliminar do directorio", + "Enable them now": "Habilitalas agora", + "Messages containing my user name": "Mensaxes que conteñen o meu nome de usuaria", + "Describe your problem here.": "Describa aquí o seu problema.", + "Toolbox": "Ferramentas", + "Collecting logs": "Obtendo rexistros", + "more": "máis", + "GitHub issue link:": "Ligazón ao reporte en GitHub:", + "Bug report sent": "Enviado o informe de fallo", + "You must specify an event type!": "Debe indicar un tipo de evento!", + "(HTTP status %(httpStatus)s)": "(Estado HTTP %(httpStatus)s)", + "All Rooms": "Todas as Salas", + "State Key": "Chave do estado", + "Please install Chrome or Firefox for the best experience.": "Por favor instale Chrome ou Firefox para a mellor experiencia de usuaria.", + "Wednesday": "Mércores", + "Quote": "Cita", + "Send logs": "Enviar informes", + "All messages": "Todas as mensaxes", + "Implementing VoIP services with Matrix": "Implementación de servizos VoIP con Matrix", + "Dev chat for the Riot/Web dev team": "Chat para o equipo de desenvolvemento do Riot/Web", + "Call invitation": "Convite de chamada", + "Riot Desktop on %(platformName)s": "Riot Desktop en %(platformName)s", + "Downloading update...": "Descargando actualización...", + "You have successfully set a password and an email address!": "Estableceu correctamente un contrasinal e enderezo de correo!", + "Failed to send custom event.": "Fallo ao enviar evento personalizado.", + "What's new?": "Qué hai de novo?", + "Discussion of the Identity Service API": "Conversa sobre a Identity Service API", + "Support for those using and running matrix-appservice-irc": "Axuda para quen usa matrix-appservice-irc", + "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & chat matrix-ios-sdk", + "Notify me for anything else": "Notificarme todo o demáis", + "When I'm invited to a room": "Cando son convidado a unha sala", + "Design and implementation of E2E in Matrix": "Deseño e implementación de E2E en Matrix", + "Click here to create a GitHub issue.": "Pulse aquí para crear un reporte en GitHub.", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Vostede pode utilizar as opcións de servidor personalizado para conectarse a outros servidores Matrix indicando o enderezo URL do Servidor.
    Esto permítelle utilizar Riot con unha conta Matrix existente en outro servidor.

    Tamén pode indicar un servidor de identidade pero non poderá convidar a usarias polo seu enderezo de correo electrónico, o ser convidada vostede por correo electrónico.", + "Can't update user notification settings": "Non se poden actualizar os axutes de notificación", + "Notify for all other messages/rooms": "Notificar para todas as outras mensaxes/salas", + "Unable to look up room ID from server": "Non se puido atopar o ID da sala do servidor", + "Couldn't find a matching Matrix room": "Non coincide con ningunha sala de Matrix", + "Support for those using the Matrix spec": "Axuda para quen usa a especificación Matrix", + "Safari and Opera work too.": "Safari e Opera tamén serven.", + "Loading bug report module": "Cargando o módulo de informe de fallos", + "Invite to this room": "Convidar a esta sala", + "You cannot delete this message. (%(code)s)": "Non pode eliminar esta mensaxe. (%(code)s)", + "Thursday": "Xoves", + "Forward Message": "Reenviar mensaxe", + "Logs sent": "Informes enviados", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s vía %(browserName)s en %(osName)s", + "Back": "Atrás", + "Reply": "Resposta", + "Show message in desktop notification": "Mostrar mensaxe nas notificacións de escritorio", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Os informes de depuración conteñen datos de utilización do aplicativo como o seu nome de usuaria, os IDs ou alcumes de salas e grupos que vostede visitou e os nomes de usuaria de outras usuarias. Non conteñen mensaxes.", + "Unhide Preview": "Desagochar a vista previsa", + "Announcements about Synapse releases": "Anuncios sobre lanzamentos de Synapse", + "Search the room directory": "Buscar no directorio de salas", + "Please describe the bug and/or send logs.": "Por favor describa a incidencia e/ou envíe o informe.", + "Unable to join network": "Non se puido conectar a rede", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Pode que os configurase nun cliente diferente de Riot. Non pode establecelos desde Riot pero aínda así aplicaranse", + "Sorry, your browser is not able to run Riot.": "Desculpe, o seu navegador non pode executar Riot.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Chat & colaboración descentralizados e cifrados grazas a [matrix]", + "Uploaded on %(date)s by %(user)s": "Subido a %(date)s por %(user)s", + "Messages in group chats": "Mensaxes en grupos de chat", + "Yesterday": "Onte", + "Error encountered (%(errorDetail)s).": "Houbo un erro (%(errorDetail)s).", + "Login": "Conectar", + "Low Priority": "Baixa prioridade", + "Unable to fetch notification target list": "Non se puido procesar a lista de obxetivo de notificacións", + "Appear Offline": "Aparecer fora de liña", + "Get started with some tips from Riot Bot!": "Iníciese con algúns consellos do Bot de Riot!", + "Set Password": "Establecer contrasinal", + "Enable audible notifications in web client": "Habilitar notificacións audibles no cliente web", + "Permalink": "Ligazón permanente", + "Welcome to Riot.im": "Benvida a Riot.im", + "Off": "Off", + "Riot does not know how to join a room on this network": "Riot non sabe cómo conectar con unha sala en esta rede", + "Mentions only": "Só mencións", + "You can now return to your account after signing out, and sign in on other devices.": "Pode voltar a súa contra tras desconectarse, e conectarse en outros dispositivos.", + "Please install Chrome or Firefox for the best experience.": "Por favor instale Chrome ou Firefox para ter a mellor experiencia de uso.", + "Enable email notifications": "Habilitar notificacións de correo", + "Event Type": "Tipo de evento", + "Download this file": "Descargue este ficheiro", + "Pin Message": "Fixar mensaxe", + "Failed to change settings": "Fallo ao cambiar os axustes", + "View Community": "Ver Comunidade", + "%(count)s Members|one": "%(count)s Membro", + "Event sent!": "Evento enviado!", + "View Source": "Ver fonte", + "Matrix technical discussions": "Discusións técnicas sobre Matrix", + "Event Content": "Contido do evento", + "Thank you!": "Grazas!", + "Building services on Matrix": "Deseñando servizos sobre Matrix", + "Collapse panel": "Agochar panel", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Co seu navegador actual a apareciencia e uso do aplicativo poderían estar totalmente falseadas, e algunhas características poderían non funcionar. Se quere pode continuar, pero debe ser consciente de que poden haber fallos!", + "Checking for an update...": "Comprobando as actualizacións...", + "General discussion about Matrix and Riot": "Discusión xeral sobre Matrix e Riot", + "There are advanced notifications which are not shown here": "Existen notificacións avanzadas que non se mostran aquí" } diff --git a/src/i18n/strings/he.json b/src/i18n/strings/he.json index e3de41600a..dd9219a776 100644 --- a/src/i18n/strings/he.json +++ b/src/i18n/strings/he.json @@ -85,5 +85,208 @@ "Unnamed room": "חדר ללא שם", "World readable": "העולם קריא", "Guests can join": "אורחים יכולים להצטרף", - "No rooms to show": "אין חדרים להצגה" + "No rooms to show": "אין חדרים להצגה", + "Fetching third party location failed": "נסיון להביא מיקום צד שלישי נכשל", + "A new version of Riot is available.": "יצאה גרסה חדשה של Riot.", + "Riot/Android & matrix-android-sdk chat": "Riot/Android & צ'ט matrix-android-sdk", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "נא תאר את הבאג. מה עשית? מה ציפית שיקרה? מה קרה בפועל?", + "Couldn't load home page": "כשל בטעינת דף הבית", + "Send Account Data": "שלח נתוני משתמש", + "All notifications are currently disabled for all targets.": "התראות מנוטרלות לכלל המערכת.", + "Uploading report": "מעדכן דוח", + "Sunday": "ראשון", + "Failed to add tag %(tagName)s to room": "נכשל בעת הוספת תג %(tagName)s לחדר", + "Notification targets": "יעדי התראה", + "Failed to set direct chat tag": "נכשל בעת סימון תג לשיחה ישירה", + "Today": "היום", + "Files": "קבצים", + "Report a bug": "דווח על שגיאה", + "Implementing VR services with Matrix": "מימוש שירותי VR ב Matrix", + "You are not receiving desktop notifications": "אתה לא מקבל התראות משולחן העבודה", + "Friday": "שישי", + "Update": "עדכון", + "You need to be using HTTPS to place a screen-sharing call.": "עליך להשתמש ב HTTPS בכדי לבצע שיחת ווידאו משותפת.", + "What's New": "מה חדש", + "Add an email address above to configure email notifications": "הוסף כתובת דואר אלקטורני למעלה בכדי להגדיר התראות", + "Expand panel": "הרחב מסגרת", + "On": "דלוק", + "%(count)s Members|other": "‭ ‭ ‮‭ םישמתשמ %(count)s", + "Filter room names": "סנן שמות חדרים", + "Changelog": "דו\"ח שינויים", + "Running Matrix services": "שירותי ה Matrix שרצים", + "Waiting for response from server": "ממתין לתשובה מהשרת", + "Send Custom Event": "שלח אירוע מותאם אישית", + "Failed to send report: ": "נכשל בעת שליחת דו\"ח: ", + "Unknown device": "מכשיר לא ידוע", + "Advanced notification settings": "הגדרות מתקדמות להתראות", + "Failed to send logs: ": "כשל במשלוח יומנים: ", + "delete the alias.": "מחיקת כינוי.", + "To return to your account in future you need to set a password": "להשתמש בחשבונך בעתיד, עליך להגדיר סיסמא", + "Forget": "שכח", + "#example": "#דוגמא", + "Riot/Web & Desktop chat": "Riot/Web & צ'ט שולחן עבודה", + "Hide panel": "הסתר מסגרת", + "You cannot delete this image. (%(code)s)": "אי אפשר למחוק את התמונה. (%(code)s)", + "Cancel Sending": "ביטול שליחה", + "This Room": "החדר הזה", + "The Home Server may be too old to support third party networks": "שרת הבית ישן ואינו יכול לתמוך ברשתות צד שלישי", + "Noisy": "רועש", + "Error saving email notification preferences": "שגיאה בעת שמירת הגדרות התראה באמצעות הדואר האלקטרוני", + "Messages containing my display name": "הודעות המכילות את שם התצוגה שלי", + "Messages in one-to-one chats": "הודעות בשיחות פרטיות", + "Contributing code to Matrix and Riot": "תרומת קוד ל Matrix ו Riot", + "Unavailable": "לא זמין", + "Community-run support for Synapse": "תמיכת הקהילה עבור Synapse", + "View Decrypted Source": "הצג מקור מפוענח", + "Failed to update keywords": "נכשל עדכון מילים", + "Notes:": "הערות:", + "remove %(name)s from the directory.": "הסר את %(name)s מהרשימה.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "התראה על מילות המפתח הבאות עוקבת אחר החוקים שאינם יכולים להיות מוצגים כאן:", + "Safari and Opera work too.": "Safari וגם Opera עובדים.", + "Please set a password!": "נא להגדיר סיסמא!", + "You have successfully set a password!": "שינוי סיסמא בוצע בהצלחה!", + "Chat with Riot Bot": "שיחה עם Riot בוט", + "Support for those using, running and writing other bridges": "שירות למשתמשים, שמריצים וכותבים חיבורים נוספים", + "Admin support for Dendrite": "תמיכת מנהל מערכת עבור Dendrite", + "An error occurred whilst saving your email notification preferences.": "קרתה שגיאה בזמן שמירת הגדרות התראה באמצעות הדואר האלקטרוני.", + "Explore Room State": "גלה מצב החדר", + "Source URL": "כתובת URL אתר המקור", + "Messages sent by bot": "הודעות שנשלחו באמצעות בוט", + "Filter results": "סנן התוצאות", + "Members": "חברים", + "No update available.": "אין עדכון זמין.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "הרבה חדרים כבר קיימים ב Matrix ומקושרים לרשתות קיימות (Slack, IRC, Gitter וכו') או עצמאיים. בדוק את הספרייה!", + "Resend": "שלח מחדש", + "Failed to get protocol list from Home Server": "נכשל בעת נסיון קבלת רשימת פרוטוקולים משרת הבית", + "Collecting app version information": "אוסף מידע על גרסת היישום", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "מחק כינוי %(alias)s של החדר והסר את %(name)s מהרשימה?", + "customServer_text": "אפשר להשתמש בהגדרות שרת מותאמות אישית בכדי להתחבר לשרתים אחרים באמצעות בחירת כתובת שרת בית שונה.
    זה יאפשר לך להשתמש ב Riot עם חשבון קיים ב Matrix אבל אל מול שרת בית שונה.

    כמו כן אפשר להגדיר זהות מותאמת אישית אבל אז לא תהיה אפשרות להזמין משתמשים באמצעות כתובת אימייל, או להזמין את עצמך באמצעות כתובת האימייל.", + "Co-ordination for Riot/Web translators": "תאום למתרגמי ה Riot/Web", + "This will allow you to return to your account after signing out, and sign in on other devices.": "זה יאפשר לך לחזור לחשבונך אחרי התנתקות ולהתחבר באמצעות התקנים אחרים.", + "Dev chat for the Dendrite dev team": "שיחת מפתחים עבור Dendrite", + "Keywords": "מילות מפתח", + "Enable notifications for this account": "אפשר התראות לחשבון זה", + "Directory": "ספרייה", + "Invite to this community": "הזמן לקהילה זו", + "Failed to get public room list": "נכשלה קבלת רשימת חדרים ציבוריים", + "Messages containing keywords": "הודעות המכילות מילות מפתח ", + "Room not found": "חדר לא נמצא", + "Tuesday": "שלישי", + "Enter keywords separated by a comma:": "הכנס מילים מופרדות באמצעות פסיק:", + "Forward Message": "העבר הודעה", + "Remove %(name)s from the directory?": "הסר את %(name)s מהרשימה?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot משתמש במספר רב של אפשרויות מתקדמות בדפדפן, חלק מהן לא זמינות או בשלבי נסיון בדפדפן שבשימושך כרגע.", + "Event sent!": "ארוע נשלח!", + "Preparing to send logs": "מתכונן לשלוח יומנים", + "Enable desktop notifications": "אפשר התראות בשולחן העבודה", + "Remember, you can always set an email address in user settings if you change your mind.": "להזכירך: תמיד ניתן לשנות כתובת אימייל בהגדרות משתש. למקרה שתתחרט/י.", + "Explore Account Data": "גלה פרטי משתמש", + "All messages (noisy)": "כל ההודעות (רועש)", + "Away": "מרוחק", + "Saturday": "שבת", + "I understand the risks and wish to continue": "אני מבין את הסיכונים אבל מבקש להמשיך", + "Direct Chat": "שיחה ישירה", + "The server may be unavailable or overloaded": "השרת אינו זמין או עמוס", + "Reject": "דחה", + "Riot is not supported on mobile web. Install the app?": "Riot לא נתמך באמצעות דפדפן במכשיר הסלולארי. האם להתקין את היישום?", + "Discussion of all things Matrix!": "דיון על כל הדברים הקשורים ל Matrix!", + "Failed to set Direct Message status of room": "נכשל בעת סימון מצב הודעה ישירה של החדר", + "Monday": "שני", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "בכדי לנתח את הבעיות, ישלח דוח עם פרטי הבעיה. אם ברצונך רק לשלוח את שנאמר למעלה, נא הסר את הסימון:", + "Remove from Directory": "הסר מהרשימה", + "Enable them now": "אפשר אותם כעת", + "Messages containing my user name": "הודעות המכילות את שם המשתמש שלי", + "Describe your problem here.": "תאר את הבעיה כאן.", + "Toolbox": "תיבת כלים", + "Collecting logs": "אוסף יומנים לנפוי שגיאה (דבאג)", + "more": "עוד", + "GitHub issue link:": "קישור לדווח תקלה בGitHub:", + "Search for a room": "חפש חדר", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "יומני ניפוי שגיאה (דבאג) מכילים מידע על שימוש ביישום, כולל שם משתמש, מזהים או כינויים שהתמשת בהם. בחדרי שיחוח, או קבוצות בהם השתתפת. וגם שמות משתמשים אחרים. אך אינם כוללים הודעות.", + "(HTTP status %(httpStatus)s)": "(מצב HTTP %(httpStatus)s )", + "All Rooms": "כל החדרים", + "State Key": "מקש מצב", + "Please install Chrome or Firefox for the best experience.": "אנא התקן Firefox או Chrome לחוויה מיטבית.", + "Wednesday": "רביעי", + "Quote": "ציטוט", + "Send logs": "שלח יומנים", + "All messages": "כל ההודעות", + "Implementing VoIP services with Matrix": "מימוש Voip ב Matrix", + "Dev chat for the Riot/Web dev team": "שיחה עם המפתחים עבור ה קבוצת הפיתוח של Riot/Web", + "Call invitation": "הזמנה לשיחה", + "Riot Desktop on %(platformName)s": "רייוט לשולחן העבודה על גבי %(platformName)s", + "Downloading update...": "מוריד עדכון...", + "You have successfully set a password and an email address!": "הצלחת להגדיר סיסמא וכתובת אימייל!", + "Failed to send custom event.": "כשל במשלוח ארוע מותאם אישית.", + "What's new?": "מה חדש?", + "Discussion of the Identity Service API": "דיון על API לשירות זהויות", + "Support for those using and running matrix-appservice-irc": "תמיכה למשתמשים ב matrix-appservice-irc", + "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & שיחה עם matrix-ios-sdk", + "Notify me for anything else": "התראה לי על כל דבר אחר", + "When I'm invited to a room": "מתי אני מוזמן לחדר", + "Design and implementation of E2E in Matrix": "תכנון וביצוע קצה לקצה ב Matrix", + "Click here to create a GitHub issue.": "הקלק כאן ליצירת דווח תקלה ‫ב: GitHub .", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "בכדי להיכנס לשרתים אחרים של מטריקס, אפשר להגדיר כתובת מוצא ראשית אחרת ל- URL שרתי מטריקס, בהגדרות: 'התאמה אישית לאפשרויות שרת'.
    ואז מתאפשר למשתמש ריוט לנצל חשבון משתמש מטריקס קיים, בשרתי מטריקס שונים.

    אפשר גם להגדיר בהתאמה אישית שרת הזדהות. אך אז לא ניתן להזמין משתמשים באימייל, ואי אפשר להזמינך באמצעות אימייל.", + "Can't update user notification settings": "לא ניתן לעדכן הגדרות התראה למשתמש", + "Notify for all other messages/rooms": "התראה לכל שאר ההודעות/החדרים", + "Unable to look up room ID from server": "לא ניתן לאתר מזהה חדר על השרת", + "Couldn't find a matching Matrix room": "לא נמצא חדר כזה ב מטריקס", + "Support for those using the Matrix spec": "תמיכה למשתמשים במאפייני ה Matrix", + "
    Safari and Opera work too.": " ספארי ו אופרה עובדים גם כן.", + "Loading bug report module": "טוען רכיב דיווח דו\"ח שגיאה", + "Invite to this room": "הזמן לחדר זה", + "You cannot delete this message. (%(code)s)": "לא ניתן למחוק הודעה זו. (%(code)s)", + "Thursday": "חמישי", + "Search…": "חפש…", + "Logs sent": "יומנים נשלחו", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s באמצעות הדפדפן %(browserName)s על גבי %(osName)s", + "Back": "אחורה", + "Reply": "תשובה", + "Show message in desktop notification": "הצג הודעה בהתראות שולחן עבודה", + "You must specify an event type!": "חובה להגדיר סוג ארוע!", + "Unhide Preview": "הצג מחדש תצוגה מקדימה", + "Announcements about Synapse releases": "הודעות לגבי גרסאות Synapse", + "Search the room directory": "חפש בספריית החדרים", + "Please describe the bug and/or send logs.": "נא תאר את הבאג ו/או שלח את הלוגים.", + "Unable to join network": "לא ניתן להצטרף לרשת", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "יתכן כי בצעת את ההגדרות בצד לקוח ולא ב Riot. לא תוכל לעדכן אותם ב Riot אבל הם עדיין תקפים", + "Sorry, your browser is not able to run Riot.": "מצטערים, הדפדפן שלך הוא אינו יכול להריץ את Riot.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "צ'ט מוצפן & ושת\"פ נעשה ע\"י ה [matrix]", + "Uploaded on %(date)s by %(user)s": "עודכן ב %(date)s ע\"י %(user)s", + "Messages in group chats": "הודעות בקבוצות השיחה", + "Yesterday": "אתמול", + "Error encountered (%(errorDetail)s).": "ארעה שגיעה %(errorDetail)s .", + "Login": "התחבר", + "Low Priority": "עדיפות נמוכה", + "Unable to fetch notification target list": "לא ניתן לאחזר רשימת יעדי התראה", + "Appear Offline": "מופיע מקוון", + "Get started with some tips from Riot Bot!": "התחל באמצעות מספר טיפים מהבוט של Riot!", + "Set Password": "הגדר סיסמא", + "Enable audible notifications in web client": "אפשר התראות קוליות בדפדפן", + "Permalink": "קישור קבוע", + "Welcome to Riot.im": "ברוכים הבאים ל Riot.im", + "Off": "סגור", + "Riot does not know how to join a room on this network": "Riot אינו יודע כיצד להצטרף לחדר ברשת זו", + "Mentions only": "מאזכר בלבד", + "Failed to remove tag %(tagName)s from room": "נכשל בעת נסיון הסרת תג %(tagName)s מהחדר", + "You can now return to your account after signing out, and sign in on other devices.": "תוכל עתה לחזור לחשבון שלך רק אחרי התנתקות וחיבור מחדש לחשבון ממכשיר אחר.", + "Please install Chrome or Firefox for the best experience.": "נא התקן כרום או פיירפוקס לשימוש מייטבי.", + "Enable email notifications": "אפשר התראות באמצעות הדואר האלקטרוני", + "Event Type": "סוג ארוע", + "Download this file": "הורד את הקובץ", + "Pin Message": "הצמד הודעה", + "Failed to change settings": "נכשל בעת שינוי הגדרות", + "View Community": "הצג קהילה", + "%(count)s Members|one": "‭ ‭ ‮‭ םישמתשמ %(count)s", + "Developer Tools": "כלי מפתחים", + "View Source": "הצג מקור", + "Matrix technical discussions": "פורום טכני של Matrix", + "Event Content": "תוכן הארוע", + "Thank you!": "רב תודות!", + "Building services on Matrix": "בניית שירותים על גבי ה Matrix", + "Collapse panel": "סגור מסגרת", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "באמצעות הדפדפן הנוכחי שלך המראה של היישום יכול להיות שגוי לחלוטין וחלק מהאפשרויות לא תתפקדנה. אם תרצה לנסות בכל זאת תוכל אבל אז כל האחריות עליך!", + "Checking for an update...": "בודק עדכונים...", + "General discussion about Matrix and Riot": "דיון כללי על Matrix ו Riot", + "There are advanced notifications which are not shown here": "ישנן התראות מתקדמות אשר אינן מוצגות כאן" } diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index b7f20d52f7..7140c6574c 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -1015,5 +1015,207 @@ "Show Stickers": "Matricák megjelenítése", "Manage sticker packs": "Matrica csomagok kezelése", "Who can join this community?": "Ki tud csatlakozni ehhez a közösséghez?", - "Everyone": "Mindenki" + "Everyone": "Mindenki", + "Fetching third party location failed": "Nem sikerült lekérdezni a harmadik fél helyét", + "A new version of Riot is available.": "Elérhető egy új Riot verzió.", + "Riot/Android & matrix-android-sdk chat": "Riot/Android és matrix-android-sdk csevegés", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Kérünk, írd le a hibát. Mit csináltál? Minek kellett volna történnie? Mi történt végül?", + "Couldn't load home page": "Nem sikerült betölteni a kezdőlapot", + "Send Account Data": "Fiókadatok küldése", + "All notifications are currently disabled for all targets.": "Minden céleszközön minden értesítés tiltva van.", + "Uploading report": "Jelentés feltöltése", + "Sunday": "Vasárnap", + "Notification targets": "Értesítések célpontja", + "Today": "Ma", + "Files": "Fájlok", + "Report a bug": "Hiba bejelentése", + "Implementing VR services with Matrix": "VR szolgáltatások implementációja Matrixba", + "You are not receiving desktop notifications": "Nem fogadsz asztali értesítéseket", + "Friday": "Péntek", + "Update": "Frissítés", + "You need to be using HTTPS to place a screen-sharing call.": "Képernyőmegosztás indításához HTTPS-t kell használnod.", + "What's New": "Újdonságok", + "Add an email address above to configure email notifications": "E-mail értesítések beállításához adj meg egy e-mail címet", + "Expand panel": "Panel kinyitása", + "On": "Be", + "%(count)s Members|other": "%(count)s tag", + "Filter room names": "Szobanevek szűrése", + "Changelog": "Változások", + "Running Matrix services": "Matrix szolgáltatások működtetése", + "Waiting for response from server": "Várakozás a szerver válaszára", + "Send Custom Event": "Egyéni esemény elküldése", + "Failed to send report: ": "A jelentést nem sikerült elküldeni: ", + "Unknown device": "Ismeretlen készülék", + "Advanced notification settings": "Haladó értesítési beállítások", + "Failed to send logs: ": "Hiba a napló küldésénél: ", + "delete the alias.": "becenév törlése.", + "To return to your account in future you need to set a password": "Hogy később visszaléphess a fiókodba, be kell állítanod egy jelszót", + "Forget": "Elfelejt", + "#example": "#példa", + "Riot/Web & Desktop chat": "Riot/Web és Desktop csevegés", + "Hide panel": "Panel elrejtése", + "You cannot delete this image. (%(code)s)": "Nem törölheted ezt a képet. (%(code)s)", + "Cancel Sending": "Küldés megszakítása", + "This Room": "Ebben a szobában", + "The Home Server may be too old to support third party networks": "Lehet, hogy a saját szerver túl régi és nem támogatja a csatlakozást más hálózatokhoz", + "Resend": "Küldés újra", + "Room not found": "A szoba nem található", + "Messages containing my display name": "A profilnevemet tartalmazó üzenetek", + "Messages in one-to-one chats": "Személyes beszélgetések üzenetei", + "Contributing code to Matrix and Riot": "Hozzájárulás a Matrix és Riot programkódjának fejlesztéséhez", + "Unavailable": "Elérhetetlen", + "Community-run support for Synapse": "Közösségi támogatás a Synapse-hez", + "View Decrypted Source": "Visszafejtett forrás megjelenítése", + "Failed to update keywords": "Nem lehet frissíteni a kulcsszavakat", + "Notes:": "Jegyzetek:", + "remove %(name)s from the directory.": "%(name)s szoba törlése a listából.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Az alábbi kulcsszavakról jövő értesítések szabályait nem lehet itt megjeleníteni:", + "Safari and Opera work too.": "Safarival és Operával is működik.", + "Please set a password!": "Állíts be egy jelszót!", + "You have successfully set a password!": "Sikerült beállítani a jelszót!", + "Chat with Riot Bot": "Csevegés a Riot Robottal", + "Support for those using, running and writing other bridges": "Támogatás azoknak, akik egyéb hidakat használnak, működtetnek vagy készítenek", + "Admin support for Dendrite": "Admin támogatás a Dendrite-hoz", + "An error occurred whilst saving your email notification preferences.": "Hiba történt az e-mail értesítési beállításaid mentése közben.", + "Explore Room State": "Szoba állapot felderítése", + "Source URL": "Forrás URL", + "Messages sent by bot": "Botok üzenetei", + "Filter results": "Találatok szűrése", + "Members": "Résztvevők", + "No update available.": "Nincs elérhető frissítés.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Már sok szoba van a Matrixon: más hálózatokkal (Slack, IRC, Gitter stb.) összekapcsolt és függetlenek szobák is. Nézd meg a szobajegyzéket!", + "Noisy": "Hangos", + "Failed to get protocol list from Home Server": "Nem sikerült a protokoll listát lekérni a saját szerverről", + "Collecting app version information": "Alkalmazás verzió információk összegyűjtése", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Törlöd a szoba nevét (%(alias)s) és eltávolítod a listából ezt: %(name)s?", + "customServer_text": "Egyedi Matrix szervert használhatsz a Saját szerver URL beállításával.
    Ezzel meglévő Matrix fiókot használhatsz Riot klienssel és egyedi szerverrel.

    Beállíthatsz egyedi \"identity\" szervert de akkor nem tudsz e-maillel meghívni felhasználót és téged sem tudnak meghívni e-maillel.", + "Co-ordination for Riot/Web translators": "Egyeztetés a Riot/Web fordítóival", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Így kijelentkezés után is vissza tudsz lépni a fiókodba, illetve más készülékekről is be tudsz lépni.", + "Dev chat for the Dendrite dev team": "Csevegés a Dendrite fejlesztői csapatával fejlesztőknek", + "Keywords": "Kulcsszavak", + "Enable notifications for this account": "Értesítések engedélyezése ehhez a fiókhoz", + "Directory": "Könyvtár", + "Invite to this community": "Meghívás ebbe a közösségbe", + "Search for a room": "Szoba keresése", + "Messages containing keywords": "Kulcsszavakat tartalmazó üzenetek", + "Error saving email notification preferences": "Hiba az e-mail értesítési beállítások mentésekor", + "Tuesday": "Kedd", + "Enter keywords separated by a comma:": "Kulcsszavak vesszővel elválasztva:", + "Forward Message": "Üzenet továbbítása", + "You have successfully set a password and an email address!": "Sikerült beállítani a jelszavad és e-mail címed!", + "Remove %(name)s from the directory?": "Törlöd ezt a szobát a listából: %(name)s?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "A Riot sok fejlett böngészőfunkciót használ, amelyeknek egy része egyáltalán nem, vagy csak kísérleti jelleggel érhető el a jelenlegi böngésződben.", + "Developer Tools": "Fejlesztői eszközök", + "Preparing to send logs": "Előkészülés napló küldéshez", + "Enable desktop notifications": "Asztali értesítések engedélyezése", + "Remember, you can always set an email address in user settings if you change your mind.": "Ha meggondolod magad, bármikor beállíthatod az e-mail címed a felhasználói beállításoknál.", + "Explore Account Data": "Fiókadatok felderítése", + "Remove from Directory": "Törlés a listából", + "Away": "Távol", + "Saturday": "Szombat", + "I understand the risks and wish to continue": "Megértettem a kockázatot és folytatom", + "Direct Chat": "Közvetlen csevegés", + "The server may be unavailable or overloaded": "A szerver nem elérhető vagy túlterhelt", + "Reject": "Elutasít", + "Riot is not supported on mobile web. Install the app?": "A mobilböngésző nem támogatja a Riotot. Telepíted inkább az alkalmazást?", + "Discussion of all things Matrix!": "Beszélgetés mindenről, ami Matrix!", + "Failed to set Direct Message status of room": "Nem lehet beállítani a szoba közvetlen beszélgetés státuszát", + "Monday": "Hétfő", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "A hibajelentésben naplófájlokat küldünk erről a kliensről, hogy feltárjuk a hibákat. Ha inkább csak a fenti szöveget szeretnéd elküldeni, töröld a pipát:", + "Send Custom State Event": "Egyéni állapot esemény küldése", + "All messages (noisy)": "Minden üzenet (hangos)", + "Enable them now": "Engedélyezés most", + "Messages containing my user name": "A felhasználónevemet tartalmazó üzenetek", + "Describe your problem here.": "Írd le ide a problémádat.", + "Toolbox": "Eszköztár", + "Collecting logs": "Naplók összegyűjtése", + "more": "tovább", + "GitHub issue link:": "GitHub hibajegy hivatkozás:", + "Bug report sent": "Hibajelentés elküldve", + "You must specify an event type!": "Meg kell jelölnöd az eseménytípust!", + "(HTTP status %(httpStatus)s)": "(HTTP állapot: %(httpStatus)s)", + "Invite to this room": "Meghívás a szobába", + "Please install Chrome or Firefox for the best experience.": "A legjobb élmény érdekében telepíts Chrome vagy Firefox böngészőt.", + "Failed to get public room list": "Nem sikerült lekérdezni a nyilvános szobák listáját", + "Quote": "Idéz", + "Send logs": "Naplófájlok elküldése", + "All messages": "Minden üzenet", + "Implementing VoIP services with Matrix": "VoIP szolgáltatások implementációja Matrixba", + "Dev chat for the Riot/Web dev team": "Csevegés a Riot/Web fejlesztői csapatával fejlesztőknek", + "Call invitation": "Hívás meghívó", + "Riot Desktop on %(platformName)s": "Riot Desktop itt: %(platformName)s", + "Downloading update...": "Frissítés letöltése...", + "State Key": "Állapotkulcs", + "Failed to send custom event.": "Nem sikerült elküldeni az egyéni eseményt.", + "What's new?": "Mik az újdonságok?", + "Discussion of the Identity Service API": "Beszélgetés az Identity Service API-ról", + "Support for those using and running matrix-appservice-irc": "Támogatás a matrix-appservice-irc használóinak és működtetőinek", + "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS és matrix-ios-sdk csevegés", + "Notify me for anything else": "Értesíts minden egyéb esetben", + "When I'm invited to a room": "Amikor meghívnak egy szobába", + "Design and implementation of E2E in Matrix": "A végponttól végpontig történő titkosítás (E2E) tervezése és implementációja a Matrixban", + "Click here to create a GitHub issue.": "Kattints ide GitHub hibajegy nyitásához .", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Az egyedi szerverbeállításoknál megadhatod egy másik szerver URL-jét, így be tudsz jelentkezni más Matrix szerverre is.
    Így a Riotot tudod használni egy már máshol meglévő Matrix fiókkal is.

    Beállíthatsz egyéni identitásszervert is, de akkor nem tudsz más felhasználókat e-mail címmel meghívni, illetve ők sem tudnak téged.", + "Can't update user notification settings": "Nem lehet frissíteni az értesítési beállításokat", + "Notify for all other messages/rooms": "Értesítés minden más üzenethez/szobához", + "Unable to look up room ID from server": "Nem lehet a szoba azonosítóját megkeresni a szerveren", + "Couldn't find a matching Matrix room": "Nem található a keresett Matrix szoba", + "Support for those using the Matrix spec": "Támogatás a Matrix specifikáció használóinak", + "Safari and Opera work too.": "Safarival és Operaval is működik.", + "Loading bug report module": "Hibabejelentő modul betöltése", + "All Rooms": "Minden szobában", + "You cannot delete this message. (%(code)s)": "Nem törölheted ezt az üzenetet. (%(code)s)", + "Thursday": "Csütörtök", + "Search…": "Keresés…", + "Logs sent": "Napló elküldve", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s alkalmazás %(browserName)s böngészőn %(osName)s rendszeren", + "Back": "Vissza", + "Reply": "Válasz", + "Show message in desktop notification": "Üzenetek megjelenítése az asztali értesítéseknél", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "A hibakereső napló alkalmazás használati adatokat tartalmaz beleértve a felhasználói nevedet, az általad meglátogatott szobák és csoportok azonosítóit alternatív neveit és más felhasználói neveket. Csevegés üzenetek szövegét nem tartalmazza.", + "Unhide Preview": "Előnézet mutatása", + "Announcements about Synapse releases": "Hírek a Synapse kiadásairól", + "Search the room directory": "Keresés a szobajegyzékben", + "Please describe the bug and/or send logs.": "Kérünk, írd le a hibát és/vagy küldd el a naplófájlokat.", + "Unable to join network": "Nem sikerült kapcsolódni a hálózathoz", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Egy másik, nem Riot-klienssel állítothattad be. A Riotban módosítani nem tudod ezeket, de érvényben vannak", + "Sorry, your browser is not able to run Riot.": "Elnézést, a böngésződben nem fut a Riot.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Decentralizált, titkosított csevegés és kollaboráció [matrix] alapokon", + "Uploaded on %(date)s by %(user)s": "Feltöltötte %(user)s ekkor: %(date)s", + "Messages in group chats": "Csoportszobák üzenetei", + "Yesterday": "Tegnap", + "Error encountered (%(errorDetail)s).": "Hiba történt (%(errorDetail)s).", + "Login": "Bejelentkezés", + "Low Priority": "Alacsony prioritás", + "Unable to fetch notification target list": "Nem sikerült letölteni az értesítési célok listáját", + "Appear Offline": "Offline látszik", + "Get started with some tips from Riot Bot!": "Kezdj a Riot Robot néhány tippjével!", + "Set Password": "Jelszó beállítása", + "Enable audible notifications in web client": "Hangértesítések engedélyezése a webkliensben", + "Permalink": "Állandó hivatkozás", + "Welcome to Riot.im": "Üdvözöl a Riot.im", + "Off": "Ki", + "Riot does not know how to join a room on this network": "A Riot nem tud csatlakozni szobához ezen a hálózaton", + "Mentions only": "Csak ha megemlítenek", + "Wednesday": "Szerda", + "You can now return to your account after signing out, and sign in on other devices.": "Most már kijelentkezés után is vissza tudsz lépni a fiókodba, és más készülékekről is be tudsz lépni.", + "Please install Chrome or Firefox for the best experience.": "A legjobb élmény érdekében telepíts Chromeot vagy Firefoxot.", + "Enable email notifications": "E-mail értesítések engedélyezése", + "Event Type": "Esemény típusa", + "Download this file": "Fájl letöltése", + "Pin Message": "Üzenet rögzítése", + "Failed to change settings": "A beállítások megváltoztatása nem sikerült", + "View Community": "Közösség megtekintése", + "%(count)s Members|one": "%(count)s tag", + "Event sent!": "Az esemény elküldve!", + "View Source": "Forrás megjelenítése", + "Matrix technical discussions": "Technikai jellegű beszélgetések a Matrixról", + "Event Content": "Esemény tartalma", + "Thank you!": "Köszönjük!", + "Building services on Matrix": "Szolgáltatások fejlesztése Matrixra", + "Collapse panel": "Panel becsukása", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Ebben a böngészőben az alkalmazás felülete tele lehet hibával, és az is lehet, hogy egyáltalán nem működik. Ha így is ki szeretnéd próbálni, megteheted, de ha valami gondod van, nem tudunk segíteni!", + "Checking for an update...": "Frissítés keresése...", + "General discussion about Matrix and Riot": "Általános beszélgetések a Matrixról és a Riotról", + "There are advanced notifications which are not shown here": "Vannak itt nem látható, haladó értesítések" } diff --git a/src/i18n/strings/id.json b/src/i18n/strings/id.json index e95f3b13af..0f0e2c2b48 100644 --- a/src/i18n/strings/id.json +++ b/src/i18n/strings/id.json @@ -201,5 +201,195 @@ "Device key:": "Kunci Perangkat:", "Devices will not yet be able to decrypt history from before they joined the room": "Perangkat tidak akan dapat mendekripsi sejarah sebelum gabung ke ruang", "Ban": "Blokir", - "Bans user with given id": "Blokir pengguna dengan id" + "Bans user with given id": "Blokir pengguna dengan id", + "Fetching third party location failed": "Gagal mengambil lokasi pihak ketiga", + "A new version of Riot is available.": "Riot versi baru telah tersedia.", + "Riot/Android & matrix-android-sdk chat": "Obrolan Riot/Android & matrix-android-sdk", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Harap jelaskan bug. Apa yang Anda lakukan? Apa yang Anda harap terjadi? Apa yang sebenarnya terjadi?", + "Couldn't load home page": "Tidak dapat memuat halaman utama", + "All notifications are currently disabled for all targets.": "Semua notifikasi saat ini dinonaktifkan untuk semua target.", + "Uploading report": "Unggah laporan", + "Sunday": "Minggu", + "Guests can join": "Tamu dapat gabung", + "Messages sent by bot": "Pesan dikirim oleh bot", + "Notification targets": "Target notifikasi", + "Failed to set direct chat tag": "Gagal mengatur tag obrolan langsung", + "Today": "Hari Ini", + "Failed to get protocol list from Home Server": "Gagal mendapatkan daftar protokol dari Server Home", + "Report a bug": "Laporkan bug", + "Implementing VR services with Matrix": "Implementasi layanan VR dengan Matrix", + "You are not receiving desktop notifications": "Anda tidak menerima notifikasi desktop", + "Dismiss": "Abaikan", + "Update": "Perbarui", + "Notifications": "Notifikasi", + "You need to be using HTTPS to place a screen-sharing call.": "Anda perlu menggunakan HTTPS untuk melakukan panggilan berbagi-layar.", + "What's New": "Apa Yang Baru", + "Add an email address above to configure email notifications": "Tambahkan alamat email di atas untuk konfigurasi notifikasi email", + "Expand panel": "Luaskan panel", + "On": "Nyala", + "Filter room names": "Saring nama ruang", + "Changelog": "Daftar perubahan", + "Running Matrix services": "Mengoperasikan layanan Matrix", + "Waiting for response from server": "Menunggu respon dari server", + "Leave": "Tinggalkan", + "Failed to send report: ": "Gagal mengirim laporan: ", + "Unknown device": "Perangkat Tidak Diketahui", + "Advanced notification settings": "Pengaturan notifikasi lanjutan", + "delete the alias.": "hapus alias.", + "To return to your account in future you need to set a password": "Untuk kembali ke akun di lain waktu, Anda perlu mengisi password", + "Forget": "Lupakan", + "World readable": "Terpublikasi Umum", + "#example": "#contoh", + "Riot/Web & Desktop chat": "Obrolan Riot/Web & Desktop", + "Hide panel": "Sembunyikan panel", + "You cannot delete this image. (%(code)s)": "Anda tidak dapat menghapus gambar ini. (%(code)s)", + "Cancel Sending": "Batalkan pengiriman", + "Warning": "Peringatan", + "This Room": "Ruang ini", + "The Home Server may be too old to support third party networks": "Server Home mungkin terlalu kuno untuk mendukung jaringan pihak ketiga", + "Noisy": "Berisik", + "Error saving email notification preferences": "Terjadi kesalahan saat menyimpan pilihan notifikasi email", + "Messages containing my display name": "Pesan mengandung nama tampilan saya", + "Messages in one-to-one chats": "Pesan di obrolan satu-ke-satu", + "Contributing code to Matrix and Riot": "Kontribusi kode untuk Matrix dan Riot", + "Unavailable": "Tidak Tersedia", + "Community-run support for Synapse": "Dukungan komunitas untuk Synapse", + "View Decrypted Source": "Tampilkan Sumber Terdekripsi", + "Failed to update keywords": "Gagal memperbarui kata kunci", + "remove %(name)s from the directory.": "hapus %(name)s dari direktori.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Notifikasi pada kata kunci berikut mengikuti aturan dimana tidak dapat ditampilkan di sini:", + "Please set a password!": "Mohon isi password!", + "powered by Matrix": "didukung oleh Matrix", + "You have successfully set a password!": "Anda berhasil mengubah password!", + "Chat with Riot Bot": "Mengobrol dengan bot Riot", + "Support for those using, running and writing other bridges": "Dukungan untuk pengguna, penyedia dan penulis jembatan lainnya", + "Admin support for Dendrite": "Dukungan Admin untuk Dendrite", + "An error occurred whilst saving your email notification preferences.": "Terjadi kesalahan saat menyimpan preferensi notifikasi email Anda.", + "All Rooms": "Semua Ruang", + "Source URL": "URL sumber", + "Failed to add tag %(tagName)s to room": "Gagal menambahkan tag %(tagName)s ke ruang", + "Members": "Anggota", + "No update available.": "Tidak ada pembaruan.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Banyak ruang sudah tersedia di Matrix, terhubung ke jaringan yang sudah ada (Slack, IRC, Gitter dls) atau independen. Cek direktori!", + "Resend": "Kirim Ulang", + "Files": "Files", + "Collecting app version information": "Mengumpukan informasi versi aplikasi", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Hapus alias ruang %(alias)s dan hapus %(name)s dari direktori?", + "customServer_text": "Anda dapat menggunakan opsi server khusus untuk masuk ke server Matrix lain dengan menyebutkan URL server Home.
    Hal ini memperbolehkan Anda untuk menggunakan Riot dengan akun Matrix yang sudah ada di server Home yang berbeda.

    Anda juga bisa mengatur server identitas khusus tapi Anda tidak akan dapat mengundang pengguna melalui alamat email, atau diundang dengan alamat email Anda.", + "Co-ordination for Riot/Web translators": "Koordinasi untuk penerjemah Riot/Web", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Hal ini akan memperbolehkan anda kembali ke akun setelah keluar dan masuk kembali di perangkat lain.", + "Dev chat for the Dendrite dev team": "Obrolan Developer untuk tim developer Dendrite", + "Design and implementation of E2E in Matrix": "Desain dan implementasi E2E di Matrix", + "Enable notifications for this account": "Aktifkan notifikasi untuk akun ini", + "Directory": "Direktori", + "Failed to get public room list": "Gagal mendapatkan daftar ruang publik", + "Messages containing keywords": "Pesan mengandung kata kunci", + "Room not found": "Ruang tidak ditemukan", + "Tuesday": "Selasa", + "Enter keywords separated by a comma:": "Masukkan kata kunci dipisahkan oleh koma:", + "Search…": "Cari…", + "Remove %(name)s from the directory?": "Hapus %(name)s dari direktori?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot menggunakan banyak fitur terdepan dari browser, dimana tidak tersedia atau dalam fase eksperimen di browser Anda.", + "Enable desktop notifications": "Aktifkan notifikasi desktop", + "Unnamed room": "Ruang tanpa nama", + "Friday": "Jumat", + "Remember, you can always set an email address in user settings if you change your mind.": "Ingat, Anda selalu dapat mengubah alamat email di pengaturan pengguna jika anda berubah pikiran.", + "All messages (noisy)": "Semua pesan (keras)", + "Saturday": "Sabtu", + "I understand the risks and wish to continue": "Saya mengerti resikonya dan berharap untuk melanjutkan", + "Direct Chat": "Obrolan Langsung", + "The server may be unavailable or overloaded": "Server mungkin tidak tersedia atau kelebihan muatan", + "Reject": "Tolak", + "Riot is not supported on mobile web. Install the app?": "Riot tidak mendukung web seluler. Install aplikasi?", + "Discussion of all things Matrix!": "Diskusi semua tentang Matrix!", + "Failed to set Direct Message status of room": "Gagal mengatur status Pesan Langsung dari ruang", + "Monday": "Senin", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Untuk diagnosis permasalahannya, catatan dari klien ini akan dikirimkan bersama laporan bug. Jika Anda memilih untuk hanya mengirimkan pesan di atas, mohon hapus centang:", + "Remove from Directory": "Hapus dari DIrektori", + "Enable them now": "Aktifkan sekarang", + "Messages containing my user name": "Pesan mengandung nama pengguna saya", + "Describe your problem here.": "Jelaskan masalah anda di sini.", + "Collecting logs": "Mengumpulkan catatan", + "more": "lagi", + "Bug report sent": "Laporan bug terkirim", + "(HTTP status %(httpStatus)s)": "(status HTTP %(httpStatus)s)", + "Failed to forget room %(errCode)s": "Gagal melupakan ruang %(errCode)s", + "Wednesday": "Rabu", + "You cannot delete this message. (%(code)s)": "Anda tidak dapat menghapus pesan ini. (%(code)s)", + "Quote": "Kutip", + "Send": "Kirim", + "Error": "Terjadi Kesalahan", + "Send logs": "Kirim catatan", + "All messages": "Semua pesan", + "Implementing VoIP services with Matrix": "Implementasi layanan VoIP dengan Matrix", + "Dev chat for the Riot/Web dev team": "Obrolan Developer untuk tim developer Riot/Web", + "Call invitation": "Undangan panggilan", + "Riot Desktop on %(platformName)s": "Riot Desktop di %(platformName)s", + "Downloading update...": "Unduh pembaruan...", + "You have successfully set a password and an email address!": "Anda telah berhasil mengubah password dan alamat email!", + "What's new?": "Apa yang baru?", + "Discussion of the Identity Service API": "Diskusi tentang API Identity Service", + "Support for those using and running matrix-appservice-irc": "Dukungan untuk pengguna dan penyedia matrix-appservice-irc", + "Riot/iOS & matrix-ios-sdk chat": "Obrolan Riot/iOS & matrix-ios-sdk", + "Notify me for anything else": "Beritau saya untuk lainnya", + "When I'm invited to a room": "Ketika Saya diundang ke ruang", + "Cancel": "Batal", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Anda dapat menggunakan opsi lain untuk mendaftar pada server Matrix yang berbeda dengan memasukkan URL server yang sesuai.
    Hal ini memungkinkan anda untuk menggunakan Riot dengan akun matrix yang telah tersedia pada Home server yang berbeda.

    Anda juga dapat melakukan pengubahan identitas server akan tetapi akan berakibat tidak dapat mengundang pengguna melalui email, atau diundang melalui email.", + "Can't update user notification settings": "Tidak dapat memperbarui pengaturan notifikasi pengguna", + "Notify for all other messages/rooms": "Beritau semua pesan/ruang", + "Unable to look up room ID from server": "Tidak dapat mencari ID ruang dari server", + "Couldn't find a matching Matrix room": "Tidak dapat menemukan ruang Matrix yang sesuai", + "Support for those using the Matrix spec": "Dukungan untuk pengguna Matrix spec", + "Safari and Opera work too.": "Safari dan Opera juga berfungsi.", + "Loading bug report module": "Memuat modul laporan bug", + "Invite to this room": "Undang ke ruang ini", + "Search for a room": "Cari ruang obrolan", + "Thursday": "Kamis", + "Forward Message": "Teruskan Pesan", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s melalui %(browserName)s di %(osName)s", + "Back": "Kembali", + "Show message in desktop notification": "Tampilkan pesan pada desktop", + "Unhide Preview": "Tampilkan Pratinjau", + "Announcements about Synapse releases": "Pengumuman tentang rilis Synapse", + "Search the room directory": "Cari di direktori ruang", + "Please describe the bug and/or send logs.": "Harap jelaskan bug dan/atau kirim catatan.", + "Unable to join network": "Tidak dapat bergabung di jaringan", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Anda mungkin sudah konfigurasi di klien selain Riot. Anda tidak dapat setel di Riot tetap berlaku", + "Sorry, your browser is not able to run Riot.": "Maaf, browser Anda tidak dapat menjalankan Riot.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Obrolan terenkripsi, terdesentralisasi & kolaborasi didukung oleh [matrix]", + "Uploaded on %(date)s by %(user)s": "Diunggah pada %(date)s oleh %(user)s", + "Messages in group chats": "Pesan di obrolan grup", + "Yesterday": "Kemarin", + "Error encountered (%(errorDetail)s).": "Terjadi kesalahan (%(errorDetail)s).", + "Keywords": "Kata Kunci", + "Low Priority": "Prioritas Rendah", + "Unable to fetch notification target list": "Tidak dapat mengambil daftar notifikasi target", + "Get started with some tips from Riot Bot!": "Mulai dengan beberapa tip dari Bot Riot!", + "Set Password": "Ubah Password", + "Enable audible notifications in web client": "Aktifkan notifikasi suara di klien web", + "Permalink": "Permalink", + "Welcome to Riot.im": "Selamat datang di Riot.im", + "Off": "Mati", + "Riot does not know how to join a room on this network": "Riot tidak tau bagaimana gabung ruang di jaringan ini", + "Mentions only": "Hanya jika disinggung", + "Failed to remove tag %(tagName)s from room": "Gagal menghapus tag %(tagName)s dari ruang", + "Remove": "Hapus", + "You can now return to your account after signing out, and sign in on other devices.": "Anda dapat kembali ke akun setelah keluar dan masuk kembali di perangkat lain.", + "Please install Chrome or Firefox for the best experience.": "Harap install Chrome atau Firefox untuk pengalaman terbaik.", + "Enable email notifications": "Aktifkan notifikasi email", + "Login": "Masuk", + "No rooms to show": "Tidak ada ruang ditunjukkan", + "Download this file": "Unduh file ini", + "Failed to change settings": "Gagal mengubah pengaturan", + "Failed to change password. Is your password correct?": "Gagal untuk mengubah password. Apakah password Anda benar?", + "View Source": "Tampilkan Sumber", + "Matrix technical discussions": "Diskusi teknis Matrix", + "Custom Server Options": "Pilihan Server Khusus", + "Thank you!": "Terima kasih!", + "Building services on Matrix": "Membangun layanan dengan Matrix", + "Collapse panel": "Lipat panel", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Dengan browser ini, tampilan dari aplikasi mungkin tidak sesuai, dan beberapa atau bahkan semua fitur mungkin tidak berjalan. Jika Anda ingin tetap mencobanya, Anda bisa melanjutkan, tapi Anda tanggung sendiri jika muncul masalah yang terjadi!", + "Checking for an update...": "Cek pembaruan...", + "General discussion about Matrix and Riot": "Diskusi umum tentang Matrix dan Riot", + "There are advanced notifications which are not shown here": "Ada notifikasi lanjutan yang tidak ditampilkan di sini" } diff --git a/src/i18n/strings/it.json b/src/i18n/strings/it.json index 84b6a357e2..e5ff92b7a8 100644 --- a/src/i18n/strings/it.json +++ b/src/i18n/strings/it.json @@ -1005,5 +1005,207 @@ "Leave this community": "Esci da questa comunità", "Sticker Messages": "Messaggi adesivi", "You don't currently have any stickerpacks enabled": "Non hai ancora alcun pacchetto di adesivi attivato", - "Add a stickerpack": "Aggiungi un pacchetto di adesivi" + "Add a stickerpack": "Aggiungi un pacchetto di adesivi", + "Fetching third party location failed": "Rilevazione posizione di terze parti fallita", + "A new version of Riot is available.": "È disponibile una nuova versione di Riot.", + "Riot/Android & matrix-android-sdk chat": "Chat su Riot/Android & matrix-android-sdk", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Per favore descrivi l'errore. Cosa hai fatto? Cosa ti aspettavi accadesse? Cos'è successo invece?", + "Couldn't load home page": "Impossibile caricare la pagina principale", + "Send Account Data": "Invia dati account", + "Advanced notification settings": "Impostazioni di notifica avanzate", + "Uploading report": "Sto caricando il report", + "Sunday": "Domenica", + "Notification targets": "Obiettivi di notifica", + "Today": "Oggi", + "Files": "File", + "Report a bug": "Segnala un errore", + "Implementing VR services with Matrix": "Implementazione servizi VR con Matrix", + "You are not receiving desktop notifications": "Non stai ricevendo le notifiche sul desktop", + "Friday": "Venerdì", + "Update": "Aggiornamento", + "You need to be using HTTPS to place a screen-sharing call.": "Devi usare HTTPS per utilizzare una chiamata con condivisione schermo.", + "Riot does not know how to join a room on this network": "Riot non sa come entrare nella stanza su questa rete", + "Add an email address above to configure email notifications": "Aggiungi un indirizzo email sopra per configurare le notifiche via email", + "Expand panel": "Espandi il pannello", + "On": "Acceso", + "%(count)s Members|other": "%(count)s membri", + "Filter room names": "Filtra i nomi delle stanze", + "Changelog": "Cambiamenti", + "Running Matrix services": "Esecuzione servizi Matrix", + "Waiting for response from server": "In attesa di una risposta dal server", + "Send Custom Event": "Invia Evento Personalizzato", + "Failed to send report: ": "Impossibile inviare il resoconto: ", + "Unknown device": "Dispositivo sconosciuto", + "All notifications are currently disabled for all targets.": "Tutte le notifiche sono disabilitate per tutti gli obbiettivi.", + "Failed to send logs: ": "Invio dei log fallito: ", + "delete the alias.": "elimina l'alias.", + "To return to your account in future you need to set a password": "Per tornare nel tuo account in futuro devi impostare una password", + "Forget": "Dimentica", + "Riot/Web & Desktop chat": "Chat su Riot/Web & Desktop", + "Hide panel": "Nascondi pannello", + "You cannot delete this image. (%(code)s)": "Non puoi eliminare quest'immagine. (%(code)s)", + "Cancel Sending": "Annulla invio", + "This Room": "Questa stanza", + "The Home Server may be too old to support third party networks": "Il server Home potrebbe essere troppo vecchio per supportare reti di terze parti", + "Noisy": "Rumoroso", + "Error saving email notification preferences": "Errore nel salvataggio delle preferenze di notifica email", + "Messages containing my display name": "Messaggi contenenti il mio nome visualizzato", + "Messages in one-to-one chats": "Messaggi in chat uno-a-uno", + "Contributing code to Matrix and Riot": "Contributi al codice di Matrix e Riot", + "Unavailable": "Non disponibile", + "Community-run support for Synapse": "Supporto per Synapse dalla comunità", + "View Decrypted Source": "Visualizza sorgente decifrato", + "Failed to update keywords": "Impossibile aggiornare le parole chiave", + "Notes:": "Note:", + "remove %(name)s from the directory.": "rimuovi %(name)s dalla lista.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Le notifiche alle seguenti parole chiave seguono regole che non possono essere mostrate qui:", + "Safari and Opera work too.": "Anche Safari e Opera vanno bene.", + "Please set a password!": "Imposta una password!", + "You have successfully set a password!": "Hai impostato una password con successo!", + "Chat with Riot Bot": "Chatta con Riot Bot", + "Support for those using, running and writing other bridges": "Supporto per chi usa, amministra e scrive altri bridge", + "Admin support for Dendrite": "Supporto amministrativo per Dendrite", + "An error occurred whilst saving your email notification preferences.": "Si è verificato un errore durante il salvataggio delle tue preferenze sulle notifiche email.", + "Explore Room State": "Esplora Stato Stanza", + "Source URL": "URL d'origine", + "Messages sent by bot": "Messaggi inviati dai bot", + "Filter results": "Filtra risultati", + "Members": "Membri", + "No update available.": "Nessun aggiornamento disponibile.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Esistono già molte stanze in Matrix, collegate a reti già esistenti (Slack, IRC, Gitter ecc) o indipendenti. Dai un'occhiata all'elenco!", + "Resend": "Reinvia", + "Failed to get protocol list from Home Server": "Impossibile ottenere la lista di protocolli dal server Home", + "Collecting app version information": "Raccolta di informazioni sulla versione dell'applicazione", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Eliminare l'alias %(alias)s e rimuovere %(name)s dalla lista?", + "customServer_text": "Puoi utilizzare un server personale per accedere su altri server Matrix specificando un diverso indirizzo URL per il server Home.
    Questo ti permetterà di usare Riot con un account Matrix già esistente su un altro server.

    Puoi anche specificare un diverso server di identità ma non sarai in grado di invitare utenti, o di essere invitato tramite indirizzo email.", + "Co-ordination for Riot/Web translators": "Coordinamento per i traduttori di Riot/Web", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Questo ti permetterà di ritornare al tuo account dopo esserti disconnesso e accedere in altri dispositivi.", + "Dev chat for the Dendrite dev team": "Chat per gli sviluppatori di Dendrite", + "Keywords": "Parole chiave", + "Enable notifications for this account": "Abilita le notifiche per questo account", + "Directory": "Lista", + "Invite to this community": "Invita a questa comunità", + "Failed to get public room list": "Impossibile ottenere la lista delle stanze pubbliche", + "Messages containing keywords": "Messaggi contenenti parole chiave", + "Room not found": "Stanza non trovata", + "Tuesday": "Martedì", + "Enter keywords separated by a comma:": "Inserisci le parole chiave separate da virgole:", + "Search…": "Cerca…", + "You have successfully set a password and an email address!": "Hai impostato con successo una password e un indirizzo email!", + "Remove %(name)s from the directory?": "Rimuovere %(name)s dalla lista?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot utilizza molte funzioni avanzate del browser, alcune delle quali non sono disponibili o sono sperimentali nel tuo browser attuale.", + "Developer Tools": "Strumenti per Sviluppatori", + "Preparing to send logs": "Preparazione invio dei log", + "Enable desktop notifications": "Abilita le notifiche desktop", + "Remember, you can always set an email address in user settings if you change your mind.": "Ricorda, puoi sempre specificare un indirizzo email nelle impostazioni utente se cambi idea.", + "Explore Account Data": "Esplora dati account", + "All messages (noisy)": "Tutti i messaggi (rumoroso)", + "Away": "Assente", + "Saturday": "Sabato", + "I understand the risks and wish to continue": "Sono consapevole dei rischi e vorrei continuare", + "Direct Chat": "Chat Diretta", + "The server may be unavailable or overloaded": "Il server potrebbe essere non disponibile o sovraccarico", + "Reject": "Rifiuta", + "Riot is not supported on mobile web. Install the app?": "Riot non è supportato sul web mobile. Vuoi installare l'applicazione?", + "Discussion of all things Matrix!": "Discussione su tutto quanto riguardi Matrix!", + "Failed to set Direct Message status of room": "Impossibile impostare lo stato di Messaggio Diretto alla stanza", + "Monday": "Lunedì", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Per diagnosticare i problemi, i log da questo client verranno inviati con questo bug report. Se vuoi solo mandare il testo sopra, togli la spunta a:", + "Send Custom State Event": "Invia Evento di Stato Personalizzato", + "Remove from Directory": "Rimuovi dalla lista", + "Enable them now": "Abilitale adesso", + "Messages containing my user name": "Messaggi contenenti il mio nome utente", + "Describe your problem here.": "Descrivi qui il tuo problema.", + "Toolbox": "Strumenti", + "Collecting logs": "Sto recuperando i log", + "more": "altro", + "GitHub issue link:": "Link segnalazione su GitHub:", + "Bug report sent": "Rapporto inviato", + "You must specify an event type!": "Devi specificare un tipo di evento!", + "(HTTP status %(httpStatus)s)": "(stato HTTP %(httpStatus)s)", + "All Rooms": "Tutte le stanze", + "Please install Chrome or Firefox for the best experience.": "Installa Chrome o Firefox per la migliore esperienza d'uso.", + "Wednesday": "Mercoledì", + "You cannot delete this message. (%(code)s)": "Non puoi eliminare questo messaggio. (%(code)s)", + "Quote": "Cita", + "Send logs": "Invia i log", + "All messages": "Tutti i messaggi", + "Implementing VoIP services with Matrix": "Implementazione servizi VoIP con Matrix", + "Dev chat for the Riot/Web dev team": "Chat per gli sviluppatori di Riot/Web", + "Call invitation": "Invito ad una chiamata", + "Riot Desktop on %(platformName)s": "Riot Desktop su %(platformName)s", + "Downloading update...": "Scaricamento aggiornamento...", + "State Key": "Chiave dello Stato", + "Failed to send custom event.": "Impossibile inviare evento personalizzato.", + "What's new?": "Cosa c'è di nuovo?", + "Discussion of the Identity Service API": "Discussione sull'Identity Service API", + "Support for those using and running matrix-appservice-irc": "Supporto per chi usa e amministra matrix-appservice-irc", + "Riot/iOS & matrix-ios-sdk chat": "Chat su Riot/iOS & matrix-ios-sdk", + "Notify me for anything else": "Notificami per qualsiasi altra cosa", + "When I'm invited to a room": "Quando vengo invitato/a in una stanza", + "Design and implementation of E2E in Matrix": "Design e implementazione di E2E in Matrix", + "Click here to create a GitHub issue.": "Clicca qui per creare una segnalazione su GitHub.", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Puoi usare le opzioni server personalizzate per accedere ad altri server Matrix specificando l'indirizzo dell'home server.
    Questo permette di usare Matrix con un account esistente su un home server diverso.

    È anche possibile impostare un diverso identity server, ma in quel caso non sarà possibile invitare utenti attraverso l'indirizzo e-mail o essere invitati attraverso l'indirizzo e-mail.", + "Can't update user notification settings": "Impossibile aggiornare le impostazioni di notifica dell'utente", + "Notify for all other messages/rooms": "Notifica per tutti gli altri messaggi/stanze", + "Unable to look up room ID from server": "Impossibile consultare l'ID stanza dal server", + "Couldn't find a matching Matrix room": "Impossibile trovare una stanza Matrix corrispondente", + "Support for those using the Matrix spec": "Supporto per chi utilizza le specifiche Matrix", + "Safari and Opera work too.": "Anche Safari e Opera funzionano.", + "Loading bug report module": "Caricamento modulo di segnalazione errori", + "Invite to this room": "Invita in questa stanza", + "Search for a room": "Cerca una stanza", + "Thursday": "Giovedì", + "Forward Message": "Inoltra messaggio", + "Logs sent": "Log inviati", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s via %(browserName)s su %(osName)s", + "Back": "Indietro", + "Failed to change settings": "Impossibile modificare le impostazioni", + "Reply": "Rispondi", + "Show message in desktop notification": "Mostra i messaggi nelle notifiche desktop", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "I log di debug contengono dati di utilizzo dell'applicazione inclusi il nome utente, gli ID o alias delle stanze o gruppi visitati e i nomi degli altri utenti. Non contengono messaggi.", + "Unhide Preview": "Mostra anteprima", + "Announcements about Synapse releases": "Annunci riguardo i rilasci di Synapse", + "Search the room directory": "Cerca nella lista delle stanze", + "Please describe the bug and/or send logs.": "Per favore descrivi l'errore e/o invia i log.", + "Unable to join network": "Impossibile collegarsi alla rete", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Potresti averli configurati in un client diverso da Riot. Non puoi cambiarli in Riot ma sono comunque applicati", + "Sorry, your browser is not able to run Riot.": "Spiacenti, ma il tuo browser non è in grado di utilizzare Riot.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Chat criptate e collaborazioni decentralizzate offerte da [matrix]", + "Uploaded on %(date)s by %(user)s": "Caricato il %(date)s da %(user)s", + "Messages in group chats": "Messaggi nelle chat di gruppo", + "Yesterday": "Ieri", + "Error encountered (%(errorDetail)s).": "Errore riscontrato (%(errorDetail)s).", + "Login": "Entra", + "Low Priority": "Priorità bassa", + "What's New": "Novità", + "Appear Offline": "Appari offline", + "Get started with some tips from Riot Bot!": "Inizia con alcuni consigli di Riot Bot!", + "Set Password": "Imposta Password", + "Enable audible notifications in web client": "Abilita notifiche audio nel client web", + "Permalink": "Link permanente", + "Welcome to Riot.im": "Benvenuto/a su Riot.im", + "Off": "Spento", + "#example": "#esempio", + "Mentions only": "Solo le citazioni", + "You can now return to your account after signing out, and sign in on other devices.": "Ora puoi tornare al tuo account dopo esserti disconnesso e accedere su altri dispositivi.", + "Please install Chrome or Firefox for the best experience.": "Per favore installaChrome o Firefox per un'esperienza migliore.", + "Enable email notifications": "Abilita le notifiche email", + "Event Type": "Tipo di Evento", + "Download this file": "Scarica questo file", + "Pin Message": "Blocca messaggio", + "Thank you!": "Grazie!", + "View Community": "Vedi la comunità", + "%(count)s Members|one": "%(count)s membro", + "Event sent!": "Evento inviato!", + "View Source": "Visualizza sorgente", + "Matrix technical discussions": "Discussioni tecniche su Matrix", + "Event Content": "Contenuto dell'Evento", + "Unable to fetch notification target list": "Impossibile ottenere la lista di obiettivi notifiche", + "Building services on Matrix": "Costruzione servizi su Matrix", + "Collapse panel": "Riduci pannello", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Con il tuo attuale browser, l'aspetto e la sensazione generale dell'applicazione potrebbero essere completamente sbagliati e alcune delle funzionalità potrebbero non funzionare. Se vuoi provare comunque puoi continuare, ma non riceverai aiuto per qualsiasi problema tu possa riscontrare!", + "Checking for an update...": "Controllo aggiornamenti...", + "General discussion about Matrix and Riot": "Discussioni generali riguardo Matrix e Riot", + "There are advanced notifications which are not shown here": "Ci sono notifiche avanzate che non sono mostrate qui" } diff --git a/src/i18n/strings/ja.json b/src/i18n/strings/ja.json index 032dacd1aa..c16fb0d28c 100644 --- a/src/i18n/strings/ja.json +++ b/src/i18n/strings/ja.json @@ -54,5 +54,71 @@ "Camera": "カメラ", "Are you sure?": "本当によろしいですか?", "OK": "OK", - "Operation failed": "操作に失敗しました" + "Operation failed": "操作に失敗しました", + "Thursday": "木曜日", + "Messages in one-to-one chats": "一対一のチャットでのメッセージ", + "A new version of Riot is available.": "新しいバージョンのRiotが利用可能です。", + "Safari and Opera work too.": "SafariOperaでも動作します。", + "All Rooms": "全ての部屋", + "You cannot delete this message. (%(code)s)": "あなたはこの発言を削除できません (%(code)s)", + "Send": "送信", + "All messages": "全ての発言", + "Uploading report": "レポートのアップロード", + "Sunday": "日曜日", + "Welcome to Riot.im": "Riot.imへようこそ", + "Direct Chat": "対話", + "Riot is not supported on mobile web. Install the app?": "Riotはスマートフォンでの表示に対応していません。できればアプリをインストールして頂けませんでしょうか?", + "Today": "今日", + "Files": "添付ファイル", + "Room not found": "部屋が見つかりません", + "Set Password": "パスワードを設定", + "Sorry, your browser is not able to run Riot.": "申し訳ありません。あなたのブラウザではRiotは動作できません。", + "Monday": "月曜日", + "Messages in group chats": "グループチャットのメッセージ", + "Friday": "金曜日", + "All messages (noisy)": "全ての発言(通知音あり)", + "Yesterday": "昨日", + "Messages sent by bot": "ボットから送信されたメッセージ", + "Low Priority": "低優先度", + "Messages containing my user name": "自身のユーザー名を含むメッセージ", + "Search the room directory": "部屋一覧を検索", + "Members": "参加者", + "Add an email address above to configure email notifications": "メール通知を設定するためには、メールアドレスを追加してください", + "Collecting logs": "ログの収集", + "No update available.": "更新はありません。", + "An error occurred whilst saving your email notification preferences.": "電子メール通知設定を保存中にエラーが発生しました。", + "Failed to change settings": "設定の変更に失敗しました", + "Mentions only": "呼び掛けられた時のみ", + "Collecting app version information": "アプリのバージョン情報を収集", + "Filter room names": "部屋名検索", + "Changelog": "変更履歴", + "Invite to this room": "この部屋へ招待", + "Waiting for response from server": "サーバからの応答を待っています", + "Wednesday": "水曜日", + "Leave": "退室", + "Enable notifications for this account": "このアカウントで通知を行う", + "Failed to update keywords": "キーワードの更新に失敗しました", + "Enable email notifications": "電子メールでの通知を行う", + "Directory": "部屋一覧", + "Download this file": "この添付ファイルをダウンロード", + "Unknown device": "不明な端末", + "Report a bug": "バグを報告", + "Failed to get public room list": "公開部屋一覧の取得に失敗しました", + "Call invitation": "通話への招待", + "Forget": "忘れる", + "Messages containing keywords": "keywordsを含むメッセージ", + "Error saving email notification preferences": "電子メール通知設定の保存エラー", + "Tuesday": "火曜日", + "Enter keywords separated by a comma:": "キーワードをコンマで区切って入力:", + "Search…": "検索…", + "Saturday": "土曜日", + "Hide panel": "右欄を非表示", + "Warning": "警告", + "This Room": "この部屋", + "When I'm invited to a room": "部屋に招待された時", + "Keywords": "キーワード", + "Resend": "再送信", + "Can't update user notification settings": "ユーザー通知の設定を更新できません", + "Messages containing my display name": "自身の表示名を含むメッセージ", + "Enable desktop notifications": "デスクトップ画面に通知を行う" } diff --git a/src/i18n/strings/ko.json b/src/i18n/strings/ko.json index 183a519320..dede270a91 100644 --- a/src/i18n/strings/ko.json +++ b/src/i18n/strings/ko.json @@ -644,5 +644,188 @@ "You added a new device '%(displayName)s', which is requesting encryption keys.": "새 장치 '%(displayName)s'를 추가했고 암호화 키를 요청하고 있어요.", "Your unverified device '%(displayName)s' is requesting encryption keys.": "인증하지 않은 장치 '%(displayName)s'가 암호화 키를 요청하고 있어요.", "Encryption key request": "암호화 키 요청", - "Edit": "수정하기" + "Edit": "수정하기", + "Fetching third party location failed": "타사 위치를 불러오지 못했어요", + "A new version of Riot is available.": "라이엇의 새 버전을 사용하실 수 있어요.", + "Riot/Android & matrix-android-sdk chat": "매트릭스/안드로이드 & matrix-ios-sdk 대화", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "오류를 설명해주세요. 무슨 일을 하셨나요? 어떤 일을 예상하셨나요? 실제로는 어떤 일이 일어났나요?", + "Couldn't load home page": "중심 화면을 불러올 수 없어요", + "All notifications are currently disabled for all targets.": "현재 모든 알림이 모든 상대에게서 꺼졌어요.", + "Uploading report": "보고를 올리는 중", + "Sunday": "일요일", + "Guests can join": "손님이 들어올 수 있어요", + "Messages sent by bot": "봇이 보낸 메시지", + "Notification targets": "알림 대상", + "Failed to set direct chat tag": "직접 이야기 지정을 설정하지 못했어요", + "Today": "오늘", + "Failed to get protocol list from Home Server": "홈 서버에서 프로토콜 목록을 얻지 못했어요", + "Report a bug": "오류 보고하기", + "Implementing VR services with Matrix": "매트릭스로 VR 서비스 구현", + "You are not receiving desktop notifications": "컴퓨터 알림을 받지 않고 있어요", + "Friday": "금요일", + "Update": "업데이트", + "You need to be using HTTPS to place a screen-sharing call.": "화면 공유를 하려면 HTTPS를 써야만 해요.", + "What's New": "새로운 점", + "Add an email address above to configure email notifications": "이메일 알림을 설정하기 위해 이메일 주소를 추가해주세요", + "Expand panel": "확장 패널", + "On": "켜기", + "Filter room names": "방 이름 거르기", + "Changelog": "바뀐 점", + "Running Matrix services": "매트릭스 서비스 실행", + "Waiting for response from server": "서버에서 응답을 기다리는 중", + "Leave": "떠나기", + "Failed to send report: ": "보고를 보내지 못했어요: ", + "Unknown device": "알 수 없는 장치", + "Advanced notification settings": "고급 알림 설정", + "delete the alias.": "가명을 지울게요.", + "To return to your account in future you need to set a password": "나중에 계정으로 돌아가려면 비밀번호 설정을 해야만 해요", + "Forget": "잊기", + "World readable": "세계에 보이기", + "Riot/Web & Desktop chat": "라이엇/웹 & 컴퓨터 이야기", + "Hide panel": "패널 숨기기", + "You cannot delete this image. (%(code)s)": "이 사진을 지우실 수 없어요. (%(code)s)", + "Cancel Sending": "보내기 취소", + "Warning": "주의", + "This Room": "방", + "The Home Server may be too old to support third party networks": "타사 네트워크를 지원하기에는 홈 서버가 너무 오래된 걸 수 있어요", + "Resend": "다시 보내기", + "Error saving email notification preferences": "이메일 알림을 설정하는데 오류가 일어났어요", + "Messages containing my display name": "내 별명이 적힌 메시지", + "Messages in one-to-one chats": "1:1 이야기의 메시지", + "Contributing code to Matrix and Riot": "매트릭스와 라이엇에 코드 기여하기", + "Unavailable": "이용할 수 없음", + "Community-run support for Synapse": "시냅스 커뮤니티 운영 지원", + "View Decrypted Source": "해독된 출처 보기", + "Send": "보내기", + "remove %(name)s from the directory.": "목록에서 %(name)s을 지웠어요.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "여기 표시될 수 없는 규칙에 따라 다음 키워드는 알리지 않아요:", + "Please set a password!": "비밀번호를 설정해주세요!", + "You have successfully set a password!": "비밀번호를 설정했어요!", + "Chat with Riot Bot": "Riot 봇과 이야기하기", + "Support for those using, running and writing other bridges": "다른 브릿지를 사용하고, 운영하고, 기록하는 사람들을 지원", + "Admin support for Dendrite": "덴드라이트 관리 지원", + "An error occurred whilst saving your email notification preferences.": "이메일 알림을 설정하다가 오류가 일어났어요.", + "Source URL": "출처 URL", + "Failed to add tag %(tagName)s to room": "방에 %(tagName)s로 지정하지 못했어요", + "Members": "구성원", + "No update available.": "업데이트가 없어요.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "기존 네트워크(Slack, IRC, Gitter 등)에 연결되있거나 독립된 많은 방들이 이미 매트릭스에 있어요. 목록을 확인해보세요!", + "Noisy": "소리", + "Files": "파일", + "Collecting app version information": "앱 버전 정보를 수집하는 중", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "방 가명 %(alias)s 을 지우고 목록에서 %(name)s를 지우시겠어요?", + "customServer_text": "사용자 지정 서버 설정에서 다른 홈 서버 URL을 지정해 다른 매트릭스 서버에 로그인할 수 있어요.
    이를 통해 라이엇과 다른 홈 서버의 기존 매트릭스 계정을 함께 쓸 수 있죠.

    사용자 지정 ID 서버를 설정할 수도 있지만 이메일 주소로 사용자를 초대하거나 초대받을 수는 없답니다.", + "Co-ordination for Riot/Web translators": "라이엇/웹 번역자를 위한 조정", + "This will allow you to return to your account after signing out, and sign in on other devices.": "이런 식으로 로그아웃한 뒤 계정으로 돌아가, 다른 장치에서 로그인하실 수 있어요.", + "Dev chat for the Dendrite dev team": "덴드라이트 개발 팀을 위한 개발자 대화", + "Design and implementation of E2E in Matrix": "매트릭스에서 E2E 설계와 구현", + "Enable notifications for this account": "이 계정의 알림 받기", + "Directory": "목록", + "Search for a room": "방에서 찾기", + "Messages containing keywords": "키워드가 적힌 메시지", + "Room not found": "방을 찾지 못했어요", + "Tuesday": "화요일", + "Enter keywords separated by a comma:": "키워드를 쉼표로 구분해 입력해주세요:", + "Search…": "찾기…", + "Remove %(name)s from the directory?": "목록에서 %(name)s을 지우시겠어요?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "라이엇은 많은 고급 브라우저 기능을 사용해요. 일부는 현재 브라우저에서 쓸 수 없거나 실험적이에요.", + "Developer Tools": "개발자 도구", + "Enable desktop notifications": "컴퓨터에서 알림 받기", + "Unnamed room": "이름없는 방", + "Remove from Directory": "목록에서 지우기", + "Saturday": "토요일", + "Remember, you can always set an email address in user settings if you change your mind.": "잊지마세요, 마음이 바뀌면 언제라도 사용자 설정에서 이메일 주소를 바꾸실 수 있다는 걸요.", + "Direct Chat": "직접 이야기하기", + "The server may be unavailable or overloaded": "서버를 쓸 수 없거나 과부하일 수 있어요", + "Reject": "거절하기", + "Riot is not supported on mobile web. Install the app?": "라이엇은 모바일 사이트를 지원하지 않아요. 앱을 설치하시겠어요?", + "Discussion of all things Matrix!": "매트릭스의 모든 것에 대한 토론!", + "Failed to set Direct Message status of room": "방의 쪽지 상태를 설정하지 못했어요", + "Monday": "월요일", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "문제를 진단하기 위해서, 이 클라이언트의 로그를 오류 보고서와 같이 보낼 거에요. 위 내용만 보내시려면, 체크를 해제하세요:", + "All messages (noisy)": "모든 메시지 (크게)", + "Enable them now": "지금 켜기", + "Forward Message": "메시지 전달", + "Describe your problem here.": "여기에 일어난 문제를 적어주세요.", + "Messages containing my user name": "내 사용자 이름이 적힌 메시지", + "Toolbox": "도구상자", + "Collecting logs": "로그 수집 중", + "more": "더 보기", + "Bug report sent": "오류 보고서를 보냈어요", + "(HTTP status %(httpStatus)s)": "(HTTP 상태 %(httpStatus)s)", + "All Rooms": "모든 방", + "Failed to get public room list": "공개한 방 목록을 얻지 못했어요", + "Quote": "인용하기", + "Failed to update keywords": "키워드를 갱신하지 못했어요", + "Send logs": "로그 보내기", + "All messages": "모든 메시지", + "Implementing VoIP services with Matrix": "매트릭스로 인터넷전화 서비스 구현", + "Dev chat for the Riot/Web dev team": "라이엇/웹 개발 팀을 위한 개발자 대화", + "Call invitation": "전화가 왔어요", + "Riot Desktop on %(platformName)s": "%(platformName)s에서 라이엇 컴퓨터판", + "Downloading update...": "업데이트를 받는 중...", + "You have successfully set a password and an email address!": "비밀번호와 이메일 주소를 설정했어요!", + "What's new?": "새로운 점은?", + "Discussion of the Identity Service API": "ID 서비스 API에 대한 논의", + "Support for those using and running matrix-appservice-irc": "matrix-appservice-irc를 사용하고 운영하는 사람들을 지원", + "Riot/iOS & matrix-ios-sdk chat": "라이엇/IOS & matrix-ios-sdk 대화", + "Notify me for anything else": "모든 걸 알리기", + "When I'm invited to a room": "방에 초대받았을 때", + "Keywords": "키워드", + "Can't update user notification settings": "사용자 알림 설정을 갱신할 수 없어요", + "Notify for all other messages/rooms": "다른 모든 메시지/방 알리기", + "Unable to look up room ID from server": "서버에서 방 ID를 찾아볼 수 없어요", + "Couldn't find a matching Matrix room": "일치하는 매트릭스 방을 찾을 수 없어요", + "Support for those using the Matrix spec": "Matrix spec을 사용하는 사람들을 지원", + "Safari and Opera work too.": "사파리오페라에서도 작동해요.", + "Loading bug report module": "오류 보고 모듈을 불러오는 중", + "Invite to this room": "이 방에 초대하기", + "You cannot delete this message. (%(code)s)": "이 메시지를 지우실 수 없어요. (%(code)s)", + "Thursday": "목요일", + "I understand the risks and wish to continue": "위험할 수 있는 걸 알고 계속하기를 바라요", + "%(appName)s via %(browserName)s on %(osName)s": "%(osName)s의 %(browserName)s을 통한 %(appName)s", + "Back": "돌아가기", + "Failed to change settings": "설정을 바꾸지 못했어요", + "Show message in desktop notification": "컴퓨터 알림에서 내용 보이기", + "Unhide Preview": "미리보기를 숨기지 않기", + "Announcements about Synapse releases": "시냅스 공개 발표", + "Search the room directory": "방 목록을 찾기", + "Please describe the bug and/or send logs.": "오류를 적어주시거나 로그를 보내주세요.", + "Unable to join network": "네트워크에 들어갈 수 없어요", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "라이엇이 아닌 다른 클라이언트에서 구성하셨을 수도 있어요. 라이엇에서 조정할 수는 없지만 여전히 적용되있을 거에요", + "Sorry, your browser is not able to run Riot.": "죄송해요. 브라우저에서 라이엇을 켤 수가 없어요.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "분산되고, 암호화된 대화 & [matrix]의 지원으로 협력", + "Uploaded on %(date)s by %(user)s": "by %(user)s가 %(date)s에 올림", + "Messages in group chats": "이야기 모임의 메시지", + "Yesterday": "어제", + "Error encountered (%(errorDetail)s).": "오류가 일어났어요 (%(errorDetail)s).", + "Low Priority": "낮은 우선순위", + "Riot does not know how to join a room on this network": "라이엇이 이 네트워크에서 방에 들어가는 법을 알 수 없어요", + "Appear Offline": "미접속으로 표시하기", + "Get started with some tips from Riot Bot!": "라이엇 봇에게 조언을 받고 시작하세요!", + "Set Password": "비밀번호 설정", + "Enable audible notifications in web client": "웹 클라이언트에서 알림 소리 켜기", + "Permalink": "고유주소", + "Welcome to Riot.im": "라이엇에 오신 걸 환영해요", + "Off": "끄기", + "#example": "#예", + "Mentions only": "답만 하기", + "Failed to remove tag %(tagName)s from room": "방에서 %(tagName)s 지정을 지우지 못했어요", + "Wednesday": "수요일", + "You can now return to your account after signing out, and sign in on other devices.": "계정을 로그아웃하신 뒤에 계정으로 돌아가, 다른 장치에서 로그인하실 수 있어요.", + "Please install Chrome or Firefox for the best experience.": "최상의 경험을 위해 크롬이나 파이어폭스를 설치해주세요.", + "Enable email notifications": "이메일로 알림 받기", + "Login": "로그인", + "No rooms to show": "보여드릴 방이 없어요", + "Download this file": "이 파일 받기", + "Thank you!": "감사합니다!", + "View Source": "출처 보기", + "Matrix technical discussions": "매트릭스 기술 논의", + "Unable to fetch notification target list": "알림 대상 목록을 불러올 수 없어요", + "Building services on Matrix": "매트릭스에서 서비스 구축", + "Collapse panel": "패널 접기", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "현재 브라우저에서는, 응용 프로그램의 모양과 기능이 완벽하게 맞지 않거나, 일부 혹은 모든 기능이 작동하지 않을 수 있어요. 계속할 수는 있지만, 맞닥뜨리는 모든 문제는 직접 해결하셔야해요!", + "Checking for an update...": "업데이트를 확인하는 중...", + "General discussion about Matrix and Riot": "매트릭스와 라이엇에 대한 일반 논의", + "There are advanced notifications which are not shown here": "여기 보이지 않는 고급 알림이 있어요" } diff --git a/src/i18n/strings/lt.json b/src/i18n/strings/lt.json index 38cc908111..a56bd7b953 100644 --- a/src/i18n/strings/lt.json +++ b/src/i18n/strings/lt.json @@ -12,5 +12,226 @@ "Your identity server's URL": "Jūsų identifikavimo serverio URL adresas", "Analytics": "Statistika", "The information being sent to us to help make Riot.im better includes:": "Informacijoje, kuri yra siunčiama Riot.im tobulinimui yra:", - "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "Mes taip pat saugome kiekvieną puslapį, kurį jūs naudojate programėlėje (dabartinis ), jūsų paskyros agentas () ir jūsų įrenginio rezoliucija ()." + "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "Mes taip pat saugome kiekvieną puslapį, kurį jūs naudojate programėlėje (dabartinis ), jūsų paskyros agentas () ir jūsų įrenginio rezoliucija ().", + "Fetching third party location failed": "Nepavyko gauti trečios šalies vietos", + "A new version of Riot is available.": "Yra nauja Riot versija.", + "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk chat", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Aprašykite klaidą. Ką darėte? Ko tikėjotės, kad įvyks? Kas iš tikrųjų įvyko?", + "I understand the risks and wish to continue": "Aš suprantu riziką ir noriu tęsti", + "Couldn't load home page": "Nepavyksta užkrauti namų puslapio", + "Send Account Data": "Siųsti paskyros duomenis", + "Advanced notification settings": "Išplėstiniai pranešimų nustatymai", + "Uploading report": "Išsiunčiama ataskaita", + "Sunday": "Sekmadienis", + "Guests can join": "Svečiai gali prisijungti", + "Notification targets": "Pranešimo objektai", + "General discussion about Matrix and Riot": "Bendros diskusijos apie Matrix ir Riot", + "Today": "Šiandien", + "Files": "Failai", + "Report a bug": "Siųsti klaidos ataskaitą", + "Implementing VR services with Matrix": "VR serviso įgyvendinimas su Matrix", + "You are not receiving desktop notifications": "Jūs negaunate darbalaukio pranešimų", + "Friday": "Penktadienis", + "Update": "Atnaujinti", + "Notifications": "Pranešimai", + "You need to be using HTTPS to place a screen-sharing call.": "Norint skambinti su ekrano bendrinimo funkcija būtina naudoti HTTPS.", + "Unable to fetch notification target list": "Nėra galimybės rasti pranešimo objektų sąrašui", + "Add an email address above to configure email notifications": "Norėdami gauti pranešimus el. paštu įveskite į aukščiau esantį laukelį el. pašto adresą", + "Expand panel": "Išskleisti skydelį", + "On": "Įjungta", + "%(count)s Members|other": "%(count)s nariai", + "Filter room names": "Filtruoti kambarių pavadinimus", + "Changelog": "Keitinių žurnalas", + "Running Matrix services": "Vykdant Matrix servisus", + "Waiting for response from server": "Laukiama atsakymo iš serverio", + "Failed to change password. Is your password correct?": "Nepavyko pakeisti slaptažodžio. Ar Jūsų slaptažodis teisingas?", + "Uploaded on %(date)s by %(user)s": "Atnaujinta %(date)s vartotojo %(user)s", + "OK": "Gerai", + "Send Custom Event": "Siųsti pasirinktinį įvykį", + "Failed to send report: ": "Nepavyko išsiųsti ataskaitos: ", + "Unknown device": "Nežinomas įrenginys", + "All notifications are currently disabled for all targets.": "Šiuo metu visi pranešimai visiems objektams yra išjungti.", + "Operation failed": "Operacija nepavyko", + "delete the alias.": "ištrinti slapyvardį.", + "To return to your account in future you need to set a password": "Ateityje norėdami prisijungti prie savo paskyros turite susigalvoti slaptažodį", + "Forget": "Pamiršti", + "World readable": "Visiems skaitomas", + "Mute": "Užtildyti", + "Riot/Web & Desktop chat": "Riot/Web & Darbalaukio čatas", + "Hide panel": "Slėpti skydelį", + "You cannot delete this image. (%(code)s)": "Jūs negalite ištrinti šio paveikslėlio. (%(code)s)", + "Cancel Sending": "Atšaukti siuntimą", + "Warning": "Įspėjimas", + "This Room": "Šis pokalbių kambarys", + "The Home Server may be too old to support third party networks": "Serveris gali būti per senas ir negali palaikyti trečių šalių tinklų", + "Resend": "Siųsti iš naujo", + "Room not found": "Kambarys nerastas", + "Downloading update...": "Atsiunčiamas atnaujinimas...", + "Messages in one-to-one chats": "Žinutės asmeniniuose pokalbiuose", + "Contributing code to Matrix and Riot": "Contributing code to Matrix and Riot", + "Unavailable": "Neprieinamas", + "Community-run support for Synapse": "Bendruomenės Synapse palaikymas", + "Error saving email notification preferences": "Klaida, įrašant pranešimų el. paštu nuostatas", + "View Decrypted Source": "Peržiūrėti iššifruotą šaltinį", + "Failed to update keywords": "Nepavyko atnaujinti raktažodžių", + "Welcome to Riot.im": "Sveiki atvykę į Riot.im", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Pranešimai šiems raktažodžiams yra uždrausti taisyklėmis:", + "Safari and Opera work too.": "Naudojant Safari ir Opera taip pat gerai veikia.", + "Please set a password!": "Prašau įrašykite slaptažodį!", + "powered by Matrix": "palaikomas Matrix", + "You have successfully set a password!": "Jūs sėkmingai įrašėte slaptažodį!", + "Chat with Riot Bot": "Kalbėtis su Riot robotu", + "Support for those using, running and writing other bridges": "Palaikymas skirtas tiems kas naudoja kitus tiltus", + "Admin support for Dendrite": "Administratoriaus Dendrite palaikymas", + "Favourite": "Svarbūs", + "All Rooms": "Visi pokalbių kambariai", + "Explore Room State": "Peržiūrėti pokalbių kambario būseną", + "Source URL": "Šaltinio URL adresas", + "Messages sent by bot": "Roboto siunčiamos žinutės", + "Cancel": "Atšaukti", + "Filter results": "Išfiltruoti rezultatus", + "Members": "Nariai", + "No update available.": "Nėra prieinamų atnaujinimų.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Daugybė kambarių yra prisijungę prie Matrix, kurie yra susieti su egzistuojančiais tinklais (Slack, IRC, Gitter etc) arba nepriklausomi. Patikrinkite kambarių katalogą!", + "Noisy": "Triukšmingas", + "Failed to get protocol list from Home Server": "Nepavyko gauti protokolų sąrašo iš serverio", + "Collecting app version information": "Renkama programėlės versijos informacija", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Ar ištrinti kambarį %(alias)s ir %(name)s kambario pavadinimą iš katalogo?", + "Co-ordination for Riot/Web translators": "Riot/Web vertėjų koordinacija", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Tai leis Jums grįžti prie paskyros po atsijungimo ir prisijungti kituose įrenginiuose.", + "Dev chat for the Dendrite dev team": "Kūrėjų čatas Dendrite dev team", + "Keywords": "Raktažodžiai", + "Unpin Message": "Atsegti žinutę", + "Enable notifications for this account": "Įjungti pranešimus šiai paskyrai", + "Remove": "Šalinti", + "Directory": "Katalogas", + "Invite to this community": "Pakviesti į šią bendruomenę", + "Search for a room": "Ieškoti kambario", + "Messages containing keywords": "Žinutės, kuriose yra raktažodžiai", + "When I'm invited to a room": "Kai aš esu pakviestas į pokalbių kambarį", + "Tuesday": "Antradienis", + "Enter keywords separated by a comma:": "Įveskite kableliais atskirtus raktažodžius:", + "Search…": "Paieška…", + "You have successfully set a password and an email address!": "Jūs sėkmingai įrašėte slaptažodį ir el. pašto adresą!", + "Remove %(name)s from the directory?": "Ar ištrinti %(name)s iš katalogo?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot naudoja daug išplėstinių naršyklės funkcionalumų, kai kurie iš jų yra neprieinami ar eksperimentinei Jūsų naršyklėje.", + "Event sent!": "Įvykis išsiųstas!", + "Bug report sent": "Klaidos ataskaita išsiųsta", + "Unnamed room": "Kambarys be pavadinimo", + "Dismiss": "Nutraukti", + "Explore Account Data": "Peržiūrėti paskyros duomenis", + "Remove from Directory": "Šalinti iš katalogo", + "Away": "Neaktyvus", + "Download this file": "Atsisiųsti šį failą", + "Saturday": "Šeštadienis", + "Remember, you can always set an email address in user settings if you change your mind.": "Nepamirškite, kad galite, bet kada įrašyti savo el. pašto adresą paskyros nustatymuose.", + "Direct Chat": "Tiesioginis pokalbis", + "The server may be unavailable or overloaded": "Gali būti, kad serveris yra neprieinamas arba perkrautas", + "Online": "Prisijungęs", + "Riot is not supported on mobile web. Install the app?": "Riot nėra palaikoma naršant svetainėje mobiliaisiais įrenginiais. Įdiegti programėlę?", + "Discussion of all things Matrix!": "Diskusijos apie viską Matrix!", + "Failed to set Direct Message status of room": "Nepavyko nustatyti tiesioginio pranešimo kambario būklės", + "Monday": "Pirmadienis", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Tam, kad nustatytume problemas, iš šio kliento bus išsiųsti žurnalai kartu su klaidos ataskaita. Jeigu norite siųsti tik žemiau esantį tekstą nuimkite šia varnelę:", + "All messages (noisy)": "Visos žinutės (triukšmingas)", + "Enable them now": "Įgalinti juos dabar", + "Enable audible notifications in web client": "Įgalinti garsinius pranešimus internetinėje aplinkoje", + "Messages containing my user name": "Žinutės, kuriose paminėtas mano naudotojo vardas", + "Describe your problem here.": "Čia aprašykite savo problemą.", + "Toolbox": "Įrankinė", + "Collecting logs": "Renkami žurnalai", + "more": "daugiau", + "Rooms": "Kambariai", + "Failed to get public room list": "Nepavyko gauti viešų pokalbių kambarių sąrašo", + "Search": "Ieškoti", + "You must specify an event type!": "Privalote nurodyti įvykio tipą!", + "(HTTP status %(httpStatus)s)": "(HTTP būsena %(httpStatus)s)", + "Failed to forget room %(errCode)s": "Nepavyko pašalinti pokalbių kambario %(errCode)s", + "What's New": "Kas naujo", + "Please install Chrome or Firefox for the best experience.": "Prašau įdiekite Chrome arba Firefox geriausiam rezultatui gauti.", + "Wednesday": "Trečiadienis", + "Send": "Siųsti", + "Error": "Klaida", + "Send logs": "Siųsti žurnalus", + "All messages": "Visos žinutės", + "unknown error code": "nežinomas klaidos kodas", + "Implementing VoIP services with Matrix": "VoIP serviso įgyvendinimas su Matrix", + "Dev chat for the Riot/Web dev team": "Kūrėjų čatas Riot/Web dev team", + "Call invitation": "Pakvietimas skambinant", + "Riot Desktop on %(platformName)s": "Riot Desktop, %(platformName)s", + "Messages containing my display name": "Žinutės, kuriose paminėtas mano vardas", + "State Key": "Būklės raktas", + "Failed to send custom event.": "Nepavyko išsiųsti pasirinktinio įvykio.", + "What's new?": "Kas naujo?", + "Discussion of the Identity Service API": "Diskusijos apie identifikavimo serviso API", + "Support for those using and running matrix-appservice-irc": "Palaikymas skirtas matrix-appservice-irc naudotojams", + "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk chat", + "Notify me for anything else": "Pranešti man apie visa kita", + "View Source": "Peržiūrėti šaltinį", + "Design and implementation of E2E in Matrix": "E2E dizainas ir įgyvendinimas Matrix'e", + "Close": "Užverti", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Norėdami jungtis prie kito nei Matrix serverio galite pasirinktinio serverio nustatymuose nurodyti kito serverio URL adresą.
    Ši funkcija leis naudoti Riot su esama Matrix serverio paskyrą kituose serveriuose.

    Taip pat galite nurodyti pasirinktinį identifikavimo serverį, bet tuomet negalėsite kviesti kitų vartotojų el. paštu ar jie jūsų.", + "Can't update user notification settings": "Nepavyksta atnaujinti naudotojo pranešimų nustatymų", + "Notify for all other messages/rooms": "Pranešti apie visas kitas žinutes/pokalbių kambarius", + "Unable to look up room ID from server": "Nepavyko gauti kambario ID iš serverio", + "Couldn't find a matching Matrix room": "Nepavyko rasti atitinkamo Matrix kambario", + "Support for those using the Matrix spec": "Palaikymas skirtas Matrix spec", + "Loading bug report module": "Įkraunamas klaidų ataskaitų modulis", + "Invite to this room": "Pakviesti į šį kambarį", + "You cannot delete this message. (%(code)s)": "Jūs negalite trinti šios žinutės. (%(code)s)", + "Thursday": "Ketvirtadienis", + "Forward Message": "Persiųsti žinutę", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s per %(browserName)s, naudojant %(osName)s", + "Back": "Atgal", + "Reply": "Atsakyti", + "Show message in desktop notification": "Rodyti žinutes darbalaukio pranešimuose", + "Announcements about Synapse releases": "Pranešimai apie Synapse naujinimus", + "Search the room directory": "Ieškoti kambarių kataloge", + "Please describe the bug and/or send logs.": "Prašau apibūdinkite programos klaidą ir/arba išsiųskite žurnalo įrašus.", + "Reject": "Atmesti", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Jūs turbūt juos sukonfigūravote kitoje programėlėje nei Riot. Negalite jų koreguoti Riot programėlėje, bet jie vistiek yra taikomi", + "Sorry, your browser is not able to run Riot.": "Atleiskite, jūsų naršyklė negali paleisti Riot.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Decentralizuotas, šifruotas čatas; bendradarbiavimas palaikomas [matrix]", + "Quote": "Citata", + "Messages in group chats": "Žinutės grupės pokalbiuose", + "Yesterday": "Vakar", + "Error encountered (%(errorDetail)s).": "Gauta klaida (%(errorDetail)s).", + "Login": "Prisijungti", + "Low Priority": "Nesvarbūs", + "Riot does not know how to join a room on this network": "Riot nežino kaip prisijungti prie kambario šiame tinkle", + "Set Password": "Nustatyti slaptažodį", + "Appear Offline": "Neprisijungęs", + "Get started with some tips from Riot Bot!": "Pradėkite su patarimais nuo Riot roboto!", + "An error occurred whilst saving your email notification preferences.": "Įrašant pranešimų el. paštu nuostatas, įvyko klaida.", + "Unable to join network": "Nepavyko prisijungti prie tinklo", + "Permalink": "Pastovioji nuoroda", + "Register": "Registruotis", + "Off": "Išjungta", + "Edit": "Koreguoti", + "#example": "#pavyzdys", + "Mentions only": "Tik paminėjimai", + "remove %(name)s from the directory.": "šalinti %(name)s iš katalogo.", + "You can now return to your account after signing out, and sign in on other devices.": "Po atsijungimo galite grįžti prie savo paskyros ir prisijungti kituose įrenginiuose.", + "Continue": "Tęsti", + "Enable desktop notifications": "Įjungti darbalaukio pranešimus", + "Enable email notifications": "Įjungti pranešimus el. paštu", + "Event Type": "Įvykio tipas", + "No rooms to show": "Nėra kambarių rodymui", + "Add rooms to this community": "Įtraukti kambarius į šią bendruomenę", + "Pin Message": "Prisegti žinutę", + "Failed to change settings": "Nepavyko pakeisti nustatymų", + "Leave": "Atsijungti", + "View Community": "Peržiūrėti bendruomenes", + "%(count)s Members|one": "%(count)s narys", + "Developer Tools": "Programuotojo įrankiai", + "Unhide Preview": "Rodyti paržiūrą", + "Custom Server Options": "Pasirinktiniai serverio nustatymai", + "Event Content": "Įvykio turinys", + "Thank you!": "Ačiū!", + "Building services on Matrix": "Servisų kūrimas ant Matrix", + "Collapse panel": "Suskleisti skydelį", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Naudojant šią naršyklę aplikacija gali atrodyti ir reaguoti neteisingai. Kai kurios arba visos funkcijos gali neveikti. Jei vis tiek norite pabandyti gali tęsti, tačiau iškilusios problemos yra jūsų pačių reikalas!", + "Checking for an update...": "Tikrinama ar yra atnaujinimų...", + "Matrix technical discussions": "Matrix techninės diskusijos", + "There are advanced notifications which are not shown here": "Yra išplėstinių pranešimų, kurie nėra čia rodomi" } diff --git a/src/i18n/strings/lv.json b/src/i18n/strings/lv.json index 8bb4d0a9bc..8ca3a169b9 100644 --- a/src/i18n/strings/lv.json +++ b/src/i18n/strings/lv.json @@ -1000,5 +1000,206 @@ "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Ja esi paziņojis par kļūdu caur GitHub, atutošanas logfaili var mums palīdzēt identificēt problēmu. Atutošanas logfaili satur programmas lietošanas datus, tostarp Tavu lietotājvārdu, istabu/grupu Id vai aliases, kuras esi apmeklējis un citu lietotāju lietotājvārdus. Tie nesatur pašas ziņas.", "Submit debug logs": "Iesniegt atutošanas logfailus", "Opens the Developer Tools dialog": "Atver Izstrādātāja instrumentus", - "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Skatījis %(displayName)s (%(userName)s) %(dateTime)s" + "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Skatījis %(displayName)s (%(userName)s) %(dateTime)s", + "Fetching third party location failed": "Neizdevās iegūt trešās puses atrašanās vietu", + "A new version of Riot is available.": "Pieejama jauna Riot versija.", + "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk čats", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Lūdzu, apraksti kļūdu. Kas tika darīts? Kādas bija gaidas (kāds rezultāts tika sagaidīts)? Kas realitātē notika?", + "Couldn't load home page": "Neizdevās ielādēt sākumlapu", + "Send Account Data": "Sūtīt konta datus", + "All notifications are currently disabled for all targets.": "Visiem saņēmējiem visi paziņojumi ir atspējoti.", + "Uploading report": "Augšuplādē atskaiti", + "Sunday": "svētdiena", + "Notification targets": "Paziņojuma mērķi", + "Today": "šodien", + "Failed to get protocol list from Home Server": "Neizdevās iegūt protokolu sarakstu no Bāzes servera", + "Report a bug": "Informēt par kļūdu", + "Implementing VR services with Matrix": "VR pakalpojumu iedzīvināšana Matrix", + "You are not receiving desktop notifications": "Darbvirsmas paziņojumi netiek saņemti", + "Friday": "piektdiena", + "Update": "Aktualizēt", + "You need to be using HTTPS to place a screen-sharing call.": "Lai izmantotu ekrāna kopīgošanas zvanu, nepieciešams izmantot HTTPS savienojumu.", + "What's New": "Kas jauns", + "Add an email address above to configure email notifications": "Lai konfigurētu epasta paziņojumus, pievieno epasta adresi", + "Expand panel": "Izvērst paneli", + "On": "ieslēgts", + "%(count)s Members|other": "%(count)s biedru", + "Filter room names": "Filtrēt pēc istabu nosaukuma", + "Changelog": "Izmaiņu saraksts (vēsture)", + "Running Matrix services": "Matrix pakalpojumu izmantošana", + "Waiting for response from server": "Gaidām atbildi no servera", + "Send Custom Event": "Sūtīt individuālu notikumu", + "Failed to send report: ": "Neizdevās nosūtīt atskaiti: ", + "Unknown device": "Nezināma ierīce", + "Advanced notification settings": "Paziņojumu papildus iestatījumi", + "Failed to send logs: ": "Neizdevās nosūtīt logfailus: ", + "delete the alias.": "dzēst aliasi/aizstājējvārdu.", + "To return to your account in future you need to set a password": "Lai nākotnē atgrieztos savā kontā, nepieciešams iestatīt paroli", + "Forget": "Aizmirst", + "#example": "#piemērs", + "Riot/Web & Desktop chat": "Riot/Web & darbvirsmas čats", + "Hide panel": "Slēpt paneli", + "You cannot delete this image. (%(code)s)": "Šo attēlu nevar izdzēst (%(code)s)", + "Cancel Sending": "Atcelt sūtīšanu", + "This Room": "šajā istabā", + "The Home Server may be too old to support third party networks": "Bāzes serveris var būt pārāk novecojis, lai ļautu izmantot trešo pušu tīmekļa resursus", + "Noisy": "ar skaņu", + "Error saving email notification preferences": "Kļūda saglabājot epasta notifikāciju paziņojumu uzstādījumus", + "Messages containing my display name": "Ziņas, kuras satur manu redzamo vārdu", + "Messages in one-to-one chats": "Ziņas viens-pret-vienu čatos", + "Contributing code to Matrix and Riot": "Dot ieguldījumu Matrix and Riot kodā un tulkojumā", + "Unavailable": "Nesasniedzams", + "Community-run support for Synapse": "\"Synapse\" komūnas nodrošināts atbalsts", + "View Decrypted Source": "Skatīt atšifrētu avotu", + "Failed to update keywords": "Neizdevās aktualizēt atslēgvārdus", + "Notes:": "Piezīmes:", + "remove %(name)s from the directory.": "dzēst %(name)s no kataloga.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Paziņojumi par šādiem atslēgvārdiem atbilst noteikumiem, kurus šeit nevar parādīt:", + "Safari and Opera work too.": "Safari un Opera arī nav skādējami.", + "Please set a password!": "Lūdzu iestati paroli!", + "You have successfully set a password!": "Esi veiksmīgi iestatījis(usi) paroli!", + "Chat with Riot Bot": "Pačatot ar Riot botu", + "Support for those using, running and writing other bridges": "Atbalsts tiem, kuri izmanto un rada citus \"tiltu\" risinājumus", + "Admin support for Dendrite": "Administrotora atbalsts \"Dendrite\"", + "An error occurred whilst saving your email notification preferences.": "Saglabājot Tavus epasta paziņojumu uzstādījumus, radās kļūda.", + "Explore Room State": "Noskaidrot istabas statusu", + "Source URL": "Avota URL adrese", + "Messages sent by bot": "Botu nosūtītās ziņas", + "Filter results": "Filtrēt rezultātus", + "Members": "Biedri", + "No update available.": "Nav pieejamu aktualizāciju.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Matrix-ā pastāv daudzas neatkarīgas un/vai eksistējošiem tīmekļa resursiem (Slack, IRC, Gitter u.tml.) piesaistītas istabas. Ieskaties katalogā!", + "Resend": "Nosūtīt atkārtoti", + "Files": "Faili", + "Collecting app version information": "Tiek iegūta programmas versijas informācija", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Dzēst istabas aliasi/aizstājējvārdu %(alias)s un dzēst %(name)s no kataloga?", + "customServer_text": "Tu vari izmantot īpašus servera uzstādījumus, lai pierakstītos citos Matrix serveros, norādot atšķirīgu servera URL adresi.
    Tas atļaus Tev izmantot Riot ar jau eksistējošu Matrix kontu citā serverī.

    Tu vari norādīt arī īpašu identitātes serveri, bet tad nevarēsi uzaicināt lietotājus pēc epasta adreses,kā arī pēc tās tikt uzaicināts/a.", + "Co-ordination for Riot/Web translators": "Riot/Web tulkotāju koordinācija", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Tas atļaus Tev atgriezties savā kontā pēc izrakstīšanās, un pierakstīties no citām ierīcēm.", + "Dev chat for the Dendrite dev team": "Dendrite izstrādatāju komandas čats", + "Keywords": "Atslēgvārdi", + "Enable notifications for this account": "Iespējot paziņojumus šim kontam", + "Directory": "Katalogs", + "Invite to this community": "Uzaicināt šajā kopienā", + "Failed to get public room list": "Neizdevās iegūt publisko istabu sarakstu", + "Messages containing keywords": "Ziņas, kuras satur atslēgvārdus", + "Room not found": "Istaba netika atrasta", + "Tuesday": "otrdiena", + "Enter keywords separated by a comma:": "Ievadi atslēgvārdus, atdalītus ar komatu:", + "Search…": "Meklēju…", + "You have successfully set a password and an email address!": "Esi veiksmīgi iestatījis(usi) paroli un epasta adresi!", + "Remove %(name)s from the directory?": "Dzēst %(name)s no kataloga?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot izmanto daudzas advancētas tīmekļa pārlūka iespējas, no kurām dažas var nebūt pieejamas vai ir eksperimentālas Tavā pašreizējajā pārlūkā.", + "Event sent!": "Notikums nosūtīts!", + "Preparing to send logs": "Gatavojos nosūtīt atutošanas logfailus", + "Enable desktop notifications": "Iespējot darbvirsmas paziņojumus", + "Explore Account Data": "Aplūkot konta datus", + "All messages (noisy)": "Visas ziņas (ar skaņu)", + "Away": "Prom (nav uz vietas)", + "Saturday": "sestdiena", + "Remember, you can always set an email address in user settings if you change your mind.": "Atceries, ka vienmēr vari iestatīt epasta adresi lietotāja uzstādījumos, ja pārdomā.", + "Direct Chat": "Tiešais čats", + "The server may be unavailable or overloaded": "Serveris nav pieejams vai ir pārslogots", + "Reject": "Noraidīt", + "Riot is not supported on mobile web. Install the app?": "Riot netiek atbalstīts mobilajā versijā. Instalēt aplikāciju?", + "Discussion of all things Matrix!": "Diskusija par visām ar Matrix saistītajām lietām!", + "Failed to set Direct Message status of room": "Neizdevās iestatīt istabas tiešās ziņas statusu", + "Monday": "pirmdiena", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Problēmu diagnosticēšanas mērķim šī klienta logfaili tiks nosūtīti kopā ar šo kļūdas atskaiti. Ja vēlies nosūtīt vienīgi zemāk redzamo tekstu, lūdzu noņem ķeksi:", + "Remove from Directory": "Dzēst no kataloga", + "Enable them now": "Iespējot tos tagad", + "Forward Message": "Pārsūtīt ziņu", + "Describe your problem here.": "Apraksti šeit savu problēmu.", + "Messages containing my user name": "Ziņas, kuras satur manu lietotājvārdu", + "Toolbox": "Instrumentārijs", + "Collecting logs": "Tiek iegūti logfaili", + "more": "vairāk", + "GitHub issue link:": "GitHub problēmpaziņojuma saite:", + "Bug report sent": "Kļūdas atskaite nosūtīta", + "You must specify an event type!": "Jānorāda notikuma tips!", + "(HTTP status %(httpStatus)s)": "(HTTP statuss %(httpStatus)s)", + "All Rooms": "visās istabās", + "Please install Chrome or Firefox for the best experience.": "Labāko lietošanas pieredzi gūsi uzstādot pārlūkprogrammu Chromium vai Firefox.", + "Wednesday": "trešdiena", + "You cannot delete this message. (%(code)s)": "Tu nevari dzēst šo ziņu. (%(code)s)", + "Quote": "Citāts", + "Send logs": "Nosūtīt logfailus", + "All messages": "Visas ziņas", + "Implementing VoIP services with Matrix": "VoIP pakalpojumu iedzīvināšana Matrix", + "Dev chat for the Riot/Web dev team": "Riot/Web izstrādātāju komandas čats", + "Call invitation": "Uzaicinājuma zvans", + "Riot Desktop on %(platformName)s": "Riot darbvirsma %(platformName)s", + "Downloading update...": "Lejupielādēju aktualizāciju...", + "State Key": "Stāvokļa atslēga", + "Failed to send custom event.": "Individuālo notikumu nosūtīt neizdevās.", + "What's new?": "Kas jauns?", + "Discussion of the Identity Service API": "Diskusija par Identitātes servisa API", + "Support for those using and running matrix-appservice-irc": "Atbalsts tiem, kuri izmanto matrix-appservice-irc", + "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk čats", + "Notify me for anything else": "Paziņot man par jebko citu", + "When I'm invited to a room": "Kad esmu uzaicināts/a istabā", + "Design and implementation of E2E in Matrix": "E2E arhitektūra un iedzīvināšana Matrix", + "Click here to create a GitHub issue.": "Nospied šeit lai izveidotu GitHub problēmpaziņojumu.", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Tu vari lietot \"custom\" servera opcijas, lai ielogotos citos Matrix serveros, norādot citu Bāzes servera URL.
    Tas atļaus tev lietot Riot ar esošo Matrix kontu uz cita Bāzes servera.

    Tu arī vari uzstādīt atsevišķu Identitāšu serveri, taču tad Tev nebūs iespēju uzaicināt lietotājus, izmantojot epasta adresi, vai pašam tikt uzaicinātam, izmantojot epasta adresi.", + "Can't update user notification settings": "Neizdodas atjaunot lietotāja paziņojumu iestatījumus", + "Notify for all other messages/rooms": "Paziņot par visām citām ziņām/istabām", + "Unable to look up room ID from server": "Nav iespējams no servera iegūt istabas Id", + "Couldn't find a matching Matrix room": "Atbilstoša Matrix istaba netika atrasta", + "Support for those using the Matrix spec": "Atbalsts tiem, kuri izmanto Matrix specifikācijas", + "Safari and Opera work too.": "darbojas arī Safari un Opera.", + "Loading bug report module": "Ielādējas kļūdu atskaišu modulis", + "Invite to this room": "Uzaicināt uz šo istabu", + "Search for a room": "Meklēt istabu", + "Thursday": "ceturtdiena", + "I understand the risks and wish to continue": "Apzinos riskus un vēlos turpināt", + "Logs sent": "Logfaili nosūtīti", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s caur %(browserName)s un %(osName)s", + "Back": "Atpakaļ", + "Reply": "Atbildēt", + "Show message in desktop notification": "Parādīt ziņu darbvirsmas paziņojumos", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Atutošanas logfaili satur programmas datus, ieskaitot Tavu lietotājvārdu, istabu/grupu ID vai aliases, kuras esi apmeklējis un citu lietotāju lietotājvārdus. Tie nesatur pašas ziņas.", + "Unhide Preview": "Rādīt priekšskatījumu", + "Announcements about Synapse releases": "Paziņojumi par \"Synapse\" izlaidumiem", + "Search the room directory": "Meklēt istabu katalogā", + "Please describe the bug and/or send logs.": "Lūdzu apraksti kļūdu un/vai nosūti logfailus.", + "Unable to join network": "Nav iespējams pievienoties tīklam", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Droši vien Tu konfigurēji tās kādā citā Matrix klientā, nevis Riot. Nav iespējams tos pārkonfigurēt ar Riot, bet tie joprojām tiek izmantoti", + "Sorry, your browser is not able to run Riot.": "Atvaino, diemžēl tavs tīmekļa pārlūks nespēj darbināt Riot.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Decentralizēta, šifrēta čata & kopdarbošanās sistēma uz [matrix] bāzes", + "Uploaded on %(date)s by %(user)s": "Augšuplādēja %(user)s %(date)s", + "Messages in group chats": "Ziņas grupas čatos", + "Yesterday": "vakar", + "Error encountered (%(errorDetail)s).": "Gadījās kļūda (%(errorDetail)s).", + "Login": "Ierakstīties", + "Low Priority": "Zemas prioritātes", + "Unable to fetch notification target list": "Neizdevās iegūt paziņojumu mērķu sarakstu", + "Appear Offline": "Šķiet nesaistē (oflainā)", + "Get started with some tips from Riot Bot!": "Iepazīsties ar dažiem knifiem no Riot bota!", + "Set Password": "Iestatīt paroli", + "Enable audible notifications in web client": "Iespējot skaņus paziņojumus web klientā", + "Permalink": "Pastāvīgā saite", + "Welcome to Riot.im": "Esiet gaidīti Riot.im", + "Off": "izslēgts", + "Riot does not know how to join a room on this network": "Riot nezin kā pievienoties šajā tīklā esošajai istabai", + "Mentions only": "Vienīgi atsauces", + "You can now return to your account after signing out, and sign in on other devices.": "Tagad vari atgriezties savā kontā arī pēc izrakstīšanās, un pierakstīties no citām ierīcēm.", + "Please install Chrome or Firefox for the best experience.": "Lūdzu instalē Chrome vai Firefox pārlūku labākai pārlūkošanas pieredzei.", + "Enable email notifications": "Iespējot paziņojumus pa epastu", + "Event Type": "Notikuma tips", + "Download this file": "Lejupielādēt šo failu", + "Pin Message": "Piekabināt ziņu", + "Failed to change settings": "Neizdevās nomainīt iestatījumus", + "View Community": "Skatīt kopienu", + "%(count)s Members|one": "%(count)s biedru", + "Developer Tools": "Attīstītāja instrumenti", + "View Source": "Skatīt avotu", + "Matrix technical discussions": "Matrix tehniskās diskusijas", + "Event Content": "Notikuma saturs", + "Thank you!": "Tencinam!", + "Building services on Matrix": "Uz Matrix bāzētu pakalpojumu izveide", + "Collapse panel": "Sakļaut (saritināt) paneli", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Tavā pašreizējā pārlūkā aplikācijas izskats un uzvedība var būt pilnīgi neatbilstoša, kā arī dažas no visām funkcijām var nedarboties. Ja vēlies turpināt izmantot šo pārlūku, Tu vari arī turpināt, apzinoties, ka šajā gadījumā esi viens/a ar iespējamo problēmu!", + "Checking for an update...": "Lūkojos pēc aktualizācijas...", + "General discussion about Matrix and Riot": "Galvenā diskusija par Matrix un Riot", + "There are advanced notifications which are not shown here": "Pastāv papildus paziņojumi, kuri šeit netiek rādīti" } diff --git a/src/i18n/strings/ml.json b/src/i18n/strings/ml.json index 2deda25ee0..8edbeaf49f 100644 --- a/src/i18n/strings/ml.json +++ b/src/i18n/strings/ml.json @@ -21,5 +21,182 @@ "Failed to change password. Is your password correct?": "രഹസ്യവാക്ക് മാറ്റാന്‍ സാധിച്ചില്ല. രഹസ്യവാക്ക് ശരിയാണോ ?", "Continue": "മുന്നോട്ട്", "Microphone": "മൈക്രോഫോൺ", - "Camera": "ക്യാമറ" + "Camera": "ക്യാമറ", + "Fetching third party location failed": "തേഡ് പാര്‍ട്ടി ലൊക്കേഷന്‍ ഫെച്ച് ചെയ്യാന്‍ കഴിഞ്ഞില്ല", + "A new version of Riot is available.": "റയട്ടിന്റെ ഒരു പുതിയ പതിപ്പ് ലഭ്യമാണ്.", + "Riot/Android & matrix-android-sdk chat": "റയട്ട്/ആന്‍ഡ്രോയ്ഡ്& matrix-android-sdk ചാറ്റ്", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "ബഗ് വിശദീകരിക്കുക. എന്ത് ചെയ്തപ്പോഴാണ് വന്നത് ? എന്തായിരുന്നു പ്രതീക്ഷിച്ചിരുന്നത് ? ശരിക്കും എന്താണ് സംഭവിച്ചത് ?", + "All notifications are currently disabled for all targets.": "അറിയിപ്പുകളെല്ലാം നിര്‍ത്തിയിരിയ്ക്കുന്നു.", + "Uploading report": "റിപ്പോര്‍ട്ട് അപ്ലോഡ് ചെയ്യുന്നു", + "Sunday": "ഞായര്‍", + "Guests can join": "അതിഥികള്‍ക്കും പ്രവേശിക്കാം", + "Messages sent by bot": "ബോട്ട് അയയ്ക്കുന്ന സന്ദേശങ്ങള്‍ക്ക്", + "Notification targets": "നോട്ടിഫിക്കേഷന്‍ ടാര്‍ഗെറ്റുകള്‍", + "Failed to set direct chat tag": "ഡയറക്റ്റ് ചാറ്റ് ടാഗ് സെറ്റ് ചെയ്യാനായില്ല", + "Today": "ഇന്ന്", + "Failed to get protocol list from Home Server": "ഹോം സെര്‍വറില്‍ നിന്ന് പ്രോട്ടോക്കോള്‍ ലിസ്റ്റ് നേടാന്‍ സാധിച്ചില്ല", + "Report a bug": "ബഗ് റിപ്പോര്‍ട്ട് ചെയ്യുക", + "Implementing VR services with Matrix": "മട്രിക്സ് ഉപയോഗിച്ചു വി.അർ. സർവീസുകൾ നടപ്പിലാക്കുന്നു", + "You are not receiving desktop notifications": "നിങ്ങള്‍ക്ക് ഇപ്പോള്‍ ഡെസ്ക്ടോപ്പ് നോട്ടിഫിക്കേഷനുകള്‍ ലഭിക്കുന്നില്ല", + "Friday": "വെള്ളി", + "Update": "പുതുക്കുക", + "You need to be using HTTPS to place a screen-sharing call.": "സ്ക്രീന്‍ ഷെയറിങ്ങ് കോള്‍ നടത്തണമെങ്കില്‍ https ഉപയോഗിക്കണം.", + "What's New": "പുതിയ വിശേഷങ്ങള്‍", + "Add an email address above to configure email notifications": "ഇ മെയില്‍ അറിയിപ്പുകൾ ലഭിക്കാന്‍ മുകളില്‍ ഇ-മെയില്‍ വിലാസം നല്‍കൂ", + "Expand panel": "പാനല്‍ വലുതാക്കുക", + "On": "ഓണ്‍", + "Filter room names": "റൂം പേരുകള്‍ ഫില്‍ട്ടര്‍ ചെയ്യുക", + "Changelog": "മാറ്റങ്ങളുടെ നാള്‍വഴി", + "Running Matrix services": "മാട്രിക്സ് സര്‍വീസുകള്‍ റണ്‍ ചെയ്യുന്നു", + "Waiting for response from server": "സെര്‍വറില്‍ നിന്നുള്ള പ്രതികരണത്തിന് കാക്കുന്നു", + "Leave": "വിടവാങ്ങുക", + "Failed to send report: ": "റിപ്പോര്‍ട്ട് അയക്കുവാന്‍ സാധിച്ചില്ല : ", + "Unknown device": "അപരിചിത ഡിവൈസ്", + "Advanced notification settings": "അറിയപ്പുകളുടെ സങ്കീര്‍ണമായ സജ്ജീകരണങ്ങള്‍", + "delete the alias.": "ഏലിയാസ് നീക്കം ചെയ്യുക.", + "To return to your account in future you need to set a password": "വീണ്ടും ഈ അക്കൌണ്ട് ഉപയോഗിക്കണമെങ്കില്‍ ഒരു രഹസ്യവാക്ക് സെറ്റ് ചെയ്യുക", + "Forget": "മറക്കുക", + "World readable": "ആർക്കും വായിക്കാവുന്നത്", + "#example": "#ഉദാഹരണം", + "Riot/Web & Desktop chat": "റയട്ട്/വെബ് & ഡെസ്ക്ടോപ്പ് ചാറ്റ്", + "Hide panel": "പാനല്‍ ഒളിപ്പിക്കുക", + "You cannot delete this image. (%(code)s)": "നിങ്ങള്‍ക്ക് ഈ ചിത്രം നീക്കം ചെയ്യാനാകില്ല. (%(code)s)", + "Cancel Sending": "അയയ്ക്കുന്നത് റദ്ദാക്കുക", + "Warning": "മുന്നറിയിപ്പ്", + "This Room": "ഈ മുറി", + "The Home Server may be too old to support third party networks": "തേഡ് പാര്‍ട്ടി നെറ്റ്‍വര്‍ക്കുകളെ പിന്തുണക്കാത്ത വളരെ പഴയ ഹോം സെര്‍വര്‍ ആയേക്കാം", + "Noisy": "ഉച്ചത്തില്‍", + "Room not found": "റൂം കണ്ടെത്താനായില്ല", + "Messages containing my display name": "എന്റെ പേര് അടങ്ങിയിരിക്കുന്ന സന്ദേശങ്ങള്‍ക്ക്", + "Messages in one-to-one chats": "നേര്‍ക്കുനേര്‍ ചാറ്റിലെ സന്ദേശങ്ങള്‍ക്ക്", + "Contributing code to Matrix and Riot": "മാട്രിക്സിലേക്കും റയട്ടിലേക്കും കോഡ് സംഭാവന ചെയ്യാം", + "Unavailable": "ലഭ്യമല്ല", + "Community-run support for Synapse": "സിനാപ്സിനുള്ള കമ്യൂണിറ്റി-നേതൃത്വത്തലുള്ള പിന്തുണ", + "View Decrypted Source": "ഡീക്രിപ്റ്റ് ചെയ്ത സോഴ്സ് കാണുക", + "Failed to update keywords": "കീവേഡുകള്‍ പുതുക്കുവാന്‍ സാധിച്ചില്ല", + "Welcome to Riot.im": "റയട്ടിലേക്ക് സ്വാഗതം", + "Notifications on the following keywords follow rules which can’t be displayed here:": "ഈ പറയുന്ന കീവേർഡുകളെ പറ്റിയുള്ള അറിയിപ്പുകൾ പിൻതുടരുന്ന നിയമങ്ങൾ ഇവിടെ കാണിക്കുവാൻ സാധ്യമല്ല:", + "Please set a password!": "ദയവായി ഒരു രഹസ്യവാക്ക് ക്രമീകരിക്കുക!", + "You have successfully set a password!": "രഹസ്യവാക്ക് സജ്ജീകരിച്ചിരിക്കുന്നു!", + "Chat with Riot Bot": "റയട്ട് ബോട്ടുമായി ചാറ്റ് ചെയ്യുക", + "Support for those using, running and writing other bridges": "മറ്റ് ബ്രിഡ്ജുകള്‍ ഉപയോഗിക്കുന്ന, റണ്‍ ചെയ്യുന്ന, എഴുതുന്നവര്‍ക്കുള്ള പിന്തുണ", + "Admin support for Dendrite": "ഡെന്‍ഡ്രൈറ്റിനുള്ള അഡ്മിന്‍ പിന്തുണ", + "An error occurred whilst saving your email notification preferences.": "ഇ-മെയില്‍ വഴി അറിയിയ്ക്കാനുള്ള നിങ്ങളുടെ സജ്ജീകരണങ്ങള്‍ സൂക്ഷിക്കുന്നതില്‍ ഒരു പ്രശ്നമുണ്ടായി.", + "Source URL": "സോഴ്സ് യു ആര്‍ എല്‍", + "Failed to add tag %(tagName)s to room": "റൂമിന് %(tagName)s എന്ന ടാഗ് ആഡ് ചെയ്യുവാന്‍ സാധിച്ചില്ല", + "Members": "അംഗങ്ങള്‍", + "No update available.": "അപ്ഡേറ്റുകള്‍ ലഭ്യമല്ല.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "മാട്രിക്സിലുള്ളതും പഴയ നെറ്റ്‍വര്‍ക്കുകളിലേക്ക് ( സ്ലാക്ക്, IRC, ഗിറ്റര്‍ മുതലായവ ) ലിങ്ക് ചെയ്തതുമൊക്കെയായ ധാരാളം റൂമുകളുണ്ട്. ഡയറക്റ്ററി പരിശാധിക്കൂ!", + "Resend": "വീണ്ടും അയയ്ക്കുക", + "Files": "ഫയലുകള്‍", + "Collecting app version information": "ആപ്പ് പതിപ്പു വിവരങ്ങള്‍ ശേഖരിക്കുന്നു", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "റൂം ഏലിയാസ് %(alias)s നീക്കം ചെയ്യുകയും %(name)s കള്‍ ഡയറക്ടറിയില്‍ നിന്നും നീക്കം ചെയ്യുകയും ചെയ്യുക ?", + "customServer_text": "മറ്റ് മാട്രിക്സ് സെര്‍വറുകളില്‍ ലോഗിന്‍ ചെയ്യാന്‍ കസ്റ്റം സെര്‍വര്‍ ഓപ്ഷനില്‍ ഹോം സെര്‍വര്‍ യു ആര്‍ എല്‍ വ്യക്തമാക്കുക.
    ഇത് വഴി മറ്റൊരു ഹോം സെര്‍വറില്‍ ഉള്ള മാട്രിക്സ് അക്കൌണ്ട് റയട്ടില്‍ ഉപയോഗിക്കാം.

    അതു പോലെ, നിങ്ങള്‍ക്ക് കസ്റ്റം ഐഡന്റിറ്റി സെര്‍വറും ക്രമീകരിക്കാം. പക്ഷേ അപ്പോള്‍ നിങ്ങള്‍ക്ക് ആരേയും ഇമെയില്‍ വഴി ക്ഷണിക്കാനോ തിരിച്ചോ സാധിക്കില്ല.", + "Co-ordination for Riot/Web translators": "റയട്ട്/വെബ് പരിഭാഷകരുടെ കൂട്ടായ്മ", + "This will allow you to return to your account after signing out, and sign in on other devices.": "സൈന്‍ ഔട്ട് ചെയ്ത ശേഷം വീണ്ടും നിങ്ങളുടെ അക്കൌണ്ടിലേക്ക് മടങ്ങി വരാനും, മറ്റ് ഡിവൈസുകളില്‍ സൈന്‍ ഇന്‍ ചെയ്യാനും ഇത് സഹായിക്കും.", + "Dev chat for the Dendrite dev team": "ഡെന്‍ഡ്രൈറ്റ് ഡെവലപ്പര്‍ ടീമിനുള്ള dev chat", + "Keywords": "കീവേഡുകള്‍", + "Enable notifications for this account": "ഈ അക്കൌണ്ടില്‍ നോട്ടിഫിക്കേഷനുകള്‍ ഇനേബിള്‍ ചെയ്യുക", + "Directory": "ഡയറക്ടറി", + "Failed to get public room list": "പബ്ലിക്ക് റൂം ലിസ്റ്റ് നേടാന്‍ സാധിച്ചില്ല", + "Messages containing keywords": "കീവേഡുകള്‍അടങ്ങിയ സന്ദേശങ്ങള്‍ക്ക്", + "Error saving email notification preferences": "ഇമെയില്‍ നോട്ടിഫിക്കേഷന്‍ സജ്ജീകരണങ്ങള്‍ സൂക്ഷിക്കവേ എറര്‍ നേരിട്ടു", + "Tuesday": "ചൊവ്വ", + "Enter keywords separated by a comma:": "കീവേഡുകളെ കോമ കൊണ്ട് വേര്‍ത്തിരിച്ച് ടൈപ്പ് ചെയ്യുക :", + "I understand the risks and wish to continue": "കുഴപ്പമാകാന്‍ സാധ്യതയുണ്ടെന്നെനിയ്ക്കു് മനസ്സിലായി, എന്നാലും മുന്നോട്ട് പോകുക", + "Remove %(name)s from the directory?": "%(name)s കള്‍ ഡയറക്റ്ററിയില്‍ നിന്നും മാറ്റണോ ?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "റയട്ട് നൂതന ബ്രൌസര്‍ ഫീച്ചറുകള്‍ ഉപയോഗിക്കുന്നു. നിങ്ങളുടെ ബ്രൌസറില്‍ അവയില്‍ പലതും ഇല്ല / പൂര്‍ണ്ണമല്ല .", + "Please install Chrome or Firefox for the best experience.": "ഏറ്റവും മികച്ച ഉപയോഗത്തിനായി ഗൂഗിള്‍ ക്രോംബ്രൌസറോ അല്ലെങ്കില്‍ ഫയര്‍ഫോക്സ് ബ്രൌസറോ ഇന്‍സ്റ്റാള്‍ ചെയ്യൂ.", + "Unnamed room": "പേരില്ലാത്ത റൂം", + "All messages (noisy)": "എല്ലാ സന്ദേശങ്ങളും (ഉച്ചത്തിൽ)", + "Saturday": "ശനി", + "Remember, you can always set an email address in user settings if you change your mind.": "ഓര്‍ക്കുക, വേണ്ട സമയത്ത് യൂസര്‍ സെറ്റിങ്സില്‍ ഒരു ഇമെയില്‍ വിലാസം നല്‍കാം.", + "Direct Chat": "നേരിട്ടുള്ള ചാറ്റ്", + "The server may be unavailable or overloaded": "സെര്‍വര്‍ ലഭ്യമല്ല അല്ലെങ്കില്‍ ഓവര്‍ലോഡഡ് ആണ്", + "Reject": "നിരസിക്കുക", + "Riot is not supported on mobile web. Install the app?": "മൊബൈലില്‍ റയട്ട് വെബ് പിന്തുണ ഇല്ല. ആപ്പ് ഇന്‍സ്റ്റാള്‍ ചെയ്യാം ?", + "Discussion of all things Matrix!": "മാട്രിക്സിനെ കുറിച്ചുള്ള ചര്‍ച്ച!", + "Failed to set Direct Message status of room": "റൂമില്‍ നിന്നും ഡയറക്റ്റ് മെസേജ് സ്റ്റാറ്റസ് സജ്ജീകരിക്കാന്‍ കഴിഞ്ഞില്ല", + "Monday": "തിങ്കള്‍", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "നേരിട്ട പ്രശ്നം മനസ്സിലാക്കാന്‍, ഈ ക്ലയന്റില്‍ നിന്നുള്ള നാള്‍വഴികള്‍ ബഗ് റിപ്പോര്‍ട്ടിനൊപ്പം അയയ്ക്കും. അതിനു പകരം ഈ എഴുത്ത് മാത്രം അയച്ചാല്‍ മതിയെങ്കില്‍ ദയവായി ശരിച്ഛിഹ്നം ഒഴിവാക്കുക:", + "Remove from Directory": "ഡയറക്റ്ററിയില്‍ നിന്നും നീക്കം ചെയ്യുക", + "Enable them now": "ഇപ്പോള്‍ ഇനേബിള്‍ ചെയ്യുക", + "Forward Message": "സന്ദേശം ഫോര്‍വേഡ് ചെയ്യുക", + "Describe your problem here.": "നിങ്ങള്‍ നേരിട്ട പ്രശ്നം ഇവിടെ വിവരിക്കാം.", + "Messages containing my user name": "എന്റെ യൂസര്‍ നെയിം അടങ്ങിയിരിക്കുന്ന സന്ദേശങ്ങള്‍ക്ക്", + "Collecting logs": "നാള്‍വഴി ശേഖരിക്കുന്നു", + "more": "കൂടുതല്‍", + "Bug report sent": "ബഗ് റിപ്പോർട്ട് അയയ്ക്കുക", + "(HTTP status %(httpStatus)s)": "(HTTP സ്റ്റാറ്റസ് %(httpStatus)s)", + "All Rooms": "എല്ലാ മുറികളും കാണുക", + "Wednesday": "ബുധന്‍", + "You cannot delete this message. (%(code)s)": "നിങ്ങള്‍ക്ക് ഈ സന്ദേശം നീക്കം ചെയ്യാനാകില്ല. (%(code)s)", + "Quote": "ഉദ്ധരിക്കുക", + "Send": "അയയ്ക്കുക", + "Send logs": "നാള്‍വഴി അയയ്ക്കുക", + "All messages": "എല്ലാ സന്ദേശങ്ങളും", + "Implementing VoIP services with Matrix": "മേട്രിക്സിന്മേൽ VoIP സർവീസുകൾ നടപ്പിലാക്കുന്നു", + "Dev chat for the Riot/Web dev team": "റയട്ട്/വെബ് ഡെവലപ്പര്‍ ടീമിനുള്ള dev chat", + "Call invitation": "വിളിയ്ക്കുന്നു", + "Riot Desktop on %(platformName)s": "%(platformName)s ലെ റയട്ട് ഡെസ്ക്ടോപ്പ്", + "Downloading update...": "അപ്ഡേറ്റ് ഡൌണ്‍ലോഡ് ചെയ്യുന്നു...", + "You have successfully set a password and an email address!": "ഇമെയില്‍ വിലാസവും രഹസ്യവാക്കും വിജയകരമായി ക്രമീകരിച്ചിരിക്കുന്നു!", + "What's new?": "എന്തൊക്കെ പുതിയ വിശേഷങ്ങള്‍ ?", + "Discussion of the Identity Service API": "ഐഡൻടിറ്റി സർവീസ് എപിഐ യെ പറ്റിയുള്ള ചർച്ച", + "Support for those using and running matrix-appservice-irc": "matrix-appservice-irc ഉപയോഗിക്കുന്നവര്‍ക്കും റണ്‍ ചെയ്യുന്നവര്‍ക്കുമുള്ള സപ്പോര്‍ട്ട്", + "Riot/iOS & matrix-ios-sdk chat": "റയട്ട്/iOS& matrix-ios-sdk ചാറ്റ്", + "Notify me for anything else": "ബാക്കി ഏതിനും എനിക്ക് അറിയിപ്പു നൽകുക", + "When I'm invited to a room": "ഞാന്‍ ഒരു റൂമിലേക്ക് ക്ഷണിക്കപ്പെടുമ്പോള്‍", + "Design and implementation of E2E in Matrix": "മാട്രിക്സിലെ e2eയുടെ ഡിസൈനും ഇമ്പ്ലിമെന്റേഷനും", + "Can't update user notification settings": "ഉപയോക്താവിനെ അറിയിയ്ക്കാനുള്ള സജ്ജീകരണം പുതുക്കാനായില്ല", + "Notify for all other messages/rooms": "ബാക്കി എല്ലാ സന്ദേശങ്ങൾക്കും/റൂമുകൾക്കും അറിയിപ്പു നൽകുക", + "Unable to look up room ID from server": "സെര്‍വറില്‍ നിന്നും റൂം ഐഡി കണ്ടെത്താനായില്ല", + "Couldn't find a matching Matrix room": "ആവശ്യപ്പെട്ട മാട്രിക്സ് റൂം കണ്ടെത്താനായില്ല", + "Support for those using the Matrix spec": "Matrix spec ഉപയോഗിക്കുന്നവര്‍ക്കുള്ള പിന്തുണ", + "Safari and Opera work too.": "സഫാരിയിലുംപിന്നെ ഓപ്പേറയിലുംപ്രവര്‍ത്തിക്കുന്നു.", + "Loading bug report module": "പിഴവുകള്‍ അറിയിയ്ക്കാനുള്ള ഘടകം ചേര്‍ക്കുന്നു", + "Invite to this room": "ഈ റൂമിലേക്ക് ക്ഷണിക്കുക", + "Search for a room": "ഒരു റൂം തിരയുക", + "Thursday": "വ്യാഴം", + "Search…": "തിരയുക…", + "%(appName)s via %(browserName)s on %(osName)s": "%(osName)sല്‍ %(browserName)s വഴി %(appName)s", + "Back": "തിരികെ", + "Unhide Preview": "പ്രിവ്യു കാണിക്കുക", + "Announcements about Synapse releases": "സിനാപ്സ് റിലീസുകളെ കുറിച്ചുള്ള അറിയിപ്പുകള്‍", + "Search the room directory": "റൂം ഡയറക്റ്ററിയില്‍ പരതുക", + "Please describe the bug and/or send logs.": "ബഗ് വിശദീകരിക്കുക , കൂടെ / അല്ലെങ്കില്‍ നാള്‍വഴികളും അയക്കുക.", + "Unable to join network": "നെറ്റ്‍വര്‍ക്കില്‍ ജോയിന്‍ ചെയ്യാന്‍ കഴിയില്ല", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "ഇവ റയട്ടല്ലാതെ മറ്റൊരു ക്ലയന്റില്‍ വച്ച് കോണ്‍ഫിഗര്‍ ചെയ്തതാകാം. റയട്ടില്‍ അവ ലഭിക്കില്ല, എങ്കിലും അവ നിലവിലുണ്ട്", + "Sorry, your browser is not able to run Riot.": "ക്ഷമിക്കണം, നിങ്ങളുടെ ബ്രൌസര്‍ റയട്ട് പ്രവര്‍ത്തിപ്പിക്കാന്‍ പര്യാപ്തമല്ല.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "വികേന്ദ്രീകൃത , എന്‍ക്രിപ്റ്റഡ് ചാറ്റ് & മാട്രിക്സ് നല്‍കുന്ന കൊളാബൊറേഷന്‍", + "Uploaded on %(date)s by %(user)s": "%(date)s ല്‍ %(user)s അപ്ലോഡ് ചെയ്തത്", + "Messages in group chats": "ഗ്രൂപ്പ് ചാറ്റുകളിലെ സന്ദേശങ്ങള്‍ക്ക്", + "Yesterday": "ഇന്നലെ", + "Error encountered (%(errorDetail)s).": "എറര്‍ നേരിട്ടു (%(errorDetail)s).", + "Low Priority": "താഴ്ന്ന പരിഗണന", + "Unable to fetch notification target list": "നോട്ടിഫിക്കേഷന്‍ ടാര്‍ഗെറ്റ് ലിസ്റ്റ് നേടാനായില്ല", + "Get started with some tips from Riot Bot!": "റയട്ട് ബോട്ടില്‍ നിന്നുള്ള നിര്‍ദേശങ്ങള്‍ സ്വീകരിച്ച് കൊണ്ട് തുടങ്ങൂ!", + "Set Password": "രഹസ്യവാക്ക് സജ്ജീകരിക്കുക", + "Enable audible notifications in web client": "വെബ് പതിപ്പിലെ അറിയിപ്പുകള്‍ കേള്‍ക്കാവുന്നതാക്കുക", + "Permalink": "പെര്‍മാലിങ്ക്", + "remove %(name)s from the directory.": "%(name)s ഡയറക്റ്ററിയില്‍ നിന്ന് നീക്കം ചെയ്യുക.", + "Off": "ഓഫ്", + "Riot does not know how to join a room on this network": "ഈ നെറ്റ്‍വര്‍ക്കിലെ ഒരു റൂമില്‍ എങ്ങനെ അംഗമാകാമെന്ന് റയട്ടിന് അറിയില്ല", + "Mentions only": "മെന്‍ഷനുകള്‍ മാത്രം", + "Failed to remove tag %(tagName)s from room": "റൂമില്‍ നിന്നും %(tagName)s ടാഗ് നീക്കം ചെയ്യുവാന്‍ സാധിച്ചില്ല", + "You can now return to your account after signing out, and sign in on other devices.": "നിങ്ങള്‍ക്ക് ഇപ്പോള്‍ സൈന്‍ ഔട്ട് ചെയ്ത ശേഷവും നിങ്ങളുടെ അക്കൌണ്ടിലേക്ക് തിരികെ വരാം, അതു പോലെ മറ്റ് ഡിവൈസുകളില്‍ സൈന്‍ ഇന്‍ ചെയ്യുകയുമാവാം.", + "Enable desktop notifications": "ഡെസ്ക്ടോപ്പ് നോട്ടിഫിക്കേഷനുകള്‍ ഇനേബിള്‍ ചെയ്യുക", + "Enable email notifications": "ഇമെയില്‍ നോട്ടിഫിക്കേഷനുകള്‍ ഇനേബിള്‍ ചെയ്യുക", + "Login": "ലോഗിന്‍", + "No rooms to show": "കാണിക്കാന്‍ റൂമുകളില്ല", + "Download this file": "ഈ ഫയല്‍ ഡൌണ്‍ലോഡ് ചെയ്യുക", + "Failed to change settings": "സജ്ജീകരണങ്ങള്‍ മാറ്റുന്നവാന്‍ സാധിച്ചില്ല", + "View Source": "സോഴ്സ് കാണുക", + "Matrix technical discussions": "മാട്രിക്സ് സാങ്കേതിക ചര്‍ച്ച", + "Building services on Matrix": "മട്രിക്സിന്മേൽ സർവീസുകൾ പണിയുന്നു", + "Collapse panel": "പാനല്‍ കൊളാപ്സ് ചെയ്യുക", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "നിങ്ങളുടെ ഇപ്പോളത്തെ ബ്രൌസര്‍ റയട്ട് പ്രവര്‍ത്തിപ്പിക്കാന്‍ പൂര്‍ണമായും പര്യാപത്മല്ല. പല ഫീച്ചറുകളും പ്രവര്‍ത്തിക്കാതെയിരിക്കാം. ഈ ബ്രൌസര്‍ തന്നെ ഉപയോഗിക്കണമെങ്കില്‍ മുന്നോട്ട് പോകാം. പക്ഷേ നിങ്ങള്‍ നേരിടുന്ന പ്രശ്നങ്ങള്‍ നിങ്ങളുടെ ഉത്തരവാദിത്തത്തില്‍ ആയിരിക്കും!", + "Checking for an update...": "അപ്ഡേറ്റ് ഉണ്ടോ എന്ന് തിരയുന്നു...", + "General discussion about Matrix and Riot": "മാട്രിക്സിനേയും റയട്ടിനേയും കുറിച്ചുള്ള പൊതു ചര്‍ച്ച", + "There are advanced notifications which are not shown here": "ഇവിടെ കാണിക്കാത്ത നൂതന നോട്ടിഫിക്കേഷനുകള്‍ ഉണ്ട്" } diff --git a/src/i18n/strings/nb_NO.json b/src/i18n/strings/nb_NO.json index 3919993663..dbeb2b9cd0 100644 --- a/src/i18n/strings/nb_NO.json +++ b/src/i18n/strings/nb_NO.json @@ -7,5 +7,114 @@ "The version of Riot.im": "Versjonen av Riot.im", "Whether or not you're logged in (we don't record your user name)": "Om du er logget inn eller ei (vi loggfører ikke brukernavnet ditt)", "Your language of choice": "Ditt valgte språk", - "Your homeserver's URL": "Din hjemservers URL" + "Your homeserver's URL": "Din hjemservers URL", + "Fetching third party location failed": "Kunne ikke hente tredjeparts lokalisering", + "Advanced notification settings": "Avanserte varslingsinnstillinger", + "Sunday": "Søndag", + "Guests can join": "Gjester kan bli med", + "Messages sent by bot": "Meldinger sendt av bot", + "Notification targets": "Mål for varsel", + "Failed to set direct chat tag": "Kunne ikke angi direkte chat-tagg", + "Today": "I dag", + "Files": "Filer", + "You are not receiving desktop notifications": "Du mottar ikke skrivebords varsler", + "Friday": "Fredag", + "Notifications": "Varsler", + "Unable to fetch notification target list": "Kunne ikke hente varsel-mål liste", + "Add an email address above to configure email notifications": "Legg til en epost adresse for å sette opp epost varsling", + "Expand panel": "Utvid panel", + "On": "På", + "Filter room names": "Filtrer romnavn", + "Leave": "Forlat", + "All notifications are currently disabled for all targets.": "Alle varsler er deaktivert for alle mottakere.", + "delete the alias.": "Slett aliaset.", + "Forget": "Glem", + "World readable": "Lesbar for alle", + "You cannot delete this image. (%(code)s)": "Du kan ikke slette dette bildet. (%(code)s)", + "Source URL": "Kilde URL", + "The Home Server may be too old to support third party networks": "Hjemme-serveren kan være for gammel til å støtte tredjeparts-nettverk", + "Resend": "Send på nytt", + "Error saving email notification preferences": "Feil ved lagring av e-postvarselinnstillinger", + "Messages in one-to-one chats": "Meldinger i en-til-en samtaler", + "View Decrypted Source": "Vis dekryptert kilde", + "Failed to update keywords": "Kunne ikke oppdatere nøkkelord", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Varsler på de følgende nøkkelordene følger regler som ikke kan vises her:", + "Room not found": "Rommet ble ikke funnet", + "Favourite": "Favoritt", + "Cancel Sending": "Avbryt sending", + "Failed to add tag %(tagName)s to room": "Kunne ikke legge til tagg %(tagName)s til rom", + "Members": "Medlemmer", + "Noisy": "Bråkete", + "Failed to get protocol list from Home Server": "Kunne ikke hente protokolliste fra Hjemme-Server", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Slett rom alias %(alias)s og fjern %(name)s fra katalogen?", + "customServer_text": "Du kan benytte de egendefinerte serveralternativene til å logge deg på andre Matrix-servere ved å spesifisere en annen Hjemmeserver-URL.
    Dette lar deg benytte Riot med en eksisterende Matrix konto på en annen hjemmeserver.

    Du kan også angi en egendefinert identitetsserver, men du vil ikke kunne invitere brukere via e-post, eller bli invitert via e-post selv.", + "Enable notifications for this account": "Aktiver varsler for denne konto", + "Directory": "Katalog", + "Failed to get public room list": "Kunne ikke hente offentlig romliste", + "Messages containing keywords": "Meldinger som inneholder nøkkelord", + "When I'm invited to a room": "Når jeg blir invitert til et rom", + "Tuesday": "Tirsdag", + "Enter keywords separated by a comma:": "Angi nøkkelord adskilt med komma:", + "I understand the risks and wish to continue": "Jeg forstår risikoen og ønsker å fortsette", + "Remove %(name)s from the directory?": "Fjern %(name)s fra katalogen?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot benytter mange avanserte nettleserfunksjoner, og noen av disse er ikke tilgjengelige eller er eksperimentelle på din nåværende nettleser.", + "Enable desktop notifications": "Aktiver skrivebordsvarsler", + "Unnamed room": "Rom uten navn", + "All messages (noisy)": "Alle meldinger (høy)", + "Direct Chat": "Direkte Chat", + "The server may be unavailable or overloaded": "Serveren kan være utilgjengelig eller overbelastet", + "Reject": "Avvis", + "Failed to set Direct Message status of room": "Kunne ikke angi status for direkte melding i rommet", + "Monday": "Mandag", + "Remove from Directory": "Fjern fra katalogen", + "Enable them now": "Aktiver dem nå", + "Messages containing my user name": "Meldinger som inneholder mitt brukernavn", + "more": "mer", + "Search for a room": "Søk etter et rom", + "Failed to forget room %(errCode)s": "Kunne ikke glemme rommet %(errCode)s", + "Wednesday": "Onsdag", + "Error": "Feil", + "unknown error code": "ukjent feilkode", + "Call invitation": "Anropsinvitasjon", + "Messages containing my display name": "Meldinger som inneholder mitt visningsnavn", + "powered by Matrix": "benytter seg av Matrix", + "Notify me for anything else": "Varsle meg om alt annet", + "View Source": "Vis kilde", + "Keywords": "Nøkkelord", + "Close": "Lukk", + "Can't update user notification settings": "Kan ikke oppdatere brukervarsel innstillinger", + "Notify for all other messages/rooms": "Varsler om alle andre meldinger/rom", + "Unable to look up room ID from server": "Kunne ikke slå opp rom-ID fra serveren", + "Couldn't find a matching Matrix room": "Kunne ikke finne et samsvarende Matrix rom", + "Safari and Opera work too.": "Safari og Opera fungerer også.", + "Invite to this room": "Inviter til dette rommet", + "You cannot delete this message. (%(code)s)": "Du kan ikke slette denne meldingen. (%(code)s)", + "Thursday": "Torsdag", + "All messages": "Alle meldinger", + "Unable to join network": "Kunne ikke bli med i nettverket", + "Sorry, your browser is not able to run Riot.": "Beklager, din nettleser er ikke i stand til å kjøre Riot.", + "Uploaded on %(date)s by %(user)s": "Lastet opp den %(date)s av %(user)s", + "Messages in group chats": "Meldinger i gruppesamtaler", + "Yesterday": "I går", + "Low Priority": "Lav Prioritet", + "Riot does not know how to join a room on this network": "Riot vet ikke hvordan man kan komme inn på et rom på dette nettverket", + "An error occurred whilst saving your email notification preferences.": "En feil oppsto i forbindelse med lagring av epost varsel innstillinger.", + "Enable audible notifications in web client": "Aktiver lyd-varsel i webklient", + "Permalink": "Permanent lenke", + "remove %(name)s from the directory.": "fjern %(name)s fra katalogen.", + "Off": "Av", + "#example": "#eksempel", + "Failed to remove tag %(tagName)s from room": "Kunne ikke fjerne tagg %(tagName)s fra rommet", + "Remove": "Fjern", + "Please install Chrome or Firefox for the best experience.": "Vennligst installer Chrome eller Firefox for den beste opplevelsen.", + "Enable email notifications": "Aktiver e-postvarsler", + "No rooms to show": "Ingen rom å vise", + "Download this file": "Last ned filen", + "Failed to change settings": "Kunne ikke endre innstillingene", + "Unhide Preview": "Vis forhåndsvisning", + "Custom Server Options": "Tilpassede serveralternativer", + "Quote": "Sitat", + "Collapse panel": "Skjul panel", + "Saturday": "Lørdag", + "There are advanced notifications which are not shown here": "Det er avanserte varsler som ikke vises her" } diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index d4bda9c6da..30cfdeb63f 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -994,5 +994,199 @@ "Clear filter": "Filter vrijmaken", "Failed to set direct chat tag": "Het is niet gelukt om de 'privégesprek' label in te stellen", "Failed to remove tag %(tagName)s from room": "Het is niet gelukt om de label %(tagName)s van de ruimte te verwijderen", - "Failed to add tag %(tagName)s to room": "Het is niet gelukt om de label %(tagName)s aan deze ruimte toe te voegen" + "Failed to add tag %(tagName)s to room": "Het is niet gelukt om de label %(tagName)s aan deze ruimte toe te voegen", + "Fetching third party location failed": "Het ophalen van de locatie van de derde partij is mislukt", + "A new version of Riot is available.": "Er is een nieuwe versie van Riot beschikbaar.", + "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk-chat", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Beschrijf de bug. Wat deed u? Wat verwachtte u? Wat gebeurde er daadwerkelijk?", + "I understand the risks and wish to continue": "Ik begrijp de risico's en wil graag verder gaan", + "Couldn't load home page": "Kon de home pagina niet laden", + "Send Account Data": "Stuur account informatie", + "All notifications are currently disabled for all targets.": "Alle meldingen zijn momenteel uitgeschakeld voor alle doelen.", + "Uploading report": "Rapport uploaden", + "Sunday": "Zondag", + "Notification targets": "Meldingsdoelen", + "Today": "Vandaag", + "Files": "Bestanden", + "Report a bug": "Een bug rapporteren", + "Implementing VR services with Matrix": "Implementatie van VR-diensten met Matrix", + "You are not receiving desktop notifications": "Je ontvangt momenteel geen desktopmeldingen", + "Friday": "Vrijdag", + "Update": "Bijwerken", + "You need to be using HTTPS to place a screen-sharing call.": "U moet HTTPS gebruiken om een oproep met schermdelen te kunnen starten.", + "What's New": "Wat is er nieuw", + "Add an email address above to configure email notifications": "Voeg een e-mailadres toe om e-mailmeldingen te ontvangen", + "Expand panel": "Paneel uitklappen", + "On": "Aan", + "%(count)s Members|other": "%(count)s Deelnemers", + "Filter room names": "Filter kamernamen", + "Changelog": "Logboek van wijzigingen", + "Running Matrix services": "Matrixdiensten beheren", + "Waiting for response from server": "Wachten op antwoord van de server", + "Send Custom Event": "Verzend aangepast evenement", + "Failed to send report: ": "Rapport verzenden mislukt: ", + "Unknown device": "Onbekend apparaat", + "Advanced notification settings": "Geavanceerde meldingsinstellingen", + "delete the alias.": "verwijder de alias.", + "To return to your account in future you need to set a password": "Om in de toekomst naar je account terug te gaan moet je een wachtwoord instellen", + "Forget": "Vergeten", + "#example": "#voorbeeld", + "Riot/Web & Desktop chat": "Riot/Web & Desktop-chat", + "Hide panel": "Paneel verbergen", + "You cannot delete this image. (%(code)s)": "Je kunt deze afbeelding niet verwijderen. (%(code)s)", + "Cancel Sending": "Versturen annuleren", + "This Room": "Deze kamer", + "The Home Server may be too old to support third party networks": "De thuisserver is misschien te oud om netwerken van derde partijen te ondersteunen", + "Resend": "Opnieuw verzenden", + "Error saving email notification preferences": "Fout bij het opslaan van de meldingsvoorkeuren voor e-mail", + "Messages containing my display name": "Berichten die mijn weergavenaam bevatten", + "Messages in one-to-one chats": "Berichten in één-op-één-gesprekken", + "Contributing code to Matrix and Riot": "Code bijdragen aan Matrix en Riot", + "Unavailable": "Niet beschikbaar", + "Community-run support for Synapse": "Synapse-ondersteuning vanuit de gemeenschap", + "View Decrypted Source": "Bekijk ontsleutelde bron", + "Failed to update keywords": "Trefwoorden bijwerken mislukt", + "remove %(name)s from the directory.": "verwijder %(name)s uit de kamerlijst.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Meldingen op de volgende trefwoorden volgen regels die hier niet kunnen worden getoond:", + "Safari and Opera work too.": "Safari en Opera werken ook.", + "Please set a password!": "Stel een wachtwoord in!", + "You have successfully set a password!": "U heeft met succes een wachtwoord ingesteld!", + "Chat with Riot Bot": "Met Riot Bot chatten", + "Support for those using, running and writing other bridges": "Ondersteuning voor het gebruiken, draaien en ontwikkelen aan andere bruggen", + "Admin support for Dendrite": "Beheerondersteuning voor Dendrite", + "An error occurred whilst saving your email notification preferences.": "Er is een fout opgetreden tijdens het opslaan van uw e-mailmeldingsvoorkeuren.", + "Explore Room State": "Verken Ruimtetoestand", + "Source URL": "Bron-URL", + "Messages sent by bot": "Berichten verzonden door een bot", + "Filter results": "Resultaten filteren", + "Members": "Leden", + "No update available.": "Geen update beschikbaar.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Veel kamers bestaan al in Matrix, gelinkt aan bestaande netwerken (Slack, IRC, Gitter, enz.) of onafhankelijk. Bekijk de kamerlijst!", + "Noisy": "Luidruchtig", + "Failed to get protocol list from Home Server": "Protocollijst ophalen van de homeserver mislukt", + "Collecting app version information": "App-versieinformatie verzamelen", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "De alias %(alias)s verwijderen en %(name)s uit de kamerlijst verwijderen?", + "customServer_text": "U kunt de aangepaste serverinstellingen gebruiken om in te loggen bij andere Matrix-servers door een andere homeserver-URL in te voeren.
    Dit maakt het mogelijk om Riot te gebruiken met een bestaand Matrix-account op een andere homeserver.

    U kunt ook een aangepaste identiteitsserver instellen, maar het is dan niet mogelijk om gebruikers uit te nodigen met behulp van een e-mailadres of zelf uitgenodigd te worden met een e-mailadres.", + "Co-ordination for Riot/Web translators": "Coördinatie voor Riot/Web-vertalers", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Hiermee kunt u naar uw account terugkeren nadat u zich heeft afgemeld, en u aanmelden op andere apparaten.", + "Dev chat for the Dendrite dev team": "Dev-chat voor het Dendrite-ontwikkelteam", + "Keywords": "Trefwoorden", + "Enable notifications for this account": "Meldingen voor dit account aanzetten", + "Directory": "Kamerlijst", + "Invite to this community": "Nodig uit in deze community", + "Search for a room": "Een kamer opzoeken", + "Messages containing keywords": "Berichten die trefwoorden bevatten", + "Room not found": "De kamer is niet gevonden", + "Tuesday": "Dinsdag", + "Enter keywords separated by a comma:": "Voeg trefwoorden toe, gescheiden door een komma:", + "Search…": "Zoeken…", + "You have successfully set a password and an email address!": "Het instellen van een wachtwoord en e-mailadres is geslaagd!", + "Remove %(name)s from the directory?": "%(name)s uit de kamerlijst verwijderen?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot gebrukt veel geavanceerde browserfuncties, waarvan enkele niet (of experimenteel) in uw webbrowser beschikbaar zijn.", + "Developer Tools": "Ontwikkelaarsgereedschap", + "Enable desktop notifications": "Desktopmeldingen aanzetten", + "Explore Account Data": "Bekijk account informatie", + "Remove from Directory": "Uit de kamerlijst verwijderen", + "Away": "Afwezig", + "Saturday": "Zaterdag", + "Remember, you can always set an email address in user settings if you change your mind.": "Onthoud dat u altijd een e-mailadres in kan stellen in de gebruikersinstellingen als u zich bedenkt.", + "Direct Chat": "Privégesprek", + "The server may be unavailable or overloaded": "De server is misschien niet beschikbaar of overbelast", + "Reject": "Afwijzen", + "Riot is not supported on mobile web. Install the app?": "Riot wordt niet ondersteund op het mobiele web. Wil je de app installeren?", + "Discussion of all things Matrix!": "Discussie over alles wat met Matrix te maken heeft!", + "Failed to set Direct Message status of room": "Het is mislukt om de directe-berichtenstatus van de kamer in te stellen", + "Monday": "Maandag", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Om diagnose van het probleem mogelijk te maken worden logboeken van deze client met het bugrapport meegestuurd. Schakel dit vinkje uit als u slechts de bovenstaande tekst mee wil sturen:", + "Send Custom State Event": "Verzend aangepast State Event", + "All messages (noisy)": "Alle berichten (luid)", + "Enable them now": "Deze nu aanzetten", + "Messages containing my user name": "Berichten die mijn gebruikersnaam bevatten", + "Describe your problem here.": "Beschrijf uw probleem hier.", + "Toolbox": "Eigenschappen", + "Collecting logs": "Logboeken verzamelen", + "more": "meer", + "Bug report sent": "Bug report verzonden", + "You must specify an event type!": "Je moet een event-type specificeren!", + "(HTTP status %(httpStatus)s)": "(HTTP-status %(httpStatus)s)", + "Invite to this room": "Uitnodigen voor deze kamer", + "Please install Chrome or Firefox for the best experience.": "Installeer alstublieft Chrome of Firefox voor de beste gebruikerservaring.", + "Failed to get public room list": "Lijst met publieke kamers ophalen mislukt", + "Send logs": "Logboeken versturen", + "All messages": "Alle berichten", + "Implementing VoIP services with Matrix": "Implementatie van VoIP-diensten met Matrix", + "Dev chat for the Riot/Web dev team": "Dev-chat voor het Riot/Web ontwikkelteam", + "Call invitation": "Oproep-uitnodiging", + "Riot Desktop on %(platformName)s": "Riot Desktop op %(platformName)s", + "Downloading update...": "Update aan het downloaden...", + "State Key": "Toestandssleutel", + "Failed to send custom event.": "Aangepast Event verzenden mislukt.", + "What's new?": "Wat is er nieuw?", + "Discussion of the Identity Service API": "Discussie over de Identity Service API", + "Support for those using and running matrix-appservice-irc": "Ondersteuning voor gebruikers en beheerders van matrix-appservice-irc", + "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk-chat", + "Notify me for anything else": "Stuur een melding voor al het andere", + "When I'm invited to a room": "Wanneer ik uitgenodigd word voor een kamer", + "Design and implementation of E2E in Matrix": "Ontwerp en implementatie van E2E in Matrix", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Je kan de custom server opties gebruiken om op andere Matrix server in te loggen door een andere Home server URL op te geven.
    Dit laat je toe om Riot te gebruiken met een bestaande Matrix account op een andere home server.

    Je kan ook een custom identiteits-server opzetten maar dan kan je geen gebruikers uitnodigen via hun email adres, of zelf uitgenodigd worden via je email adres.", + "Can't update user notification settings": "Het is niet gelukt om de meldingsinstellingen van de gebruiker bij te werken", + "Notify for all other messages/rooms": "Stuur een melding voor alle andere berichten/kamers", + "Unable to look up room ID from server": "Het is mislukt om de kamer-ID op te halen van de server", + "Couldn't find a matching Matrix room": "Het is niet gelukt om een bijbehorende Matrix-kamer te vinden", + "Support for those using the Matrix spec": "Ondersteuning voor gebruikers van Matrix-specificatie", + "Safari and Opera work too.": "Safari en Opera werken ook.", + "Loading bug report module": "Bugrapporteermodule laden", + "All Rooms": "Alle kamers", + "You cannot delete this message. (%(code)s)": "Je kunt dit bericht niet verwijderen. (%(code)s)", + "Thursday": "Donderdag", + "Forward Message": "Bericht doorsturen", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s via %(browserName)s op %(osName)s", + "Back": "Terug", + "Reply": "Beantwoord", + "Show message in desktop notification": "Toon boodschap in bureaublad popup", + "Unhide Preview": "Zichtbaar maken preview", + "Announcements about Synapse releases": "Aankondigingen over Synapse-uitgaven", + "Search the room directory": "De kamerlijst doorzoeken", + "Please describe the bug and/or send logs.": "Beschrijf de bug en/of verstuur logboeken.", + "Unable to join network": "Het is mislukt om toe te treden tot dit netwerk", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Je hebt ze mogelijk ingesteld in een andere client dan Riot. Je kunt ze niet aanpassen in Riot maar ze zijn wel actief", + "Sorry, your browser is not able to run Riot.": "Sorry, uw browser werkt niet met Riot.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Gedecentaliseerd en versleuteld chatten & samenwerken mogelijk gemaakt door [matrix]", + "Uploaded on %(date)s by %(user)s": "Geüpload op %(date)s door %(user)s", + "Messages in group chats": "Berichten in groepsgesprekken", + "Yesterday": "Gisteren", + "Error encountered (%(errorDetail)s).": "Fout ondervonden (%(errorDetail)s).", + "Login": "Aanmelden", + "Low Priority": "Lage prioriteit", + "Unable to fetch notification target list": "Het is mislukt om de lijst van notificatiedoelen op te halen", + "Appear Offline": "Lijk offline", + "Get started with some tips from Riot Bot!": "Begin met enkele tips van Riot Bot!", + "Set Password": "Wachtwoord instellen", + "Enable audible notifications in web client": "Geluidsmeldingen in de webclient aanzetten", + "Permalink": "Permanente link", + "Welcome to Riot.im": "Welkom bij Riot.im", + "Off": "Uit", + "Riot does not know how to join a room on this network": "Riot weet niet hoe het moet deelnemen in een kamer op dit netwerk", + "Mentions only": "Alleen vermeldingen", + "Wednesday": "Woensdag", + "You can now return to your account after signing out, and sign in on other devices.": "U kunt nu terugkeren naar uw account nadat u bent afgemeld, en u aanmelden op andere apparaten.", + "Please install Chrome or Firefox for the best experience.": "Installeer Chrome of Firefox voor de beste ervaring.", + "Enable email notifications": "E-mailmeldingen aanzetten", + "Event Type": "Event-type", + "Download this file": "Download dit bestand", + "Pin Message": "Bericht vastpinnen", + "Failed to change settings": "Instellingen wijzigen mislukt", + "View Community": "Gemeenschap Weergeven", + "%(count)s Members|one": "%(count)s Deelnemer", + "Event sent!": "Event verstuurd!", + "View Source": "Bekijk bron", + "Matrix technical discussions": "Technische discussies over Matrix", + "Event Content": "Event-inhoud", + "Thank you!": "Bedankt!", + "Building services on Matrix": "Diensten op Matrix bouwen", + "Collapse panel": "Paneel inklappen", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Met uw huidige browser kan de applicatie er volledig incorrect uitzien. Tevens is het mogelijk dat niet alle functies naar behoren werken. U kunt doorgaan als u het toch wil proberen, maar bij problemen bent u volledig op uzelf aangewezen!", + "Checking for an update...": "Aan het kijken voor een update...", + "General discussion about Matrix and Riot": "Algemene discussie over Matrix en Riot", + "There are advanced notifications which are not shown here": "Er zijn geavanceerde notificaties die hier niet getoond worden" } diff --git a/src/i18n/strings/pl.json b/src/i18n/strings/pl.json index 9f672277f6..052fa53907 100644 --- a/src/i18n/strings/pl.json +++ b/src/i18n/strings/pl.json @@ -698,5 +698,217 @@ "Your homeserver's URL": "Adres URL twojego serwera domowego", "Your identity server's URL": "Adres URL twojego serwera tożsamości", "The information being sent to us to help make Riot.im better includes:": "Oto informacje przesyłane do nas, służące do poprawy Riot.im:", - "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "Zapisujemy również każdą stronę, z której korzystasz w aplikacji (obecnie ), twój User Agent () oraz rozdzielczość ekranu twojego urządzenia ()." + "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "Zapisujemy również każdą stronę, z której korzystasz w aplikacji (obecnie ), twój User Agent () oraz rozdzielczość ekranu twojego urządzenia ().", + "Fetching third party location failed": "Pobranie lokalizacji zewnętrznej nie powiodło się", + "A new version of Riot is available.": "Dostępna jest nowa wersja Riot.", + "Riot/Android & matrix-android-sdk chat": "Czat o Riot/Android i matrix-android-sdk", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Proszę opisz problem (w miarę możliwości po angielsku). Co doprowadziło do błędu? Jakie było Twoje oczekiwanie, a co stało się zamiast tego?", + "Couldn't load home page": "Nie można załadować strony startowej", + "Send Account Data": "Wyślij dane konta", + "All notifications are currently disabled for all targets.": "Wszystkie powiadomienia są obecnie wyłączone dla wszystkich celów.", + "Uploading report": "Raport wysyłania", + "Sunday": "Niedziela", + "Guests can join": "Goście mogą dołączyć", + "Failed to add tag %(tagName)s to room": "Nie można dodać tagu %(tagName)s do pokoju", + "Notification targets": "Cele powiadomień", + "Failed to set direct chat tag": "Nie udało się ustawić znacznika rozmów bezpośrednich", + "Today": "Dzisiaj", + "Failed to get protocol list from Home Server": "Nie można pobrać listy protokołów z serwera domowego", + "Report a bug": "Zgłoś błąd", + "Implementing VR services with Matrix": "Implementowanie usług wirtualnej rzeczywistości w oparciu o Matrix", + "You are not receiving desktop notifications": "Nie otrzymujesz powiadomień na pulpit", + "Friday": "Piątek", + "Update": "Uaktualnienie", + "You need to be using HTTPS to place a screen-sharing call.": "Musisz używać bezpiecznego protokołu HTTPS aby użyć połączenia współdzielenia ekranu.", + "What's New": "Co nowego", + "Add an email address above to configure email notifications": "Dodaj adres e-mail powyżej, aby skonfigurować powiadomienia e-mailowe", + "Expand panel": "Rozwiń panel", + "On": "Włącz", + "%(count)s Members|other": "%(count)s Członków", + "Filter room names": "Filtruj nazwy pokojów", + "Changelog": "Dziennik zmian", + "Running Matrix services": "Utrzymywanie usług Matrix", + "Waiting for response from server": "Czekam na odpowiedź serwera", + "Leave": "Opuść", + "Send Custom Event": "Wyślij niestandardowe wydarzenie", + "Failed to send report: ": "Nie udało się wysłać raportu: ", + "Unknown device": "Nieznane urządzenie", + "Advanced notification settings": "Zaawansowane ustawienia powiadomień", + "Failed to send logs: ": "Niepowodzenie wysyłki zapisu rozmów ", + "delete the alias.": "usunąć alias.", + "To return to your account in future you need to set a password": "Aby wrócić do swojego konta w przyszłości musisz ustawić hasło ", + "Forget": "Zapomnij", + "World readable": "Całkowicie publiczne", + "#example": "#przykład", + "Riot/Web & Desktop chat": "Czat o Riot/Web i Desktop", + "Hide panel": "Ukryj panel", + "You cannot delete this image. (%(code)s)": "Nie możesz usunąć tego obrazka. (%(code)s)", + "Cancel Sending": "Anuluj wysyłanie", + "Warning": "Ostrzeżenie", + "This Room": "Ten pokój", + "The Home Server may be too old to support third party networks": "Serwer domowy może być za stary dla innych sieci", + "Resend": "Wyślij jeszcze raz", + "Error saving email notification preferences": "Wystąpił błąd podczas zapisywania ustawień powiadomień e-mailowych", + "Messages containing my display name": "Wiadomości zawierające moją wyświetlaną nazwę", + "Messages in one-to-one chats": "Wiadomości w rozmowach jeden-na-jeden", + "Contributing code to Matrix and Riot": "Wspieranie rozwoju Matrix i Riot", + "Unavailable": "Niedostępny", + "Community-run support for Synapse": "Wsparcie społeczności dla Synapse", + "View Decrypted Source": "Pokaż zdeszyfrowane źródło", + "Send": "Wyślij", + "Notes:": "Notatki:", + "remove %(name)s from the directory.": "usuń %(name)s z katalogu.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Powiadomienia o słowach kluczowych spełniają reguły, które nie mogą być tu wyświetlone:", + "Safari and Opera work too.": "Safari i Opera również się sprawdzą.", + "Please set a password!": "Proszę, ustaw hasło!", + "You have successfully set a password!": "Hasło zostało zmienione z powodzeniem!", + "Chat with Riot Bot": "Rozmowa z Botem Riota", + "Support for those using, running and writing other bridges": "Wsparcie dla używających, zapewniających i piszących inne mosty", + "Admin support for Dendrite": "Wsparcie administratorskie dla Dendrite", + "An error occurred whilst saving your email notification preferences.": "Podczas zapisywania ustawień powiadomień e-mail wystąpił błąd.", + "Explore Room State": "Przeglądaj stan pokoju", + "Source URL": "Źródłowy URL", + "Messages sent by bot": "Wiadomości wysłane przez bota", + "Filter results": "Filtruj wyniki", + "Members": "Członkowie", + "No update available.": "Brak aktualizacji.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Matrix ma wiele, już działających pokoi, połączonych z istniejącymi sieciami, takimi jak Slack, IRC lub Gitter, a także wiele zupełnie niezależnych. Możesz przejrzeć je wszystkie w spisie pokoi!", + "Noisy": "Głośny", + "Files": "Pliki", + "Collecting app version information": "Zbieranie informacji o wersji aplikacji", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Usuń alias %(alias)s i usuń %(name)s z katalogu?", + "customServer_text": "Możesz używać opcji serwera niestandardowego do logowania się na inne serwery Matrix, określając inny adres URL serwera domowego.
    Pozwala to na wykorzystanie Riot z istniejącym kontem Matrix na innym serwerze domowym.

    Można również ustawić niestandardowy serwer tożsamości, ale nie będzie można zapraszać użytkowników adresem e-mail, ani być zaproszonym przez adres e-mailowy.", + "Co-ordination for Riot/Web translators": "Koordynacja tłumaczy Riot/Web", + "This will allow you to return to your account after signing out, and sign in on other devices.": "To pozwoli Ci powrócić do Twojego konta po wylogowaniu i ponownym zalogowaniu się na innych urządzeniach.", + "Dev chat for the Dendrite dev team": "Czat deweloperów zespołu Dendrite", + "Keywords": "Słowa kluczowe", + "Enable notifications for this account": "Włącz powiadomienia na tym koncie", + "Directory": "Księga adresowa", + "Invite to this community": "Zaproś do tej społeczności", + "Failed to get public room list": "Nie udało się uzyskać publicznej listy pokojowej", + "Messages containing keywords": "Wiadomości zawierające słowa kluczowe", + "Room not found": "Pokój nie znaleziony", + "Tuesday": "Wtorek", + "Enter keywords separated by a comma:": "Wpisz słowa kluczowe oddzielone przecinkami:", + "Forward Message": "Przekaż wiadomość", + "You have successfully set a password and an email address!": "Z powodzeniem ustawiono hasło i adres e-mail dla Twojego konta!", + "Remove %(name)s from the directory?": "Usunąć %(name)s z katalogu?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot używa wiele zaawansowanych technologii, które nie są dostępne lub są w fazie testów w Twojej przeglądarce.", + "Developer Tools": "Narzędzia programistyczne", + "Preparing to send logs": "Przygotowywanie do wysłania zapisu rozmów", + "Please install Chrome or Firefox for the best experience.": "Zainstaluj proszę Chrome lub Firefox.", + "Unnamed room": "Pokój bez nazwy", + "Remember, you can always set an email address in user settings if you change your mind.": "Pamiętaj, że zawsze możesz zmienić swój e-mail lub hasło w panelu ustawień użytkownika.", + "Explore Account Data": "Odkryj dane konta", + "All messages (noisy)": "Wszystkie wiadomości (głośno)", + "Away": "Niedostępny", + "Saturday": "Sobota", + "I understand the risks and wish to continue": "Rozumiem ryzyko i chcę kontynuować", + "Direct Chat": "Rozmowa bezpośrednia", + "The server may be unavailable or overloaded": "Serwer jest nieosiągalny lub jest przeciążony", + "Reject": "Odrzuć", + "Riot is not supported on mobile web. Install the app?": "Riot nie jest obsługiwany przez przeglądarki mobilne. Zainstaluj aplikację?", + "Discussion of all things Matrix!": "Rozmowa o wszystkim Matrixowym!", + "Failed to set Direct Message status of room": "Nie udało się ustawić statusu Rozmów Bezpośrednich dla pokoju", + "Monday": "Poniedziałek", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "W celu zdiagnozowania problemów logi z tego klienta zostaną wysłane wraz z tym raportem o błędzie. Jeśli wolisz wysłać tylko tekst powyżej, proszę odznacz:", + "Send Custom State Event": "Wyślij wydarzenie o niestandardowym stanie", + "Remove from Directory": "Usuń z katalogu", + "Enable them now": "Włącz je teraz", + "Messages containing my user name": "Wiadomości zawierające moją nazwę użytkownika", + "Describe your problem here.": "Opisz swój problem tutaj.", + "Toolbox": "Przybornik", + "Collecting logs": "Zbieranie dzienników", + "more": "więcej", + "GitHub issue link:": "Link do wątku na GitHubie:", + "Bug report sent": "Raport błędu wysłany", + "You must specify an event type!": "Musisz określić typ wydarzenia!", + "(HTTP status %(httpStatus)s)": "(status HTTP %(httpStatus)s)", + "All Rooms": "Wszystkie pokoje", + "Please install Chrome or Firefox for the best experience.": "Zainstaluj Chrome lub Firefox dla najlepszego doświadczenia.", + "Wednesday": "Środa", + "You cannot delete this message. (%(code)s)": "Nie możesz usunąć tej wiadomości. (%(code)s)", + "Quote": "Cytat", + "Failed to update keywords": "Nie udało się zaktualizować słów kluczowych", + "Send logs": "Wyślij logi", + "All messages": "Wszystkie wiadomości", + "Implementing VoIP services with Matrix": "Implementowanie usług telefonii internetowej VoIP w oparciu o Matrix", + "Dev chat for the Riot/Web dev team": "Czat deweloperów zespołu Riot/Web", + "Call invitation": "Zaproszenie do rozmowy", + "Riot Desktop on %(platformName)s": "Riot Desktop na %(platformName)s", + "Downloading update...": "Pobieranie aktualizacji...", + "State Key": "Klucz stanu", + "Failed to send custom event.": "Wysyłanie niestandardowego wydarzenia nie powiodło się.", + "What's new?": "Co nowego?", + "Discussion of the Identity Service API": "Dyskusja na temat API Identity Service", + "Support for those using and running matrix-appservice-irc": "Wsparcie dla hostujących i korzystających z matrix-appservice-irc", + "Riot/iOS & matrix-ios-sdk chat": "Czat o Riot/iOS i matrix-ios-sdk", + "Notify me for anything else": "Powiadom mnie o całej reszcie", + "When I'm invited to a room": "Kiedy zostanę zaproszony do pokoju", + "Design and implementation of E2E in Matrix": "Projektowanie i implementacja szyfrowania klient-klient (end-to-end) w Matrix", + "Click here to create a GitHub issue.": "Kliknij tutaj aby założyć wątek na GitHubie dot. problemu.", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Możesz skorzystać z opcji dedykowanego serwera, aby zalogować się na inne serwery Matrix, podając inny adres URL serwera Domowego.
    Pozwala to na używanie Riot z istniejącym kontem Matrix na innym serwerze domowym.

    Możesz również ustawić dedykowany serwer tożsamości, ale nie będziesz w stanie zapraszać użytkowników przez adres email, lub otrzymywać zaproszeń na adres email.", + "Can't update user notification settings": "Nie można zaktualizować ustawień powiadomień użytkownika", + "Notify for all other messages/rooms": "Powiadamiaj o wszystkich innych wiadomośsciach/pokojach", + "Unable to look up room ID from server": "Nie można wyszukać ID pokoju na serwerze", + "Couldn't find a matching Matrix room": "Nie można znaleźć pasującego pokoju Matrix", + "Support for those using the Matrix spec": "Wsparcie dla używających specyfikacji Matrix", + "Safari and Opera work too.": "Safari i Opera też działają.", + "Loading bug report module": "Ładowanie modułu raportu błędów", + "Invite to this room": "Zaproś do tego pokoju", + "Search for a room": "Szukaj pokoju", + "Thursday": "Czwartek", + "Search…": "Szukaj…", + "Logs sent": "Zapis rozmów wysłany", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s przez %(browserName)s na %(osName)s", + "Back": "Powrót", + "Reply": "Odpowiedz", + "Show message in desktop notification": "Pokaż wiadomość w notyfikacji na pulpicie", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Dziennik błędów zawiera dane użytkowania aplikacji, w tym: twoją nazwę użytkownika, numery ID, aliasy pokojów i grup które odwiedzałeś i loginy innych użytkowników. Nie zawiera wiadomości.", + "Unhide Preview": "Odkryj podgląd", + "Announcements about Synapse releases": "Ogłoszenia na temat Synapse", + "Search the room directory": "Wyszukaj katalog pokojów", + "Please describe the bug and/or send logs.": "Proszę opisz błąd i/lub wyślij logi.", + "Unable to join network": "Nie można dołączyć do sieci", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Możliwe, że skofigurowałeś je w innym kliencie, niż Riot. Nie możesz ich zmieniać w Riot, ale nadal mają zastosowanie", + "Sorry, your browser is not able to run Riot.": "Przepraszamy, Twoja przeglądarka nie jest w stanie uruchomić Riot.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Zdecentralizowany, szyfrowany czat & współpraca wspierana przez [matrix]", + "Uploaded on %(date)s by %(user)s": "Wysłane %(date)s przez %(user)s", + "Messages in group chats": "Wiadomości w czatach grupowych", + "Yesterday": "Wczoraj", + "Error encountered (%(errorDetail)s).": "Wystąpił błąd (%(errorDetail)s).", + "Login": "Logowanie", + "Low Priority": "Niski priorytet", + "Unable to fetch notification target list": "Nie można pobrać listy docelowej dla powiadomień", + "Appear Offline": "Ustaw status niedostępny", + "Get started with some tips from Riot Bot!": "Rozpocznij z wskazówkami Riot Bota!", + "Set Password": "Ustaw hasło", + "Enable audible notifications in web client": "Włącz dźwiękowe powiadomienia w kliencie internetowym", + "Permalink": "Odnośnik bezpośredni", + "Welcome to Riot.im": "Witamy w Riot.im", + "Off": "Wyłącz", + "Riot does not know how to join a room on this network": "Riot nie wie, jak dołączyć do pokoju w tej sieci", + "Mentions only": "Tylko, gdy wymienieni", + "Failed to remove tag %(tagName)s from room": "Nie udało się usunąć tagu %(tagName)s z pokoju", + "You can now return to your account after signing out, and sign in on other devices.": "Teraz możesz powrócić do swojego konta na innych urządzeniach po wylogowaniu i ponownym zalogowaniu się.", + "Enable desktop notifications": "Włącz powiadomienia", + "Enable email notifications": "Włącz powiadomienia e-mailowe", + "Event Type": "Typ wydarzenia", + "No rooms to show": "Brak pokoi do wyświetlenia", + "Download this file": "Pobierz plik", + "Pin Message": "Przypnij Wiadomość", + "Failed to change settings": "Nie udało się zmienić ustawień", + "View Community": "Pokaż społeczność", + "%(count)s Members|one": "%(count)s Członek", + "Event sent!": "Wydarzenie wysłane!", + "View Source": "Pokaż źródło", + "Matrix technical discussions": "Dyskusje techniczne Matrixa", + "Event Content": "Zawartość wydarzenia", + "Thank you!": "Dziękujemy!", + "Building services on Matrix": "Tworzenie usług w oparciu o Matrix", + "Collapse panel": "Ukryj panel", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Z Twoją obecną przeglądarką, wygląd oraz wrażenia z używania aplikacji mogą być niepoprawne, a niektóre funkcje wcale nie działać. Kontynuuj jeśli chcesz spróbować, jednak trudno będzie pomóc w przypadku błędów, które mogą nastąpić!", + "Checking for an update...": "Sprawdzanie aktualizacji...", + "General discussion about Matrix and Riot": "Generalna rozmowa o Matrix i Riot", + "There are advanced notifications which are not shown here": "Masz zaawansowane powiadomienia, nie pokazane tutaj" } diff --git a/src/i18n/strings/pt.json b/src/i18n/strings/pt.json index 2a99cd191c..f046907637 100644 --- a/src/i18n/strings/pt.json +++ b/src/i18n/strings/pt.json @@ -715,5 +715,194 @@ "To configure the room, you must be a": "Para configurar esta sala, tens de ser um(a)", "To ban users, you must be a": "Para banir utilizadores, tens de ser um(a)", "To remove other users' messages, you must be a": "Para remover mensagens de outros utilizadores, tens de ser um(a)", - "To send events of type , you must be a": "Para enviar eventos do tipo , tens de ser um(a)" + "To send events of type , you must be a": "Para enviar eventos do tipo , tens de ser um(a)", + "Fetching third party location failed": "Falha ao obter localização de terceiros", + "A new version of Riot is available.": "Uma nova versão do Riot está disponível.", + "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk chat", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Por favor descreva a falha encontrada. O que fez? O que esperava que acontecesse? O que realmente aconteceu?", + "I understand the risks and wish to continue": "Entendo os riscos e pretendo continuar", + "Couldn't load home page": "Não foi possível carregar a página inicial", + "Advanced notification settings": "Configurações avançadas de notificação", + "Uploading report": "A enviar o relatório", + "Sunday": "Domingo", + "Guests can join": "Convidados podem entrar", + "Messages sent by bot": "Mensagens enviadas por bots", + "Notification targets": "Alvos de notificação", + "Failed to set direct chat tag": "Falha ao definir conversa como pessoal", + "Today": "Hoje", + "Failed to get protocol list from Home Server": "Falha ao obter a lista de protocolos do servidor padrão", + "Report a bug": "Reportar uma falha", + "Implementing VR services with Matrix": "Implementar serviços de realidade virtual (VR) com o Matrix", + "You are not receiving desktop notifications": "Não está a receber notificações de desktop", + "Friday": "Sexta-feira", + "Update": "Atualizar", + "You need to be using HTTPS to place a screen-sharing call.": "Necessita de estar a usar HTTPS para poder iniciar uma chamada com partilha de ecrã.", + "What's New": "Novidades", + "Add an email address above to configure email notifications": "Insira um endereço de email no campo acima para configurar as notificações por email", + "Expand panel": "Expandir o painel", + "On": "Ativado", + "Filter room names": "Filtrar salas por título", + "Changelog": "Histórico de alterações", + "Running Matrix services": "Correr serviços do Matrix", + "Waiting for response from server": "À espera de resposta do servidor", + "Uploaded on %(date)s by %(user)s": "Enviada em %(date)s por %(user)s", + "Send Custom Event": "Enviar evento personalizado", + "Failed to send report: ": "Falha ao enviar o relatório: ", + "Unknown device": "Dispositivo desconhecido", + "All notifications are currently disabled for all targets.": "Todas as notificações estão atualmente desativadas para todos os casos.", + "delete the alias.": "apagar o apelido da sala.", + "To return to your account in future you need to set a password": "Para voltar à sua conta no futuro, necessita de definir uma palavra-passe", + "Forget": "Esquecer", + "World readable": "Público", + "#example": "#exemplo", + "Riot/Web & Desktop chat": "Riot/Web & Desktop chat", + "Hide panel": "Ocultar o painel", + "You cannot delete this image. (%(code)s)": "Não pode apagar esta imagem. (%(code)s)", + "Cancel Sending": "Cancelar o envio", + "Warning": "Aviso", + "This Room": "Esta sala", + "The Home Server may be too old to support third party networks": "O servidor pode ser muito antigo para suportar redes de terceiros", + "Resend": "Reenviar", + "Error saving email notification preferences": "Erro ao guardar as preferências de notificação por e-mail", + "Messages containing my display name": "Mensagens contendo o meu nome público", + "Messages in one-to-one chats": "Mensagens em conversas pessoais", + "Contributing code to Matrix and Riot": "Contribuir código para o Matrix e para o Riot", + "Unavailable": "Indisponível", + "Community-run support for Synapse": "Suporte da comunidade para o Synapse", + "View Decrypted Source": "Ver a fonte desencriptada", + "Failed to update keywords": "Falha ao atualizar as palavras-chave", + "remove %(name)s from the directory.": "remover %(name)s da lista pública de salas.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Notificações sobre as seguintes palavras-chave seguem regras que não podem ser exibidas aqui:", + "Please set a password!": "Por favor, defina uma palavra-passe!", + "You have successfully set a password!": "Palavra-passe definida com sucesso!", + "Chat with Riot Bot": "Falar com o Bot do Riot", + "Support for those using, running and writing other bridges": "Suporte para aqueles a usar, correr e desenvolver outras pontes (bridges)", + "Admin support for Dendrite": "Suporte de administração para o Dendrite", + "An error occurred whilst saving your email notification preferences.": "Ocorreu um erro ao guardar as suas preferências de notificação por email.", + "Explore Room State": "Explorar estado da sala", + "Source URL": "URL fonte", + "Failed to add tag %(tagName)s to room": "Falha ao adicionar %(tagName)s à sala", + "Filter results": "Filtrar resultados", + "Members": "Membros", + "No update available.": "Nenhuma atualização disponível.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Já existem muitas salas no Matrix, ligadas a redes já existentes (Slack, IRC, Gitter, etc) ou independentes. Dê uma vista de olhos no diretório!", + "Noisy": "Barulhento", + "Files": "Ficheiros", + "Collecting app version information": "A recolher informação da versão da app", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Apagar o apelido %(alias)s da sala e remover %(name)s da lista pública?", + "customServer_text": "Pode usar as opções de servidor personalizado para entrar noutros servidores Matrix especificando para isso um URL de outro Servidor de Base.
    Isto permite que use o Riot com uma conta Matrix que exista noutro Servidor de Base.

    Também pode configurar um servidor de Identidade personalizado mas não poderá convidar utilizadores através do endereço de e-mail, ou ser convidado pelo seu endereço de e-mail.", + "Co-ordination for Riot/Web translators": "Coordenação para a equipa de tradutores do Riot/Web", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Isto irá permitir-lhe voltar à sua conta depois de terminar sessão, assim como iniciar sessão noutros dispositivos.", + "Dev chat for the Dendrite dev team": "Conversa de desenvolvimento para a equipa do Dendrite", + "Keywords": "Palavras-chave", + "Enable notifications for this account": "Ativar notificações para esta conta", + "Directory": "Diretório", + "Search for a room": "Pesquisar por uma sala", + "Messages containing keywords": "Mensagens contendo palavras-chave", + "Room not found": "Sala não encontrada", + "Tuesday": "Terça-feira", + "Enter keywords separated by a comma:": "Insira palavras-chave separadas por vírgula:", + "Search…": "Pesquisar…", + "Remove %(name)s from the directory?": "Remover %(name)s da lista pública de salas?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "O Riot usa muitas funcionalidades avançadas do navegador, algumas das quais não estão disponíveis ou ainda são experimentais no seu navegador atual.", + "Developer Tools": "Ferramentas de desenvolvedor", + "Enable desktop notifications": "Ativar notificações no desktop", + "Unnamed room": "Sala sem nome", + "Remove from Directory": "Remover da lista pública de salas", + "Saturday": "Sábado", + "Remember, you can always set an email address in user settings if you change your mind.": "Lembre-se, pode sempre definir um endereço de e-mail nas definições de utilizador se mudar de ideias.", + "Direct Chat": "Conversa pessoal", + "The server may be unavailable or overloaded": "O servidor pode estar inacessível ou sobrecarregado", + "Reject": "Rejeitar", + "Riot is not supported on mobile web. Install the app?": "O Riot não é suportado na web para dispositivos móveis. Quer instalar a app?", + "Discussion of all things Matrix!": "Discussão de tudo o que envolva o Matrix!", + "Failed to set Direct Message status of room": "Falha em definir a mensagem de status da sala", + "Monday": "Segunda-feira", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Para diagnosticar problemas, relatórios deste cliente serão enviados juntamente com esta notificação de falha. Se preferir enviar apenas o texto acima, por favor remova a seleção:", + "Send Custom State Event": "Enviar evento personalizado de estado", + "All messages (noisy)": "Todas as mensagens (alto)", + "Enable them now": "Ativar agora", + "Messages containing my user name": "Mensagens contendo o meu nome de utilizador", + "Describe your problem here.": "Descreva o seu problema aqui.", + "Collecting logs": "A recolher logs", + "more": "mais", + "Support for those using the Matrix spec": "Suporte para os utilizadores da especificação do Matrix", + "You must specify an event type!": "Tem que especificar um tipo de evento!", + "(HTTP status %(httpStatus)s)": "(Estado HTTP %(httpStatus)s)", + "Invite to this room": "Convidar para esta sala", + "State Key": "Chave de estado", + "Failed to get public room list": "Falha ao obter a lista de salas públicas", + "Send": "Enviar", + "Send logs": "Enviar relatórios de erro", + "All messages": "Todas as mensagens", + "Implementing VoIP services with Matrix": "Implementar serviços VoIP com o Matrix", + "Dev chat for the Riot/Web dev team": "Conversa de desenvolvimento para a equipa do Riot/Web", + "Call invitation": "Convite para chamada", + "Riot Desktop on %(platformName)s": "Riot para computadores desktop em %(platformName)s", + "Downloading update...": "A transferir atualização...", + "You have successfully set a password and an email address!": "Palavra passe e endereço de e-mail definidos com sucesso!", + "Failed to send custom event.": "Falha ao enviar evento personalizado.", + "What's new?": "O que há de novo?", + "Discussion of the Identity Service API": "Discussão da API do serviço de identidade", + "Support for those using and running matrix-appservice-irc": "Suporte para aqueles a correr e a utilizar o matrix-appservice-irc", + "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk chat", + "Notify me for anything else": "Notificar-me sobre qualquer outro evento", + "When I'm invited to a room": "Quando sou convidado para uma sala", + "Design and implementation of E2E in Matrix": "Design e implementação de encriptação ponto-a-ponto (E2E) no Matrix", + "Can't update user notification settings": "Não é possível atualizar as preferências de notificação", + "Notify for all other messages/rooms": "Notificar para todas as outras mensagens/salas", + "Unable to look up room ID from server": "Não foi possível obter a identificação da sala do servidor", + "Couldn't find a matching Matrix room": "Não foi possível encontrar uma sala correspondente no servidor Matrix", + "Bug report sent": "Relatório de erros enviado", + "Safari and Opera work too.": "Safari e Opera também funcionam.", + "Loading bug report module": "A carregar o módulo de relato de erros", + "All Rooms": "Todas as salas", + "You cannot delete this message. (%(code)s)": "Não pode apagar esta mensagem. (%(code)s)", + "Thursday": "Quinta-feira", + "Forward Message": "Encaminhar", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s via %(browserName)s em %(osName)s", + "Back": "Voltar", + "Unhide Preview": "Mostrar a pré-visualização novamente", + "Announcements about Synapse releases": "Anúncios acerca de lançamentos do Synapse", + "Search the room directory": "Procurar o diretório de salas", + "Please describe the bug and/or send logs.": "Por favor descreva a falha e/ou envie os logs de erro.", + "Unable to join network": "Não foi possível juntar-se à rede", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Pode ter configurado num outro cliente sem ser o Riot. Não pode ajustá-las no Riot, mas ainda assim elas aplicam-se", + "Sorry, your browser is not able to run Riot.": "Desculpe, o seu navegador não é capaz de executar o Riot.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Chat descentralizado, encriptado & colaborativo alimentado por [matrix]", + "Building services on Matrix": "Construir serviços no Matrix", + "Messages in group chats": "Mensagens em salas", + "Yesterday": "Ontem", + "Error encountered (%(errorDetail)s).": "Erro encontrado (%(errorDetail)s).", + "Login": "Entrar", + "Low Priority": "Baixa prioridade", + "Unable to fetch notification target list": "Não foi possível obter a lista de alvos de notificação", + "Get started with some tips from Riot Bot!": "Comece com algumas dicas do Bot do Riot", + "Set Password": "Definir palavra-passe", + "Enable audible notifications in web client": "Ativar notificações de áudio no cliente web", + "Permalink": "Link permanente", + "Welcome to Riot.im": "Bem-vindo ao Riot.im", + "Off": "Desativado", + "Riot does not know how to join a room on this network": "O Riot não sabe como entrar numa sala nesta rede", + "Mentions only": "Apenas menções", + "Failed to remove tag %(tagName)s from room": "Não foi possível remover a marcação %(tagName)s desta sala", + "Wednesday": "Quarta-feira", + "You can now return to your account after signing out, and sign in on other devices.": "Pode agora voltar à sua conta no fim de terminar sessão, e iniciar sessão noutros dispositivos.", + "Please install Chrome or Firefox for the best experience.": "Por favor instale Chrome ou Firefox para ter a melhor experiência.", + "Enable email notifications": "Ativar notificações por e-mail", + "Event Type": "Tipo de evento", + "No rooms to show": "Não existem salas a serem exibidas", + "Download this file": "Transferir este ficheiro", + "Failed to change settings": "Falha ao alterar as configurações", + "Event sent!": "Evento enviado!", + "View Source": "Ver a fonte", + "Matrix technical discussions": "Discussões técnicas do Matrix", + "Event Content": "Conteúdo do evento", + "Thank you!": "Obrigado!", + "Quote": "Citar", + "Collapse panel": "Colapsar o painel", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Com o seu navegador atual, a aparência e sensação de uso da aplicação podem estar completamente incorretas, e algumas das funcionalidades poderão não funcionar. Se quiser tentar de qualquer maneira pode continuar, mas está por sua conta com algum problema que possa encontrar!", + "Checking for an update...": "A procurar uma atualização...", + "General discussion about Matrix and Riot": "Discussão geral acerca do Matrix e do Riot", + "There are advanced notifications which are not shown here": "Existem notificações avançadas que não são exibidas aqui" } diff --git a/src/i18n/strings/pt_BR.json b/src/i18n/strings/pt_BR.json index fc0899873a..046617d934 100644 --- a/src/i18n/strings/pt_BR.json +++ b/src/i18n/strings/pt_BR.json @@ -994,5 +994,200 @@ "Key request sent.": "Requisição de chave enviada.", "Re-request encryption keys from your other devices.": "Requisitar novamente chaves de encriptação de seus outros dispositivos.", "%(user)s is a %(userRole)s": "%(user)s é %(userRole)s", - "Changes made to your community might not be seen by other users for up to 30 minutes.": "Mudanças feitas para sua comunidade podem não chegar aos outros usuários por até 30 minutos." + "Changes made to your community might not be seen by other users for up to 30 minutes.": "Mudanças feitas para sua comunidade podem não chegar aos outros usuários por até 30 minutos.", + "Fetching third party location failed": "Falha ao acessar localização de terceiros", + "A new version of Riot is available.": "Uma nova versão do Riot está disponível.", + "Riot/Android & matrix-android-sdk chat": "Riot/Chat do Android e do matrix-android-sdk", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Por favor, descreva a falha encontrada. O que você estava fazendo? O que você esperava que devia ocorrer? E o que aconteceu efetivamente?", + "I understand the risks and wish to continue": "Entendo os riscos e desejo continuar", + "Couldn't load home page": "Não foi possível carregar a página inicial", + "Send Account Data": "Enviar Dados da Conta", + "Advanced notification settings": "Configurações avançadas de notificação", + "Uploading report": "Enviando o relatório", + "Sunday": "Domingo", + "Notification targets": "Alvos de notificação", + "Today": "Hoje", + "Failed to get protocol list from Home Server": "Falha em acessar a lista de protocolos do servidor padrão", + "Report a bug": "Reportar uma falha", + "Implementing VR services with Matrix": "Implementando serviços de Realidade Virtual (VR) com Matrix", + "You are not receiving desktop notifications": "Você não está recebendo notificações desktop", + "Friday": "Sexta", + "Update": "Atualizar", + "You need to be using HTTPS to place a screen-sharing call.": "Você precisa estar usando HTTPS para poder iniciar uma chamada com compartilhamento de tela.", + "What's New": "Novidades", + "Add an email address above to configure email notifications": "Insira um endereço de email no campo acima para configurar suas notificações por email", + "Expand panel": "Expandir o painel", + "On": "Ativado", + "%(count)s Members|other": "%(count)s Membros", + "Filter room names": "Filtrar salas por título", + "Changelog": "Histórico de alterações", + "Running Matrix services": "Rodando serviços Matrix", + "Waiting for response from server": "Esperando por resposta do servidor", + "Uploaded on %(date)s by %(user)s": "Enviada em %(date)s por %(user)s", + "Send Custom Event": "Enviar Evento Customizado", + "Failed to send report: ": "Falha ao enviar o relatório: ", + "Unknown device": "Dispositivo desconhecido", + "All notifications are currently disabled for all targets.": "Todas as notificações estão atualmente desabilitadas para todos os casos.", + "delete the alias.": "apagar o apelido da sala.", + "To return to your account in future you need to set a password": "Para poder, futuramente, retornar à sua conta, você precisa definir uma senha", + "Forget": "Esquecer", + "#example": "#exemplo", + "Riot/Web & Desktop chat": "Riot/chat da web e do computador desktop", + "Hide panel": "Ocultar o painel", + "You cannot delete this image. (%(code)s)": "Você não pode apagar esta imagem. (%(code)s)", + "Cancel Sending": "Cancelar o envio", + "This Room": "Esta sala", + "The Home Server may be too old to support third party networks": "O servidor pode ser muito antigo para suportar redes de terceiros", + "Resend": "Reenviar", + "Error saving email notification preferences": "Erro ao salvar as preferências de notificação por email", + "Messages containing my display name": "Mensagens contendo meu nome público", + "Messages in one-to-one chats": "Mensagens em conversas pessoais", + "Contributing code to Matrix and Riot": "Contribuindo com código para o Matrix e o Riot", + "Unavailable": "Indisponível", + "Community-run support for Synapse": "Apoio ao Synapse gerido pela comunidade", + "View Decrypted Source": "Ver a fonte descriptografada", + "Failed to update keywords": "Falha ao alterar as palavras-chave", + "remove %(name)s from the directory.": "remover %(name)s da lista pública de salas.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Notificações sobre as seguintes palavras-chave seguem regras que não podem ser exibidas aqui:", + "Safari and Opera work too.": "Safari e Opera Funciona bem.", + "Please set a password!": "Por favor, defina uma senha!", + "You have successfully set a password!": "Você definiu sua senha com sucesso!", + "Chat with Riot Bot": "Conversar com o Bot do Riot", + "Support for those using, running and writing other bridges": "Apoio para as pessoas que estejam usando, rodando e escrevendo outras pontes (bridges)", + "Admin support for Dendrite": "Suporte de administração para Dendrite", + "An error occurred whilst saving your email notification preferences.": "Um erro ocorreu enquanto o sistema estava salvando suas preferências de notificação por email.", + "Explore Room State": "Explorar Estado da Sala", + "Source URL": "URL fonte", + "Messages sent by bot": "Mensagens enviadas por bots", + "Filter results": "Filtrar resultados", + "Members": "Membros", + "No update available.": "Não há atualizações disponíveis.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Muitas salas já existem no Matrix, algumas independentes, e outras relacionadas a redes existentes (tais como Slack, IRC, Gitter, entre outras). Dê uma olhada na lista de salas públicas!", + "Noisy": "Barulhento", + "Files": "Arquivos", + "Collecting app version information": "Coletando informação sobre a versão do app", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Apagar o apelido %(alias)s da sala e remover %(name)s da lista pública?", + "customServer_text": "Você pode usar as opções de servidor personalizado para entrar em outros servidores Matrix, especificando uma URL de outro Servidor de Base.
    Isso permite que você use Riot com uma conta Matrix que exista em outro Servidor de Base.

    Você também pode configurar um servidor de Identidade personalizado, mas neste caso não poderá convidar usuárias(os) pelo endereço de e-mail, ou ser convidado(a) pelo seu endereço de e-mail.", + "Co-ordination for Riot/Web translators": "Coordenação para tradutoras(es) do Riot/Web", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Isso permitirá que você possa retornar à sua conta após fazer logout, e também fazer login em outros dispositivos.", + "Dev chat for the Dendrite dev team": "Chat de desenvolvimento para o time devel do Dendrite", + "Keywords": "Palavras-chave", + "Enable notifications for this account": "Ativar notificações para esta conta", + "Directory": "Diretório", + "Invite to this community": "Convidar para essa comunidade", + "Search for a room": "Procurar por uma sala", + "Messages containing keywords": "Mensagens contendo palavras-chave", + "Room not found": "Sala não encontrada", + "Tuesday": "Terça", + "Enter keywords separated by a comma:": "Coloque cada palavras-chave separada por vírgula:", + "Search…": "Buscar…", + "You have successfully set a password and an email address!": "Você definiu uma senha e um endereço de e-mail com sucesso!", + "Remove %(name)s from the directory?": "Remover %(name)s da lista pública de salas?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "O Riot usa muitas funcionalidades avançadas do navegador, algumas das quais não estão disponíveis ou ainda são experimentais no seu navegador atual.", + "Developer Tools": "Ferramentas do desenvolvedor", + "Enable desktop notifications": "Ativar notificações no desktop", + "Explore Account Data": "Explorar Dados da Conta", + "Remove from Directory": "Remover da lista pública de salas", + "Away": "Ausente", + "Saturday": "Sábado", + "Remember, you can always set an email address in user settings if you change your mind.": "Lembre-se: você pode sempre definir um endereço de e-mail nas configurações de usuário, se mudar de ideia.", + "Direct Chat": "Conversa pessoal", + "The server may be unavailable or overloaded": "O servidor pode estar inacessível ou sobrecarregado", + "Reject": "Rejeitar", + "Riot is not supported on mobile web. Install the app?": "Riot versão web não é suportado a partir de celular. Quer instalar o app para celular?", + "Discussion of all things Matrix!": "Discussão sobre todas as coisas do Matrix!", + "Failed to set Direct Message status of room": "Falha em definir a mensagem de status da sala", + "Monday": "Segunda", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Para diagnosticar problemas, relatórios deste cliente serão enviados junto a esta notificação de falha. Se você prefere apenas enviar o seu texto acima, por favor des-selecione:", + "Send Custom State Event": "Enviar Evento de Estado Personalizado", + "All messages (noisy)": "Todas as mensagens (alto)", + "Enable them now": "Habilitar agora", + "Messages containing my user name": "Mensagens contendo meu nome de usuário", + "Describe your problem here.": "Descreva o seu problema aqui.", + "Toolbox": "Ferramentas", + "Collecting logs": "Coletando logs", + "more": "ver mais", + "Bug report sent": "Relatório do bug enviado", + "You must specify an event type!": "Você precisa especificar um tipo do evento!", + "(HTTP status %(httpStatus)s)": "(Status HTTP %(httpStatus)s)", + "Invite to this room": "Convidar para esta sala", + "Please install Chrome or Firefox for the best experience.": "Por favor Instale Chrome Ou Firefox para uma melhor Experiencia.", + "Failed to get public room list": "Falha ao acessar a lista pública de salas", + "Send logs": "Enviar relatórios de erro", + "All messages": "Todas as mensagens", + "Implementing VoIP services with Matrix": "Implementando serviços VoIP com Matrix", + "Dev chat for the Riot/Web dev team": "Chat de desenvolvimento para o time devel do Riot/Web", + "Call invitation": "Convite para chamada", + "Riot Desktop on %(platformName)s": "Riot para computadores desktop em %(platformName)s", + "Downloading update...": "Baixando atualização...", + "State Key": "Chave do Estado", + "Failed to send custom event.": "Falha ao enviar evento personalizado.", + "What's new?": "O que há de novidades?", + "Discussion of the Identity Service API": "Discussão do API do Serviço de Identidades", + "Support for those using and running matrix-appservice-irc": "Apoio para as pessoas usando e rodando matrix-appservice-irc", + "Riot/iOS & matrix-ios-sdk chat": "Riot/chat do iOS e do matrix-ios-sdk", + "Notify me for anything else": "Notificar-me sobre qualquer outro evento", + "When I'm invited to a room": "Quando sou convidada(o) a uma sala", + "Design and implementation of E2E in Matrix": "Design e implementação de criptografia ponta-a-ponta (E2E) no Matrix", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Você pode usar as opções customizadas de servidor para conectar-se a outros servidores Matrix ao especificar uma outra URL de Servidor de Base (homeserver).
    Isso permite que você use o Riot com uma conta Matrix existente em outro servidor de base.

    Você também pode definir um servidor de identidade customizado, mas neste caso você não poderá convidar outras pesoas por endereço de email, ou ser convidada/o pelo seu endereço de email.", + "Can't update user notification settings": "Não é possível atualizar as preferências de notificação", + "Notify for all other messages/rooms": "Notificar para todas as outras mensagens e salas", + "Unable to look up room ID from server": "Não foi possível buscar identificação da sala no servidor", + "Couldn't find a matching Matrix room": "Não foi possível encontrar uma sala correspondente no servidor Matrix", + "Support for those using the Matrix spec": "Apoio para as pessoas que estão usando as especificações Matrix", + "Safari and Opera work too.": "Safari e Opera funcionam também.", + "Loading bug report module": "Carregando o módulo de relatórios de erros", + "All Rooms": "Todas as salas", + "You cannot delete this message. (%(code)s)": "Você não pode apagar esta mensagem. (%(code)s)", + "Thursday": "Quinta", + "Forward Message": "Encaminhar", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s via %(browserName)s em %(osName)s", + "Back": "Voltar", + "Reply": "Responder", + "Show message in desktop notification": "Mostrar mensagens na notificação", + "Unhide Preview": "Mostrar a pré-visualização", + "Announcements about Synapse releases": "Anúncios sobre lançamentos do Synapse", + "Search the room directory": "Buscar na lista pública de salas", + "Please describe the bug and/or send logs.": "Por favor, descreva as falhas e/ou envie os logs de erro.", + "Unable to join network": "Não foi possível conectar na rede", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Você pode te-las configurado em outro cliente além do Riot. Você não pode ajustá-las no Riot, mas ainda assim elas se aplicam aqui", + "Sorry, your browser is not able to run Riot.": "Perdão. O seu navegador não é capaz de rodar o Riot.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Chat descentralizado, criptografado e colaborativo impulsionado por [matrix]", + "Building services on Matrix": "Construindo serviços no Matrix", + "Messages in group chats": "Mensagens em salas", + "Yesterday": "Ontem", + "Error encountered (%(errorDetail)s).": "Erro encontrado (%(errorDetail)s).", + "Login": "Fazer login", + "Low Priority": "Baixa prioridade", + "Unable to fetch notification target list": "Não foi possível obter a lista de alvos de notificação", + "Appear Offline": "Aparecer Desconectado", + "Get started with some tips from Riot Bot!": "Comece com algumas dicas do Bot do Riot!", + "Set Password": "Definir senha", + "Enable audible notifications in web client": "Ativar notificações de áudio no cliente web", + "Permalink": "Link permanente", + "Welcome to Riot.im": "Seja bem-vinda(o) a Riot.im", + "Off": "Desativado", + "Riot does not know how to join a room on this network": "O sistema não sabe como entrar na sala desta rede", + "Mentions only": "Apenas menções", + "Wednesday": "Quarta", + "You can now return to your account after signing out, and sign in on other devices.": "Você pode retornar agora para a sua conta depois de fazer logout, e então fazer login em outros dispositivos.", + "Please install Chrome or Firefox for the best experience.": "Por favor instale Chrome ou Firefox para ter a melhor experiência de uso.", + "Enable email notifications": "Ativar notificações por email", + "Event Type": "Tipo do Evento", + "Download this file": "Baixar este arquivo", + "Pin Message": "Fixar Mensagem", + "Failed to change settings": "Falhou ao mudar as preferências", + "View Community": "Ver a comunidade", + "%(count)s Members|one": "%(count)s Membros", + "Event sent!": "Evento enviado!", + "View Source": "Ver a fonte", + "Matrix technical discussions": "Discussões técnicas do Matrix", + "Event Content": "Conteúdo do Evento", + "Thank you!": "Obrigado!", + "Quote": "Citar", + "Collapse panel": "Colapsar o painel", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Com o seu navegador atual, a aparência e sensação de uso da aplicação podem estar completamente incorretas, e algumas das funcionalidades poderão não funcionar. Se você quiser tentar de qualquer maneira, pode continuar, mas aí vai ter que se virar sozinho(a) com os problemas que porventura encontrar!", + "Checking for an update...": "Verificando se há atualizações...", + "General discussion about Matrix and Riot": "Discussão geral sobre o Matrix e o Riot", + "There are advanced notifications which are not shown here": "Existem opções avançadas que não são exibidas aqui" } diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index d732be55da..a77e8605c0 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -1008,5 +1008,207 @@ "to add some!": "для добавления!", "Click": "Нажмите", "Who can join this community?": "Кто может присоединиться к этому сообществу?", - "Everyone": "Все" + "Everyone": "Все", + "Fetching third party location failed": "Не удалось извлечь местоположение третьей стороны", + "A new version of Riot is available.": "Доступна новая версия Riot.", + "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk чат", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Пожалуйста, опишите ошибку. Что сделали? Чего ожидали? Что на самом деле произошло?", + "I understand the risks and wish to continue": "Я понимаю риски и желаю продолжить", + "Couldn't load home page": "Не удалось загрузить домашнюю страницу", + "Send Account Data": "Отправить данные аккаунта", + "All notifications are currently disabled for all targets.": "Все оповещения для всех устройств отключены.", + "Uploading report": "Отправка отчета", + "Sunday": "Воскресенье", + "Notification targets": "Цели уведомления", + "Today": "Сегодня", + "Files": "Файлы", + "Report a bug": "Сообщить об ошибке", + "Implementing VR services with Matrix": "Внедрение сервисов виртуальной реальности (VR) с помощью Matrix", + "You are not receiving desktop notifications": "Вы не получаете уведомления на рабочем столе", + "Friday": "Пятница", + "Update": "Обновление", + "You need to be using HTTPS to place a screen-sharing call.": "Требуется использование HTTPS для совместного использования рабочего стола.", + "What's New": "Что нового", + "Add an email address above to configure email notifications": "Добавьте email адрес для оповещений", + "Expand panel": "Развернуть панель", + "On": "Включить", + "%(count)s Members|other": "%(count)s членов", + "Filter room names": "Фильтр по названию комнат", + "Changelog": "История изменений", + "Running Matrix services": "Запуск сервисов Matrix", + "Waiting for response from server": "Ожидание ответа от сервера", + "Uploaded on %(date)s by %(user)s": "Отправлено %(date)s для %(user)s", + "Send Custom Event": "Отправить индивидуальное мероприятие", + "Failed to send report: ": "Не удалось отправить отчет: ", + "Unknown device": "Неизвестное устройство", + "Advanced notification settings": "Дополнительные параметры уведомлений", + "Failed to send logs: ": "Не удалось отправить журналы: ", + "delete the alias.": "удалить псевдоним.", + "To return to your account in future you need to set a password": "Чтобы вернуться к учетной записи в будущем, необходимо задать пароль", + "Forget": "Забыть", + "#example": "#пример", + "Riot/Web & Desktop chat": "Riot/Web & Desktop-чат", + "Hide panel": "Скрыть панель", + "You cannot delete this image. (%(code)s)": "Это изображение нельзя удалить. (%(code)s)", + "Cancel Sending": "Отменить отправку", + "This Room": "Эта комната", + "The Home Server may be too old to support third party networks": "Домашний сервер может быть слишком старым для поддержки сетей сторонних производителей", + "Noisy": "Со звуком", + "Room not found": "Комната не найдена", + "Messages containing my display name": "Сообщения, содержащие мое имя", + "Messages in one-to-one chats": "Сообщения в индивидуальных чатах", + "Contributing code to Matrix and Riot": "Внести свой вклад в разработку кода Matrix и Riot", + "Unavailable": "Недоступен", + "Community-run support for Synapse": "Поддержка Synapse от сообщества", + "Error saving email notification preferences": "Ошибка при сохранении настроек уведомлений по email", + "View Decrypted Source": "Просмотр расшифрованного источника", + "Failed to update keywords": "Не удалось обновить ключевые слова", + "Notes:": "Заметки:", + "remove %(name)s from the directory.": "удалить %(name)s из каталога.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Уведомления по следующим ключевым словам соответствуют правилам, которые нельзя отобразить здесь:", + "Safari and Opera work too.": "Safari и Opera работают тоже.", + "Please set a password!": "Пожалуйста, установите пароль!", + "You have successfully set a password!": "Вы успешно установили пароль!", + "Chat with Riot Bot": "Пообщаться с ботом Riot", + "Support for those using, running and writing other bridges": "Поддержка для тех, кто использует, разрабатывает и внедряет приложения интеграции для Matrix", + "Admin support for Dendrite": "Административная поддержка Dendrite", + "An error occurred whilst saving your email notification preferences.": "Возникла ошибка при сохранении настроек оповещения по email.", + "Explore Room State": "Просмотр статуса комнаты", + "Source URL": "Исходный URL-адрес", + "Messages sent by bot": "Сообщения, отправленные ботом", + "Filter results": "Фильтрация результатов", + "Members": "Участники", + "No update available.": "Нет доступных обновлений.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "В Matrix существует множество комнат, как связанных с существующими сетями (Slack, IRC, Gitter и пр.), так и независимых. Ищите в каталоге!", + "Resend": "Переотправить", + "Failed to get protocol list from Home Server": "Не удалось получить список протоколов с домашнего сервера", + "Collecting app version information": "Сбор информации о версии приложения", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Удалить псевдоним комнаты %(alias)s и удалить %(name)s из каталога?", + "customServer_text": "Вы можете использовать настраиваемые параметры сервера для входа на другие серверы Matrix, указав другой URL-адрес домашнего сервера.
    Это позволяет использовать это приложение с существующей учетной записью Matrix на другом домашнем сервере.

    Вы также можете установить другой сервер идентификации, но это, как правило, будет препятствовать взаимодействию с пользователями на основе адреса электронной почты.", + "Co-ordination for Riot/Web translators": "Координация для переводчиков Riot/Web", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Это позволит вам вернуться к учетной записи после выхода из системы и войти на других устройствах.", + "Dev chat for the Dendrite dev team": "Чат с командой разработчиков Dendrite", + "Keywords": "Ключевые слова", + "Enable notifications for this account": "Включить уведомления для этой учетной записи", + "Directory": "Каталог", + "Invite to this community": "Пригласить в это сообщество", + "Search for a room": "Поиск комнаты", + "Messages containing keywords": "Сообщения, содержащие определенные ключевые слова", + "View Source": "Просмотр источника", + "Tuesday": "Вторник", + "Enter keywords separated by a comma:": "Введите ключевые слова, разделенные запятой:", + "Search…": "Поиск.…", + "You have successfully set a password and an email address!": "Вы успешно установили пароль и адрес email!", + "Remove %(name)s from the directory?": "Удалить %(name)s из каталога?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot использует многие передовые возможности браузера, некоторые из которых недоступны или являются экспериментальным в вашем текущем браузере.", + "Developer Tools": "Инструменты разработчика", + "Preparing to send logs": "Подготовка к отправке журналов", + "Enable desktop notifications": "Включить оповещения на рабочем столе", + "Explore Account Data": "Просмотр данных аккаунта", + "All messages (noisy)": "Все сообщения (со звуком)", + "Away": "Нет на месте", + "Saturday": "Суббота", + "Remember, you can always set an email address in user settings if you change your mind.": "Помните, что вы всегда сможете задать адрес email в настройках пользователя, если передумаете.", + "Direct Chat": "Прямой чат", + "The server may be unavailable or overloaded": "Сервер, вероятно, недоступен или перегружен", + "Reject": "Отклонить", + "Riot is not supported on mobile web. Install the app?": "Riot не поддерживает версию веб-сайта для мобильных устройств. Установить приложение?", + "Discussion of all things Matrix!": "Дискуссия обо всем, что связано с Matrix!", + "Failed to set Direct Message status of room": "Не удалось установить статус прямого сообщения в комнате", + "Monday": "Понедельник", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Чтобы диагностировать проблемы, журналы работы этого клиента будут отправлены вместе с сообщением об ошибке. Если вы предпочитаете отправить только текст выше, пожалуйста, снимите отметку:", + "Send Custom State Event": "Отправить статус индивидуального мероприятия", + "Remove from Directory": "Удалить из каталога", + "Enable them now": "Включить сейчас", + "Messages containing my user name": "Сообщение, содержащие мое имя пользователя", + "Describe your problem here.": "Опишите вашу проблему здесь.", + "Toolbox": "Панель инструментов", + "Collecting logs": "Сбор журналов", + "more": "больше", + "GitHub issue link:": "Ссылка на проблему в GitHub:", + "Bug report sent": "Отчет об ошибке отправлен", + "You must specify an event type!": "Необходимо указать тип мероприятия!", + "(HTTP status %(httpStatus)s)": "(статус HTTP %(httpStatus)s)", + "Invite to this room": "Пригласить в комнату", + "Please install Chrome or Firefox for the best experience.": "Лучший опыт вы получите, установив Chrome или Firefox.", + "Failed to get public room list": "Не удалось получить список общедоступных комнат", + "Send logs": "Отправка журналов", + "All messages": "Все сообщения", + "Implementing VoIP services with Matrix": "Внедрение VoIP-услуг с помощью Matrix", + "Dev chat for the Riot/Web dev team": "Чат с командой разработчиков Riot/Web", + "Call invitation": "Пригласительный звонок", + "Riot Desktop on %(platformName)s": "Riot Desktop на %(platformName)s", + "Downloading update...": "Загрузка обновления...", + "State Key": "Ключ состояния", + "Failed to send custom event.": "Не удалось отправить индивидуальное мероприятие.", + "What's new?": "Что нового?", + "Discussion of the Identity Service API": "Обсуждение API службы идентификации", + "Support for those using and running matrix-appservice-irc": "Поддержка тех, кто использует и работает с matrix-appservice-irc", + "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk чат", + "Notify me for anything else": "Уведомлять во всех остальных случаях", + "When I'm invited to a room": "Когда меня приглашают в комнату", + "Design and implementation of E2E in Matrix": "Разработка и внедрение сквозного шифрования (E2E) в Matrix", + "Click here to create a GitHub issue.": "Нажмите здесь для создания запроса о проблеме на GitHub.", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Вы можете использовать пользовательские параметры сервера для входа на другие сервера Matrix, указав другой URL-адрес домашнего сервера.
    Это позволяет использовать Riot с существующей учетной записью Matrix на другом домашнем сервере.

    Кроме того, можно установить пользовательский сервер идентификации, однако вы не сможете ни пригласить других пользователей, ни быть приглашенным, используя адрес электронной почты, .", + "Can't update user notification settings": "Не удается обновить пользовательские настройки оповещения", + "Notify for all other messages/rooms": "Уведомлять обо всех других сообщениях/комнатах", + "Unable to look up room ID from server": "Не удалось найти ID комнаты на сервере", + "Couldn't find a matching Matrix room": "Не удалось найти подходящую комнату Matrix", + "Support for those using the Matrix spec": "Поддержка пользователей, использующих Matrix spec", + "Safari and Opera work too.": "Safari и Opera работают тоже.", + "Loading bug report module": "Загрузка модуля Отчет об ошибках", + "All Rooms": "Все комнаты", + "You cannot delete this message. (%(code)s)": "Это сообщение нельзя удалить. (%(code)s)", + "Thursday": "Четверг", + "Forward Message": "Переслать сообщение", + "Logs sent": "Журналы отправлены", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s с %(browserName)s на %(osName)s", + "Back": "Назад", + "Reply": "Ответить", + "Show message in desktop notification": "Показывать сообщение в уведомлении на рабочем столе", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Журналы отладки содержат данные об использовании приложения, включая ваше имя пользователя, идентификаторы или псевдонимы комнат или групп, которые вы посетили, а также имена других пользователей. Они не содержат сообщений.", + "Unhide Preview": "Показать предварительный просмотр", + "Announcements about Synapse releases": "Объявления о выпусках Synapse", + "Search the room directory": "Поиск в каталоге комнат", + "Please describe the bug and/or send logs.": "Опишите ошибку и/или отправьте журналы.", + "Unable to join network": "Не удается подключиться к сети", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Возможно вы настроили их не в Riot, а в другом Matrix-клиенте. Настроить их в Riot не удастся, но они будут в нем применяться", + "Sorry, your browser is not able to run Riot.": "К сожалению, ваш браузер не способен запустить Riot.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Децентрализованный, зашифрованный чат и совместная работа при поддержке [matrix]", + "Building services on Matrix": "Разработка сервисов на Matrix", + "Messages in group chats": "Сообщения в групповых чатах", + "Yesterday": "Вчера", + "Error encountered (%(errorDetail)s).": "Обнаружена ошибка (%(errorDetail)s).", + "Login": "Войти", + "Low Priority": "Низкий приоритет", + "Unable to fetch notification target list": "Не удалось получить список целей уведомления", + "Appear Offline": "Отображать как не в сети", + "Get started with some tips from Riot Bot!": "Начните с некоторых советов от бота Riot!", + "Set Password": "Задать пароль", + "Enable audible notifications in web client": "Включить звуковые уведомления в веб-клиенте", + "Permalink": "Постоянная ссылка", + "Welcome to Riot.im": "Добро пожаловать на Riot.im", + "Off": "Выключить", + "Riot does not know how to join a room on this network": "Riot не знает, как присоединиться к комнате, принадлежащей к этой сети", + "Mentions only": "Только при упоминаниях", + "Wednesday": "Среда", + "You can now return to your account after signing out, and sign in on other devices.": "Теперь вы сможете вернуться к своей учетной записи после выхода из системы и войти на других устройствах.", + "Please install Chrome or Firefox for the best experience.": "Для получения наилучшего опыта при работе с Riot, пожалуйста, установите Chrome или Firefox.", + "Enable email notifications": "Включить уведомления по email", + "Event Type": "Тип мероприятия", + "Download this file": "Скачать этот файл", + "Pin Message": "Закрепить сообщение", + "Failed to change settings": "Не удалось изменить настройки", + "View Community": "Просмотр сообщества", + "%(count)s Members|one": "%(count)s член", + "Event sent!": "Мероприятие отправлено!", + "Matrix technical discussions": "Технические дискуссии о Matrix", + "Event Content": "Содержание мероприятия", + "Thank you!": "Спасибо!", + "Quote": "Цитата", + "Collapse panel": "Свернуть панель", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "В текущем браузере внешний вид приложения может быть полностью неверным, а некоторые или все функции могут не работать. Если вы хотите попробовать в любом случае, то можете продолжить, но с теми проблемами, с которыми вы можете столкнуться вам придется разбираться самостоятельно!", + "Checking for an update...": "Проверка обновлений...", + "General discussion about Matrix and Riot": "Общая дискуссия о Matrix и Riot", + "There are advanced notifications which are not shown here": "Существуют дополнительные уведомления, которые не показаны здесь" } diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index 72ba11b6d4..40e8ea3367 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -1002,5 +1002,205 @@ "Debug Logs Submission": "Odoslanie ladiacich záznamov", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Ak ste nám poslali hlásenie o chybe cez Github, ladiace záznamy nám môžu pomôcť lepšie identifikovať chybu. Ladiace záznamy obsahujú údaje o používaní aplikácii, vrátane vašeho používateľského mena, názvy a aliasy miestností a komunít, ku ktorým ste sa pripojili a mená ostatných používateľov. Tieto záznamy neobsahujú samotný obsah vašich správ.", "Submit debug logs": "Odoslať ladiace záznamy", - "Opens the Developer Tools dialog": "Otvorí dialóg nástroje pre vývojárov" + "Opens the Developer Tools dialog": "Otvorí dialóg nástroje pre vývojárov", + "Fetching third party location failed": "Nepodarilo sa získať umiestnenie tretej strany", + "A new version of Riot is available.": "Dostupná je nová verzia Riot.", + "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk chat", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Prosím, Napíšte text hlásenia. Čo ste práve robili? Čo ste očakávali? Čo sa v skutočnosti udialo?", + "Couldn't load home page": "Nie je možné načítať domovskú stránku", + "Send Account Data": "Odoslať Údaje Účtu", + "All notifications are currently disabled for all targets.": "Momentálne sú zakázané všetky oznámenia pre všetky ciele.", + "Uploading report": "Prebieha odovzdanie hlásenia", + "Sunday": "Nedeľa", + "Notification targets": "Ciele oznámení", + "Today": "Dnes", + "Files": "Súbory", + "Report a bug": "Ohlásiť chybu", + "Implementing VR services with Matrix": "Implementácia služieb VR s Matrix", + "You are not receiving desktop notifications": "Nedostávate oznámenia na pracovnej ploche", + "Friday": "Piatok", + "Update": "Aktualizovať", + "You need to be using HTTPS to place a screen-sharing call.": "Ak si želáte spustiť zdieľanie obrazovky, musíte byť pripojení cez protokol HTTPS.", + "Unable to fetch notification target list": "Nie je možné získať zoznam cieľov oznámení", + "Add an email address above to configure email notifications": "Ak si chcete nastaviť oznamovanie emailom, pridajte si emailovú adresu vyššie", + "Expand panel": "Rozbaliť panel", + "On": "Povolené", + "%(count)s Members|other": "%(count)s Členov", + "Filter room names": "Filtrovať názvy miestností", + "Changelog": "Zoznam zmien", + "Running Matrix services": "Prevádzka služieb postavených na Matrix", + "Waiting for response from server": "Čakanie na odpoveď zo servera", + "Uploaded on %(date)s by %(user)s": "Nahral používateľ %(user)s dňa %(date)s", + "Send Custom Event": "Odoslať vlastnú udalosť", + "Failed to send report: ": "Nepodarilo sa odoslať hlásenie: ", + "Unknown device": "Neznáme zariadenie", + "Advanced notification settings": "Pokročilé nastavenia oznámení", + "Failed to send logs: ": "Nepodarilo sa odoslať záznamy: ", + "delete the alias.": "vymazať alias.", + "To return to your account in future you need to set a password": "Aby ste sa v budúcnosti mohli vrátiť k vašemu účtu mali by ste si teraz nastaviť heslo", + "Forget": "Zabudnuť", + "Riot/Web & Desktop chat": "Riot/Web & Desktop chat", + "Hide panel": "Skryť panel", + "You cannot delete this image. (%(code)s)": "Nemôžete vymazať tento obrázok. (%(code)s)", + "Cancel Sending": "Zrušiť odosielanie", + "This Room": "V tejto miestnosti", + "Get started with some tips from Riot Bot!": "Začnite zopár tipmi v diskusii s Riot Bot!", + "The Home Server may be too old to support third party networks": "Domovský server môže byť natoľko zastaralý, že nepodporuje siete tretíh strán", + "Resend": "Poslať znovu", + "Room not found": "Miestnosť nenájdená", + "Downloading update...": "Sťahovanie aktualizácie...", + "Messages in one-to-one chats": "Správy v priamych konverzáciách", + "Contributing code to Matrix and Riot": "Prispievanie kódu projektom Matrix a Riot", + "Unavailable": "Nedostupné", + "Community-run support for Synapse": "Komunitná podpora pre Synapse", + "View Decrypted Source": "Zobraziť dešifrovaný zdroj", + "Failed to update keywords": "Nepodarilo sa aktualizovať kľúčové slová", + "Notes:": "Poznámky:", + "remove %(name)s from the directory.": "odstrániť %(name)s z adresára.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Oznámenia nasledujúcich kľúčových slov sa riadia pravidlami, ktoré nie je možné zobraziť na tomto mieste:", + "Safari and Opera work too.": "Správne fungujú aj Safari a Opera.", + "Please set a password!": "Prosím, nastavte si heslo!", + "You have successfully set a password!": "Ǔspešne ste si nastavili heslo!", + "Chat with Riot Bot": "Konverzácia s Riot Bot", + "Support for those using, running and writing other bridges": "Podpora pre používateľov, prevádzkovateľov a tvorcov premostení do ďalších sietí", + "Admin support for Dendrite": "Administrátorská podpora pre Dendrite", + "Explore Room State": "Preskúmať Stav Miestnosti", + "Source URL": "Pôvodná URL", + "Messages sent by bot": "Správy odosielané robotmi", + "Filter results": "Filtrovať výsledky", + "Members": "Členovia", + "No update available.": "K dispozícii nie je žiadna aktualizácia.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Na Matrixe je k dispozícii množstvo nezávislých diskusných miestností a tiež miestnosti prepojené z iných sietí (Slack, IRC, Gitter atď). Pozrite si adresár!", + "Noisy": "Hlučné", + "Failed to get protocol list from Home Server": "Nepodarilo sa získať zoznam protokolov z domovského servera", + "Collecting app version information": "Získavajú sa informácie o verzii aplikácii", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Vymazať alias %(alias)s a odstrániť miestnosť %(name)s z adresára?", + "Co-ordination for Riot/Web translators": "Koordinácia prekladov Riot/Web", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Toto vám v budúcnosti umožní vrátiť sa k vašemu účtu aj po odhlásení, alebo tiež prihlásiť sa na iných zariadeniach.", + "Dev chat for the Dendrite dev team": "Diskusia pre tím vývojárov Dendrite", + "Keywords": "Kľúčové slová", + "Enable notifications for this account": "Povoliť oznámenia pre tento účet", + "Directory": "Adresár", + "Invite to this community": "Pozvať do tejto komunity", + "Failed to get public room list": "Nepodarilo sa získať zoznam verejných miestností", + "Search…": "Hľadať…", + "Messages containing keywords": "Správy obsahujúce kľúčové slová", + "Error saving email notification preferences": "Chyba pri ukladaní nastavení oznamovania emailom", + "Tuesday": "Utorok", + "Enter keywords separated by a comma:": "Zadajte kľúčové slová oddelené čiarkou:", + "Forward Message": "Preposlať správu", + "Remove %(name)s from the directory?": "Odstrániť miestnosť %(name)s z adresára?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot sa spolieha na mnohé pokročilé vlastnosti prehliadača internetu, a niektoré z nich sú vo vašom prehliadači experimentálne alebo nie sú k dispozícii vôbec.", + "Event sent!": "Udalosť odoslaná!", + "Preparing to send logs": "príprava odoslania záznamov", + "Enable desktop notifications": "Povoliť oznámenia na pracovnej ploche", + "Explore Account Data": "Preskúmať Údaje účtu", + "All messages (noisy)": "Všetky správy (hlučné)", + "Away": "Preč", + "Saturday": "Sobota", + "Remember, you can always set an email address in user settings if you change your mind.": "Všimnite si, Emailovú adresu môžete pridať aj neskôr v časti nastavenia, ak zmeníte svoj názor.", + "Direct Chat": "Priama konverzácia", + "The server may be unavailable or overloaded": "Server môže byť nedostupný alebo preťažený", + "Reject": "Odmietnuť", + "Riot is not supported on mobile web. Install the app?": "Riot nie je podporovaný na mobilných zariadeniach. Želáte si nainštalovať aplikáciu?", + "Discussion of all things Matrix!": "Diskusia o všetkom okolo Matrix!", + "Failed to set Direct Message status of room": "Nepodarilo sa nastaviť stav miestnosti priama konverzácia", + "Monday": "Pondelok", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "S cieľom lepšej diagnostiky problému sa spolu s vašim hlásením odošlú záznami o činnosti programu Riot. Ak si želáte odoslať len text hlásenia, odškrtnite nasledujúce pole:", + "Remove from Directory": "Odstrániť z adresára", + "Enable them now": "Povolte si ich teraz", + "Messages containing my user name": "Správy obsahujúce moje používateľské meno", + "Describe your problem here.": "Tu popíšte váš problém.", + "Toolbox": "Nástroje", + "Collecting logs": "Získavajú sa záznamy", + "more": "viac", + "GitHub issue link:": "Odkaz hlásenia na Github:", + "Search for a room": "Vyhľadať miestnosť", + "You must specify an event type!": "Musíte nastaviť typ udalosti!", + "(HTTP status %(httpStatus)s)": "(HTTP status %(httpStatus)s)", + "All Rooms": "Vo všetkych miestnostiach", + "State Key": "State Key", + "Please install Chrome or Firefox for the best experience.": "Aby ste s používania mali čo možno najlepší dojem, nainštalujte si Chrome alebo Firefox.", + "Wednesday": "Streda", + "Quote": "Citácia", + "Send logs": "Zahrnúť záznamy", + "All messages": "Všetky správy", + "Implementing VoIP services with Matrix": "Implementácia VoIP služieb s Matrix", + "Dev chat for the Riot/Web dev team": "Diskusia pre tím vývojárov Riot/Web", + "Call invitation": "Audio / Video hovory", + "Riot Desktop on %(platformName)s": "Riot Desktop pre %(platformName)s", + "Messages containing my display name": "Správy obsahujúce moje zobrazované meno", + "You have successfully set a password and an email address!": "Úspešne si si nastavili heslo aj emailovú adresu!", + "Failed to send custom event.": "Odoslanie vlastnej udalosti zlyhalo.", + "What's new?": "Čo je nové?", + "Discussion of the Identity Service API": "Diskusia o API služby totožností", + "Support for those using and running matrix-appservice-irc": "Podpora pre používateľov a prevádzkovateľov matrix-appservice-irc", + "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk chat", + "Notify me for anything else": "Oznamovať mi všetko ostatné", + "When I'm invited to a room": "Pozvania vstúpiť do miestnosti", + "Design and implementation of E2E in Matrix": "Návrh a implementácia E2E pre Matrix", + "Click here to create a GitHub issue.": "Kliknutím sem nám pošlete hlásenie o chybe cez Github.", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Vlastné nastavenia servera môžete použiť na pripojenie k iným serverom Matrix a to zadaním URL adresy domovského servera.
    Umožní vám to použiť Riot s už existujúcim Matrix účtom na akomkoľvek domovskom servery.

    Môžete tiež nastaviť vlastný server totožností, no ak tak urobíte, nebudete môcť do konverzácií pozývať používateľov zadaním ich emailovej adresy, ani ostatní nebudú môcť pozvať vás zadaním vašej emailovej adresy.", + "Can't update user notification settings": "Nie je možné aktualizovať používateľské nastavenia oznamovania", + "Notify for all other messages/rooms": "oznamovať všetky ostatné správy / miestnosti", + "Unable to look up room ID from server": "Nie je možné vyhľadať ID miestnosti na servery", + "Couldn't find a matching Matrix room": "Nie je možné nájsť zodpovedajúcu Matrix miestnosť", + "Bug report sent": "Hlásenie chyby odoslané", + "Safari and Opera work too.": "Safari a Opera tiež fungujú spoľahlivo.", + "Loading bug report module": "Načítanie modulu hlásenia chýb", + "Invite to this room": "Pozvať do tejto miestnosti", + "You cannot delete this message. (%(code)s)": "Nemôžete vymazať túto správu. (%(code)s)", + "Thursday": "Štvrtok", + "I understand the risks and wish to continue": "Rozumiem rizikám a želám si pokračovať", + "Logs sent": "Záznamy boli odoslané", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s cez %(browserName)s pre %(osName)s", + "Back": "Naspäť", + "Reply": "Odpovedať", + "Show message in desktop notification": "Zobraziť text správy v oznámení na pracovnej ploche", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Ladiace záznamy obsahujú údaje o používaní aplikácii, vrátane vašeho používateľského mena, názvy a aliasy miestností a komunít, ku ktorým ste sa pripojili a mená ostatných používateľov. Tieto záznamy neobsahujú samotný obsah vašich správ.", + "Unhide Preview": "Zobraziť náhľad", + "Announcements about Synapse releases": "Oznamy o verziách Synapse", + "Search the room directory": "Prehľadať adresár miestností", + "Please describe the bug and/or send logs.": "Prosím, popíšte problém a / alebo pošlite záznamy.", + "Unable to join network": "Nie je možné sa pripojiť k sieti", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Tieto nastavenia oznámení sa použijú aj napriek tomu, že ich nemôžete meniť cez Riot. Pravdepodobne ste si ich nastavili v inej aplikácii", + "Sorry, your browser is not able to run Riot.": "Prepáčte, vo vašom prehliadači nie je možné spustiť Riot.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Decentralizovaný, šifrovaný chat a spolupráca na platforme [matrix]", + "Building services on Matrix": "Stavba služieb na Matrix", + "Messages in group chats": "Správy v skupinových konverzáciách", + "Yesterday": "Včera", + "Error encountered (%(errorDetail)s).": "Vyskytla sa chyba (%(errorDetail)s).", + "Event Type": "Typ Udalosti", + "Low Priority": "Nízka priorita", + "What's New": "Čo Je Nové", + "Set Password": "Nastaviť Heslo", + "Appear Offline": "Zdá sa byť nedostupný", + "Support for those using the Matrix spec": "Podpora pre konzumentov špecifikácie Matrix", + "An error occurred whilst saving your email notification preferences.": "Počas ukladania vašich nastavení oznamovania emailom sa vyskytla chyba.", + "Enable audible notifications in web client": "Povoliť zvukové oznámenia vo webovom klientovi", + "Permalink": "Trvalý odkaz", + "Welcome to Riot.im": "Víta vás Riot.im", + "Off": "Zakázané", + "Riot does not know how to join a room on this network": "Riot nedokáže vstúpiť do miestnosti na tejto sieti", + "Mentions only": "Len zmienky", + "You can now return to your account after signing out, and sign in on other devices.": "Odteraz sa budete k svojmu účtu vedieť vrátiť aj po odhlásení, alebo tiež prihlásiť na iných zariadeniach.", + "Please install Chrome or Firefox for the best experience.": "Prosím, nainštalujte si Chrome alebo Firefox , aby bol váš zážitok pri používaní Riot čo možno najlepší.", + "Enable email notifications": "Povoliť oznamovanie emailom", + "Login": "Prihlásiť", + "Download this file": "Stiahnuť tento súbor", + "Pin Message": "Pripnúť správu", + "Failed to change settings": "Nepodarilo sa zmeniť nastavenia", + "View Community": "Zobraziť komunitu", + "%(count)s Members|one": "%(count)s Člen", + "Developer Tools": "Vývojárske Nástroje", + "View Source": "Zobraziť zdroj", + "Matrix technical discussions": "Technické diskusie o Matrix", + "Event Content": "Obsah Udalosti", + "Thank you!": "Ďakujeme!", + "#example": "#príklad", + "Collapse panel": "Zbaliť panel", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Vo vašom súčasnom prehliadači nemusí Riot vizerať ani fungovať správne a niektoré alebo všetky vlastnosti môžu chýbať. Ak to chcete vyskúšať, môžete pokračovať, no pri riešení problémov s tým spojených si budete musieť poradiť na vlastnú päsť!", + "Checking for an update...": "Kontrola dostupnosti aktualizácie...", + "General discussion about Matrix and Riot": "Všeobecná diskusia o Matrix a Riot", + "There are advanced notifications which are not shown here": "Niektoré pokročilé oznámenia nemôžu byť zobrazené" } diff --git a/src/i18n/strings/sq.json b/src/i18n/strings/sq.json index 3d8e6553ed..8ec4b34c27 100644 --- a/src/i18n/strings/sq.json +++ b/src/i18n/strings/sq.json @@ -116,5 +116,224 @@ "Unrecognised room alias:": "Emri i dhomës të panjohur:", "Ignored user": "Përdoruesë të shpërfillur", "You are now ignoring %(userId)s": "Tash %(userId)s shpërfillet prej teje", - "Unignored user": "Përdorues jo më i shpërfillur" + "Unignored user": "Përdorues jo më i shpërfillur", + "Fetching third party location failed": "Dështoi prurja e vendndodhjes së palës së tretë", + "A new version of Riot is available.": "Ka gati një version të ri Riot-it.", + "Riot/Android & matrix-android-sdk chat": "Fjalosje mbi Riot/Android & matrix-android-sdk", + "Couldn't load home page": "S’u ngarkua dot faqja hyrëse", + "Send Account Data": "Dërgo të Dhëna Llogarie", + "All notifications are currently disabled for all targets.": "Krejt njoftimet hëpërhë janë çaktivizuar për krejt objektivat.", + "Uploading report": "Po ngarkohet raporti", + "Sunday": "E diel", + "Guests can join": "Vizitorët mund të marrin pjesë", + "Notification targets": "Objektiva njoftimesh", + "Today": "Sot", + "Files": "Kartela", + "Implementing VR services with Matrix": "Sendërtim shërbimesh VR me Matrix-in", + "You are not receiving desktop notifications": "Nuk po merrni njoftime për desktop", + "Friday": "E premte", + "Update": "Përditësoje", + "Notifications": "Njoftime", + "You need to be using HTTPS to place a screen-sharing call.": "Që të bëni një thirrje me ndarje ekrani, duhet të jeni duke përdorur HTTPS-në.", + "Unable to fetch notification target list": "S’arrihet të sillet listë objektivash njoftimi", + "Add an email address above to configure email notifications": "Shtoni më sipër një adresë email që të formësoni njoftime me email", + "Expand panel": "Zgjerojeni panelin", + "On": "On", + "%(count)s Members|other": "%(count)s Anëtarë", + "Filter room names": "Filtroni emra dhomash", + "Changelog": "Regjistër ndryshimesh", + "Reject": "Hidheni tej", + "Running Matrix services": "Xhirim shërbimesh Matrix", + "Waiting for response from server": "Po pritet për përgjigje shërbyesi", + "Failed to change password. Is your password correct?": "S’u arrit të ndryshohet fjalëkalimi. A është i saktë fjalëkalimi juaj?", + "Uploaded on %(date)s by %(user)s": "Ngarkuar më %(date)s nga %(user)s", + "OK": "OK", + "Send Custom Event": "Dërgoni Akt Vetjak", + "Unknown device": "Pajisje e panjohur", + "Advanced notification settings": "Rregullime të mëtejshme për njoftimet", + "Failed to send logs: ": "S’u arrit të dërgohen regjistra: ", + "delete the alias.": "fshije aliasin.", + "To return to your account in future you need to set a password": "Që të riktheheni te llogaria juaj në të ardhmen, lypset të caktoni një fjalëkalim", + "Forget": "Harroje", + "World readable": "E lexueshme nga bota", + "Mute": "Pa Zë", + "Riot/Web & Desktop chat": "Fjalosje mbi Riot/Web & Desktop", + "Hide panel": "Fshihe panelin", + "You cannot delete this image. (%(code)s)": "S’mund ta fshini këtë figurë. (%(code)s)", + "Cancel Sending": "Anuloje Dërgimin", + "Warning": "Sinjalizim", + "This Room": "Këtë Dhomë", + "The Home Server may be too old to support third party networks": "Shërbyesi Home mund të jetë shumë i vjetër për të mbuluar rrjete nga palë të treta", + "Resend": "Ridërgoje", + "Room not found": "Dhoma s’u gjet", + "Downloading update...": "Po shkarkohet përditësim…", + "Messages in one-to-one chats": "Mesazhe në fjalosje tek për tek", + "Contributing code to Matrix and Riot": "Kontribut me kod te Matrix dhe te Riot", + "Unavailable": "S’kapet", + "Community-run support for Synapse": "Asistencë për Synapse-in nga bashkësia", + "View Decrypted Source": "Shihni Burim të Shfshehtëzuar", + "Failed to update keywords": "S’u arrit të përditësohen fjalëkyçe", + "Notes:": "Shënime:", + "Welcome to Riot.im": "Mirë se vini te Riot.im", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Njoftimet e shkaktuara nga fjalëkyçet vijuese ndjekin rregulla që s’mund të shfaqen këtu:", + "Safari and Opera work too.": "Safari dhe Opera bëjnë, po ashtu.", + "Please set a password!": "Ju lutemi, caktoni një fjalëkalim!", + "powered by Matrix": "bazuar në Matrix", + "You have successfully set a password!": "Caktuat me sukses një fjalëkalim!", + "Chat with Riot Bot": "Fjalosuni me Robotin Riot", + "Support for those using, running and writing other bridges": "Asistencë për ata që përdorin, xhirojnë ose programojnë ura të tjera", + "Admin support for Dendrite": "Asistencë përgjegjësi për Dendrite-in", + "Favourite": "E parapëlqyer", + "All Rooms": "Krejt Dhomat", + "Explore Room State": "Eksploroni Gjendje Dhome", + "Source URL": "URL-ja e Burimit", + "Messages sent by bot": "Mesazhe të dërguar nga bot", + "Cancel": "Anuloje", + "Filter results": "Filtroni përfundimet", + "Members": "Anëtarë", + "No update available.": "S’ka përditësim gati.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Ka tashmë plot dhoma në Matrix, të lidhura me rrjete ekzistues (Slack, IRC, Gitter, etj) ose të pavarur. Hidhini një sy listës!", + "Noisy": "I zhurmshëm", + "Failed to get protocol list from Home Server": "S’u arrit të merrej listë protokollesh nga Shërbyesi Home", + "Collecting app version information": "Po grumbullohen të dhëna versioni aplikacioni", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Të fshihet aliasi i dhomës %(alias)s dhe të hiqet %(name)s nga drejtoria?", + "Co-ordination for Riot/Web translators": "Bashkërendim për përkthyesit e Riot/Web-it", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Kjo do t’ju lejojë të riktheheni te llogaria juaj pasi të keni bërë daljen, dhe të hyni që nga pajisje të tjera.", + "Dev chat for the Dendrite dev team": "Fjalosje zhvillimi, për ekipin e zhvilluesve të Dendrite-it", + "Keywords": "Fjalëkyçe", + "Unpin Message": "Shfiksojeni Mesazhin", + "Enable notifications for this account": "Aktivizo njoftime për këtë llogari", + "Remove": "Hiqe", + "Directory": "Drejtori", + "Invite to this community": "Ftojeni te kjo bashkësi", + "Search for a room": "Kërkoni për një dhomë", + "Search…": "Kërkoni…", + "Messages containing keywords": "Mesazhe që përmbajnë fjalëkyçe", + "Error saving email notification preferences": "Gabim në ruajtje parapëlqimesh për njoftime me email", + "Tuesday": "E martë", + "Enter keywords separated by a comma:": "Jepni fjalëkyçe ndarë me presje:", + "Forward Message": "Përcille Mesazhin", + "You have successfully set a password and an email address!": "Keni caktuar me sukses një fjalëkalim dhe një adresë email!", + "Remove %(name)s from the directory?": "Të hiqet %(name)s prej drejtorisë?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot-i përdor mjaft veçori të përparuara të shfletuesve, disa prej të cilave s’janë gati ose janë eksperimentale në shfletuesin tuaj të tanishëm.", + "Event sent!": "Akti u dërgua!", + "Preparing to send logs": "Po përgatitet për dërgim regjistrash", + "Unnamed room": "Dhomë e paemërtuar", + "Dismiss": "Mos e merr parasysh", + "Explore Account Data": "Eksploroni të Dhëna Llogarie", + "All messages (noisy)": "Tërë Mesazhet (e zhurmshme)", + "Away": "Larguar", + "Saturday": "E shtunë", + "Remember, you can always set an email address in user settings if you change your mind.": "Mos harroni, mundeni përherë të caktoni një adresë email te rregullimet e përdoruesit, nëse ndërroni mendje.", + "Direct Chat": "Fjalosje e Drejtpërdrejtë", + "The server may be unavailable or overloaded": "Shërbyesi mund të jetë i pakapshëm ose i mbingarkuar", + "Online": "Në linjë", + "Riot is not supported on mobile web. Install the app?": "Riot-i nuk mbulohet nën web për celularët. Të instalohet aplikacioni?", + "Discussion of all things Matrix!": "Diskutime mbi gjithçka të lidhur me Matrix-in!", + "Failed to set Direct Message status of room": "S’u arrit të caktohej gjendje Mesazhesh të Drejtpërdrejtë në dhomë", + "Monday": "E hënë", + "Download this file": "Shkarkoje këtë kartelë", + "Remove from Directory": "Hiqe prej Drejtorie", + "Enable them now": "Aktivizoji tani", + "Messages containing my user name": "Mesazhe që përmbajnë emrin tim", + "Toolbox": "Grup mjetesh", + "Collecting logs": "Po grumbullohen regjistra", + "more": "më tepër", + "GitHub issue link:": "Lidhje çështjeje GitHub:", + "Failed to get public room list": "S’u të merrej listë dhomash publike", + "Search": "Kërkim", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Regjistrat e diagnostikimeve përmbajnë të dhëna përdorimi të aplikacioneve, përfshi emrin tuaj të përdoruesit, ID ose aliase të dhomave apo grupeve që keni vizituar dhe emrat e përdoruesve të përdoruesve të tjerë. Nuk përmbajnë mesazhe.", + "(HTTP status %(httpStatus)s)": "(Gjendje HTTP %(httpStatus)s)", + "Failed to forget room %(errCode)s": "S’u arrit të harrohej dhoma %(errCode)s", + "Submit debug logs": "Parashtro regjistra diagnostikimi", + "Please install Chrome or Firefox for the best experience.": "Ju lutemi, për funksionimin më të mirë, instaloni Chrome ose Firefox.", + "Wednesday": "E mërkurë", + "Quote": "Citim", + "Error": "Gabim", + "Send logs": "Dërgo regjistra", + "All messages": "Krejt mesazhet", + "unknown error code": "kod gabimi të panjohur", + "Implementing VoIP services with Matrix": "Sendërtim shërbimesh VoIP me Matrix-in", + "Dev chat for the Riot/Web dev team": "Fjalosje mbi zhvillimin, për ekipin e zhvilluesve të Riot/Web-i", + "Call invitation": "Ftesë për thirrje", + "Thank you!": "Faleminderit!", + "Riot Desktop on %(platformName)s": "Riot Desktop në %(platformName)s", + "Messages containing my display name": "Mesazhe që përmbajnë emrin tim të ekranit", + "State Key": "Kyç Gjendjeje", + "Failed to send custom event.": "S’u arrit të dërgohet akt vetjak.", + "What's new?": "Ç’ka të re?", + "Discussion of the Identity Service API": "Diskutime mbi Identity Service API", + "Support for those using and running matrix-appservice-irc": "Asistencë për ata që përdorin dhe xhirojnë matrix-appservice-irc", + "Riot/iOS & matrix-ios-sdk chat": "Fjalosje mbi Riot/iOS & matrix-android-sdk", + "Notify me for anything else": "Njoftomë për gjithçka tjetër", + "When I'm invited to a room": "Kur ftohem në një dhomë", + "Design and implementation of E2E in Matrix": "Konceptimi dhe sendërtimi i E2E në Matrix", + "Close": "Mbylle", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Mund t’i përdorni mundësitë e shërbyesit vetjak për të hyrë në shërbyes të tjerë Matrix, duke dhënë URL-në e një tjetër shërbyesi Home.
    Kjo ju lejon ta përdorni Riot-in me një llogari Matrix ekzistuese në një tjetër shërbyes vatër.

    Mundeni edhe të caktoni një shërbyes vetjak identitetesh, por s’do të jeni në gjendje të ftoni përdorues përmes adresash email, ose të ftoheni ju vetëm përmes adrese email.", + "Can't update user notification settings": "S’përditësohen dot rregullime njoftimi të përdoruesit", + "Notify for all other messages/rooms": "Njoftim për krejt mesazhet/dhomat e tjera", + "Unable to look up room ID from server": "S’arrihet të kërkohet ID dhome nga shërbyesi", + "Click here to create a GitHub issue.": "Klikoni këtu që të hapni një çështje në GitHub.", + "Couldn't find a matching Matrix room": "S’u gjet dot një dhomë Matrix me përputhje", + "Support for those using the Matrix spec": "Asistencë për ata që përdorin specifikimet Matrix", + "Invite to this room": "Ftoje te kjo dhomë", + "You cannot delete this message. (%(code)s)": "S’mund ta fshini këtë mesazh. (%(code)s)", + "Thursday": "E enjte", + "I understand the risks and wish to continue": "I kuptoj rreziqet dhe dua të vazhdoj", + "Logs sent": "Regjistrat u dërguan", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s përmes %(browserName)s nën %(osName)s", + "Back": "Mbrapsht", + "Reply": "Përgjigjuni", + "Show message in desktop notification": "Shfaq mesazh në njoftim për desktop", + "You must specify an event type!": "Duhet të përcaktoni një lloj akti!", + "Unhide Preview": "Shfshihe Paraparjen", + "Announcements about Synapse releases": "Njoftime rreth hedhjesh në qarkullim të Synapse-it", + "Search the room directory": "Kërkoni te drejtoria e dhomave", + "Unable to join network": "S’arrihet të hyhet në rrjet", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Mund t’i keni formësuar në një tjetër klient nga Riot-i. S’mund t’i sintonizoni në Riot, por ata janë ende të vlefshëm", + "Sorry, your browser is not able to run Riot.": "Na ndjeni, shfletuesi juaj nuk është në gjendje të xhirojë Riot-in.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Decentralised, encrypted Fjalosje & bashkëpunim i decentralizuar, i fshehtëzuar, bazuar në [matrix]", + "Building services on Matrix": "Ndërtim shërbimesh mbi Matrix", + "Messages in group chats": "Mesazhe në fjalosje në grup", + "Yesterday": "Dje", + "Error encountered (%(errorDetail)s).": "U has gabim (%(errorDetail)s).", + "Event Type": "Lloj Akti", + "Low Priority": "Përparësi e Ulët", + "What's New": "Ç’ka të Re", + "Set Password": "Caktoni Fjalëkalim", + "Appear Offline": "Shfaqju Si Jo Në Linjë", + "Get started with some tips from Riot Bot!": "Fillojani me disa ndihmëza nga Roboti Riot!", + "An error occurred whilst saving your email notification preferences.": "Ndodhi një gabim teksa ruheshin parapëlqimet tuaja për njoftime me email.", + "Enable audible notifications in web client": "Aktivizoni njoftime audio te klienti web", + "Permalink": "Permalidhje", + "Register": "Regjistrohuni", + "Off": "Off", + "Edit": "Përpunoni", + "Riot does not know how to join a room on this network": "Riot-i nuk di si të hyjë në një dhomë në këtë rrjet", + "Mentions only": "Vetëm @përmendje", + "remove %(name)s from the directory.": "hiqe %(name)s prej drejtorie.", + "You can now return to your account after signing out, and sign in on other devices.": "Mund të ktheheni te llogaria juaj, pasi të keni bërë daljen, dhe të bëni hyrjen nga pajisje të tjera.", + "Continue": "Vazhdo", + "Enable desktop notifications": "Aktivizo njoftime në desktop", + "Enable email notifications": "Aktivizo njoftime me email", + "Login": "Hyrje", + "No rooms to show": "S’ka dhoma për shfaqje", + "Add rooms to this community": "Shtoni dhoma te kjo bashkësi", + "Pin Message": "Fiksojeni Mesazhin", + "Failed to change settings": "S’u arrit të ndryshoheshin rregullimet", + "Leave": "Dilni", + "View Community": "Shihni Bashkësinë", + "%(count)s Members|one": "%(count)s Anëtar", + "Developer Tools": "Mjete Zhvilluesi", + "View Source": "Shihini Burimin", + "General discussion about Matrix and Riot": "Diskutime të përgjithshme mbi Matrix-in dhe Riot-in", + "Custom Server Options": "Mundësi Vetjake Shërbyesi", + "Event Content": "Lëndë Akti", + "Rooms": "Dhoma", + "#example": "#shembull", + "Collapse panel": "Tkurre panelin", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Me shfletuesin tuaj të tanishëm, pamja dhe ndjesitë nga aplikacioni mund të jenë plotësisht të pasakta, dhe disa nga ose krejt veçoritë të mos funksionojnë. Nëse doni ta provoni sido qoftë, mund të vazhdoni, por mos u ankoni për çfarëdo problemesh që mund të hasni!", + "Checking for an update...": "Po kontrollohet për një përditësim…", + "Matrix technical discussions": "Diskutime teknike rreth Matrix-it", + "There are advanced notifications which are not shown here": "Ka njoftime të thelluara që nuk shfaqen këtu" } diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index a6d8ab8540..05f50d49a0 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -994,5 +994,196 @@ "Key request sent.": "Захтев за дељење кључа послат.", "Re-request encryption keys from your other devices.": "Поново затражи кључеве за шифровање са осталих ваших уређаја.", "%(user)s is a %(userRole)s": "Корисник %(user)s је у улози %(userRole)s", - "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Да бисте поставили филтер, повуците аватар заједнице на површ филтрирања скроз на леву страну екрана. Можете кликнути на аватар у површи филтрирања било када да бисте видели само собе и особе везане за ту заједницу." + "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Да бисте поставили филтер, повуците аватар заједнице на површ филтрирања скроз на леву страну екрана. Можете кликнути на аватар у површи филтрирања било када да бисте видели само собе и особе везане за ту заједницу.", + "Fetching third party location failed": "Добављање локације треће стране није успело", + "A new version of Riot is available.": "Ново издање RIot-а је доступно.", + "Riot/Android & matrix-android-sdk chat": "Riot/Андроид и matrix-android-sdk ћаскање", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Опишите грешку. Шта сте урадили? Шта сте очекивали да се догоди? Шта се заправо догодило?", + "Couldn't load home page": "Нисам могао да учитам почетну страну", + "Send Account Data": "Пошаљи податке налога", + "All notifications are currently disabled for all targets.": "Сва обавештења су тренутно онемогућена за све циљеве.", + "Uploading report": "Отпремам извештај", + "Sunday": "Недеља", + "Notification targets": "Циљеви обавештења", + "Today": "Данас", + "Files": "Датотеке", + "Report a bug": "Пријави грешку", + "Implementing VR services with Matrix": "Израда услуга за ВР уз Матрикс", + "You are not receiving desktop notifications": "Не примате стона обавештења", + "Friday": "Петак", + "Update": "Ажурирај", + "You need to be using HTTPS to place a screen-sharing call.": "Морате користити HTTPS да бисте започели позив са дељењем екрана.", + "Unable to fetch notification target list": "Не могу да досегнем списак циљева за обавештења", + "Add an email address above to configure email notifications": "Додајте мејл адресу изнад да бисте подесили мејл обавештења", + "Expand panel": "Прошири површ", + "On": "Укључено", + "%(count)s Members|other": "%(count)s чланова", + "Filter room names": "Филтрирај називе соба", + "Changelog": "Записник о изменама", + "Running Matrix services": "Покренуте Матрикс услуге", + "Waiting for response from server": "Чекам на одговор са сервера", + "Uploaded on %(date)s by %(user)s": "Отпремљено датума %(date)s од корисника %(user)s", + "Send Custom Event": "Пошаљи прилагођени догађај", + "Failed to send report: ": "Нисам успео да пошаљем извештај: ", + "Off": "Искључено", + "Unknown device": "Непознати уређај", + "Advanced notification settings": "Напредна подешавања обавештења", + "delete the alias.": "обриши алијас.", + "To return to your account in future you need to set a password": "Да бисте се вратили на ваш налог у будућности, морате поставити лозинку", + "Forget": "Заборави", + "Riot/Web & Desktop chat": "Riot/веб и стоно ћаскање", + "Hide panel": "Сакриј површ", + "You cannot delete this image. (%(code)s)": "Не можете обрисати ову слику. (%(code)s)", + "Cancel Sending": "Откажи слање", + "This Room": "Ова соба", + "Get started with some tips from Riot Bot!": "Крените уз пар савета од Riot бота!", + "The Home Server may be too old to support third party networks": "Кућни сервер је можда сувише застарео да би подржао мреже трећих страна", + "All messages (loud)": "Све поруке (гласно)", + "Room not found": "Соба није пронађена", + "Downloading update...": "Преузимам ажурирање...", + "Messages in one-to-one chats": "Поруке у један-на-један ћаскањима", + "Contributing code to Matrix and Riot": "Додавање кода у Матрикс и Riot", + "Unavailable": "Недоступан", + "Community-run support for Synapse": "Подршка од стране заједнице за Synapse", + "View Decrypted Source": "Погледај дешифровани извор", + "Failed to update keywords": "Нисам успео да ажурирам кључне речи", + "remove %(name)s from the directory.": "уклони %(name)s из фасцикле.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Обавештења за следеће кључне речи прате правила која не могу бити приказана овде:", + "Safari and Opera work too.": "Сафари и Опера такође раде.", + "Please set a password!": "Поставите лозинку!", + "You have successfully set a password!": "Успешно сте поставили лозинку!", + "Chat with Riot Bot": "Ћаскајте са Riot ботом", + "Support for those using, running and writing other bridges": "Подршка за оне који користе, одржавају и пишу друге мостове", + "Admin support for Dendrite": "Администраторска подршка за Dendrite", + "Explore Room State": "Истражи стање собе", + "Source URL": "Адреса извора", + "Messages sent by bot": "Поруке послате од бота", + "Filter results": "Филтрирај резултате", + "Members": "Чланови", + "No update available.": "Нема нових ажурирања.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Много соба већ постоји у Матриксу, неке су повезане на постојеће мреже (Slack, IRC, Gitter итд.) а неке независне. Погледајте фасциклу!", + "Noisy": "Бучно", + "Failed to get protocol list from Home Server": "Нисам успео да добијем списак протокола од кућног сервера", + "Collecting app version information": "Прикупљам податке о издању апликације", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Обрисати алијас собе %(alias)s и уклонити %(name)s из фасцикле?", + "Co-ordination for Riot/Web translators": "Координација за Riot/веб преводиоце", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Ово ће вам омогућити да се вратите у ваш налог након што се одјавите и пријавите, на другим уређајима.", + "Dev chat for the Dendrite dev team": "Програмерско ћаскање за Dendrite програмерски тим", + "Keywords": "Кључне речи", + "Enable notifications for this account": "Омогући обавештења за овај налог", + "Directory": "Фасцикла", + "Invite to this community": "Позови у ову заједницу", + "Failed to get public room list": "Нисам успео да добавим списак јавних соба", + "Search…": "Претрага…", + "Messages containing keywords": "Поруке које садрже кључне речи", + "Error saving email notification preferences": "Грешка при чувању поставки мејл обавештења", + "Tuesday": "Уторак", + "Enter keywords separated by a comma:": "Унесите кључне речи одвојене зарезима:", + "Forward Message": "Проследи поруку", + "Remove %(name)s from the directory?": "Уклонити %(name)s из фасцикле?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot користи напредне могућности прегледача од којих неке нису доступне или су у пробној фази, у вашем прегледачу.", + "Event sent!": "Догађај је послат!", + "Explore Account Data": "Истражи податке налога", + "All messages (noisy)": "Све поруке (гласно)", + "Away": "Одустан", + "Saturday": "Субота", + "Remember, you can always set an email address in user settings if you change your mind.": "Запамтите, увек можете поставити мејл адресу у корисничким подешавањима, уколико се предомислите.", + "Direct Chat": "Директно ћаскање", + "The server may be unavailable or overloaded": "Сервер је можда недоступан или преоптерећен", + "Reject": "Одбаци", + "Riot is not supported on mobile web. Install the app?": "RIot не ради на мобилном вебу. Инсталирати апликацију?", + "Discussion of all things Matrix!": "Разговори о свим Матрикс стварима!", + "Failed to set Direct Message status of room": "Нисам успео да подесим стање директне поруке собе", + "Monday": "Понедељак", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Да бисмо проучили проблеме, послаћемо записнике са овог клијента уз овај извештај о грешци. Уколико само желите да пошаљете текст изнад, дештиклирајте:", + "Remove from Directory": "Уклони из фасцикле", + "Enable them now": "Омогућите их сада", + "Messages containing my user name": "Поруке које садрже моје корисничко име", + "Describe your problem here.": "Опишите ваш проблем овде.", + "Toolbox": "Алатница", + "Collecting logs": "Прикупљам записнике", + "more": "више", + "Search for a room": "Потражи собу", + "You must specify an event type!": "Морате навести врсту догађаја!", + "(HTTP status %(httpStatus)s)": "(HTTP стање %(httpStatus)s)", + "All Rooms": "Све собе", + "State Key": "Кључ стања", + "Please install Chrome or Firefox for the best experience.": "Инсталирајте Хром (Chrome) или Фајерфокс (Firefox) за најбољи угођај.", + "Wednesday": "Среда", + "Send logs": "Пошаљи записнике", + "All messages": "Све поруке", + "Implementing VoIP services with Matrix": "Израда VoIP услуга уз Матрикс", + "Dev chat for the Riot/Web dev team": "Програмерско ћаскање за Riot/веб програмерски тим", + "Call invitation": "Позивница за позив", + "Riot Desktop on %(platformName)s": "Riot стони програм за %(platformName)s", + "Messages containing my display name": "Поруке које садрже моје приказно име", + "You have successfully set a password and an email address!": "Успешно сте поставили лозинку и мејл адресу!", + "Failed to send custom event.": "Нисам успео да пошаљем прилагођени догађај.", + "What's new?": "Шта је ново?", + "Discussion of the Identity Service API": "Разговори о API-ју идентитетског сервиса", + "Support for those using and running matrix-appservice-irc": "Подршка за оне који користе и одржавају matrix-appservice-irc", + "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS и matrix-ios-sdk ћаскање", + "Notify me for anything else": "Обавести ме за било шта друго", + "When I'm invited to a room": "Када сам позван у собу", + "Design and implementation of E2E in Matrix": "Дизајн и имплементација E2E у Матриксу", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Можете користити опције прилагођеног сервера за пријаву у друге Матрикс сервере навођењем другачије адресе кућног сервера.
    Ово вам омогућава да користите Riot са постојећим Матрикс налогомна другом кућном серверу.

    Такође, можете поставити прилагођени идентитески сервер али нећете моћи да позивате кориснике по мејл адреси а ни други вас.", + "Can't update user notification settings": "Не могу да ажурирам корисничка подешавања обавештења", + "Notify for all other messages/rooms": "Обавести за све друге поруке и собе", + "Unable to look up room ID from server": "Не могу да погледам ИБ собе на серверу", + "Couldn't find a matching Matrix room": "Не могу да нађем одговарајућу Матрикс собу", + "Bug report sent": "Извештај о грешци послат", + "Loading bug report module": "Учитавам модул за извештавање о грешкама", + "Invite to this room": "Позови у ову собу", + "You cannot delete this message. (%(code)s)": "Не можете обрисати ову поруку. (%(code)s)", + "Thursday": "Четвртак", + "I understand the risks and wish to continue": "Разумем опасност и желим да наставим", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s преко прегледача %(browserName)s на систему %(osName)s", + "Back": "Назад", + "Reply": "Одговори", + "Show message in desktop notification": "Прикажи поруку у стоном обавештењу", + "Unhide Preview": "Откриј преглед", + "Announcements about Synapse releases": "Објаве поводом нових Synapse издања", + "Search the room directory": "Претражи фасциклу са собама", + "Please describe the bug and/or send logs.": "Опишите грешку и/или пошаљите записнике.", + "Unable to join network": "Не могу да приступим мрежи", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Можда сте их подесили у неком другом клијенту а не Riot-у. Не можете их преправљати у Riot-у али се и даље примењују", + "Sorry, your browser is not able to run Riot.": "Нажалост, ваш прегледач не може да покреће Riot.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Децентрализовано, шифровано ћаскање и сарадња коју покреће [matrix]", + "Building services on Matrix": "Стварање услуга уз помоћ Матрикса", + "Messages in group chats": "Поруке у групним ћаскањима", + "Yesterday": "Јуче", + "Error encountered (%(errorDetail)s).": "Догодила се грешка (%(errorDetail)s).", + "Event Type": "Врста догађаја", + "Low Priority": "Најмања важност", + "What's New": "Шта је ново", + "Set Password": "Постави лозинку", + "Appear Offline": "Прикажи себе као ван мреже", + "Support for those using the Matrix spec": "Подршка за оне који користе Матрикс спецификацију", + "An error occurred whilst saving your email notification preferences.": "Догодила се грешка при чувању ваших поставки мејл обавештења.", + "Enable audible notifications in web client": "Омогући звучна обавештења у веб клијенту", + "Permalink": "Трајна веза", + "Welcome to Riot.im": "Добродошли у Riot.im", + "Resend": "Поново пошаљи", + "Riot does not know how to join a room on this network": "Riot не зна како да приступи соби на овој мрежи", + "Mentions only": "Само спомињања", + "You can now return to your account after signing out, and sign in on other devices.": "Можете се вратити у ваш налог након што се одјавите и пријавите поново, на другим уређајима.", + "Enable desktop notifications": "Омогући стона обавештења", + "Enable email notifications": "Омогући мејл обавештења", + "Login": "Пријава", + "Download this file": "Преузми ову датотеку", + "Pin Message": "Закачи поруку", + "Failed to change settings": "Нисам успео да променим подешавања", + "View Community": "Погледај заједницу", + "%(count)s Members|one": "%(count)s члан", + "Developer Tools": "Програмерске алатке", + "View Source": "Погледај извор", + "Matrix technical discussions": "Технички разговори о Матриксу", + "Event Content": "Садржај догађаја", + "Thank you!": "Хвала вам!", + "#example": "#пример", + "Collapse panel": "Скупи површ", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Са вашим тренутним прегледачем изглед и угођај ове апликације може бити скроз неправилан и неке могућности можда неће радити. Уколико желите да ипак пробате, можете наставити али ћете бити без подршке за било које проблеме на које налетите!", + "Checking for an update...": "Проверавам ажурирања...", + "General discussion about Matrix and Riot": "Општи разговори о Матриксу и Riot-у", + "There are advanced notifications which are not shown here": "Постоје напредна обавештења која нису приказана овде" } diff --git a/src/i18n/strings/sv.json b/src/i18n/strings/sv.json index 8c0c722bdd..2296d2178f 100644 --- a/src/i18n/strings/sv.json +++ b/src/i18n/strings/sv.json @@ -433,5 +433,189 @@ "You need to be logged in.": "Du måste vara inloggad.", "You need to be able to invite users to do that.": "Du måste kunna bjuda in användare för att göra det.", "You are not in this room.": "Du är inte i det här rummet.", - "You do not have permission to do that in this room.": "Du har inte behörighet att göra det i det här rummet." + "You do not have permission to do that in this room.": "Du har inte behörighet att göra det i det här rummet.", + "Fetching third party location failed": "Det gick inte att hämta platsdata från tredje part", + "A new version of Riot is available.": "En ny version av Riot är tillgänglig.", + "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk-chatt", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Beskriv buggen. Vad gjorde du? Vad förväntade du dig att ska hända? Vad hände?", + "Couldn't load home page": "Kunde inte ladda startsidan", + "All notifications are currently disabled for all targets.": "Alla aviseringar är för tillfället avstängda för alla mål.", + "Uploading report": "Laddar upp rapport", + "Sunday": "söndag", + "Messages sent by bot": "Meddelanden från bottar", + "Notification targets": "Aviseringsmål", + "Failed to set direct chat tag": "Det gick inte att markera rummet som direkt chatt", + "Today": "idag", + "Failed to get protocol list from Home Server": "Det gick inte att hämta protokollistan från hemservern", + "Report a bug": "Rapportera en bugg", + "Implementing VR services with Matrix": "Implementation av VR-tjänster med Matrix", + "You are not receiving desktop notifications": "Du får inte skrivbordsaviseringar", + "Friday": "fredag", + "Update": "Uppdatera", + "You need to be using HTTPS to place a screen-sharing call.": "Du måste använda HTTPS för att dela din skärm.", + "What's New": "Vad är nytt", + "Add an email address above to configure email notifications": "Lägg till en epostadress här för att konfigurera epostaviseringar", + "Expand panel": "Öppna panel", + "On": "På", + "%(count)s Members|other": "%(count)s 1 Medlemmar", + "Filter room names": "Filtrera rumsnamn", + "Changelog": "Ändringslogg", + "Running Matrix services": "Driva Matrix-tjänster", + "Waiting for response from server": "Väntar på svar från servern", + "Leave": "Lämna", + "Uploaded on %(date)s by %(user)s": "%(user)s laddade upp %(date)s", + "Failed to send report: ": "Det gick inte att sända rapporten: ", + "Unknown device": "Okänd enhet", + "Advanced notification settings": "Avancerade aviseringsinställingar", + "delete the alias.": "radera adressen.", + "To return to your account in future you need to set a password": "För att återgå till ditt konto i framtiden måste du välja ett lösenord", + "Forget": "Glöm bort", + "#example": "#exempel", + "Riot/Web & Desktop chat": "Riot/Web & Desktop-chatt", + "Hide panel": "Göm panel", + "You cannot delete this image. (%(code)s)": "Du kan inte radera den här bilden. (%(code)s)", + "Cancel Sending": "Avbryt sändning", + "Warning": "Varning", + "This Room": "Det här rummet", + "The Home Server may be too old to support third party networks": "Hemservern kan vara för gammal för stöda tredje parters nätverk", + "Noisy": "Högljudd", + "Room not found": "Rummet hittades inte", + "Messages containing my display name": "Meddelanden som innehåller mitt namn", + "Messages in one-to-one chats": "Meddelanden i privata chattar", + "Contributing code to Matrix and Riot": "Bidra med kod till Matrix och Riot", + "Unavailable": "Inte tillgänglig", + "Community-run support for Synapse": "Gemenskapsdriven användarhjälp för Synapse", + "View Decrypted Source": "Visa dekrypterad källa", + "Failed to update keywords": "Det gick inte att uppdatera nyckelorden", + "remove %(name)s from the directory.": "ta bort %(name)s från katalogen.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Aviseringar för följande nyckelord följer regler som inte kan visas här:", + "Please set a password!": "Vänligen välj ett lösenord!", + "You have successfully set a password!": "Du har valt ett nytt lösenord!", + "Chat with Riot Bot": "Chatta med Riot Bot", + "Support for those using, running and writing other bridges": "Hjälp för de som använder, driver och utvecklar andra bryggor", + "Admin support for Dendrite": "Hjälp för administratörer av Dendrite", + "An error occurred whilst saving your email notification preferences.": "Ett fel uppstod då epostaviseringsinställningarna sparades.", + "Explore Room State": "Utforska rumläget", + "Source URL": "Käll-URL", + "Failed to add tag %(tagName)s to room": "Det gick inte att lägga till \"%(tagName)s\" till rummet", + "Filter results": "Filtrera resultaten", + "Members": "Medlemmar", + "No update available.": "Ingen uppdatering tillgänglig.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Många rum finns redan i Matrix, länkade till andra nätverk (Slack, IRC, Gitter etc.) eller fristående. Kolla in katalogen!", + "Resend": "Sänd igen", + "Files": "Filer", + "Collecting app version information": "Samlar in appversionsinformation", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Radera rumsadressen %(alias)s och ta bort %(name)s från katalogen?", + "customServer_text": "Du kan använda serverinställningarna för att logga in i en annan Matrix-server genom att specifiera en URL till en annan hemserver.
    Så här kan du använda Riot med ett existerande Matrix-konto på en annan hemserver.

    Du kan också specifiera en egen identitetsserver, men du kommer inte att kunna bjuda in andra via epostadress, eller bli inbjuden via epostadress.", + "Co-ordination for Riot/Web translators": "Koordination för översättare av Riot/Web", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Detta kommer tillåta dig att återgå till ditt konto efter att ha loggat ut, och logga in på andra enheter.", + "Dev chat for the Dendrite dev team": "Chatt för utvecklare av Dendrite", + "Keywords": "Nyckelord", + "Enable notifications for this account": "Sätt på aviseringar för det här kontot", + "Directory": "Katalog", + "Failed to get public room list": "Det gick inte att hämta listan över offentliga rum", + "Messages containing keywords": "Meddelanden som innehåller nyckelord", + "Error saving email notification preferences": "Ett fel uppstod då epostaviseringsinställningarna sparades", + "Tuesday": "tisdag", + "Enter keywords separated by a comma:": "Skriv in nyckelord, separerade med kommatecken:", + "Search…": "Sök…", + "Remove %(name)s from the directory?": "Ta bort %(name)s från katalogen?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot använder flera avancerade webbläsaregenskaper, av vilka alla inte stöds eller är experimentella i din nuvarande webbläsare.", + "Enable desktop notifications": "Sätt på skrivbordsaviseringar", + "Remember, you can always set an email address in user settings if you change your mind.": "Kom ihåg att du alltid kan välja en e-postadress i dina användarinställningar om du ändrar dig.", + "All messages (noisy)": "Alla meddelanden (högljudd)", + "Away": "Borta", + "Saturday": "lördag", + "I understand the risks and wish to continue": "Jag förstår riskerna och vill fortsätta", + "Direct Chat": "Direkt-chatt", + "The server may be unavailable or overloaded": "Servern kan vara överbelastad eller inte tillgänglig", + "Reject": "Avvisa", + "Riot is not supported on mobile web. Install the app?": "Riot stöds inte på mobil-webb. Installera appen?", + "Discussion of all things Matrix!": "Diskussion om allt gällande Matrix!", + "Failed to set Direct Message status of room": "Det gick inte att sätta Direkt meddelande-status på rummet", + "Monday": "måndag", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "För att diagnostisera problem kommer loggar från den här klienten att sändas med rapporten. Om du bara vill sända texten ovan, kryssa av rutan:", + "Remove from Directory": "Ta bort från katalogen", + "Enable them now": "Sätt på nu", + "Messages containing my user name": "Meddelanden som innehåller mitt användarnamn", + "Describe your problem here.": "Beskriv problemet här.", + "Collecting logs": "Samlar in loggar", + "more": "mera", + "Bug report sent": "Buggraporten skickades", + "(HTTP status %(httpStatus)s)": "(HTTP-status %(httpStatus)s)", + "All Rooms": "Alla rum", + "Wednesday": "onsdag", + "You cannot delete this message. (%(code)s)": "Du kan inte radera det här meddelandet. (%(code)s)", + "Send": "Sänd", + "Send logs": "Sänd loggar", + "All messages": "Alla meddelanden", + "Implementing VoIP services with Matrix": "Implementation av VoIP-tjänster med Matrix", + "Dev chat for the Riot/Web dev team": "Chatt för utvecklare av Riot/Web", + "Call invitation": "Inbjudan till samtal", + "Riot Desktop on %(platformName)s": "Riot Desktop på %(platformName)s", + "Downloading update...": "Laddar ned uppdatering...", + "You have successfully set a password and an email address!": "Du har framgångsrikt valt ett lösenord och en e-postadress!", + "What's new?": "Vad är nytt?", + "Discussion of the Identity Service API": "Diskussion om Identity Service API:n", + "Support for those using and running matrix-appservice-irc": "Hjälp för de som använder och driver matrix-appservice-irc", + "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk-chatt", + "Notify me for anything else": "Avisera för allt annat", + "When I'm invited to a room": "När jag bjuds in till ett rum", + "Design and implementation of E2E in Matrix": "Design och implementation av E2E i Matrix", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Du kan använda anpassade serverinställningar för att logga in på andra Matrix-servrar genom att ange en annan hemserver-URL.
    Du kan då använda Riot med ett befintligt Matrix-konto på en annan hemserver.

    Du kan också ange en anpassad identitetsserver men kommer då inte kunna bjuda in användare med epostadress, eller själv bli inbjuden med epostadress.", + "Can't update user notification settings": "Kan inte uppdatera aviseringsinställningarna", + "Notify for all other messages/rooms": "Avisera för alla andra meddelanden/rum", + "Unable to look up room ID from server": "Det gick inte att hämta rums-ID:t från servern", + "Couldn't find a matching Matrix room": "Kunde inte hitta ett matchande Matrix-rum", + "Support for those using the Matrix spec": "Hjälp för de som använder Matrix specifikation", + "Safari and Opera work too.": "Safari och Opera fungerar också.", + "Loading bug report module": "Laddar buggrapportsmodul", + "Invite to this room": "Bjud in i rummet", + "Search for a room": "Sök efter rum", + "Thursday": "torsdag", + "Forward Message": "Vidarebefordra meddelande", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s via %(browserName)s på %(osName)s", + "Back": "Tillbaka", + "Reply": "Svara", + "Show message in desktop notification": "Visa meddelande i skrivbordsavisering", + "Unhide Preview": "Visa förhandsvisning", + "Announcements about Synapse releases": "Meddelanden om Synapse-versioner", + "Search the room directory": "Sök i rumskatalogen", + "Please describe the bug and/or send logs.": "Beskriv buggen och/eller sänd loggar.", + "Unable to join network": "Det gick inte att ansluta till nätverket", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Du kan ha konfigurerat dem i en annan klient än Riot. Du kan inte ändra dem i Riot men de tillämpas ändå", + "Sorry, your browser is not able to run Riot.": "Beklagar, din webbläsare kan inte köra Riot.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Decentraliserad, krypterad chatt & samarbete möjliggjort med [matrix]", + "Building services on Matrix": "Bygga tjänster med Matrix", + "Messages in group chats": "Meddelanden i gruppchattar", + "Yesterday": "igår", + "Error encountered (%(errorDetail)s).": "Fel påträffat (%(errorDetail)s).", + "Low Priority": "Låg prioritet", + "Unable to fetch notification target list": "Det gick inte att hämta aviseringsmållistan", + "Appear Offline": "Visa som utloggad", + "Get started with some tips from Riot Bot!": "Kom igång med några tips från Riot Bot!", + "Set Password": "Välj lösenord", + "Enable audible notifications in web client": "Sätt på högljudda aviseringar i webbklienten", + "Permalink": "Permanent länk", + "Welcome to Riot.im": "Välkommen till Riot.im", + "Off": "Av", + "Riot does not know how to join a room on this network": "Riot kan inte gå med i ett rum på det här nätverket", + "Mentions only": "Endast omnämnande", + "Failed to remove tag %(tagName)s from room": "Det gick inte att radera taggen %(tagName)s från rummet", + "You can now return to your account after signing out, and sign in on other devices.": "Du kan nu återgå till ditt konto efter att ha loggat ut och logga in på andra enheter.", + "Please install Chrome or Firefox for the best experience.": "Installera Chrome eller Firefox för den bästa upplevelsen.", + "Enable email notifications": "Sätt på epostaviseringar", + "Login": "Logga in", + "Download this file": "Ladda ner filen", + "Failed to change settings": "Det gick inte att spara inställningarna", + "%(count)s Members|one": "%(count)s 1 Medlem", + "View Source": "Visa källa", + "Matrix technical discussions": "Teknisk diskussion om Matrix", + "Thank you!": "Tack!", + "Quote": "Citera", + "Collapse panel": "Kollapsa panel", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Med din nuvarande webbläsare kan appens utseende vara helt fel, och vissa eller alla egenskaper kommer nödvändigtvis inte att fungera. Om du ändå vill försöka så kan du fortsätta, men gör det på egen risk!", + "Checking for an update...": "Letar efter uppdateringar...", + "General discussion about Matrix and Riot": "Allmän diskussion om Matrix och Riot", + "There are advanced notifications which are not shown here": "Det finns avancerade aviseringar som inte visas här" } diff --git a/src/i18n/strings/te.json b/src/i18n/strings/te.json index ec45eefadf..0c0ff8da9e 100644 --- a/src/i18n/strings/te.json +++ b/src/i18n/strings/te.json @@ -182,5 +182,110 @@ "Notifications": "ప్రకటనలు", "Operation failed": "కార్యం విఫలమైంది", "Search": "శోధన", - "Settings": "అమరికలు" + "Settings": "అమరికలు", + "Fetching third party location failed": "మూడవ పార్టీ స్థానాన్ని పొందడం విఫలమైంది", + "A new version of Riot is available.": "కొత్త రిమోట్ వివరణము అందుబాటులో ఉంది.", + "Couldn't load home page": "హోమ్ పేజీని లోడ్ చేయలేకపోయాము", + "Advanced notification settings": "ఆధునిక తాఖీదు అమరిక", + "Sunday": "ఆదివారం", + "Guests can join": "అతిథులు చేరవచ్చు", + "Messages sent by bot": "బాట్ పంపిన సందేశాలు", + "Notification targets": "తాఖీదు లక్ష్యాలు", + "Failed to set direct chat tag": "ప్రత్యక్ష మాటామంతి బొందు సెట్ చేయడంలో విఫలమైంది", + "Today": "ఈ రోజు", + "Failed to get protocol list from Home Server": "హోమ్ సర్వర్ నుండి ప్రోటోకాల్ జాబితాను పొందడం విఫలమైంది", + "Report a bug": "లోపమును నివేదించు", + "Friday": "శుక్రువారం", + "Add an email address above to configure email notifications": "ఇమెయిల్ ప్రకటనలను రూపశిల్పం చేయడానికి ఎగువ ఇమెయిల్ చిరునామాను జోడించండి", + "Expand panel": "ప్యానెల్ను విస్తరింపజేయండి", + "On": "వేయుము", + "Filter room names": "గది పేర్లను ఫిల్టర్ చేయండి", + "Changelog": "మార్పు వివరణ", + "Leave": "వదిలి", + "Failed to send report: ": "నివేదికను పంపడంలో విఫలమైంది: ", + "All notifications are currently disabled for all targets.": "ప్రస్తుతానికి అన్ని చోట్లనుంచి అన్ని ప్రకటనలు ఆగి వున్నాయి.", + "delete the alias.": "అలియాస్ తొలగించండి.", + "Forget": "మర్చిపో", + "Hide panel": "ప్యానెల్ను దాచు", + "Source URL": "మూల URL", + "Warning": "హెచ్చరిక", + "Noisy": "శబ్దం", + "Room not found": "గది కనుగొనబడలేదు", + "Messages containing my display name": "నా ప్రదర్శన పేరును కలిగి ఉన్న సందేశాలు", + "Messages in one-to-one chats": "సందేశాలు నుండి ఒకరికి ఒకటి మాటామంతి", + "Failed to update keywords": "కీలక పదాలను నవీకరించడంలో విఫలమైంది", + "remove %(name)s from the directory.": "వివరము నుండి %(name)s ను తొలిగించు.", + "Please set a password!": "దయచేసి మీ రహస్యపదాన్నీ అమర్చండి!", + "Chat with Riot Bot": "రియోట్ బొట్తో మాటామంతి చేయండి", + "Cancel Sending": "పంపడాన్ని ఆపేయండి", + "Failed to add tag %(tagName)s to room": "%(tagName)s ను బొందు జోడించడంలో విఫలమైంది", + "Members": "సభ్యులు", + "No update available.": "ఏ నవీకరణ అందుబాటులో లేదు.", + "Resend": "మళ్ళి పంపుము", + "Files": "దస్ర్తాలు", + "Collecting app version information": "అనువర్తన సంస్కరణ సమాచారాన్ని సేకరించడం", + "Forward Message": "సందేశాన్ని మునుముందుకు చేయండి", + "Enable notifications for this account": "ఈ ఖాతా కోసం తాఖీదు ప్రారంభించండి", + "Directory": "వివరం", + "Search for a room": "గది కోసం శోధించండి", + "Messages containing keywords": "కీలక పదాలనుకలిగి ఉన్న సందేశం", + "Error saving email notification preferences": "ఇమెయిల్ ప్రకటనలను ప్రాధాన్యతలను దాచు చేయడంలో లోపం", + "Tuesday": "మంగళవారం", + "Enter keywords separated by a comma:": "కామాతో వేరు చేయబడిన కీలక పదాలను నమోదు చేయండి:", + "I understand the risks and wish to continue": "నేను నష్టాలను అర్థం చేసుకుంటాను మరియు కొనసాగించాలని కోరుకుంటున్నాను", + "Remove %(name)s from the directory?": "వివరము నుండి %(name)s తొలిగించు?", + "Remove from Directory": "`వివరము నుండి తొలిగించు", + "Direct Chat": "ప్రత్యక్ష మాటామంతి", + "Reject": "తిరస్కరించు", + "Failed to set Direct Message status of room": "గది యొక్క ప్రత్యక్ష సందేశ స్థితి సెట్ చేయడంలో విఫలమైంది", + "Monday": "సోమవారం", + "All messages (noisy)": "అన్ని సందేశాలు (గట్టిగ)", + "Enable them now": "ఇప్పుడే వాటిని ప్రారంభించండి", + "Messages containing my user name": "నా వినియోగదారు పేరు కలిగి ఉన్న సందేశాలు", + "Describe your problem here.": "ఇక్కడ మీ సమస్యను వివరించండి.", + "Collecting logs": "నమోదు సేకరించడం", + "more": "మరింత", + "Failed to get public room list": "ప్రజా గది జాబితాను పొందడం విఫలమైంది", + "(HTTP status %(httpStatus)s)": "(HTTP స్థితి %(httpStatus)s)", + "All Rooms": "అన్ని గదులు", + "Wednesday": "బుధవారం", + "Send": "పంపండి", + "Send logs": "నమోదును పంపు", + "All messages": "అన్ని సందేశాలు", + "Call invitation": "మాట్లాడడానికి ఆహ్వానం", + "Riot Desktop on %(platformName)s": "రియట్ రంగస్థలం లో %(platformName)s", + "Downloading update...": "నవీకరణను దిగుమతి చేస్తోంది...", + "Keywords": "ముఖ్యపదాలు", + "Can't update user notification settings": "వినియోగదారు ప్రకటన ప్రాదాన్యాలు నవీకరించదడానేకి రాదు", + "Notify for all other messages/rooms": "అన్ని ఇతర సందేశాలు / గదులు కోసం తెలియజేయండి", + "Couldn't find a matching Matrix room": "సరిపోలిక మ్యాట్రిక్స్ గదిని కనుగొనలేకపోయాము", + "Safari and Opera work too.": "సఫరిఇంకఒపెరకుద పని చెసతయి.", + "Loading bug report module": "దోష నివేదిక అధిభాగం లోడ్ చేస్తోంది", + "Invite to this room": "ఈ గదికి ఆహ్వానించండి", + "Thursday": "గురువారం", + "Search…": "శోధన…", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s %(browserName)s ద్వర %(osName)s కి", + "Search the room directory": "గది వివరాన్ని శోధించండి", + "Sorry, your browser is not able to run Riot.": "క్షమించండి, మీ బ్రౌజర్ రియట్ని అమలు చేయలేరు.", + "Messages in group chats": "సమూహ మాటామంతిలో సందేశాలు", + "Yesterday": "నిన్న", + "Error encountered (%(errorDetail)s).": "లోపం సంభవించింది (%(errorDetail)s).", + "Low Priority": "తక్కువ ప్రాధాన్యత", + "Set Password": "రహస్యపదాన్నీ అమర్చండి", + "An error occurred whilst saving your email notification preferences.": "మీ ఇమెయిల్ ప్రకటన ప్రాధాన్యాలు బద్రపరిచేతప్పుడు ఎదో తప్పు జరిగింది.", + "Enable audible notifications in web client": "వెబ్ బంట్రౌతు వినిపించే నోటిఫికేషన్లను ప్రారంభించండి", + "Welcome to Riot.im": "రిమోట్.ఇం కి స్వగతం", + "Off": "ఆపు", + "Mentions only": "మాత్రమే ప్రస్తావిస్తుంది", + "Failed to remove tag %(tagName)s from room": "గది నుండి బొందు %(tagName)s తొలగించడంలో విఫలమైంది", + "Enable desktop notifications": "రంగస్థల తాఖీదు ప్రారంభించండి", + "Enable email notifications": "ఇమెయిల్ ప్రకటనలను ప్రారంభించండి", + "Login": "ప్రవేశ ద్వారం", + "No rooms to show": "చూపించడానికి గదులు లేవు", + "Download this file": "ఈ దస్త్రం దిగుమతి చేయండి", + "Failed to change settings": "అమరిక మార్చడం విఫలమైంది", + "#example": "#ఉదాహరణ", + "Collapse panel": "ప్యానెల్ కుదించు", + "Checking for an update...": "నవీకరణ కోసం చూస్తోంది...", + "Saturday": "శనివారం" } diff --git a/src/i18n/strings/th.json b/src/i18n/strings/th.json index 540902c8f1..06f205840c 100644 --- a/src/i18n/strings/th.json +++ b/src/i18n/strings/th.json @@ -435,5 +435,180 @@ "Error decrypting image": "เกิดข้อผิดพลาดในการถอดรหัสรูป", "Image '%(Body)s' cannot be displayed.": "ไม่สามารถแสดงรูป '%(Body)s' ได้", "This image cannot be displayed.": "ไม่สามารถแสดงรูปนี้ได้", - "Error decrypting video": "เกิดข้อผิดพลาดในการถอดรหัสวิดิโอ" + "Error decrypting video": "เกิดข้อผิดพลาดในการถอดรหัสวิดิโอ", + "Fetching third party location failed": "การเรียกข้อมูลตำแหน่งจากบุคคลที่สามล้มเหลว", + "A new version of Riot is available.": "มี Riot เวอร์ชั่นใหม่", + "Riot/Android & matrix-android-sdk chat": "แชทเกี่ยวกับ Riot บน Android และ matrix-android-sdk", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "กรุณาอธิบายจุดบกพร่อง คุณทำอะไร? ควรจะเกิดอะไรขึ้น? แล้วอะไรคือสิ่งที่เกิดขึ้นจริง?", + "I understand the risks and wish to continue": "ฉันเข้าใจความเสี่ยงและต้องการดำเนินการต่อ", + "Advanced notification settings": "ตั้งค่าการแจ้งเตือนขั้นสูง", + "Uploading report": "กำลังอัปโหลดรายงาน", + "Sunday": "วันอาทิตย์", + "Guests can join": "แขกเข้าร่วมได้", + "Failed to add tag %(tagName)s to room": "การเพิ่มแท็ก %(tagName)s ของห้องนี้ล้มเหลว", + "Notification targets": "เป้าหมายการแจ้งเตือน", + "Failed to set direct chat tag": "การติดแท็กแชทตรงล้มเหลว", + "Today": "วันนี้", + "Files": "ไฟล์", + "Report a bug": "รายงานจุดบกพร่อง", + "Implementing VR services with Matrix": "การอิมพลีเมนต์บริการ VR ด้วย Matrix", + "You are not receiving desktop notifications": "การแจ้งเตือนบนเดสก์ทอปถูกปิดอยู่", + "Friday": "วันศุกร์", + "Update": "อัปเดต", + "You need to be using HTTPS to place a screen-sharing call.": "คุณต้องใช้ HTTPS เพื่อเริ่มติดต่อแบบแบ่งปันหน้าจอ", + "What's New": "มีอะไรใหม่", + "Add an email address above to configure email notifications": "เพิ่มที่อยู่อีเมลข้างบนเพื่อตั้งค่าการแจ้งเตือนทางอีเมล", + "Expand panel": "ขยายหน้าต่าง", + "On": "เปิด", + "Filter room names": "กรองชื่อห้อง", + "Changelog": "บันทึกการเปลี่ยนแปลง", + "Running Matrix services": "การติดตั้งบริการ Matrix", + "Waiting for response from server": "กำลังรอการตอบสนองจากเซิร์ฟเวอร์", + "Leave": "ออกจากห้อง", + "Uploaded on %(date)s by %(user)s": "อัปโหลดเมื่อ %(date)s โดย %(user)s", + "Failed to send report: ": "การส่งรายงานล้มเหลว: ", + "Unknown device": "อุปกรณ์ที่ไม่รู้จัก", + "All notifications are currently disabled for all targets.": "การแจ้งเตือนทั้งหมดถูกปิดใช้งานสำหรับทุกอุปกรณ์", + "delete the alias.": "ลบนามแฝง", + "To return to your account in future you need to set a password": "คุณต้องตั้งรหัสผ่านเพื่อจะกลับมาที่บัญชีนี้ในอนาคต", + "Forget": "ลืม", + "World readable": "ทุกคนอ่านได้", + "Riot/Web & Desktop chat": "แชทเกี่ยวกับ Riot บนเว็บและเดสก์ทอป", + "Hide panel": "ซ่อนหน้าต่าง", + "You cannot delete this image. (%(code)s)": "คุณไม่สามารถลบรูปนี้ได้ (%(code)s)", + "Cancel Sending": "ยกเลิกการส่ง", + "Warning": "คำเตือน", + "This Room": "ห้องนี้", + "The Home Server may be too old to support third party networks": "เซิร์ฟเวอร์บ้านอาจเก่าเกินกว่าจะรองรับเครือข่ายของบุคคลที่สาม", + "Resend": "ส่งใหม่", + "Room not found": "ไม่พบห้อง", + "Messages containing my display name": "ข้อความที่มีชื่อของฉัน", + "Messages in one-to-one chats": "ข้อความในแชทตัวต่อตัว", + "Contributing code to Matrix and Riot": "สมทบโค๊ดให้ Matrix และ Riot", + "Unavailable": "ไม่มี", + "Community-run support for Synapse": "ฝ่ายสนับสนุน Synapse โดยชุมชนผู้ใช้", + "Error saving email notification preferences": "การบันทึกการตั้งค่าการแจ้งเตือนทางอีเมลผิดพลาด", + "View Decrypted Source": "ดูซอร์สที่ถอดรหัสแล้ว", + "Send": "ส่ง", + "remove %(name)s from the directory.": "ถอด %(name)s ออกจากไดเรกทอรี", + "Notifications on the following keywords follow rules which can’t be displayed here:": "การแจ้งเตือนจากคีย์เวิร์ดเหล่านี้ เป็นไปตามกฏที่ไม่สามารถแสดงที่นี่ได้:", + "Please set a password!": "กรุณาตั้งรหัสผ่าน!", + "You have successfully set a password!": "การตั้งรหัสผ่านเสร็จสมบูรณ์!", + "Chat with Riot Bot": "แชทกับบอท Riot", + "Support for those using, running and writing other bridges": "ฝ่ายสนับสนุนสำหรับผู้ใช้หรือพัฒนาตัวเชื่อมอื่น ๆ", + "Admin support for Dendrite": "ฝ่ายสนับสนุน Dendrite จากผู้ดูแล", + "An error occurred whilst saving your email notification preferences.": "เกิดข้อผิดพลาดระหว่างบันทึกการตั้งค่าการแจ้งเตือนทางอีเมล", + "Source URL": "URL ต้นฉบับ", + "Messages sent by bot": "ข้อความจากบอท", + "Members": "สมาชิก", + "No update available.": "ไม่มีอัปเดตที่ใหม่กว่า", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "มีห้องอยู่มากมายใน Matrix ทั้งห้องที่เชื่อมไปยังเครือข่ายอื่น (Slack, IRC, Gitter ฯลฯ) และห้องที่อยู่ด้วยตัวเอง ลองดูไดเรกทอรีสิ!", + "Noisy": "เสียงดัง", + "Failed to get protocol list from Home Server": "การขอรายชื่อโปรโตคอลจากเซิร์ฟเวอร์บ้านล้มเหลว", + "Collecting app version information": "กำลังรวบรวมข้อมูลเวอร์ชันแอป", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "ลบนามแฝง %(alias)s ของห้องและถอด %(name)s ออกจากไดเรกทอรี?", + "customServer_text": "คุณสามารถกำหนดเซิร์ฟเวอร์บ้านเองได้โดยใส่ URL ของเซิร์ฟเวอร์นั้น เพื่อเข้าสู่ระบบของเซิร์ฟเวอร์ Matrix อื่น
    ทั้งนี่เพื่อให้คุณสามารถใช้ Riot กับบัญชี Matrix ที่มีอยู่แล้วบนเซิร์ฟเวอร์บ้านอื่น ๆ ได้

    คุณอาจเลือกเซิร์ฟเวอร์ระบุตัวตนเองด้วยก็ได้ แต่คุณจะไม่สามารถเชิญผู้ใช้อื่นด้วยที่อยู่อีเมล หรือรับคำเชิญจากผู้ใช้อื่นทางที่อยู่อีเมลได้", + "Co-ordination for Riot/Web translators": "แชทสำหรับประสานงานการแปล Riot บนเว็บ", + "This will allow you to return to your account after signing out, and sign in on other devices.": "เพื่อคุณจะได้กลับมายังบัญชีเดิมของคุณได้ หลังจากออกจากระบบ แล้วกลับเข้าสู่ระบบในอุปกรณ์อื่น ๆ", + "Dev chat for the Dendrite dev team": "แชทสำหรับทีมพัฒนา Dendrite", + "Design and implementation of E2E in Matrix": "การออกแบบและใช้งาน E2E ใน Matrix", + "Enable notifications for this account": "เปิดใช้งานการแจ้งเตือนสำหรับบัญชีนี้", + "Directory": "ไดเรกทอรี", + "Search for a room": "ค้นหาห้อง", + "Messages containing keywords": "ข้อความที่มีคีย์เวิร์ด", + "View Source": "ดูซอร์ส", + "Tuesday": "วันอังคาร", + "Enter keywords separated by a comma:": "กรอกคีย์เวิร์ดทั้งหมด คั่นด้วยเครื่องหมายจุลภาค:", + "Search…": "ค้นหา…", + "Remove %(name)s from the directory?": "ถอด %(name)s ออกจากไดเรกทอรี?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot ใช้คุณสมบัติขั้นสูงในเบราว์เซอร์หลายประการ คุณสมบัติบางอย่างอาจยังไม่พร้อมใช้งานหรืออยู่ในขั้นทดลองในเบราว์เซอร์ปัจจุบันของคุณ", + "Please install Chrome or Firefox for the best experience.": "กรุณาติดตั้ง Chrome หรือ Firefox เพื่อประสบการณ์ที่ดีที่สุด", + "Unnamed room": "ห้องที่ไม่มีชื่อ", + "All messages (noisy)": "ทุกข้อความ (เสียงดัง)", + "Saturday": "วันเสาร์", + "Remember, you can always set an email address in user settings if you change your mind.": "อย่าลืม คุณสามารถตั้งที่อยู่อีเมลในการตั้งค่าผู้ใช้ได้ทุกเมื่อหากคุณเปลี่ยนใจ", + "Direct Chat": "แชทโดยตรง", + "The server may be unavailable or overloaded": "เซิร์ฟเวอร์อาจไม่พร้อมใช้งานหรือทำงานหนักเกินไป", + "Reject": "ปฏิเสธ", + "Riot is not supported on mobile web. Install the app?": "Riot ไม่รองรับเว็บบนอุปกรณ์พกพา ติดตั้งแอป?", + "Discussion of all things Matrix!": "พูดคุยทุกเรื่อง เรื่อง Matrix!", + "Failed to set Direct Message status of room": "การตั้งสถานะข้อความตรงของห้องล้มเหลว", + "Monday": "วันจันทร์", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "ล็อกจากไคลเอนต์จะถูกแนบพร้อมกับรายงานนี้เพื่อวินิจฉัยปัญหา หากคุณต้องการส่งเฉพาะข้อความด้านบน กรุณาเอาเครื่องหมายออก:", + "Remove from Directory": "ถอดออกจากไดเรกทอรี", + "Enable them now": "เปิดใช้งานเดี๋ยวนี้", + "Messages containing my user name": "ข้อความที่มีชื่อผู้ใช้ของฉัน", + "Describe your problem here.": "อธิบายปัญหาที่นี่", + "Collecting logs": "กำลังรวบรวมล็อก", + "more": "เพิ่มเติม", + "Failed to get public room list": "การขอรายชื่อห้องสาธารณะล้มเหลว", + "(HTTP status %(httpStatus)s)": "(สถานะ HTTP %(httpStatus)s)", + "All Rooms": "ทุกห้อง", + "Wednesday": "วันพุธ", + "Failed to update keywords": "การอัปเดตคีย์เวิร์ดล้มเหลว", + "Send logs": "ส่งล็อก", + "All messages": "ทุกข้อความ", + "Implementing VoIP services with Matrix": "การอิมพลีเมนต์บริการ VoIP ด้วย Matrix", + "Dev chat for the Riot/Web dev team": "แชทสำหรับทีมพัฒนา Riot บนเว็บ", + "Call invitation": "คำเชิญเข้าร่วมการโทร", + "Riot Desktop on %(platformName)s": "Riot เดสก์ทอปบน %(platformName)s", + "Downloading update...": "กำลังดาวน์โหลดอัปเดต...", + "You have successfully set a password and an email address!": "ตั้งรหัสผ่านและที่อยู่อีเมลสำเร็จแล้ว!", + "What's new?": "มีอะไรใหม่?", + "Discussion of the Identity Service API": "พูดคุยเกี่ยวกับ Identity Service API", + "Support for those using and running matrix-appservice-irc": "ฝ่ายสนับสนุนสำหรับผู้ใช้ matrix-appservice-irc", + "Riot/iOS & matrix-ios-sdk chat": "แชทเกี่ยวกับ Riot บน iOS และ matrix-ios-sdk", + "Notify me for anything else": "แจ้งเตือนสำหรับอย่างอื่นทั้งหมด", + "When I'm invited to a room": "เมื่อฉันได้รับคำเชิญเข้าห้อง", + "Keywords": "คีย์เวิร์ด", + "Can't update user notification settings": "ไม่สามารถอัปเดตการตั้งค่าการแจ้งเตือนของผู้ใช้", + "Notify for all other messages/rooms": "แจ้งเตือนจากห้อง/ข้อความอื่น ๆ ทั้งหมด", + "Unable to look up room ID from server": "ไม่สามารถหา ID ห้องจากเซิร์ฟเวอร์ได้", + "Couldn't find a matching Matrix room": "ไม่พบห้อง Matrix ที่ตรงกับคำค้นหา", + "Support for those using the Matrix spec": "ฝ่ายสนับสนุนสำหรับผู้ใช้สเปค Matrix", + "Safari and Opera work too.": "Safari หรือ Opera ก็ใช้ได้", + "Loading bug report module": "กำลังโหลดโมดูลรายงานจุดบกพร่อง", + "Invite to this room": "เชิญเข้าห้องนี้", + "You cannot delete this message. (%(code)s)": "คุณไม่สามารถลบข้อความนี้ได้ (%(code)s)", + "Thursday": "วันพฤหัสบดี", + "Forward Message": "ส่งต่อข้อความ", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s ผ่านทาง %(browserName)s บน %(osName)s", + "Unhide Preview": "แสดงตัวอย่าง", + "Announcements about Synapse releases": "ประกาศเกี่ยวกับ Synapse รุ่นใหม่", + "Search the room directory": "ค้นหาในไดเรกทอรีห้อง", + "Please describe the bug and/or send logs.": "กรุณาอธิบายจุดบกพร่อง และ/หรือ ส่งล็อก", + "Unable to join network": "ไม่สามารถเข้าร่วมเครือข่ายได้", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "คุณอาจมีการตั้งค่าจากไคลเอนต์อื่นนอกจาก Riot การตั้งต่าเหล่านั้นยังถูกใช้งานอยู่แต่คุณจะปรับแต่งจากใน Riot ไม่ได้", + "Sorry, your browser is not able to run Riot.": "ขออภัย เบราว์เซอร์ของคุณไม่สามารถ run Riot ได้", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "ระบบแชทและประสานงาน ไร้ศูนย์กลางและเข้ารหัสได้ โดยใช้เทคโนโลยีจาก [matrix]", + "Building services on Matrix": "การพัฒนาบริการบน Matrix", + "Messages in group chats": "ข้อความในแชทกลุ่ม", + "Yesterday": "เมื่อวานนี้", + "Error encountered (%(errorDetail)s).": "เกิดข้อผิดพลาด (%(errorDetail)s)", + "Low Priority": "ความสำคัญต่ำ", + "Riot does not know how to join a room on this network": "Riot ไม่รู้วิธีเข้าร่วมห้องในเครือข่ายนี้", + "Get started with some tips from Riot Bot!": "มาเริ่มกันด้วยเคล็ดลับเล็กน้อยจากบอท Riot!", + "Set Password": "ตั้งรหัสผ่าน", + "Enable audible notifications in web client": "เปิดใช้งานเสียงแจ้งเตือนบนเว็บไคลเอนต์", + "Permalink": "ลิงก์ถาวร", + "Welcome to Riot.im": "ยินดีต้อนรับสู่ Riot.im", + "Off": "ปิด", + "#example": "#example", + "Mentions only": "เมื่อถูกกล่าวถึงเท่านั้น", + "Failed to remove tag %(tagName)s from room": "การลบแท็ก %(tagName)s จากห้องล้มเหลว", + "You can now return to your account after signing out, and sign in on other devices.": "คุณสามารถกลับไปยังบัญชีของคุณหลังจากออกจากระบบ แล้วกลับเขาสู่ระบบบนอุปกรณ์อื่น ๆ", + "Enable desktop notifications": "เปิดใช้งานการแจ้งเตือนบนเดสก์ทอป", + "Enable email notifications": "เปิดใช้งานการแจ้งเตือนทางอีเมล", + "Login": "เข้าสู่ระบบ", + "No rooms to show": "ไม่มีห้องที่จะแสดง", + "Download this file": "ดาวน์โหลดไฟล์นี้", + "Failed to change settings": "การแก้ไขการตั้งค่าล้มเหลว", + "Matrix technical discussions": "พูดคุยเรื่อง Matrix เชิงเทคนิค", + "Unable to fetch notification target list": "ไม่สามารถรับรายชื่ออุปกรณ์แจ้งเตือน", + "Quote": "อ้างอิง", + "Collapse panel": "ซ่อนหน้าต่าง", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "การแสดงผลของโปรแกรมอาจผิดพลาด ฟังก์ชันบางอย่างหรือทั้งหมดอาจไม่ทำงานในเบราว์เซอร์ปัจจุบันของคุณ หากคุณต้องการลองดำเนินการต่อ คุณต้องรับมือกับปัญหาที่อาจจะเกิดขึ้นด้วยตัวคุณเอง!", + "Checking for an update...": "กำลังตรวจหาอัปเดต...", + "General discussion about Matrix and Riot": "พูดคุยเรื่องทั่วไป ทั้ง Matrix และ Riot", + "There are advanced notifications which are not shown here": "มีการแจ้งเตือนขั้นสูงที่ไม่ได้แสดงที่นี่" } diff --git a/src/i18n/strings/tr.json b/src/i18n/strings/tr.json index 922bdc33a1..8ead0231d4 100644 --- a/src/i18n/strings/tr.json +++ b/src/i18n/strings/tr.json @@ -641,5 +641,173 @@ "Ignore request": "İsteği yoksay", "You added a new device '%(displayName)s', which is requesting encryption keys.": "Şifreleme anahtarları isteyen , '%(displayName)s' isminde yeni bir cihaz eklediniz .", "Your unverified device '%(displayName)s' is requesting encryption keys.": "Tanımlanmamış cihazınız '%(displayName)s' , şifreleme anahtarlarını istiyor.", - "Encryption key request": "Şifreleme anahtarı isteği" + "Encryption key request": "Şifreleme anahtarı isteği", + "Fetching third party location failed": "Üçüncü parti konumunu çekemedi", + "A new version of Riot is available.": "Riot'un yeni bir versiyonu mevcuttur.", + "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk sohbet", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Lütfen hatayı tanımlayın. Ne yaptınız ? Ne gerçekleşmesini beklediniz ? Ne gerçekleşti ?", + "All notifications are currently disabled for all targets.": "Tüm bildirimler şu anda tüm hedefler için devre dışı bırakılmıştır.", + "Uploading report": "Rapor yükleniyor", + "Sunday": "Pazar", + "Guests can join": "Misafirler katılabilirler", + "Messages sent by bot": "Bot tarafından gönderilen mesajlar", + "Notification targets": "Bildirim hedefleri", + "Failed to set direct chat tag": "Direkt sohbet etiketi ayarlanamadı", + "Today": "Bugün", + "Failed to get protocol list from Home Server": "Ana Sunucu'dan protokol listesi alınamadı", + "Report a bug": "Hata Bildir", + "Implementing VR services with Matrix": "Matrix'te VR hizmetlerini implement etmek", + "You are not receiving desktop notifications": "Masaüstü bildirimleri almıyorsunuz", + "Friday": "Cuma", + "Update": "Güncelleştirme", + "You need to be using HTTPS to place a screen-sharing call.": "Ekran paylaşımlı arama yapmak için HTTPS kullanıyor olmalısınız.", + "What's New": "Yenilikler", + "Add an email address above to configure email notifications": "E-posta bildirimlerini yapılandırmak için yukarıya bir e-posta adresi ekleyin", + "Expand panel": "Genişletme paneli", + "On": "Açık", + "Filter room names": "Oda isimlerini filtrele", + "Changelog": "Değişiklikler", + "Running Matrix services": "Çalışan Matrix hizmetleri", + "Waiting for response from server": "Sunucudan yanıt bekleniyor", + "Leave": "Ayrıl", + "Failed to send report: ": "Rapor gönderilemedi: ", + "Unknown device": "Bilinmeyen aygıt", + "Advanced notification settings": "Gelişmiş bildirim ayarları", + "delete the alias.": "Tüm rumuzları sil.", + "Forget": "Unut", + "World readable": "Okunabilir dünya", + "#example": "örnek", + "Riot/Web & Desktop chat": "Riot/Web & Masaüstü sohbet", + "Hide panel": "Paneli gizle", + "You cannot delete this image. (%(code)s)": "Bu resmi silemezsiniz. (%(code)s)", + "Cancel Sending": "Göndermeyi İptal Et", + "This Room": "Bu Oda", + "The Home Server may be too old to support third party networks": "Ana Sunucu 3. parti ağları desteklemek için çok eski olabilir", + "Noisy": "Gürültülü", + "Room not found": "Oda bulunamadı", + "Messages in one-to-one chats": "Bire bir sohbetlerdeki mesajlar", + "Contributing code to Matrix and Riot": "Matrix ve Riot'a kod katkısı (contribution) sağla", + "Unavailable": "Kullanım dışı", + "Community-run support for Synapse": "Synapse için topluluk tarafından işlenen destek", + "View Decrypted Source": "Şifresi Çözülmüş(Decrypted) Kaynağı Görüntüle", + "Failed to update keywords": "Anahtar kelimeler güncellenemedi", + "remove %(name)s from the directory.": "%(name)s'i dizinden kaldır.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Aşağıdaki anahtar kelimeleri ile ilgili bildirimler burada gösterilemeyen kuralları takip eder:", + "Please set a password!": "Lütfen bir şifre ayarlayın !", + "You have successfully set a password!": "Başarıyla bir şifre ayarladınız!", + "Chat with Riot Bot": "Riot Bot ile Sohbet Et", + "Support for those using, running and writing other bridges": "Diğer köprüleri kullanan , çalıştıran ve yazanlar için destek", + "Admin support for Dendrite": "Dendrite için Admin desteği", + "Source URL": "Kaynak URL", + "Failed to add tag %(tagName)s to room": "%(tagName)s etiketi odaya eklenemedi", + "Members": "Üyeler", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Matrix'te varolan ağlara (Slack , IRC , Gitter vb.) bağlı ya da bağımsız bir çok oda var . Dizini kontrol edin!", + "Resend": "Yeniden Gönder", + "Files": "Dosyalar", + "Collecting app version information": "Uygulama sürümü bilgileri toplanıyor", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "%(alias)s oda rumuzu silinsin ve %(name)s dizinden kaldırılsın mı ?", + "customServer_text": "Farklı bir Ana Sunucu URL'si belirleyerek başka bir Matrix sunucusunda oturum açmak için Özel Sunucu Seçeneklerini kullanabilirsiniz.
    Bu , Riot'u mevcut Matrix hesabı ile farklı bir Ana Sunucuda kullanmanıza olanak tanır.

    Ayrıca Özel Kimlik Sunucu'da ayarlayabilirsiniz ama kullanıcıları e-posta adresleriyle veya kendi e-posta adresinizle davet edemezsiniz.", + "Co-ordination for Riot/Web translators": "Riot/Web çevirmenleri için koordinasyon", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Bu oturumunuzu kapattıktan sonra hesabınıza dönmenizi ve diğer cihazlarda oturum açmanızı sağlar.", + "Dev chat for the Dendrite dev team": "Dendrite Geliştirici Takımı için Geliştirici sohbeti", + "Keywords": "Anahtar kelimeler", + "Enable notifications for this account": "Bu hesap için bildirimleri etkinleştir", + "Directory": "Dizin", + "Failed to get public room list": "Genel odalar listesi alınamadı", + "Messages containing keywords": " anahtar kelimeleri içeren mesajlar", + "Error saving email notification preferences": "E-posta bildirim tercihlerini kaydetme hatası", + "Tuesday": "Salı", + "Enter keywords separated by a comma:": "Anahtar kelimeleri virgül ile ayırarak girin:", + "I understand the risks and wish to continue": "Riskleri anlıyorum ve devam etmek istiyorum", + "Remove %(name)s from the directory?": "%(name)s'i dizinden kaldırılsın mı ?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot geçerli tarayıcınızda mevcut olmayan veya denemelik olan birçok gelişmiş tarayıcı özelliği kullanıyor.", + "Enable desktop notifications": "Masaüstü bildirimlerini etkinleştir", + "Unnamed room": "İsimsiz oda", + "All messages (noisy)": "Tüm mesajlar (uzun)", + "Saturday": "Cumartesi", + "Remember, you can always set an email address in user settings if you change your mind.": "Unutmayın , fikrinizi değiştirirseniz her zaman bir şifre ve e-posta adresi ayarlayabilirsiniz.", + "Direct Chat": "Doğrudan Sohbet", + "The server may be unavailable or overloaded": "Sunucu kullanılamıyor veya aşırı yüklenmiş olabilir", + "Reject": "Reddet", + "Riot is not supported on mobile web. Install the app?": "Riot mobil web'de desteklenmiyor . Uygulamayı yükle ?", + "Discussion of all things Matrix!": "Matrix'in tüm tartışması!", + "Failed to set Direct Message status of room": "Odanın Direkt Mesaj durumu ayarlanamadı", + "Monday": "Pazartesi", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Sorunları teşhis etmek için , bu istemciden kayıtlar hata raporu ile beraber gönderilecek . Yalnızca yukarıdaki metni göndermek isterseniz , lütfen işareti kaldırın:", + "Remove from Directory": "Dizinden Kaldır", + "Enable them now": "Onları şimdi etkinleştir", + "Forward Message": "Mesajı İlet", + "Describe your problem here.": "Probleminizi burada açıklayın.", + "Messages containing my user name": "Kullanıcı ismimi içeren mesajlar", + "Collecting logs": "Kayıtlar toplanıyor", + "more": "Daha", + "Search for a room": "Oda ara", + "(HTTP status %(httpStatus)s)": "(HTTP durumu %(httpStatus)s)", + "All Rooms": "Tüm Odalar", + "Wednesday": "Çarşamba", + "Quote": "Alıntı", + "Send": "Gönder", + "Send logs": "Kayıtları gönder", + "All messages": "Tüm mesajlar", + "Implementing VoIP services with Matrix": "Matrix'te VoIP hizmetlerini implement etmek", + "Dev chat for the Riot/Web dev team": "Riot/Web Geliştirici takımı için Geliştirici sohbeti", + "Call invitation": "Arama davetiyesi", + "Riot Desktop on %(platformName)s": "%(platformName)s platformunda Riot Masaüstü", + "Messages containing my display name": "İsmimi içeren mesajlar", + "You have successfully set a password and an email address!": "Başarıyla bir şifre ve e-posta adresi ayarladın !", + "What's new?": "Yeni olan ne ?", + "Discussion of the Identity Service API": "Kimlik Hizmet API ( Identity Service API ) Tartışması", + "Support for those using and running matrix-appservice-irc": "matrix-appservice-irc kullanan ve çalıştıran kullanıcılar için destek", + "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk sohbet", + "Notify me for anything else": "Başka herhangi bir şey için bana bildirim yap", + "When I'm invited to a room": "Bir odaya davet edildiğimde", + "Design and implementation of E2E in Matrix": "Matrix'te E2E ' nin Tasarım ve İmplementasyonu", + "Can't update user notification settings": "Kullanıcı bildirim ayarları güncellenemiyor", + "Notify for all other messages/rooms": "Diğer tüm mesajlar / odalar için bildirim yapın", + "Unable to look up room ID from server": "Sunucudan oda ID'si aranamadı", + "Couldn't find a matching Matrix room": "Eşleşen bir Matrix odası bulunamadı", + "Support for those using the Matrix spec": "Matrix teknik özelliklerini kullananlar için destek", + "Safari and Opera work too.": " Safari ve Opera da çalışıyor.", + "Loading bug report module": "Hata raporlama modülü yükleniyor", + "Invite to this room": "Bu odaya davet et", + "You cannot delete this message. (%(code)s)": "Bu mesajı silemezsiniz (%(code)s)", + "Thursday": "Perşembe", + "Search…": "Arama…", + "%(appName)s via %(browserName)s on %(osName)s": "%(osName)s işletim sisteminde %(browserName)s ile %(appName)s", + "Unhide Preview": "Önizlemeyi Göster", + "Announcements about Synapse releases": "Synapse sürümleri hakkında duyurular", + "Search the room directory": "Oda dizinini ara", + "Please describe the bug and/or send logs.": "Lütfen hatayı tanımlayın ve/veya kayıtları gönderin.", + "Unable to join network": "Ağa bağlanılamıyor", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Onları Riot dışında bir istemciden yapılandırmış olabilirsiniz . Onları Riot içersinide ayarlayamazsınız ama hala geçerlidirler", + "Sorry, your browser is not able to run Riot.": "Üzgünüz , tarayıcınız Riot'u çalıştıramıyor .", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Dağıtık , şifreli sohbet & işbirliği ile Matrix tarafından desteklenmektedir", + "Uploaded on %(date)s by %(user)s": "%(user)s tarafında %(date)s e yüklendi", + "Messages in group chats": "Grup sohbetlerindeki mesajlar", + "Yesterday": "Dün", + "Low Priority": "Düşük Öncelikli", + "Unable to fetch notification target list": "Bildirim hedef listesi çekilemedi", + "Get started with some tips from Riot Bot!": "Bazı Riot Bot ipuçları ile başlayın !", + "An error occurred whilst saving your email notification preferences.": "E-posta bildirim tercihlerinizi kaydetme işlemi sırasında bir hata oluştu.", + "Enable audible notifications in web client": "Web istemcisinde sesli bildirimleri etkinleştir", + "Permalink": "Kalıcı Bağlantı(permalink)", + "Welcome to Riot.im": "Riot.im'e Hoş Geldiniz", + "Off": "Kapalı", + "Riot does not know how to join a room on this network": "Riot bu ağdaki bir odaya nasıl gireceğini bilmiyor", + "Mentions only": "Sadece Mention'lar", + "Failed to remove tag %(tagName)s from room": "Odadan %(tagName)s etiketi kaldırılamadı", + "You can now return to your account after signing out, and sign in on other devices.": "Şimdi oturumunuzu iptal ettikten sonra başka cihazda oturum açarak hesabınıza dönebilirsiniz.", + "Please install Chrome or Firefox for the best experience.": "Lütfen Chrome ya da Firefox 'u en iyi deneyim için yükleyin.", + "Enable email notifications": "E-posta bildirimlerini etkinleştir", + "Login": "Oturum aç", + "No rooms to show": "Gösterilecek oda yok", + "Download this file": "Bu dosyayı indir", + "Failed to change settings": "Ayarlar değiştirilemedi", + "View Source": "Kaynağı Görüntüle", + "Matrix technical discussions": "Matrix teknik tartışmalar", + "Building services on Matrix": "Matrix üzerinde Yapı hizmetleri", + "Collapse panel": "Katlanır panel", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Geçerli tarayıcınız ile birlikte , uygulamanın görünüş ve kullanım hissi tamamen hatalı olabilir ve bazı ya da tüm özellikler çalışmayabilir. Yine de denemek isterseniz devam edebilirsiniz ancak karşılaşabileceğiniz sorunlar karşısında kendi başınasınız !", + "General discussion about Matrix and Riot": "Matrix ve Riot hakkında genel tartışma", + "There are advanced notifications which are not shown here": "Burada gösterilmeyen gelişmiş bildirimler var" } diff --git a/src/i18n/strings/uk.json b/src/i18n/strings/uk.json index 2ff04fec65..71b6cca767 100644 --- a/src/i18n/strings/uk.json +++ b/src/i18n/strings/uk.json @@ -96,5 +96,211 @@ "Rooms": "Кімнати", "Add rooms to this community": "Добавити кімнати в це суспільство", "This email address is already in use": "Ця адреса елект. почти вже використовується", - "This phone number is already in use": "Цей телефонний номер вже використовується" + "This phone number is already in use": "Цей телефонний номер вже використовується", + "Fetching third party location failed": "Не вдалось отримати стороннє місцеперебування", + "Messages in one-to-one chats": "Повідомлення у чатах \"сам на сам\"", + "A new version of Riot is available.": "Доступне оновлення для Riot.", + "Riot/Android & matrix-android-sdk chat": "Обговорення Riot/Android та matrix-android-sdk", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Опишіть, будь ласка, ваду. Що ви зробили? На що ви очікували? Що трапилось натомість?", + "Couldn't load home page": "Не вдалось завантажити домівку", + "Send Account Data": "Відправити данні аккаунта", + "Advanced notification settings": "Додаткові налаштування сповіщень", + "Uploading report": "Завантаження звіту", + "Sunday": "Неділя", + "Guests can join": "Гості можуть приєднуватися", + "Failed to add tag %(tagName)s to room": "Не вдалось додати до кімнати мітку %(tagName)s", + "Notification targets": "Цілі сповіщень", + "General discussion about Matrix and Riot": "Загальне обговорення Matrix та Riot", + "Failed to set direct chat tag": "Не вдалося встановити мітку прямого чату", + "Today": "Сьогодні", + "Failed to get protocol list from Home Server": "Не вдалось отримати перелік протоколів з Домашнього серверу", + "Report a bug": "Звітувати про вади", + "Implementing VR services with Matrix": "Впровадження служб віртуальної реальності в рамках Matrix", + "You are not receiving desktop notifications": "Ви не отримуєте сповіщення на стільниці", + "Friday": "П'ятниця", + "Update": "Оновити", + "You need to be using HTTPS to place a screen-sharing call.": "Ви маєте використовувати HTTPS щоб зробити виклик із поширенням екрану.", + "What's New": "Що нового", + "Add an email address above to configure email notifications": "Додайте вище адресу е-пошти щоб налаштувати сповіщення е-поштою", + "Expand panel": "Розгорнути панель", + "On": "Увімкнено", + "Filter room names": "Відфільтрувати назви кімнат", + "Changelog": "Журнал змін", + "Running Matrix services": "Запуск служби Matrix", + "Waiting for response from server": "Очікується відповідь від сервера", + "Leave": "Вийти", + "Send Custom Event": "Відправити приватний захід", + "Failed to send report: ": "Не вдалося надіслати звіт: ", + "Unknown device": "Невідомий пристрій", + "All notifications are currently disabled for all targets.": "Сповіщення для усіх цілей на даний момент вимкнені.", + "Failed to send logs: ": "Не вдалося відправити журнали: ", + "delete the alias.": "видалити псевдонім.", + "To return to your account in future you need to set a password": "Щоб мати змогу використовувати вашу обліковку у майбутньому, зазначте пароль", + "Forget": "Забути", + "World readable": "Відкрито для світу", + "#example": "#зразок", + "Riot/Web & Desktop chat": "Обговорення Riot для оглядачів та стільниці", + "Hide panel": "Сховати панель", + "You cannot delete this image. (%(code)s)": "Ви не можете видалити це зображення. (%(code)s)", + "Cancel Sending": "Скасувати надсилання", + "Warning": "Попередження", + "This Room": "Ця кімната", + "The Home Server may be too old to support third party networks": "Домашній сервер може бути застарим для підтримки сторонніх мереж", + "Noisy": "Шумний", + "Error saving email notification preferences": "Помилка при збереженні параметрів сповіщень е-поштою", + "Messages containing my display name": "Повідомлення, вміщає моє ім'я", + "Remember, you can always set an email address in user settings if you change your mind.": "Пам'ятайте, що ви завжди можете встановити адресу е-пошти у налаштуваннях, якщо передумаєте.", + "Contributing code to Matrix and Riot": "Тим, хто хоче долучитись до розробки Matrix та Riot", + "Unavailable": "Нема в наявності", + "Community-run support for Synapse": "Спільнота підтримки Synapse", + "View Decrypted Source": "Переглянути розшифроване джерело", + "Failed to update keywords": "Не вдалось оновити ключові слова", + "remove %(name)s from the directory.": "прибрати %(name)s з каталогу.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Сповіщення з наступних ключових слів дотримуються правил, що не можуть бути показані тут:", + "Safari and Opera work too.": "Safari та Opera працюють теж.", + "Please set a password!": "Встановіть пароль, будь ласка!", + "You have successfully set a password!": "Пароль успішно встановлено!", + "Chat with Riot Bot": "Розмовляти з Riot-ботом", + "Support for those using, running and writing other bridges": "Підтримка користувачів, адміністраторів та розробників інших Matrix-мостів", + "Admin support for Dendrite": "Адміністрування Dendrite", + "An error occurred whilst saving your email notification preferences.": "Під час збереження налаштувань сповіщень е-поштою трапилася помилка.", + "Explore Room State": "Перегляд статуса кімнати", + "Source URL": "Джерельне посилання", + "Messages sent by bot": "Повідомлення, надіслані ботом", + "Filter results": "Фільтр результатів", + "Members": "Члени", + "No update available.": "Оновлення відсутні.", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "У мережі Matrix вже існує багато кімнат, що з'єднані як з існуючими мережами (Slack, IRC, Gitter тощо), так і незалежними. Подивіться у каталозі кімнат!", + "Resend": "Перенадіслати", + "Files": "Файли", + "Collecting app version information": "Збір інформації про версію застосунка", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Видалити псевдонім %(alias)s та прибрати з каталогу %(name)s?", + "customServer_text": "Ви можете скористатись нетиповими параметрами сервера щоб увійти в інші сервери Matrix, зазначивши посилання на окремий Домашній сервер
    Це дозволяє вам використовувати Riot із вже існуючою обліковкою Matrix на іншому Домашньому сервері.

    Ви також можете зазначити нетиповий сервер ідентифікації, але ви не матимете змоги ані запрошувати користувачів за е-поштою, ані бути запрошеними за е-поштою самі.", + "Co-ordination for Riot/Web translators": "Координація для перекладачів Riot/Web", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Це дозволить вам повернутися до своєї обліковки після виходу з неї, та заходити з інших пристроїв.", + "Dev chat for the Dendrite dev team": "Чат команди розробників Dendrite", + "Keywords": "Ключові слова", + "Enable notifications for this account": "Увімкнути сповіщення для цієї обліковки", + "Directory": "Каталог", + "Invite to this community": "Запросити в це суспільство", + "Failed to get public room list": "Не вдалось отримати перелік прилюдних кімнат", + "Messages containing keywords": "Повідомлення, що містять ключові слова", + "When I'm invited to a room": "Коли мене запрошено до кімнати", + "Tuesday": "Вівторок", + "Enter keywords separated by a comma:": "Введіть ключові слова через кому:", + "Forward Message": "Переслати повідомлення", + "You have successfully set a password and an email address!": "Пароль та адресу е-пошти успішно встановлено!", + "Remove %(name)s from the directory?": "Прибрати %(name)s з каталогу?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot використовує багато новітніх функцій, деякі з яких не доступні або є експериментальними у вашому оглядачі.", + "Developer Tools": "Інструменти розробника", + "Preparing to send logs": "Підготовка до відправки журланлу", + "Please install Chrome or Firefox for the best experience.": "Для більшої зручності у використанні встановіть, будь ласка, Chrome або Firefox.", + "Unnamed room": "Неназвана кімната", + "Explore Account Data": "Продивитись данні аккаунта", + "All messages (noisy)": "Усі повідомлення (гучно)", + "Away": "Нема на місці", + "Saturday": "Субота", + "I understand the risks and wish to continue": "Я ознайомлений з ризиками і хочу продовжити", + "Direct Chat": "Прямий чат", + "The server may be unavailable or overloaded": "Сервер може бути недосяжним або перевантаженим", + "Room not found": "Кімнату не знайдено", + "Reject": "Відмовитись", + "Riot is not supported on mobile web. Install the app?": "Riot не працює через оглядач на мобільних пристроях. Встановити застосунок?", + "Discussion of all things Matrix!": "Обговорення усіх деталей про Matrix!", + "Failed to set Direct Message status of room": "Не вдалось встановити статус прямого спілкування в кімнаті", + "Monday": "Понеділок", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "З метою діагностики проблем журнали з цього застосунку будуть надіслані разом зі звітом про вади. Якщо ви бажаєте надіслати лише вищенаведений текст, відозначте, будь ласка:", + "Send Custom State Event": "Відправити статус приватного заходу", + "Remove from Directory": "Прибрати з каталогу", + "Enable them now": "Увімкнути їх зараз", + "Messages containing my user name": "Повідомлення, що містять моє ім'я користувача", + "Describe your problem here.": "Опишіть вашу проблему тут.", + "Toolbox": "Панель інструментів", + "Collecting logs": "Збір журналів", + "more": "докладніше", + "Bug report sent": "Звіт про помилки відправлений", + "You must specify an event type!": "Необхідно вказати тип захода!", + "(HTTP status %(httpStatus)s)": "(статус HTTP %(httpStatus)s)", + "All Rooms": "Усі кімнати", + "Please install Chrome or Firefox for the best experience.": "Краще встановіть Chrome або Firefox.", + "Wednesday": "Середа", + "You cannot delete this message. (%(code)s)": "Ви не можете видалити це повідомлення. (%(code)s)", + "Quote": "Цитувати", + "Send": "Надіслати", + "Send logs": "Надіслати журнали", + "All messages": "Усі повідомлення", + "Implementing VoIP services with Matrix": "Впровадження служб VoIP через Matrix", + "Dev chat for the Riot/Web dev team": "Чат команди розробників Riot/Web", + "Call invitation": "Запрошення до виклику", + "Riot Desktop on %(platformName)s": "Riot Desktop на %(platformName)s", + "Downloading update...": "Звантаженя оновлення…", + "State Key": "Ключ стану", + "Failed to send custom event.": "Не вдалося відправити приватний захід.", + "What's new?": "Що нового?", + "Discussion of the Identity Service API": "Обговорення Identity Service API", + "Support for those using and running matrix-appservice-irc": "Підтримка користувачів matrix-appservice-irc", + "Riot/iOS & matrix-ios-sdk chat": "Обговорення Riot/iOS та matrix-ios-sdk", + "Notify me for anything else": "Сповіщати мене про будь-що інше", + "View Source": "Переглянути джерело", + "Design and implementation of E2E in Matrix": "Планування та впровадження E2E шифрування у Matrix", + "Click here to create a GitHub issue.": "Нажміть тут для створення запитання по проблемі на GitHub.", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Ви можете використовувати параметри користувача сервера для входа на другі сервера Matrix, вказав другий URL-адресу домашнього сервера.
    Це дозволяє використовувати Riot з обліковим записом Matrix який існує на другому домашньому сервері.

    Окрім цього, можливо встановити ідентифікаційний сервер користувача, але ви не зможете запросити других користувачів та бути запрошенному використовуючи адресу електронної пошти.", + "Can't update user notification settings": "Неможливо оновити налаштування користувацьких сповіщень", + "Notify for all other messages/rooms": "Сповіщати щодо всіх повідомлень/кімнат", + "Unable to look up room ID from server": "Неможливо знайти ID кімнати на сервері", + "Couldn't find a matching Matrix room": "Неможливо знайти відповідну кімнату", + "Support for those using the Matrix spec": "Підтримка користувачів специфікацій Matrix", + "Safari and Opera work too.": "Safari та Opera також підтримуються.", + "Loading bug report module": "Завантаження модуля звітів про вади", + "Invite to this room": "Запросити до цієї кімнати", + "Search for a room": "Пошук кімнати", + "Thursday": "Четвер", + "Search…": "Пошук…", + "Logs sent": "Журнали відправленні", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s через %(browserName)s на %(osName)s", + "Back": "Назад", + "Reply": "Відповісти", + "Show message in desktop notification": "Показати повідомлення в сповіщення на робочому столі", + "Announcements about Synapse releases": "Оголошення випусків Synapse", + "Search the room directory": "Шукати у каталозі кімнат", + "Please describe the bug and/or send logs.": "Опишіть, будь ласка, ваду та/або надішліть журнали.", + "Unable to join network": "Неможливо приєднатись до мережі", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Можливо, ви налаштували їх не у Riot, а у іншому застосунку. Ви не можете регулювати їх у Riot, але вони все ще мають силу", + "Sorry, your browser is not able to run Riot.": "Вибачте, ваш оглядач не спроможний запустити Riot.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "Децентралізований, шифрований чат та засіб для співробітництва, що працює на [matrix]", + "Uploaded on %(date)s by %(user)s": "Завантажено %(date)s користувачем %(user)s", + "Messages in group chats": "Повідомлення у групових чатах", + "Yesterday": "Вчора", + "Error encountered (%(errorDetail)s).": "Трапилась помилка (%(errorDetail)s).", + "Login": "Зайти", + "Low Priority": "Неважливі", + "Unable to fetch notification target list": "Неможливо отримати перелік цілей сповіщення", + "Appear Offline": "Відображати як не в мережі", + "Get started with some tips from Riot Bot!": "Розпочніть за допомогою декількох підказок від Riot-боту!", + "Set Password": "Задати пароль", + "Enable audible notifications in web client": "Увімкнути звукові сповіщення у мережевому застосунку", + "Permalink": "Постійне посилання", + "Welcome to Riot.im": "Ласкаво просимо до Riot.im", + "Off": "Вимкнено", + "Riot does not know how to join a room on this network": "Riot не знає як приєднатись до кімнати у цій мережі", + "Mentions only": "Тільки згадки", + "Failed to remove tag %(tagName)s from room": "Не вдалося прибрати з кімнати мітку %(tagName)s", + "You can now return to your account after signing out, and sign in on other devices.": "Тепер ви можете повернутися до своєї обліковки після виходу з неї, та зайти з інших пристроїв.", + "Enable desktop notifications": "Увімкнути сповіщення на стільниці", + "Enable email notifications": "Увімкнути сповіщення е-поштою", + "Event Type": "Тип західу", + "No rooms to show": "Кімнати відсутні", + "Download this file": "Звантажити цей файл", + "Pin Message": "Прикріпити повідомлення", + "Failed to change settings": "Не вдалось змінити налаштування", + "Event sent!": "Захід відправлено!", + "Unhide Preview": "Відкрити попередній перегляд", + "Event Content": "Зміст заходу", + "Thank you!": "Дякую!", + "Building services on Matrix": "Створення служб на основі Matrix", + "Collapse panel": "Згорнути панель", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "У вашому оглядачі вигляд застосунку може бути повністю іншим, а деякі або навіть усі функції можуть не працювати. Якщо ви наполягаєте, то можете продовжити користування, але ви маєте впоратись з усіма можливими проблемами власноруч!", + "Checking for an update...": "Перевірка оновлень…", + "Matrix technical discussions": "Технічні обговорення Matrix", + "There are advanced notifications which are not shown here": "Є додаткові сповіщення, що не показуються тут" } diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index c7e67319ef..ad5387ad40 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -803,5 +803,207 @@ "Failed to set direct chat tag": "无法设定私聊标签", "Failed to remove tag %(tagName)s from room": "移除聊天室标签 %(tagName)s 失败", "Failed to add tag %(tagName)s to room": "无法为聊天室新增标签 %(tagName)s", - "Submit debug logs": "提交调试日志" + "Submit debug logs": "提交调试日志", + "Fetching third party location failed": "获取第三方位置失败", + "A new version of Riot is available.": "Riot 有更新可用。", + "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk 聊天", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "请描述这个 bug,您做了什么动作?预期会发生的状况?以及实际发生的?", + "Couldn't load home page": "不能加载首页", + "Send Account Data": "发送账户数据", + "All notifications are currently disabled for all targets.": "当前所有目标的通知均已禁用。", + "Uploading report": "上传报告", + "Sunday": "星期日", + "Notification targets": "通知目标", + "Today": "今天", + "Failed to get protocol list from Home Server": "无法从主服务器取得协议列表", + "Report a bug": "报告一个 bug", + "Implementing VR services with Matrix": "使用 Matrix 实现虚拟现实服务", + "You are not receiving desktop notifications": "您将不会收到桌面通知", + "Friday": "星期五", + "Update": "更新", + "You need to be using HTTPS to place a screen-sharing call.": "你需要使用 HTTPS 来放置屏幕分享通话。", + "What's New": "新鲜事", + "Add an email address above to configure email notifications": "请在上方输入电子邮件地址以接收邮件通知", + "Expand panel": "展开面板", + "On": "打开", + "%(count)s Members|other": "%(count)s 位成员", + "Filter room names": "过滤聊天室名称", + "Changelog": "变更日志", + "Running Matrix services": "正在运行 Matrix 服务", + "Waiting for response from server": "正在等待服务器响应", + "Send Custom Event": "发送自定义事件", + "Failed to send report: ": "无法发送报告: ", + "Unknown device": "未知设备", + "Advanced notification settings": "通知高级设置", + "Failed to send logs: ": "无法发送日志: ", + "delete the alias.": "删除别名。", + "To return to your account in future you need to set a password": "要在未来回到您的账号,您需要 设置密码", + "Forget": "忘记", + "#example": "#例子", + "Riot/Web & Desktop chat": "Riot/Web & 桌面聊天", + "Hide panel": "隐藏面板", + "You cannot delete this image. (%(code)s)": "您不能删除这个图片。(%(code)s)", + "Cancel Sending": "取消发送", + "This Room": "此聊天室", + "The Home Server may be too old to support third party networks": "主服务器可能太老旧无法支持第三方网络", + "Noisy": "吵闹", + "Error saving email notification preferences": "保存电子邮件通知的首选项时出错", + "Messages containing my display name": "消息中含有我的显示名称", + "Messages in one-to-one chats": "一对一聊天种的消息", + "Contributing code to Matrix and Riot": "贡献程序代码给 Matrix 与 Riot", + "Unavailable": "无法获得", + "Community-run support for Synapse": "运行 Synapse 的社区支持", + "View Decrypted Source": "查看解密的来源", + "Failed to update keywords": "无法更新关键字", + "Notes:": "记录:", + "remove %(name)s from the directory.": "从目录中移除 %(name)s。", + "Notifications on the following keywords follow rules which can’t be displayed here:": "以下关键字依照规则将不会在此显示:", + "Safari and Opera work too.": "SafariOpera 也能工作。", + "Please set a password!": "请设置密码!", + "You have successfully set a password!": "您已成功设置密码!", + "Chat with Riot Bot": "与 Riot 机器人聊天", + "Support for those using, running and writing other bridges": "那些使用、运行并撰写其他桥接应用的支持", + "Admin support for Dendrite": "Dendrite 的管理员支持", + "An error occurred whilst saving your email notification preferences.": "保存邮件通知首选项设定时出现错误。", + "Explore Room State": "探索聊天室状态", + "Source URL": "源网址", + "Messages sent by bot": "由机器人发出的消息", + "Filter results": "过滤结果", + "Members": "成员", + "No update available.": "没有可用更新。", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Matrix 中已有许多聊天室,连接到已有的网络(Slack、IRC 与 Gitter 等)或独立的网络,请查看目录!", + "Resend": "重新发送", + "Files": "文件", + "Collecting app version information": "正在收集应用版本信息", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "确定要删除聊天室别名 %(alias)s 并将 %(name)s 从列表中删除吗?", + "customServer_text": "你可以通过指定自定义服务器选项中的其他主服务器的 URL 来登录其他 Matrix 服务器。
    该选项允许你在 Riot 上使用其他主服务器上的帐号。

    你也可以自定义身份验证服务器,但你将不能通过邮件邀请其他用户,同样的,你也不能通过邮件被其他用户邀请。", + "Co-ordination for Riot/Web translators": "Riot/Web 翻译者的协调区", + "This will allow you to return to your account after signing out, and sign in on other devices.": "这让您可以在注销后回到您的账号,并在其他设备上登录。", + "Dev chat for the Dendrite dev team": "Dendrite 的开发团队的开发聊天", + "Keywords": "关键字", + "Enable notifications for this account": "为本账号启用通知", + "Directory": "聊天室目录", + "Invite to this community": "邀请加入此社区", + "Failed to get public room list": "无法取得公开的聊天室列表", + "Messages containing keywords": "消息包含 关键字", + "Room not found": "找不到聊天室", + "Tuesday": "星期二", + "Enter keywords separated by a comma:": "输入以逗号间隔的关键字:", + "Forward Message": "转发消息", + "You have successfully set a password and an email address!": "您已经成功设置了密码和电子邮件地址!", + "Remove %(name)s from the directory?": "从目录中移除 %(name)s 吗?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot 使用了许多先进的浏览器功能,有些在你目前所用的浏览器上无法使用或仅为实验性的功能。", + "Developer Tools": "开发者工具", + "Preparing to send logs": "准备发送日志", + "Enable desktop notifications": "启用桌面通知", + "Remember, you can always set an email address in user settings if you change your mind.": "请记住,如果您改变想法,您永远可以在用户设置中设置电子邮件。", + "Explore Account Data": "探索账户数据", + "All messages (noisy)": "全部消息(高亮)", + "Away": "离开", + "Saturday": "星期六", + "I understand the risks and wish to continue": "我了解这些风险并愿意继续", + "Direct Chat": "私聊", + "The server may be unavailable or overloaded": "服务器可能无法使用或超过负载", + "Reject": "拒绝", + "Riot is not supported on mobile web. Install the app?": "Riot 不支持浏览器网页,要安装 app 吗?", + "Discussion of all things Matrix!": "讨论所有关于 Matrix 的事情!", + "Failed to set Direct Message status of room": "无法设置聊天室的私聊状态", + "Monday": "星期一", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "为了诊断问题,来自客户端的活动记录会随着这个程序 bug 报告一并发出。如果你只想送出以上文字,请取消勾选:", + "Send Custom State Event": "发送自定义状态事件", + "Remove from Directory": "从目录中移除", + "Enable them now": "现在启用", + "Messages containing my user name": "消息中包含我的用户名", + "Describe your problem here.": "在这里描述你的问题。", + "Toolbox": "工具箱", + "Collecting logs": "正在收集日志", + "more": "更多", + "GitHub issue link:": "Github issue 链接:", + "Bug report sent": "发送DEBUG报告", + "You must specify an event type!": "你必须制定一个事件类型!", + "(HTTP status %(httpStatus)s)": "(HTTP 状态 %(httpStatus)s)", + "All Rooms": "全部聊天室", + "Please install Chrome or Firefox for the best experience.": "请安装 ChromeFirefox 以获得最佳体验。", + "Wednesday": "星期三", + "You cannot delete this message. (%(code)s)": "您不能删除此消息。(%(code)s)", + "Quote": "引述", + "Send logs": "发送日志", + "All messages": "全部消息", + "Implementing VoIP services with Matrix": "使用 Matrix 实现 VoIP 服务", + "Dev chat for the Riot/Web dev team": "Riot/Web 开发团队的开发聊天", + "Call invitation": "语音邀请", + "Riot Desktop on %(platformName)s": "Riot 桌面版在 %(platformName)s", + "Downloading update...": "正在下载更新…", + "State Key": "状态密钥", + "Failed to send custom event.": "发送自定义事件失败。", + "What's new?": "有什么新闻?", + "Discussion of the Identity Service API": "识别服务 API 的讨论", + "Support for those using and running matrix-appservice-irc": "使用与执行 matrix-appservice-irc 的支持", + "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk 聊天", + "Notify me for anything else": "所有消息都通知我", + "When I'm invited to a room": "当我被邀请进入聊天室", + "Design and implementation of E2E in Matrix": "在 Matrix 中 E2E 的设计与实现", + "Click here to create a GitHub issue.": "点击这里 创建一个 GitHub issue.", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "您可以使用自订的服务器选项,并指定不同的主服务器 URL 来登录其他的 Matrix 服务器。
    这让您可以在不同的服务器上以既有的 Matrix 帐号使用 Riot。

    您也可以设置一个自订的身份服务器,但您可能无法透过电子邮件地址来邀请用户,或是让别人透过电子邮件邀请您。", + "Can't update user notification settings": "不能更新用户通知设置", + "Notify for all other messages/rooms": "为所有其他消息/聊天室显示通知", + "Unable to look up room ID from server": "无法在服务器上找到聊天室 ID", + "Couldn't find a matching Matrix room": "未找到符合的 Matrix 聊天室", + "Support for those using the Matrix spec": "使用 Matrix 规范的支持", + "Safari and Opera work too.": "SafariOpera 均可运行。", + "Loading bug report module": "正在载入 bug 报告模块", + "Invite to this room": "邀请别人加入此聊天室", + "Search for a room": "搜索聊天室", + "Thursday": "星期四", + "Search…": "搜索…", + "Logs sent": "记录已发送", + "%(appName)s via %(browserName)s on %(osName)s": "应用 %(appName)s 通过 %(osName)s 上的 %(browserName)s 浏览器运行", + "Back": "返回", + "Reply": "回复", + "Show message in desktop notification": "在桌面通知中显示信息", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "调试日志包含使用数据(包括您的用户名,您访问过的聊天室 / 小组的 ID 或别名以及其他用户的用户名)。它们不包含聊天信息。", + "Unhide Preview": "取消隐藏预览", + "Announcements about Synapse releases": "Synapse 的发布公告", + "Search the room directory": "搜索聊天室目录", + "Please describe the bug and/or send logs.": "请描述这个 bug 和/或发送日志。", + "Unable to join network": "无法加入网络", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "您也许不曾在其他 Riot 之外的客户端设置它们。在 Riot 下你无法调整他们但仍然可用", + "Sorry, your browser is not able to run Riot.": "抱歉,您的浏览器 无法 运行 Riot.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "去中心化,加密聊天 & 由 [matrix] 提供", + "Uploaded on %(date)s by %(user)s": "由 %(user)s 在 %(date)s 上传", + "Messages in group chats": "群组聊天中的消息", + "Yesterday": "昨天", + "Error encountered (%(errorDetail)s).": "遇到错误 (%(errorDetail)s)。", + "Login": "登录", + "Low Priority": "低优先级", + "Unable to fetch notification target list": "无法获取通知目标列表", + "Appear Offline": "似乎离线了", + "Get started with some tips from Riot Bot!": "使用从 Riot 机器人学来的小窍门开始!", + "Set Password": "设置密码", + "Enable audible notifications in web client": "在网页客户端启用音频通知", + "Permalink": "永久链接", + "Welcome to Riot.im": "欢迎来到 Riot.im", + "Off": "关闭", + "Riot does not know how to join a room on this network": "Riot 不知道如何在此网络中加入聊天室", + "Mentions only": "只限提及", + "You can now return to your account after signing out, and sign in on other devices.": "您可以在注销后回到您的账号,并在其他设备上登录。", + "Please install Chrome or Firefox for the best experience.": "请安装 ChromeFirefox 来得到最佳体验。", + "Enable email notifications": "启用电子邮件通知", + "Event Type": "事件类型", + "Download this file": "下载该文件", + "Pin Message": "置顶消息", + "Failed to change settings": "变更设置失败", + "View Community": "查看社区", + "%(count)s Members|one": "%(count)s 位成员", + "Event sent!": "事件已发出!", + "View Source": "查看源码", + "Matrix technical discussions": "Matrix 技术讨论", + "Event Content": "事件内容", + "Thank you!": "谢谢!", + "Building services on Matrix": "正在 Matrix 上建立服务", + "Collapse panel": "折叠面板", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "您目前的浏览器,应用程序的外观和感觉完全不正确,有些或全部功能可能无法使用。如果您仍想继续尝试,可以继续,但请自行负担其后果!", + "Checking for an update...": "正在检查更新…", + "General discussion about Matrix and Riot": "关于 Matrix 与 Riot 的一般讨论", + "There are advanced notifications which are not shown here": "更多的通知并没有在此显示出来" } diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 0be62a27e5..3ed45061f4 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -1015,5 +1015,207 @@ "Show Stickers": "顯示貼圖", "Manage sticker packs": "管理貼圖包", "Who can join this community?": "誰可以加入此社群?", - "Everyone": "每個人" + "Everyone": "每個人", + "Fetching third party location failed": "抓取第三方位置失敗", + "A new version of Riot is available.": "Riot 釋出了新版本。", + "Riot/Android & matrix-android-sdk chat": "Riot/Android 與 matrix-android-sdk 的討論", + "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "請描述這個程式臭蟲,您做了什麼動作?您預期會發生什麼狀況?以及實際發生的狀況為何?", + "I understand the risks and wish to continue": "我了解這些風險並願意繼續", + "Couldn't load home page": "無法載入首頁", + "Send Account Data": "傳送帳號資料", + "Advanced notification settings": "進階通知設定", + "Uploading report": "上傳報告", + "Sunday": "星期日", + "Notification targets": "通知目標", + "Today": "今天", + "Failed to get protocol list from Home Server": "無法從主機伺服器取得協定清單", + "Report a bug": "回報程式臭蟲", + "Implementing VR services with Matrix": "使用 Matrix 實作虛擬實境服務的討論", + "You are not receiving desktop notifications": "你將不會收到桌面通知", + "Friday": "星期五", + "Update": "更新", + "You need to be using HTTPS to place a screen-sharing call.": "你需要使用 HTTPS 來放置螢幕分享的通話。", + "Unable to fetch notification target list": "無法抓取通知的目標清單", + "Add an email address above to configure email notifications": "在上面新增電子郵件以設定電子郵件通知", + "Expand panel": "展開面板", + "On": "開啟", + "%(count)s Members|other": "%(count)s 個成員", + "Filter room names": "過濾聊天室名稱", + "Changelog": "變更記錄", + "Running Matrix services": "關於 Matrix 服務營運", + "Waiting for response from server": "正在等待來自伺服器的回應", + "Uploaded on %(date)s by %(user)s": "由 %(user)s 在 %(date)s 上傳", + "Send Custom Event": "傳送自訂事件", + "Failed to send report: ": "無法傳送報告: ", + "Unknown device": "未知裝置", + "All notifications are currently disabled for all targets.": "目前所有的通知功能已停用。", + "Failed to send logs: ": "無法傳送除錯訊息: ", + "delete the alias.": "刪除別名。", + "To return to your account in future you need to set a password": "未來若需回來使用您的帳號,您需要 設定密碼", + "Forget": "忘記", + "Riot/Web & Desktop chat": "Riot/Web 與桌面版的討論", + "Hide panel": "隱藏面板", + "You cannot delete this image. (%(code)s)": "你不能刪除這個圖片。(%(code)s)", + "Cancel Sending": "取消傳送", + "This Room": "這個聊天室", + "The Home Server may be too old to support third party networks": "主機伺服器可能太老舊無法支援第三方網路", + "Resend": "重新傳送", + "Room not found": "找不到聊天室", + "Messages containing my display name": "訊息中有包含我的顯示名稱", + "Messages in one-to-one chats": "在一對一聊天中的訊息", + "Contributing code to Matrix and Riot": "關於貢獻 Matrix 和 Riot", + "Unavailable": "無法取得", + "Community-run support for Synapse": "Synapse 社群支援聊天室", + "Error saving email notification preferences": "儲存電子郵件通知偏好設定時出錯", + "View Decrypted Source": "檢視解密的來源", + "Failed to update keywords": "無法更新關鍵字", + "Notes:": "備註:", + "remove %(name)s from the directory.": "自目錄中移除 %(name)s。", + "Notifications on the following keywords follow rules which can’t be displayed here:": "以下關鍵字依照規則其通知將不會顯示在此:", + "Safari and Opera work too.": "SafariOpera 也可以運作。", + "Please set a password!": "請設定密碼!", + "You have successfully set a password!": "您已經成功設定密碼!", + "Chat with Riot Bot": "與 Riot 機器人聊天", + "Support for those using, running and writing other bridges": "使用、執行與撰寫其他橋接服務的支援聊天室", + "Admin support for Dendrite": "Dendrite 管理員支援聊天室", + "An error occurred whilst saving your email notification preferences.": "在儲存你的電子郵件通知偏好時發生錯誤。", + "Explore Room State": "探索聊天室狀態", + "Source URL": "來源網址", + "Messages sent by bot": "由機器人送出的訊息", + "Filter results": "過濾結果", + "Members": "成員", + "No update available.": "沒有可用的更新。", + "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Matrix 中已有許多聊天室,連結到已有的網路(Slack、IRC 與 Gitter 等等)或是獨立的網路。來看看聊天室目錄吧!", + "Noisy": "吵鬧", + "Files": "檔案", + "Collecting app version information": "收集應用程式版本資訊", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "刪除聊天室別名 %(alias)s 並從目錄移除 %(name)s?", + "customServer_text": "你可以使用自訂伺服器選項來登入其它的 Matrix 伺服器,只要在在主機伺服器網址上指定其網址資料。
    這可讓你透過已有的 Matrix 帳號在不同的主機伺服器上使用 Riot。

    你也可以設定自定的識別伺服器但你將無法透過電子郵件來邀請用戶或是以自己的電子郵件來接受別人的邀請。", + "Co-ordination for Riot/Web translators": "Riot/Web 翻譯者的協調聊天室", + "This will allow you to return to your account after signing out, and sign in on other devices.": "這讓您可以在登入後回到您帳號,並在其他裝置上登入。", + "Dev chat for the Dendrite dev team": "Dendrite 開發團隊的開發聊天室", + "Design and implementation of E2E in Matrix": "Matrix 中點對點加密的設計與實作討論", + "Enable notifications for this account": "本帳號啟用通知", + "Directory": "目錄", + "Invite to this community": "邀請至此社群", + "Search for a room": "搜尋聊天室", + "Messages containing keywords": "訊息包含 關鍵字", + "When I'm invited to a room": "當我被邀請加入聊天室", + "Tuesday": "星期二", + "Enter keywords separated by a comma:": "輸入以逗號隔開的關鍵字:", + "Forward Message": "轉寄訊息", + "You have successfully set a password and an email address!": "您已經成功設定密碼與電子郵件地址!", + "Remove %(name)s from the directory?": "自目錄中移除 %(name)s?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot 使用了許多先進的瀏覽器功能,有些在你目前所用的瀏覽器上無法使用或僅為實驗中的功能。", + "Developer Tools": "開發者工具", + "Preparing to send logs": "準備傳送除錯訊息", + "Enable desktop notifications": "啟用桌面通知", + "Explore Account Data": "探索帳號資料", + "All messages (noisy)": "所有訊息(吵鬧)", + "Away": "離開", + "Saturday": "星期六", + "Remember, you can always set an email address in user settings if you change your mind.": "記住,如果您改變心意了,您永遠可以在使用者設定中設定電子郵件地址。", + "Direct Chat": "私人聊天", + "The server may be unavailable or overloaded": "伺服器可能無法使用或是超過負載", + "Reject": "拒絕", + "Riot is not supported on mobile web. Install the app?": "Riot 不支援行動版網頁,要安裝應用程式嗎?", + "Discussion of all things Matrix!": "所有 Matrix 相關的一般討論", + "Failed to set Direct Message status of room": "無法設定聊天室的私人訊息狀態", + "Monday": "星期一", + "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "為了診斷問題,來自客戶端的活動記錄會隨著這個程式臭蟲報告一起送出。如果你只想送出以上文字,請取消勾選:", + "Send Custom State Event": "傳送自訂狀態事件", + "Remove from Directory": "自目錄中移除", + "Enable them now": "現在啟用", + "Messages containing my user name": "訊息中有我的使用者名稱", + "Describe your problem here.": "在此描述你的問題。", + "Toolbox": "工具箱", + "Collecting logs": "收集記錄", + "more": "更多", + "GitHub issue link:": "GitHub 問題回報連結:", + "Bug report sent": "已傳送臭蟲回報", + "You must specify an event type!": "您必須指定事件類型!", + "(HTTP status %(httpStatus)s)": "(HTTP 狀態 %(httpStatus)s)", + "All Rooms": "所有的聊天室", + "What's New": "新鮮事", + "Please install Chrome or Firefox for the best experience.": "請安裝 ChromeFirefox 以取得最佳體驗。", + "Failed to get public room list": "無法取得公開的聊天室清單", + "Send logs": "傳送記錄", + "All messages": "所有訊息", + "Implementing VoIP services with Matrix": "使用 Matrix 實作 VoIP 服務的討論", + "Dev chat for the Riot/Web dev team": "Riot/Web 開發團隊的開發聊天室", + "Call invitation": "通話邀請", + "Riot Desktop on %(platformName)s": "Riot 桌面版在 %(platformName)s", + "Downloading update...": "正在下䵧更新...", + "State Key": "狀態金鑰", + "Failed to send custom event.": "傳送自訂式件失敗。", + "What's new?": "有什麼新聞?", + "Discussion of the Identity Service API": "識別服務 API 的討論", + "Support for those using and running matrix-appservice-irc": "matrix-appservice-irc 使用者與營運的支援", + "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS 與 matrix-ios-sdk 的討論", + "Notify me for anything else": "所有消息都通知我", + "View Source": "檢視來源", + "Keywords": "關鍵字", + "Click here to create a GitHub issue.": "點選這裡來建立 GitHub 問題回報。", + "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "您可以使用自訂的伺服器選項,並指定不同的家伺服器 URL 來登入其他的 Matrix 伺服器。
    這讓您可以在不同的伺服器上以既有的 Matrix 帳號使用 Riot。

    您也可以設定一個自訂的識別伺服器,但您可能無法透過電子郵件地址來邀請使用者,或是讓別人透過電子郵件邀請您。", + "Can't update user notification settings": "無法更新使用者的通知設定", + "Notify for all other messages/rooms": "通知其他所有的訊息/聊天室", + "Unable to look up room ID from server": "無法從伺服器找到聊天室 ID", + "Couldn't find a matching Matrix room": "不能找到符合 Matrix 的聊天室", + "Support for those using the Matrix spec": "Matrix 規格使用者支援聊天室", + "Safari and Opera work too.": "SafariOpera 也能使用。", + "Loading bug report module": "正在載入程式臭蟲報告模組", + "Invite to this room": "邀請加入這個聊天室", + "You cannot delete this message. (%(code)s)": "你不能刪除這個訊息。(%(code)s)", + "Thursday": "星期四", + "Search…": "搜尋…", + "Logs sent": "除錯訊息已經傳送", + "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s 透過 %(browserName)s 在 %(osName)s", + "Back": "返回", + "Reply": "回覆", + "Show message in desktop notification": "在桌面通知中顯示訊息", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "除錯訊息包含應用程式的使用資料,包括您的使用者名稱、您所造訪的房間/群組的 ID 或別名、其他使用者的使用者名稱等,其中不包含訊息本身。", + "Unhide Preview": "取消隱藏預覽", + "Announcements about Synapse releases": "Synapse 發行公告", + "Search the room directory": "搜尋聊天室目錄", + "Please describe the bug and/or send logs.": "請描述這個程式臭蟲以及/或送出活動記錄。", + "Unable to join network": "無法加入網路", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "你也許不曾在其它 Riot 之外的客戶端設定它們。在 Riot 底下你無法調整它們但其仍然可用", + "Sorry, your browser is not able to run Riot.": "可惜,您的瀏覽器 無法 執行 Riot.", + "Decentralised, encrypted chat & collaboration powered by [matrix]": "去中心化、保密的聊天與協作,由 [matrix] 出品", + "Building services on Matrix": "關於在 Matrix 上開發服務", + "Messages in group chats": "在群組聊天中的訊息", + "Yesterday": "昨天", + "Error encountered (%(errorDetail)s).": "遇到錯誤 (%(errorDetail)s)。", + "Login": "登入", + "Low Priority": "低優先度", + "Riot does not know how to join a room on this network": "Riot 不知道如何在此網路中加入聊天室", + "Appear Offline": "顯示為離線", + "Get started with some tips from Riot Bot!": "從 Riot 機器人了解使用 Riot 的訣竅吧!", + "Set Password": "設定密碼", + "Enable audible notifications in web client": "在網頁客戶端啟用音訊通知", + "Permalink": "永久連結", + "Welcome to Riot.im": "歡迎來到 Riot.im", + "Off": "關閉", + "#example": "#範例", + "Mentions only": "僅提及", + "Wednesday": "星期三", + "You can now return to your account after signing out, and sign in on other devices.": "您可以在登出後回到您的帳號,並在其他裝置上登入。", + "Please install Chrome or Firefox for the best experience.": "諘安裝 ChromeFirefox 來取得最佳體驗。", + "Enable email notifications": "啟用電子郵件通知", + "Event Type": "事件類型", + "Download this file": "下載這個檔案", + "Pin Message": "釘選訊息", + "Failed to change settings": "變更設定失敗", + "View Community": "檢視社群", + "%(count)s Members|one": "%(count)s 個成員", + "Event sent!": "事件已傳送!", + "Matrix technical discussions": "Matrix 技術討論", + "Event Content": "事件內容", + "Thank you!": "感謝您!", + "Quote": "引用", + "Collapse panel": "摺疊面板", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "您目前的瀏覽器,其應用程式的外觀和感覺可能完全不正確,有些或全部功能可以無法使用。如果您仍想要繼續嘗試,可以繼續,但必須自行承擔後果!", + "Checking for an update...": "正在檢查更新...", + "General discussion about Matrix and Riot": "Matrix 與 Riot 的一般討論", + "There are advanced notifications which are not shown here": "有些進階的通知並未在此顯示" } From cb5ff404e10ae74d7c1b765ecc3dfc990abbbe48 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 15 Apr 2018 23:16:31 +0100 Subject: [PATCH 0784/1160] fix missing i18n --- src/components/views/dialogs/BugReportDialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/dialogs/BugReportDialog.js b/src/components/views/dialogs/BugReportDialog.js index 3c10919ecf..086cb98cde 100644 --- a/src/components/views/dialogs/BugReportDialog.js +++ b/src/components/views/dialogs/BugReportDialog.js @@ -65,7 +65,7 @@ export default class BugReportDialog extends React.Component { if (!this._unmounted) { this.props.onFinished(false); const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - Modal.createTrackedDialog('Bug report sent', '', QuestionDialog, { + Modal.createTrackedDialog(_t('Bug report sent'), '', QuestionDialog, { title: _t('Logs sent'), description: _t('Thank you!'), hasCancelButton: false, From faa19249021736a112bbf1eee03122db974ae5d1 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 15 Apr 2018 23:18:18 +0100 Subject: [PATCH 0785/1160] run gen-i18n to normalise en_EN and remove stuff still in vector-web --- src/i18n/strings/en_EN.json | 384 ++++++++++++++++-------------------- 1 file changed, 174 insertions(+), 210 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index df15766ae1..31d202b0a3 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -100,6 +100,7 @@ "You need to be logged in.": "You need to be logged in.", "You need to be able to invite users to do that.": "You need to be able to invite users to do that.", "Unable to create widget.": "Unable to create widget.", + "Missing roomId.": "Missing roomId.", "Failed to send request.": "Failed to send request.", "This room is not recognised.": "This room is not recognised.", "Power level must be positive integer.": "Power level must be positive integer.", @@ -186,6 +187,8 @@ "Message Replies": "Message Replies", "Message Pinning": "Message Pinning", "Presence Management": "Presence Management", + "Tag Panel": "Tag Panel", + "Sticker Messages": "Sticker Messages", "Disable Emoji suggestions while typing": "Disable Emoji suggestions while typing", "Use compact timeline layout": "Use compact timeline layout", "Hide removed messages": "Hide removed messages", @@ -211,6 +214,17 @@ "Enable URL previews for this room (only affects you)": "Enable URL previews for this room (only affects you)", "Enable URL previews by default for participants in this room": "Enable URL previews by default for participants in this room", "Room Colour": "Room Colour", + "Collecting app version information": "Collecting app version information", + "Collecting logs": "Collecting logs", + "Uploading report": "Uploading report", + "Waiting for response from server": "Waiting for response from server", + "Messages containing my display name": "Messages containing my display name", + "Messages containing my user name": "Messages containing my user name", + "Messages in one-to-one chats": "Messages in one-to-one chats", + "Messages in group chats": "Messages in group chats", + "When I'm invited to a room": "When I'm invited to a room", + "Call invitation": "Call invitation", + "Messages sent by bot": "Messages sent by bot", "Active call (%(roomName)s)": "Active call (%(roomName)s)", "unknown caller": "unknown caller", "Incoming voice call from %(name)s": "Incoming voice call from %(name)s", @@ -252,16 +266,36 @@ "Failed to set display name": "Failed to set display name", "Disable Notifications": "Disable Notifications", "Enable Notifications": "Enable Notifications", + "Error saving email notification preferences": "Error saving email notification preferences", + "An error occurred whilst saving your email notification preferences.": "An error occurred whilst saving your email notification preferences.", + "Keywords": "Keywords", + "Enter keywords separated by a comma:": "Enter keywords separated by a comma:", + "OK": "OK", + "Failed to change settings": "Failed to change settings", + "Can't update user notification settings": "Can't update user notification settings", + "Failed to update keywords": "Failed to update keywords", + "Messages containing keywords": "Messages containing keywords", + "Notify for all other messages/rooms": "Notify for all other messages/rooms", + "Notify me for anything else": "Notify me for anything else", + "Enable notifications for this account": "Enable notifications for this account", + "All notifications are currently disabled for all targets.": "All notifications are currently disabled for all targets.", + "Add an email address above to configure email notifications": "Add an email address above to configure email notifications", + "Enable email notifications": "Enable email notifications", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Notifications on the following keywords follow rules which can’t be displayed here:", + "Unable to fetch notification target list": "Unable to fetch notification target list", + "Notification targets": "Notification targets", + "Advanced notification settings": "Advanced notification settings", + "There are advanced notifications which are not shown here": "There are advanced notifications which are not shown here", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply", + "Enable desktop notifications": "Enable desktop notifications", + "Show message in desktop notification": "Show message in desktop notification", + "Enable audible notifications in web client": "Enable audible notifications in web client", + "Off": "Off", + "On": "On", + "Noisy": "Noisy", "Cannot add any more widgets": "Cannot add any more widgets", "The maximum permitted number of widgets have already been added to this room.": "The maximum permitted number of widgets have already been added to this room.", "Add a widget": "Add a widget", - "Stickerpack": "Stickerpack", - "Sticker Messages": "Sticker Messages", - "You don't currently have any stickerpacks enabled": "You don't currently have any stickerpacks enabled", - "Click": "Click", - "here": "here", - "to add some!": "to add some!", - "Add a stickerpack": "Add a stickerpack", "Drop File Here": "Drop File Here", "Drop file here to upload": "Drop file here to upload", " (unsupported)": " (unsupported)", @@ -329,10 +363,6 @@ "Hangup": "Hangup", "Voice call": "Voice call", "Video call": "Video call", - "Hide Apps": "Hide Apps", - "Show Apps": "Show Apps", - "Hide Stickers": "Hide Stickers", - "Show Stickers": "Show Stickers", "Upload file": "Upload file", "Show Text Formatting Toolbar": "Show Text Formatting Toolbar", "Send an encrypted reply…": "Send an encrypted reply…", @@ -479,7 +509,15 @@ "Advanced": "Advanced", "This room's internal ID is": "This room's internal ID is", "Add a topic": "Add a topic", + "Search…": "Search…", + "This Room": "This Room", + "All Rooms": "All Rooms", "Cancel": "Cancel", + "You don't currently have any stickerpacks enabled": "You don't currently have any stickerpacks enabled", + "Add a stickerpack": "Add a stickerpack", + "Stickerpack": "Stickerpack", + "Hide Stickers": "Hide Stickers", + "Show Stickers": "Show Stickers", "Scroll to unread messages": "Scroll to unread messages", "Jump to first unread message.": "Jump to first unread message.", "Close": "Close", @@ -506,6 +544,15 @@ "URL previews are enabled by default for participants in this room.": "URL previews are enabled by default for participants in this room.", "URL previews are disabled by default for participants in this room.": "URL previews are disabled by default for participants in this room.", "URL Previews": "URL Previews", + "Sunday": "Sunday", + "Monday": "Monday", + "Tuesday": "Tuesday", + "Wednesday": "Wednesday", + "Thursday": "Thursday", + "Friday": "Friday", + "Saturday": "Saturday", + "Today": "Today", + "Yesterday": "Yesterday", "Error decrypting audio": "Error decrypting audio", "Error decrypting attachment": "Error decrypting attachment", "Decrypt %(text)s": "Decrypt %(text)s", @@ -583,16 +630,29 @@ "Something went wrong when trying to get your communities.": "Something went wrong when trying to get your communities.", "Display your community flair in rooms configured to show it.": "Display your community flair in rooms configured to show it.", "You're not currently a member of any communities.": "You're not currently a member of any communities.", + "You are not receiving desktop notifications": "You are not receiving desktop notifications", + "Enable them now": "Enable them now", + "What's New": "What's New", + "Update": "Update", + "What's new?": "What's new?", + "A new version of Riot is available.": "A new version of Riot is available.", + "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", + "Set Password": "Set Password", + "Error encountered (%(errorDetail)s).": "Error encountered (%(errorDetail)s).", + "Checking for an update...": "Checking for an update...", + "No update available.": "No update available.", + "Downloading update...": "Downloading update...", + "Warning": "Warning", "Unknown Address": "Unknown Address", "NOTE: Apps are not end-to-end encrypted": "NOTE: Apps are not end-to-end encrypted", "Do you want to load widget from URL:": "Do you want to load widget from URL:", "Allow": "Allow", - "Manage sticker packs": "Manage sticker packs", "Delete Widget": "Delete Widget", "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?", "Delete widget": "Delete widget", "Revoke widget access": "Revoke widget access", "Minimize apps": "Minimize apps", + "Picture": "Picture", "Edit": "Edit", "Create new room": "Create new room", "Unblacklist": "Unblacklist", @@ -603,6 +663,9 @@ "Delete": "Delete", "Communities": "Communities", "Home": "Home", + "You cannot delete this image. (%(code)s)": "You cannot delete this image. (%(code)s)", + "Uploaded on %(date)s by %(user)s": "Uploaded on %(date)s by %(user)s", + "Download this file": "Download this file", "Integrations Error": "Integrations Error", "Could not connect to the integration server": "Could not connect to the integration server", "Manage Integrations": "Manage Integrations", @@ -673,6 +736,19 @@ "email address": "email address", "Try using one of the following valid address types: %(validTypesList)s.": "Try using one of the following valid address types: %(validTypesList)s.", "You have entered an invalid address.": "You have entered an invalid address.", + "Preparing to send logs": "Preparing to send logs", + "Bug report sent": "Bug report sent", + "Logs sent": "Logs sent", + "Thank you!": "Thank you!", + "Failed to send logs: ": "Failed to send logs: ", + "Submit debug logs": "Submit debug logs", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.", + "Click here to create a GitHub issue.": "Click here to create a GitHub issue.", + "GitHub issue link:": "GitHub issue link:", + "Notes:": "Notes:", + "Send logs": "Send logs", + "Unavailable": "Unavailable", + "Changelog": "Changelog", "Create a new chat or reuse an existing one": "Create a new chat or reuse an existing one", "Start new chat": "Start new chat", "You already have existing direct chats with this user:": "You already have existing direct chats with this user:", @@ -707,8 +783,21 @@ "In future this verification process will be more sophisticated.": "In future this verification process will be more sophisticated.", "Verify device": "Verify device", "I verify that the keys match": "I verify that the keys match", + "Back": "Back", + "Send Custom Event": "Send Custom Event", + "You must specify an event type!": "You must specify an event type!", + "Event sent!": "Event sent!", + "Failed to send custom event.": "Failed to send custom event.", + "Event Type": "Event Type", + "State Key": "State Key", + "Event Content": "Event Content", + "Send Account Data": "Send Account Data", + "Filter results": "Filter results", + "Explore Room State": "Explore Room State", + "Explore Account Data": "Explore Account Data", + "Toolbox": "Toolbox", + "Developer Tools": "Developer Tools", "An error has occurred.": "An error has occurred.", - "OK": "OK", "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.", "Start verification": "Start verification", @@ -737,6 +826,14 @@ "To get started, please pick a username!": "To get started, please pick a username!", "This will be your account name on the homeserver, or you can pick a different server.": "This will be your account name on the homeserver, or you can pick a different server.", "If you already have a Matrix account you can log in instead.": "If you already have a Matrix account you can log in instead.", + "You have successfully set a password!": "You have successfully set a password!", + "You have successfully set a password and an email address!": "You have successfully set a password and an email address!", + "You can now return to your account after signing out, and sign in on other devices.": "You can now return to your account after signing out, and sign in on other devices.", + "Remember, you can always set an email address in user settings if you change your mind.": "Remember, you can always set an email address in user settings if you change your mind.", + "Failed to change password. Is your password correct?": "Failed to change password. Is your password correct?", + "(HTTP status %(httpStatus)s)": "(HTTP status %(httpStatus)s)", + "Please set a password!": "Please set a password!", + "This will allow you to return to your account after signing out, and sign in on other devices.": "This will allow you to return to your account after signing out, and sign in on other devices.", "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.", "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.", "Room contains unknown devices": "Room contains unknown devices", @@ -746,6 +843,36 @@ "Public Chat": "Public Chat", "Custom": "Custom", "Alias (optional)": "Alias (optional)", + "You cannot delete this message. (%(code)s)": "You cannot delete this message. (%(code)s)", + "Resend": "Resend", + "Cancel Sending": "Cancel Sending", + "Forward Message": "Forward Message", + "Reply": "Reply", + "Pin Message": "Pin Message", + "View Source": "View Source", + "View Decrypted Source": "View Decrypted Source", + "Unhide Preview": "Unhide Preview", + "Permalink": "Permalink", + "Quote": "Quote", + "Source URL": "Source URL", + "Away": "Away", + "Appear Offline": "Appear Offline", + "Failed to set Direct Message status of room": "Failed to set Direct Message status of room", + "All messages (noisy)": "All messages (noisy)", + "All messages": "All messages", + "Mentions only": "Mentions only", + "Leave": "Leave", + "Forget": "Forget", + "Reject": "Reject", + "Low Priority": "Low Priority", + "Direct Chat": "Direct Chat", + "View Community": "View Community", + "Sorry, your browser is not able to run Riot.": "Sorry, your browser is not able to run Riot.", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.", + "Please install Chrome or Firefox for the best experience.": "Please install Chrome or Firefox for the best experience.", + "Safari and Opera work too.": "Safari and Opera work too.", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!", + "I understand the risks and wish to continue": "I understand the risks and wish to continue", "Name": "Name", "Topic": "Topic", "Make this room private": "Make this room private", @@ -775,7 +902,6 @@ "Unable to join community": "Unable to join community", "Leave Community": "Leave Community", "Leave %(groupName)s?": "Leave %(groupName)s?", - "Leave": "Leave", "Unable to leave community": "Unable to leave community", "Community Settings": "Community Settings", "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.", @@ -785,17 +911,19 @@ "Featured Users:": "Featured Users:", "%(inviter)s has invited you to join this community": "%(inviter)s has invited you to join this community", "Join this community": "Join this community", + "Leave this community": "Leave this community", "You are an administrator of this community": "You are an administrator of this community", "You are a member of this community": "You are a member of this community", "Who can join this community?": "Who can join this community?", "Everyone": "Everyone", - "Leave this community": "Leave this community", "Your community hasn't got a Long Description, a HTML page to show to community members.
    Click here to open settings and give it one!": "Your community hasn't got a Long Description, a HTML page to show to community members.
    Click here to open settings and give it one!", "Long Description (HTML)": "Long Description (HTML)", "Description": "Description", "Community %(groupId)s not found": "Community %(groupId)s not found", "This Home server does not support communities": "This Home server does not support communities", "Failed to load %(groupId)s": "Failed to load %(groupId)s", + "Couldn't load home page": "Couldn't load home page", + "Login": "Login", "Reject invitation": "Reject invitation", "Are you sure you want to reject the invitation?": "Are you sure you want to reject the invitation?", "Failed to reject invitation": "Failed to reject invitation", @@ -816,6 +944,32 @@ "Join an existing community": "Join an existing community", "To join an existing community you'll have to know its community identifier; this will look something like +example:matrix.org.": "To join an existing community you'll have to know its community identifier; this will look something like +example:matrix.org.", "You have no visible notifications": "You have no visible notifications", + "Members": "Members", + "%(count)s Members|other": "%(count)s Members", + "%(count)s Members|one": "%(count)s Member", + "Invite to this room": "Invite to this room", + "Files": "Files", + "Notifications": "Notifications", + "Hide panel": "Hide panel", + "Invite to this community": "Invite to this community", + "Failed to get protocol list from Home Server": "Failed to get protocol list from Home Server", + "The Home Server may be too old to support third party networks": "The Home Server may be too old to support third party networks", + "Failed to get public room list": "Failed to get public room list", + "The server may be unavailable or overloaded": "The server may be unavailable or overloaded", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Delete the room alias %(alias)s and remove %(name)s from the directory?", + "Remove %(name)s from the directory?": "Remove %(name)s from the directory?", + "Remove from Directory": "Remove from Directory", + "remove %(name)s from the directory.": "remove %(name)s from the directory.", + "delete the alias.": "delete the alias.", + "Unable to join network": "Unable to join network", + "Riot does not know how to join a room on this network": "Riot does not know how to join a room on this network", + "Room not found": "Room not found", + "Couldn't find a matching Matrix room": "Couldn't find a matching Matrix room", + "Fetching third party location failed": "Fetching third party location failed", + "Unable to look up room ID from server": "Unable to look up room ID from server", + "Directory": "Directory", + "Search for a room": "Search for a room", + "#example": "#example", "Scroll to bottom of page": "Scroll to bottom of page", "Message not sent due to unknown devices being present": "Message not sent due to unknown devices being present", "Show devices, send anyway or cancel.": "Show devices, send anyway or cancel.", @@ -823,13 +977,13 @@ "%(count)s of your messages have not been sent.|one": "Your message was not sent.", "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "Resend all or cancel all now. You can also select individual messages to resend or cancel.", "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Resend message or cancel message now.", - "Warning": "Warning", "Connectivity to the server has been lost.": "Connectivity to the server has been lost.", "Sent messages will be stored until your connection has returned.": "Sent messages will be stored until your connection has returned.", "%(count)s new messages|other": "%(count)s new messages", "%(count)s new messages|one": "%(count)s new message", "Active call": "Active call", "There's no one else here! Would you like to invite others or stop warning about the empty room?": "There's no one else here! Would you like to invite others or stop warning about the empty room?", + "more": "more", "You seem to be uploading files, are you sure you want to quit?": "You seem to be uploading files, are you sure you want to quit?", "You seem to be in a call, are you sure you want to quit?": "You seem to be in a call, are you sure you want to quit?", "Failed to upload file": "Failed to upload file", @@ -846,6 +1000,9 @@ "Click to mute video": "Click to mute video", "Click to unmute audio": "Click to unmute audio", "Click to mute audio": "Click to mute audio", + "Expand panel": "Expand panel", + "Collapse panel": "Collapse panel", + "Filter room names": "Filter room names", "Clear filter": "Clear filter", "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.", "Tried to load a specific point in this room's timeline, but was unable to find it.": "Tried to load a specific point in this room's timeline, but was unable to find it.", @@ -860,7 +1017,6 @@ "Server may be unavailable or overloaded": "Server may be unavailable or overloaded", "Sign out": "Sign out", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.", - "Failed to change password. Is your password correct?": "Failed to change password. Is your password correct?", "Success": "Success", "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them", "Remove Contact Information?": "Remove Contact Information?", @@ -878,7 +1034,6 @@ "Ignored Users": "Ignored Users", "Debug Logs Submission": "Debug Logs Submission", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.", - "Submit debug logs": "Submit debug logs", "Riot collects anonymous analytics to allow us to improve the application.": "Riot collects anonymous analytics to allow us to improve the application.", "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.", "Learn more about how we use analytics.": "Learn more about how we use analytics.", @@ -905,7 +1060,6 @@ "VoIP": "VoIP", "Email": "Email", "Add email address": "Add email address", - "Notifications": "Notifications", "Profile": "Profile", "Display name": "Display name", "Account": "Account", @@ -1009,195 +1163,5 @@ "Import": "Import", "Failed to set direct chat tag": "Failed to set direct chat tag", "Failed to remove tag %(tagName)s from room": "Failed to remove tag %(tagName)s from room", - "Failed to add tag %(tagName)s to room": "Failed to add tag %(tagName)s to room", - "Fetching third party location failed": "Fetching third party location failed", - "A new version of Riot is available.": "A new version of Riot is available.", - "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk chat", - "Couldn't load home page": "Couldn't load home page", - "Send Account Data": "Send Account Data", - "All notifications are currently disabled for all targets.": "All notifications are currently disabled for all targets.", - "Uploading report": "Uploading report", - "Sunday": "Sunday", - "Notification targets": "Notification targets", - "Today": "Today", - "Files": "Files", - "Implementing VR services with Matrix": "Implementing VR services with Matrix", - "You are not receiving desktop notifications": "You are not receiving desktop notifications", - "Friday": "Friday", - "Update": "Update", - "You need to be using HTTPS to place a screen-sharing call.": "You need to be using HTTPS to place a screen-sharing call.", - "Unable to fetch notification target list": "Unable to fetch notification target list", - "Add an email address above to configure email notifications": "Add an email address above to configure email notifications", - "Expand panel": "Expand panel", - "On": "On", - "%(count)s Members|other": "%(count)s Members", - "Filter room names": "Filter room names", - "Changelog": "Changelog", - "Running Matrix services": "Running Matrix services", - "Waiting for response from server": "Waiting for response from server", - "Uploaded on %(date)s by %(user)s": "Uploaded on %(date)s by %(user)s", - "Send Custom Event": "Send Custom Event", - "Unknown device": "Unknown device", - "Advanced notification settings": "Advanced notification settings", - "Failed to send logs: ": "Failed to send logs: ", - "delete the alias.": "delete the alias.", - "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", - "Forget": "Forget", - "Riot/Web & Desktop chat": "Riot/Web & Desktop chat", - "Hide panel": "Hide panel", - "You cannot delete this image. (%(code)s)": "You cannot delete this image. (%(code)s)", - "Cancel Sending": "Cancel Sending", - "This Room": "This Room", - "The Home Server may be too old to support third party networks": "The Home Server may be too old to support third party networks", - "Resend": "Resend", - "Room not found": "Room not found", - "Downloading update...": "Downloading update...", - "Messages in one-to-one chats": "Messages in one-to-one chats", - "Contributing code to Matrix and Riot": "Contributing code to Matrix and Riot", - "Unavailable": "Unavailable", - "Community-run support for Synapse": "Community-run support for Synapse", - "View Decrypted Source": "View Decrypted Source", - "Failed to update keywords": "Failed to update keywords", - "Notes:": "Notes:", - "remove %(name)s from the directory.": "remove %(name)s from the directory.", - "Notifications on the following keywords follow rules which can’t be displayed here:": "Notifications on the following keywords follow rules which can’t be displayed here:", - "Safari and Opera work too.": "Safari and Opera work too.", - "Please set a password!": "Please set a password!", - "You have successfully set a password!": "You have successfully set a password!", - "Chat with Riot Bot": "Chat with Riot Bot", - "Support for those using, running and writing other bridges": "Support for those using, running and writing other bridges", - "Admin support for Dendrite": "Admin support for Dendrite", - "Explore Room State": "Explore Room State", - "Source URL": "Source URL", - "Messages sent by bot": "Messages sent by bot", - "Filter results": "Filter results", - "Members": "Members", - "No update available.": "No update available.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!", - "Noisy": "Noisy", - "Failed to get protocol list from Home Server": "Failed to get protocol list from Home Server", - "Collecting app version information": "Collecting app version information", - "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Delete the room alias %(alias)s and remove %(name)s from the directory?", - "Discussion of all things Matrix!": "Discussion of all things Matrix!", - "Co-ordination for Riot/Web translators": "Co-ordination for Riot/Web translators", - "This will allow you to return to your account after signing out, and sign in on other devices.": "This will allow you to return to your account after signing out, and sign in on other devices.", - "Dev chat for the Dendrite dev team": "Dev chat for the Dendrite dev team", - "Design and implementation of E2E in Matrix": "Design and implementation of E2E in Matrix", - "Enable notifications for this account": "Enable notifications for this account", - "Directory": "Directory", - "Invite to this community": "Invite to this community", - "Failed to get public room list": "Failed to get public room list", - "Search…": "Search…", - "Messages containing keywords": "Messages containing keywords", - "When I'm invited to a room": "When I'm invited to a room", - "Tuesday": "Tuesday", - "Enter keywords separated by a comma:": "Enter keywords separated by a comma:", - "Forward Message": "Forward Message", - "Remove %(name)s from the directory?": "Remove %(name)s from the directory?", - "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.", - "Event sent!": "Event sent!", - "Preparing to send logs": "Preparing to send logs", - "Explore Account Data": "Explore Account Data", - "All messages (noisy)": "All messages (noisy)", - "Away": "Away", - "Saturday": "Saturday", - "Remember, you can always set an email address in user settings if you change your mind.": "Remember, you can always set an email address in user settings if you change your mind.", - "Direct Chat": "Direct Chat", - "The server may be unavailable or overloaded": "The server may be unavailable or overloaded", - "Reject": "Reject", - "Riot is not supported on mobile web. Install the app?": "Riot is not supported on mobile web. Install the app?", - "Error saving email notification preferences": "Error saving email notification preferences", - "Failed to set Direct Message status of room": "Failed to set Direct Message status of room", - "Monday": "Monday", - "Remove from Directory": "Remove from Directory", - "Enable them now": "Enable them now", - "Messages containing my user name": "Messages containing my user name", - "Toolbox": "Toolbox", - "Collecting logs": "Collecting logs", - "more": "more", - "GitHub issue link:": "GitHub issue link:", - "Search for a room": "Search for a room", - "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.", - "(HTTP status %(httpStatus)s)": "(HTTP status %(httpStatus)s)", - "All Rooms": "All Rooms", - "State Key": "State Key", - "Please install Chrome or Firefox for the best experience.": "Please install Chrome or Firefox for the best experience.", - "Wednesday": "Wednesday", - "Quote": "Quote", - "Send logs": "Send logs", - "All messages": "All messages", - "Implementing VoIP services with Matrix": "Implementing VoIP services with Matrix", - "Dev chat for the Riot/Web dev team": "Dev chat for the Riot/Web dev team", - "Call invitation": "Call invitation", - "Riot Desktop on %(platformName)s": "Riot Desktop on %(platformName)s", - "Messages containing my display name": "Messages containing my display name", - "You have successfully set a password and an email address!": "You have successfully set a password and an email address!", - "Failed to send custom event.": "Failed to send custom event.", - "What's new?": "What's new?", - "Discussion of the Identity Service API": "Discussion of the Identity Service API", - "Support for those using and running matrix-appservice-irc": "Support for those using and running matrix-appservice-irc", - "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk chat", - "Notify me for anything else": "Notify me for anything else", - "View Source": "View Source", - "Keywords": "Keywords", - "Click here to create a GitHub issue.": "Click here to create a GitHub issue.", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.", - "Can't update user notification settings": "Can't update user notification settings", - "Notify for all other messages/rooms": "Notify for all other messages/rooms", - "Unable to look up room ID from server": "Unable to look up room ID from server", - "Couldn't find a matching Matrix room": "Couldn't find a matching Matrix room", - "Support for those using the Matrix spec": "Support for those using the Matrix spec", - "Invite to this room": "Invite to this room", - "You cannot delete this message. (%(code)s)": "You cannot delete this message. (%(code)s)", - "Thursday": "Thursday", - "I understand the risks and wish to continue": "I understand the risks and wish to continue", - "Logs sent": "Logs sent", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s via %(browserName)s on %(osName)s", - "Back": "Back", - "Reply": "Reply", - "Show message in desktop notification": "Show message in desktop notification", - "You must specify an event type!": "You must specify an event type!", - "Unhide Preview": "Unhide Preview", - "Announcements about Synapse releases": "Announcements about Synapse releases", - "Search the room directory": "Search the room directory", - "Unable to join network": "Unable to join network", - "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply", - "Sorry, your browser is not able to run Riot.": "Sorry, your browser is not able to run Riot.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Decentralised, encrypted chat & collaboration powered by [matrix]", - "Building services on Matrix": "Building services on Matrix", - "Messages in group chats": "Messages in group chats", - "Yesterday": "Yesterday", - "Error encountered (%(errorDetail)s).": "Error encountered (%(errorDetail)s).", - "Event Type": "Event Type", - "Low Priority": "Low Priority", - "What's New": "What's New", - "Set Password": "Set Password", - "Appear Offline": "Appear Offline", - "Get started with some tips from Riot Bot!": "Get started with some tips from Riot Bot!", - "An error occurred whilst saving your email notification preferences.": "An error occurred whilst saving your email notification preferences.", - "Enable audible notifications in web client": "Enable audible notifications in web client", - "Permalink": "Permalink", - "Welcome to Riot.im": "Welcome to Riot.im", - "Off": "Off", - "Riot does not know how to join a room on this network": "Riot does not know how to join a room on this network", - "Mentions only": "Mentions only", - "You can now return to your account after signing out, and sign in on other devices.": "You can now return to your account after signing out, and sign in on other devices.", - "Enable desktop notifications": "Enable desktop notifications", - "Enable email notifications": "Enable email notifications", - "Login": "Login", - "Download this file": "Download this file", - "Pin Message": "Pin Message", - "Failed to change settings": "Failed to change settings", - "View Community": "View Community", - "%(count)s Members|one": "%(count)s Member", - "Developer Tools": "Developer Tools", - "General discussion about Matrix and Riot": "General discussion about Matrix and Riot", - "Event Content": "Event Content", - "Thank you!": "Thank you!", - "#example": "#example", - "Collapse panel": "Collapse panel", - "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!", - "Checking for an update...": "Checking for an update...", - "Matrix technical discussions": "Matrix technical discussions", - "There are advanced notifications which are not shown here": "There are advanced notifications which are not shown here" + "Failed to add tag %(tagName)s to room": "Failed to add tag %(tagName)s to room" } From df564af8bd90df670407e74a6ed07f5c5c819878 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 15 Apr 2018 23:18:47 +0100 Subject: [PATCH 0786/1160] run prune-i18n to bring the translations back in line with normalised en_EN --- src/i18n/strings/ar.json | 6 ---- src/i18n/strings/bg.json | 51 ------------------------------- src/i18n/strings/ca.json | 47 ----------------------------- src/i18n/strings/cs.json | 51 ------------------------------- src/i18n/strings/da.json | 43 --------------------------- src/i18n/strings/de_DE.json | 52 -------------------------------- src/i18n/strings/el.json | 46 ---------------------------- src/i18n/strings/en_US.json | 48 ------------------------------ src/i18n/strings/eo.json | 50 ------------------------------- src/i18n/strings/es.json | 49 ------------------------------ src/i18n/strings/eu.json | 51 ------------------------------- src/i18n/strings/fa.json | 42 -------------------------- src/i18n/strings/fi.json | 51 ------------------------------- src/i18n/strings/fr.json | 56 ----------------------------------- src/i18n/strings/gl.json | 52 -------------------------------- src/i18n/strings/he.json | 44 --------------------------- src/i18n/strings/hu.json | 56 ----------------------------------- src/i18n/strings/id.json | 47 ----------------------------- src/i18n/strings/it.json | 53 --------------------------------- src/i18n/strings/ja.json | 6 ---- src/i18n/strings/ko.json | 46 ---------------------------- src/i18n/strings/lt.json | 41 ------------------------- src/i18n/strings/lv.json | 53 --------------------------------- src/i18n/strings/ml.json | 43 --------------------------- src/i18n/strings/nb_NO.json | 3 -- src/i18n/strings/nl.json | 53 --------------------------------- src/i18n/strings/pl.json | 50 ------------------------------- src/i18n/strings/pt.json | 49 ------------------------------ src/i18n/strings/pt_BR.json | 54 --------------------------------- src/i18n/strings/ru.json | 55 ---------------------------------- src/i18n/strings/sk.json | 49 ------------------------------ src/i18n/strings/sq.json | 34 --------------------- src/i18n/strings/sr.json | 50 ------------------------------- src/i18n/strings/sv.json | 49 ------------------------------ src/i18n/strings/te.json | 12 -------- src/i18n/strings/th.json | 46 ---------------------------- src/i18n/strings/tr.json | 46 ---------------------------- src/i18n/strings/uk.json | 46 ---------------------------- src/i18n/strings/zh_Hans.json | 51 ------------------------------- src/i18n/strings/zh_Hant.json | 56 ----------------------------------- 40 files changed, 1787 deletions(-) diff --git a/src/i18n/strings/ar.json b/src/i18n/strings/ar.json index f26a9850b4..cb223f5aaf 100644 --- a/src/i18n/strings/ar.json +++ b/src/i18n/strings/ar.json @@ -27,21 +27,17 @@ "Couldn't find a matching Matrix room": "لا يمكن إيجاد غرفة مايتركس متطابقة", "Unavailable": "غير متوفر", "A new version of Riot is available.": "هناك نسخة جديدة مِن رايوت متوفرة.", - "Safari and Opera work too.": "متصفح سافاري و متصفح أوبرا يعملان أيضاً.", "All Rooms": "كل الغُرف", "All messages": "كل الرسائل", "All notifications are currently disabled for all targets.": "كل التنبيهات غير مفعلة حالياً للجميع.", "Direct Chat": "دردشة مباشرة", "Please set a password!": "يرجى تعيين كلمة مرور !", "You have successfully set a password!": "تم تعيين كلمة السر بنجاح !", - "Riot is not supported on mobile web. Install the app?": "رايوت غير مدعوم في وضعية الويب على الهاتف. هل تريد تثبيت التطبيق ؟", - "Report a bug": "الإبلاغ عن عِلّة", "Can't update user notification settings": "لا يمكن تحديث إعدادات الإشعارات الخاصة بالمستخدم", "Explore Room State": "إكتشاف حالة الغرفة", "All messages (noisy)": "كل الرسائل (صوت مرتفع)", "Update": "تحديث", "What's New": "آخِر المُستجدّات", - "Describe your problem here.": "صِف مشكلتك هنا.", "Toolbox": "علبة الأدوات", "Add an email address above to configure email notifications": "أضف بريداً إلكترونياً أعلاه من أجل ضبط الإشعارات عبر البريد الإلكتروني", "Collecting logs": "تجميع السجلات", @@ -57,12 +53,10 @@ "Directory": "الدليل", "Send logs": "إرسال السِجلات", "Download this file": "تنزيل هذا الملف", - "Unknown device": "جهاز مجهول", "Thank you!": "شكرًا !", "Advanced notification settings": "الإعدادات المتقدمة للإشعارات", "Call invitation": "دعوة لمحادثة", "delete the alias.": "إلغاء المُعرف.", - "Riot Desktop on %(platformName)s": "الواجهة المكتبية لرايوت على %(platformName)s", "Developer Tools": "أدوات التطوير", "Downloading update...": "عملية تنزيل التحديث جارية …", "State Key": "مفتاح الحالة", diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 4ebe205eb8..3ca31b4534 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -331,8 +331,6 @@ "Hangup": "Затвори", "Voice call": "Гласово повикване", "Video call": "Видео повикване", - "Hide Apps": "Скрий приложенията", - "Show Apps": "Покажи приложенията", "Upload file": "Качи файл", "Show Text Formatting Toolbar": "Показване на лентата с инструменти за форматиране на текст", "Send an encrypted reply…": "Изпрати шифрован отговор…", @@ -435,7 +433,6 @@ "Encryption is enabled in this room": "Шифроването е включено в тази стая", "Encryption is not enabled in this room": "Шифроването не е включено в тази стая", "Privileged Users": "Потребители с привилегии", - "%(user)s is a": "%(user)s е", "No users have specific privileges in this room": "Никой няма специфични привилегии в тази стая", "Banned users": "Блокирани потребители", "This room is not accessible by remote Matrix servers": "Тази стая не е достъпна за далечни Matrix сървъри", @@ -718,8 +715,6 @@ "Loading device info...": "Зареждане на информация за устройството...", "Encryption key request": "Заявка за ключ за шифроване", "Otherwise, click here to send a bug report.": "В противен случай, натиснете тук, за да изпратите съобщение за грешка.", - "Report it": "Съобщи за нея", - "Bug Report": "Съобщаване за грешка", "Unable to restore session": "Неуспешно възстановяване на сесията", "Continue anyway": "Продължи въпреки това", "Invalid Email Address": "Невалиден имейл адрес", @@ -729,7 +724,6 @@ "Unable to verify email address.": "Неуспешно потвърждение на имейл адрес.", "Unable to accept invite": "Неуспешно приемане на поканата", "Unable to reject invite": "Неуспешно отхвърляне на поканата", - "Unable to leave room": "Неуспешно напускане на стаята", "Tried to load a specific point in this room's timeline, but was unable to find it.": "Беше направен опит да се зареди конкретна точка в хронологията на тази стая, но не я намери.", "Unable to remove contact information": "Неуспешно премахване на информацията за контакти", "This will allow you to reset your password and receive notifications.": "Това ще Ви позволи да възстановите Вашата парола и да получавате известия.", @@ -786,7 +780,6 @@ "Failed to fetch avatar URL": "Неуспешно изтегляне от адреса на аватара", "Signed Out": "Излязохте", "For security, this session has been signed out. Please sign in again.": "Поради мерки за сигурност, тази сесия е прекратена. Моля, влезте отново.", - "Cryptography data migrated": "Бяха мигрирани криптографските данни", "Logout": "Излез", "Sign out": "Изход", "Error whilst fetching joined communities": "Грешка при извличането на общности, към които сте присъединени", @@ -848,7 +841,6 @@ "Device ID:": "Идентификатор на устройството:", "Device key:": "Ключ на устройството:", "Ignored Users": "Игнорирани потребители", - "Found a bug?": "Намерихте грешка?", "Riot collects anonymous analytics to allow us to improve the application.": "Riot събира анонимни статистики, за да ни позволи да подобрим приложението.", "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Поверителността е важна за нас, затова за нашите статистики не събираме лични или идентифициращи Вас данни.", "Learn more about how we use analytics.": "Научете повече за това как използваме статистическите данни.", @@ -976,7 +968,6 @@ "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Ако преди сте използвали по-нова версия на Riot, Вашата сесия може да не бъде съвместима с текущата версия. Затворете този прозорец и се върнете в по-новата версия.", "This will be your account name on the homeserver, or you can pick a different server.": "Това ще бъде името на профила Ви на Home сървъра, или можете да изберете друг сървър.", "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Препоръчваме Ви да минете през процеса за потвърждение за всяко устройство, за да потвърдите, че принадлежат на легитимен собственик. Ако предпочитате, можете да изпратите съобщение без потвърждение.", - "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "Извършена е еднократна миграция на криптографски данни. Шифроването от край до край няма да работи, ако се върнете към по-стара версия на Riot. Ако искате да използвате криптография от край до край на по-стара версия, първо излезте от Riot. За да запазите историята на съобщенията, експортирайте и импортирайте отново Вашите ключове.", "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Засечени са данни от по-стара версия на Riot. Това ще доведе до неправилна работа на криптографията от край до край в по-старата версия. Шифрованите от край до край съобщения, които са били обменени наскоро (при използването на по-стара версия), може да не успеят да бъдат разшифровани в тази версия. Това също може да доведе до неуспех в обмяната на съобщения в тази версия. Ако имате проблеми, излезте и влезте отново в профила си. За да запазите историята на съобщенията, експортирайте и импортирайте отново Вашите ключове.", "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.": "Възстановяването на парола ще нулира всички ключове за шифроване от край до край за всички устройства, правейки историята на шифрования чат невъзможна за четене, освен ако първо не експортирате Вашите ключове за стаята и ги импортирате отново след това. В бъдеще това ще бъде подобрено.", "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": "Вие сте излязли от профила си от всички устройства и вече няма да получавате известия. За да включите известията отново, влезте в профила си от всички устройства", @@ -995,7 +986,6 @@ "Key request sent.": "Заявката за ключ е изпратена.", "Re-request encryption keys from your other devices.": "Заявете отново ключове за шифроване от другите Ви устройства.", "%(user)s is a %(userRole)s": "%(user)s е %(userRole)s", - "Changes made to your community might not be seen by other users for up to 30 minutes.": "Промени, направени във общността Ви, може да не бъдат видяни от другите потребители за най-много 30 минути.", "Code": "Код", "Debug Logs Submission": "Изпращане на логове за дебъгване", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Ако сте изпратили грешка чрез GitHub, логовете за дебъгване могат да ни помогнат да проследим проблема. Логовете за дебъгване съдържат данни за използване на приложението, включващи потребителското Ви име, идентификаторите или псевдонимите на стаите или групите, които сте посетили, и потребителските имена на други потребители. Те не съдържат съобщения.", @@ -1009,8 +999,6 @@ "Leave this community": "Напуснете тази общност", "Fetching third party location failed": "Неуспешно извличане на адреса на стаята от друга мрежа", "A new version of Riot is available.": "Налична е нова версия на Riot.", - "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk чат", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Моля, опишете грешката. Какво направихте? Какво очаквахте да стане? Какво стана всъщност?", "Couldn't load home page": "Неуспешно зареждане на началната страница", "Send Account Data": "Изпращане на Account Data", "All notifications are currently disabled for all targets.": "В момента известията са изключени за всички цели.", @@ -1019,12 +1007,9 @@ "Notification targets": "Устройства, получаващи известия", "Today": "Днес", "Files": "Файлове", - "Report a bug": "Докладвай за грешка", - "Implementing VR services with Matrix": "Внедряване на VR услуги с Matrix", "You are not receiving desktop notifications": "Не получавате известия на работния плот", "Friday": "Петък", "Update": "Актуализиране", - "You need to be using HTTPS to place a screen-sharing call.": "Трябва да използвате HTTPS, за да споделите екрана си.", "Unable to fetch notification target list": "Неуспешно извличане на списък с устройства получаващи известия", "Add an email address above to configure email notifications": "За конфигурация на имейл известия добавете имейл адрес по-горе.", "Expand panel": "Разшири панела", @@ -1032,31 +1017,24 @@ "%(count)s Members|other": "%(count)s Членове", "Filter room names": "Филтрирай стаи по име", "Changelog": "Списък на промените", - "Running Matrix services": "Хостинг на Matrix услуги", "Waiting for response from server": "Изчакване на отговор от сървъра", "Uploaded on %(date)s by %(user)s": "Качено на %(date)s от %(user)s", "Send Custom Event": "Изпрати потребителско събитие", - "Failed to send report: ": "Неуспешно изпращане на доклада: ", - "Unknown device": "Непознато устройство", "Advanced notification settings": "Разширени настройки за известяване", "Failed to send logs: ": "Неуспешно изпращане на логове: ", "delete the alias.": "изтрий псевдонима.", "To return to your account in future you need to set a password": "За да се върнете в профила си в бъдеще, трябва да зададете парола", "Forget": "Забрави", - "Riot/Web & Desktop chat": "Riot/Web & Desktop чат", "Hide panel": "Скриване на панела", "You cannot delete this image. (%(code)s)": "Не можете да изтриете тази снимка. (%(code)s)", "Cancel Sending": "Откажи изпращането", "This Room": "В тази стая", - "Get started with some tips from Riot Bot!": "Започнете с някои съвети от Riot Bot!", "The Home Server may be too old to support third party networks": "Home сървърът може да е твърде стар, за да поддържа работа с други мрежи", "Resend": "Изпрати отново", "Room not found": "Стаята не е намерена", "Downloading update...": "Сваляне на нова версия...", "Messages in one-to-one chats": "Съобщения в индивидуални чатове", - "Contributing code to Matrix and Riot": "Допринасяне с код към Matrix и Riot", "Unavailable": "Не е наличен", - "Community-run support for Synapse": "Поддръжка за Synapse от общността", "View Decrypted Source": "Прегледай разшифрования източник", "Failed to update keywords": "Грешка при обновяване на ключови думи", "Notes:": "Бележки:", @@ -1065,24 +1043,17 @@ "Safari and Opera work too.": "Safari и Opera са други алтернативи.", "Please set a password!": "Моля, въведете парола!", "You have successfully set a password!": "Вие успешно зададохте парола!", - "Chat with Riot Bot": "Чат с Riot Bot", - "Support for those using, running and writing other bridges": "Поддръжка за тези, които използват, работят и пишат Matrix мостове", - "Admin support for Dendrite": "Административна поддръжка за Dendrite", "Explore Room State": "Преглед на състоянието на стаята", "Source URL": "URL на източника", "Messages sent by bot": "Съобщения изпратени от бот", "Filter results": "Филтриране на резултати", "Members": "Членове", "No update available.": "Няма нова версия.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "В Matrix съществуват много стаи, свързани към вече съществуващи мрежи (Slack, IRC, Gitter и т.н.) или независими такива. Разгледайте директорията!", "Noisy": "Шумно", "Failed to get protocol list from Home Server": "Неуспешно получаване на списък с протоколи от Home сървър", "Collecting app version information": "Събиране на информация за версията на приложението", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Изтриване на псевдонима %(alias)s на стаята и премахване на %(name)s от директорията?", - "Co-ordination for Riot/Web translators": "Координация за преводачи на Riot/Web", "This will allow you to return to your account after signing out, and sign in on other devices.": "Това ще Ви позволи да се върнете в профила си след излизане от него, и да влезете от други устройства.", - "Dev chat for the Dendrite dev team": "Чат за разработващия екип на Dendrite", - "Design and implementation of E2E in Matrix": "Разработване и внедряване на E2E шифроване в Matrix", "Enable notifications for this account": "Включване на известия за този профил", "Directory": "Директория", "Invite to this community": "Покани в тази общност", @@ -1106,15 +1077,11 @@ "Direct Chat": "Директен чат", "The server may be unavailable or overloaded": "Сървърът не е наличен или е претоварен", "Reject": "Отхвърли", - "Riot is not supported on mobile web. Install the app?": "Riot не поддържа мобилен уеб браузър. Инсталиране на приложението?", - "Discussion of all things Matrix!": "Дискусия за всичко свързано с Matrix!", "Failed to set Direct Message status of room": "Неуспешно настройване на стаята като Директен чат", "Monday": "Понеделник", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "За да се диагностицират проблемите, логовете от този клиент ще бъдат изпратени с този доклад за грешки. Ако предпочитате да изпратите само текста по-горе, моля, премахнете отметката:", "Remove from Directory": "Премахни от директорията", "Enable them now": "Включете ги сега", "Messages containing my user name": "Съобщения, съдържащи моето потребителско име", - "Describe your problem here.": "Опишете своя проблем тук.", "Toolbox": "Инструменти", "Collecting logs": "Събиране на логове", "more": "още", @@ -1128,47 +1095,33 @@ "Quote": "Цитирай", "Send logs": "Изпращане на логове", "All messages": "Всички съобщения", - "Implementing VoIP services with Matrix": "Внедряване на VoIP услуги с Matrix", - "Dev chat for the Riot/Web dev team": "Чат за разработващия екип на Riot/Web", "Call invitation": "Покана за разговор", - "Riot Desktop on %(platformName)s": "Riot Desktop под %(platformName)s", "Messages containing my display name": "Съобщения, съдържащи моя псевдоним", "State Key": "State ключ", "Failed to send custom event.": "Неуспешно изпращане на потребителско събитие.", "What's new?": "Какво ново?", - "Discussion of the Identity Service API": "Дискусия върху API услугата за самоличност", - "Support for those using and running matrix-appservice-irc": "Поддръжка за използващите и работещите с matrix-appservice-irc", - "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk чат", "Notify me for anything else": "Извести ме за всичко останало", "When I'm invited to a room": "Когато ме поканят в стая", "Keywords": "Ключови думи", "Click here to create a GitHub issue.": "Натиснете тук, за да създадете GitHub issue.", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Може да използвате опциите за друг сървър, за да влезете в други Matrix сървъри като посочите различен Home сървър.
    Това Ви позволява да използвате Riot със съществуващ Matrix профил на различен Home сървър.

    Възможно е и да зададете друг сървър за самоличност. В този случай обаче няма да бъде възможно да поканите други потребители по имейл адрес, както и самите Вие няма да можете да бъдете поканени по имейл адрес.", "Can't update user notification settings": "Неуспешно обновяване на потребителски настройки за известяване", "Notify for all other messages/rooms": "Извести ме за всички други съобщения/стаи", "Unable to look up room ID from server": "Стая с такъв идентификатор не е намерена на сървъра", "Couldn't find a matching Matrix room": "Не успяхме да намерим съответната Matrix стая", "Bug report sent": "Докладът за грешки е изпратен", - "Loading bug report module": "Зареждане на модул за докладване на проблем", "Invite to this room": "Покани в тази стая", "You cannot delete this message. (%(code)s)": "Това съобщение не може да бъде изтрито. (%(code)s)", "Thursday": "Четвъртък", "I understand the risks and wish to continue": "Разбирам рисковете и желая да продължа", "Logs sent": "Логовете са изпратени", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s в %(browserName)s под %(osName)s", "Back": "Назад", "Reply": "Отговори", "Show message in desktop notification": "Показване на съдържание в известията на работния плот", "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Логовете за дебъгване съдържат данни за използване на приложението, включващи потребителското Ви име, идентификаторите или псевдонимите на стаите или групите, които сте посетили, и потребителските имена на други потребители. Те не съдържат съобщения.", "Unhide Preview": "Покажи отново прегледа", - "Announcements about Synapse releases": "Обявления за нови версии на Synapse", - "Search the room directory": "Търсене в директорията със стаи", - "Please describe the bug and/or send logs.": "Моля, опишете проблема и/или изпратете логове.", "Unable to join network": "Неуспешно присъединяване към мрежата", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Възможна конфигурация на настройките за известия в клиент, различен от Riot. Не могат да бъдат променени в Riot, но важат въпреки това", "Sorry, your browser is not able to run Riot.": "За жалост, Вашият браузър не може да пусне Riot.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Децентрализиран, шифрован чат и колаборация базирани на [matrix]", - "Building services on Matrix": "Разработка на услуги в Matrix", "Messages in group chats": "Съобщения в групови чатове", "Yesterday": "Вчера", "Error encountered (%(errorDetail)s).": "Възникна грешка (%(errorDetail)s).", @@ -1177,11 +1130,9 @@ "What's New": "Какво ново", "Set Password": "Задаване на парола", "Appear Offline": "Показване като офлайн", - "Support for those using the Matrix spec": "Поддръжка за използващите Matrix спецификацията", "An error occurred whilst saving your email notification preferences.": "Възникна грешка при запазване на настройките за имейл известяване.", "Enable audible notifications in web client": "Включване на звукови известия в уеб клиент", "Permalink": "Permalink", - "Welcome to Riot.im": "Добре дошли в Riot.im", "Off": "Изключено", "Riot does not know how to join a room on this network": "Riot не знае как да се присъедини към стая от тази мрежа", "Mentions only": "Само при споменаване", @@ -1196,13 +1147,11 @@ "%(count)s Members|one": "%(count)s Член", "Event sent!": "Събитието е изпратено!", "View Source": "Прегледай източника", - "Matrix technical discussions": "Технически дискусии в Matrix", "Event Content": "Съдържание на събитието", "Thank you!": "Благодарим!", "#example": "#пример", "Collapse panel": "Свий панела", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "С текущия Ви браузър, изглеждането и усещането на приложението може да бъде неточно, и някои или всички от функциите може да не функционират,работят......... Ако искате може да продължите така или иначе, но сте сами по отношение на евентуалните проблеми, които може да срещнете!", "Checking for an update...": "Проверяване за нова версия...", - "General discussion about Matrix and Riot": "Обща дискусия относно Matrix и Riot", "There are advanced notifications which are not shown here": "Съществуват разширени настройки за известия, които не са показани тук" } diff --git a/src/i18n/strings/ca.json b/src/i18n/strings/ca.json index 5ce387ecdc..9774b5bb20 100644 --- a/src/i18n/strings/ca.json +++ b/src/i18n/strings/ca.json @@ -337,8 +337,6 @@ "Hangup": "Penja", "Voice call": "Trucada de veu", "Video call": "Trucada de vídeo", - "Hide Apps": "Amaga les aplicacions", - "Show Apps": "Mostra les aplicacions", "Upload file": "Puja el fitxer", "Show Text Formatting Toolbar": "Mostra la barra d'eines de format de text", "Send an encrypted reply…": "Envia una resposta encriptada…", @@ -756,7 +754,6 @@ "Leave Community": "Abandona la comunitat", "Leave %(groupName)s?": "Voleu sortir de la comunitat %(groupName)s?", "Leave": "Surt", - "Unable to leave room": "No s'ha pogut sortir de la sala", "Community Settings": "Paràmetres de la comunitat", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Aquestes sales es mostren a la pàgina de la comunitat als seus membres i poden entrar-hi fent clic sobre elles.", "Featured Rooms:": "Sales destacades:", @@ -872,8 +869,6 @@ "Analytics": "Analítiques", "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s ha canviat el seu nom visible a %(displayName)s.", "Server may be unavailable or overloaded": "El servidor pot estar inaccessible o sobrecarregat", - "Report it": "Informa", - "Found a bug?": "Has trobat un error?", "Display name": "Nom visible", "Identity Server is": "El servidor d'identitat es", "Submit debug logs": "Enviar logs de depuració", @@ -885,8 +880,6 @@ "The information being sent to us to help make Riot.im better includes:": "La informació enviada a Riot.im per ajudar-nos a millorar inclou:", "Fetching third party location failed": "S'ha produït un error en obtenir la ubicació de tercers", "A new version of Riot is available.": "Hi ha una nova versió del Riot disponible.", - "Riot/Android & matrix-android-sdk chat": "Riot/Android & Xat matrix-android-sdk", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Si us plau, descriviu l'error. Què heu fet, què esperàveu que passes i què sembla haver passat?", "Couldn't load home page": "No s'ha pogut carregar la pàgina d'inici", "Send Account Data": "Envia les dades del compte", "Advanced notification settings": "Paràmetres avançats de notificacions", @@ -897,12 +890,9 @@ "Failed to set direct chat tag": "No s'ha pogut establir l'etiqueta del xat directe", "Today": "Avui", "Files": "Fitxers", - "Report a bug": "Informa d'una errada", - "Implementing VR services with Matrix": "Implementació de serveis VR amb Matrix", "You are not receiving desktop notifications": "No esteu rebent notificacions d'escriptori", "Friday": "Divendres", "Update": "Actualització", - "You need to be using HTTPS to place a screen-sharing call.": "Heu d'utilitzar HTTPS per poder fer una trucada amb pantalla compartida.", "What's New": "Novetats", "Add an email address above to configure email notifications": "Afegiu més amunt un correu electrònic per a configurar les notificacions", "Expand panel": "Expandeix el panel", @@ -910,32 +900,25 @@ "%(count)s Members|other": "%(count)s membres", "Filter room names": "Filtra els noms de les sales", "Changelog": "Registre de canvis", - "Running Matrix services": "Serveis de Matrix en marxa", "Waiting for response from server": "S'està esperant una resposta del servidor", "Uploaded on %(date)s by %(user)s": "Pujat el %(date)s per l'usuari %(user)s", "Send Custom Event": "Envia els esdeveniments personalitzats", - "Failed to send report: ": "No s'ha pogut enviar l'informe ", - "Unknown device": "Dispositiu desconegut", "All notifications are currently disabled for all targets.": "Actualment totes les notificacions estan inhabilitades per a tots els objectius.", "Failed to send logs: ": "No s'han pogut enviar els logs: ", "delete the alias.": "esborra l'alies.", "To return to your account in future you need to set a password": "Per poder tornar al vostre compte en un futur, heu de set a password", "Forget": "Oblida", "#example": "#exemple", - "Riot/Web & Desktop chat": "Riot/Web & Xat d'escriptori", "Hide panel": "Amaga el panel", "You cannot delete this image. (%(code)s)": "No podeu eliminar aquesta imatge. (%(code)s)", "Cancel Sending": "Cancel·la l'enviament", "This Room": "Aquesta sala", - "Get started with some tips from Riot Bot!": "Comenceu amb alguns consells de Riot Bot!", "The Home Server may be too old to support third party networks": "El servidor local pot ser massa antic per a ser compatible amb xarxes de tercers", "Resend": "Reenvia", "Room not found": "No s'ha trobat la sala", "Messages containing my display name": "Missatges que contenen el meu nom visible", "Messages in one-to-one chats": "Missatges en xats un a un", - "Contributing code to Matrix and Riot": "Contribuir amb codi a Matrix i Riot", "Unavailable": "No disponible", - "Community-run support for Synapse": "Suport de la comunitat per a Synapse", "Error saving email notification preferences": "No s'han pogut desar les preferències de les notificacions a causa d'un error", "View Decrypted Source": "Mostra el codi desencriptat", "Failed to update keywords": "No s'han pogut actualitzar les paraules clau", @@ -945,9 +928,6 @@ "Safari and Opera work too.": "Safari i Opera també fan la feina.", "Please set a password!": "Si us plau, establiu una contrasenya", "You have successfully set a password!": "Heu establert correctament la contrasenya", - "Chat with Riot Bot": "Conversa amb el Bot de Riot", - "Support for those using, running and writing other bridges": "Suport per a aquells que utilitzen, executen i escriuen altres ponts", - "Admin support for Dendrite": "Suport dels administrador per a Dendrite", "An error occurred whilst saving your email notification preferences.": "S'ha produït un error en desar les vostres preferències de notificació per correu electrònic.", "Explore Room State": "Esbrina els estats de les sales", "Source URL": "URL origen", @@ -955,15 +935,11 @@ "Filter results": "Resultats del filtre", "Members": "Membres", "No update available.": "No hi ha cap actualització disponible.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Ja existeixen moltes sales a Matrix vinculades a xarxes existents (Slack, IRC, Gitter, etc.) o independents. Feu un cop d'ull al directori!", "Noisy": "Sorollós", "Failed to get protocol list from Home Server": "No s'ha pogut obtenir la llista de protocols del servidor local", "Collecting app version information": "S'està recollint la informació de la versió de l'aplicació", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Voleu esborrar de la sala l'alies %(alias)s i retirar %(name)s del directori?", - "Co-ordination for Riot/Web translators": "Coordinació per a traductors de Riot/Web", "This will allow you to return to your account after signing out, and sign in on other devices.": "Això farà possible que pugueu tronar al vostre compte des de qualsevol dispositiu.", - "Dev chat for the Dendrite dev team": "Xat de l'equip Dendrite per a desenvolupadors", - "Design and implementation of E2E in Matrix": "Disseny i implementació de l'E2E a Matrix", "Enable notifications for this account": "Habilita les notificacions per aquest compte", "Directory": "Directori", "Invite to this community": "Convida a aquesta comunitat", @@ -986,15 +962,11 @@ "Direct Chat": "Xat directe", "The server may be unavailable or overloaded": "El servidor pot no estar disponible o sobrecarregat", "Reject": "Rebutja", - "Riot is not supported on mobile web. Install the app?": "Riot no és compatible amb la web per a mòbils. Voleu instal·lar l'aplicació per a mòbils?", - "Discussion of all things Matrix!": "Debats sobre qualsevol cosa de Matrix!", "Failed to set Direct Message status of room": "No s'ha pogut establir l'estat del missatge directe de la sala", "Monday": "Dilluns", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Amb aquest informe d'error, alguns registres d'aquesta aplicació s'enviaran també per tal de fer un diagnostic del problema. Si preferiu enviar només el text anterior, desseleccioneu:", "All messages (noisy)": "Tots els missatges (sorollós)", "Enable them now": "Habilita-ho ara", "Messages containing my user name": "Missatges que contenen el meu nom d'usuari", - "Describe your problem here.": "Descriu aquí el teu problema.", "Toolbox": "Caixa d'eines", "Collecting logs": "S'estan recopilant els registres", "more": "més", @@ -1008,47 +980,33 @@ "Wednesday": "Dimecres", "Send logs": "Envia els registres", "All messages": "Tots els missatges", - "Implementing VoIP services with Matrix": "Implementació de serveis VoIP amb Matrix", - "Dev chat for the Riot/Web dev team": "Xat de l'equip de desenvolupadors Riot/Web per a desenvolupadors", "Call invitation": "Invitació de trucada", - "Riot Desktop on %(platformName)s": "Riot d'escriptori per a %(platformName)s", "Downloading update...": "Descarregant l'actualització...", "You have successfully set a password and an email address!": "Heu establert correctament la vostra contrasenya i l'adreça de correu electrònic", "Failed to send custom event.": "No s'ha pogut enviar l'esdeveniment personalitzat.", "What's new?": "Què hi ha de nou?", - "Discussion of the Identity Service API": "Debat sobre l'API Identity Service", - "Support for those using and running matrix-appservice-irc": "Suport per a aquells que utilitzen i executen matrix-appservice-irc", - "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & Xat de matrix-ios-sdk", "Notify me for anything else": "Notifica'm per a qualsevol altra cosa", "View Source": "Mostra el codi", "Keywords": "Paraules clau", "Click here to create a GitHub issue.": "Clica aquí per crear una issue a GitHub.", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Podeu utilitzar opcions de servidor personalitzades per iniciar sessió en altres servidors Matrix especificant una URL diferent a la del servidor principal.
    Això us permet utilitzar Riot amb un compte de Matrix existent en un servidor d'origen diferent.

    També podeu establir un servidor d'identitat personalitzat, però no podreu convidar o ser convidat per correu electrònic.", "Can't update user notification settings": "No es poden actualitzar els paràmetres de les notificacions de l'usuari", "Notify for all other messages/rooms": "Notifica per a tots els altres missatges o sales", "Unable to look up room ID from server": "No s'ha pogut cercar l'ID de la sala en el servidor", "Couldn't find a matching Matrix room": "No s'ha pogut trobar una sala de Matrix que coincideixi", "Bug report sent": "S'ha enviat l'informe d'error", - "Safari and Opera work too.": "També funcionen el Safari i l'Opera.", - "Loading bug report module": "S'està carregant l'informe del modul", "Invite to this room": "Convida a aquesta sala", "You cannot delete this message. (%(code)s)": "No podeu eliminar aquest missatge. (%(code)s)", "Thursday": "Dijous", "I understand the risks and wish to continue": "Entenc el riscos i desitjo continuar", "Logs sent": "Logs enviats", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s via %(browserName)s per a %(osName)s", "Back": "Enrere", "Reply": "Respon", "Show message in desktop notification": "Mostra els missatges amb notificacions d'escriptori", "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Els logs de depuració contenen dades d'ús de l'aplicació que inclouen el teu nom d'usuari, les IDs o pseudònims de les sales o grups que has visitat i els noms d'usuari d'altres usuaris. No contenen missatges.", "Unhide Preview": "Mostra la previsualització", - "Announcements about Synapse releases": "Anuncis sobre llançaments de Synapse", - "Search the room directory": "Cerqueu el directori de sales", - "Please describe the bug and/or send logs.": "Si us plau, descriviu l'error i/o envia els registres.", "Unable to join network": "No s'ha pogut unir-se a la xarxa", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "És possible que els hàgiu configurat en un client diferent de Riot. No podeu modificar-los amb Riot, però encara s'apliquen", "Sorry, your browser is not able to run Riot.": "Disculpeu, el seu navegador not pot executar Riot.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Xat descentralitzat, encriptat & col·laboració amb tecnologia de [matrix]", "Quote": "Cita", "Messages in group chats": "Missatges en xats de grup", "Yesterday": "Ahir", @@ -1057,11 +1015,9 @@ "Low Priority": "Baixa prioritat", "Unable to fetch notification target list": "No s'ha pogut obtenir la llista d'objectius de les notificacions", "Appear Offline": "Apareix sense connexió", - "Support for those using the Matrix spec": "Suport per a aquells que utilitzen l'especificació Matrix", "Set Password": "Establiu una contrasenya", "Enable audible notifications in web client": "Habilita les notificacions d'àudio al client web", "Permalink": "Enllaç permanent", - "Welcome to Riot.im": "Benvingut a Riot.im", "Off": "Apagat", "Riot does not know how to join a room on this network": "El Riot no sap com unir-se a una sala en aquesta xarxa", "Mentions only": "Només mencions", @@ -1076,13 +1032,10 @@ "View Community": "Mira la communitat", "%(count)s Members|one": "%(count)s membre", "Event sent!": "S'ha enviat l'esdeveniment", - "Matrix technical discussions": "Debats tècnics sobre Matrix", "Event Content": "Contingut de l'esdeveniment", "Thank you!": "Gràcies!", - "Building services on Matrix": "Construir serveis a Matrix", "Collapse panel": "Col·lapsa el tauler", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Amb el vostre navegador actual, l'aparença de l'aplicació pot ser completament incorrecta i algunes o totes les funcions poden no funcionar correctament. Si voleu provar-ho de totes maneres, podeu continuar, però esteu sols pel que fa als problemes que pugueu trobar!", "Checking for an update...": "Comprovant si hi ha actualitzacions...", - "General discussion about Matrix and Riot": "Debat general sobre Matrix i Riot", "There are advanced notifications which are not shown here": "Hi ha notificacions avançades que no es mostren aquí" } diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index 5a4d2afe7e..920c77dd25 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -90,7 +90,6 @@ "Are you sure you want to upload the following files?": "Určitě chcete nahrát následující soubory?", "Attachment": "Příloha", "Autoplay GIFs and videos": "Automaticky přehrávat GIFy a videa", - "Bug Report": "Hlášení o chybě", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Nelze se připojit k domovskému serveru – zkontrolujte prosím své připojení, prověřte, zdali je SSL certifikát vašeho domovského serveru důvěryhodný, a že některé z rozšíření prohlížeče neblokuje komunikaci.", "Anyone who knows the room's link, apart from guests": "Kdokoliv, kdo má odkaz na místnost, kromě hostů", "Anyone who knows the room's link, including guests": "Kdokoliv, kdo má odkaz na místnost, a to i hosté", @@ -207,7 +206,6 @@ "%(senderName)s answered the call.": "%(senderName)s přijal/a hovor.", "Click to mute audio": "Kliknutím ztlumíte zvuk", "Failed to verify email address: make sure you clicked the link in the email": "E-mailovou adresu se nepodařilo ověřit. Přesvědčte se, že jste kliknul/a na zaslaný odkaz", - "Found a bug?": "Našli jste chybu?", "Guest access is disabled on this Home Server.": "Na tomto domovském serveru je hostům vstup odepřen.", "Guests cannot join this room even if explicitly invited.": "Hosté nemohou vstoupit do této místnosti, i když jsou přímo pozváni.", "Hide read receipts": "Skrýt potvrzení o přečtení", @@ -278,7 +276,6 @@ "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Tuto změnu nepůjde vrátit zpět, protože tomuto uživateli nastavujete stejnou úroveň moci, jakou máte vy.", "Alias (optional)": "Alias (nepovinný)", "Room name (optional)": "Název místnosti (nepovinný)", - "Report it": "Nahlásit to", "Results from DuckDuckGo": "Výsledky z DuckDuckGo", "Return to login screen": "Vrátit k přihlašovací obrazovce", "Riot does not have permission to send you notifications - please check your browser settings": "Riot není oprávněn posílat vám upozornění – zkontrolujte prosím nastavení svého prohlížeče", @@ -306,7 +303,6 @@ "%(senderName)s set a profile picture.": "%(senderName)s si nastavil/a profilový obrázek.", "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s si změnil/a zobrazované jméno na %(displayName)s.", "Sets the room topic": "Nastavuje téma místnosti", - "Show Apps": "Zobrazit aplikace", "Show panel": "Zobrazit panel", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Zobrazovat časové značky v 12hodinovém formátu (např. 2:30 odp.)", "Sign in": "Přihlásit", @@ -530,7 +526,6 @@ "Make Moderator": "Udělit moderátorství", "and %(count)s others...|one": "a někdo další...", "Hangup": "Zavěsit", - "Hide Apps": "Skrýt aplikace", "Show Text Formatting Toolbar": "Zobrazit nástroje formátování textu", "Hide Text Formatting Toolbar": "Skrýt nástroje formátování textu", "Jump to message": "Přeskočit na zprávu", @@ -560,7 +555,6 @@ "Leave Community": "Odejít ze skupiny", "Leave %(groupName)s?": "Odejít z %(groupName)s?", "Leave": "Odejít", - "Unable to leave room": "Nepodařilo se odejít z místnosti", "Hide join/leave messages (invites/kicks/bans unaffected)": "Skrýt zprávy o vstupu či odejití (pozvánky, vykopnutí a vykázání zůstanou)", "Failed to remove user from community": "Nepodařilo se odebrat uživatele ze skupiny", "Failed to remove room from community": "Nepodařilo se odebrat místnost ze skupiny", @@ -951,8 +945,6 @@ "Warning": "Upozornění", "Fetching third party location failed": "Nepodařilo se zjistit umístění třetí strany", "A new version of Riot is available.": "Je dostupná nová verze Riotu.", - "Riot/Android & matrix-android-sdk chat": "Riot/Android a matrix-android-sdk chat", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Prosím popište chybu. Co jste dělal/a? Co jste čekal/a, že se stane? Co se stalo?", "I understand the risks and wish to continue": "Rozumím rizikům a přeji si pokračovat", "Couldn't load home page": "Nepodařilo se nahrát úvodní stránku", "Send Account Data": "Poslat data o účtu", @@ -964,12 +956,9 @@ "Failed to set direct chat tag": "Nepodařilo se nastavit štítek přímého chatu", "Today": "Dnes", "Files": "Soubory", - "Report a bug": "Nahlásit chybu", - "Implementing VR services with Matrix": "Implementace VR služeb v Matrixu", "You are not receiving desktop notifications": "Nedostáváte upozornění na desktopu", "Friday": "Pátek", "Update": "Aktualizace", - "You need to be using HTTPS to place a screen-sharing call.": "Pro uskutečnění hovoru se sdílením obrazovky musíte používat HTTPS.", "What's New": "Co je nového", "Add an email address above to configure email notifications": "Abyste mohli nastavovat e-mailová upozornění, musíte uvést svoji e-mailovou adresu v kolonce výše", "Expand panel": "Rozbalit panel", @@ -977,16 +966,12 @@ "%(count)s Members|other": "%(count)s Členů", "Filter room names": "Filtrovat místnosti dle názvu", "Changelog": "Seznam změn", - "Running Matrix services": "Provozování Matrix služeb", "Waiting for response from server": "Čekám na odezvu ze serveru", "Send Custom Event": "Odeslat vlastní událost", - "Failed to send report: ": "Nepodařilo se odeslat hlášení: ", - "Unknown device": "Neznámé zařízení", "All notifications are currently disabled for all targets.": "Veškeré notifikace jsou aktuálně pro všechny cíle vypnuty.", "delete the alias.": "smazat alias.", "To return to your account in future you need to set a password": "Abyste se mohli ke svému účtu v budoucnu vrátit, musíte si nastavit heslo", "Forget": "Zapomenout", - "Riot/Web & Desktop chat": "Riot/Web a Desktop chat", "Hide panel": "Skrýt panel", "You cannot delete this image. (%(code)s)": "Tento obrázek nemůžete smazat. (%(code)s)", "Cancel Sending": "Zrušit odesílání", @@ -996,9 +981,7 @@ "Room not found": "Místnost nenalezena", "Messages containing my display name": "Zprávy obsahující mé zobrazované jméno", "Remember, you can always set an email address in user settings if you change your mind.": "Vězte, že kdybyste si to rozmysleli, e-mailovou adresu můžete kdykoliv doplnit v uživatelském nastavení.", - "Contributing code to Matrix and Riot": "Přispívaní kódem do Matrixu a Riotu", "Unavailable": "Nedostupné", - "Community-run support for Synapse": "Komunitou řízená podpora pro Synapse", "Error saving email notification preferences": "Chyba při ukládání nastavení e-mailových upozornění", "View Decrypted Source": "Zobrazit dešifrovaný zdroj", "Failed to update keywords": "Nepodařilo se aktualizovat klíčová slova", @@ -1007,24 +990,17 @@ "Safari and Opera work too.": "Safari a Opera fungují taky.", "Please set a password!": "Prosím nastavte si heslo!", "You have successfully set a password!": "Úspěšně jste si nastavili heslo!", - "Chat with Riot Bot": "Chatujte s Riot Botem", - "Support for those using, running and writing other bridges": "Podpora pro ty, kteří používají, provozují nebo vyvíjejí ostatní můstky", - "Admin support for Dendrite": "Správcovská podpora pro Dendrite", "Explore Room State": "Prohlížet stav místnosti", "Source URL": "Zdrojová URL", "Failed to add tag %(tagName)s to room": "Nepodařilo se přidat štítek %(tagName)s k místnosti", "Filter results": "Filtrovat výsledky", "Members": "Členové", "No update available.": "Není dostupná žádná aktualizace.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "V Matrixu je spousta samostatných, nebo s jinými sítěmi (Slack, IRC, Gitter aj.) propojených místností. Prohlédněte si jejich adresář!", "Resend": "Poslat znovu", "Failed to get protocol list from Home Server": "Z domovského serveru se nepodařilo získat seznam protokolů", "Collecting app version information": "Sbírání informací o verzi aplikace", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Smazat alias místnosti %(alias)s a odstranit %(name)s z adresáře?", - "customServer_text": "Ve vlastních serverových volbách se můžete přihlásit na ostatní Matrix servery, a to tak, že určíte URL jiného domovského serveru.
    To znamená, že můžete používat Riot s již existujícím Matrix účtem na jiném domovském serveru.

    Taky můžete nastavit vlastní server identity, pak ale nebudete moci zvát ostatní nebo naopak být ostatními zván prostřednictvím e-mailové adresy.", - "Co-ordination for Riot/Web translators": "Součinnost překladatelů Riot/Web", "This will allow you to return to your account after signing out, and sign in on other devices.": "Toto vám umožní vrátit se po odhlášení ke svému účtu a používat jej na ostatních zařízeních.", - "Dev chat for the Dendrite dev team": "Chat vývojového týmu Dendrite", "Keywords": "Klíčová slova", "Enable notifications for this account": "Zapnout upozornění na tomto účtu", "Directory": "Adresář", @@ -1048,16 +1024,11 @@ "Direct Chat": "Přímý chat", "The server may be unavailable or overloaded": "Server může být nedostupný nebo přetížený", "Reject": "Odmítnout", - "Riot is not supported on mobile web. Install the app?": "Riot není podporovaný na mobilním webu. Nainstalovat aplikaci?", - "Discussion of all things Matrix!": "Diskuse o všem okolo Matrixu!", "Failed to set Direct Message status of room": "Nepodařilo se přiřadit místnosti status Přímé zprávy", "Monday": "Pondělí", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Kvůli diagnostice budou spolu s tímto hlášením o chybě odeslány i záznamy z klienta. Chcete-li odeslat pouze text výše, prosím odškrtněte:", - "Send Custom State Event": "Poslat vlastní stavovou událost", "All messages (noisy)": "Všechny zprávy (hlasitě)", "Enable them now": "Povolit nyní", "Messages containing my user name": "Zprávy obsahující mé uživatelské jméno", - "Describe your problem here.": "Popište zde svůj problém.", "Toolbox": "Sada nástrojů", "Collecting logs": "Sbírání logů", "more": "více", @@ -1069,45 +1040,29 @@ "Failed to get public room list": "Nepodařilo se získat seznam veřejných místností", "Send logs": "Odeslat záznamy", "All messages": "Všechny zprávy", - "Implementing VoIP services with Matrix": "Implementace VoIP služeb v Matrixu", - "Dev chat for the Riot/Web dev team": "Chat vývojového týmu Riot/Web", "Call invitation": "Pozvánka k hovoru", - "Riot Desktop on %(platformName)s": "Riot Desktop na %(platformName)s", "Downloading update...": "Stahování aktualizace...", "State Key": "Stavový klíč", "Failed to send custom event.": "Nepodařilo se odeslat vlastní událost.", "What's new?": "Co je nového?", - "Discussion of the Identity Service API": "Diskuze o API služby identity", - "Support for those using and running matrix-appservice-irc": "Podpora pro používání matrix-appservice-irc", - "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS a matrix-ios-sdk chat", "Notify me for anything else": "Upozorni mě na cokoliv jiného", "When I'm invited to a room": "Pokud jsem pozván do místnosti", - "Design and implementation of E2E in Matrix": "Návrh a implementace E2E v Matrixu", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Přes vlastní serverové volby se můžete přihlásit k dalším Matrix serverům tak, že zadáte jinou adresu domovského serveru.
    Díky tomu můžete v Riotu používat Matrix účet z jiného domovského serveru.

    Můžete nastavit i vlastní server identity, ale pak už nebudete moci zvát ani být zván/a skrze e-mailovou adresu.", "Can't update user notification settings": "Nelze aktualizovat uživatelské nastavení upozornění", "Notify for all other messages/rooms": "Upozorni na všechny ostatní zprávy/místnosti", "Unable to look up room ID from server": "Nelze získat ID místnosti ze serveru", "Couldn't find a matching Matrix room": "Odpovídající Matrix místost nenalezena", - "Support for those using the Matrix spec": "Podpora pro uživatele Matrix specifikace", - "Safari and Opera work too.": "Safari a Opera fungují také.", - "Loading bug report module": "Nahrává se modul nahlašování chyb", "All Rooms": "Všechny místnosti", "You cannot delete this message. (%(code)s)": "Tuto zprávu nemůžete smazat. (%(code)s)", "Thursday": "Čtvrtek", "Search…": "Vyhledat…", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s přes %(browserName)s na %(osName)s", "Back": "Zpět", "Failed to change settings": "Nepodařilo se změnit nastavení", "Reply": "Odpovědět", "Show message in desktop notification": "Zobrazovat zprávu v upozornění na ploše", "Unhide Preview": "Zobrazit náhled", - "Announcements about Synapse releases": "Oznámení o vydáních Synapse", - "Search the room directory": "Prohledat adresář místností", - "Please describe the bug and/or send logs.": "Prosím popište chybu a/nebo pošlete záznamy.", "Unable to join network": "Nelze se připojit k síti", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Snad jste je nastavili v jiném klientu než Riot. V Riotu je nemůžete upravit, ale přesto platí", "Sorry, your browser is not able to run Riot.": "Omlouváme se, váš prohlížeč není schopný spustit Riot.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Decentralizovaný, šifrovaný chat a spolupráce na platformě [matrix]", "Uploaded on %(date)s by %(user)s": "Nahráno %(date)s uživatelem %(user)s", "Messages in group chats": "Zprávy ve skupinových chatech", "Yesterday": "Včera", @@ -1117,18 +1072,15 @@ "Riot does not know how to join a room on this network": "Riot neví, jak vstoupit do místosti na této síti", "Set Password": "Nastavit heslo", "Appear Offline": "Jevit se offline", - "Get started with some tips from Riot Bot!": "Začněte s radami od Riot Bota!", "An error occurred whilst saving your email notification preferences.": "Při ukládání nastavení e-mailových upozornění nastala chyba.", "Enable audible notifications in web client": "Povolit zvuková upozornění ve webové aplikaci", "Permalink": "Trvalý odkaz", - "Welcome to Riot.im": "Vítá vás Riot.im", "Off": "Vypnout", "#example": "#příklad", "Mentions only": "Pouze zmínky", "Failed to remove tag %(tagName)s from room": "Nepodařilo se odstranit štítek %(tagName)s z místnosti", "Wednesday": "Středa", "You can now return to your account after signing out, and sign in on other devices.": "Nyní se můžete ke svému účtu vrátit i po odhlášení a používat jej na ostatních zařízeních.", - "Please install Chrome or Firefox for the best experience.": "Prosím nainstalujte si Chrome nebo Firefox pro nejlepší zážitek.", "Enable email notifications": "Zapnout upozornění přes e-mail", "Event Type": "Typ události", "Download this file": "Stáhnout tento soubor", @@ -1137,14 +1089,11 @@ "View Community": "Zobrazit Komunitu", "%(count)s Members|one": "%(count)s Člen", "Event sent!": "Událost odeslána!", - "Matrix technical discussions": "Technické diskuse o Matrixu", - "Building services on Matrix": "Stavění služeb na Matrixu", "Event Content": "Obsah události", "Unable to fetch notification target list": "Nepodařilo se získat seznam cílů upozornění", "Quote": "Citace", "Collapse panel": "Sbalit panel", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Vzhled a chování aplikace může být ve vašem aktuální prohlížeči nesprávné a některé nebo všechny funkce mohou být chybné. Chcete-li i přes to pokračovat, nebudeme vám bránit, ale se všemi problémy, na které narazíte, si musíte poradit sami!", "Checking for an update...": "Kontrola aktualizací...", - "General discussion about Matrix and Riot": "Obecná diskuse o Matrixu a Riotu", "There are advanced notifications which are not shown here": "Jsou k dispozici pokročilá upozornění, která zde nejsou zobrazena" } diff --git a/src/i18n/strings/da.json b/src/i18n/strings/da.json index f47550afca..044c251e94 100644 --- a/src/i18n/strings/da.json +++ b/src/i18n/strings/da.json @@ -52,7 +52,6 @@ "Are you sure you want to reject the invitation?": "Er du sikker på du vil afvise invitationen?", "Are you sure you want to upload the following files?": "Er du sikker på du vil sende de følgende filer?", "Banned users": "Bortviste brugere", - "Bug Report": "Fejlrapport", "Bulk Options": "Masseindstillinger", "Can't load user settings": "Kan ikke indlæse brugerindstillinger", "Changes to who can read history will only apply to future messages in this room": "Ændringer til hvem der kan læse historie gælder kun for fremtidige meddelelser i dette rum", @@ -245,8 +244,6 @@ "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s inviterede %(targetDisplayName)s til rummet.", "Fetching third party location failed": "Hentning af tredjeparts placering mislykkedes", "A new version of Riot is available.": "En ny version a Riot er tilgængelig.", - "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk chat", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Beskriv venlist fejlen. Hvad gjorde du? Hvad forventede du ville ske? Hvad skete rent faktisk?", "Couldn't load home page": "Kunne ikke indlæse startsiden", "Send Account Data": "Send Konto Data", "All notifications are currently disabled for all targets.": "Alle meddelelser er for øjeblikket deaktiveret for alle mål.", @@ -257,44 +254,34 @@ "Failed to set direct chat tag": "Kunne ikke markere rummet som direkte chat", "Today": "I dag", "Files": "Filer", - "Report a bug": "Rapportér en fejl", - "Implementing VR services with Matrix": "Implementering af VR tjenester med Matrix", "You are not receiving desktop notifications": "Du modtager ikke skrivebordsmeddelelser", "Friday": "Fredag", "Update": "Opdater", - "You need to be using HTTPS to place a screen-sharing call.": "Du skal bruge HTTPS for at lave skærm-delings-opkald.", "What's New": "Hvad er nyt", "Add an email address above to configure email notifications": "Tilføj en emailadresse ovenfor for at konfigurere e-mail-underretninger", "Expand panel": "Udvid panel", "On": "Tændt", "Filter room names": "Filtrér rumnavne", "Changelog": "Ændringslog", - "Running Matrix services": "Drift af Matrix tjenester", "Waiting for response from server": "Venter på svar fra server", "Uploaded on %(date)s by %(user)s": "Uploadet den %(date)s af %(user)s", "Send Custom Event": "Send Brugerdefineret Begivenhed", - "Failed to send report: ": "Kunne ikke sende rapport: ", "Off": "Slukket", - "Unknown device": "Ukendt enhed", "Advanced notification settings": "Avancerede notifikationsindstillinger", "delete the alias.": "Slet aliaset.", "To return to your account in future you need to set a password": "For at komme ind på din konto i fremtiden skal du indstille et password", "Forget": "Glem", "#example": "#eksempel", - "Riot/Web & Desktop chat": "Riot/Web- & Desktopchat", "Hide panel": "Gem panel", "You cannot delete this image. (%(code)s)": "Du kan ikke slette dette billede. (%(code)s)", "Cancel Sending": "Stop Forsendelse", "Warning": "Advarsel", "This Room": "Dette rum", "The Home Server may be too old to support third party networks": "Hjemmeserveren kan være for gammel til at understøtte tredjepartsnetværk", - "All messages (loud)": "Alle beskeder (høj)", "Room not found": "Rummet ikke fundet", "Messages containing my display name": "Beskeder der indeholder mit viste navn", "Messages in one-to-one chats": "Beskeder i en-til-en chats", - "Contributing code to Matrix and Riot": "Biddrag med kode til Matrix og Riot", "Unavailable": "Utilgængelig", - "Community-run support for Synapse": "Fællesskabsstyret hjælp til Synapse", "Error saving email notification preferences": "Fejl ved at gemme e-mail-underretningsindstillinger", "View Decrypted Source": "Se Dekrypteret Kilde", "Failed to update keywords": "Kunne ikke opdatere søgeord", @@ -303,9 +290,6 @@ "Safari and Opera work too.": "Safari og Opera virker også.", "Please set a password!": "Indstil venligst et password!", "You have successfully set a password!": "Du har succesfuldt indstillet et password!", - "Chat with Riot Bot": "Chat med Riot Bot", - "Support for those using, running and writing other bridges": "Hjælp til dem der bruger, driver og skriver andre bridges", - "Admin support for Dendrite": "Adminstrationshjælp til Dendrite", "An error occurred whilst saving your email notification preferences.": "Der opstod en fejl under opbevaring af dine e-mail-underretningsindstillinger.", "Explore Room State": "Udforsk Rum Tilstand", "Source URL": "Kilde URL", @@ -313,14 +297,11 @@ "Filter results": "Filtrér resultater", "Members": "Medlemmer", "No update available.": "Ingen opdatering tilgængelig.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Masser af rum ekistere allerede i Matrix, forbundet til eksisterende netværk (Slack, IRC, Gitter osv.) eller selvstændige. Tjek kataloget ud!", "Noisy": "Støjende", "Failed to get protocol list from Home Server": "Kunne ikke få protokolliste fra Home Server", "Collecting app version information": "Indsamler app versionsoplysninger", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Slet rumaliaset %(alias)s og fjern %(name)s fra kataloget?", - "Co-ordination for Riot/Web translators": "Co-ordination af Riot/Web oversættere", "This will allow you to return to your account after signing out, and sign in on other devices.": "Dette vil tillade dig at vende tilbage til din konto efter at have logget ud og at logge ind på andre enheder.", - "Dev chat for the Dendrite dev team": "Udviklerchat til Dendrite udviklerholdet", "Keywords": "Søgeord", "Enable notifications for this account": "Aktivér underretninger for dette brugernavn", "Directory": "Rum katalog", @@ -342,19 +323,14 @@ "Direct Chat": "Personlig Chat", "The server may be unavailable or overloaded": "Serveren kan være utilgængelig eller overbelastet", "Reject": "Afvis", - "Riot is not supported on mobile web. Install the app?": "Riot understøtter ikke mobilhjemmesider. Vil du installere app'en?", - "Discussion of all things Matrix!": "Diskussion om alt der har med Matrix at gøre!", "Failed to set Direct Message status of room": "Kunne ikke indstille Direkte Beskedstatus for rummet", "Monday": "Mandag", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "For at diagnosticere problemer vil logs fra denne klient blive sendt sammen med fejlrapporten. Hvis du vil foretrække kun at sende teksten foroven, bedes du fjerne fluebenet:", "Remove from Directory": "Fjern fra Katalog", "Enable them now": "Aktivér dem nu", "Messages containing my user name": "Beskeder der indeholder mit brugernavn", - "Describe your problem here.": "Beskriv dit problem her.", "Toolbox": "Værktøjer", "Collecting logs": "Indsamler logfiler", "more": "mere", - "Support for those using the Matrix spec": "Hjælp til dem der anvender Matrix speciffikationen", "You must specify an event type!": "Du skal angive en begivenhedstype!", "(HTTP status %(httpStatus)s)": "(HTTP tilstand %(httpStatus)s)", "Invite to this room": "Inviter til dette rum", @@ -364,42 +340,28 @@ "Send": "Send", "Send logs": "Send logs", "All messages": "Alle beskeder", - "Implementing VoIP services with Matrix": "Implementering af VoIP tjenester med Matrix", - "Dev chat for the Riot/Web dev team": "Udviklerchat til Riot/Web udviklerholdet", "Call invitation": "Opkalds invitation", - "Riot Desktop on %(platformName)s": "Riot Desktop på %(platformName)s", "Downloading update...": "Downloader opdatering...", "You have successfully set a password and an email address!": "Du har succesfuldt indstillet et password og en emailadresse!", "Failed to send custom event.": "Kunne ikke sende brugerdefinerede begivenhed.", "What's new?": "Hvad er nyt?", - "Discussion of the Identity Service API": "Diskussion af Identity Service API'en", - "Support for those using and running matrix-appservice-irc": "Hjælp til dem der bruger og kører matrix-appservice-irc", - "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk chat", "Notify me for anything else": "Underret mig om noget andet", "View Source": "Se Kilde", - "Design and implementation of E2E in Matrix": "Design og implementering af E2E i Matrix", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Du kan bruge de brugerdefinerede server indstillinger til at logge ind på andre Matrix servere ved at skrive en anden Home Server adresse.
    Dette tillader dig at bruge Riot med en eksisterende Matrix konto på en anden home server.

    Du kan også indstille en brugerdefineret identity server men så vil du ikke kunne invitere brugere ved hjælp af deres emailadresse eller selv blive inviteret med emailadresse.", "Can't update user notification settings": "Kan ikke opdatere brugermeddelelsesindstillinger", "Notify for all other messages/rooms": "Underret om alle andre meddelelser / rum", "Unable to look up room ID from server": "Kunne ikke slå rum-id op på server", "Couldn't find a matching Matrix room": "Kunne ikke finde et matchende Matrix-rum", "Bug report sent": "Fejl rapporteret", - "Loading bug report module": "Indlæser fejlrepporterings modul", "All Rooms": "Alle rum", "You cannot delete this message. (%(code)s)": "Du kan ikke slette denne besked. (%(code)s)", "Thursday": "Torsdag", "I understand the risks and wish to continue": "Jeg forstår risikoen og ønsker at fortsætte", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s via %(browserName)s på %(osName)s", "Back": "Tilbage", "Show message in desktop notification": "Vis besked i skrivebordsnotifikation", "Unhide Preview": "Vis Forhåndsvisning", - "Announcements about Synapse releases": "Announceringer om Synapse udgivelser", - "Search the room directory": "Søg i rumkataloget", - "Please describe the bug and/or send logs.": "Beskriv venligst fejlen og/eller send logs.", "Unable to join network": "Kan ikke forbinde til netværket", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Du har muligvis konfigureret dem i en anden klient end Riot. Du kan ikke tune dem i Riot, men de gælder stadig", "Sorry, your browser is not able to run Riot.": "Beklager, din browser kan ikke køre Riot.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Decentraliseret, krypteret chat & samarbejde baseret på [matrix]", "Quote": "Citat", "Messages in group chats": "Beskeder i gruppechats", "Yesterday": "I går", @@ -408,11 +370,9 @@ "Low Priority": "Lav prioritet", "Unable to fetch notification target list": "Kan ikke hente meddelelsesmålliste", "Appear Offline": "Fremstå Offline", - "Get started with some tips from Riot Bot!": "Kom godt i gang med nogle tips fra Riot Bot!", "Set Password": "Indstil Password", "Enable audible notifications in web client": "Aktivér hørbare underretninger i webklienten", "Permalink": "Permanent link", - "Welcome to Riot.im": "Velkommen til Riot.im", "Resend": "Send igen", "Riot does not know how to join a room on this network": "Riot ved ikke, hvordan man kan deltage i et rum på dette netværk", "Mentions only": "Kun nævninger", @@ -426,13 +386,10 @@ "Pin Message": "Fasthold Besked", "Failed to change settings": "Kunne ikke ændre indstillinger", "Developer Tools": "Udviklingsværktøjer", - "Matrix technical discussions": "Matrix tekniske diskussioner", "Event Content": "Begivenhedsindhold", "Thank you!": "Tak!", - "Building services on Matrix": "Bygning af tjenester på Matrix", "Collapse panel": "Slå panel sammen", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Med din nuværnde broser kan udseendet og fornemmelsen af programmet være helt forkert og nogle funktioner virker måske ikke. Hvis du alligevel vil prøve så kan du fortsætte, men det er på egen risiko!", "Checking for an update...": "Checker om der er en opdatering...", - "General discussion about Matrix and Riot": "Generel diskussion om Matrix og Riot", "There are advanced notifications which are not shown here": "Der er avancerede meddelelser, som ikke vises her" } diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index b28cfdce1c..6e88c8b2fd 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -51,7 +51,6 @@ "Are you sure you want to reject the invitation?": "Bist du sicher, dass du die Einladung ablehnen willst?", "Are you sure you want to upload the following files?": "Bist du sicher, dass du die folgenden Dateien hochladen möchtest?", "Banned users": "Verbannte Benutzer", - "Bug Report": "Fehlerbericht", "Changes to who can read history will only apply to future messages in this room": "Änderungen, die bestimmen, wer den Chatverlauf lesen kann, gelten nur für zukünftige Nachrichten in diesem Raum", "Clear Cache and Reload": "Cache leeren und neu laden", "Confirm your new password": "Neues Passwort bestätigen", @@ -89,7 +88,6 @@ "Forgot your password?": "Passwort vergessen?", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Aus Sicherheitsgründen werden beim Ausloggen alle Ende-zu-Ende-Verschlüsselungs-Schlüssel in diesem Browser gelöscht. Wenn du in späteren Riot-Sitzungen den bisherigen Chatverlauf entschlüsseln möchtest, exportiere bitte deine Schlüssel zur sicheren Aufbewahrung.", "For security, this session has been signed out. Please sign in again.": "Aus Sicherheitsgründen wurde diese Sitzung beendet. Bitte melde dich erneut an.", - "Found a bug?": "Fehler gefunden?", "Guests cannot join this room even if explicitly invited.": "Gäste können diesem Raum nicht beitreten, auch wenn sie explizit eingeladen wurden.", "Hangup": "Auflegen", "Homeserver is": "Home-Server:", @@ -398,7 +396,6 @@ "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": "Melden", "riot-web version:": "Version von riot-web:", "Scroll to bottom of page": "Zum Seitenende springen", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Zeitstempel im 12-Stunden-Format anzeigen (z. B. 2:30pm)", @@ -653,11 +650,9 @@ "Define the power level of a user": "Setze das Berechtigungslevel eines Benutzers", "Edit": "Editieren", "Enable automatic language detection for syntax highlighting": "Automatische Spracherkennung für die Syntax-Hervorhebung aktivieren", - "Hide Apps": "Apps verbergen", "Hide join/leave messages (invites/kicks/bans unaffected)": "Betreten-/Verlassen-Benachrichtigungen verbergen (gilt nicht für Einladungen/Kicks/Bans)", "Revoke widget access": "Ziehe Widget-Zugriff zurück", "Sets the room topic": "Setzt das Raum-Thema", - "Show Apps": "Apps anzeigen", "To get started, please pick a username!": "Um zu starten, wähle bitte einen Nutzernamen!", "Unable to create widget.": "Widget kann nicht erstellt werden.", "Unbans user with given id": "Verbannung aufheben für Benutzer mit angegebener ID", @@ -692,7 +687,6 @@ "You are no longer ignoring %(userId)s": "%(userId)s wird nicht mehr ignoriert", "Message removed by %(userId)s": "Nachricht wurde von %(userId)s entfernt", "Name or matrix ID": "Name oder Matrix-ID", - "Unable to leave room": "Verlassen des Raumes fehlgeschlagen", "Leave": "Verlassen", "Failed to invite the following users to %(groupId)s:": "Die folgenden Benutzer konnten nicht in die Gruppe %(groupId)s eingeladen werden:", "Leave %(groupName)s?": "%(groupName)s verlassen?", @@ -992,7 +986,6 @@ "Key request sent.": "Schlüssel-Anfragen gesendet.", "Re-request encryption keys from your other devices.": "Verschlüsselungs-Schlüssel von deinen anderen Geräten erneut anfragen.", "%(user)s is a %(userRole)s": "%(user)s ist ein %(userRole)s", - "Changes made to your community might not be seen by other users for up to 30 minutes.": "Änderungen, die an deiner Community gemacht werden, können bis zu 30 Minuten brauchen, bis sie für andere sichtbar sind.", "Debug Logs Submission": "Einsenden des Fehlerprotokolls", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Wenn du einen Fehler via GitHub gemeldet hast, können Fehlerberichte uns helfen um das Problem zu finden. Sie enthalten Anwendungsdaten wie deinen Nutzernamen, Raum- und Gruppen-ID's und Aliase die du besucht hast und Nutzernamen anderer Nutzer. Sie enthalten keine Nachrichten.", "Submit debug logs": "Fehlerberichte einreichen", @@ -1006,8 +999,6 @@ "Leave this community": "Community verlassen", "Fetching third party location failed": "Das Abrufen des Drittanbieterstandorts ist fehlgeschlagen", "A new version of Riot is available.": "Eine neue Version von Riot ist verfügbar.", - "Riot/Android & matrix-android-sdk chat": "Riot-Android & matrix-android-sdk-Chat", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Bitte den Softwarefehler (vorzugsweise auf Englisch) beschreiben. Was hast du gemacht? Was sollte passieren? Was ist tatsächlich passiert?", "Couldn't load home page": "Startseite konnte nicht geladen werden", "Send Account Data": "Benutzerkonto-Daten senden", "All notifications are currently disabled for all targets.": "Aktuell sind alle Benachrichtigungen für alle Ziele deaktiviert.", @@ -1016,12 +1007,9 @@ "Notification targets": "Benachrichtigungsziele", "Today": "Heute", "Files": "Dateien", - "Report a bug": "Einen Softwarefehler melden", - "Implementing VR services with Matrix": "Implementierung von VR-Diensten mit Matrix", "You are not receiving desktop notifications": "Du erhältst keine Desktop-Benachrichtigungen", "Friday": "Freitag", "Update": "Aktualisieren", - "You need to be using HTTPS to place a screen-sharing call.": "Du musst HTTPS nutzen um einen Anruf mit Bildschirmfreigabe durchzuführen.", "What's New": "Was ist neu", "Add an email address above to configure email notifications": "Füge oben eine E-Mail-Adresse hinzu, um die E-Mail-Benachrichtigungseinstellungen zu konfigurieren", "Expand panel": "Panel ausklappen", @@ -1029,18 +1017,14 @@ "%(count)s Members|other": "%(count)s Mitglieder", "Filter room names": "Raum-Namen filtern", "Changelog": "Änderungsprotokoll", - "Running Matrix services": "Matrix-Dienste betreiben", "Waiting for response from server": "Auf Antwort vom Server warten", "Send Custom Event": "Benutzerdefiniertes Event senden", - "Failed to send report: ": "Senden des Reports fehlgeschlagen: ", - "Unknown device": "Unbekanntes Gerät", "Advanced notification settings": "Erweiterte Benachrichtigungs-Einstellungen", "Failed to send logs: ": "Senden von Logs fehlgeschlagen: ", "delete the alias.": "Lösche den Alias.", "To return to your account in future you need to set a password": "Um in Zukunft auf dein Benutzerkonto zugreifen zu können, musst du ein Passwort setzen", "Forget": "Entfernen", "#example": "#Beispiel", - "Riot/Web & Desktop chat": "Riot/Web & Desktop-Chat", "Hide panel": "Panel verbergen", "You cannot delete this image. (%(code)s)": "Das Bild kann nicht gelöscht werden. (%(code)s)", "Cancel Sending": "Senden abbrechen", @@ -1050,9 +1034,7 @@ "Room not found": "Raum nicht gefunden", "Messages containing my display name": "Nachrichten, die meinen Anzeigenamen enthalten", "Messages in one-to-one chats": "Nachrichten in Einzel-Chats", - "Contributing code to Matrix and Riot": "Code zu Matrix und Riot beitragen", "Unavailable": "Nicht verfügbar", - "Community-run support for Synapse": "Support für Synapse von der Community", "View Decrypted Source": "Entschlüsselten Quellcode ansehen", "Failed to update keywords": "Schlüsselwörter konnten nicht aktualisiert werden", "Notes:": "Notizen:", @@ -1061,9 +1043,6 @@ "Safari and Opera work too.": "Safari und Opera sind weitere Alternativen.", "Please set a password!": "Bitte setze ein Passwort!", "You have successfully set a password!": "Du hast erfolgreich ein Passwort gesetzt!", - "Chat with Riot Bot": "Mit dem Riot-Bot chatten", - "Support for those using, running and writing other bridges": "Unterstützung für die, die andere Matrix-Bridges nutzen, betreiben oder entwickeln", - "Admin support for Dendrite": "Admin-Unterstützung für Dendrite", "An error occurred whilst saving your email notification preferences.": "Beim Speichern deiner E-Mail-Benachrichtigungseinstellungen ist ein Fehler aufgetreten.", "Explore Room State": "Raum-Status erkunden", "Source URL": "Quell-URL", @@ -1071,15 +1050,11 @@ "Filter results": "Ergebnisse filtern", "Members": "Mitglieder", "No update available.": "Kein Update verfügbar.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Im Matrix-Netzwerk existieren bereits jetzt zahlreiche Räume, die entweder mit bekannten Netzwerken wie Slack, IRC, Gitter, usw. verknüpft sind oder auch komplett eigenständig betrieben werden. Einen genauen Überblick erhältst du im Raum-Verzeichnis!", "Noisy": "Laut", "Failed to get protocol list from Home Server": "Fehler beim Abrufen der Protokoll-Liste vom Home-Server", "Collecting app version information": "App-Versionsinformationen werden abgerufen", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Soll der Raum-Alias %(alias)s gelöscht und der %(name)s aus dem Verzeichnis entfernt werden?", - "customServer_text": "Du kannst die erweiterten Server-Optionen nutzen, um dich auf anderen Matrix-Servern anzumelden, indem du eine andere Heimserver-URL eingibst.
    Dies ermöglicht es dir, Riot mit einem bereits existierenden Matrix-Konto auf einem anderen Heimserver zu nutzen.

    Du kannst auch einen benutzerdefinierten Identitäts-Server eingeben, allerdings wirst du dann nicht in der Lage sein, andere Benutzer per E-Mail-Adresse einzuladen oder selbst Einladungen per E-Mail-Adresse zu erhalten.", - "Co-ordination for Riot/Web translators": "Koordination für Riot/Web-Übersetzer", "This will allow you to return to your account after signing out, and sign in on other devices.": "Dies erlaubt dir, dich wieder an deinem Konto anzumelden, nachdem du dich abgemeldet hast.", - "Dev chat for the Dendrite dev team": "Entwickler-Chat für das Dendrite-Entwickler-Team", "Keywords": "Schlüsselwörter", "Enable notifications for this account": "Benachrichtigungen für dieses Benutzerkonto aktivieren", "Directory": "Raum-Verzeichnis", @@ -1105,16 +1080,11 @@ "Direct Chat": "Direkt-Chat", "The server may be unavailable or overloaded": "Der Server ist vermutlich nicht erreichbar oder überlastet", "Reject": "Ablehnen", - "Riot is not supported on mobile web. Install the app?": "Riot wird im mobilen Web nicht unterstützt. App installieren?", - "Discussion of all things Matrix!": "\"Diskussion über alle Dinge\"-Matrix!", "Failed to set Direct Message status of room": "Konnte den direkten Benachrichtigungsstatus nicht setzen", "Monday": "Montag", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Zur Diagnose von Softwareproblemen werden mit diesem Fehlerbericht auch Log-Dateien übermittelt. Wenn nur der oben eingegebene Text übermittelt werden soll, bitte die nachfolgende Auswahl entsprechend abwählen:", - "Send Custom State Event": "Benutzerdefiniertes Status-Event senden", "Remove from Directory": "Aus dem Raum-Verzeichnis entfernen", "Enable them now": "Aktiviere diese jetzt", "Messages containing my user name": "Nachrichten, die meinen Benutzernamen enthalten", - "Describe your problem here.": "Beschreibe dein Problem hier.", "Toolbox": "Werkzeugkasten", "Collecting logs": "Protokolle werden abgerufen", "more": "mehr", @@ -1129,48 +1099,31 @@ "Quote": "Zitat", "Send logs": "Logdateien übermitteln", "All messages": "Alle Nachrichten", - "Implementing VoIP services with Matrix": "Implementierung von VoIP-Diensten mit Matrix", - "Dev chat for the Riot/Web dev team": "Entwickler-Chat für das Riot/Web-Entwickler-Team", "Call invitation": "Anruf-Einladung", - "Riot Desktop on %(platformName)s": "Riot Desktop auf %(platformName)s", "Downloading update...": "Update wird heruntergeladen...", "State Key": "Status-Schlüssel", "Failed to send custom event.": "Senden des benutzerdefinierten Events fehlgeschlagen.", "What's new?": "Was ist neu?", - "Discussion of the Identity Service API": "Diskussion der Identitätsdienst-API", - "Support for those using and running matrix-appservice-irc": "Unterstützung für die, die \"matrix-appservice-irc\" betreiben und nutzen", - "Riot/iOS & matrix-ios-sdk chat": "Riot-iOS & \"matrix-ios-sdk\"-Chat", "Notify me for anything else": "Über alles andere benachrichtigen", "When I'm invited to a room": "Wenn ich in einen Raum eingeladen werde", - "Design and implementation of E2E in Matrix": "Design und Implementierung von Ende-zu-Ende-Verschlüsselung in Matrix", "Click here to create a GitHub issue.": "Klicke hier um ein GithHub-Problem zu erstellen.", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Die benutzerdefinierten Server-Einstellungen kannst du verwenden, um dich auf anderen Matrix-Servern anzumelden, indem du eine abweichende Heimserver-URL eingibst.
    Somit ist es möglich, Riot mit einem bereits bestehendem Matrix-Benutzerkonto auf einem anderen Heimserver zu verwenden.

    Außerdem kannst du einen benutzerdefinierten Identitätsserver eingeben. Allerdings kannst du in diesem Fall Benutzer nicht mehr per E-Mail-Adresse einladen und auch selbst nicht mehr per E-Mail-Adresse eingeladen werden.", "Can't update user notification settings": "Benachrichtigungs-Einstellungen des Benutzers konnten nicht aktualisiert werden", "Notify for all other messages/rooms": "Benachrichtigungen für alle anderen Mitteilungen/Räume aktivieren", "Unable to look up room ID from server": "Es ist nicht möglich, die Raum-ID auf dem Server nachzuschlagen", "Couldn't find a matching Matrix room": "Konnte keinen entsprechenden Matrix-Raum finden", - "Support for those using the Matrix spec": "Unterstützung für die Nutzer der Matrix-Spezification", - "Safari and Opera work too.": "Safari und Opera funktionieren ebenfalls.", - "Loading bug report module": "Lade Fehlerbericht-Modul", "All Rooms": "In allen Räumen", "Search for a room": "Nach einem Raum suchen", "Thursday": "Donnerstag", "Search…": "Suchen…", "Logs sent": "Logs gesendet", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s via %(browserName)s auf %(osName)s", "Back": "Zurück", "Reply": "Antworten", "Show message in desktop notification": "Nachricht in der Desktop-Benachrichtigung anzeigen", "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Fehlerberichte enthalten Anwendungsdaten wie deinen Nutzernamen, Raum- und Gruppen-ID's und Aliase die du besucht hast sowie Nutzernamen anderer Nutzer. Sie enthalten keine Nachrichten.", "Unhide Preview": "Vorschau wieder anzeigen", - "Announcements about Synapse releases": "Ankündigungen über Synapse-Versionen", - "Search the room directory": "Raum-Verzeichnis durchsuchen", - "Please describe the bug and/or send logs.": "Bitte den Fehler beschreiben und/oder Log-Dateien übermitteln.", "Unable to join network": "Es ist nicht möglich, dem Netzwerk beizutreten", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Du hast sie eventuell auf einem anderen Matrix-Client und nicht in Riot konfiguriert. Sie können in Riot nicht verändert werden, gelten aber trotzdem", "Sorry, your browser is not able to run Riot.": "Es tut uns leid, aber dein Browser kann Riot nicht ausführen.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Dezentrale, verschlüsselte Chat- & Kollaborationslösung unterstützt von [matrix]", - "Building services on Matrix": "Dienste für Matrix entwickeln", "Messages in group chats": "Nachrichten in Gruppen-Chats", "Yesterday": "Gestern", "Error encountered (%(errorDetail)s).": "Es ist ein Fehler aufgetreten (%(errorDetail)s).", @@ -1178,16 +1131,13 @@ "Low Priority": "Niedrige Priorität", "Unable to fetch notification target list": "Liste der Benachrichtigungsempfänger konnte nicht abgerufen werden", "Appear Offline": "Als offline anzeigen", - "Get started with some tips from Riot Bot!": "Lass Dir vom Riot-Bot eine Einführung geben!", "Set Password": "Passwort einrichten", "Enable audible notifications in web client": "Audio-Benachrichtigungen im Web-Client aktivieren", "Permalink": "Permanenter Link", - "Welcome to Riot.im": "Willkommen bei Riot.im", "Off": "Aus", "Riot does not know how to join a room on this network": "Riot weiß nicht, wie es einem Raum auf diesem Netzwerk beitreten soll", "Mentions only": "Nur, wenn du erwähnt wirst", "You can now return to your account after signing out, and sign in on other devices.": "Du kannst nun zu deinem Benutzerkonto zurückkehren, nachdem du dich abgemeldet hast. Anschließend kannst du dich an anderen Geräten anmelden.", - "Please install Chrome or Firefox for the best experience.": "Bitte installiere Chrome oder Firefox für die beste Erfahrung.", "Enable email notifications": "E-Mail-Benachrichtigungen aktivieren", "Event Type": "Event-Typ", "Download this file": "Datei herunterladen", @@ -1197,13 +1147,11 @@ "%(count)s Members|one": "%(count)s Mitglied", "Event sent!": "Event gesendet!", "View Source": "Quellcode ansehen", - "Matrix technical discussions": "Technische Diskussion über Matrix", "Event Content": "Event-Inhalt", "Thank you!": "Danke!", "Uploaded on %(date)s by %(user)s": "Hochgeladen: %(date)s von %(user)s", "Collapse panel": "Panel einklappen", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "In deinem aktuell verwendeten Browser können Aussehen und Handhabung der Anwendung unter Umständen noch komplett fehlerhaft sein, so dass einige bzw. im Extremfall alle Funktionen nicht zur Verfügung stehen. Du kannst es trotzdem versuchen und fortfahren, bist dabei aber bezüglich aller auftretenden Probleme auf dich allein gestellt!", "Checking for an update...": "Nach Updates suchen...", - "General discussion about Matrix and Riot": "Allgemeine Diskussion über Matrix und Riot", "There are advanced notifications which are not shown here": "Es existieren erweiterte Benachrichtigungen, welche hier nicht angezeigt werden" } diff --git a/src/i18n/strings/el.json b/src/i18n/strings/el.json index 726b81ac9b..b5acd8855e 100644 --- a/src/i18n/strings/el.json +++ b/src/i18n/strings/el.json @@ -36,7 +36,6 @@ "Attachment": "Επισύναψη", "%(senderName)s banned %(targetName)s.": "Ο χρήστης %(senderName)s έδιωξε τον χρήστη %(targetName)s.", "Autoplay GIFs and videos": "Αυτόματη αναπαραγωγή GIFs και βίντεο", - "Bug Report": "Αναφορά σφάλματος", "Anyone who knows the room's link, apart from guests": "Oποιοσδήποτε", "%(items)s and %(lastItem)s": "%(items)s %(lastItem)s", "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Ένα μήνυμα στάλθηκε στο +%(msisdn)s. Παρακαλώ γράψε τον κωδικό επαλήθευσης που περιέχει", @@ -117,7 +116,6 @@ "Forgot your password?": "Ξεχάσατε τoν κωδικό πρόσβασης σας;", "For security, this session has been signed out. Please sign in again.": "Για λόγους ασφαλείας, αυτή η συνεδρία έχει τερματιστεί. Παρακαλούμε συνδεθείτε ξανά.", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Για λόγους ασφαλείας, τα κλειδιά κρυπτογράφησης θα διαγράφονται από τον περιηγητή κατά την αποσύνδεση σας. Εάν επιθυμείτε να αποκρυπτογραφήσετε τις συνομιλίες σας στο μέλλον, εξάγετε τα κλειδιά σας και κρατήστε τα ασφαλή.", - "Found a bug?": "Βρήκατε κάποιο πρόβλημα;", "Hangup": "Κλείσιμο", "Historical": "Ιστορικό", "Homeserver is": "Ο διακομιστής είναι", @@ -262,7 +260,6 @@ "Remote addresses for this room:": "Απομακρυσμένες διευθύνσεις για το δωμάτιο:", "Remove Contact Information?": "Αφαίρεση πληροφοριών επαφής;", "Remove %(threePid)s?": "Αφαίρεση %(threePid)s;", - "Report it": "Αναφορά", "Results from DuckDuckGo": "Αποτελέσματα από DuckDuckGo", "Return to login screen": "Επιστροφή στην οθόνη σύνδεσης", "Room %(roomId)s not visible": "Το δωμάτιο %(roomId)s δεν είναι ορατό", @@ -646,8 +643,6 @@ "Check for update": "Έλεγχος για ενημέρωση", "Fetching third party location failed": "Η λήψη τοποθεσίας απέτυχε", "A new version of Riot is available.": "Μία νέα έκδοση του Riot είναι διαθέσιμη.", - "Riot/Android & matrix-android-sdk chat": "Συζήτηση για το Riot/Android & matrix-android-sdk", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Παρακαλούμε περιγράψτε το σφάλμα. Τι κάνατε; Τι περιμένατε να συμβεί; Τι έγινε τελικά;", "All notifications are currently disabled for all targets.": "Όλες οι ειδοποιήσεις είναι προς το παρόν απενεργοποιημένες για όλες τις συσκευές.", "Uploading report": "Αποστολή αναφοράς", "Sunday": "Κυριακή", @@ -657,30 +652,23 @@ "Failed to set direct chat tag": "Δεν ήταν δυνατός ο χαρακτηρισμός της συνομιλίας ως 1-προς-1", "Today": "Σήμερα", "Files": "Αρχεία", - "Report a bug": "Αναφορά σφάλματος", - "Implementing VR services with Matrix": "Υλοποίηση υπηρεσίων VR με το Matrix", "You are not receiving desktop notifications": "Δεν λαμβάνετε ειδοποιήσεις στην επιφάνεια εργασίας", "Friday": "Παρασκευή", "Update": "Ενημέρωση", - "You need to be using HTTPS to place a screen-sharing call.": "Απαιτείται η χρήση HTTPS για το διαμοιρασμό της επιφάνειας εργασίας μέσω κλήσης.", "Riot does not know how to join a room on this network": "To Riot δεν γνωρίζει πως να συνδεθεί σε δωμάτια που ανήκουν σ' αυτό το δίκτυο", "Add an email address above to configure email notifications": "Προσθέστε μια διεύθυνση ηλεκτρονικής αλληλογραφίας στο παραπάνω πεδίο, για να έχετε τη δυνατότητα να λαμβάνετε ειδοποιήσεις", "Expand panel": "Μεγιστοποίηση καρτέλας", "On": "Ενεργό", "Filter room names": "Φιλτράρισμα δωματίων", "Changelog": "Αλλαγές", - "Running Matrix services": "Χρησιμοποιώντας τις υπηρεσίες του Matrix", "Waiting for response from server": "Αναμονή απάντησης από τον διακομιστή", "Leave": "Αποχώρηση", "Uploaded on %(date)s by %(user)s": "Απεστάλη στις %(date)s από %(user)s", - "Failed to send report: ": "Δεν ήταν δυνατή η αποστολή της αναφοράς: ", - "Unknown device": "Άγνωστη συσκευή", "Advanced notification settings": "Προχωρημένες ρυθμίσεις ειδοποιήσεων", "delete the alias.": "διέγραψε το ψευδώνυμο.", "To return to your account in future you need to set a password": "Για να επιστρέψετε στον λογαριασμό σας μελλοντικα πρέπει να ορίσετε έναν κωδικό πρόσβασης", "Forget": "Παράλειψη", "World readable": "Εμφανές σε όλους", - "Riot/Web & Desktop chat": "Συζήτηση για το Riot/Web & Desktop", "Hide panel": "Απόκρυψη καρτέλας", "You cannot delete this image. (%(code)s)": "Δεν μπορείτε να διαγράψετε αυτή την εικόνα. (%(code)s)", "Cancel Sending": "Ακύρωση αποστολής", @@ -691,32 +679,23 @@ "Room not found": "Το δωμάτιο δεν βρέθηκε", "Messages containing my display name": "Μηνύματα που περιέχουν το όνομα μου", "Messages in one-to-one chats": "Μηνύματα σε 1-προς-1 συνομιλίες", - "Contributing code to Matrix and Riot": "Συνεισφορά κώδικα στο Matrix και Riot", "Unavailable": "Μη διαθέσιμο", - "Community-run support for Synapse": "Κοινοτική υποστήριξη για το Synapse", "View Decrypted Source": "Προβολή του αποκρυπτογραφημένου κώδικα", "Send": "Αποστολή", "remove %(name)s from the directory.": "αφαίρεση του %(name)s από το ευρετήριο.", "Notifications on the following keywords follow rules which can’t be displayed here:": "Οι ειδοποιήσεις για τις επόμενες λέξεις κλειδία ακολουθούν κανόνες που δεν είναι δυνατόν να εμφανιστούν εδώ:", "Please set a password!": "Παρακαλούμε ορίστε έναν κωδικό πρόσβασης!", "You have successfully set a password!": "Ο κωδικός πρόσβασης ορίστηκε επιτυχώς!", - "Chat with Riot Bot": "Συνομιλία με το Riot Bot", - "Support for those using, running and writing other bridges": "Υποστήριξη για τους χρήστες που χρησιμοποιούν ή αναπτύσσουν εφαρμογές ενσωμάτωσης για το Matrix", - "Admin support for Dendrite": "Υποστήριξη διαχειριστή για το Dendrite", "An error occurred whilst saving your email notification preferences.": "Ένα σφάλμα προέκυψε κατά την αποθήκευση των ρυθμίσεων σας.", "Source URL": "Πηγαίο URL", "Messages sent by bot": "Μηνύματα από bots", "Members": "Μέλη", "No update available.": "Δεν υπάρχει διαθέσιμη ενημέρωση.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Αρκετά δωμάτια υπάρχουν ήδη στο Matrix, συνδεδεμένα σε υπάρχοντα δίκτυα (Slack, IRC, Gitter κ.λπ) ή αυτόνομα. Ρίξτε μια ματιά στο ευρετήριο!", "Noisy": "Δυνατά", "Failed to get protocol list from Home Server": "Δεν ήταν δυνατή η εύρεση των διαθέσιμων πρωτοκόλλων από το διακομιστή", "Collecting app version information": "Συγκέντρωση πληροφοριών σχετικά με την έκδοση της εφαρμογής", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Διαγραφή του ψευδώνυμου %(alias)s και αφαίρεση του %(name)s από το ευρετήριο;", - "customServer_text": "Μπορείτε να χρησιμοποιήσετε τις προσαρμοσμένες ρυθμίσεις για να εισέλθετε σε άλλους διακομιστές Matrix επιλέγοντας μια διαφορετική διεύθυνση για το διακομιστή.
    Αυτό σας επιτρέπει να χρησιμοποιήσετε την εφαρμογή Riot με έναν υπάρχοντα λογαριασμό σε διαφορετικό διακομιστή.

    Επίσης μπορείτε να επιλέξετε ένα διαφορετικό διακομιστή ταυτότητας αλλά δεν θα έχετε τη δυνατότητα να προσκαλέσετε άλλους χρήστες ή να σας προσκαλέσουν μέσω μηνυμάτων ηλεκτρονικής αλληλογραφίας.", - "Co-ordination for Riot/Web translators": "Συντονισμός για μεταφραστές του Riot/Web", "This will allow you to return to your account after signing out, and sign in on other devices.": "Αυτό θα σας επιτρέψει να επιστρέψετε στον λογαριασμό σας αφού αποσυνδεθείτε και συνδεθείτε από άλλες συσκευές.", - "Dev chat for the Dendrite dev team": "Συζήτηση με την ομάδα ανάπτυξης του Dendrite", "Keywords": "Λέξεις κλειδιά", "Enable notifications for this account": "Ενεργοποίηση ειδοποιήσεων για τον λογαριασμό", "Directory": "Ευρετήριο", @@ -728,7 +707,6 @@ "I understand the risks and wish to continue": "Κατανοώ του κινδύνους και επιθυμώ να συνεχίσω", "Remove %(name)s from the directory?": "Αφαίρεση του %(name)s από το ευρετήριο;", "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Το Riot χρησιμοποιεί αρκετά προχωρημένα χαρακτηριστικά των περιηγητών Ιστού, ορισμένα από τα οποία δεν είναι διαθέσιμα ή είναι σε πειραματικό στάδιο στον περιηγητή σας.", - "Please install Chrome or Firefox for the best experience.": "Παρακαλούμε εγκαταστήστε έναν από τους περιηγητές Chrome ή Firefox για την καλύτερη δυνατή εμπειρία.", "Unnamed room": "Ανώνυμο δωμάτιο", "Remove from Directory": "Αφαίρεση από το ευρετήριο", "Saturday": "Σάββατο", @@ -736,15 +714,11 @@ "Direct Chat": "Απευθείας συνομιλία", "The server may be unavailable or overloaded": "Ο διακομιστής είναι μη διαθέσιμος ή υπερφορτωμένος", "Reject": "Απόρριψη", - "Riot is not supported on mobile web. Install the app?": "Το Riot δεν υποστηρίζεται από περιηγητές κινητών. Θέλετε να εγκαταστήσετε την εφαρμογή;", - "Discussion of all things Matrix!": "Συζήτηση για όλα τα πράγματα του Matrix!", "Failed to set Direct Message status of room": "Δεν ήταν δυνατός ο ορισμός της κατάστασης Direct Message του δωματίου", "Monday": "Δευτέρα", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Προκειμένου να διαγνωστούν προβλήματα, τα αρχεία καταγραφής από αυτόν τον πελάτη θα σταλούν με αυτήν την αναφορά σφάλματος. Αν προτιμάτε να στείλετε μόνο το παραπάνω κείμενο, απενεργοποιήστε:", "All messages (noisy)": "Όλα τα μηνύματα (δυνατά)", "Enable them now": "Ενεργοποίηση", "Forward Message": "Προώθηση", - "Describe your problem here.": "Περιγράψτε το πρόβλημα σας εδώ.", "Messages containing my user name": "Μηνύματα που περιέχουν το ψευδώνυμο μου", "Collecting logs": "Συγκέντρωση πληροφοριών", "more": "περισσότερα", @@ -755,50 +729,32 @@ "Failed to update keywords": "Οι λέξεις κλειδιά δεν ενημερώθηκαν", "Send logs": "Αποστολή πληροφοριών", "All messages": "Όλα τα μηνύματα", - "Implementing VoIP services with Matrix": "Υλοποίηση υπηρεσίων VoIP με το Matrix", - "Dev chat for the Riot/Web dev team": "Συζήτηση με την ομάδα ανάπτυξης του Riot/Web", "Call invitation": "Πρόσκληση σε κλήση", - "Riot Desktop on %(platformName)s": "Riot Desktop σε %(platformName)s", "Downloading update...": "Γίνεται λήψη της ενημέρωσης...", "You have successfully set a password and an email address!": "Ο κωδικός πρόσβασης και η διεύθυνση ηλεκτρονικής αλληλογραφίας ορίστηκαν επιτυχώς!", "What's new?": "Τι νέο υπάρχει;", - "Discussion of the Identity Service API": "Συζήτηση σχετικά με το Identity Service API", - "Support for those using and running matrix-appservice-irc": "Υποστήριξη για τους χρήστες που χρησιμοποιούν το matrix-appservice-irc", - "Riot/iOS & matrix-ios-sdk chat": "Συζήτηση για το Riot/iOS & matrix-ios-sdk", "Notify me for anything else": "Ειδοποίηση για οτιδήποτε άλλο", "When I'm invited to a room": "Όταν με προσκαλούν σ' ένα δωμάτιο", - "Design and implementation of E2E in Matrix": "Σχεδιασμός και υλοποίηση του E2E στο Matrix", "Can't update user notification settings": "Δεν είναι δυνατή η ενημέρωση των ρυθμίσεων ειδοποίησης χρήστη", "Notify for all other messages/rooms": "Ειδοποίηση για όλα τα υπόλοιπα μηνύματα/δωμάτια", "Unable to look up room ID from server": "Δεν είναι δυνατή η εύρεση του ID για το δωμάτιο", "Couldn't find a matching Matrix room": "Δεν βρέθηκε κάποιο δωμάτιο", - "Support for those using the Matrix spec": "Υποστήριξη για τους χρήστες που χρησιμοποιούν το Matrix spec", - "Safari and Opera work too.": "Safari και Opera λειτουργούν επίσης.", - "Loading bug report module": "Φόρτωση μονάδας αναφοράς σφαλμάτων", "Invite to this room": "Πρόσκληση σε αυτό το δωμάτιο", "You cannot delete this message. (%(code)s)": "Δεν μπορείτε να διαγράψετε αυτό το μήνυμα. (%(code)s)", "Thursday": "Πέμπτη", "Search…": "Αναζήτηση…", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s μέσω %(browserName)s σε %(osName)s", "Unhide Preview": "Προεπισκόπηση", - "Announcements about Synapse releases": "Ανακοινώσεις σχετικά με τις εκδόσεις του Synapse", - "Search the room directory": "Αναζήτηση του ευρετηρίου δωματίων", - "Please describe the bug and/or send logs.": "Παρακαλούμε περιγράψτε το σφάλμα και/ή στείλτε πληροφορίες σχετικά με την εφαρμογή.", "Unable to join network": "Δεν είναι δυνατή η σύνδεση στο δίκτυο", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Ισως να έχετε κάνει τις ρυθμίσεις σε άλλη εφαρμογή εκτός του Riot. Δεν μπορείτε να τις αλλάξετε μέσω του Riot αλλά ισχύουν κανονικά", "Sorry, your browser is not able to run Riot.": "Λυπούμαστε, αλλά ο περιηγητές σας δεν υποστηρίζεται από το Riot.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Αποκεντρωμένη, κρυπτογραφημένη συνομιλία & συνεργασία με τη βοήθεια του [matrix]", - "Building services on Matrix": "Ανάπτυξη υπηρεσιών στο Matrix", "Messages in group chats": "Μηνύματα σε ομαδικές συνομιλίες", "Yesterday": "Χθές", "Error encountered (%(errorDetail)s).": "Παρουσιάστηκε σφάλμα (%(errorDetail)s).", "Low Priority": "Χαμηλή προτεραιότητα", "What's New": "Τι νέο υπάρχει", - "Get started with some tips from Riot Bot!": "Ξεκινήστε με μερικές συμβουλές από το Riot Bot!", "Set Password": "Ορισμός κωδικού πρόσβασης", "Enable audible notifications in web client": "Ενεργοποίηση ηχητικών ειδοποιήσεων", "Permalink": "Μόνιμος σύνδεσμος", - "Welcome to Riot.im": "Καλώς ήλθατε στο Riot.im", "Off": "Ανενεργό", "#example": "#παράδειγμα", "Mentions only": "Μόνο αναφορές", @@ -811,12 +767,10 @@ "Download this file": "Λήψη αρχείου", "Failed to change settings": "Δεν ήταν δυνατή η αλλαγή των ρυθμίσεων", "View Source": "Προβολή κώδικα", - "Matrix technical discussions": "Τεχνικές συζητήσεις σχετικά με το Matrix", "Unable to fetch notification target list": "Δεν ήταν δυνατή η εύρεση στόχων για τις ειδοποιήσεις", "Quote": "Παράθεση", "Collapse panel": "Ελαχιστοποίηση καρτέλας", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Με τον τρέχον περιηγητή, η εμφάνιση και η αίσθηση της εφαρμογής ενδέχεται να είναι εντελώς εσφαλμένη και ορισμένες ή όλες οι λειτουργίες ενδέχεται να μην λειτουργούν. Εάν θέλετε να το δοκιμάσετε ούτως ή άλλως μπορείτε να συνεχίσετε, αλλά είστε μόνοι σας σε ό, τι αφορά τα προβλήματα που μπορεί να αντιμετωπίσετε!", "Checking for an update...": "Γίνεται έλεγχος για ενημέρωση...", - "General discussion about Matrix and Riot": "Γενική συζήτηση σχετικά με Matrix και Riot", "There are advanced notifications which are not shown here": "Υπάρχουν προχωρημένες ειδοποιήσεις οι οποίες δεν εμφανίζονται εδώ" } diff --git a/src/i18n/strings/en_US.json b/src/i18n/strings/en_US.json index 0c9bfdf881..a3184fdc38 100644 --- a/src/i18n/strings/en_US.json +++ b/src/i18n/strings/en_US.json @@ -46,7 +46,6 @@ "Banned users": "Banned users", "Bans user with given id": "Bans user with given id", "Blacklisted": "Blacklisted", - "Bug Report": "Bug Report", "Bulk Options": "Bulk Options", "Call Timeout": "Call Timeout", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.", @@ -159,12 +158,10 @@ "Forgot your password?": "Forgot your password?", "For security, this session has been signed out. Please sign in again.": "For security, this session has been signed out. Please sign in again.", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.", - "Found a bug?": "Found a bug?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s", "Guest access is disabled on this Home Server.": "Guest access is disabled on this Home Server.", "Guests cannot join this room even if explicitly invited.": "Guests cannot join this room even if explicitly invited.", "Hangup": "Hangup", - "Hide Apps": "Hide Apps", "Hide read receipts": "Hide read receipts", "Hide Text Formatting Toolbar": "Hide Text Formatting Toolbar", "Historical": "Historical", @@ -282,7 +279,6 @@ "Remove": "Remove", "Remove %(threePid)s?": "Remove %(threePid)s?", "%(senderName)s requested a VoIP conference.": "%(senderName)s requested a VoIP conference.", - "Report it": "Report it", "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.": "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.", "Results from DuckDuckGo": "Results from DuckDuckGo", "Return to login screen": "Return to login screen", @@ -314,7 +310,6 @@ "%(senderName)s set a profile picture.": "%(senderName)s set a profile picture.", "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s set their display name to %(displayName)s.", "Settings": "Settings", - "Show Apps": "Show Apps", "Show panel": "Show panel", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Show timestamps in 12 hour format (e.g. 2:30pm)", "Signed Out": "Signed Out", @@ -713,8 +708,6 @@ "%(senderName)s changed the pinned messages for the room.": "%(senderName)s changed the pinned messages for the room.", "Fetching third party location failed": "Fetching third party location failed", "A new version of Riot is available.": "A new version of Riot is available.", - "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk chat", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Please describe the bug. What did you do? What did you expect to happen? What actually happened?", "Couldn't load home page": "Couldn't load home page", "All notifications are currently disabled for all targets.": "All notifications are currently disabled for all targets.", "Uploading report": "Uploading report", @@ -725,30 +718,23 @@ "Failed to set direct chat tag": "Failed to set direct chat tag", "Today": "Today", "Failed to get protocol list from Home Server": "Failed to get protocol list from Home Server", - "Report a bug": "Report a bug", - "Implementing VR services with Matrix": "Implementing VR services with Matrix", "You are not receiving desktop notifications": "You are not receiving desktop notifications", "Friday": "Friday", "Update": "Update", - "You need to be using HTTPS to place a screen-sharing call.": "You need to be using HTTPS to place a screen-sharing call.", "What's New": "What's New", "Add an email address above to configure email notifications": "Add an email address above to configure email notifications", "Expand panel": "Expand panel", "On": "On", "Filter room names": "Filter room names", "Changelog": "Changelog", - "Running Matrix services": "Running Matrix services", "Waiting for response from server": "Waiting for response from server", "Leave": "Leave", - "Failed to send report: ": "Failed to send report: ", - "Unknown device": "Unknown device", "Advanced notification settings": "Advanced notification settings", "delete the alias.": "delete the alias.", "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", "Forget": "Forget", "World readable": "World readable", "#example": "#example", - "Riot/Web & Desktop chat": "Riot/Web & Desktop chat", "Hide panel": "Hide panel", "You cannot delete this image. (%(code)s)": "You cannot delete this image. (%(code)s)", "Cancel Sending": "Cancel Sending", @@ -759,32 +745,23 @@ "Room not found": "Room not found", "Messages containing my display name": "Messages containing my display name", "Messages in one-to-one chats": "Messages in one-to-one chats", - "Contributing code to Matrix and Riot": "Contributing code to Matrix and Riot", "Unavailable": "Unavailable", - "Community-run support for Synapse": "Community-run support for Synapse", "View Decrypted Source": "View Decrypted Source", "Failed to update keywords": "Failed to update keywords", "remove %(name)s from the directory.": "remove %(name)s from the directory.", "Notifications on the following keywords follow rules which can’t be displayed here:": "Notifications on the following keywords follow rules which can’t be displayed here:", "Please set a password!": "Please set a password!", "You have successfully set a password!": "You have successfully set a password!", - "Chat with Riot Bot": "Chat with Riot Bot", - "Support for those using, running and writing other bridges": "Support for those using, running and writing other bridges", - "Admin support for Dendrite": "Admin support for Dendrite", "An error occurred whilst saving your email notification preferences.": "An error occurred while saving your email notification preferences.", "Source URL": "Source URL", "Failed to add tag %(tagName)s to room": "Failed to add tag %(tagName)s to room", "Members": "Members", "No update available.": "No update available.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!", "Resend": "Resend", "Files": "Files", "Collecting app version information": "Collecting app version information", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Delete the room alias %(alias)s and remove %(name)s from the directory?", - "customServer_text": "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.", - "Co-ordination for Riot/Web translators": "Co-ordination for Riot/Web translators", "This will allow you to return to your account after signing out, and sign in on other devices.": "This will allow you to return to your account after signing out, and sign in on other devices.", - "Dev chat for the Dendrite dev team": "Dev chat for the Dendrite dev team", "Keywords": "Keywords", "Unpin Message": "Unpin Message", "Enable notifications for this account": "Enable notifications for this account", @@ -806,15 +783,11 @@ "Direct Chat": "Direct Chat", "The server may be unavailable or overloaded": "The server may be unavailable or overloaded", "Reject": "Reject", - "Riot is not supported on mobile web. Install the app?": "Riot is not supported on mobile web. Install the app?", - "Discussion of all things Matrix!": "Discussion of all things Matrix!", "Failed to set Direct Message status of room": "Failed to set Direct Message status of room", "Monday": "Monday", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please uncheck:", "Remove from Directory": "Remove from Directory", "Enable them now": "Enable them now", "Messages containing my user name": "Messages containing my user name", - "Describe your problem here.": "Describe your problem here.", "Collecting logs": "Collecting logs", "more": "more", "Search for a room": "Search for a room", @@ -825,56 +798,38 @@ "Send": "Send", "Send logs": "Send logs", "All messages": "All messages", - "Implementing VoIP services with Matrix": "Implementing VoIP services with Matrix", - "Dev chat for the Riot/Web dev team": "Dev chat for the Riot/Web dev team", "Call invitation": "Call invitation", - "Riot Desktop on %(platformName)s": "Riot Desktop on %(platformName)s", "Downloading update...": "Downloading update...", "You have successfully set a password and an email address!": "You have successfully set a password and an email address!", "What's new?": "What's new?", - "Discussion of the Identity Service API": "Discussion of the Identity Service API", - "Support for those using and running matrix-appservice-irc": "Support for those using and running matrix-appservice-irc", - "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk chat", "Notify me for anything else": "Notify me for anything else", "When I'm invited to a room": "When I'm invited to a room", - "Design and implementation of E2E in Matrix": "Design and implementation of E2E in Matrix", "Can't update user notification settings": "Can't update user notification settings", "Notify for all other messages/rooms": "Notify for all other messages/rooms", "Unable to look up room ID from server": "Unable to look up room ID from server", "Couldn't find a matching Matrix room": "Couldn't find a matching Matrix room", - "Support for those using the Matrix spec": "Support for those using the Matrix spec", - "Safari and Opera work too.": "Safari and Opera work too.", - "Loading bug report module": "Loading bug report module", "Invite to this room": "Invite to this room", "You cannot delete this message. (%(code)s)": "You cannot delete this message. (%(code)s)", "Thursday": "Thursday", "Forward Message": "Forward Message", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s via %(browserName)s on %(osName)s", "Unhide Preview": "Unhide Preview", - "Announcements about Synapse releases": "Announcements about Synapse releases", - "Search the room directory": "Search the room directory", - "Please describe the bug and/or send logs.": "Please describe the bug and/or send logs.", "Unable to join network": "Unable to join network", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply", "Sorry, your browser is not able to run Riot.": "Sorry, your browser is not able to run Riot.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Decentralised, encrypted chat & collaboration powered by [matrix]", "Uploaded on %(date)s by %(user)s": "Uploaded on %(date)s by %(user)s", "Messages in group chats": "Messages in group chats", "Yesterday": "Yesterday", "Error encountered (%(errorDetail)s).": "Error encountered (%(errorDetail)s).", "Low Priority": "Low Priority", "Unable to fetch notification target list": "Unable to fetch notification target list", - "Get started with some tips from Riot Bot!": "Get started with some tips from Riot Bot!", "Set Password": "Set Password", "Enable audible notifications in web client": "Enable audible notifications in web client", "Permalink": "Permalink", - "Welcome to Riot.im": "Welcome to Riot.im", "Off": "Off", "Riot does not know how to join a room on this network": "Riot does not know how to join a room on this network", "Mentions only": "Mentions only", "Failed to remove tag %(tagName)s from room": "Failed to remove tag %(tagName)s from room", "You can now return to your account after signing out, and sign in on other devices.": "You can now return to your account after signing out, and sign in on other devices.", - "Please install Chrome or Firefox for the best experience.": "Please install Chrome or Firefox for the best experience.", "Enable email notifications": "Enable email notifications", "Login": "Login", "No rooms to show": "No rooms to show", @@ -882,11 +837,8 @@ "Pin Message": "Pin Message", "Failed to change settings": "Failed to change settings", "View Source": "View Source", - "Matrix technical discussions": "Matrix technical discussions", - "Building services on Matrix": "Building services on Matrix", "Collapse panel": "Collapse panel", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!", "Checking for an update...": "Checking for an update...", - "General discussion about Matrix and Riot": "General discussion about Matrix and Riot", "There are advanced notifications which are not shown here": "There are advanced notifications which are not shown here" } diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index 31c3bc57ad..fb852d39a9 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -307,8 +307,6 @@ "Hangup": "Fini vokon", "Voice call": "Voĉvoko", "Video call": "Vidvoko", - "Hide Apps": "Kaŝi aplikaĵojn", - "Show Apps": "Montri aplikaĵojn", "Upload file": "Alŝuti dosieron", "Show Text Formatting Toolbar": "Montri tekstaranĝan breton", "You do not have permission to post to this room": "Mankas al vi permeso afiŝi en la ĉambro", @@ -731,7 +729,6 @@ "Unable to reject invite": "Invito ne rifuzeblas", "Leave Community": "Forlasi komunumon", "Leave %(groupName)s?": "Ĉu foriri el %(groupName)s?", - "Unable to leave room": "Ĉambro ne forlaseblas", "Community Settings": "Komunumaj agordoj", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Tiuj ĉi ĉambroj montriĝas al komunumanoj sur la paĝo de la komunumo. Ili povas aliĝi al la ĉambroj per alklakoj.", "Featured Rooms:": "Elstarigitaj ĉambroj:", @@ -813,9 +810,6 @@ "Device ID:": "Aparata identigilo:", "Device key:": "Aparata ŝlosilo:", "Ignored Users": "Malatentataj uzantoj", - "Bug Report": "Cimraporto", - "Found a bug?": "Ĉu vi trovis cimon?", - "Report it": "Raporti ĝin", "Analytics": "Analizo", "Riot collects anonymous analytics to allow us to improve the application.": "Riot kolektas sennomaj analizajn datumojn por helpi plibonigadon de la programo.", "Labs": "Eksperimentaj funkcioj", @@ -966,8 +960,6 @@ "Failed to add tag %(tagName)s to room": "Malsukcesis aldoni etikedon %(tagName)s al ĉambro", "Fetching third party location failed": "Malsukcesis trovi lokon de ekstera liveranto", "A new version of Riot is available.": "Nova versio de Riot haveblas.", - "Riot/Android & matrix-android-sdk chat": "Babilado pri Riot ĉe Android kaj matrix-android-sdk", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Bonvolu priskribi la cimon. Kion vi faris? Kion vi atendis? Kio fakte okazis?", "I understand the risks and wish to continue": "Mi komprenas la riskojn kaj volas daŭrigi", "Couldn't load home page": "Malsukcesis enlegi hejmpaĝon", "Send Account Data": "Sendi kontajn informojn", @@ -978,12 +970,9 @@ "Failed to set direct chat tag": "Malsukcesis agordi la etikedon de rekta babilo", "Today": "Hodiaŭ", "Files": "Dosieroj", - "Report a bug": "Raporti cimon", - "Implementing VR services with Matrix": "Realigado de VR-servoj en Matrix", "You are not receiving desktop notifications": "Vi ne ricevadas sciigojn labortablajn", "Friday": "Vendredo", "Update": "Ĝisdatigi", - "You need to be using HTTPS to place a screen-sharing call.": "Vi devas uzi HTTPS por ekranvidadi.", "What's New": "Kio novas", "Add an email address above to configure email notifications": "Aldonu retadreson supre por agordi retpoŝtajn sciigojn", "Expand panel": "Etendi panelon", @@ -991,17 +980,13 @@ "%(count)s Members|other": "%(count)s Membroj", "Filter room names": "Filtri nomojn de ĉambroj", "Changelog": "Protokolo de ŝanĝoj", - "Running Matrix services": "Funkciigado de servoj de Matrix", "Waiting for response from server": "Atendante respondon el la servilo", "Send Custom Event": "Sendi propran okazon", - "Failed to send report: ": "Malsukcesis sendi raporton: ", - "Unknown device": "Nekonata aparato", "All notifications are currently disabled for all targets.": "Ĉiuj sciigoj nun estas malŝaltitaj por ĉiuj aparatoj.", "delete the alias.": "forigi la kromnomon.", "To return to your account in future you need to set a password": "Por reveni al via konto estonte, vi devas agordi pasvorton", "Forget": "Forgesi", "#example": "#ekzemplo", - "Riot/Web & Desktop chat": "Babilado pri Riot ĉe reto kaj labortablo", "Hide panel": "Kaŝi panelon", "You cannot delete this image. (%(code)s)": "Vi ne povas forigi tiun ĉi bildon. (%(code)s)", "Cancel Sending": "Nuligi sendon", @@ -1011,9 +996,7 @@ "Room not found": "Ĉambro ne troviĝis", "Messages containing my display name": "Mesaĝoj enhavantaj mian vidigan nomon", "Messages in one-to-one chats": "Mesaĝoj en duopaj babiloj", - "Contributing code to Matrix and Riot": "Kontribuado de kodo al Matrix kaj Riot", "Unavailable": "Nedisponebla", - "Community-run support for Synapse": "Komunuma subtenado de Synapse", "View Decrypted Source": "Vidi malĉifritan fonton", "Failed to update keywords": "Malsukcesis ĝisdatigi la ŝlosilvortojn", "remove %(name)s from the directory.": "forigi %(name)s de la ujo.", @@ -1021,9 +1004,6 @@ "Safari and Opera work too.": "Ankaŭ Safario kaj Opero funkcias.", "Please set a password!": "Bonvolu agordi pasvorton!", "You have successfully set a password!": "Vi sukcese agordis pasvorton!", - "Chat with Riot Bot": "Babilu kun la roboto Riot Bot", - "Support for those using, running and writing other bridges": "Subteno por tiuj, kiuj uzas, funkciigas, aŭ evoluigas aliajn pontojn", - "Admin support for Dendrite": "Administra subtenado por Dendrite", "An error occurred whilst saving your email notification preferences.": "Eraro okazis dum konservado de agordoj pri retpoŝtaj sciigoj.", "Explore Room State": "Esplori staton de ĉambro", "Source URL": "Fonta URL", @@ -1031,16 +1011,11 @@ "Filter results": "Filtri rezultojn", "Members": "Anoj", "No update available.": "Neniuj ĝisdatigoj haveblas.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Multaj ĉambroj jam ekzistas en Matrix; kaj sendependaj, kaj ligitaj kun jamaj retoj (Slock, IRC, Gitter, ktp.). Rigardu la ĉambrujon!", "Resend": "Resendi", "Failed to get protocol list from Home Server": "Malsukcesis akiri liston de protokoloj el la hejmservilo", "Collecting app version information": "Kolektanta informon pri versio de la aplikaĵo", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Ĉu forigi la ĉambran kromnomon %(alias)s kaj forigi %(name)s de la ujo?", - "customServer_text": "Vi povas uzi opciojn personigitajn de la servilo por ensaluti en aliajn servilojn Matrix specifante alian adreson URL-an de alia servilo Home.
    Tio permesas al vi uzi Riot per ekzistanta konto en alia Home servilo.

    Vi povas ankaŭ agordi servilon identecan personigita, sed ne eblos inviti uzantojn pere de retpoŝtadreso, aŭ esti invitita pere de retpoŝtadreso vi mem.", - "Co-ordination for Riot/Web translators": "Kunordigado por tradukistoj de Riot ĉe reto", "This will allow you to return to your account after signing out, and sign in on other devices.": "Tio ĉi permesos al vi reveni al via konto post adiaŭo, kaj saluti kun alia aparato.", - "Dev chat for the Dendrite dev team": "Babilado por la programista skipo de Dendrite", - "Design and implementation of E2E in Matrix": "Fasonado kaj realigado de ĝiscela ĉifrado en Matrix", "Enable notifications for this account": "Ŝalti sciigojn por tiu ĉi konto", "Directory": "Dosierujo", "Invite to this community": "Inviti al tiu ĉi komunumo", @@ -1054,7 +1029,6 @@ "Remove %(name)s from the directory?": "Ĉu forigi %(name)s de la ujo?", "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot uzas multajn specialajn funkciojn, el kiuj kelkaj ne disponeblas aŭ estas eksperimentaj en via nuna foliumilo.", "Event sent!": "Okazo sendiĝis!", - "Please install Chrome or Firefox for the best experience.": "Bonvolu instali \"Chrome\"\"Firefox\" por la plej bona sperto.", "Explore Account Data": "Esplori kontajn datumojn", "All messages (noisy)": "Ĉiuj mesaĝoj (lauta)", "Away": "Foresta", @@ -1063,15 +1037,11 @@ "Direct Chat": "Rekta babilo", "The server may be unavailable or overloaded": "La servilo povas esti nedisponebla aŭ troŝarĝita", "Reject": "Rifuzi", - "Riot is not supported on mobile web. Install the app?": "Riot ne estas subtenata sur poŝkomputila reto. Ĉu instali la aplikaĵon?", - "Discussion of all things Matrix!": "Diskutado pri ĉio rilata al Matrix!", "Failed to set Direct Message status of room": "Malsukcesis agordi staton de rekta mesaĝo al la ĉambro", "Monday": "Lundo", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Por diagnozi problemojn, protokoloj el tiu ĉi kliento sendiĝos kune kun tiu ĉi raporto de eraro. Se vi preferas sendi nur la supran tekston, bonvolu malŝalti:", "Remove from Directory": "Forigi de ujo", "Enable them now": "Ŝalti ilin nun", "Messages containing my user name": "Mesaĝoj enhavantaj mian salutnomon", - "Describe your problem here.": "Priskribu vian problemon ĉi tie.", "Toolbox": "Ilaro", "Collecting logs": "Kolektante protokolon", "more": "pli", @@ -1085,45 +1055,30 @@ "Quote": "Citi", "Send logs": "Sendi protokolojn", "All messages": "Ĉiuj mesaĝoj", - "Implementing VoIP services with Matrix": "Realigado de VoIP-servoj en Matrix", - "Dev chat for the Riot/Web dev team": "Babilado por la programista skipo de Riot ĉe reto", "Call invitation": "Invito al voko", - "Riot Desktop on %(platformName)s": "Riot Labortablo sur %(platformName)s", "Downloading update...": "Elŝutanta ĝisdatigon…", "State Key": "Stata ŝlosilo", "Failed to send custom event.": "Malsukcesis sendi propran okazon.", "What's new?": "Kio novas?", - "Discussion of the Identity Service API": "Diskutado pri API de la identiga servo", - "Support for those using and running matrix-appservice-irc": "Subteno por tiuj, kiuj uzas kaj funkciigas matrix-appservice-irc", - "Riot/iOS & matrix-ios-sdk chat": "Babilado pri Riot ĉe iOS kaj matrix-ios-sdk", "Notify me for anything else": "Sciigu min pri ĉio alia", "When I'm invited to a room": "Kiam mi estas invitita al ĉambro", "Keywords": "Ŝlosilvortoj", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Vi povas uzi proprajn servilajn elektojn por saluti aliajn servilojn de Matrix, per specifo de alia hejmservila URL.
    Tio permesas al vi uzi klienton Riot kun jama konto de Matrix en alia hejmservilo.

    Vi ankaŭ povas agordi propran identigan servilon, sed vi ne povos inviti uzantojn per retpoŝtadreso, aŭ esti invitata per retpoŝtadreso mem.", "Can't update user notification settings": "Agordoj de sciigoj al uzanto ne ĝisdatigeblas", "Notify for all other messages/rooms": "Sciigu min por ĉiu alia babilejo", "Unable to look up room ID from server": "Ĉambra identigaĵo ne akireblas de la servilo", "Couldn't find a matching Matrix room": "Malsukcesis trovi kongruan ĉambron en Matrix", - "Support for those using the Matrix spec": "Subteno por tiuj, kiuj uzas la specifaĵon de Matrix", - "Safari and Opera work too.": "Safari kaj Opera ankaŭ funkcias.", - "Loading bug report module": "Enleganta cimraportan modulon", "All Rooms": "Ĉiuj babilejoj", "Search for a room": "Serĉi ĉambron", "Thursday": "Ĵaŭdo", "Forward Message": "Plusendi mesaĝon", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s per %(browserName)s je %(osName)s", "Back": "Reen", "Failed to change settings": "Malsukcesis ŝanĝi la agordojn", "Reply": "Respondi", "Show message in desktop notification": "Montradi mesaĝojn en labortablaj sciigoj", "Unhide Preview": "Malkaŝi antaŭrigardon", - "Announcements about Synapse releases": "Anoncoj pri eldonoj de Synapse", - "Search the room directory": "Serĉi en la ĉambrujo", - "Please describe the bug and/or send logs.": "Bonvolu priskribi la cimon kaj/aŭ sendi protokolojn.", "Unable to join network": "Malsukcesis konektiĝi al la reto", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Vi eble agordis ilin en alia kliento. Vi ne povas agordi ilin en Riot, sed ili ankoraŭ validas", "Sorry, your browser is not able to run Riot.": "Pardonu, via foliumilo ne kapablas funkciigi klienton Riot.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Malcentra, ĉifrita babilado & kunlaboro povigita de [matrix]", "Uploaded on %(date)s by %(user)s": "Alŝutita je %(date)s de %(user)s", "Messages in group chats": "Mesaĝoj en grupaj babiloj", "Yesterday": "Hieraŭ", @@ -1132,11 +1087,9 @@ "Low Priority": "Malalta prioritato", "Unable to fetch notification target list": "Malsukcesis akiri la liston de celoj por sciigoj", "Appear Offline": "Montriĝi kiel eksterreta", - "Get started with some tips from Riot Bot!": "Komencu kun kelkaj sugestoj de la roboto Riot Bot!", "Set Password": "Agordi pasvorton", "Enable audible notifications in web client": "Ŝalti aŭdeblajn sciigojn en la retkliento", "Permalink": "Konstanta ligilo", - "Welcome to Riot.im": "Bonvenu al Riot.im", "Off": "For", "Riot does not know how to join a room on this network": "Riot ne scias aliĝi al ĉambroj en tiu ĉi reto", "Mentions only": "Nur mencioj", @@ -1152,12 +1105,9 @@ "%(count)s Members|one": "%(count)s Membro", "Developer Tools": "Evoluigiloj", "View Source": "Vidi fonton", - "Matrix technical discussions": "Teĥnikaj diskutoj pri Matrix", "Event Content": "Enhavo de okazo", - "Building services on Matrix": "Konstruado de servoj sur Matrix", "Collapse panel": "Maletendi panelon", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Kun via nuna foliumilo, la aspekto kaj funkciado de la aplikaĵo povas esti tute malĝusta, kaj kelkaj aŭ ĉiu funkcioj eble ne tute funkcios. Se vi tamen volas provi, vi povas daŭrigi, sed vi ricevos nenian subtenon se vi renkontos problemojn!", "Checking for an update...": "Serĉanta ĝisdatigojn…", - "General discussion about Matrix and Riot": "Ĝenerala diskutado pri Matrix kaj Riot", "There are advanced notifications which are not shown here": "Ekzistas specialaj sciigoj, kiuj ne montriĝas ĉi tie" } diff --git a/src/i18n/strings/es.json b/src/i18n/strings/es.json index 0e03b0ecf3..36bf4b7b3b 100644 --- a/src/i18n/strings/es.json +++ b/src/i18n/strings/es.json @@ -29,7 +29,6 @@ "Banned users": "Usuarios bloqueados", "Bans user with given id": "Bloquear usuario por ID", "Blacklisted": "En lista negra", - "Bug Report": "Reporte de fallo", "Bulk Options": "Opciones masivas", "Call Timeout": "Tiempo de espera de la llamada", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "No se puede conectar al servidor via HTTP, cuando es necesario un enlace HTTPS en la barra de direcciones de tu navegador. Ya sea usando HTTPS o habilitando los scripts inseguros.", @@ -132,7 +131,6 @@ "Forgot your password?": "¿Olvidaste tu clave?", "For security, this session has been signed out. Please sign in again.": "Por seguridad, esta sesión ha sido cerrada. Por favor inicia sesión nuevamente.", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Por seguridad, al cerrar la sesión borrará cualquier clave de encriptación de extremo a extremo en este navegador. Si quieres ser capaz de descifrar tu historial de conversación, para las futuras sesiones en Riot, por favor exporta las claves de la sala para protegerlas.", - "Found a bug?": "¿Encontraste un error?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s de %(fromPowerLevel)s a %(toPowerLevel)s", "Guests cannot join this room even if explicitly invited.": "Invitados no pueden unirse a esta sala aun cuando han sido invitados explícitamente.", "Hangup": "Colgar", @@ -376,7 +374,6 @@ "Remove": "Eliminar", "Remove %(threePid)s?": "¿Eliminar %(threePid)s?", "%(senderName)s requested a VoIP conference.": "%(senderName)s ha solicitado una conferencia Voz-IP.", - "Report it": "Informar", "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.": "Reiniciar la contraseña también reiniciará las claves de cifrado extremo-a-extremo, haciendo ilegible el historial de las conversaciones, salvo que exporte previamente las claves de sala, y las importe posteriormente. Esto será mejorado en futuras versiones.", "Results from DuckDuckGo": "Resultados desde DuckDuckGo", "Return to login screen": "Volver a la pantalla de inicio de sesión", @@ -430,10 +427,8 @@ "Define the power level of a user": "Definir el nivel de poder de los usuarios", "Edit": "Editar", "Enable automatic language detection for syntax highlighting": "Activar la detección automática del lenguaje para resaltar la sintaxis", - "Hide Apps": "Ocultar aplicaciones", "Hide join/leave messages (invites/kicks/bans unaffected)": "Ocultar mensajes de entrada/salida (no afecta invitaciones/kicks/bans)", "Sets the room topic": "Configura el tema de la sala", - "Show Apps": "Mostrar aplicaciones", "To get started, please pick a username!": "Para empezar, ¡por favor elija un nombre de usuario!", "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Se ha intentado cargar cierto punto en la cronología de esta sala, pero no tiene permiso para ver el mensaje solicitado.", "Tried to load a specific point in this room's timeline, but was unable to find it.": "Se ha intentado cargar cierto punto en la cronología de esta sala, pero no se ha podido encontrarlo.", @@ -590,8 +585,6 @@ "Which rooms would you like to add to this community?": "¿Qué salas deseas añadir a esta comunidad?", "Fetching third party location failed": "Falló la obtención de la ubicación de un tercero", "A new version of Riot is available.": "Una nueva versión de Riot está disponible.", - "Riot/Android & matrix-android-sdk chat": "Conversaciones sobre Riot/Android & matrix-android-sdk", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Por favor describa el error. ¿Qué acción ejecutó? ¿Cuál era el resultado que esperaba? ¿Que pasó realmente?", "I understand the risks and wish to continue": "Entiendo los riesgos y deseo continuar", "Couldn't load home page": "No se puede cargar la página principal", "Send Account Data": "Enviar Datos de la Cuenta", @@ -604,12 +597,9 @@ "Failed to set direct chat tag": "Error al establecer la etiqueta de chat directo", "Today": "Hoy", "Files": "Archivos", - "Report a bug": "Informar de un fallo", - "Implementing VR services with Matrix": "Implementación de servicios VR con Matrix", "You are not receiving desktop notifications": "No estás recibiendo notificaciones de escritorio", "Friday": "Viernes", "Update": "Actualizar", - "You need to be using HTTPS to place a screen-sharing call.": "Debes usar HTTPS para hacer una llamada con pantalla compartida.", "What's New": "Novedades", "Add an email address above to configure email notifications": "Añade una dirección de correo arriba para configurar las notificaciones por correo", "Expand panel": "Expandir panel", @@ -617,20 +607,16 @@ "%(count)s Members|other": "%(count)s miembros", "Filter room names": "Filtrar los nombres de las salas", "Changelog": "Registro de cambios", - "Running Matrix services": "Ejecutando servicios de Matrix", "Waiting for response from server": "Esperando una respuesta del servidor", "Leave": "Salir", "Uploaded on %(date)s by %(user)s": "Subido el %(date)s por %(user)s", "Send Custom Event": "Enviar Evento Personalizado", - "Failed to send report: ": "Error al enviar informe: ", - "Unknown device": "Dispositivo desconocido", "All notifications are currently disabled for all targets.": "Las notificaciones estan desactivadas para todos los objetivos.", "Failed to send logs: ": "Error al enviar registros: ", "delete the alias.": "borrar el alias.", "To return to your account in future you need to set a password": "Para regresar a tu cuenta en el futuro debes establecer una contraseña", "Forget": "Olvidar", "World readable": "Legible por todo el mundo", - "Riot/Web & Desktop chat": "Conversaciones de Riot/Web & Desktop", "Hide panel": "Ocultar panel", "You cannot delete this image. (%(code)s)": "No puedes eliminar esta imagen. (%(code)s)", "Cancel Sending": "Cancelar envío", @@ -640,9 +626,7 @@ "Room not found": "Sala no encontrada", "Messages containing my display name": "Mensajes que contienen mi nombre", "Messages in one-to-one chats": "Mensajes en chats uno a uno", - "Contributing code to Matrix and Riot": "Contribuciones de código para Matrix y Riot", "Unavailable": "No disponible", - "Community-run support for Synapse": "Soporte comunitario de Synapse", "View Decrypted Source": "Ver Fuente Descifrada", "Failed to update keywords": "Error al actualizar las palabras clave", "Notes:": "Notas:", @@ -651,9 +635,6 @@ "Safari and Opera work too.": "Safari y Opera también funcionan.", "Please set a password!": "¡Por favor establece una contraseña!", "You have successfully set a password!": "¡Has establecido una nueva contraseña!", - "Chat with Riot Bot": "Conversar con el Bot de Riot", - "Support for those using, running and writing other bridges": "Soporte para usuarios, administradores y desarrolladores de otros puentes", - "Admin support for Dendrite": "Soporte administrativo para Dendrite", "An error occurred whilst saving your email notification preferences.": "Se ha producido un error al guardar las preferencias de notificación por email.", "Explore Room State": "Explorar Estado de la Sala", "Source URL": "URL de Origen", @@ -661,15 +642,11 @@ "Filter results": "Filtrar resultados", "Members": "Miembros", "No update available.": "No hay actualizaciones disponibles.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Muchas salas ya están disponibles en Matrix, enlazadas a redes existentes (Slack, IRC, Gitter, etc) o independientes. ¡Revisa el directorio!", "Noisy": "Ruidoso", "Failed to get protocol list from Home Server": "Error al obtener la lista de protocolos desde el Home Server", "Collecting app version information": "Recolectando información de la versión de la aplicación", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "¿Borrar el alias de la sala %(alias)s y eliminar %(name)s del directorio?", - "customServer_text": "Puedes utilizar las opciones de servidor personalizadas para iniciar sesión en otros servidores Matrix especificando una URL de Home server distinta.
    Esto te permite usar Riot con una cuenta Matrix existente en un Home server distinto.

    También puedes configurar un servidor de identidad personalizado, pero no podrás ni invitar usuarios ni ser invitado a través de tu dirección de correo electrónico.", - "Co-ordination for Riot/Web translators": "Coordinación para traductores de Riot/Web", "This will allow you to return to your account after signing out, and sign in on other devices.": "Esto te permitirá regresar a tu cuenta después de cerrar sesión, así como iniciar sesión en otros dispositivos.", - "Dev chat for the Dendrite dev team": "Conversaciones del equipo de desarrollo de Dendrite", "Keywords": "Palabras clave", "Enable notifications for this account": "Habilitar notificaciones para esta cuenta", "Directory": "Directorio", @@ -695,15 +672,11 @@ "Direct Chat": "Conversación directa", "The server may be unavailable or overloaded": "El servidor puede estar no disponible o sobrecargado", "Reject": "Rechazar", - "Riot is not supported on mobile web. Install the app?": "Riot no está soportado en navegadores Web móviles. ¿Quieres instalar la aplicación?", - "Discussion of all things Matrix!": "¡Discusión sobre todas las cosas de Matrix!", "Failed to set Direct Message status of room": "No se pudo establecer el estado de Mensaje Directo de la sala", "Monday": "Lunes", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Para diagnosticar los problemas, los registros de este cliente serán enviados adjuntos a este informe de fallo. Si quisieras enviar el texto anterior solamente, entonces desmarca:", "All messages (noisy)": "Todos los mensajes (ruidoso)", "Enable them now": "Habilitarlos ahora", "Messages containing my user name": "Mensajes que contienen mi nombre de usuario", - "Describe your problem here.": "Describe el problema aquí.", "Toolbox": "Caja de Herramientas", "Collecting logs": "Recolectando registros", "more": "más", @@ -717,49 +690,32 @@ "Send": "Enviar", "Send logs": "Enviar registros", "All messages": "Todos los mensajes", - "Implementing VoIP services with Matrix": "Implementación de servicios VoIP con Matrix", - "Dev chat for the Riot/Web dev team": "Conversaciones del equipo de desarrollo de Riot/Web", "Call invitation": "Invitación a la llamada", "Thank you!": "¡Gracias!", - "Riot Desktop on %(platformName)s": "Riot Desktop en %(platformName)s", "Downloading update...": "Descargando actualizaciones...", "State Key": "Clave de estado", "Failed to send custom event.": "Ha fallado el envio del evento personalizado.", "What's new?": "¿Qué hay de nuevo?", - "Discussion of the Identity Service API": "Discusión sobre el API de Identity Service", - "Support for those using and running matrix-appservice-irc": "Soporte para aquellos que usan o administran matrix-appservice-irc", - "Riot/iOS & matrix-ios-sdk chat": "Conversaciones sobre Riot/iOS & matrix-ios-sdk", "Notify me for anything else": "Notificarme para cualquier otra cosa", "When I'm invited to a room": "Cuando estoy invitado a una sala", - "Design and implementation of E2E in Matrix": "Diseño e implementación de E2E en Matrix", "Click here to create a GitHub issue.": "Haz click aquí para crear una incidencia en Github.", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Puedes usar las opciones del servidor personalizado para acceder a otros servidores Matrix especificando su URL.
    Esto te permite usar Riot con una cuenta Matrix existente en un servidor doméstico distinto.

    También puedes establecer un servidor de identidad personalizado pero no podrás invitar a otros usuarios usando su dirección de correo electrónico, y tampoco ser invitado por el tuyo.", "Can't update user notification settings": "No se puede actualizar la configuración de notificaciones del usuario", "Notify for all other messages/rooms": "Notificar para todos los demás mensajes/salas", "Unable to look up room ID from server": "No se puede buscar el ID de la sala desde el servidor", "Couldn't find a matching Matrix room": "No se encontró una sala Matrix que coincida", - "Support for those using the Matrix spec": "Soporte para usuarios de la especificación de Matrix", - "Safari and Opera work too.": "Safari y Opera también funcionan.", - "Loading bug report module": "Cargando módulo de reporte de errores", "All Rooms": "Todas las salas", "You cannot delete this message. (%(code)s)": "No puedes eliminar este mensaje. (%(code)s)", "Thursday": "Jueves", "Forward Message": "Reenviar mensaje", "Logs sent": "Registros enviados", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s via %(browserName)s en %(osName)s", "Back": "Atrás", "Reply": "Responder", "Show message in desktop notification": "Mostrar mensaje en la notificación del escritorio", "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Los registros de depuración contienen datos de uso de la aplicación como nombre de usuario, ID o alias de las salas o grupos que hayas visitado (y nombres de usuario de otros usuarios). No contienen mensajes.", "Unhide Preview": "Mostrar Vista Previa", - "Announcements about Synapse releases": "Anuncios de lanzamientos de Synapse", - "Search the room directory": "Buscar en el directorio de salas", - "Please describe the bug and/or send logs.": "Por favor describe el error y/o envía los registros.", "Unable to join network": "No se puede unir a la red", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Es posible que los hayas configurado en un cliente que no sea Riot. No puedes ajustarlos en Riot, pero todavía se aplican", "Sorry, your browser is not able to run Riot.": "¡Lo sentimos! Su navegador no puede ejecutar Riot.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Conversaciones cifradas y descentralizadas & colaboración con el poder de [matrix]", - "Building services on Matrix": "Construyendo servicios con Matrix", "Messages in group chats": "Mensajes en chats de grupo", "Yesterday": "Ayer", "Error encountered (%(errorDetail)s).": "Error encontrado (%(errorDetail)s).", @@ -767,18 +723,15 @@ "Low Priority": "Baja Prioridad", "Riot does not know how to join a room on this network": "Riot no sabe cómo unirse a una sala en esta red", "Appear Offline": "Mostrarse Desconectado", - "Get started with some tips from Riot Bot!": "¡Comenzar con algunos consejos de Riot Bot!", "Set Password": "Establecer contraseña", "Enable audible notifications in web client": "Habilitar notificaciones audibles en el cliente web", "Permalink": "Enlace permanente", - "Welcome to Riot.im": "Bienvenido a Riot.im", "Off": "Apagado", "#example": "#ejemplo", "Mentions only": "Sólo menciones", "Failed to remove tag %(tagName)s from room": "Error al eliminar la etiqueta %(tagName)s de la sala", "Wednesday": "Miércoles", "You can now return to your account after signing out, and sign in on other devices.": "Ahora puedes regresar a tu cuenta después de cerrar tu sesión, e iniciar sesión en otros dispositivos.", - "Please install Chrome or Firefox for the best experience.": "Por favor instale Google Chrome o Mozilla Firefox para una mejor experiencia.", "Enable email notifications": "Habilitar notificaciones por email", "Event Type": "Tipo de Evento", "No rooms to show": "Sin salas para mostrar", @@ -789,13 +742,11 @@ "%(count)s Members|one": "%(count)s miembro", "Developer Tools": "Herramientas de Desarrollo", "View Source": "Ver Fuente", - "Matrix technical discussions": "Discusiones técnicas sobre Matrix", "Event Content": "Contenido del Evento", "Unable to fetch notification target list": "No se puede obtener la lista de objetivos de notificación", "Quote": "Citar", "Collapse panel": "Colapsar panel", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "En su navegador actual, la apariencia y comportamiento de la aplicación puede ser completamente incorrecta, y algunas de las características podrían no funcionar. Si aún desea probarlo puede continuar, pero ¡no podremos ofrecer soporte por cualquier problema que pudiese tener!", "Checking for an update...": "Comprobando actualizaciones...", - "General discussion about Matrix and Riot": "Discusión general sobre Matrix y Riot", "There are advanced notifications which are not shown here": "Hay notificaciones avanzadas que no se muestran aquí" } diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index 2c02b2f313..1555cf9693 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -36,7 +36,6 @@ "Invites": "Gonbidapenak", "Low priority": "Lehentasun baxua", "No results": "Emaitzarik ez", - "Bug Report": "Arazte-txostena", "Join Room": "Elkartu gelara", "Register": "Eman izena", "Submit": "Bidali", @@ -135,7 +134,6 @@ "Start Chat": "Hasi txata", "Success": "Arrakasta", "For security, this session has been signed out. Please sign in again.": "Segurtasunagatik saio hau amaitu da. Hasi saioa berriro.", - "Found a bug?": "Akats bat aurkitu duzu?", "Guests cannot join this room even if explicitly invited.": "Bisitariak ezin dira gela honetara elkartu ez bazaie zuzenean gonbidatu.", "Hangup": "Eseki", "Homeserver is": "Hasiera zerbitzaria:", @@ -357,7 +355,6 @@ "%(senderName)s removed their profile picture.": "%(senderName)s erabiltzaileak bere profileko argazkia kendu du.", "Remove %(threePid)s?": "Kendu %(threePid)s?", "%(senderName)s requested a VoIP conference.": "%(senderName)s erabiltzaileak VoIP konferentzia bat eskatu du.", - "Report it": "Eman berri", "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.": "Oraingoz pasahitza aldatzeak gailu guztietako muturretik muturrerako zifratze-gakoak berrezarriko ditu, eta ezin izango dituzu zifratutako txatetako historialak irakurri ez badituzu aurretik zure gelako gakoak esportatzen eta aldaketa eta gero berriro inportatzen.", "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Une honetan egiaztatu gabeko gailuak blokeatzen ari zara, gailu hauetara mezuak bidali ahal izateko egiaztatu behar dituzu.", "Results from DuckDuckGo": "DuckDuckGo bilatzaileko emaitzak", @@ -652,7 +649,6 @@ "Do you want to load widget from URL:": "Trepeta bat kargatu nahi duzu URL honetatik:", "Edit": "Editatu", "Enable automatic language detection for syntax highlighting": "Gaitu hizkuntza antzemate automatikoa sintaxia nabarmentzeko", - "Hide Apps": "Ezkutatu aplikazioak", "Hide join/leave messages (invites/kicks/bans unaffected)": "Ezkutatu elkartze/ateratze mezuak (gonbidapenak/kanporatzeak/debekuak ez dira aldatzen)", "Integrations Error": "Integrazio errorea", "Publish this room to the public in %(domain)s's room directory?": "Argitaratu gela hau publikora %(domain)s domeinuko gelen direktorioan?", @@ -661,7 +657,6 @@ "NOTE: Apps are not end-to-end encrypted": "OHARRA: Aplikazioek ez dute muturretik muturrerako zifratzea", "Revoke widget access": "Indargabetu trepetaren sarbidea", "Sets the room topic": "Gelaren mintzagaia ezartzen du", - "Show Apps": "Erakutsi aplikazioak", "The maximum permitted number of widgets have already been added to this room.": "Gehienez onartzen diren trepeta kopurua gehitu da gela honetara.", "To get started, please pick a username!": "Hasteko, hautatu erabiltzaile-izen bat!", "Unable to create widget.": "Ezin izan da trepeta sortu.", @@ -812,7 +807,6 @@ "Leave Community": "Atera komunitatetik", "Leave %(groupName)s?": "Atera %(groupName)s komunitatetik?", "Leave": "Atera", - "Unable to leave room": "Ezin izan da gelatik atera", "Community Settings": "Komunitatearen ezarpenak", "You are an administrator of this community": "Komunitate honen administratzailea zara", "You are a member of this community": "Komunitate honetako kidea zara", @@ -992,7 +986,6 @@ "Key request sent.": "Gako eskaria bidalita.", "Re-request encryption keys from your other devices.": "Berriz eskatu zifratze-gakoak zure beste gailuetatik.", "%(user)s is a %(userRole)s": "%(user)s %(userRole)s da", - "Changes made to your community might not be seen by other users for up to 30 minutes.": "Zure komunitateari egindako aldaketak agian ez dira beste erabiltzaileentzat ikusgai egongo 30 minutu pasatu arte.", "Code": "Kodea", "Debug Logs Submission": "Arazte-egunkarien bidalketak", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Akats bat bidali baduzu GitHub bidez, arazte-egunkariek arazoa aurkitzen lagundu gaitzakete. Arazte-egunkariek aplikazioak darabilen datuak dauzkate, zure erabiltzaile izena barne, bisitatu dituzun gelen ID-ak edo ezizenak eta beste erabiltzaileen izenak. Ez dute mezurik.", @@ -1006,8 +999,6 @@ "Leave this community": "Atera komunitate honetatik", "Fetching third party location failed": "Huts egin du hirugarrengoen kokalekua eskuratzean", "A new version of Riot is available.": "Riot bertsio berri bat dago eskuragarri.", - "Riot/Android & matrix-android-sdk chat": "Riot/Android eta matrix-android-sdk txata", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Deskribatu akatsa. Zer egin duzu? Zer gertatuko zela uste zenuen? Zer gertatu da?", "Couldn't load home page": "Ezin izan da hasiera orria kargatu", "Send Account Data": "Bidali kontuaren datuak", "All notifications are currently disabled for all targets.": "Une honetan jakinarazpen guztiak helburu guztietarako desgaituta daude.", @@ -1016,12 +1007,9 @@ "Notification targets": "Jakinarazpenen helburuak", "Today": "Gaur", "Failed to get protocol list from Home Server": "Huts egin du protokoloen zerrenda hasiera zerbitzaritik jasotzean", - "Report a bug": "Eman akats baten berri", - "Implementing VR services with Matrix": "VR zerbitzuak inplementatzea Matrix erabilita", "You are not receiving desktop notifications": "Ez dituzu mahaigaineko jakinarazpenak jasotzen", "Friday": "Ostirala", "Update": "Eguneratu", - "You need to be using HTTPS to place a screen-sharing call.": "HTTPS erabili behar duzu sekretuak partekatzeko dei bat ezartzeko.", "What's New": "Zer dago berri", "Add an email address above to configure email notifications": "Gehitu e-mail helbide bat goian e-mail bidezko jakinarazpenak konfiguratzeko", "Expand panel": "Hedatu panela", @@ -1029,18 +1017,14 @@ "%(count)s Members|other": "%(count)s kide", "Filter room names": "Iragazi gelen izenak", "Changelog": "Aldaketa-egunkaria", - "Running Matrix services": "Matrix zerbitzuak exekutatzea", "Waiting for response from server": "Zerbitzariaren erantzunaren zain", "Send Custom Event": "Bidali gertaera pertsonalizatua", - "Failed to send report: ": "Huts egin du txostena bidaltzean: ", - "Unknown device": "Gailu ezezaguna", "Advanced notification settings": "Jakinarazpen aurreratuen ezarpenak", "Failed to send logs: ": "Huts egin du egunkariak bidaltzean: ", "delete the alias.": "ezabatu ezizena.", "To return to your account in future you need to set a password": "Etorkizunean kontura itzuli ahal izateko pasahitz bat ezarri behar duzu", "Forget": "Ahaztu", "#example": "#adibidea", - "Riot/Web & Desktop chat": "Riot/Web eta mahaigaineko txata", "Hide panel": "Ezkutatu panela", "You cannot delete this image. (%(code)s)": "Ezin duzu irudi hau ezabatu. (%(code)s)", "Cancel Sending": "Utzi bidaltzeari", @@ -1050,9 +1034,7 @@ "Error saving email notification preferences": "Errorea e-mail jakinarazpenen hobespenak gordetzean", "Messages containing my display name": "Nire pantaila-izena duten mezuak", "Messages in one-to-one chats": "Biren arteko txatetako mezuak", - "Contributing code to Matrix and Riot": "Kodearekin lagundu Matrix eta Riot", "Unavailable": "Eskuraezina", - "Community-run support for Synapse": "Synapse-rako laguntza komunitatea", "View Decrypted Source": "Ikusi deszifratutako iturria", "Failed to update keywords": "Huts egin du hitz gakoak eguneratzean", "Notes:": "Oharrak:", @@ -1061,9 +1043,6 @@ "Safari and Opera work too.": "Safari eta Opera badabiltza ere.", "Please set a password!": "Ezarri pasahitza mesedez!", "You have successfully set a password!": "Ongi ezarri duzu pasahitza!", - "Chat with Riot Bot": "Txateatu Riot botarekin", - "Support for those using, running and writing other bridges": "Bestelako zubiak erabili, exekutatu eta idazten dituztenentzako laguntza", - "Admin support for Dendrite": "Dendrite kudeatzaileentzako laguntza", "An error occurred whilst saving your email notification preferences.": "Errore bat gertatu da zure e-mail bidezko jakinarazpenen hobespenak gordetzean.", "Explore Room State": "Miatu gelaren egoera", "Source URL": "Iturriaren URLa", @@ -1071,15 +1050,11 @@ "Filter results": "Iragazi emaitzak", "Members": "Kideak", "No update available.": "Ez dago eguneraketarik eskuragarri.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Badauden sareetara lotutako gela ugari daude Matrixen (Slack, IRC, Gitter eta abar), baita independienteak. Begiratu direktorioa!", "Resend": "Birbidali", "Files": "Fitxategiak", "Collecting app version information": "Aplikazioaren bertsio-informazioa biltzen", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Ezabatu gelaren %(alias)s ezizena eta kendu %(name)s direktoriotik?", - "customServer_text": "Zerbitzari pertsonalizatuaren aukerak erabili ditzakezu beste hasiera zerbitzari baten URLa jarrita beste Matrix zerbitzarietan saioa hasteko.
    Honek oraingo Matrix kontuarekin Riot beste hasiera zerbitzari batean erabiltzea ahalbidetzen dizu.

    Identitate zerbitzari pertsonalizatu bat jar dezakezu ere baina ezin izango dituzu erabiltzaileak bere e-mail helbidea erabilita gonbidatu, edo besteek zu gonbidatu zure e-mail helbidea erabilita.", - "Co-ordination for Riot/Web translators": "Riot/Web itzultzaileen arteko koordinazioa", "This will allow you to return to your account after signing out, and sign in on other devices.": "Honek zure kontura itzultzea ahalbidetuko dizu, beste gailuetan saioa amaitu eta berriro hasi eta gero.", - "Dev chat for the Dendrite dev team": "Dendrite garapen taldearen txata", "Keywords": "Hitz gakoak", "Enable notifications for this account": "Gaitu jakinarazpenak kontu honetarako", "Directory": "Direktorioa", @@ -1105,15 +1080,11 @@ "Direct Chat": "Txat zuzena", "The server may be unavailable or overloaded": "Zerbitzaria eskuraezin edo gainezka egon daiteke", "Reject": "Baztertu", - "Riot is not supported on mobile web. Install the app?": "Riotek ez du euskarririk mugikorrentzako webean. Instalatu aplikazioa?", - "Discussion of all things Matrix!": "Matrix-ekin zerikusia duen guztiari buruzko eztabaida!", "Failed to set Direct Message status of room": "Huts egin du Mezu Zuzena egoera gelan ezartzean", "Monday": "Astelehena", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Arazoak diagnostikatzeko, bezero honen egunkariak bidaliko dira arazte-txosten honekin. Testua besterik ez baduzu bidali nahi, desmarkatu:", "Remove from Directory": "Kendu direktoriotik", "Enable them now": "Gaitu orain", "Messages containing my user name": "Nire erabiltzaile-izena duten mezuak", - "Describe your problem here.": "Azaldu zure arazoa hemen.", "Toolbox": "Tresna-kutxa", "Collecting logs": "Egunkariak biltzen", "more": "gehiago", @@ -1128,47 +1099,31 @@ "Quote": "Aipua", "Send logs": "Bidali egunkariak", "All messages": "Mezu guztiak", - "Implementing VoIP services with Matrix": "VoIP zerbitzuak inplementatzea Matrix erabilita", - "Dev chat for the Riot/Web dev team": "Riot/web garapen taldearen txata", "Call invitation": "Dei gonbidapena", - "Riot Desktop on %(platformName)s": "Riot Desktop %(platformName)s plataforman", "Downloading update...": "Eguneraketa deskargatzen...", "State Key": "Egoera gakoa", "Failed to send custom event.": "Huts egin du gertaera pertsonalizatua bidaltzean.", "What's new?": "Zer dago berri?", - "Discussion of the Identity Service API": "Identitate zerbitzuaren APIari buruzko eztabaida", - "Support for those using and running matrix-appservice-irc": "matrix-appservice-irc exekutatu edo erabiltzen dutenentzako laguntza", - "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS eta matrix-ios-sdk txata", "Notify me for anything else": "Jakinarazi beste edozer", "When I'm invited to a room": "Gela batetara gonbidatzen nautenean", - "Design and implementation of E2E in Matrix": "Matrix-en E2E diseinu eta inplementazioa", "Click here to create a GitHub issue.": "Egin klik hemen GitHub-en arazoaren berri emateko.", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Zerbitzari pertsonalizatuaren aukerak erabili ditzakezu beste Matrix zerbitzarietan saioa hasteko, han beste hasiera-zerbitzari baten URLa sartuz.
    Horrela Riot aurretik duzun kontu batekin erabili dezakezu beste hasiera-zerbitzari batean.

    Identitate-zerbitzari pertsonalizatu bat ezarri dezakezu ere, baina orduan ezin izango dituzu erabiltzaileak e-mail helbidea erabiliz gonbidatu, edo ezin izan izango zaituzte zu e-mail helbidea erabiliz gonbidatu.", "Can't update user notification settings": "Ezin dira erabiltzailearen jakinarazpenen ezarpenak eguneratu", "Notify for all other messages/rooms": "Jakinarazi beste mezu/gela guztiak", "Unable to look up room ID from server": "Ezin izan da gelaren IDa zerbitzarian bilatu", "Couldn't find a matching Matrix room": "Ezin izan da bat datorren Matrix gela bat aurkitu", - "Support for those using the Matrix spec": "Matrix espezifikazioa darabilenentzako laguntza", - "Safari and Opera work too.": "Safari eta Opera badabiltza ere.", - "Loading bug report module": "Arazte-txosten modulua kargatzen", "Invite to this room": "Gonbidatu gela honetara", "Search for a room": "Bilatu gela bat", "Thursday": "Osteguna", "Search…": "Bilatu…", "Logs sent": "Egunkariak bidalita", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s %(browserName)s bidez %(osName)s ostalarian", "Back": "Atzera", "Reply": "Erantzun", "Show message in desktop notification": "Erakutsi mezua mahaigaineko jakinarazpenean", "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Arazte-egunkariek aplikazioak darabilen datuak dauzkate, zure erabiltzaile izena barne, bisitatu dituzun gelen ID-ak edo ezizenak eta beste erabiltzaileen izenak. Ez dute mezurik.", "Unhide Preview": "Ez ezkutatu aurrebista", - "Announcements about Synapse releases": "Synapse bertsio berrien iragarkiak", - "Search the room directory": "Bilatu gelen direktorioa", - "Please describe the bug and/or send logs.": "Deskribatu akatsa eta/edo bidali egunkariak.", "Unable to join network": "Ezin izan da sarera elkartu", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Agian Riot ez beste bezero batean konfiguratu dituzu. Ezin dituzu Riot bidez doitu, baina aplikagarriak dira", "Sorry, your browser is not able to run Riot.": "Zure nabigatzaileak ez du Riot erabiltzeko gaitasunik.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Deszentralizatutako eta zifratutako txat eta elkarlana [matrix] sareari esker", "Uploaded on %(date)s by %(user)s": "%(user)s erabiltzaileak %(date)s (e)an igota", "Messages in group chats": "Talde txatetako mezuak", "Yesterday": "Atzo", @@ -1177,16 +1132,13 @@ "Low Priority": "Lehentasun baxua", "Unable to fetch notification target list": "Ezin izan da jakinarazpen helburuen zerrenda eskuratu", "Appear Offline": "Agertu deskonektatuta", - "Get started with some tips from Riot Bot!": "Hasi Riot botaren aholku batzuekin!", "Set Password": "Ezarri pasahitza", "Enable audible notifications in web client": "Gaitu jakinarazpen entzungarriak web bezeroan", "Permalink": "Esteka iraunkorra", - "Welcome to Riot.im": "Ongi etorri Riot.im mezularitzara", "Off": "Ez", "Riot does not know how to join a room on this network": "Riotek ez daki nola elkartu gela batetara sare honetan", "Mentions only": "Aipamenak besterik ez", "You can now return to your account after signing out, and sign in on other devices.": "Zure kontura itzuli zaitezke beste gailuetan saioa amaitu eta berriro hastean.", - "Please install Chrome or Firefox for the best experience.": "Instalatu Chrome edo Firefox esperientzia on baterako.", "Enable email notifications": "Gaitu e-mail bidezko jakinarazpenak", "Event Type": "Gertaera mota", "Download this file": "Deskargatu fitxategi hau", @@ -1196,13 +1148,10 @@ "%(count)s Members|one": "Kide %(count)s", "Developer Tools": "Garatzaile-tresnak", "View Source": "Ikusi iturria", - "Matrix technical discussions": "Matrix buruzko eztabaida teknikoak", "Event Content": "Gertaeraren edukia", "Thank you!": "Eskerrik asko!", - "Building services on Matrix": "Matrix-en gaineko zerbitzuak eraikitzea", "Collapse panel": "Tolestu panela", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Zure oraingo nabigatzailearekin aplikazioaren itxura eta portaera guztiz okerra izan daiteke, eta funtzio batzuk ez dira ibiliko. Hala ere aurrera jarraitu dezakezu saiatu nahi baduzu, baina zure erantzukizunaren menpe geratzen dira aurkitu ditzakezun arazoak!", "Checking for an update...": "Eguneraketarik dagoen egiaztatzen...", - "General discussion about Matrix and Riot": "Matrix eta Riot-i buruzko eztabaida orokorra", "There are advanced notifications which are not shown here": "Hemen erakusten ez diren jakinarazpen aurreratuak daude" } diff --git a/src/i18n/strings/fa.json b/src/i18n/strings/fa.json index a5501d1246..2e359e21cb 100644 --- a/src/i18n/strings/fa.json +++ b/src/i18n/strings/fa.json @@ -2,8 +2,6 @@ "Fetching third party location failed": "تطبیق اطلاعات از منابع‌ دسته سوم با شکست مواجه شد", "Messages in one-to-one chats": "پیام‌های درون چت‌های یک‌به‌یک", "A new version of Riot is available.": "نسخه‌ی جدید از رایوت موجود است.", - "Riot/Android & matrix-android-sdk chat": "رایوت/اندروید & چت در مورد matrix-android-sdk", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "لطفا باگ را دقیقا تشریح کنید. چه کار کردید؟ انتظار داشتید چه اتفاقی بیفتد؟ دقیقا چه اتفاقی افتاد؟", "Advanced notification settings": "تنظیمات پیشرفته برای آگاه‌سازی‌ها", "Uploading report": "در حال بارگذاری گزارش", "Sunday": "یکشنبه", @@ -13,25 +11,19 @@ "Failed to set direct chat tag": "تنظیم تگ برای چت مستقیم موفقیت‌آمیز نبود", "Today": "امروز", "Files": "فایل‌ها", - "Report a bug": "باگ‌ها را گزارش کنید", - "Implementing VR services with Matrix": "پیاده‌سازی سرویس‌های VR با ماتریکس", "You are not receiving desktop notifications": "شما آگاه‌سازی‌های دسکتاپ را دریافت نمی‌کنید", "Friday": "آدینه", "Update": "به‌روزرسانی", "Notifications": "آگاه‌سازی‌ها", - "You need to be using HTTPS to place a screen-sharing call.": "شما باید از ارتباط امن HTTPS برای به‌راه‌اندازی یک چتِ شامل به اشتراک‌گذاری صفحه‌ی کامیپوتر استفاده کنید.", "What's New": "تازه‌ها", "Add an email address above to configure email notifications": "آدرس ایمیلتان را به بالا بیفزایید تا بتوانید آگاه‌سازی با ایمیل را مدیریت کنید", "Expand panel": "پنل را بگشا", "On": "روشن", "Filter room names": "جستجو در گپ‌ها", "Changelog": "تغییراتِ به‌وجودآمده", - "Running Matrix services": "اجرای سرویس‌های ماتریکسی", "Waiting for response from server": "در انتظار پاسخی از سمت سرور", "Leave": "خروج", "OK": "باشه", - "Failed to send report: ": "فرستادن گزارش موفقیت‌آمیز نبود: ", - "Unknown device": "دستگاه ناشناخته", "All notifications are currently disabled for all targets.": "همه‌ی آگاه‌سازی‌ها برای تمام هدف‌ها غیرفعال‌اند.", "Operation failed": "عملیات شکست خورد", "delete the alias.": "نام مستعار را پاک کن.", @@ -39,7 +31,6 @@ "Forget": "فراموش کن", "World readable": "خواندن جهانی", "Mute": "سکوت", - "Riot/Web & Desktop chat": "رایوت/وب & چت دسکتاپ", "Hide panel": "پنل را پنهان کن", "You cannot delete this image. (%(code)s)": "شما نمی‌توانید این تصویر را پاک کنید. (%(code)s)", "Cancel Sending": "فرستادن را لغو کن", @@ -50,32 +41,24 @@ "Downloading update...": "در حال بارگیریِ به‌روزرسانی...", "#example": "#نمونه", "Remember, you can always set an email address in user settings if you change your mind.": "به خاطر داشته باشید که اگر نظرتان عوض شد می‌توانید از بخش تنظیمات یک ایمیل را به اکانتتان متصل کنید.", - "Contributing code to Matrix and Riot": "کمک به برنامه‌نویسی در ماتریکس و رایوت", "Unavailable": "غیرقابل‌دسترسی", - "Community-run support for Synapse": "پشتیبانی سیناپس اداره‌شده توسط جامعه‌ی کاربری", "View Decrypted Source": "دیدن منبع رمزگشایی شده", "Failed to update keywords": "به‌روزرسانی کلیدواژه‌ها موفقیت‌آمیز نبود", "remove %(name)s from the directory.": "%(name)s را از فهرست گپ‌ها حذف کن", "Please set a password!": "لطفا یک پسورد اختیار کنید!", "powered by Matrix": "قدرت‌یافته از ماتریکس", "You have successfully set a password!": "شما با موفقیت رمزتان را انتخاب کردید!", - "Chat with Riot Bot": "با رایوت‌بات چت کنید", - "Support for those using, running and writing other bridges": "پشتیبانی برای آنان که یک پل را استفاده اجرا کرده و یا می‌نویسند", - "Admin support for Dendrite": "پشتیبانی ادمین برای Dendrite", "Favourite": "علاقه‌مندی‌ها", "All Rooms": "همه‌ی گپ‌ها", "Source URL": "آدرس مبدا", "Failed to add tag %(tagName)s to room": "در افزودن تگ %(tagName)s موفقیت‌آمیز نبود", "Members": "اعضا", "No update available.": "هیچ به روزرسانی جدیدی موجود نیست.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "بسیاری از گپ‌گاه‌های موجود در فهرستِ گپ‌ها به شبکه‌های موجود(اسلک، آی‌آر‌سی، گلیتر و...) متصل و یا مستقل‌اند؛ به آنها نگاهی بیندازید!", "Noisy": "پرسروصدا", "Failed to get protocol list from Home Server": "دریافت لیست پروتکل‌ها از کارگزار مبدا موفقیت‌آمیز نبود", "Collecting app version information": "درحال جمع‌آوری اطلاعات نسخه‌ی برنامه", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "آیا مطمئنید که می‌خواهید نام مستعار گپ %(alias)s را پاک و %(name)s را از فهرست حذف کنید؟", - "Co-ordination for Riot/Web translators": "هماهنگی برای مترجمان رایوت/وب", "This will allow you to return to your account after signing out, and sign in on other devices.": "این به شما اجازه خواهد داد که پس از خروج به اکانت خود بازگردید و از سایر دستگاه‌ها وارد شوید.", - "Dev chat for the Dendrite dev team": "چت توسعه‌دهندگان برای تیم Dendrite", "Cancel": "لغو", "Enable notifications for this account": "آگاه سازی با رایانامه را برای این اکانت فعال کن", "Directory": "فهرست گپ‌گاه‌ها", @@ -87,7 +70,6 @@ "Forward Message": "هدایت پیام", "Remove %(name)s from the directory?": "آیا مطمئنید می‌خواهید %(name)s را از فهرست گپ‌ها حذف کنید؟", "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "رایوت از بسیاری از ویژگی‌های پیشرفته در مروگرها استفاده می‌کند، برخی از این ویژگی‌ها در مرورگر کنونی شما موجود نیستند و یا در حالت آزمایشی قرار دارند.", - "Please install Chrome or Firefox for the best experience.": "لطفا برای بهترین تجربه‌ی کاربری ازکروم یا فایرفاکس استفاده کنید", "Unnamed room": "گپ نام‌گذاری نشده", "Dismiss": "نادیده بگیر", "Remove from Directory": "از فهرستِ گپ‌ها حذف کن", @@ -96,15 +78,11 @@ "Direct Chat": "چت مستقیم", "The server may be unavailable or overloaded": "این سرور ممکن است ناموجود یا بسیار شلوغ باشد", "Reject": "پس زدن", - "Riot is not supported on mobile web. Install the app?": "رایوت در موبایل‌ها پشتیبانی نمیشود؛ تمایلی دارید که اپ را نصب کنید؟", - "Discussion of all things Matrix!": "بحث درمورد تمام چیز‌های مربوط به ماتریکس!", "Failed to set Direct Message status of room": "تنظیم حالت پیام مستقیم برای گپ موفقیت‌آمیز نبود", "Monday": "دوشنبه", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "برای بهبود و رفع مشکلات، گزارش‌هایی از این کارخواه به عنوان مستنداتی از یک باگ ارسال خوهند شد. اگر ترجیح می‌دهید که فقط متن بالا ارسال شود لطفا تیک را بردارید", "All messages (noisy)": "همه‌ی پیام‌ها(بلند)", "Enable them now": "همین حالا فعالشان کن", "Messages containing my user name": "پیام‌های شامل نامِ کاربری من", - "Describe your problem here.": "مشکلتان را در اینجا توضیح دهید.", "Collecting logs": "درحال جمع‌آوری گزارش‌ها", "more": "بیشتر", "Search for a room": "جستجوی برای یک گپ", @@ -118,39 +96,24 @@ "Send logs": "ارسال گزارش‌ها", "All messages": "همه‌ی پیام‌ها", "unknown error code": "کد خطای ناشناخته", - "Implementing VoIP services with Matrix": "پیاده‌سازی سرویس‌های VoIP با ماتریکس", - "Dev chat for the Riot/Web dev team": "چت توسعه‌دهندگان برای تیم رایوت/وب", "Call invitation": "دعوت به تماس", - "Riot Desktop on %(platformName)s": "رایوت دسکتاپ بر %(platformName)s", "Messages containing my display name": "پیام‌های حاوی نمای‌نامِ من", "You have successfully set a password and an email address!": "تخصیص ایمیل و پسوردتان با موفقیت انجام شد!", "What's new?": "تازه‌ها", - "Discussion of the Identity Service API": "بحث درمورد API سرویس هویت", - "Support for those using and running matrix-appservice-irc": "پشتیبانی برای کسانی که matrix-appservice-irc را اجرا و استفاده می‌کنند", - "Riot/iOS & matrix-ios-sdk chat": "رایوت/آی‌او‌اس & چت در مورد matrix-ios-sdk", "Notify me for anything else": "مرا برای هرچیز دیگری باخبر کن", "When I'm invited to a room": "وقتی من به گپی دعوت میشوم", - "Design and implementation of E2E in Matrix": "طراحی و پیاده‌سازی رمزگذاری E2E در ماتریکس", "Close": "بستن", "Can't update user notification settings": "امکان به‌روزرسانی تنظیمات آگاه‌سازی کاربر وجود ندارد", "Notify for all other messages/rooms": "برای همه‌ی پیام‌ها/گپ‌های دیگر آگاه‌سازی کن", "Couldn't find a matching Matrix room": "گپ‌گاه مورد نظر در ماتریکس یافت نشد", - "Support for those using the Matrix spec": "پشتیبانی برای آنان که از مستندات ماتریکس استفاده می‌کنند", - "Safari and Opera work too.": "سافاری و اپرا نیز کار می‌کنند.", - "Loading bug report module": "درحال بارگذاری و اجرای ماژولِ گزارش باگ", "Invite to this room": "دعوت به این گپ", "You cannot delete this message. (%(code)s)": "شما نمی‌توانید این پیام را پاک کنید. (%(code)s)", "Thursday": "پنج‌شنبه", "Search…": "جستجو…", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s از طریق %(browserName)s بر %(osName)s", "Unhide Preview": "پیش‌نمایش را نمایان کن", - "Announcements about Synapse releases": "اطلاعیه‌ها درباره‌ی نسخه‌ها و انتشار سیناپس", - "Search the room directory": "در فهرست گپ‌ها جستجو کنید", - "Please describe the bug and/or send logs.": "لطفا باگ را توصیف کنید و یا گزارش‌ها را بفرستید", "Unable to join network": "خطا در ورود به شبکه", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "ممکن است شما این تنظیمات را در کارخواهی به جز رایوت اعمال کرده باشید. شما نمی‌توانید انها را تغییر دهید اما آنها همچنان تاثیر خود را دارند", "Sorry, your browser is not able to run Riot.": "متاسفانه مرورگر شما نمی‌تواند رایوت را اجرا کند.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "چت مرکزگریز و رمزنگاری‌شده & ارائه‌ای از ماتریکس", "Uploaded on %(date)s by %(user)s": "آپلود شده در تاریخ %(date)s توسط %(user)s", "Messages in group chats": "پیام‌های درون چت‌های گروهی", "Yesterday": "دیروز", @@ -159,11 +122,9 @@ "Low Priority": "کم اهمیت", "Unable to fetch notification target list": "ناتوانی در تطبیق لیست آگاه‌سازی‌های هدف", "Set Password": "پسوردتان را انتخاب کنید", - "Get started with some tips from Riot Bot!": "با کمی راهنمایی از رایوت‌بات شروع کنید!", "An error occurred whilst saving your email notification preferences.": "خطایی در حین ذخیره‌ی ترجیجات شما درباره‌ی رایانامه رخ داد.", "Enable audible notifications in web client": "آگاه‌سازی صدادار را در کارگزار وب فعال کن", "Permalink": "پایاپیوند", - "Welcome to Riot.im": "به Riot.im خوش‌آمدید", "Off": "خاموش", "Riot does not know how to join a room on this network": "رایوت از چگونگی ورود به یک گپ در این شبکه اطلاعی ندارد", "Mentions only": "فقط نام‌بردن‌ها", @@ -179,12 +140,9 @@ "Failed to change settings": "تغییر تنظیمات موفقیت‌آمیز نبود", "Failed to change password. Is your password correct?": "خطا در تغییر گذرواژه. آیا از درستی گذرواژه‌تان اطمینان دارید؟", "View Source": "دیدن منبع", - "Matrix technical discussions": "بحث‌های فنی درباره‌ی ماتریکس", "Custom Server Options": "تنظیمات سفارشی برای سرور", - "Building services on Matrix": "ساخت سرویس بر روی ماتریکس", "Collapse panel": "پنل را ببند", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "با مرورگر کنونی شما، ظاهر و حس استفاده از برنامه ممکن است کاملا اشتباه باشد و برخی یا همه‌ی ویژگی‌ها ممکن است کار نکنند. می‌توانید به استفاده ادامه دهید اما مسئولیت هر مشکلی که به آن بربخورید بر عهده‌ی خودتان است!", "Checking for an update...": "درحال بررسی به‌روزرسانی‌ها...", - "General discussion about Matrix and Riot": "بحث‌های کلی درمورد ماتریکس و رایوت", "There are advanced notifications which are not shown here": "آگاه‌سازی‌های پیشرفته‌ای هستند که در اینجا نشان داده نشده‌اند" } diff --git a/src/i18n/strings/fi.json b/src/i18n/strings/fi.json index fe2e493d19..4a83f456c7 100644 --- a/src/i18n/strings/fi.json +++ b/src/i18n/strings/fi.json @@ -71,7 +71,6 @@ "Ban": "Anna porttikielto", "Banned users": "Porttikiellon saanneet käyttäjät", "Bans user with given id": "Antaa porttikiellon käyttäjälle jolla on annettu tunniste", - "Bug Report": "Virheraportti", "Bulk Options": "Bulkkiasetukset", "Changes your display nickname": "Muuttaa näyttönimesi", "Changes colour scheme of current room": "Muuttaa tamänhetkisen huoneen väritystä", @@ -166,8 +165,6 @@ "Forgot your password?": "Unohditko salasanasi?", "For security, this session has been signed out. Please sign in again.": "Turvallisuussyistä tämä istunto on vanhentunut. Ole hyvä ja kirjaudu uudestaan.", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Turvallusuussyistä uloskirjautuminen poistaa kaikki päästä päähän-salausavaimet tästä selaimesta. Jos haluat purkaa keskustelujen salaukset tulevaisuudessa pitää sinun viedä purkuavaimet ja pitää ne turvallisesti tallessa.", - "Found a bug?": "Löysitkö virheen?", - "Hide Apps": "Piilota sovellukset", "Hide read receipts": "Piilota lukukuittaukset", "Hide Text Formatting Toolbar": "Piilota tekstinmuotoilutyökalupalkki", "Homeserver is": "Kotipalvelin on", @@ -475,7 +472,6 @@ "%(targetName)s rejected the invitation.": "%(targetName)s hylkäsi kutsun.", "Remote addresses for this room:": "Tämän huoneen etäosoitteet:", "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s poisti näyttönimensä (%(oldDisplayName)s).", - "Report it": "Ilmoita siitä", "Riot does not have permission to send you notifications - please check your browser settings": "Riotilla ei ole oikeuksia lähettää sinulle ilmoituksia. Ole hyvä ja tarkista selaimen asetukset", "Riot was not given permission to send notifications - please try again": "Riotilla ei saannut oikeuksia lähettää ilmoituksia. Ole hyvä ja yritä uudelleen", "Room %(roomId)s not visible": "Huone %(roomId)s ei ole näkyvissä", @@ -680,7 +676,6 @@ "User Options": "Käyttäjä-asetukset", "Make Moderator": "Anna moderaattorioikeudet", "Admin Tools": "Ylläpitotyökalut", - "Show Apps": "Näytä appit", "Unpin Message": "Poista viestin kiinnitys", "Jump to message": "Hyppää viestiin", "No pinned messages.": "Ei kiinnitettyjä viestejä.", @@ -785,7 +780,6 @@ "Leave Community": "Poistu yhteisöstä", "Leave %(groupName)s?": "Poistu yhteisöstä %(groupName)s?", "Leave": "Poistu", - "Unable to leave room": "Poistuminen epäonnistui", "Community Settings": "Yhteisöasetukset", "Add rooms to this community": "Lisää huoneita yhteisöön", "Featured Rooms:": "Esiinnostetut huoneet:", @@ -938,8 +932,6 @@ "Access Token:": "Pääsykoodi:", "Fetching third party location failed": "Kolmannen osapuolen paikan haku epäonnistui", "A new version of Riot is available.": "Uusi Riot-versio on saatavilla.", - "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk -keskustelu", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Ole hyvä ja kuvaile virhe. Mitä teit? Mitä oletit tapahtuvan? Mitä itse asiassa tapahtui?", "Couldn't load home page": "Kotisivun lataus epäonnistui", "Send Account Data": "Lähetä tilin tiedot", "All notifications are currently disabled for all targets.": "Kaikki ilmoitukset on kytketty pois kaikilta kohteilta.", @@ -950,12 +942,9 @@ "Failed to set direct chat tag": "Suoran viestittelyn tagin asettaminen epäonnistui", "Today": "Tänään", "Files": "Tiedostot", - "Report a bug": "Ilmoita ongelmasta", - "Implementing VR services with Matrix": "VR-palvelujen implementointi Matrixin avulla", "You are not receiving desktop notifications": "Et vastaanota työpöytäilmoituksia", "Friday": "Perjantai", "Update": "Päivitä", - "You need to be using HTTPS to place a screen-sharing call.": "Sinun täytyy käyttää HTTPS -yhteyttä, jotta voit jakaa ruudun.", "What's New": "Mikä on uutta", "Add an email address above to configure email notifications": "Lisää sähköpostiosoite yllä saadaksesi ilmoituksia sähköpostiisi", "Expand panel": "Avaa paneeli", @@ -963,17 +952,13 @@ "%(count)s Members|other": "%(count)s jäsentä", "Filter room names": "Suodata", "Changelog": "Muutosloki", - "Running Matrix services": "Matrix-palvelujen ylläpito", "Waiting for response from server": "Odotetaan vastausta palvelimelta", "Send Custom Event": "Lähetä kustomoitu tapahtuma", - "Failed to send report: ": "Raportin lähettäminen epäonnistui: ", - "Unknown device": "Tuntematon laite", "Advanced notification settings": "Lisäasetukset ilmoituksille", "delete the alias.": "poista alias.", "To return to your account in future you need to set a password": "Voidaksesi tulevaisuudessa palata tilillesi sinut pitää asettaa salasana", "Forget": "Unohda", "#example": "#esimerkki", - "Riot/Web & Desktop chat": "Riot/Web & Työpöytä-keskustelu", "Hide panel": "Piilota paneeli", "You cannot delete this image. (%(code)s)": "Et voi poistaa tätä kuvaa. (%(code)s)", "Cancel Sending": "Peruuta lähetys", @@ -983,35 +968,25 @@ "Room not found": "Huonetta ei löytynyt", "Downloading update...": "Ladataan päivitystä...", "Messages in one-to-one chats": "Viestit henkilökohtaisissa keskusteluissa", - "Contributing code to Matrix and Riot": "Osallistu kehitystyöhön", "Unavailable": "Ei saatavilla", - "Community-run support for Synapse": "Yhteisön tarjoama Synapse-tuki", "Error saving email notification preferences": "Virhe tallennettaessa sähköposti-ilmoitusasetuksia", "View Decrypted Source": "Näytä purettu lähdekoodi", "Failed to update keywords": "Avainsanojen päivittäminen epäonnistui", - "Welcome to Riot.im": "Tervetuloa Riot.im -palveluun", "Notifications on the following keywords follow rules which can’t be displayed here:": "Seuraaviin avainsanoihin liittyvät ilmoitukset seuraavat sääntöjä joita ei voida näyttää tässä:", "Safari and Opera work too.": "Safari ja Opera ovat myös tuettuja.", "Please set a password!": "Ole hyvä ja aseta salasana!", "You have successfully set a password!": "Olet onnistuneesti asettanut salasanan!", - "Chat with Riot Bot": "Keskustele Riot Botin kanssa", - "Support for those using, running and writing other bridges": "Tuki niille jotka käyttävät, ajavat ja ohjelmoivat muita siltoja", - "Admin support for Dendrite": "Dendrite ylläpitotuki", "Explore Room State": "Huoneen tila", "Source URL": "Lähde URL", "Messages sent by bot": "Bottien lähettämät viestit", "Filter results": "Suodata", "Members": "Jäsenet", "No update available.": "Ei päivityksiä saatavilla.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Matrixissa on olemassa monia huoneita, jotka on linkitetty olemassa oleviin verkkoihin (Slack, IRC, Gitter yms.). Tutustu hakemistoon!", "Resend": "Lähetä uudelleen", "Failed to get protocol list from Home Server": "Protokollalistan hakeminen Kotipalvelimelta ei onnistunut", "Collecting app version information": "Haetaan versiotietoja", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Poista huonetunnus %(alias)s ja poista %(name)s hakemistosta?", - "customServer_text": "Voit käyttää palvelinasetuksia muille Matrix-palvelimille kirjautumiseen asettamalla oman kotipalvelinosoitteen.
    Näin voit käyttää Riotia toisella kotipalvelimella sijaitsevan Matrix-käyttäjän kanssa.

    Voit myös asettaa oman tunnistautumispalvelimen, mutta sinua ei voi kutsua etkä voi kutsua muita sähköpostiosoitteella.", - "Co-ordination for Riot/Web translators": "Riot/Web kääntäjien koordinointi", "This will allow you to return to your account after signing out, and sign in on other devices.": "Tämä mahdollistaa sinut palamaan tilillesi uloskirjautumisen jälkeen sekä kirjautumaan muilla laitteilla.", - "Dev chat for the Dendrite dev team": "Kehittäjäkeskustelu Dendrite kehitystiimille", "Keywords": "Avainsanat", "Enable notifications for this account": "Ota käyttöön ilmoitukset tälle tilille", "Directory": "Hakemisto", @@ -1035,16 +1010,11 @@ "Direct Chat": "Suora viestittely", "The server may be unavailable or overloaded": "Palvelin saattaa olla saavuttamaton tai ylikuormitettu", "Reject": "Hylkää", - "Riot is not supported on mobile web. Install the app?": "Riot ei tue laitettasi. Asenna mobiilisovellus?", - "Discussion of all things Matrix!": "Keskustelu kaikesta Matrixiin liittyvästä!", "Failed to set Direct Message status of room": "Huoneen suoran viestittelyn tilan asettaminen epäonnistui", "Monday": "Maanantai", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Diagnoosin helpottamiseksi lokitietoja tältä laitteelta lähetetään tämän bugiraportin mukana. Poista ruksi jos haluat lätettää vain ylläolevan tekstin:", - "Send Custom State Event": "Lähetä kustomoitu tilatapahtuma", "Remove from Directory": "Poista hakemistosta", "Enable them now": "Ota käyttöön nyt", "Forward Message": "Edelleenlähetä viesti", - "Describe your problem here.": "Kuvaa ongelmasi tähän.", "Messages containing my user name": "Viestit joissa mainitaan käyttäjänimeni", "Toolbox": "Työkalut", "Collecting logs": "Haetaan lokitietoja", @@ -1058,44 +1028,28 @@ "Quote": "Lainaa", "Send logs": "Lähetä lokit", "All messages": "Kaikki viestit", - "Implementing VoIP services with Matrix": "VoIP-palvelujen implementointi Matrixin avulla", - "Dev chat for the Riot/Web dev team": "Kehittäjäkeskustelu Riot/Web kehitystiimille", "Call invitation": "Puhelukutsu", - "Riot Desktop on %(platformName)s": "Riot Desktop %(platformName)s", "Messages containing my display name": "Viestit joissa mainitaan nimimerkkini", "State Key": "Tila-avain", "Failed to send custom event.": "Kustomoidun tapahtuman lähettäminen epäonnistui.", "What's new?": "Mikä on uutta?", - "Discussion of the Identity Service API": "Keskustelu Identity Service rajapinnasta", - "Support for those using and running matrix-appservice-irc": "Tuki niille jotka käyttävät ja ajavat matrix-appservice-irc", - "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk -keskustelu", "Notify me for anything else": "Ilmoita minulle kaikesta muusta", "When I'm invited to a room": "Kun minut kutsutaan huoneeseen", - "Design and implementation of E2E in Matrix": "Matrix päästä-päähän salauksen suunnittelu ja implementointi", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Voit käyttää edistyksellisiä asetuksia kirjautuaksesi muille Matrix palvelimille, määrittelemällä kotipalvelimen URL-osoitteen.
    Tämän avulla voit käyttää Riot:ia olemassa olevalla toisen Matrix palvelimen käyttäjätilillä.

    Voit myös asettaa valinnaisen identiteettipalvelimen, mutta et voi kutsua käyttäjiä sähköpostiosoitteella tai tulla kutsutuksi.", "Can't update user notification settings": "Käyttäjän ilmoitusasetusten päivittäminen epäonnistui", "Notify for all other messages/rooms": "Ilmoita kaikista muista viesteistä/huoneista", "Unable to look up room ID from server": "Huone-ID:n haku palvelimelta epäonnistui", "Couldn't find a matching Matrix room": "Vastaavaa Matrix-huonetta ei löytynyt", - "Support for those using the Matrix spec": "Tuki Matrix-spesifikaation käyttäjille", - "Safari and Opera work too.": "Safari ja Opera toimivat myös.", - "Loading bug report module": "Ladataan bugiraportointimoduuli", "Invite to this room": "Kutsu käyttäjiä", "You cannot delete this message. (%(code)s)": "Et voi poistaa tätä viestiä. (%(code)s)", "Thursday": "Torstai", "I understand the risks and wish to continue": "Ymmärrän riskit ja haluan jatkaa", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s %(browserName)s %(osName)s", "Back": "Takaisin", "Reply": "Vastaa", "Show message in desktop notification": "Näytä viestit ilmoituskeskuksessa", "Unhide Preview": "Näytä ennakkokatselu", - "Announcements about Synapse releases": "Ilmoitukset uusista Synapse-julkaisuista", - "Search the room directory": "Hae hakemistosta", - "Please describe the bug and/or send logs.": "Ole hyvä ja kuvaile virhe sekä/tai lähetä lokitiedot.", "Unable to join network": "Verkkoon liittyminen epäonnistui", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Olet saattanut muuttaa niitä toisessa asiakasohjelmassa kuin Riot. Et voi muuttaa niitä Riotissa mutta ne pätevät kuitenkin", "Sorry, your browser is not able to run Riot.": "Valitettavasti Riot ei toimi selaimessasi.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Salattua ja vikasietoista viestintää Matrix -teknologialla", "Uploaded on %(date)s by %(user)s": "Ladattu %(date)s käyttäjän %(user)s toimesta", "Messages in group chats": "Viestit ryhmäkeskusteluissa", "Yesterday": "Eilen", @@ -1105,7 +1059,6 @@ "Unable to fetch notification target list": "Ilmoituskohdelistan haku epäonnistui", "Set Password": "Aseta salasana", "Appear Offline": "Offline-tila", - "Get started with some tips from Riot Bot!": "Aloita Riot Botin vinkkien avulla!", "An error occurred whilst saving your email notification preferences.": "Sähköposti-ilmoitusasetuksia tallettaessa tapahtui virhe.", "Enable audible notifications in web client": "Ota käyttöön äänelliset ilmoitukset", "Permalink": "Pysyvä linkki", @@ -1116,7 +1069,6 @@ "Failed to remove tag %(tagName)s from room": "Tagin %(tagName)s poistaminen huoneelta epäonnistui", "Wednesday": "Keskiviikko", "You can now return to your account after signing out, and sign in on other devices.": "Voit nyt palata tilillesi kirjauduttua ulos, sekä kirjautua muilla laitteilla.", - "Please install Chrome or Firefox for the best experience.": "Ole hyvä ja asenna Chrome tai Firefox parhaan kokemuksen saavuttamiseksi.", "Enable email notifications": "Ota käyttöön sähköposti-ilmoitukset", "Event Type": "Tapahtuman tyyppi", "Download this file": "Lataa tiedosto", @@ -1125,13 +1077,10 @@ "View Community": "Näytä yhteisö", "%(count)s Members|one": "%(count)s jäsen", "Event sent!": "Tapahtuma lähetetty!", - "Matrix technical discussions": "Tekniset keskustelut", "Event Content": "Tapahtuman sisältö", "Thank you!": "Kiitos!", - "Building services on Matrix": "Palveluiden rakentaminen Matrixin avulla", "Collapse panel": "Piilota paneeli", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Nykyisellä selaimellasi ohjelman ulkonäkö voi olla aivan virheellinen, ja jotkut ominaisuudet eivät saata toimia. Voit jatkaa jos haluat kokeilla mutta et voi odottaa saavasi apua mahdollisesti ilmeneviin ongelmiin!", "Checking for an update...": "Tarkistetaan päivityksen saatavuutta...", - "General discussion about Matrix and Riot": "Matrix- ja Riot keskustelut", "There are advanced notifications which are not shown here": "On kehittyneitä ilmoituksia joita ei näytetä tässä" } diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index d30c4e6a71..b94dae49e4 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -57,7 +57,6 @@ "Banned users": "Utilisateurs bannis", "Bans user with given id": "Bannit l'utilisateur à partir de son identifiant", "Blacklisted": "Sur liste noire", - "Bug Report": "Rapport d'erreur", "Call Timeout": "Délai d’appel expiré", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Impossible de se connecter au serveur d'accueil en HTTP si l'URL dans la barre de votre explorateur est en HTTPS. Utilisez HTTPS ou activez le support des scripts non-vérifiés.", "Can't load user settings": "Impossible de charger les paramètres de l'utilisateur", @@ -133,7 +132,6 @@ "Forget room": "Oublier le salon", "Forgot your password?": "Mot de passe oublié ?", "For security, this session has been signed out. Please sign in again.": "Par mesure de sécurité, la session a expiré. Merci de vous authentifier à nouveau.", - "Found a bug?": "Vous avez trouvé un problème ?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s de %(fromPowerLevel)s à %(toPowerLevel)s", "Hangup": "Raccrocher", "Hide read receipts": "Cacher les accusés de lecture", @@ -241,7 +239,6 @@ "%(senderName)s removed their profile picture.": "%(senderName)s a supprimé son image de profil.", "Remove %(threePid)s?": "Supprimer %(threePid)s ?", "%(senderName)s requested a VoIP conference.": "%(senderName)s a demandé une téléconférence audio.", - "Report it": "Le signaler", "Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Pour le moment, réinitialiser le mot de passe va réinitialiser les clés de chiffrement sur tous les appareils, rendant l’historique des salons chiffrés illisible, à moins que vous exportiez d'abord les clés de salon puis que vous les ré-importiez après. Cela sera amélioré prochainement.", "Return to login screen": "Retourner à l’écran de connexion", "Riot does not have permission to send you notifications - please check your browser settings": "Riot n’a pas la permission de vous envoyer des notifications - merci de vérifier les paramètres de votre navigateur", @@ -651,11 +648,9 @@ "Define the power level of a user": "Définir le rang d'un utilisateur", "Edit": "Modifier", "Enable automatic language detection for syntax highlighting": "Activer la détection automatique de la langue pour la correction orthographique", - "Hide Apps": "Masquer les applications", "Hide join/leave messages (invites/kicks/bans unaffected)": "Masquer les messages d'arrivée/départ (n'affecte pas les invitations/exclusions/bannissements)", "Revoke widget access": "Révoquer les accès du widget", "Sets the room topic": "Défini le sujet du salon", - "Show Apps": "Afficher les applications", "To get started, please pick a username!": "Pour commencer, choisissez un nom d'utilisateur !", "Unable to create widget.": "Impossible de créer un widget.", "Unbans user with given id": "Révoque le bannissement de l'utilisateur à partir de son identifiant", @@ -862,7 +857,6 @@ "Leave Community": "Quitter la communauté", "Leave %(groupName)s?": "Quitter %(groupName)s ?", "Leave": "Quitter", - "Unable to leave room": "Impossible de partir du salon", "Community Settings": "Paramètres de la communauté", "Add rooms to this community": "Ajouter des salons à cette communauté", "%(inviter)s has invited you to join this community": "%(inviter)s vous a invité à rejoindre cette communauté", @@ -992,7 +986,6 @@ "Key request sent.": "Demande de clé envoyée.", "Re-request encryption keys from your other devices.": "Re-demander les clés de chiffrement depuis vos autres appareils.", "%(user)s is a %(userRole)s": "%(user)s est %(userRole)s", - "Changes made to your community might not be seen by other users for up to 30 minutes.": "Les changements effectués sur votre communauté peuvent ne pas apparaître pour les autres utilisateurs avant 30 minutes.", "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Vu par %(displayName)s (%(userName)s) à %(dateTime)s", "Code": "Code", "Debug Logs Submission": "Envoi des journaux de débogage", @@ -1007,19 +1000,13 @@ "Stickerpack": "Pack de stickers", "Sticker Messages": "Messages sticker", "You don't currently have any stickerpacks enabled": "Vous n'avez activé aucun pack de stickers pour l'instant", - "Click": "Cliquer", - "here": "ici", - "to add some!": "pour en ajouter !", "Add a stickerpack": "Ajouter un pack de stickers", "Hide Stickers": "Masquer les stickers", "Show Stickers": "Afficher les stickers", - "Manage sticker packs": "Gérer les packs de stickers", "Who can join this community?": "Qui peut rejoindre cette communauté ?", "Everyone": "Tout le monde", "Fetching third party location failed": "Échec de la récupération de la localisation tierce", "A new version of Riot is available.": "Une nouvelle version de Riot est disponible.", - "Riot/Android & matrix-android-sdk chat": "Discussions sur Riot/Android & matrix-android-sdk", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Veuillez décrire l'erreur. Qu'avez-vous fait ? Quel était le comportement attendu ? Que s'est-il réellement passé ?", "Couldn't load home page": "Impossible de charger la page d'accueil", "Send Account Data": "Envoyer les données du compte", "All notifications are currently disabled for all targets.": "Toutes les notifications sont désactivées pour tous les appareils.", @@ -1028,12 +1015,9 @@ "Notification targets": "Appareils recevant les notifications", "Today": "Aujourd'hui", "Files": "Fichiers", - "Report a bug": "Signaler un problème", - "Implementing VR services with Matrix": "Implémentation de services de réalité virtuelle avec Matrix", "You are not receiving desktop notifications": "Vous ne recevez pas les notifications sur votre bureau", "Friday": "Vendredi", "Update": "Mettre à jour", - "You need to be using HTTPS to place a screen-sharing call.": "Vous devez utiliser HTTPS pour effectuer un appel en partage d’écran.", "What's New": "Nouveautés", "Add an email address above to configure email notifications": "Ajouter une adresse e-mail pour la configuration des notifications par e-mail", "Expand panel": "Dévoiler le panneau", @@ -1041,17 +1025,13 @@ "%(count)s Members|other": "%(count)s membres", "Filter room names": "Filtrer les salons par nom", "Changelog": "Journal des modifications", - "Running Matrix services": "Exécution de services Matrix", "Waiting for response from server": "En attente d’une réponse du serveur", "Send Custom Event": "Envoyer l'événement personnalisé", - "Failed to send report: ": "Échec de l’envoi du rapport : ", - "Unknown device": "Appareil inconnu", "Advanced notification settings": "Paramètres de notification avancés", "delete the alias.": "supprimer l'alias.", "To return to your account in future you need to set a password": "Pour pouvoir retrouver votre compte dans le futur, vous devez définir un mot de passe", "Forget": "Oublier", "#example": "#exemple", - "Riot/Web & Desktop chat": "Discussions sur Riot/Web & Bureau", "Hide panel": "Cacher le panneau", "You cannot delete this image. (%(code)s)": "Vous ne pouvez pas supprimer cette image. (%(code)s)", "Cancel Sending": "Annuler l'envoi", @@ -1061,9 +1041,7 @@ "Room not found": "Salon non trouvé", "Messages containing my display name": "Messages contenant mon nom affiché", "Messages in one-to-one chats": "Messages dans les discussions directes", - "Contributing code to Matrix and Riot": "Contribuer du code à Matrix et Riot", "Unavailable": "Indisponible", - "Community-run support for Synapse": "Support communautaire sur Synapse", "View Decrypted Source": "Voir la source déchiffrée", "Failed to update keywords": "Échec dans la mise à jour des mots-clés", "remove %(name)s from the directory.": "supprimer %(name)s du répertoire.", @@ -1071,9 +1049,6 @@ "Safari and Opera work too.": "Safari et Opera fonctionnent également.", "Please set a password!": "Veuillez définir un mot de passe !", "You have successfully set a password!": "Vous avez défini un mot de passe avec succès !", - "Chat with Riot Bot": "Discussion avec Riot Bot", - "Support for those using, running and writing other bridges": "Support pour les utilisateurs, administrateurs et développeurs d'autres passerelles", - "Admin support for Dendrite": "Support admin pour Dendrite", "An error occurred whilst saving your email notification preferences.": "Une erreur est survenue lors de la sauvegarde de vos préférences de notification par e-mail.", "Explore Room State": "Parcourir l'état du salon", "Source URL": "URL de la source", @@ -1081,15 +1056,11 @@ "Filter results": "Filtrer les résultats", "Members": "Membres", "No update available.": "Aucune mise à jour disponible.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "De nombreux salons existent déjà dans Matrix, liés à des réseaux existants (Slack, IRC, Gitter etc) ou indépendants. Jetez un œil au répertoire !", "Resend": "Renvoyer", "Failed to get protocol list from Home Server": "Échec lors de la récupération de la liste sur le serveur", "Collecting app version information": "Récupération des informations de version de l’application", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Supprimer l'alias %(alias)s du salon et supprimer %(name)s du répertoire ?", - "customServer_text": "Vous pouvez utiliser les options de serveur personnalisées pour vous connecter à d'autres serveurs Matrix, en spécifiant une adresse de serveur d'accueil différente.
    Cela permet d'utiliser Riot avec un compte Matrix existant sur un serveur d'accueil différent.

    Vous pouvez aussi indiquer un serveur d'identité personnalisé mais vous ne pourrez pas inviter d'utilisateurs par e-mail ou être invité par e-mail.", - "Co-ordination for Riot/Web translators": "Coordination des traducteurs de Riot/Web", "This will allow you to return to your account after signing out, and sign in on other devices.": "Cela vous permettra de retourner sur votre compte après vous être déconnecté, et de vous identifier sur d'autres appareils.", - "Dev chat for the Dendrite dev team": "Discussion pour l'équipe de développeurs de Dendrite", "Keywords": "Mots-clés", "Enable notifications for this account": "Activer les notifications pour ce compte", "Directory": "Répertoire", @@ -1114,16 +1085,11 @@ "Direct Chat": "Discussion directe", "The server may be unavailable or overloaded": "Le serveur est indisponible ou surchargé", "Reject": "Rejeter", - "Riot is not supported on mobile web. Install the app?": "Riot n’est pas supporté sur les appareils mobiles. Installer l’application ?", - "Discussion of all things Matrix!": "Discussion sur tout ce qui concerne Matrix !", "Failed to set Direct Message status of room": "Échec du réglage de l'état du salon en Discussion directe", "Monday": "Lundi", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Afin de diagnostiquer les problèmes, les journaux de ce client vont être envoyés avec ce rapport d’erreur. Si vous préférez n'envoyer que le texte ci-dessus, décochez la case :", - "Send Custom State Event": "Envoyer l'événement d'état personnalisé", "All messages (noisy)": "Tous les messages (fort)", "Enable them now": "Les activer maintenant", "Messages containing my user name": "Message contenant mon nom d'utilisateur", - "Describe your problem here.": "Décrivez votre problème ici.", "Toolbox": "Boîte à outils", "Collecting logs": "Récupération des journaux", "more": "plus", @@ -1137,44 +1103,28 @@ "Quote": "Citer", "Send logs": "Envoyer les journaux", "All messages": "Tous les messages", - "Implementing VoIP services with Matrix": "Implémentation de services de voix sur IP avec Matrix", - "Dev chat for the Riot/Web dev team": "Discussions de l'équipe de développeurs de Riot/Web", "Call invitation": "Appel entrant", - "Riot Desktop on %(platformName)s": "Version bureau de Riot sur %(platformName)s", "Downloading update...": "Mise à jour en cours de téléchargement...", "State Key": "Clé d'état", "Failed to send custom event.": "Échec de l'envoi de l'événement personnalisé.", "What's new?": "Nouveautés ?", - "Discussion of the Identity Service API": "Discussion sur l’API du Service Identité", - "Support for those using and running matrix-appservice-irc": "Support pour ceux qui utilisent et exécutent matrix-appservice-irc", - "Riot/iOS & matrix-ios-sdk chat": "Discussions sur Riot/iOS & matrix-ios-sdk", "Notify me for anything else": "Me notifier pour tout le reste", "View Source": "Voir la source", - "Design and implementation of E2E in Matrix": "Définition et implémentation du chiffrement de bout en bout dans Matrix", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Vous pouvez utiliser les options de serveur personnalisé pour vous connecter à d'autres serveurs Matrix en précisant un serveur d'accueil différent.
    Cela vous permet d'utiliser Riot avec un compte Matrix existant sur un autre serveur d'accueil.

    Vous pouvez aussi renseigner un serveur d'identité personnalisé mais vous ne pourrez pas inviter d'utilisateurs avec leur adresse e-mail, ou être invité avec votre adresse e-mail.", "Can't update user notification settings": "Impossible de mettre à jour les paramètres de notification de l'utilisateur", "Notify for all other messages/rooms": "Me notifier pour tous les autres messages/salons", "Unable to look up room ID from server": "Impossible de récupérer l'ID du salon sur le serveur", "Couldn't find a matching Matrix room": "Impossible de trouver un salon Matrix correspondant", - "Support for those using the Matrix spec": "Support pour les utilisateurs de la spécification de Matrix", - "Safari and Opera work too.": "Safari et Opera fonctionnent aussi.", - "Loading bug report module": "Chargement du module de rapport d’erreur", "All Rooms": "Tous les salons", "Search for a room": "Rechercher un salon", "Thursday": "Jeudi", "Forward Message": "Transférer le message", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s dans %(browserName)s sous %(osName)s", "Back": "Retour", "Reply": "Répondre", "Show message in desktop notification": "Afficher le message dans les notifications de bureau", "Unhide Preview": "Dévoiler l'aperçu", - "Announcements about Synapse releases": "Communiqués sur les nouvelles versions de Synapse", - "Search the room directory": "Rechercher dans le répertoire de salons", - "Please describe the bug and/or send logs.": "Veuillez décrire le problème et/ou envoyer les journaux.", "Unable to join network": "Impossible de rejoindre le réseau", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Vous les avez probablement configurées dans un autre client que Riot. Vous ne pouvez pas les configurer dans Riot mais elles s'appliquent quand même", "Sorry, your browser is not able to run Riot.": "Désolé, Riot n'est pas supporté par votre navigateur.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Discussion & collaboration décentralisées et chiffrées, propulsées par [matrix]", "Uploaded on %(date)s by %(user)s": "Téléchargé le %(date)s par %(user)s", "Messages in group chats": "Messages dans les discussions de groupe", "Yesterday": "Hier", @@ -1183,16 +1133,13 @@ "Low Priority": "Priorité basse", "Unable to fetch notification target list": "Impossible de récupérer la liste des appareils recevant les notifications", "Appear Offline": "Apparaître Hors ligne", - "Get started with some tips from Riot Bot!": "Démarrer avec quelques astuces de Riot Bot !", "Set Password": "Définir un mot de passe", "Enable audible notifications in web client": "Activer les notifications sonores pour le client web", "Permalink": "Permalien", - "Welcome to Riot.im": "Bienvenue sur Riot.im", "Off": "Désactivé", "Riot does not know how to join a room on this network": "Riot ne peut pas joindre un salon sur ce réseau", "Mentions only": "Seulement les mentions", "You can now return to your account after signing out, and sign in on other devices.": "Vous pouvez maintenant revenir sur votre compte après vous être déconnecté, et vous identifier sur d'autres appareils.", - "Please install Chrome or Firefox for the best experience.": "Veuillez installer Chrome ou Firefox pour une expérience optimale.", "Enable email notifications": "Activer les notifications par e-mail", "Event Type": "Type d'événement", "Download this file": "Télécharger ce fichier", @@ -1202,13 +1149,10 @@ "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Depuis votre navigateur actuel, le visuel et le ressenti de l'application pourraient être complètement erronés, et certaines fonctionnalités pourraient ne pas être supportées. Vous pouvez continuer malgré tout, mais vous n'aurez aucune aide si vous rencontrez des problèmes !", "%(count)s Members|one": "%(count)s membre", "Event sent!": "Événement envoyé !", - "Matrix technical discussions": "Discussions techniques sur Matrix", "Event Content": "Contenu de l'événement", "Thank you!": "Merci !", - "Building services on Matrix": "Développement de services sur Matrix", "Collapse panel": "Cacher le panneau", "When I'm invited to a room": "Quand je suis invité dans un salon", "Checking for an update...": "Recherche de mise à jour...", - "General discussion about Matrix and Riot": "Discussion générale sur Matrix et Riot", "There are advanced notifications which are not shown here": "Il existe une configuration avancée des notifications qui ne peut être affichée ici" } diff --git a/src/i18n/strings/gl.json b/src/i18n/strings/gl.json index e0b94e5fcd..564230f613 100644 --- a/src/i18n/strings/gl.json +++ b/src/i18n/strings/gl.json @@ -302,8 +302,6 @@ "Hangup": "Quedada", "Voice call": "Chamada de voz", "Video call": "Chamada de vídeo", - "Hide Apps": "Agochar Apps", - "Show Apps": "Mostrar Apps", "Upload file": "Subir ficheiro", "Show Text Formatting Toolbar": "Mostrar barra de formato de texto", "Send an encrypted reply…": "Enviar unha resposta cifrada…", @@ -736,7 +734,6 @@ "Leave Community": "Deixar a comunidade", "Leave %(groupName)s?": "Deixar %(groupName)s?", "Leave": "Saír", - "Unable to leave room": "Non puido deixar a sala", "Community Settings": "Axustes da comunidade", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Estas salas son mostradas aos membros da comunidade na páxina da comunidade. Os membros da comunidade poden unirse as salas pulsando en elas.", "Add rooms to this community": "Engadir salas a esta comunidade", @@ -826,9 +823,6 @@ "Device ID:": "ID de dispositivo:", "Device key:": "Chave do dispositivo:", "Ignored Users": "Usuarias ignoradas", - "Bug Report": "Informe de fallo", - "Found a bug?": "Atopou un fallo?", - "Report it": "Informe", "Analytics": "Analytics", "Riot collects anonymous analytics to allow us to improve the application.": "Riot recolle información analítica anónima para permitirnos mellorar o aplicativo.", "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "A intimidade impórtanos, así que non recollemos información personal ou identificable nos datos dos nosos análises.", @@ -989,7 +983,6 @@ "Flair will appear if enabled in room settings": "O Aura aparecerá si está habilitada nas preferencias da sala", "Flair will not appear": "O Aura non aparecerá", "Display your community flair in rooms configured to show it.": "Mostrar o aura da súa comunidade en salas configuradas para mostralo.", - "Changes made to your community might not be seen by other users for up to 30 minutes.": "Os cambios feitos a súa comunidade poderían tardar uns 30 minutos en ser visibles para os membros.", "Did you know: you can use communities to filter your Riot.im experience!": "Sabía que pode utilizar as comunidades para mellorar a súa experiencia con Riot.im!", "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Para establecer un filtro, arrastre un avatar da comunidade sobre o panel de filtros na parte esquerda da pantalla. Pode pulsar nun avatar no panel de filtrado en calquer moemento para ver só salas e xente asociada a esa comunidade.", "Deops user with given id": "Degradar usuaria co id dado", @@ -1006,8 +999,6 @@ "Opens the Developer Tools dialog": "Abre o cadro de Ferramentas de Desenvolvedoras", "Fetching third party location failed": "Fallo ao obter a localización de terceiros", "A new version of Riot is available.": "Está dispoñible unha nova versión de Riot.", - "Riot/Android & matrix-android-sdk chat": "Chat para Riot/Android & matrix-android-sdk", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Por favor describa a incidencia. Que estaba a facer? Que tiña que pasar? Que aconteceu en realidade?", "Couldn't load home page": "Non se cargou a páxina de inicio", "Send Account Data": "Enviar datos da conta", "All notifications are currently disabled for all targets.": "Todas as notificacións están deshabilitadas para todos os destinos.", @@ -1016,12 +1007,9 @@ "Notification targets": "Obxetivos das notificacións", "Today": "Hoxe", "Failed to get protocol list from Home Server": "Fallo ao obter a lista de protocolo desde o servidor", - "Report a bug": "Informar de un fallo", - "Implementing VR services with Matrix": "Implementando servizos de RV con Matrix", "You are not receiving desktop notifications": "Non está a recibir notificacións de escritorio", "Friday": "Venres", "Update": "Actualizar", - "You need to be using HTTPS to place a screen-sharing call.": "Precisa utilizar HTTPS para establecer unha chamada de pantalla compartida.", "What's New": "Qué hai de novo", "Add an email address above to configure email notifications": "Engada un enderezo de correo electrónico para configurar as notificacións", "Expand panel": "Expandir panel", @@ -1029,18 +1017,14 @@ "%(count)s Members|other": "%(count)s Membros", "Filter room names": "Filtrar nomes de sala", "Changelog": "Rexistro de cambios", - "Running Matrix services": "Servizos correndo sobre Matrix", "Waiting for response from server": "Agardando pola resposta do servidor", "Send Custom Event": "Enviar evento personalizado", - "Failed to send report: ": "Fallo no envío do informe: ", - "Unknown device": "Dispositivo descoñecido", "Advanced notification settings": "Axustes avanzados de notificación", "Failed to send logs: ": "Fallo ao enviar os informes: ", "delete the alias.": "borrar alcume.", "To return to your account in future you need to set a password": "Para voltar a súa conta no futuro debe establecer un contrasinal>/u>", "Forget": "Esquecer", "#example": "#exemplo", - "Riot/Web & Desktop chat": "Riot/Web & chat de Escritorio", "Hide panel": "Agochar panel", "You cannot delete this image. (%(code)s)": "Non pode eliminar esta imaxe. (%(code)s)", "Cancel Sending": "Cancelar o envío", @@ -1050,9 +1034,7 @@ "Error saving email notification preferences": "Fallo ao cargar os axustes de notificacións", "Messages containing my display name": "Mensaxes que conteñen o meu nome público", "Messages in one-to-one chats": "Mensaxes en chats un-a-un", - "Contributing code to Matrix and Riot": "Contribuíndo ao código en Matrix e Riot", "Unavailable": "Non dispoñible", - "Community-run support for Synapse": "Axuda da comunidade para Synapse", "View Decrypted Source": "Ver a fonte descifrada", "Failed to update keywords": "Fallo ao actualizar as palabras chave", "Notes:": "Notas:", @@ -1061,9 +1043,6 @@ "Safari and Opera work too.": "Safari e Opera tamén funcionan.", "Please set a password!": "Por favor estableza un contrasinal!", "You have successfully set a password!": "Mudou con éxito o seu contrasinal!", - "Chat with Riot Bot": "Chat co Bot de Riot", - "Support for those using, running and writing other bridges": "Axuda para que utiliza, executa e desenvolve outras pontes", - "Admin support for Dendrite": "Axuda administrador para Dendrite", "An error occurred whilst saving your email notification preferences.": "Algo fallou mentras se gardaban as súas preferencias de notificaicón.", "Explore Room State": "Explorar estado da sala", "Search for a room": "Buscar unha sala", @@ -1072,15 +1051,11 @@ "Filter results": "Filtrar resultados", "Members": "Membresía", "No update available.": "Sen actualizacións.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Xa existen multitude de salas en Matrix, ligadas a redes existentes (Slack, IRC, Gitter etc) ou independentes. Busque no directorio!", "Resend": "Voltar a enviar", "Files": "Ficheiros", "Collecting app version information": "Obtendo información sobre a versión da app", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Eliminar o alcume da sala %(alias)s e borrar %(name)s do directorio?", - "customServer_text": "Pode utilizar os axustes do servidor personalizado para conectarse a outros servidores Matrix indicando un URL de Inicio do servidor.
    Esto permítelle utilizar Riot con unha conta existente de Matrix nun servidor diferente.

    Tamén pode establecer un servidor personalizado de identidade mais non poderá invitar a usuarias a través de enderezos de correo ou ser vostede invitada do mesmo xeito.", - "Co-ordination for Riot/Web translators": "Coordinación para tradutores de Riot/Web", "This will allow you to return to your account after signing out, and sign in on other devices.": "Esto permitiralle voltar a súa conta tras desconectarse, e conectarse en outros dispositivos.", - "Dev chat for the Dendrite dev team": "Chat para o equipo de desenvolvemento de Dendrite", "Keywords": "Palabras chave", "Enable notifications for this account": "Habilitar notificacións para esta conta", "Directory": "Directorio", @@ -1105,16 +1080,11 @@ "Direct Chat": "Chat directo", "The server may be unavailable or overloaded": "O servidor podería non estar dispoñible ou sobrecargado", "Reject": "Rexeitar", - "Riot is not supported on mobile web. Install the app?": "Riot no se pode executar na web móbil. Instalar a app?", - "Discussion of all things Matrix!": "Conversa sobre to o relativo a Matrix!", "Failed to set Direct Message status of room": "Fallo ao establecer o estado Mensaxe Directa da sala", "Monday": "Luns", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Para poder diagnosticar o problema, os rexistros de este cliente enviaranse neste informe de fallo. Si prefire enviar só o texto superior, desmarque:", - "Send Custom State Event": "Enviar evento de estado personalizado", "Remove from Directory": "Eliminar do directorio", "Enable them now": "Habilitalas agora", "Messages containing my user name": "Mensaxes que conteñen o meu nome de usuaria", - "Describe your problem here.": "Describa aquí o seu problema.", "Toolbox": "Ferramentas", "Collecting logs": "Obtendo rexistros", "more": "máis", @@ -1129,47 +1099,31 @@ "Quote": "Cita", "Send logs": "Enviar informes", "All messages": "Todas as mensaxes", - "Implementing VoIP services with Matrix": "Implementación de servizos VoIP con Matrix", - "Dev chat for the Riot/Web dev team": "Chat para o equipo de desenvolvemento do Riot/Web", "Call invitation": "Convite de chamada", - "Riot Desktop on %(platformName)s": "Riot Desktop en %(platformName)s", "Downloading update...": "Descargando actualización...", "You have successfully set a password and an email address!": "Estableceu correctamente un contrasinal e enderezo de correo!", "Failed to send custom event.": "Fallo ao enviar evento personalizado.", "What's new?": "Qué hai de novo?", - "Discussion of the Identity Service API": "Conversa sobre a Identity Service API", - "Support for those using and running matrix-appservice-irc": "Axuda para quen usa matrix-appservice-irc", - "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & chat matrix-ios-sdk", "Notify me for anything else": "Notificarme todo o demáis", "When I'm invited to a room": "Cando son convidado a unha sala", - "Design and implementation of E2E in Matrix": "Deseño e implementación de E2E en Matrix", "Click here to create a GitHub issue.": "Pulse aquí para crear un reporte en GitHub.", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Vostede pode utilizar as opcións de servidor personalizado para conectarse a outros servidores Matrix indicando o enderezo URL do Servidor.
    Esto permítelle utilizar Riot con unha conta Matrix existente en outro servidor.

    Tamén pode indicar un servidor de identidade pero non poderá convidar a usarias polo seu enderezo de correo electrónico, o ser convidada vostede por correo electrónico.", "Can't update user notification settings": "Non se poden actualizar os axutes de notificación", "Notify for all other messages/rooms": "Notificar para todas as outras mensaxes/salas", "Unable to look up room ID from server": "Non se puido atopar o ID da sala do servidor", "Couldn't find a matching Matrix room": "Non coincide con ningunha sala de Matrix", - "Support for those using the Matrix spec": "Axuda para quen usa a especificación Matrix", - "Safari and Opera work too.": "Safari e Opera tamén serven.", - "Loading bug report module": "Cargando o módulo de informe de fallos", "Invite to this room": "Convidar a esta sala", "You cannot delete this message. (%(code)s)": "Non pode eliminar esta mensaxe. (%(code)s)", "Thursday": "Xoves", "Forward Message": "Reenviar mensaxe", "Logs sent": "Informes enviados", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s vía %(browserName)s en %(osName)s", "Back": "Atrás", "Reply": "Resposta", "Show message in desktop notification": "Mostrar mensaxe nas notificacións de escritorio", "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Os informes de depuración conteñen datos de utilización do aplicativo como o seu nome de usuaria, os IDs ou alcumes de salas e grupos que vostede visitou e os nomes de usuaria de outras usuarias. Non conteñen mensaxes.", "Unhide Preview": "Desagochar a vista previsa", - "Announcements about Synapse releases": "Anuncios sobre lanzamentos de Synapse", - "Search the room directory": "Buscar no directorio de salas", - "Please describe the bug and/or send logs.": "Por favor describa a incidencia e/ou envíe o informe.", "Unable to join network": "Non se puido conectar a rede", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Pode que os configurase nun cliente diferente de Riot. Non pode establecelos desde Riot pero aínda así aplicaranse", "Sorry, your browser is not able to run Riot.": "Desculpe, o seu navegador non pode executar Riot.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Chat & colaboración descentralizados e cifrados grazas a [matrix]", "Uploaded on %(date)s by %(user)s": "Subido a %(date)s por %(user)s", "Messages in group chats": "Mensaxes en grupos de chat", "Yesterday": "Onte", @@ -1178,16 +1132,13 @@ "Low Priority": "Baixa prioridade", "Unable to fetch notification target list": "Non se puido procesar a lista de obxetivo de notificacións", "Appear Offline": "Aparecer fora de liña", - "Get started with some tips from Riot Bot!": "Iníciese con algúns consellos do Bot de Riot!", "Set Password": "Establecer contrasinal", "Enable audible notifications in web client": "Habilitar notificacións audibles no cliente web", "Permalink": "Ligazón permanente", - "Welcome to Riot.im": "Benvida a Riot.im", "Off": "Off", "Riot does not know how to join a room on this network": "Riot non sabe cómo conectar con unha sala en esta rede", "Mentions only": "Só mencións", "You can now return to your account after signing out, and sign in on other devices.": "Pode voltar a súa contra tras desconectarse, e conectarse en outros dispositivos.", - "Please install Chrome or Firefox for the best experience.": "Por favor instale Chrome ou Firefox para ter a mellor experiencia de uso.", "Enable email notifications": "Habilitar notificacións de correo", "Event Type": "Tipo de evento", "Download this file": "Descargue este ficheiro", @@ -1197,13 +1148,10 @@ "%(count)s Members|one": "%(count)s Membro", "Event sent!": "Evento enviado!", "View Source": "Ver fonte", - "Matrix technical discussions": "Discusións técnicas sobre Matrix", "Event Content": "Contido do evento", "Thank you!": "Grazas!", - "Building services on Matrix": "Deseñando servizos sobre Matrix", "Collapse panel": "Agochar panel", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Co seu navegador actual a apareciencia e uso do aplicativo poderían estar totalmente falseadas, e algunhas características poderían non funcionar. Se quere pode continuar, pero debe ser consciente de que poden haber fallos!", "Checking for an update...": "Comprobando as actualizacións...", - "General discussion about Matrix and Riot": "Discusión xeral sobre Matrix e Riot", "There are advanced notifications which are not shown here": "Existen notificacións avanzadas que non se mostran aquí" } diff --git a/src/i18n/strings/he.json b/src/i18n/strings/he.json index dd9219a776..9543a64b8f 100644 --- a/src/i18n/strings/he.json +++ b/src/i18n/strings/he.json @@ -88,8 +88,6 @@ "No rooms to show": "אין חדרים להצגה", "Fetching third party location failed": "נסיון להביא מיקום צד שלישי נכשל", "A new version of Riot is available.": "יצאה גרסה חדשה של Riot.", - "Riot/Android & matrix-android-sdk chat": "Riot/Android & צ'ט matrix-android-sdk", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "נא תאר את הבאג. מה עשית? מה ציפית שיקרה? מה קרה בפועל?", "Couldn't load home page": "כשל בטעינת דף הבית", "Send Account Data": "שלח נתוני משתמש", "All notifications are currently disabled for all targets.": "התראות מנוטרלות לכלל המערכת.", @@ -100,12 +98,9 @@ "Failed to set direct chat tag": "נכשל בעת סימון תג לשיחה ישירה", "Today": "היום", "Files": "קבצים", - "Report a bug": "דווח על שגיאה", - "Implementing VR services with Matrix": "מימוש שירותי VR ב Matrix", "You are not receiving desktop notifications": "אתה לא מקבל התראות משולחן העבודה", "Friday": "שישי", "Update": "עדכון", - "You need to be using HTTPS to place a screen-sharing call.": "עליך להשתמש ב HTTPS בכדי לבצע שיחת ווידאו משותפת.", "What's New": "מה חדש", "Add an email address above to configure email notifications": "הוסף כתובת דואר אלקטורני למעלה בכדי להגדיר התראות", "Expand panel": "הרחב מסגרת", @@ -113,18 +108,14 @@ "%(count)s Members|other": "‭ ‭ ‮‭ םישמתשמ %(count)s", "Filter room names": "סנן שמות חדרים", "Changelog": "דו\"ח שינויים", - "Running Matrix services": "שירותי ה Matrix שרצים", "Waiting for response from server": "ממתין לתשובה מהשרת", "Send Custom Event": "שלח אירוע מותאם אישית", - "Failed to send report: ": "נכשל בעת שליחת דו\"ח: ", - "Unknown device": "מכשיר לא ידוע", "Advanced notification settings": "הגדרות מתקדמות להתראות", "Failed to send logs: ": "כשל במשלוח יומנים: ", "delete the alias.": "מחיקת כינוי.", "To return to your account in future you need to set a password": "להשתמש בחשבונך בעתיד, עליך להגדיר סיסמא", "Forget": "שכח", "#example": "#דוגמא", - "Riot/Web & Desktop chat": "Riot/Web & צ'ט שולחן עבודה", "Hide panel": "הסתר מסגרת", "You cannot delete this image. (%(code)s)": "אי אפשר למחוק את התמונה. (%(code)s)", "Cancel Sending": "ביטול שליחה", @@ -134,9 +125,7 @@ "Error saving email notification preferences": "שגיאה בעת שמירת הגדרות התראה באמצעות הדואר האלקטרוני", "Messages containing my display name": "הודעות המכילות את שם התצוגה שלי", "Messages in one-to-one chats": "הודעות בשיחות פרטיות", - "Contributing code to Matrix and Riot": "תרומת קוד ל Matrix ו Riot", "Unavailable": "לא זמין", - "Community-run support for Synapse": "תמיכת הקהילה עבור Synapse", "View Decrypted Source": "הצג מקור מפוענח", "Failed to update keywords": "נכשל עדכון מילים", "Notes:": "הערות:", @@ -145,9 +134,6 @@ "Safari and Opera work too.": "Safari וגם Opera עובדים.", "Please set a password!": "נא להגדיר סיסמא!", "You have successfully set a password!": "שינוי סיסמא בוצע בהצלחה!", - "Chat with Riot Bot": "שיחה עם Riot בוט", - "Support for those using, running and writing other bridges": "שירות למשתמשים, שמריצים וכותבים חיבורים נוספים", - "Admin support for Dendrite": "תמיכת מנהל מערכת עבור Dendrite", "An error occurred whilst saving your email notification preferences.": "קרתה שגיאה בזמן שמירת הגדרות התראה באמצעות הדואר האלקטרוני.", "Explore Room State": "גלה מצב החדר", "Source URL": "כתובת URL אתר המקור", @@ -155,15 +141,11 @@ "Filter results": "סנן התוצאות", "Members": "חברים", "No update available.": "אין עדכון זמין.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "הרבה חדרים כבר קיימים ב Matrix ומקושרים לרשתות קיימות (Slack, IRC, Gitter וכו') או עצמאיים. בדוק את הספרייה!", "Resend": "שלח מחדש", "Failed to get protocol list from Home Server": "נכשל בעת נסיון קבלת רשימת פרוטוקולים משרת הבית", "Collecting app version information": "אוסף מידע על גרסת היישום", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "מחק כינוי %(alias)s של החדר והסר את %(name)s מהרשימה?", - "customServer_text": "אפשר להשתמש בהגדרות שרת מותאמות אישית בכדי להתחבר לשרתים אחרים באמצעות בחירת כתובת שרת בית שונה.
    זה יאפשר לך להשתמש ב Riot עם חשבון קיים ב Matrix אבל אל מול שרת בית שונה.

    כמו כן אפשר להגדיר זהות מותאמת אישית אבל אז לא תהיה אפשרות להזמין משתמשים באמצעות כתובת אימייל, או להזמין את עצמך באמצעות כתובת האימייל.", - "Co-ordination for Riot/Web translators": "תאום למתרגמי ה Riot/Web", "This will allow you to return to your account after signing out, and sign in on other devices.": "זה יאפשר לך לחזור לחשבונך אחרי התנתקות ולהתחבר באמצעות התקנים אחרים.", - "Dev chat for the Dendrite dev team": "שיחת מפתחים עבור Dendrite", "Keywords": "מילות מפתח", "Enable notifications for this account": "אפשר התראות לחשבון זה", "Directory": "ספרייה", @@ -188,15 +170,11 @@ "Direct Chat": "שיחה ישירה", "The server may be unavailable or overloaded": "השרת אינו זמין או עמוס", "Reject": "דחה", - "Riot is not supported on mobile web. Install the app?": "Riot לא נתמך באמצעות דפדפן במכשיר הסלולארי. האם להתקין את היישום?", - "Discussion of all things Matrix!": "דיון על כל הדברים הקשורים ל Matrix!", "Failed to set Direct Message status of room": "נכשל בעת סימון מצב הודעה ישירה של החדר", "Monday": "שני", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "בכדי לנתח את הבעיות, ישלח דוח עם פרטי הבעיה. אם ברצונך רק לשלוח את שנאמר למעלה, נא הסר את הסימון:", "Remove from Directory": "הסר מהרשימה", "Enable them now": "אפשר אותם כעת", "Messages containing my user name": "הודעות המכילות את שם המשתמש שלי", - "Describe your problem here.": "תאר את הבעיה כאן.", "Toolbox": "תיבת כלים", "Collecting logs": "אוסף יומנים לנפוי שגיאה (דבאג)", "more": "עוד", @@ -211,47 +189,31 @@ "Quote": "ציטוט", "Send logs": "שלח יומנים", "All messages": "כל ההודעות", - "Implementing VoIP services with Matrix": "מימוש Voip ב Matrix", - "Dev chat for the Riot/Web dev team": "שיחה עם המפתחים עבור ה קבוצת הפיתוח של Riot/Web", "Call invitation": "הזמנה לשיחה", - "Riot Desktop on %(platformName)s": "רייוט לשולחן העבודה על גבי %(platformName)s", "Downloading update...": "מוריד עדכון...", "You have successfully set a password and an email address!": "הצלחת להגדיר סיסמא וכתובת אימייל!", "Failed to send custom event.": "כשל במשלוח ארוע מותאם אישית.", "What's new?": "מה חדש?", - "Discussion of the Identity Service API": "דיון על API לשירות זהויות", - "Support for those using and running matrix-appservice-irc": "תמיכה למשתמשים ב matrix-appservice-irc", - "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & שיחה עם matrix-ios-sdk", "Notify me for anything else": "התראה לי על כל דבר אחר", "When I'm invited to a room": "מתי אני מוזמן לחדר", - "Design and implementation of E2E in Matrix": "תכנון וביצוע קצה לקצה ב Matrix", "Click here to create a GitHub issue.": "הקלק כאן ליצירת דווח תקלה ‫ב: GitHub .", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "בכדי להיכנס לשרתים אחרים של מטריקס, אפשר להגדיר כתובת מוצא ראשית אחרת ל- URL שרתי מטריקס, בהגדרות: 'התאמה אישית לאפשרויות שרת'.
    ואז מתאפשר למשתמש ריוט לנצל חשבון משתמש מטריקס קיים, בשרתי מטריקס שונים.

    אפשר גם להגדיר בהתאמה אישית שרת הזדהות. אך אז לא ניתן להזמין משתמשים באימייל, ואי אפשר להזמינך באמצעות אימייל.", "Can't update user notification settings": "לא ניתן לעדכן הגדרות התראה למשתמש", "Notify for all other messages/rooms": "התראה לכל שאר ההודעות/החדרים", "Unable to look up room ID from server": "לא ניתן לאתר מזהה חדר על השרת", "Couldn't find a matching Matrix room": "לא נמצא חדר כזה ב מטריקס", - "Support for those using the Matrix spec": "תמיכה למשתמשים במאפייני ה Matrix", - "
    Safari and Opera work too.": " ספארי ו אופרה עובדים גם כן.", - "Loading bug report module": "טוען רכיב דיווח דו\"ח שגיאה", "Invite to this room": "הזמן לחדר זה", "You cannot delete this message. (%(code)s)": "לא ניתן למחוק הודעה זו. (%(code)s)", "Thursday": "חמישי", "Search…": "חפש…", "Logs sent": "יומנים נשלחו", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s באמצעות הדפדפן %(browserName)s על גבי %(osName)s", "Back": "אחורה", "Reply": "תשובה", "Show message in desktop notification": "הצג הודעה בהתראות שולחן עבודה", "You must specify an event type!": "חובה להגדיר סוג ארוע!", "Unhide Preview": "הצג מחדש תצוגה מקדימה", - "Announcements about Synapse releases": "הודעות לגבי גרסאות Synapse", - "Search the room directory": "חפש בספריית החדרים", - "Please describe the bug and/or send logs.": "נא תאר את הבאג ו/או שלח את הלוגים.", "Unable to join network": "לא ניתן להצטרף לרשת", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "יתכן כי בצעת את ההגדרות בצד לקוח ולא ב Riot. לא תוכל לעדכן אותם ב Riot אבל הם עדיין תקפים", "Sorry, your browser is not able to run Riot.": "מצטערים, הדפדפן שלך הוא אינו יכול להריץ את Riot.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "צ'ט מוצפן & ושת\"פ נעשה ע\"י ה [matrix]", "Uploaded on %(date)s by %(user)s": "עודכן ב %(date)s ע\"י %(user)s", "Messages in group chats": "הודעות בקבוצות השיחה", "Yesterday": "אתמול", @@ -260,17 +222,14 @@ "Low Priority": "עדיפות נמוכה", "Unable to fetch notification target list": "לא ניתן לאחזר רשימת יעדי התראה", "Appear Offline": "מופיע מקוון", - "Get started with some tips from Riot Bot!": "התחל באמצעות מספר טיפים מהבוט של Riot!", "Set Password": "הגדר סיסמא", "Enable audible notifications in web client": "אפשר התראות קוליות בדפדפן", "Permalink": "קישור קבוע", - "Welcome to Riot.im": "ברוכים הבאים ל Riot.im", "Off": "סגור", "Riot does not know how to join a room on this network": "Riot אינו יודע כיצד להצטרף לחדר ברשת זו", "Mentions only": "מאזכר בלבד", "Failed to remove tag %(tagName)s from room": "נכשל בעת נסיון הסרת תג %(tagName)s מהחדר", "You can now return to your account after signing out, and sign in on other devices.": "תוכל עתה לחזור לחשבון שלך רק אחרי התנתקות וחיבור מחדש לחשבון ממכשיר אחר.", - "Please install Chrome or Firefox for the best experience.": "נא התקן כרום או פיירפוקס לשימוש מייטבי.", "Enable email notifications": "אפשר התראות באמצעות הדואר האלקטרוני", "Event Type": "סוג ארוע", "Download this file": "הורד את הקובץ", @@ -280,13 +239,10 @@ "%(count)s Members|one": "‭ ‭ ‮‭ םישמתשמ %(count)s", "Developer Tools": "כלי מפתחים", "View Source": "הצג מקור", - "Matrix technical discussions": "פורום טכני של Matrix", "Event Content": "תוכן הארוע", "Thank you!": "רב תודות!", - "Building services on Matrix": "בניית שירותים על גבי ה Matrix", "Collapse panel": "סגור מסגרת", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "באמצעות הדפדפן הנוכחי שלך המראה של היישום יכול להיות שגוי לחלוטין וחלק מהאפשרויות לא תתפקדנה. אם תרצה לנסות בכל זאת תוכל אבל אז כל האחריות עליך!", "Checking for an update...": "בודק עדכונים...", - "General discussion about Matrix and Riot": "דיון כללי על Matrix ו Riot", "There are advanced notifications which are not shown here": "ישנן התראות מתקדמות אשר אינן מוצגות כאן" } diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 7140c6574c..a55a357a55 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -69,7 +69,6 @@ "Banned users": "Kitiltott felhasználók", "Bans user with given id": "Kitiltja a felhasználót a megadott ID-vel", "Blacklisted": "Fekete listára téve", - "Bug Report": "Hiba jelentés", "Bulk Options": "Tömeges beállítások", "Call Timeout": "Hívás időtúllépés", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Nem lehet kapcsolódni a saját szerverhez - ellenőrizd a kapcsolatot, biztosítsd, hogy a saját szerver tanúsítványa hiteles legyen, és a böngésző kiterjesztések ne blokkolják a kéréseket.", @@ -192,7 +191,6 @@ "Forgot your password?": "Elfelejtetted a jelszavad?", "For security, this session has been signed out. Please sign in again.": "A biztonság érdekében ez a kapcsolat le lesz bontva. Légy szíves jelentkezz be újra.", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "A biztonság érdekében a kilépéskor a ponttól pontig való (E2E) titkosításhoz szükséges kulcsok törlésre kerülnek a böngészőből. Ha a régi üzeneteket továbbra is el szeretnéd olvasni, kérlek mentsed ki a szobákhoz tartozó kulcsot.", - "Found a bug?": "Hibát találtál?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s : %(fromPowerLevel)s -> %(toPowerLevel)s", "Guest access is disabled on this Home Server.": "Vendég belépés tiltva van a Saját szerveren.", "Guests cannot join this room even if explicitly invited.": "Vendégek akkor sem csatlakozhatnak ehhez a szobához ha külön meghívók kaptak.", @@ -309,7 +307,6 @@ "%(senderName)s removed their profile picture.": "%(senderName)s törölte a profil képét.", "Remove %(threePid)s?": "Töröl: %(threePid)s?", "%(senderName)s requested a VoIP conference.": "%(senderName)s VoIP konferenciát kezdeményez.", - "Report it": "Jelent", "Results from DuckDuckGo": "Eredmények a DuckDuckGo-ból", "Return to login screen": "Vissza a bejelentkezési képernyőre", "Riot does not have permission to send you notifications - please check your browser settings": "Riotnak nincs jogosultsága értesítést küldeni neked - ellenőrizd a böngésző beállításait", @@ -652,13 +649,11 @@ "Define the power level of a user": "A felhasználó szintjének meghatározása", "Edit": "Szerkeszt", "Enable automatic language detection for syntax highlighting": "Nyelv automatikus felismerése szintaxis kiemeléshez", - "Hide Apps": "Alkalmazások elrejtése", "Hide join/leave messages (invites/kicks/bans unaffected)": "Belép/kilép üzenetek elrejtése (meghívók, kirúgások, kitiltások nem érintettek)", "AM": "de", "PM": "du", "Revoke widget access": "Kisalkalmazás hozzáférésének visszavonása", "Sets the room topic": "Szoba téma beállítás", - "Show Apps": "Alkalmazások mutatása", "To get started, please pick a username!": "Az induláshoz válassz egy felhasználói nevet!", "Unable to create widget.": "Nem lehet kisalkalmazást létrehozni.", "Unbans user with given id": "Visszaengedi a megadott azonosítójú felhasználót", @@ -719,7 +714,6 @@ "Description": "Leírás", "Name or matrix ID": "Név vagy Matrix azonosító", "Unable to accept invite": "A meghívót nem lehet elfogadni", - "Unable to leave room": "A szobát nem lehet elhagyni", "Leave": "Elhagy", "Failed to invite the following users to %(groupId)s:": "Az alábbi felhasználókat nem sikerült meghívni a(z) %(groupId)s:", "Failed to invite users to %(groupId)s": "Nem sikerült meghívni a felhasználókat ebbe a csoportba: %(groupId)s", @@ -992,7 +986,6 @@ "Key request sent.": "Kulcs kérés elküldve.", "Re-request encryption keys from your other devices.": "Kulcsok újrakérése a többi eszközödtől.", "%(user)s is a %(userRole)s": "%(user)s egy %(userRole)s", - "Changes made to your community might not be seen by other users for up to 30 minutes.": "A közösségedben végrehajtott változtatás valószínűleg legalább 30 percig nem lesz látható mások számára.", "Code": "Kód", "Debug Logs Submission": "Hibakeresési napló elküldése", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Ha a GitHubon keresztül küldted be a hibát, a hibakeresési napló segíthet nekünk a javításban. A napló felhasználási adatokat tartalmaz mint a felhasználói neved, az általad meglátogatott szobák vagy csoportok azonosítóját vagy alternatív nevét és mások felhasználói nevét. De nem tartalmazzák az üzeneteket.", @@ -1007,19 +1000,13 @@ "Stickerpack": "Matrica csomag", "Sticker Messages": "Matrica üzenetek", "You don't currently have any stickerpacks enabled": "Nincs engedélyezett matrica csomagod", - "Click": "Kattints", - "here": "ide", - "to add some!": "hogy adj hozzá párat!", "Add a stickerpack": "Matrica csomag hozzáadása", "Hide Stickers": "Matricák elrejtése", "Show Stickers": "Matricák megjelenítése", - "Manage sticker packs": "Matrica csomagok kezelése", "Who can join this community?": "Ki tud csatlakozni ehhez a közösséghez?", "Everyone": "Mindenki", "Fetching third party location failed": "Nem sikerült lekérdezni a harmadik fél helyét", "A new version of Riot is available.": "Elérhető egy új Riot verzió.", - "Riot/Android & matrix-android-sdk chat": "Riot/Android és matrix-android-sdk csevegés", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Kérünk, írd le a hibát. Mit csináltál? Minek kellett volna történnie? Mi történt végül?", "Couldn't load home page": "Nem sikerült betölteni a kezdőlapot", "Send Account Data": "Fiókadatok küldése", "All notifications are currently disabled for all targets.": "Minden céleszközön minden értesítés tiltva van.", @@ -1028,12 +1015,9 @@ "Notification targets": "Értesítések célpontja", "Today": "Ma", "Files": "Fájlok", - "Report a bug": "Hiba bejelentése", - "Implementing VR services with Matrix": "VR szolgáltatások implementációja Matrixba", "You are not receiving desktop notifications": "Nem fogadsz asztali értesítéseket", "Friday": "Péntek", "Update": "Frissítés", - "You need to be using HTTPS to place a screen-sharing call.": "Képernyőmegosztás indításához HTTPS-t kell használnod.", "What's New": "Újdonságok", "Add an email address above to configure email notifications": "E-mail értesítések beállításához adj meg egy e-mail címet", "Expand panel": "Panel kinyitása", @@ -1041,18 +1025,14 @@ "%(count)s Members|other": "%(count)s tag", "Filter room names": "Szobanevek szűrése", "Changelog": "Változások", - "Running Matrix services": "Matrix szolgáltatások működtetése", "Waiting for response from server": "Várakozás a szerver válaszára", "Send Custom Event": "Egyéni esemény elküldése", - "Failed to send report: ": "A jelentést nem sikerült elküldeni: ", - "Unknown device": "Ismeretlen készülék", "Advanced notification settings": "Haladó értesítési beállítások", "Failed to send logs: ": "Hiba a napló küldésénél: ", "delete the alias.": "becenév törlése.", "To return to your account in future you need to set a password": "Hogy később visszaléphess a fiókodba, be kell állítanod egy jelszót", "Forget": "Elfelejt", "#example": "#példa", - "Riot/Web & Desktop chat": "Riot/Web és Desktop csevegés", "Hide panel": "Panel elrejtése", "You cannot delete this image. (%(code)s)": "Nem törölheted ezt a képet. (%(code)s)", "Cancel Sending": "Küldés megszakítása", @@ -1062,9 +1042,7 @@ "Room not found": "A szoba nem található", "Messages containing my display name": "A profilnevemet tartalmazó üzenetek", "Messages in one-to-one chats": "Személyes beszélgetések üzenetei", - "Contributing code to Matrix and Riot": "Hozzájárulás a Matrix és Riot programkódjának fejlesztéséhez", "Unavailable": "Elérhetetlen", - "Community-run support for Synapse": "Közösségi támogatás a Synapse-hez", "View Decrypted Source": "Visszafejtett forrás megjelenítése", "Failed to update keywords": "Nem lehet frissíteni a kulcsszavakat", "Notes:": "Jegyzetek:", @@ -1073,9 +1051,6 @@ "Safari and Opera work too.": "Safarival és Operával is működik.", "Please set a password!": "Állíts be egy jelszót!", "You have successfully set a password!": "Sikerült beállítani a jelszót!", - "Chat with Riot Bot": "Csevegés a Riot Robottal", - "Support for those using, running and writing other bridges": "Támogatás azoknak, akik egyéb hidakat használnak, működtetnek vagy készítenek", - "Admin support for Dendrite": "Admin támogatás a Dendrite-hoz", "An error occurred whilst saving your email notification preferences.": "Hiba történt az e-mail értesítési beállításaid mentése közben.", "Explore Room State": "Szoba állapot felderítése", "Source URL": "Forrás URL", @@ -1083,15 +1058,11 @@ "Filter results": "Találatok szűrése", "Members": "Résztvevők", "No update available.": "Nincs elérhető frissítés.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Már sok szoba van a Matrixon: más hálózatokkal (Slack, IRC, Gitter stb.) összekapcsolt és függetlenek szobák is. Nézd meg a szobajegyzéket!", "Noisy": "Hangos", "Failed to get protocol list from Home Server": "Nem sikerült a protokoll listát lekérni a saját szerverről", "Collecting app version information": "Alkalmazás verzió információk összegyűjtése", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Törlöd a szoba nevét (%(alias)s) és eltávolítod a listából ezt: %(name)s?", - "customServer_text": "Egyedi Matrix szervert használhatsz a Saját szerver URL beállításával.
    Ezzel meglévő Matrix fiókot használhatsz Riot klienssel és egyedi szerverrel.

    Beállíthatsz egyedi \"identity\" szervert de akkor nem tudsz e-maillel meghívni felhasználót és téged sem tudnak meghívni e-maillel.", - "Co-ordination for Riot/Web translators": "Egyeztetés a Riot/Web fordítóival", "This will allow you to return to your account after signing out, and sign in on other devices.": "Így kijelentkezés után is vissza tudsz lépni a fiókodba, illetve más készülékekről is be tudsz lépni.", - "Dev chat for the Dendrite dev team": "Csevegés a Dendrite fejlesztői csapatával fejlesztőknek", "Keywords": "Kulcsszavak", "Enable notifications for this account": "Értesítések engedélyezése ehhez a fiókhoz", "Directory": "Könyvtár", @@ -1117,16 +1088,11 @@ "Direct Chat": "Közvetlen csevegés", "The server may be unavailable or overloaded": "A szerver nem elérhető vagy túlterhelt", "Reject": "Elutasít", - "Riot is not supported on mobile web. Install the app?": "A mobilböngésző nem támogatja a Riotot. Telepíted inkább az alkalmazást?", - "Discussion of all things Matrix!": "Beszélgetés mindenről, ami Matrix!", "Failed to set Direct Message status of room": "Nem lehet beállítani a szoba közvetlen beszélgetés státuszát", "Monday": "Hétfő", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "A hibajelentésben naplófájlokat küldünk erről a kliensről, hogy feltárjuk a hibákat. Ha inkább csak a fenti szöveget szeretnéd elküldeni, töröld a pipát:", - "Send Custom State Event": "Egyéni állapot esemény küldése", "All messages (noisy)": "Minden üzenet (hangos)", "Enable them now": "Engedélyezés most", "Messages containing my user name": "A felhasználónevemet tartalmazó üzenetek", - "Describe your problem here.": "Írd le ide a problémádat.", "Toolbox": "Eszköztár", "Collecting logs": "Naplók összegyűjtése", "more": "tovább", @@ -1140,47 +1106,31 @@ "Quote": "Idéz", "Send logs": "Naplófájlok elküldése", "All messages": "Minden üzenet", - "Implementing VoIP services with Matrix": "VoIP szolgáltatások implementációja Matrixba", - "Dev chat for the Riot/Web dev team": "Csevegés a Riot/Web fejlesztői csapatával fejlesztőknek", "Call invitation": "Hívás meghívó", - "Riot Desktop on %(platformName)s": "Riot Desktop itt: %(platformName)s", "Downloading update...": "Frissítés letöltése...", "State Key": "Állapotkulcs", "Failed to send custom event.": "Nem sikerült elküldeni az egyéni eseményt.", "What's new?": "Mik az újdonságok?", - "Discussion of the Identity Service API": "Beszélgetés az Identity Service API-ról", - "Support for those using and running matrix-appservice-irc": "Támogatás a matrix-appservice-irc használóinak és működtetőinek", - "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS és matrix-ios-sdk csevegés", "Notify me for anything else": "Értesíts minden egyéb esetben", "When I'm invited to a room": "Amikor meghívnak egy szobába", - "Design and implementation of E2E in Matrix": "A végponttól végpontig történő titkosítás (E2E) tervezése és implementációja a Matrixban", "Click here to create a GitHub issue.": "Kattints ide GitHub hibajegy nyitásához .", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Az egyedi szerverbeállításoknál megadhatod egy másik szerver URL-jét, így be tudsz jelentkezni más Matrix szerverre is.
    Így a Riotot tudod használni egy már máshol meglévő Matrix fiókkal is.

    Beállíthatsz egyéni identitásszervert is, de akkor nem tudsz más felhasználókat e-mail címmel meghívni, illetve ők sem tudnak téged.", "Can't update user notification settings": "Nem lehet frissíteni az értesítési beállításokat", "Notify for all other messages/rooms": "Értesítés minden más üzenethez/szobához", "Unable to look up room ID from server": "Nem lehet a szoba azonosítóját megkeresni a szerveren", "Couldn't find a matching Matrix room": "Nem található a keresett Matrix szoba", - "Support for those using the Matrix spec": "Támogatás a Matrix specifikáció használóinak", - "Safari and Opera work too.": "Safarival és Operaval is működik.", - "Loading bug report module": "Hibabejelentő modul betöltése", "All Rooms": "Minden szobában", "You cannot delete this message. (%(code)s)": "Nem törölheted ezt az üzenetet. (%(code)s)", "Thursday": "Csütörtök", "Search…": "Keresés…", "Logs sent": "Napló elküldve", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s alkalmazás %(browserName)s böngészőn %(osName)s rendszeren", "Back": "Vissza", "Reply": "Válasz", "Show message in desktop notification": "Üzenetek megjelenítése az asztali értesítéseknél", "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "A hibakereső napló alkalmazás használati adatokat tartalmaz beleértve a felhasználói nevedet, az általad meglátogatott szobák és csoportok azonosítóit alternatív neveit és más felhasználói neveket. Csevegés üzenetek szövegét nem tartalmazza.", "Unhide Preview": "Előnézet mutatása", - "Announcements about Synapse releases": "Hírek a Synapse kiadásairól", - "Search the room directory": "Keresés a szobajegyzékben", - "Please describe the bug and/or send logs.": "Kérünk, írd le a hibát és/vagy küldd el a naplófájlokat.", "Unable to join network": "Nem sikerült kapcsolódni a hálózathoz", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Egy másik, nem Riot-klienssel állítothattad be. A Riotban módosítani nem tudod ezeket, de érvényben vannak", "Sorry, your browser is not able to run Riot.": "Elnézést, a böngésződben nem fut a Riot.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Decentralizált, titkosított csevegés és kollaboráció [matrix] alapokon", "Uploaded on %(date)s by %(user)s": "Feltöltötte %(user)s ekkor: %(date)s", "Messages in group chats": "Csoportszobák üzenetei", "Yesterday": "Tegnap", @@ -1189,17 +1139,14 @@ "Low Priority": "Alacsony prioritás", "Unable to fetch notification target list": "Nem sikerült letölteni az értesítési célok listáját", "Appear Offline": "Offline látszik", - "Get started with some tips from Riot Bot!": "Kezdj a Riot Robot néhány tippjével!", "Set Password": "Jelszó beállítása", "Enable audible notifications in web client": "Hangértesítések engedélyezése a webkliensben", "Permalink": "Állandó hivatkozás", - "Welcome to Riot.im": "Üdvözöl a Riot.im", "Off": "Ki", "Riot does not know how to join a room on this network": "A Riot nem tud csatlakozni szobához ezen a hálózaton", "Mentions only": "Csak ha megemlítenek", "Wednesday": "Szerda", "You can now return to your account after signing out, and sign in on other devices.": "Most már kijelentkezés után is vissza tudsz lépni a fiókodba, és más készülékekről is be tudsz lépni.", - "Please install Chrome or Firefox for the best experience.": "A legjobb élmény érdekében telepíts Chromeot vagy Firefoxot.", "Enable email notifications": "E-mail értesítések engedélyezése", "Event Type": "Esemény típusa", "Download this file": "Fájl letöltése", @@ -1209,13 +1156,10 @@ "%(count)s Members|one": "%(count)s tag", "Event sent!": "Az esemény elküldve!", "View Source": "Forrás megjelenítése", - "Matrix technical discussions": "Technikai jellegű beszélgetések a Matrixról", "Event Content": "Esemény tartalma", "Thank you!": "Köszönjük!", - "Building services on Matrix": "Szolgáltatások fejlesztése Matrixra", "Collapse panel": "Panel becsukása", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Ebben a böngészőben az alkalmazás felülete tele lehet hibával, és az is lehet, hogy egyáltalán nem működik. Ha így is ki szeretnéd próbálni, megteheted, de ha valami gondod van, nem tudunk segíteni!", "Checking for an update...": "Frissítés keresése...", - "General discussion about Matrix and Riot": "Általános beszélgetések a Matrixról és a Riotról", "There are advanced notifications which are not shown here": "Vannak itt nem látható, haladó értesítések" } diff --git a/src/i18n/strings/id.json b/src/i18n/strings/id.json index 0f0e2c2b48..5eccf72100 100644 --- a/src/i18n/strings/id.json +++ b/src/i18n/strings/id.json @@ -13,7 +13,6 @@ "Are you sure?": "Anda yakin?", "An error has occurred.": "Telah terjadi kesalahan.", "Are you sure you want to reject the invitation?": "Anda yakin menolak undangannya?", - "Bug Report": "Laporan Bug", "Can't load user settings": "Tidak dapat memuat pengaturan pengguna", "Change Password": "Ubah Password", "Click here to fix": "Klik di sini untuk perbaiki", @@ -56,7 +55,6 @@ "Favourite": "Favorit", "Favourites": "Favorit", "Forgot your password?": "Lupa password?", - "Found a bug?": "Menemukan bug?", "Import": "Impor", "Incorrect verification code": "Kode verifikasi tidak benar", "Invalid Email Address": "Alamat email tidak benar", @@ -88,7 +86,6 @@ "Public Chat": "Obrolan Publik", "Reason": "Alasan", "Register": "Registrasi", - "Report it": "Laporkan", "riot-web version:": "riot-web versi:", "Return to login screen": "Kembali ke halaman masuk", "Room Colour": "Warna Ruang", @@ -204,8 +201,6 @@ "Bans user with given id": "Blokir pengguna dengan id", "Fetching third party location failed": "Gagal mengambil lokasi pihak ketiga", "A new version of Riot is available.": "Riot versi baru telah tersedia.", - "Riot/Android & matrix-android-sdk chat": "Obrolan Riot/Android & matrix-android-sdk", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Harap jelaskan bug. Apa yang Anda lakukan? Apa yang Anda harap terjadi? Apa yang sebenarnya terjadi?", "Couldn't load home page": "Tidak dapat memuat halaman utama", "All notifications are currently disabled for all targets.": "Semua notifikasi saat ini dinonaktifkan untuk semua target.", "Uploading report": "Unggah laporan", @@ -216,31 +211,24 @@ "Failed to set direct chat tag": "Gagal mengatur tag obrolan langsung", "Today": "Hari Ini", "Failed to get protocol list from Home Server": "Gagal mendapatkan daftar protokol dari Server Home", - "Report a bug": "Laporkan bug", - "Implementing VR services with Matrix": "Implementasi layanan VR dengan Matrix", "You are not receiving desktop notifications": "Anda tidak menerima notifikasi desktop", "Dismiss": "Abaikan", "Update": "Perbarui", "Notifications": "Notifikasi", - "You need to be using HTTPS to place a screen-sharing call.": "Anda perlu menggunakan HTTPS untuk melakukan panggilan berbagi-layar.", "What's New": "Apa Yang Baru", "Add an email address above to configure email notifications": "Tambahkan alamat email di atas untuk konfigurasi notifikasi email", "Expand panel": "Luaskan panel", "On": "Nyala", "Filter room names": "Saring nama ruang", "Changelog": "Daftar perubahan", - "Running Matrix services": "Mengoperasikan layanan Matrix", "Waiting for response from server": "Menunggu respon dari server", "Leave": "Tinggalkan", - "Failed to send report: ": "Gagal mengirim laporan: ", - "Unknown device": "Perangkat Tidak Diketahui", "Advanced notification settings": "Pengaturan notifikasi lanjutan", "delete the alias.": "hapus alias.", "To return to your account in future you need to set a password": "Untuk kembali ke akun di lain waktu, Anda perlu mengisi password", "Forget": "Lupakan", "World readable": "Terpublikasi Umum", "#example": "#contoh", - "Riot/Web & Desktop chat": "Obrolan Riot/Web & Desktop", "Hide panel": "Sembunyikan panel", "You cannot delete this image. (%(code)s)": "Anda tidak dapat menghapus gambar ini. (%(code)s)", "Cancel Sending": "Batalkan pengiriman", @@ -251,9 +239,7 @@ "Error saving email notification preferences": "Terjadi kesalahan saat menyimpan pilihan notifikasi email", "Messages containing my display name": "Pesan mengandung nama tampilan saya", "Messages in one-to-one chats": "Pesan di obrolan satu-ke-satu", - "Contributing code to Matrix and Riot": "Kontribusi kode untuk Matrix dan Riot", "Unavailable": "Tidak Tersedia", - "Community-run support for Synapse": "Dukungan komunitas untuk Synapse", "View Decrypted Source": "Tampilkan Sumber Terdekripsi", "Failed to update keywords": "Gagal memperbarui kata kunci", "remove %(name)s from the directory.": "hapus %(name)s dari direktori.", @@ -261,25 +247,17 @@ "Please set a password!": "Mohon isi password!", "powered by Matrix": "didukung oleh Matrix", "You have successfully set a password!": "Anda berhasil mengubah password!", - "Chat with Riot Bot": "Mengobrol dengan bot Riot", - "Support for those using, running and writing other bridges": "Dukungan untuk pengguna, penyedia dan penulis jembatan lainnya", - "Admin support for Dendrite": "Dukungan Admin untuk Dendrite", "An error occurred whilst saving your email notification preferences.": "Terjadi kesalahan saat menyimpan preferensi notifikasi email Anda.", "All Rooms": "Semua Ruang", "Source URL": "URL sumber", "Failed to add tag %(tagName)s to room": "Gagal menambahkan tag %(tagName)s ke ruang", "Members": "Anggota", "No update available.": "Tidak ada pembaruan.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Banyak ruang sudah tersedia di Matrix, terhubung ke jaringan yang sudah ada (Slack, IRC, Gitter dls) atau independen. Cek direktori!", "Resend": "Kirim Ulang", "Files": "Files", "Collecting app version information": "Mengumpukan informasi versi aplikasi", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Hapus alias ruang %(alias)s dan hapus %(name)s dari direktori?", - "customServer_text": "Anda dapat menggunakan opsi server khusus untuk masuk ke server Matrix lain dengan menyebutkan URL server Home.
    Hal ini memperbolehkan Anda untuk menggunakan Riot dengan akun Matrix yang sudah ada di server Home yang berbeda.

    Anda juga bisa mengatur server identitas khusus tapi Anda tidak akan dapat mengundang pengguna melalui alamat email, atau diundang dengan alamat email Anda.", - "Co-ordination for Riot/Web translators": "Koordinasi untuk penerjemah Riot/Web", "This will allow you to return to your account after signing out, and sign in on other devices.": "Hal ini akan memperbolehkan anda kembali ke akun setelah keluar dan masuk kembali di perangkat lain.", - "Dev chat for the Dendrite dev team": "Obrolan Developer untuk tim developer Dendrite", - "Design and implementation of E2E in Matrix": "Desain dan implementasi E2E di Matrix", "Enable notifications for this account": "Aktifkan notifikasi untuk akun ini", "Directory": "Direktori", "Failed to get public room list": "Gagal mendapatkan daftar ruang publik", @@ -300,15 +278,11 @@ "Direct Chat": "Obrolan Langsung", "The server may be unavailable or overloaded": "Server mungkin tidak tersedia atau kelebihan muatan", "Reject": "Tolak", - "Riot is not supported on mobile web. Install the app?": "Riot tidak mendukung web seluler. Install aplikasi?", - "Discussion of all things Matrix!": "Diskusi semua tentang Matrix!", "Failed to set Direct Message status of room": "Gagal mengatur status Pesan Langsung dari ruang", "Monday": "Senin", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Untuk diagnosis permasalahannya, catatan dari klien ini akan dikirimkan bersama laporan bug. Jika Anda memilih untuk hanya mengirimkan pesan di atas, mohon hapus centang:", "Remove from Directory": "Hapus dari DIrektori", "Enable them now": "Aktifkan sekarang", "Messages containing my user name": "Pesan mengandung nama pengguna saya", - "Describe your problem here.": "Jelaskan masalah anda di sini.", "Collecting logs": "Mengumpulkan catatan", "more": "lagi", "Bug report sent": "Laporan bug terkirim", @@ -321,42 +295,27 @@ "Error": "Terjadi Kesalahan", "Send logs": "Kirim catatan", "All messages": "Semua pesan", - "Implementing VoIP services with Matrix": "Implementasi layanan VoIP dengan Matrix", - "Dev chat for the Riot/Web dev team": "Obrolan Developer untuk tim developer Riot/Web", "Call invitation": "Undangan panggilan", - "Riot Desktop on %(platformName)s": "Riot Desktop di %(platformName)s", "Downloading update...": "Unduh pembaruan...", "You have successfully set a password and an email address!": "Anda telah berhasil mengubah password dan alamat email!", "What's new?": "Apa yang baru?", - "Discussion of the Identity Service API": "Diskusi tentang API Identity Service", - "Support for those using and running matrix-appservice-irc": "Dukungan untuk pengguna dan penyedia matrix-appservice-irc", - "Riot/iOS & matrix-ios-sdk chat": "Obrolan Riot/iOS & matrix-ios-sdk", "Notify me for anything else": "Beritau saya untuk lainnya", "When I'm invited to a room": "Ketika Saya diundang ke ruang", "Cancel": "Batal", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Anda dapat menggunakan opsi lain untuk mendaftar pada server Matrix yang berbeda dengan memasukkan URL server yang sesuai.
    Hal ini memungkinkan anda untuk menggunakan Riot dengan akun matrix yang telah tersedia pada Home server yang berbeda.

    Anda juga dapat melakukan pengubahan identitas server akan tetapi akan berakibat tidak dapat mengundang pengguna melalui email, atau diundang melalui email.", "Can't update user notification settings": "Tidak dapat memperbarui pengaturan notifikasi pengguna", "Notify for all other messages/rooms": "Beritau semua pesan/ruang", "Unable to look up room ID from server": "Tidak dapat mencari ID ruang dari server", "Couldn't find a matching Matrix room": "Tidak dapat menemukan ruang Matrix yang sesuai", - "Support for those using the Matrix spec": "Dukungan untuk pengguna Matrix spec", - "Safari and Opera work too.": "Safari dan Opera juga berfungsi.", - "Loading bug report module": "Memuat modul laporan bug", "Invite to this room": "Undang ke ruang ini", "Search for a room": "Cari ruang obrolan", "Thursday": "Kamis", "Forward Message": "Teruskan Pesan", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s melalui %(browserName)s di %(osName)s", "Back": "Kembali", "Show message in desktop notification": "Tampilkan pesan pada desktop", "Unhide Preview": "Tampilkan Pratinjau", - "Announcements about Synapse releases": "Pengumuman tentang rilis Synapse", - "Search the room directory": "Cari di direktori ruang", - "Please describe the bug and/or send logs.": "Harap jelaskan bug dan/atau kirim catatan.", "Unable to join network": "Tidak dapat bergabung di jaringan", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Anda mungkin sudah konfigurasi di klien selain Riot. Anda tidak dapat setel di Riot tetap berlaku", "Sorry, your browser is not able to run Riot.": "Maaf, browser Anda tidak dapat menjalankan Riot.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Obrolan terenkripsi, terdesentralisasi & kolaborasi didukung oleh [matrix]", "Uploaded on %(date)s by %(user)s": "Diunggah pada %(date)s oleh %(user)s", "Messages in group chats": "Pesan di obrolan grup", "Yesterday": "Kemarin", @@ -364,18 +323,15 @@ "Keywords": "Kata Kunci", "Low Priority": "Prioritas Rendah", "Unable to fetch notification target list": "Tidak dapat mengambil daftar notifikasi target", - "Get started with some tips from Riot Bot!": "Mulai dengan beberapa tip dari Bot Riot!", "Set Password": "Ubah Password", "Enable audible notifications in web client": "Aktifkan notifikasi suara di klien web", "Permalink": "Permalink", - "Welcome to Riot.im": "Selamat datang di Riot.im", "Off": "Mati", "Riot does not know how to join a room on this network": "Riot tidak tau bagaimana gabung ruang di jaringan ini", "Mentions only": "Hanya jika disinggung", "Failed to remove tag %(tagName)s from room": "Gagal menghapus tag %(tagName)s dari ruang", "Remove": "Hapus", "You can now return to your account after signing out, and sign in on other devices.": "Anda dapat kembali ke akun setelah keluar dan masuk kembali di perangkat lain.", - "Please install Chrome or Firefox for the best experience.": "Harap install Chrome atau Firefox untuk pengalaman terbaik.", "Enable email notifications": "Aktifkan notifikasi email", "Login": "Masuk", "No rooms to show": "Tidak ada ruang ditunjukkan", @@ -383,13 +339,10 @@ "Failed to change settings": "Gagal mengubah pengaturan", "Failed to change password. Is your password correct?": "Gagal untuk mengubah password. Apakah password Anda benar?", "View Source": "Tampilkan Sumber", - "Matrix technical discussions": "Diskusi teknis Matrix", "Custom Server Options": "Pilihan Server Khusus", "Thank you!": "Terima kasih!", - "Building services on Matrix": "Membangun layanan dengan Matrix", "Collapse panel": "Lipat panel", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Dengan browser ini, tampilan dari aplikasi mungkin tidak sesuai, dan beberapa atau bahkan semua fitur mungkin tidak berjalan. Jika Anda ingin tetap mencobanya, Anda bisa melanjutkan, tapi Anda tanggung sendiri jika muncul masalah yang terjadi!", "Checking for an update...": "Cek pembaruan...", - "General discussion about Matrix and Riot": "Diskusi umum tentang Matrix dan Riot", "There are advanced notifications which are not shown here": "Ada notifikasi lanjutan yang tidak ditampilkan di sini" } diff --git a/src/i18n/strings/it.json b/src/i18n/strings/it.json index e5ff92b7a8..0c07d83224 100644 --- a/src/i18n/strings/it.json +++ b/src/i18n/strings/it.json @@ -356,8 +356,6 @@ "Hangup": "Riaggancia", "Voice call": "Chiamata vocale", "Video call": "Chiamata video", - "Hide Apps": "Nascondi apps", - "Show Apps": "Mostra apps", "Upload file": "Invia file", "Show Text Formatting Toolbar": "Mostra barra di formattazione testo", "Send an encrypted reply…": "Invia una risposta criptata…", @@ -776,9 +774,7 @@ "Leave Community": "Esci dalla comunità", "Leave %(groupName)s?": "Uscire da %(groupName)s?", "Leave": "Esci", - "Unable to leave room": "Impossibile uscire dalla stanza", "Community Settings": "Impostazioni comunità", - "Changes made to your community might not be seen by other users for up to 30 minutes.": "Le modifiche fatte alla tua comunità potrebbero non essere visibili agli altri utenti per i prossimi 30 minuti.", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Queste stanze sono mostrate ai membri della comunità nella pagina della stessa. I membri della comunità possono entrare nelle stanze cliccandoci sopra.", "Featured Rooms:": "Stanze in evidenza:", "Featured Users:": "Utenti in evidenza:", @@ -992,12 +988,8 @@ "Failed to remove tag %(tagName)s from room": "Rimozione etichetta %(tagName)s dalla stanza fallita", "Failed to add tag %(tagName)s to room": "Aggiunta etichetta %(tagName)s alla stanza fallita", "Stickerpack": "Pacchetto adesivi", - "Click": "Clicca", - "here": "qui", - "to add some!": "per aggiungerne alcuni!", "Hide Stickers": "Nascondi gli adesivi", "Show Stickers": "Mostra gli adesivi", - "Manage sticker packs": "Gestisci pacchetti di adesivi", "Unable to join community": "Impossibile unirsi alla comunità", "Unable to leave community": "Impossibile uscire dalla comunità", "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Le modifiche al nome e all'avatar effettuate alla tua comunità potrebbero non essere visibili agli altri utenti per i prossimi 30 minuti.", @@ -1008,8 +1000,6 @@ "Add a stickerpack": "Aggiungi un pacchetto di adesivi", "Fetching third party location failed": "Rilevazione posizione di terze parti fallita", "A new version of Riot is available.": "È disponibile una nuova versione di Riot.", - "Riot/Android & matrix-android-sdk chat": "Chat su Riot/Android & matrix-android-sdk", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Per favore descrivi l'errore. Cosa hai fatto? Cosa ti aspettavi accadesse? Cos'è successo invece?", "Couldn't load home page": "Impossibile caricare la pagina principale", "Send Account Data": "Invia dati account", "Advanced notification settings": "Impostazioni di notifica avanzate", @@ -1018,12 +1008,9 @@ "Notification targets": "Obiettivi di notifica", "Today": "Oggi", "Files": "File", - "Report a bug": "Segnala un errore", - "Implementing VR services with Matrix": "Implementazione servizi VR con Matrix", "You are not receiving desktop notifications": "Non stai ricevendo le notifiche sul desktop", "Friday": "Venerdì", "Update": "Aggiornamento", - "You need to be using HTTPS to place a screen-sharing call.": "Devi usare HTTPS per utilizzare una chiamata con condivisione schermo.", "Riot does not know how to join a room on this network": "Riot non sa come entrare nella stanza su questa rete", "Add an email address above to configure email notifications": "Aggiungi un indirizzo email sopra per configurare le notifiche via email", "Expand panel": "Espandi il pannello", @@ -1031,17 +1018,13 @@ "%(count)s Members|other": "%(count)s membri", "Filter room names": "Filtra i nomi delle stanze", "Changelog": "Cambiamenti", - "Running Matrix services": "Esecuzione servizi Matrix", "Waiting for response from server": "In attesa di una risposta dal server", "Send Custom Event": "Invia Evento Personalizzato", - "Failed to send report: ": "Impossibile inviare il resoconto: ", - "Unknown device": "Dispositivo sconosciuto", "All notifications are currently disabled for all targets.": "Tutte le notifiche sono disabilitate per tutti gli obbiettivi.", "Failed to send logs: ": "Invio dei log fallito: ", "delete the alias.": "elimina l'alias.", "To return to your account in future you need to set a password": "Per tornare nel tuo account in futuro devi impostare una password", "Forget": "Dimentica", - "Riot/Web & Desktop chat": "Chat su Riot/Web & Desktop", "Hide panel": "Nascondi pannello", "You cannot delete this image. (%(code)s)": "Non puoi eliminare quest'immagine. (%(code)s)", "Cancel Sending": "Annulla invio", @@ -1051,9 +1034,7 @@ "Error saving email notification preferences": "Errore nel salvataggio delle preferenze di notifica email", "Messages containing my display name": "Messaggi contenenti il mio nome visualizzato", "Messages in one-to-one chats": "Messaggi in chat uno-a-uno", - "Contributing code to Matrix and Riot": "Contributi al codice di Matrix e Riot", "Unavailable": "Non disponibile", - "Community-run support for Synapse": "Supporto per Synapse dalla comunità", "View Decrypted Source": "Visualizza sorgente decifrato", "Failed to update keywords": "Impossibile aggiornare le parole chiave", "Notes:": "Note:", @@ -1062,9 +1043,6 @@ "Safari and Opera work too.": "Anche Safari e Opera vanno bene.", "Please set a password!": "Imposta una password!", "You have successfully set a password!": "Hai impostato una password con successo!", - "Chat with Riot Bot": "Chatta con Riot Bot", - "Support for those using, running and writing other bridges": "Supporto per chi usa, amministra e scrive altri bridge", - "Admin support for Dendrite": "Supporto amministrativo per Dendrite", "An error occurred whilst saving your email notification preferences.": "Si è verificato un errore durante il salvataggio delle tue preferenze sulle notifiche email.", "Explore Room State": "Esplora Stato Stanza", "Source URL": "URL d'origine", @@ -1072,15 +1050,11 @@ "Filter results": "Filtra risultati", "Members": "Membri", "No update available.": "Nessun aggiornamento disponibile.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Esistono già molte stanze in Matrix, collegate a reti già esistenti (Slack, IRC, Gitter ecc) o indipendenti. Dai un'occhiata all'elenco!", "Resend": "Reinvia", "Failed to get protocol list from Home Server": "Impossibile ottenere la lista di protocolli dal server Home", "Collecting app version information": "Raccolta di informazioni sulla versione dell'applicazione", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Eliminare l'alias %(alias)s e rimuovere %(name)s dalla lista?", - "customServer_text": "Puoi utilizzare un server personale per accedere su altri server Matrix specificando un diverso indirizzo URL per il server Home.
    Questo ti permetterà di usare Riot con un account Matrix già esistente su un altro server.

    Puoi anche specificare un diverso server di identità ma non sarai in grado di invitare utenti, o di essere invitato tramite indirizzo email.", - "Co-ordination for Riot/Web translators": "Coordinamento per i traduttori di Riot/Web", "This will allow you to return to your account after signing out, and sign in on other devices.": "Questo ti permetterà di ritornare al tuo account dopo esserti disconnesso e accedere in altri dispositivi.", - "Dev chat for the Dendrite dev team": "Chat per gli sviluppatori di Dendrite", "Keywords": "Parole chiave", "Enable notifications for this account": "Abilita le notifiche per questo account", "Directory": "Lista", @@ -1106,16 +1080,11 @@ "Direct Chat": "Chat Diretta", "The server may be unavailable or overloaded": "Il server potrebbe essere non disponibile o sovraccarico", "Reject": "Rifiuta", - "Riot is not supported on mobile web. Install the app?": "Riot non è supportato sul web mobile. Vuoi installare l'applicazione?", - "Discussion of all things Matrix!": "Discussione su tutto quanto riguardi Matrix!", "Failed to set Direct Message status of room": "Impossibile impostare lo stato di Messaggio Diretto alla stanza", "Monday": "Lunedì", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Per diagnosticare i problemi, i log da questo client verranno inviati con questo bug report. Se vuoi solo mandare il testo sopra, togli la spunta a:", - "Send Custom State Event": "Invia Evento di Stato Personalizzato", "Remove from Directory": "Rimuovi dalla lista", "Enable them now": "Abilitale adesso", "Messages containing my user name": "Messaggi contenenti il mio nome utente", - "Describe your problem here.": "Descrivi qui il tuo problema.", "Toolbox": "Strumenti", "Collecting logs": "Sto recuperando i log", "more": "altro", @@ -1130,48 +1099,32 @@ "Quote": "Cita", "Send logs": "Invia i log", "All messages": "Tutti i messaggi", - "Implementing VoIP services with Matrix": "Implementazione servizi VoIP con Matrix", - "Dev chat for the Riot/Web dev team": "Chat per gli sviluppatori di Riot/Web", "Call invitation": "Invito ad una chiamata", - "Riot Desktop on %(platformName)s": "Riot Desktop su %(platformName)s", "Downloading update...": "Scaricamento aggiornamento...", "State Key": "Chiave dello Stato", "Failed to send custom event.": "Impossibile inviare evento personalizzato.", "What's new?": "Cosa c'è di nuovo?", - "Discussion of the Identity Service API": "Discussione sull'Identity Service API", - "Support for those using and running matrix-appservice-irc": "Supporto per chi usa e amministra matrix-appservice-irc", - "Riot/iOS & matrix-ios-sdk chat": "Chat su Riot/iOS & matrix-ios-sdk", "Notify me for anything else": "Notificami per qualsiasi altra cosa", "When I'm invited to a room": "Quando vengo invitato/a in una stanza", - "Design and implementation of E2E in Matrix": "Design e implementazione di E2E in Matrix", "Click here to create a GitHub issue.": "Clicca qui per creare una segnalazione su GitHub.", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Puoi usare le opzioni server personalizzate per accedere ad altri server Matrix specificando l'indirizzo dell'home server.
    Questo permette di usare Matrix con un account esistente su un home server diverso.

    È anche possibile impostare un diverso identity server, ma in quel caso non sarà possibile invitare utenti attraverso l'indirizzo e-mail o essere invitati attraverso l'indirizzo e-mail.", "Can't update user notification settings": "Impossibile aggiornare le impostazioni di notifica dell'utente", "Notify for all other messages/rooms": "Notifica per tutti gli altri messaggi/stanze", "Unable to look up room ID from server": "Impossibile consultare l'ID stanza dal server", "Couldn't find a matching Matrix room": "Impossibile trovare una stanza Matrix corrispondente", - "Support for those using the Matrix spec": "Supporto per chi utilizza le specifiche Matrix", - "Safari and Opera work too.": "Anche Safari e Opera funzionano.", - "Loading bug report module": "Caricamento modulo di segnalazione errori", "Invite to this room": "Invita in questa stanza", "Search for a room": "Cerca una stanza", "Thursday": "Giovedì", "Forward Message": "Inoltra messaggio", "Logs sent": "Log inviati", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s via %(browserName)s su %(osName)s", "Back": "Indietro", "Failed to change settings": "Impossibile modificare le impostazioni", "Reply": "Rispondi", "Show message in desktop notification": "Mostra i messaggi nelle notifiche desktop", "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "I log di debug contengono dati di utilizzo dell'applicazione inclusi il nome utente, gli ID o alias delle stanze o gruppi visitati e i nomi degli altri utenti. Non contengono messaggi.", "Unhide Preview": "Mostra anteprima", - "Announcements about Synapse releases": "Annunci riguardo i rilasci di Synapse", - "Search the room directory": "Cerca nella lista delle stanze", - "Please describe the bug and/or send logs.": "Per favore descrivi l'errore e/o invia i log.", "Unable to join network": "Impossibile collegarsi alla rete", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Potresti averli configurati in un client diverso da Riot. Non puoi cambiarli in Riot ma sono comunque applicati", "Sorry, your browser is not able to run Riot.": "Spiacenti, ma il tuo browser non è in grado di utilizzare Riot.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Chat criptate e collaborazioni decentralizzate offerte da [matrix]", "Uploaded on %(date)s by %(user)s": "Caricato il %(date)s da %(user)s", "Messages in group chats": "Messaggi nelle chat di gruppo", "Yesterday": "Ieri", @@ -1180,16 +1133,13 @@ "Low Priority": "Priorità bassa", "What's New": "Novità", "Appear Offline": "Appari offline", - "Get started with some tips from Riot Bot!": "Inizia con alcuni consigli di Riot Bot!", "Set Password": "Imposta Password", "Enable audible notifications in web client": "Abilita notifiche audio nel client web", "Permalink": "Link permanente", - "Welcome to Riot.im": "Benvenuto/a su Riot.im", "Off": "Spento", "#example": "#esempio", "Mentions only": "Solo le citazioni", "You can now return to your account after signing out, and sign in on other devices.": "Ora puoi tornare al tuo account dopo esserti disconnesso e accedere su altri dispositivi.", - "Please install Chrome or Firefox for the best experience.": "Per favore installaChrome o Firefox per un'esperienza migliore.", "Enable email notifications": "Abilita le notifiche email", "Event Type": "Tipo di Evento", "Download this file": "Scarica questo file", @@ -1199,13 +1149,10 @@ "%(count)s Members|one": "%(count)s membro", "Event sent!": "Evento inviato!", "View Source": "Visualizza sorgente", - "Matrix technical discussions": "Discussioni tecniche su Matrix", "Event Content": "Contenuto dell'Evento", "Unable to fetch notification target list": "Impossibile ottenere la lista di obiettivi notifiche", - "Building services on Matrix": "Costruzione servizi su Matrix", "Collapse panel": "Riduci pannello", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Con il tuo attuale browser, l'aspetto e la sensazione generale dell'applicazione potrebbero essere completamente sbagliati e alcune delle funzionalità potrebbero non funzionare. Se vuoi provare comunque puoi continuare, ma non riceverai aiuto per qualsiasi problema tu possa riscontrare!", "Checking for an update...": "Controllo aggiornamenti...", - "General discussion about Matrix and Riot": "Discussioni generali riguardo Matrix e Riot", "There are advanced notifications which are not shown here": "Ci sono notifiche avanzate che non sono mostrate qui" } diff --git a/src/i18n/strings/ja.json b/src/i18n/strings/ja.json index c16fb0d28c..9cf8a92426 100644 --- a/src/i18n/strings/ja.json +++ b/src/i18n/strings/ja.json @@ -58,16 +58,13 @@ "Thursday": "木曜日", "Messages in one-to-one chats": "一対一のチャットでのメッセージ", "A new version of Riot is available.": "新しいバージョンのRiotが利用可能です。", - "Safari and Opera work too.": "SafariOperaでも動作します。", "All Rooms": "全ての部屋", "You cannot delete this message. (%(code)s)": "あなたはこの発言を削除できません (%(code)s)", "Send": "送信", "All messages": "全ての発言", "Uploading report": "レポートのアップロード", "Sunday": "日曜日", - "Welcome to Riot.im": "Riot.imへようこそ", "Direct Chat": "対話", - "Riot is not supported on mobile web. Install the app?": "Riotはスマートフォンでの表示に対応していません。できればアプリをインストールして頂けませんでしょうか?", "Today": "今日", "Files": "添付ファイル", "Room not found": "部屋が見つかりません", @@ -81,7 +78,6 @@ "Messages sent by bot": "ボットから送信されたメッセージ", "Low Priority": "低優先度", "Messages containing my user name": "自身のユーザー名を含むメッセージ", - "Search the room directory": "部屋一覧を検索", "Members": "参加者", "Add an email address above to configure email notifications": "メール通知を設定するためには、メールアドレスを追加してください", "Collecting logs": "ログの収集", @@ -101,8 +97,6 @@ "Enable email notifications": "電子メールでの通知を行う", "Directory": "部屋一覧", "Download this file": "この添付ファイルをダウンロード", - "Unknown device": "不明な端末", - "Report a bug": "バグを報告", "Failed to get public room list": "公開部屋一覧の取得に失敗しました", "Call invitation": "通話への招待", "Forget": "忘れる", diff --git a/src/i18n/strings/ko.json b/src/i18n/strings/ko.json index dede270a91..32ca09aee1 100644 --- a/src/i18n/strings/ko.json +++ b/src/i18n/strings/ko.json @@ -47,7 +47,6 @@ "Ban": "차단", "Banned users": "차단한 사용자", "Blacklisted": "요주의", - "Bug Report": "오류 보고", "Can't load user settings": "사용사 설정을 불러올 수 없어요", "Change Password": "비밀번호 바꾸기", "Changes your display nickname": "보여줄 별명을 바꾸기", @@ -193,7 +192,6 @@ "Forgot your password?": "비밀번호를 잊어버리셨어요?", "For security, this session has been signed out. Please sign in again.": "보안을 위해서, 이 세션에서 로그아웃했어요. 다시 로그인해주세요.", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "보안을 위해서, 로그아웃하면 이 브라우저에서 모든 종단간 암호화 키를 없앨 거에요. 이후 라이엇에서 이야기를 해독하고 싶으시면, 방 키를 내보내서 안전하게 보관하세요.", - "Found a bug?": "오류를 찾으셨나요?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s를 %(fromPowerLevel)s에서 %(toPowerLevel)s로", "Guest access is disabled on this Home Server.": "손님은 이 홈 서버에 접근하실 수 없어요.", "Guests cannot join this room even if explicitly invited.": "손님은 분명하게 초대받았어도 이 방에 들어가실 수 없어요.", @@ -314,7 +312,6 @@ "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s님이 별명 (%(oldDisplayName)s)을 지우셨어요.", "Remove %(threePid)s?": "%(threePid)s 지우시겠어요?", "%(senderName)s requested a VoIP conference.": "%(senderName)s님이 인터넷전화 회의를 요청하셨어요.", - "Report it": "보고하기", "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.": "비밀번호를 다시 설정하면 현재 모든 장치의 종단간 암호화 키가 다시 설정되고, 먼저 방의 키를 내보내고 나중에 다시 불러오지 않는 한, 암호화한 이야기 기록을 읽을 수 없게 되어요. 앞으로는 이 기능을 더 좋게 만들 거에요.", "Results from DuckDuckGo": "덕덕고에서 검색한 결과", "Return to login screen": "로그인 화면으로 돌아가기", @@ -647,8 +644,6 @@ "Edit": "수정하기", "Fetching third party location failed": "타사 위치를 불러오지 못했어요", "A new version of Riot is available.": "라이엇의 새 버전을 사용하실 수 있어요.", - "Riot/Android & matrix-android-sdk chat": "매트릭스/안드로이드 & matrix-ios-sdk 대화", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "오류를 설명해주세요. 무슨 일을 하셨나요? 어떤 일을 예상하셨나요? 실제로는 어떤 일이 일어났나요?", "Couldn't load home page": "중심 화면을 불러올 수 없어요", "All notifications are currently disabled for all targets.": "현재 모든 알림이 모든 상대에게서 꺼졌어요.", "Uploading report": "보고를 올리는 중", @@ -659,29 +654,22 @@ "Failed to set direct chat tag": "직접 이야기 지정을 설정하지 못했어요", "Today": "오늘", "Failed to get protocol list from Home Server": "홈 서버에서 프로토콜 목록을 얻지 못했어요", - "Report a bug": "오류 보고하기", - "Implementing VR services with Matrix": "매트릭스로 VR 서비스 구현", "You are not receiving desktop notifications": "컴퓨터 알림을 받지 않고 있어요", "Friday": "금요일", "Update": "업데이트", - "You need to be using HTTPS to place a screen-sharing call.": "화면 공유를 하려면 HTTPS를 써야만 해요.", "What's New": "새로운 점", "Add an email address above to configure email notifications": "이메일 알림을 설정하기 위해 이메일 주소를 추가해주세요", "Expand panel": "확장 패널", "On": "켜기", "Filter room names": "방 이름 거르기", "Changelog": "바뀐 점", - "Running Matrix services": "매트릭스 서비스 실행", "Waiting for response from server": "서버에서 응답을 기다리는 중", "Leave": "떠나기", - "Failed to send report: ": "보고를 보내지 못했어요: ", - "Unknown device": "알 수 없는 장치", "Advanced notification settings": "고급 알림 설정", "delete the alias.": "가명을 지울게요.", "To return to your account in future you need to set a password": "나중에 계정으로 돌아가려면 비밀번호 설정을 해야만 해요", "Forget": "잊기", "World readable": "세계에 보이기", - "Riot/Web & Desktop chat": "라이엇/웹 & 컴퓨터 이야기", "Hide panel": "패널 숨기기", "You cannot delete this image. (%(code)s)": "이 사진을 지우실 수 없어요. (%(code)s)", "Cancel Sending": "보내기 취소", @@ -692,33 +680,23 @@ "Error saving email notification preferences": "이메일 알림을 설정하는데 오류가 일어났어요", "Messages containing my display name": "내 별명이 적힌 메시지", "Messages in one-to-one chats": "1:1 이야기의 메시지", - "Contributing code to Matrix and Riot": "매트릭스와 라이엇에 코드 기여하기", "Unavailable": "이용할 수 없음", - "Community-run support for Synapse": "시냅스 커뮤니티 운영 지원", "View Decrypted Source": "해독된 출처 보기", "Send": "보내기", "remove %(name)s from the directory.": "목록에서 %(name)s을 지웠어요.", "Notifications on the following keywords follow rules which can’t be displayed here:": "여기 표시될 수 없는 규칙에 따라 다음 키워드는 알리지 않아요:", "Please set a password!": "비밀번호를 설정해주세요!", "You have successfully set a password!": "비밀번호를 설정했어요!", - "Chat with Riot Bot": "Riot 봇과 이야기하기", - "Support for those using, running and writing other bridges": "다른 브릿지를 사용하고, 운영하고, 기록하는 사람들을 지원", - "Admin support for Dendrite": "덴드라이트 관리 지원", "An error occurred whilst saving your email notification preferences.": "이메일 알림을 설정하다가 오류가 일어났어요.", "Source URL": "출처 URL", "Failed to add tag %(tagName)s to room": "방에 %(tagName)s로 지정하지 못했어요", "Members": "구성원", "No update available.": "업데이트가 없어요.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "기존 네트워크(Slack, IRC, Gitter 등)에 연결되있거나 독립된 많은 방들이 이미 매트릭스에 있어요. 목록을 확인해보세요!", "Noisy": "소리", "Files": "파일", "Collecting app version information": "앱 버전 정보를 수집하는 중", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "방 가명 %(alias)s 을 지우고 목록에서 %(name)s를 지우시겠어요?", - "customServer_text": "사용자 지정 서버 설정에서 다른 홈 서버 URL을 지정해 다른 매트릭스 서버에 로그인할 수 있어요.
    이를 통해 라이엇과 다른 홈 서버의 기존 매트릭스 계정을 함께 쓸 수 있죠.

    사용자 지정 ID 서버를 설정할 수도 있지만 이메일 주소로 사용자를 초대하거나 초대받을 수는 없답니다.", - "Co-ordination for Riot/Web translators": "라이엇/웹 번역자를 위한 조정", "This will allow you to return to your account after signing out, and sign in on other devices.": "이런 식으로 로그아웃한 뒤 계정으로 돌아가, 다른 장치에서 로그인하실 수 있어요.", - "Dev chat for the Dendrite dev team": "덴드라이트 개발 팀을 위한 개발자 대화", - "Design and implementation of E2E in Matrix": "매트릭스에서 E2E 설계와 구현", "Enable notifications for this account": "이 계정의 알림 받기", "Directory": "목록", "Search for a room": "방에서 찾기", @@ -738,15 +716,11 @@ "Direct Chat": "직접 이야기하기", "The server may be unavailable or overloaded": "서버를 쓸 수 없거나 과부하일 수 있어요", "Reject": "거절하기", - "Riot is not supported on mobile web. Install the app?": "라이엇은 모바일 사이트를 지원하지 않아요. 앱을 설치하시겠어요?", - "Discussion of all things Matrix!": "매트릭스의 모든 것에 대한 토론!", "Failed to set Direct Message status of room": "방의 쪽지 상태를 설정하지 못했어요", "Monday": "월요일", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "문제를 진단하기 위해서, 이 클라이언트의 로그를 오류 보고서와 같이 보낼 거에요. 위 내용만 보내시려면, 체크를 해제하세요:", "All messages (noisy)": "모든 메시지 (크게)", "Enable them now": "지금 켜기", "Forward Message": "메시지 전달", - "Describe your problem here.": "여기에 일어난 문제를 적어주세요.", "Messages containing my user name": "내 사용자 이름이 적힌 메시지", "Toolbox": "도구상자", "Collecting logs": "로그 수집 중", @@ -759,16 +733,10 @@ "Failed to update keywords": "키워드를 갱신하지 못했어요", "Send logs": "로그 보내기", "All messages": "모든 메시지", - "Implementing VoIP services with Matrix": "매트릭스로 인터넷전화 서비스 구현", - "Dev chat for the Riot/Web dev team": "라이엇/웹 개발 팀을 위한 개발자 대화", "Call invitation": "전화가 왔어요", - "Riot Desktop on %(platformName)s": "%(platformName)s에서 라이엇 컴퓨터판", "Downloading update...": "업데이트를 받는 중...", "You have successfully set a password and an email address!": "비밀번호와 이메일 주소를 설정했어요!", "What's new?": "새로운 점은?", - "Discussion of the Identity Service API": "ID 서비스 API에 대한 논의", - "Support for those using and running matrix-appservice-irc": "matrix-appservice-irc를 사용하고 운영하는 사람들을 지원", - "Riot/iOS & matrix-ios-sdk chat": "라이엇/IOS & matrix-ios-sdk 대화", "Notify me for anything else": "모든 걸 알리기", "When I'm invited to a room": "방에 초대받았을 때", "Keywords": "키워드", @@ -776,25 +744,17 @@ "Notify for all other messages/rooms": "다른 모든 메시지/방 알리기", "Unable to look up room ID from server": "서버에서 방 ID를 찾아볼 수 없어요", "Couldn't find a matching Matrix room": "일치하는 매트릭스 방을 찾을 수 없어요", - "Support for those using the Matrix spec": "Matrix spec을 사용하는 사람들을 지원", - "Safari and Opera work too.": "사파리오페라에서도 작동해요.", - "Loading bug report module": "오류 보고 모듈을 불러오는 중", "Invite to this room": "이 방에 초대하기", "You cannot delete this message. (%(code)s)": "이 메시지를 지우실 수 없어요. (%(code)s)", "Thursday": "목요일", "I understand the risks and wish to continue": "위험할 수 있는 걸 알고 계속하기를 바라요", - "%(appName)s via %(browserName)s on %(osName)s": "%(osName)s의 %(browserName)s을 통한 %(appName)s", "Back": "돌아가기", "Failed to change settings": "설정을 바꾸지 못했어요", "Show message in desktop notification": "컴퓨터 알림에서 내용 보이기", "Unhide Preview": "미리보기를 숨기지 않기", - "Announcements about Synapse releases": "시냅스 공개 발표", - "Search the room directory": "방 목록을 찾기", - "Please describe the bug and/or send logs.": "오류를 적어주시거나 로그를 보내주세요.", "Unable to join network": "네트워크에 들어갈 수 없어요", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "라이엇이 아닌 다른 클라이언트에서 구성하셨을 수도 있어요. 라이엇에서 조정할 수는 없지만 여전히 적용되있을 거에요", "Sorry, your browser is not able to run Riot.": "죄송해요. 브라우저에서 라이엇을 켤 수가 없어요.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "분산되고, 암호화된 대화 & [matrix]의 지원으로 협력", "Uploaded on %(date)s by %(user)s": "by %(user)s가 %(date)s에 올림", "Messages in group chats": "이야기 모임의 메시지", "Yesterday": "어제", @@ -802,30 +762,24 @@ "Low Priority": "낮은 우선순위", "Riot does not know how to join a room on this network": "라이엇이 이 네트워크에서 방에 들어가는 법을 알 수 없어요", "Appear Offline": "미접속으로 표시하기", - "Get started with some tips from Riot Bot!": "라이엇 봇에게 조언을 받고 시작하세요!", "Set Password": "비밀번호 설정", "Enable audible notifications in web client": "웹 클라이언트에서 알림 소리 켜기", "Permalink": "고유주소", - "Welcome to Riot.im": "라이엇에 오신 걸 환영해요", "Off": "끄기", "#example": "#예", "Mentions only": "답만 하기", "Failed to remove tag %(tagName)s from room": "방에서 %(tagName)s 지정을 지우지 못했어요", "Wednesday": "수요일", "You can now return to your account after signing out, and sign in on other devices.": "계정을 로그아웃하신 뒤에 계정으로 돌아가, 다른 장치에서 로그인하실 수 있어요.", - "Please install Chrome or Firefox for the best experience.": "최상의 경험을 위해 크롬이나 파이어폭스를 설치해주세요.", "Enable email notifications": "이메일로 알림 받기", "Login": "로그인", "No rooms to show": "보여드릴 방이 없어요", "Download this file": "이 파일 받기", "Thank you!": "감사합니다!", "View Source": "출처 보기", - "Matrix technical discussions": "매트릭스 기술 논의", "Unable to fetch notification target list": "알림 대상 목록을 불러올 수 없어요", - "Building services on Matrix": "매트릭스에서 서비스 구축", "Collapse panel": "패널 접기", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "현재 브라우저에서는, 응용 프로그램의 모양과 기능이 완벽하게 맞지 않거나, 일부 혹은 모든 기능이 작동하지 않을 수 있어요. 계속할 수는 있지만, 맞닥뜨리는 모든 문제는 직접 해결하셔야해요!", "Checking for an update...": "업데이트를 확인하는 중...", - "General discussion about Matrix and Riot": "매트릭스와 라이엇에 대한 일반 논의", "There are advanced notifications which are not shown here": "여기 보이지 않는 고급 알림이 있어요" } diff --git a/src/i18n/strings/lt.json b/src/i18n/strings/lt.json index a56bd7b953..277b0cf427 100644 --- a/src/i18n/strings/lt.json +++ b/src/i18n/strings/lt.json @@ -15,8 +15,6 @@ "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "Mes taip pat saugome kiekvieną puslapį, kurį jūs naudojate programėlėje (dabartinis ), jūsų paskyros agentas () ir jūsų įrenginio rezoliucija ().", "Fetching third party location failed": "Nepavyko gauti trečios šalies vietos", "A new version of Riot is available.": "Yra nauja Riot versija.", - "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk chat", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Aprašykite klaidą. Ką darėte? Ko tikėjotės, kad įvyks? Kas iš tikrųjų įvyko?", "I understand the risks and wish to continue": "Aš suprantu riziką ir noriu tęsti", "Couldn't load home page": "Nepavyksta užkrauti namų puslapio", "Send Account Data": "Siųsti paskyros duomenis", @@ -25,16 +23,12 @@ "Sunday": "Sekmadienis", "Guests can join": "Svečiai gali prisijungti", "Notification targets": "Pranešimo objektai", - "General discussion about Matrix and Riot": "Bendros diskusijos apie Matrix ir Riot", "Today": "Šiandien", "Files": "Failai", - "Report a bug": "Siųsti klaidos ataskaitą", - "Implementing VR services with Matrix": "VR serviso įgyvendinimas su Matrix", "You are not receiving desktop notifications": "Jūs negaunate darbalaukio pranešimų", "Friday": "Penktadienis", "Update": "Atnaujinti", "Notifications": "Pranešimai", - "You need to be using HTTPS to place a screen-sharing call.": "Norint skambinti su ekrano bendrinimo funkcija būtina naudoti HTTPS.", "Unable to fetch notification target list": "Nėra galimybės rasti pranešimo objektų sąrašui", "Add an email address above to configure email notifications": "Norėdami gauti pranešimus el. paštu įveskite į aukščiau esantį laukelį el. pašto adresą", "Expand panel": "Išskleisti skydelį", @@ -42,14 +36,11 @@ "%(count)s Members|other": "%(count)s nariai", "Filter room names": "Filtruoti kambarių pavadinimus", "Changelog": "Keitinių žurnalas", - "Running Matrix services": "Vykdant Matrix servisus", "Waiting for response from server": "Laukiama atsakymo iš serverio", "Failed to change password. Is your password correct?": "Nepavyko pakeisti slaptažodžio. Ar Jūsų slaptažodis teisingas?", "Uploaded on %(date)s by %(user)s": "Atnaujinta %(date)s vartotojo %(user)s", "OK": "Gerai", "Send Custom Event": "Siųsti pasirinktinį įvykį", - "Failed to send report: ": "Nepavyko išsiųsti ataskaitos: ", - "Unknown device": "Nežinomas įrenginys", "All notifications are currently disabled for all targets.": "Šiuo metu visi pranešimai visiems objektams yra išjungti.", "Operation failed": "Operacija nepavyko", "delete the alias.": "ištrinti slapyvardį.", @@ -57,7 +48,6 @@ "Forget": "Pamiršti", "World readable": "Visiems skaitomas", "Mute": "Užtildyti", - "Riot/Web & Desktop chat": "Riot/Web & Darbalaukio čatas", "Hide panel": "Slėpti skydelį", "You cannot delete this image. (%(code)s)": "Jūs negalite ištrinti šio paveikslėlio. (%(code)s)", "Cancel Sending": "Atšaukti siuntimą", @@ -68,21 +58,15 @@ "Room not found": "Kambarys nerastas", "Downloading update...": "Atsiunčiamas atnaujinimas...", "Messages in one-to-one chats": "Žinutės asmeniniuose pokalbiuose", - "Contributing code to Matrix and Riot": "Contributing code to Matrix and Riot", "Unavailable": "Neprieinamas", - "Community-run support for Synapse": "Bendruomenės Synapse palaikymas", "Error saving email notification preferences": "Klaida, įrašant pranešimų el. paštu nuostatas", "View Decrypted Source": "Peržiūrėti iššifruotą šaltinį", "Failed to update keywords": "Nepavyko atnaujinti raktažodžių", - "Welcome to Riot.im": "Sveiki atvykę į Riot.im", "Notifications on the following keywords follow rules which can’t be displayed here:": "Pranešimai šiems raktažodžiams yra uždrausti taisyklėmis:", "Safari and Opera work too.": "Naudojant Safari ir Opera taip pat gerai veikia.", "Please set a password!": "Prašau įrašykite slaptažodį!", "powered by Matrix": "palaikomas Matrix", "You have successfully set a password!": "Jūs sėkmingai įrašėte slaptažodį!", - "Chat with Riot Bot": "Kalbėtis su Riot robotu", - "Support for those using, running and writing other bridges": "Palaikymas skirtas tiems kas naudoja kitus tiltus", - "Admin support for Dendrite": "Administratoriaus Dendrite palaikymas", "Favourite": "Svarbūs", "All Rooms": "Visi pokalbių kambariai", "Explore Room State": "Peržiūrėti pokalbių kambario būseną", @@ -92,14 +76,11 @@ "Filter results": "Išfiltruoti rezultatus", "Members": "Nariai", "No update available.": "Nėra prieinamų atnaujinimų.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Daugybė kambarių yra prisijungę prie Matrix, kurie yra susieti su egzistuojančiais tinklais (Slack, IRC, Gitter etc) arba nepriklausomi. Patikrinkite kambarių katalogą!", "Noisy": "Triukšmingas", "Failed to get protocol list from Home Server": "Nepavyko gauti protokolų sąrašo iš serverio", "Collecting app version information": "Renkama programėlės versijos informacija", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Ar ištrinti kambarį %(alias)s ir %(name)s kambario pavadinimą iš katalogo?", - "Co-ordination for Riot/Web translators": "Riot/Web vertėjų koordinacija", "This will allow you to return to your account after signing out, and sign in on other devices.": "Tai leis Jums grįžti prie paskyros po atsijungimo ir prisijungti kituose įrenginiuose.", - "Dev chat for the Dendrite dev team": "Kūrėjų čatas Dendrite dev team", "Keywords": "Raktažodžiai", "Unpin Message": "Atsegti žinutę", "Enable notifications for this account": "Įjungti pranešimus šiai paskyrai", @@ -128,16 +109,12 @@ "Direct Chat": "Tiesioginis pokalbis", "The server may be unavailable or overloaded": "Gali būti, kad serveris yra neprieinamas arba perkrautas", "Online": "Prisijungęs", - "Riot is not supported on mobile web. Install the app?": "Riot nėra palaikoma naršant svetainėje mobiliaisiais įrenginiais. Įdiegti programėlę?", - "Discussion of all things Matrix!": "Diskusijos apie viską Matrix!", "Failed to set Direct Message status of room": "Nepavyko nustatyti tiesioginio pranešimo kambario būklės", "Monday": "Pirmadienis", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Tam, kad nustatytume problemas, iš šio kliento bus išsiųsti žurnalai kartu su klaidos ataskaita. Jeigu norite siųsti tik žemiau esantį tekstą nuimkite šia varnelę:", "All messages (noisy)": "Visos žinutės (triukšmingas)", "Enable them now": "Įgalinti juos dabar", "Enable audible notifications in web client": "Įgalinti garsinius pranešimus internetinėje aplinkoje", "Messages containing my user name": "Žinutės, kuriose paminėtas mano naudotojo vardas", - "Describe your problem here.": "Čia aprašykite savo problemą.", "Toolbox": "Įrankinė", "Collecting logs": "Renkami žurnalai", "more": "daugiau", @@ -155,43 +132,28 @@ "Send logs": "Siųsti žurnalus", "All messages": "Visos žinutės", "unknown error code": "nežinomas klaidos kodas", - "Implementing VoIP services with Matrix": "VoIP serviso įgyvendinimas su Matrix", - "Dev chat for the Riot/Web dev team": "Kūrėjų čatas Riot/Web dev team", "Call invitation": "Pakvietimas skambinant", - "Riot Desktop on %(platformName)s": "Riot Desktop, %(platformName)s", "Messages containing my display name": "Žinutės, kuriose paminėtas mano vardas", "State Key": "Būklės raktas", "Failed to send custom event.": "Nepavyko išsiųsti pasirinktinio įvykio.", "What's new?": "Kas naujo?", - "Discussion of the Identity Service API": "Diskusijos apie identifikavimo serviso API", - "Support for those using and running matrix-appservice-irc": "Palaikymas skirtas matrix-appservice-irc naudotojams", - "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk chat", "Notify me for anything else": "Pranešti man apie visa kita", "View Source": "Peržiūrėti šaltinį", - "Design and implementation of E2E in Matrix": "E2E dizainas ir įgyvendinimas Matrix'e", "Close": "Užverti", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Norėdami jungtis prie kito nei Matrix serverio galite pasirinktinio serverio nustatymuose nurodyti kito serverio URL adresą.
    Ši funkcija leis naudoti Riot su esama Matrix serverio paskyrą kituose serveriuose.

    Taip pat galite nurodyti pasirinktinį identifikavimo serverį, bet tuomet negalėsite kviesti kitų vartotojų el. paštu ar jie jūsų.", "Can't update user notification settings": "Nepavyksta atnaujinti naudotojo pranešimų nustatymų", "Notify for all other messages/rooms": "Pranešti apie visas kitas žinutes/pokalbių kambarius", "Unable to look up room ID from server": "Nepavyko gauti kambario ID iš serverio", "Couldn't find a matching Matrix room": "Nepavyko rasti atitinkamo Matrix kambario", - "Support for those using the Matrix spec": "Palaikymas skirtas Matrix spec", - "Loading bug report module": "Įkraunamas klaidų ataskaitų modulis", "Invite to this room": "Pakviesti į šį kambarį", "You cannot delete this message. (%(code)s)": "Jūs negalite trinti šios žinutės. (%(code)s)", "Thursday": "Ketvirtadienis", "Forward Message": "Persiųsti žinutę", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s per %(browserName)s, naudojant %(osName)s", "Back": "Atgal", "Reply": "Atsakyti", "Show message in desktop notification": "Rodyti žinutes darbalaukio pranešimuose", - "Announcements about Synapse releases": "Pranešimai apie Synapse naujinimus", - "Search the room directory": "Ieškoti kambarių kataloge", - "Please describe the bug and/or send logs.": "Prašau apibūdinkite programos klaidą ir/arba išsiųskite žurnalo įrašus.", "Reject": "Atmesti", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Jūs turbūt juos sukonfigūravote kitoje programėlėje nei Riot. Negalite jų koreguoti Riot programėlėje, bet jie vistiek yra taikomi", "Sorry, your browser is not able to run Riot.": "Atleiskite, jūsų naršyklė negali paleisti Riot.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Decentralizuotas, šifruotas čatas; bendradarbiavimas palaikomas [matrix]", "Quote": "Citata", "Messages in group chats": "Žinutės grupės pokalbiuose", "Yesterday": "Vakar", @@ -201,7 +163,6 @@ "Riot does not know how to join a room on this network": "Riot nežino kaip prisijungti prie kambario šiame tinkle", "Set Password": "Nustatyti slaptažodį", "Appear Offline": "Neprisijungęs", - "Get started with some tips from Riot Bot!": "Pradėkite su patarimais nuo Riot roboto!", "An error occurred whilst saving your email notification preferences.": "Įrašant pranešimų el. paštu nuostatas, įvyko klaida.", "Unable to join network": "Nepavyko prisijungti prie tinklo", "Permalink": "Pastovioji nuoroda", @@ -228,10 +189,8 @@ "Custom Server Options": "Pasirinktiniai serverio nustatymai", "Event Content": "Įvykio turinys", "Thank you!": "Ačiū!", - "Building services on Matrix": "Servisų kūrimas ant Matrix", "Collapse panel": "Suskleisti skydelį", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Naudojant šią naršyklę aplikacija gali atrodyti ir reaguoti neteisingai. Kai kurios arba visos funkcijos gali neveikti. Jei vis tiek norite pabandyti gali tęsti, tačiau iškilusios problemos yra jūsų pačių reikalas!", "Checking for an update...": "Tikrinama ar yra atnaujinimų...", - "Matrix technical discussions": "Matrix techninės diskusijos", "There are advanced notifications which are not shown here": "Yra išplėstinių pranešimų, kurie nėra čia rodomi" } diff --git a/src/i18n/strings/lv.json b/src/i18n/strings/lv.json index 8ca3a169b9..a4a222a602 100644 --- a/src/i18n/strings/lv.json +++ b/src/i18n/strings/lv.json @@ -46,7 +46,6 @@ "Banned users": "Banotie/bloķētie lietotāji (kuriem liegta pieeja)", "Bans user with given id": "Bloķē (liedz pieeju) lietotāju pēc uzdotā ID (nobano)", "Blacklisted": "Melnajā sarakstā iekļautie", - "Bug Report": "Paziņojums par kļūdu", "Bulk Options": "Grupveida darbību parametri", "Call Timeout": "Savienojuma gaidīšanas noilgums", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Neizdodas savienoties ar bāzes serveri. Pārbaudi tīkla savienojumu un pārliecinies, ka bāzes servera SSL sertifikāts ir uzticams, kā arī pārlūkā instalētie paplašinājumi nebloķē pieprasījumus.", @@ -178,7 +177,6 @@ "Forgot your password?": "Aizmirsi paroli?", "For security, this session has been signed out. Please sign in again.": "Drošības nolūkos, šī sesija ir beigusies. Lūdzu, pieraksties par jaunu.", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Drošības nolūkos, izrakstīšanās dzēsīs jebkādas ierīce-ierīce šifrēšanas atslēgas no šī pārlūka. Ja Tu vēlies saglabāt iespēju atšifrēt tavu saziņas vēsturi no Riot nākotnes sesijām, lūdzu eksportē tavas istabas atslēgas, saglabājot tās drošā vietā.", - "Found a bug?": "Pamanīji kļūdu?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s no %(fromPowerLevel)s uz %(toPowerLevel)s", "Guest access is disabled on this Home Server.": "Šajā Bāzes serverī viesu pierakstīšanās nav iespējama.", "Guests cannot join this room even if explicitly invited.": "Viesi nevar pievienoties šai istabai, pat ja ir uzaicināti.", @@ -304,7 +302,6 @@ "Remove": "Dzēst", "Remove %(threePid)s?": "Dzēst %(threePid)s?", "%(senderName)s requested a VoIP conference.": "%(senderName)s vēlas VoIP konferenci.", - "Report it": "Ziņot par to", "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.": "Paroles atiestatīšana atiestatīs visas ierīce-ierīce šifrēšanas atslēgas visās ierīcēs, padarot čata šifrēto ziņu vēsturi nelasāmu, ja vien Tu pirms tam neesi eksportējis savas istabas atslēgas un atkārtoti importējis tās atpakaļ. Nākotnē šo ir plānots uzlabot.", "Results from DuckDuckGo": "Rezultāti no DuckDuckGo", "Return to login screen": "Atgriezties uz pierakstīšanās lapu", @@ -654,7 +651,6 @@ "Do you want to load widget from URL:": "Vai vēlies ielādēt widžetu no URL:", "Edit": "Rediģēt", "Enable automatic language detection for syntax highlighting": "Iespējot automātisko valodas noteikšanu sintakses iezīmējumiem", - "Hide Apps": "Slēpt aplikācijas", "Hide join/leave messages (invites/kicks/bans unaffected)": "Slēpt ziņas par pievienošanos istabai vai došanos prom no tās (tas neietekmē uzaicinājumus, vai izsperšanas/banošanas darbības)", "Integrations Error": "Integrācijas kļūda", "Publish this room to the public in %(domain)s's room directory?": "Publicēt šo istabu publiskajā %(domain)s katalogā?", @@ -662,7 +658,6 @@ "PM": "PM", "NOTE: Apps are not end-to-end encrypted": "PIEZĪME: Aplikācijās nav ierīce-ierīce šifrēšanas", "Sets the room topic": "Iestata istabas tematu", - "Show Apps": "Rādīt aplikācijas", "The maximum permitted number of widgets have already been added to this room.": "Maksimāli atļautais vidžetu skaits šai istabai jau sasniegts.", "To get started, please pick a username!": "Lai sāktu, lūdzu izvēlies lietotājvārdu!", "Unable to create widget.": "Nav iespējams izveidot widžetu.", @@ -918,7 +913,6 @@ "Failed to remove the room from the summary of %(groupId)s": "Neizdevās dzēst istabu no %(groupId)s kopsavilkuma", "The room '%(roomName)s' could not be removed from the summary.": "Istabu '%(roomName)s' neizdevās dzēst no kopsavilkuma.", "Leave Community": "Atstāt kopienu", - "Unable to leave room": "Nav iespējams atstāt istabu", "Community Settings": "Kopienas iestatījumi", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Šīs istabas tiek rādītas kopienas dalībniekiem šīs kopienas lapā. Kopienas dalībnieki var pievienoties istabām, uzklikšķinot uz tām.", "Your community hasn't got a Long Description, a HTML page to show to community members.
    Click here to open settings and give it one!": "Jūsu kopienai nav plašāka HTML-lapas apraksta ko parādīt dalībniekiem.
    Klikšķini šeit, lai atvērtu iestatījumus un to pievienotu!", @@ -926,8 +920,6 @@ "Failed to load %(groupId)s": "Neizdevās ielādēt %(groupId)s", "This Home server does not support communities": "Šis Bāzes serveris neatbalsta kopienas", "This room is not public. You will not be able to rejoin without an invite.": "Šīs istaba nav publiska. Tu nevari tajā ieiet bez uzaicinājuma.", - "Cryptography data migrated": "Sifrēšanas dati tika pārnesti", - "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "Veikta vienreizēja šifrēšanas datu pārnese. Sifrēšana (end-to-end) nedarbosies, ja Tu atgriezīses pie vecākas Riot versijas. Ja nepieciešams izmantot end-to-end šifrēšanu, izmantojot vecāku versija, vispirms izraksties no Riot. Lai saglabātu ziņu vēsturi, eksportē un tad importē savas kripto-atslēgas.", "Old cryptography data detected": "Tika uzieti novecojuši šifrēšanas dati", "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Uzieti dati no vecākas Riot versijas. Tas novedīs pie \"end-to-end\" šifrēšanas problēmām vecākajā versijā. Šajā versijā nevar tikt atšifrēti ziņojumi, kuri radīti izmantojot vecākajā versijā \"end-to-end\" šifrētas ziņas. Tas var arī novest pie ziņapmaiņas, kas veikta ar šo versiju, neizdošanās. Ja rodas ķibeles, izraksties un par jaunu pieraksties sistēmā. Lai saglabātu ziņu vēsturi, eksportē un tad importē savas šifrēšanas atslēgas.", "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Radi kopienu, lai apvienotu lietotājus un istabas. Izveido mājaslapu, lai iezīmētu Matrix visumā savu klātbūtni, vietu un telpu.", @@ -982,7 +974,6 @@ "Unable to accept invite": "Nav iespējams pieņemt uzaicinājumu", "Unable to reject invite": "Nav iespējams noraidīt uzaicinājumu", "Leave %(groupName)s?": "Atstāt %(groupName)s?", - "Changes made to your community might not be seen by other users for up to 30 minutes.": "Izmaiņas, kuras izdarītas Tavā kopienā, var neparādīties citiem lietotājiem līdz pat 30 minūtēm.", "%(inviter)s has invited you to join this community": "%(inviter)s uzaicina Tevi pievienoties šai kopienai", "You are an administrator of this community": "Tu esi šīs kopienas administrators", "You are a member of this community": "Tu esi šīs kopienas biedrs", @@ -1003,8 +994,6 @@ "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Skatījis %(displayName)s (%(userName)s) %(dateTime)s", "Fetching third party location failed": "Neizdevās iegūt trešās puses atrašanās vietu", "A new version of Riot is available.": "Pieejama jauna Riot versija.", - "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk čats", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Lūdzu, apraksti kļūdu. Kas tika darīts? Kādas bija gaidas (kāds rezultāts tika sagaidīts)? Kas realitātē notika?", "Couldn't load home page": "Neizdevās ielādēt sākumlapu", "Send Account Data": "Sūtīt konta datus", "All notifications are currently disabled for all targets.": "Visiem saņēmējiem visi paziņojumi ir atspējoti.", @@ -1013,12 +1002,9 @@ "Notification targets": "Paziņojuma mērķi", "Today": "šodien", "Failed to get protocol list from Home Server": "Neizdevās iegūt protokolu sarakstu no Bāzes servera", - "Report a bug": "Informēt par kļūdu", - "Implementing VR services with Matrix": "VR pakalpojumu iedzīvināšana Matrix", "You are not receiving desktop notifications": "Darbvirsmas paziņojumi netiek saņemti", "Friday": "piektdiena", "Update": "Aktualizēt", - "You need to be using HTTPS to place a screen-sharing call.": "Lai izmantotu ekrāna kopīgošanas zvanu, nepieciešams izmantot HTTPS savienojumu.", "What's New": "Kas jauns", "Add an email address above to configure email notifications": "Lai konfigurētu epasta paziņojumus, pievieno epasta adresi", "Expand panel": "Izvērst paneli", @@ -1026,18 +1012,14 @@ "%(count)s Members|other": "%(count)s biedru", "Filter room names": "Filtrēt pēc istabu nosaukuma", "Changelog": "Izmaiņu saraksts (vēsture)", - "Running Matrix services": "Matrix pakalpojumu izmantošana", "Waiting for response from server": "Gaidām atbildi no servera", "Send Custom Event": "Sūtīt individuālu notikumu", - "Failed to send report: ": "Neizdevās nosūtīt atskaiti: ", - "Unknown device": "Nezināma ierīce", "Advanced notification settings": "Paziņojumu papildus iestatījumi", "Failed to send logs: ": "Neizdevās nosūtīt logfailus: ", "delete the alias.": "dzēst aliasi/aizstājējvārdu.", "To return to your account in future you need to set a password": "Lai nākotnē atgrieztos savā kontā, nepieciešams iestatīt paroli", "Forget": "Aizmirst", "#example": "#piemērs", - "Riot/Web & Desktop chat": "Riot/Web & darbvirsmas čats", "Hide panel": "Slēpt paneli", "You cannot delete this image. (%(code)s)": "Šo attēlu nevar izdzēst (%(code)s)", "Cancel Sending": "Atcelt sūtīšanu", @@ -1047,9 +1029,7 @@ "Error saving email notification preferences": "Kļūda saglabājot epasta notifikāciju paziņojumu uzstādījumus", "Messages containing my display name": "Ziņas, kuras satur manu redzamo vārdu", "Messages in one-to-one chats": "Ziņas viens-pret-vienu čatos", - "Contributing code to Matrix and Riot": "Dot ieguldījumu Matrix and Riot kodā un tulkojumā", "Unavailable": "Nesasniedzams", - "Community-run support for Synapse": "\"Synapse\" komūnas nodrošināts atbalsts", "View Decrypted Source": "Skatīt atšifrētu avotu", "Failed to update keywords": "Neizdevās aktualizēt atslēgvārdus", "Notes:": "Piezīmes:", @@ -1058,9 +1038,6 @@ "Safari and Opera work too.": "Safari un Opera arī nav skādējami.", "Please set a password!": "Lūdzu iestati paroli!", "You have successfully set a password!": "Esi veiksmīgi iestatījis(usi) paroli!", - "Chat with Riot Bot": "Pačatot ar Riot botu", - "Support for those using, running and writing other bridges": "Atbalsts tiem, kuri izmanto un rada citus \"tiltu\" risinājumus", - "Admin support for Dendrite": "Administrotora atbalsts \"Dendrite\"", "An error occurred whilst saving your email notification preferences.": "Saglabājot Tavus epasta paziņojumu uzstādījumus, radās kļūda.", "Explore Room State": "Noskaidrot istabas statusu", "Source URL": "Avota URL adrese", @@ -1068,15 +1045,11 @@ "Filter results": "Filtrēt rezultātus", "Members": "Biedri", "No update available.": "Nav pieejamu aktualizāciju.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Matrix-ā pastāv daudzas neatkarīgas un/vai eksistējošiem tīmekļa resursiem (Slack, IRC, Gitter u.tml.) piesaistītas istabas. Ieskaties katalogā!", "Resend": "Nosūtīt atkārtoti", "Files": "Faili", "Collecting app version information": "Tiek iegūta programmas versijas informācija", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Dzēst istabas aliasi/aizstājējvārdu %(alias)s un dzēst %(name)s no kataloga?", - "customServer_text": "Tu vari izmantot īpašus servera uzstādījumus, lai pierakstītos citos Matrix serveros, norādot atšķirīgu servera URL adresi.
    Tas atļaus Tev izmantot Riot ar jau eksistējošu Matrix kontu citā serverī.

    Tu vari norādīt arī īpašu identitātes serveri, bet tad nevarēsi uzaicināt lietotājus pēc epasta adreses,kā arī pēc tās tikt uzaicināts/a.", - "Co-ordination for Riot/Web translators": "Riot/Web tulkotāju koordinācija", "This will allow you to return to your account after signing out, and sign in on other devices.": "Tas atļaus Tev atgriezties savā kontā pēc izrakstīšanās, un pierakstīties no citām ierīcēm.", - "Dev chat for the Dendrite dev team": "Dendrite izstrādatāju komandas čats", "Keywords": "Atslēgvārdi", "Enable notifications for this account": "Iespējot paziņojumus šim kontam", "Directory": "Katalogs", @@ -1101,15 +1074,11 @@ "Direct Chat": "Tiešais čats", "The server may be unavailable or overloaded": "Serveris nav pieejams vai ir pārslogots", "Reject": "Noraidīt", - "Riot is not supported on mobile web. Install the app?": "Riot netiek atbalstīts mobilajā versijā. Instalēt aplikāciju?", - "Discussion of all things Matrix!": "Diskusija par visām ar Matrix saistītajām lietām!", "Failed to set Direct Message status of room": "Neizdevās iestatīt istabas tiešās ziņas statusu", "Monday": "pirmdiena", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Problēmu diagnosticēšanas mērķim šī klienta logfaili tiks nosūtīti kopā ar šo kļūdas atskaiti. Ja vēlies nosūtīt vienīgi zemāk redzamo tekstu, lūdzu noņem ķeksi:", "Remove from Directory": "Dzēst no kataloga", "Enable them now": "Iespējot tos tagad", "Forward Message": "Pārsūtīt ziņu", - "Describe your problem here.": "Apraksti šeit savu problēmu.", "Messages containing my user name": "Ziņas, kuras satur manu lietotājvārdu", "Toolbox": "Instrumentārijs", "Collecting logs": "Tiek iegūti logfaili", @@ -1125,47 +1094,31 @@ "Quote": "Citāts", "Send logs": "Nosūtīt logfailus", "All messages": "Visas ziņas", - "Implementing VoIP services with Matrix": "VoIP pakalpojumu iedzīvināšana Matrix", - "Dev chat for the Riot/Web dev team": "Riot/Web izstrādātāju komandas čats", "Call invitation": "Uzaicinājuma zvans", - "Riot Desktop on %(platformName)s": "Riot darbvirsma %(platformName)s", "Downloading update...": "Lejupielādēju aktualizāciju...", "State Key": "Stāvokļa atslēga", "Failed to send custom event.": "Individuālo notikumu nosūtīt neizdevās.", "What's new?": "Kas jauns?", - "Discussion of the Identity Service API": "Diskusija par Identitātes servisa API", - "Support for those using and running matrix-appservice-irc": "Atbalsts tiem, kuri izmanto matrix-appservice-irc", - "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk čats", "Notify me for anything else": "Paziņot man par jebko citu", "When I'm invited to a room": "Kad esmu uzaicināts/a istabā", - "Design and implementation of E2E in Matrix": "E2E arhitektūra un iedzīvināšana Matrix", "Click here to create a GitHub issue.": "Nospied šeit lai izveidotu GitHub problēmpaziņojumu.", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Tu vari lietot \"custom\" servera opcijas, lai ielogotos citos Matrix serveros, norādot citu Bāzes servera URL.
    Tas atļaus tev lietot Riot ar esošo Matrix kontu uz cita Bāzes servera.

    Tu arī vari uzstādīt atsevišķu Identitāšu serveri, taču tad Tev nebūs iespēju uzaicināt lietotājus, izmantojot epasta adresi, vai pašam tikt uzaicinātam, izmantojot epasta adresi.", "Can't update user notification settings": "Neizdodas atjaunot lietotāja paziņojumu iestatījumus", "Notify for all other messages/rooms": "Paziņot par visām citām ziņām/istabām", "Unable to look up room ID from server": "Nav iespējams no servera iegūt istabas Id", "Couldn't find a matching Matrix room": "Atbilstoša Matrix istaba netika atrasta", - "Support for those using the Matrix spec": "Atbalsts tiem, kuri izmanto Matrix specifikācijas", - "Safari and Opera work too.": "darbojas arī Safari un Opera.", - "Loading bug report module": "Ielādējas kļūdu atskaišu modulis", "Invite to this room": "Uzaicināt uz šo istabu", "Search for a room": "Meklēt istabu", "Thursday": "ceturtdiena", "I understand the risks and wish to continue": "Apzinos riskus un vēlos turpināt", "Logs sent": "Logfaili nosūtīti", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s caur %(browserName)s un %(osName)s", "Back": "Atpakaļ", "Reply": "Atbildēt", "Show message in desktop notification": "Parādīt ziņu darbvirsmas paziņojumos", "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Atutošanas logfaili satur programmas datus, ieskaitot Tavu lietotājvārdu, istabu/grupu ID vai aliases, kuras esi apmeklējis un citu lietotāju lietotājvārdus. Tie nesatur pašas ziņas.", "Unhide Preview": "Rādīt priekšskatījumu", - "Announcements about Synapse releases": "Paziņojumi par \"Synapse\" izlaidumiem", - "Search the room directory": "Meklēt istabu katalogā", - "Please describe the bug and/or send logs.": "Lūdzu apraksti kļūdu un/vai nosūti logfailus.", "Unable to join network": "Nav iespējams pievienoties tīklam", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Droši vien Tu konfigurēji tās kādā citā Matrix klientā, nevis Riot. Nav iespējams tos pārkonfigurēt ar Riot, bet tie joprojām tiek izmantoti", "Sorry, your browser is not able to run Riot.": "Atvaino, diemžēl tavs tīmekļa pārlūks nespēj darbināt Riot.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Decentralizēta, šifrēta čata & kopdarbošanās sistēma uz [matrix] bāzes", "Uploaded on %(date)s by %(user)s": "Augšuplādēja %(user)s %(date)s", "Messages in group chats": "Ziņas grupas čatos", "Yesterday": "vakar", @@ -1174,16 +1127,13 @@ "Low Priority": "Zemas prioritātes", "Unable to fetch notification target list": "Neizdevās iegūt paziņojumu mērķu sarakstu", "Appear Offline": "Šķiet nesaistē (oflainā)", - "Get started with some tips from Riot Bot!": "Iepazīsties ar dažiem knifiem no Riot bota!", "Set Password": "Iestatīt paroli", "Enable audible notifications in web client": "Iespējot skaņus paziņojumus web klientā", "Permalink": "Pastāvīgā saite", - "Welcome to Riot.im": "Esiet gaidīti Riot.im", "Off": "izslēgts", "Riot does not know how to join a room on this network": "Riot nezin kā pievienoties šajā tīklā esošajai istabai", "Mentions only": "Vienīgi atsauces", "You can now return to your account after signing out, and sign in on other devices.": "Tagad vari atgriezties savā kontā arī pēc izrakstīšanās, un pierakstīties no citām ierīcēm.", - "Please install Chrome or Firefox for the best experience.": "Lūdzu instalē Chrome vai Firefox pārlūku labākai pārlūkošanas pieredzei.", "Enable email notifications": "Iespējot paziņojumus pa epastu", "Event Type": "Notikuma tips", "Download this file": "Lejupielādēt šo failu", @@ -1193,13 +1143,10 @@ "%(count)s Members|one": "%(count)s biedru", "Developer Tools": "Attīstītāja instrumenti", "View Source": "Skatīt avotu", - "Matrix technical discussions": "Matrix tehniskās diskusijas", "Event Content": "Notikuma saturs", "Thank you!": "Tencinam!", - "Building services on Matrix": "Uz Matrix bāzētu pakalpojumu izveide", "Collapse panel": "Sakļaut (saritināt) paneli", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Tavā pašreizējā pārlūkā aplikācijas izskats un uzvedība var būt pilnīgi neatbilstoša, kā arī dažas no visām funkcijām var nedarboties. Ja vēlies turpināt izmantot šo pārlūku, Tu vari arī turpināt, apzinoties, ka šajā gadījumā esi viens/a ar iespējamo problēmu!", "Checking for an update...": "Lūkojos pēc aktualizācijas...", - "General discussion about Matrix and Riot": "Galvenā diskusija par Matrix un Riot", "There are advanced notifications which are not shown here": "Pastāv papildus paziņojumi, kuri šeit netiek rādīti" } diff --git a/src/i18n/strings/ml.json b/src/i18n/strings/ml.json index 8edbeaf49f..098c062006 100644 --- a/src/i18n/strings/ml.json +++ b/src/i18n/strings/ml.json @@ -24,8 +24,6 @@ "Camera": "ക്യാമറ", "Fetching third party location failed": "തേഡ് പാര്‍ട്ടി ലൊക്കേഷന്‍ ഫെച്ച് ചെയ്യാന്‍ കഴിഞ്ഞില്ല", "A new version of Riot is available.": "റയട്ടിന്റെ ഒരു പുതിയ പതിപ്പ് ലഭ്യമാണ്.", - "Riot/Android & matrix-android-sdk chat": "റയട്ട്/ആന്‍ഡ്രോയ്ഡ്& matrix-android-sdk ചാറ്റ്", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "ബഗ് വിശദീകരിക്കുക. എന്ത് ചെയ്തപ്പോഴാണ് വന്നത് ? എന്തായിരുന്നു പ്രതീക്ഷിച്ചിരുന്നത് ? ശരിക്കും എന്താണ് സംഭവിച്ചത് ?", "All notifications are currently disabled for all targets.": "അറിയിപ്പുകളെല്ലാം നിര്‍ത്തിയിരിയ്ക്കുന്നു.", "Uploading report": "റിപ്പോര്‍ട്ട് അപ്ലോഡ് ചെയ്യുന്നു", "Sunday": "ഞായര്‍", @@ -35,30 +33,23 @@ "Failed to set direct chat tag": "ഡയറക്റ്റ് ചാറ്റ് ടാഗ് സെറ്റ് ചെയ്യാനായില്ല", "Today": "ഇന്ന്", "Failed to get protocol list from Home Server": "ഹോം സെര്‍വറില്‍ നിന്ന് പ്രോട്ടോക്കോള്‍ ലിസ്റ്റ് നേടാന്‍ സാധിച്ചില്ല", - "Report a bug": "ബഗ് റിപ്പോര്‍ട്ട് ചെയ്യുക", - "Implementing VR services with Matrix": "മട്രിക്സ് ഉപയോഗിച്ചു വി.അർ. സർവീസുകൾ നടപ്പിലാക്കുന്നു", "You are not receiving desktop notifications": "നിങ്ങള്‍ക്ക് ഇപ്പോള്‍ ഡെസ്ക്ടോപ്പ് നോട്ടിഫിക്കേഷനുകള്‍ ലഭിക്കുന്നില്ല", "Friday": "വെള്ളി", "Update": "പുതുക്കുക", - "You need to be using HTTPS to place a screen-sharing call.": "സ്ക്രീന്‍ ഷെയറിങ്ങ് കോള്‍ നടത്തണമെങ്കില്‍ https ഉപയോഗിക്കണം.", "What's New": "പുതിയ വിശേഷങ്ങള്‍", "Add an email address above to configure email notifications": "ഇ മെയില്‍ അറിയിപ്പുകൾ ലഭിക്കാന്‍ മുകളില്‍ ഇ-മെയില്‍ വിലാസം നല്‍കൂ", "Expand panel": "പാനല്‍ വലുതാക്കുക", "On": "ഓണ്‍", "Filter room names": "റൂം പേരുകള്‍ ഫില്‍ട്ടര്‍ ചെയ്യുക", "Changelog": "മാറ്റങ്ങളുടെ നാള്‍വഴി", - "Running Matrix services": "മാട്രിക്സ് സര്‍വീസുകള്‍ റണ്‍ ചെയ്യുന്നു", "Waiting for response from server": "സെര്‍വറില്‍ നിന്നുള്ള പ്രതികരണത്തിന് കാക്കുന്നു", "Leave": "വിടവാങ്ങുക", - "Failed to send report: ": "റിപ്പോര്‍ട്ട് അയക്കുവാന്‍ സാധിച്ചില്ല : ", - "Unknown device": "അപരിചിത ഡിവൈസ്", "Advanced notification settings": "അറിയപ്പുകളുടെ സങ്കീര്‍ണമായ സജ്ജീകരണങ്ങള്‍", "delete the alias.": "ഏലിയാസ് നീക്കം ചെയ്യുക.", "To return to your account in future you need to set a password": "വീണ്ടും ഈ അക്കൌണ്ട് ഉപയോഗിക്കണമെങ്കില്‍ ഒരു രഹസ്യവാക്ക് സെറ്റ് ചെയ്യുക", "Forget": "മറക്കുക", "World readable": "ആർക്കും വായിക്കാവുന്നത്", "#example": "#ഉദാഹരണം", - "Riot/Web & Desktop chat": "റയട്ട്/വെബ് & ഡെസ്ക്ടോപ്പ് ചാറ്റ്", "Hide panel": "പാനല്‍ ഒളിപ്പിക്കുക", "You cannot delete this image. (%(code)s)": "നിങ്ങള്‍ക്ക് ഈ ചിത്രം നീക്കം ചെയ്യാനാകില്ല. (%(code)s)", "Cancel Sending": "അയയ്ക്കുന്നത് റദ്ദാക്കുക", @@ -69,32 +60,22 @@ "Room not found": "റൂം കണ്ടെത്താനായില്ല", "Messages containing my display name": "എന്റെ പേര് അടങ്ങിയിരിക്കുന്ന സന്ദേശങ്ങള്‍ക്ക്", "Messages in one-to-one chats": "നേര്‍ക്കുനേര്‍ ചാറ്റിലെ സന്ദേശങ്ങള്‍ക്ക്", - "Contributing code to Matrix and Riot": "മാട്രിക്സിലേക്കും റയട്ടിലേക്കും കോഡ് സംഭാവന ചെയ്യാം", "Unavailable": "ലഭ്യമല്ല", - "Community-run support for Synapse": "സിനാപ്സിനുള്ള കമ്യൂണിറ്റി-നേതൃത്വത്തലുള്ള പിന്തുണ", "View Decrypted Source": "ഡീക്രിപ്റ്റ് ചെയ്ത സോഴ്സ് കാണുക", "Failed to update keywords": "കീവേഡുകള്‍ പുതുക്കുവാന്‍ സാധിച്ചില്ല", - "Welcome to Riot.im": "റയട്ടിലേക്ക് സ്വാഗതം", "Notifications on the following keywords follow rules which can’t be displayed here:": "ഈ പറയുന്ന കീവേർഡുകളെ പറ്റിയുള്ള അറിയിപ്പുകൾ പിൻതുടരുന്ന നിയമങ്ങൾ ഇവിടെ കാണിക്കുവാൻ സാധ്യമല്ല:", "Please set a password!": "ദയവായി ഒരു രഹസ്യവാക്ക് ക്രമീകരിക്കുക!", "You have successfully set a password!": "രഹസ്യവാക്ക് സജ്ജീകരിച്ചിരിക്കുന്നു!", - "Chat with Riot Bot": "റയട്ട് ബോട്ടുമായി ചാറ്റ് ചെയ്യുക", - "Support for those using, running and writing other bridges": "മറ്റ് ബ്രിഡ്ജുകള്‍ ഉപയോഗിക്കുന്ന, റണ്‍ ചെയ്യുന്ന, എഴുതുന്നവര്‍ക്കുള്ള പിന്തുണ", - "Admin support for Dendrite": "ഡെന്‍ഡ്രൈറ്റിനുള്ള അഡ്മിന്‍ പിന്തുണ", "An error occurred whilst saving your email notification preferences.": "ഇ-മെയില്‍ വഴി അറിയിയ്ക്കാനുള്ള നിങ്ങളുടെ സജ്ജീകരണങ്ങള്‍ സൂക്ഷിക്കുന്നതില്‍ ഒരു പ്രശ്നമുണ്ടായി.", "Source URL": "സോഴ്സ് യു ആര്‍ എല്‍", "Failed to add tag %(tagName)s to room": "റൂമിന് %(tagName)s എന്ന ടാഗ് ആഡ് ചെയ്യുവാന്‍ സാധിച്ചില്ല", "Members": "അംഗങ്ങള്‍", "No update available.": "അപ്ഡേറ്റുകള്‍ ലഭ്യമല്ല.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "മാട്രിക്സിലുള്ളതും പഴയ നെറ്റ്‍വര്‍ക്കുകളിലേക്ക് ( സ്ലാക്ക്, IRC, ഗിറ്റര്‍ മുതലായവ ) ലിങ്ക് ചെയ്തതുമൊക്കെയായ ധാരാളം റൂമുകളുണ്ട്. ഡയറക്റ്ററി പരിശാധിക്കൂ!", "Resend": "വീണ്ടും അയയ്ക്കുക", "Files": "ഫയലുകള്‍", "Collecting app version information": "ആപ്പ് പതിപ്പു വിവരങ്ങള്‍ ശേഖരിക്കുന്നു", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "റൂം ഏലിയാസ് %(alias)s നീക്കം ചെയ്യുകയും %(name)s കള്‍ ഡയറക്ടറിയില്‍ നിന്നും നീക്കം ചെയ്യുകയും ചെയ്യുക ?", - "customServer_text": "മറ്റ് മാട്രിക്സ് സെര്‍വറുകളില്‍ ലോഗിന്‍ ചെയ്യാന്‍ കസ്റ്റം സെര്‍വര്‍ ഓപ്ഷനില്‍ ഹോം സെര്‍വര്‍ യു ആര്‍ എല്‍ വ്യക്തമാക്കുക.
    ഇത് വഴി മറ്റൊരു ഹോം സെര്‍വറില്‍ ഉള്ള മാട്രിക്സ് അക്കൌണ്ട് റയട്ടില്‍ ഉപയോഗിക്കാം.

    അതു പോലെ, നിങ്ങള്‍ക്ക് കസ്റ്റം ഐഡന്റിറ്റി സെര്‍വറും ക്രമീകരിക്കാം. പക്ഷേ അപ്പോള്‍ നിങ്ങള്‍ക്ക് ആരേയും ഇമെയില്‍ വഴി ക്ഷണിക്കാനോ തിരിച്ചോ സാധിക്കില്ല.", - "Co-ordination for Riot/Web translators": "റയട്ട്/വെബ് പരിഭാഷകരുടെ കൂട്ടായ്മ", "This will allow you to return to your account after signing out, and sign in on other devices.": "സൈന്‍ ഔട്ട് ചെയ്ത ശേഷം വീണ്ടും നിങ്ങളുടെ അക്കൌണ്ടിലേക്ക് മടങ്ങി വരാനും, മറ്റ് ഡിവൈസുകളില്‍ സൈന്‍ ഇന്‍ ചെയ്യാനും ഇത് സഹായിക്കും.", - "Dev chat for the Dendrite dev team": "ഡെന്‍ഡ്രൈറ്റ് ഡെവലപ്പര്‍ ടീമിനുള്ള dev chat", "Keywords": "കീവേഡുകള്‍", "Enable notifications for this account": "ഈ അക്കൌണ്ടില്‍ നോട്ടിഫിക്കേഷനുകള്‍ ഇനേബിള്‍ ചെയ്യുക", "Directory": "ഡയറക്ടറി", @@ -106,7 +87,6 @@ "I understand the risks and wish to continue": "കുഴപ്പമാകാന്‍ സാധ്യതയുണ്ടെന്നെനിയ്ക്കു് മനസ്സിലായി, എന്നാലും മുന്നോട്ട് പോകുക", "Remove %(name)s from the directory?": "%(name)s കള്‍ ഡയറക്റ്ററിയില്‍ നിന്നും മാറ്റണോ ?", "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "റയട്ട് നൂതന ബ്രൌസര്‍ ഫീച്ചറുകള്‍ ഉപയോഗിക്കുന്നു. നിങ്ങളുടെ ബ്രൌസറില്‍ അവയില്‍ പലതും ഇല്ല / പൂര്‍ണ്ണമല്ല .", - "Please install Chrome or Firefox for the best experience.": "ഏറ്റവും മികച്ച ഉപയോഗത്തിനായി ഗൂഗിള്‍ ക്രോംബ്രൌസറോ അല്ലെങ്കില്‍ ഫയര്‍ഫോക്സ് ബ്രൌസറോ ഇന്‍സ്റ്റാള്‍ ചെയ്യൂ.", "Unnamed room": "പേരില്ലാത്ത റൂം", "All messages (noisy)": "എല്ലാ സന്ദേശങ്ങളും (ഉച്ചത്തിൽ)", "Saturday": "ശനി", @@ -114,15 +94,11 @@ "Direct Chat": "നേരിട്ടുള്ള ചാറ്റ്", "The server may be unavailable or overloaded": "സെര്‍വര്‍ ലഭ്യമല്ല അല്ലെങ്കില്‍ ഓവര്‍ലോഡഡ് ആണ്", "Reject": "നിരസിക്കുക", - "Riot is not supported on mobile web. Install the app?": "മൊബൈലില്‍ റയട്ട് വെബ് പിന്തുണ ഇല്ല. ആപ്പ് ഇന്‍സ്റ്റാള്‍ ചെയ്യാം ?", - "Discussion of all things Matrix!": "മാട്രിക്സിനെ കുറിച്ചുള്ള ചര്‍ച്ച!", "Failed to set Direct Message status of room": "റൂമില്‍ നിന്നും ഡയറക്റ്റ് മെസേജ് സ്റ്റാറ്റസ് സജ്ജീകരിക്കാന്‍ കഴിഞ്ഞില്ല", "Monday": "തിങ്കള്‍", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "നേരിട്ട പ്രശ്നം മനസ്സിലാക്കാന്‍, ഈ ക്ലയന്റില്‍ നിന്നുള്ള നാള്‍വഴികള്‍ ബഗ് റിപ്പോര്‍ട്ടിനൊപ്പം അയയ്ക്കും. അതിനു പകരം ഈ എഴുത്ത് മാത്രം അയച്ചാല്‍ മതിയെങ്കില്‍ ദയവായി ശരിച്ഛിഹ്നം ഒഴിവാക്കുക:", "Remove from Directory": "ഡയറക്റ്ററിയില്‍ നിന്നും നീക്കം ചെയ്യുക", "Enable them now": "ഇപ്പോള്‍ ഇനേബിള്‍ ചെയ്യുക", "Forward Message": "സന്ദേശം ഫോര്‍വേഡ് ചെയ്യുക", - "Describe your problem here.": "നിങ്ങള്‍ നേരിട്ട പ്രശ്നം ഇവിടെ വിവരിക്കാം.", "Messages containing my user name": "എന്റെ യൂസര്‍ നെയിം അടങ്ങിയിരിക്കുന്ന സന്ദേശങ്ങള്‍ക്ക്", "Collecting logs": "നാള്‍വഴി ശേഖരിക്കുന്നു", "more": "കൂടുതല്‍", @@ -135,47 +111,31 @@ "Send": "അയയ്ക്കുക", "Send logs": "നാള്‍വഴി അയയ്ക്കുക", "All messages": "എല്ലാ സന്ദേശങ്ങളും", - "Implementing VoIP services with Matrix": "മേട്രിക്സിന്മേൽ VoIP സർവീസുകൾ നടപ്പിലാക്കുന്നു", - "Dev chat for the Riot/Web dev team": "റയട്ട്/വെബ് ഡെവലപ്പര്‍ ടീമിനുള്ള dev chat", "Call invitation": "വിളിയ്ക്കുന്നു", - "Riot Desktop on %(platformName)s": "%(platformName)s ലെ റയട്ട് ഡെസ്ക്ടോപ്പ്", "Downloading update...": "അപ്ഡേറ്റ് ഡൌണ്‍ലോഡ് ചെയ്യുന്നു...", "You have successfully set a password and an email address!": "ഇമെയില്‍ വിലാസവും രഹസ്യവാക്കും വിജയകരമായി ക്രമീകരിച്ചിരിക്കുന്നു!", "What's new?": "എന്തൊക്കെ പുതിയ വിശേഷങ്ങള്‍ ?", - "Discussion of the Identity Service API": "ഐഡൻടിറ്റി സർവീസ് എപിഐ യെ പറ്റിയുള്ള ചർച്ച", - "Support for those using and running matrix-appservice-irc": "matrix-appservice-irc ഉപയോഗിക്കുന്നവര്‍ക്കും റണ്‍ ചെയ്യുന്നവര്‍ക്കുമുള്ള സപ്പോര്‍ട്ട്", - "Riot/iOS & matrix-ios-sdk chat": "റയട്ട്/iOS& matrix-ios-sdk ചാറ്റ്", "Notify me for anything else": "ബാക്കി ഏതിനും എനിക്ക് അറിയിപ്പു നൽകുക", "When I'm invited to a room": "ഞാന്‍ ഒരു റൂമിലേക്ക് ക്ഷണിക്കപ്പെടുമ്പോള്‍", - "Design and implementation of E2E in Matrix": "മാട്രിക്സിലെ e2eയുടെ ഡിസൈനും ഇമ്പ്ലിമെന്റേഷനും", "Can't update user notification settings": "ഉപയോക്താവിനെ അറിയിയ്ക്കാനുള്ള സജ്ജീകരണം പുതുക്കാനായില്ല", "Notify for all other messages/rooms": "ബാക്കി എല്ലാ സന്ദേശങ്ങൾക്കും/റൂമുകൾക്കും അറിയിപ്പു നൽകുക", "Unable to look up room ID from server": "സെര്‍വറില്‍ നിന്നും റൂം ഐഡി കണ്ടെത്താനായില്ല", "Couldn't find a matching Matrix room": "ആവശ്യപ്പെട്ട മാട്രിക്സ് റൂം കണ്ടെത്താനായില്ല", - "Support for those using the Matrix spec": "Matrix spec ഉപയോഗിക്കുന്നവര്‍ക്കുള്ള പിന്തുണ", - "Safari and Opera work too.": "സഫാരിയിലുംപിന്നെ ഓപ്പേറയിലുംപ്രവര്‍ത്തിക്കുന്നു.", - "Loading bug report module": "പിഴവുകള്‍ അറിയിയ്ക്കാനുള്ള ഘടകം ചേര്‍ക്കുന്നു", "Invite to this room": "ഈ റൂമിലേക്ക് ക്ഷണിക്കുക", "Search for a room": "ഒരു റൂം തിരയുക", "Thursday": "വ്യാഴം", "Search…": "തിരയുക…", - "%(appName)s via %(browserName)s on %(osName)s": "%(osName)sല്‍ %(browserName)s വഴി %(appName)s", "Back": "തിരികെ", "Unhide Preview": "പ്രിവ്യു കാണിക്കുക", - "Announcements about Synapse releases": "സിനാപ്സ് റിലീസുകളെ കുറിച്ചുള്ള അറിയിപ്പുകള്‍", - "Search the room directory": "റൂം ഡയറക്റ്ററിയില്‍ പരതുക", - "Please describe the bug and/or send logs.": "ബഗ് വിശദീകരിക്കുക , കൂടെ / അല്ലെങ്കില്‍ നാള്‍വഴികളും അയക്കുക.", "Unable to join network": "നെറ്റ്‍വര്‍ക്കില്‍ ജോയിന്‍ ചെയ്യാന്‍ കഴിയില്ല", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "ഇവ റയട്ടല്ലാതെ മറ്റൊരു ക്ലയന്റില്‍ വച്ച് കോണ്‍ഫിഗര്‍ ചെയ്തതാകാം. റയട്ടില്‍ അവ ലഭിക്കില്ല, എങ്കിലും അവ നിലവിലുണ്ട്", "Sorry, your browser is not able to run Riot.": "ക്ഷമിക്കണം, നിങ്ങളുടെ ബ്രൌസര്‍ റയട്ട് പ്രവര്‍ത്തിപ്പിക്കാന്‍ പര്യാപ്തമല്ല.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "വികേന്ദ്രീകൃത , എന്‍ക്രിപ്റ്റഡ് ചാറ്റ് & മാട്രിക്സ് നല്‍കുന്ന കൊളാബൊറേഷന്‍", "Uploaded on %(date)s by %(user)s": "%(date)s ല്‍ %(user)s അപ്ലോഡ് ചെയ്തത്", "Messages in group chats": "ഗ്രൂപ്പ് ചാറ്റുകളിലെ സന്ദേശങ്ങള്‍ക്ക്", "Yesterday": "ഇന്നലെ", "Error encountered (%(errorDetail)s).": "എറര്‍ നേരിട്ടു (%(errorDetail)s).", "Low Priority": "താഴ്ന്ന പരിഗണന", "Unable to fetch notification target list": "നോട്ടിഫിക്കേഷന്‍ ടാര്‍ഗെറ്റ് ലിസ്റ്റ് നേടാനായില്ല", - "Get started with some tips from Riot Bot!": "റയട്ട് ബോട്ടില്‍ നിന്നുള്ള നിര്‍ദേശങ്ങള്‍ സ്വീകരിച്ച് കൊണ്ട് തുടങ്ങൂ!", "Set Password": "രഹസ്യവാക്ക് സജ്ജീകരിക്കുക", "Enable audible notifications in web client": "വെബ് പതിപ്പിലെ അറിയിപ്പുകള്‍ കേള്‍ക്കാവുന്നതാക്കുക", "Permalink": "പെര്‍മാലിങ്ക്", @@ -192,11 +152,8 @@ "Download this file": "ഈ ഫയല്‍ ഡൌണ്‍ലോഡ് ചെയ്യുക", "Failed to change settings": "സജ്ജീകരണങ്ങള്‍ മാറ്റുന്നവാന്‍ സാധിച്ചില്ല", "View Source": "സോഴ്സ് കാണുക", - "Matrix technical discussions": "മാട്രിക്സ് സാങ്കേതിക ചര്‍ച്ച", - "Building services on Matrix": "മട്രിക്സിന്മേൽ സർവീസുകൾ പണിയുന്നു", "Collapse panel": "പാനല്‍ കൊളാപ്സ് ചെയ്യുക", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "നിങ്ങളുടെ ഇപ്പോളത്തെ ബ്രൌസര്‍ റയട്ട് പ്രവര്‍ത്തിപ്പിക്കാന്‍ പൂര്‍ണമായും പര്യാപത്മല്ല. പല ഫീച്ചറുകളും പ്രവര്‍ത്തിക്കാതെയിരിക്കാം. ഈ ബ്രൌസര്‍ തന്നെ ഉപയോഗിക്കണമെങ്കില്‍ മുന്നോട്ട് പോകാം. പക്ഷേ നിങ്ങള്‍ നേരിടുന്ന പ്രശ്നങ്ങള്‍ നിങ്ങളുടെ ഉത്തരവാദിത്തത്തില്‍ ആയിരിക്കും!", "Checking for an update...": "അപ്ഡേറ്റ് ഉണ്ടോ എന്ന് തിരയുന്നു...", - "General discussion about Matrix and Riot": "മാട്രിക്സിനേയും റയട്ടിനേയും കുറിച്ചുള്ള പൊതു ചര്‍ച്ച", "There are advanced notifications which are not shown here": "ഇവിടെ കാണിക്കാത്ത നൂതന നോട്ടിഫിക്കേഷനുകള്‍ ഉണ്ട്" } diff --git a/src/i18n/strings/nb_NO.json b/src/i18n/strings/nb_NO.json index dbeb2b9cd0..47da50122c 100644 --- a/src/i18n/strings/nb_NO.json +++ b/src/i18n/strings/nb_NO.json @@ -47,7 +47,6 @@ "Noisy": "Bråkete", "Failed to get protocol list from Home Server": "Kunne ikke hente protokolliste fra Hjemme-Server", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Slett rom alias %(alias)s og fjern %(name)s fra katalogen?", - "customServer_text": "Du kan benytte de egendefinerte serveralternativene til å logge deg på andre Matrix-servere ved å spesifisere en annen Hjemmeserver-URL.
    Dette lar deg benytte Riot med en eksisterende Matrix konto på en annen hjemmeserver.

    Du kan også angi en egendefinert identitetsserver, men du vil ikke kunne invitere brukere via e-post, eller bli invitert via e-post selv.", "Enable notifications for this account": "Aktiver varsler for denne konto", "Directory": "Katalog", "Failed to get public room list": "Kunne ikke hente offentlig romliste", @@ -86,7 +85,6 @@ "Notify for all other messages/rooms": "Varsler om alle andre meldinger/rom", "Unable to look up room ID from server": "Kunne ikke slå opp rom-ID fra serveren", "Couldn't find a matching Matrix room": "Kunne ikke finne et samsvarende Matrix rom", - "Safari and Opera work too.": "Safari og Opera fungerer også.", "Invite to this room": "Inviter til dette rommet", "You cannot delete this message. (%(code)s)": "Du kan ikke slette denne meldingen. (%(code)s)", "Thursday": "Torsdag", @@ -106,7 +104,6 @@ "#example": "#eksempel", "Failed to remove tag %(tagName)s from room": "Kunne ikke fjerne tagg %(tagName)s fra rommet", "Remove": "Fjern", - "Please install Chrome or Firefox for the best experience.": "Vennligst installer Chrome eller Firefox for den beste opplevelsen.", "Enable email notifications": "Aktiver e-postvarsler", "No rooms to show": "Ingen rom å vise", "Download this file": "Last ned filen", diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index 30cfdeb63f..5647c1f4ef 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -29,7 +29,6 @@ "Banned users": "Verbannen gebruikers", "Bans user with given id": "Verbant de gebruiker met het gegeven ID", "Blacklisted": "Buitengesloten", - "Bug Report": "Bug report", "Bulk Options": "Bulk opties", "Call Timeout": "Gesprek time-out", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Kan niet met de thuisserver verbinden via HTTP wanneer er een HTTPS-URL in je browser balk staat. Gebruik HTTPS of activeer onveilige scripts.", @@ -262,7 +261,6 @@ "Forgot your password?": "Wachtwoord vergeten?", "For security, this session has been signed out. Please sign in again.": "Voor veiligheidsredenen is deze sessie uitgelogd. Log alsjeblieft opnieuw in.", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "In verband met veiligheidsredenen zullen alle end-to-endbeveiligingsleutels van deze browser verwijderd worden. Als je je gespreksgeschiedenis van toekomstige Riot sessies wilt kunnen ontsleutelen, exporteer en bewaar dan de ruimte sleutels.", - "Found a bug?": "Een fout gevonden?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s van %(fromPowerLevel)s naar %(toPowerLevel)s", "Guest access is disabled on this Home Server.": "Gasttoegang is uitgeschakeld op deze thuisserver.", "Guests cannot join this room even if explicitly invited.": "Gasten kunnen niet tot deze ruimte toetreden, zelfs als ze expliciet uitgenodigd zijn.", @@ -340,7 +338,6 @@ "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 end-to-endbeveiligingssleutels 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.", "Results from DuckDuckGo": "Resultaten van DuckDuckGo", "Return to login screen": "Naar het inlogscherm terugkeren", @@ -654,7 +651,6 @@ "Do you want to load widget from URL:": "Wil je de widget laden van de URL:", "Edit": "Aanpassen", "Enable automatic language detection for syntax highlighting": "Automatische taaldetectie voor zinsbouwmarkeringen aanzetten", - "Hide Apps": "Apps verbergen", "Hide join/leave messages (invites/kicks/bans unaffected)": "Toetreed/verlaat berichten verbergen (uitnodigingen/verwijderingen/verbanningen zullen ongeschonden blijven)", "Integrations Error": "Integratiesfout", "Publish this room to the public in %(domain)s's room directory?": "Deze ruimte publiekelijk maken in %(domain)s's ruimte catalogus?", @@ -663,7 +659,6 @@ "NOTE: Apps are not end-to-end encrypted": "OPMERKING: Apps zijn niet end-to-endbeveiligd", "Revoke widget access": "Toegang tot widget intrekken", "Sets the room topic": "Wijzigt het ruimte-onderwerp", - "Show Apps": "Apps Weergeven", "The maximum permitted number of widgets have already been added to this room.": "Het maximum aantal toegestane widgets is al aan deze ruimte toegevoegd.", "To get started, please pick a username!": "Om te beginnen, kies een gebruikersnaam!", "Unable to create widget.": "Niet in staat om een widget te maken.", @@ -925,7 +920,6 @@ "Leave Community": "Gemeenschap Verlaten", "Leave %(groupName)s?": "%(groupName)s verlaten?", "Leave": "Verlaten", - "Unable to leave room": "De ruimte kon niet verlaten worden", "Community Settings": "Gemeenschapsinstellingen", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Deze ruimtes worden aan gemeenschapsleden getoond op de gemeenschapspagina. Gemeenschapsleden kunnen tot de ruimtes toetreden door er op te klikken.", "%(inviter)s has invited you to join this community": "%(inviter)s heeft jou uitgenodigd om tot deze gemeenschap toe te treden", @@ -937,8 +931,6 @@ "Community %(groupId)s not found": "Gemeenschap %(groupId)s is niet gevonden", "This Home server does not support communities": "Deze Thuisserver ondersteunt geen gemeenschappen", "Failed to load %(groupId)s": "Het is niet gelukt om %(groupId)s te laden", - "Cryptography data migrated": "Cryptografie gegevens zijn gemigreerd", - "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "Een eenmalige migratie van cryptografie gegevens heeft plaatsgevonden. Eind-tot-eind versleuteling zal niet werken als je terug gaat naar een oudere versie van Riot. Log eerst uit op Riot als je eind-tot-eind versleuteling wil gebruiken op een oudere versie. Exporteer je sleutels en importeer ze achteraf weer als je de berichtgeschiedenis wilt behouden.", "Old cryptography data detected": "Oude cryptografie gegevens gedetecteerd", "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Er zijn gegevens van een oudere versie van Riot gedetecteerd. Dit zal eind-tot-eind versleuteling laten storen in de oudere versie. Eind-tot-eind berichten dat recent zijn uitgewisseld zal misschien niet ontsleutelbaar zijn in deze versie. Dit zou er misschien ook voor kunnen zorgen dat berichten die zijn uitgewisseld in deze versie falen. Indien je problemen ervaart, log opnieuw in. Om de berichtgeschiedenis te behouden, exporteer de sleutels en importeer ze achteraf weer.", "Your Communities": "Jouw Gemeenschappen", @@ -997,8 +989,6 @@ "Failed to add tag %(tagName)s to room": "Het is niet gelukt om de label %(tagName)s aan deze ruimte toe te voegen", "Fetching third party location failed": "Het ophalen van de locatie van de derde partij is mislukt", "A new version of Riot is available.": "Er is een nieuwe versie van Riot beschikbaar.", - "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk-chat", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Beschrijf de bug. Wat deed u? Wat verwachtte u? Wat gebeurde er daadwerkelijk?", "I understand the risks and wish to continue": "Ik begrijp de risico's en wil graag verder gaan", "Couldn't load home page": "Kon de home pagina niet laden", "Send Account Data": "Stuur account informatie", @@ -1008,12 +998,9 @@ "Notification targets": "Meldingsdoelen", "Today": "Vandaag", "Files": "Bestanden", - "Report a bug": "Een bug rapporteren", - "Implementing VR services with Matrix": "Implementatie van VR-diensten met Matrix", "You are not receiving desktop notifications": "Je ontvangt momenteel geen desktopmeldingen", "Friday": "Vrijdag", "Update": "Bijwerken", - "You need to be using HTTPS to place a screen-sharing call.": "U moet HTTPS gebruiken om een oproep met schermdelen te kunnen starten.", "What's New": "Wat is er nieuw", "Add an email address above to configure email notifications": "Voeg een e-mailadres toe om e-mailmeldingen te ontvangen", "Expand panel": "Paneel uitklappen", @@ -1021,17 +1008,13 @@ "%(count)s Members|other": "%(count)s Deelnemers", "Filter room names": "Filter kamernamen", "Changelog": "Logboek van wijzigingen", - "Running Matrix services": "Matrixdiensten beheren", "Waiting for response from server": "Wachten op antwoord van de server", "Send Custom Event": "Verzend aangepast evenement", - "Failed to send report: ": "Rapport verzenden mislukt: ", - "Unknown device": "Onbekend apparaat", "Advanced notification settings": "Geavanceerde meldingsinstellingen", "delete the alias.": "verwijder de alias.", "To return to your account in future you need to set a password": "Om in de toekomst naar je account terug te gaan moet je een wachtwoord instellen", "Forget": "Vergeten", "#example": "#voorbeeld", - "Riot/Web & Desktop chat": "Riot/Web & Desktop-chat", "Hide panel": "Paneel verbergen", "You cannot delete this image. (%(code)s)": "Je kunt deze afbeelding niet verwijderen. (%(code)s)", "Cancel Sending": "Versturen annuleren", @@ -1041,9 +1024,7 @@ "Error saving email notification preferences": "Fout bij het opslaan van de meldingsvoorkeuren voor e-mail", "Messages containing my display name": "Berichten die mijn weergavenaam bevatten", "Messages in one-to-one chats": "Berichten in één-op-één-gesprekken", - "Contributing code to Matrix and Riot": "Code bijdragen aan Matrix en Riot", "Unavailable": "Niet beschikbaar", - "Community-run support for Synapse": "Synapse-ondersteuning vanuit de gemeenschap", "View Decrypted Source": "Bekijk ontsleutelde bron", "Failed to update keywords": "Trefwoorden bijwerken mislukt", "remove %(name)s from the directory.": "verwijder %(name)s uit de kamerlijst.", @@ -1051,9 +1032,6 @@ "Safari and Opera work too.": "Safari en Opera werken ook.", "Please set a password!": "Stel een wachtwoord in!", "You have successfully set a password!": "U heeft met succes een wachtwoord ingesteld!", - "Chat with Riot Bot": "Met Riot Bot chatten", - "Support for those using, running and writing other bridges": "Ondersteuning voor het gebruiken, draaien en ontwikkelen aan andere bruggen", - "Admin support for Dendrite": "Beheerondersteuning voor Dendrite", "An error occurred whilst saving your email notification preferences.": "Er is een fout opgetreden tijdens het opslaan van uw e-mailmeldingsvoorkeuren.", "Explore Room State": "Verken Ruimtetoestand", "Source URL": "Bron-URL", @@ -1061,15 +1039,11 @@ "Filter results": "Resultaten filteren", "Members": "Leden", "No update available.": "Geen update beschikbaar.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Veel kamers bestaan al in Matrix, gelinkt aan bestaande netwerken (Slack, IRC, Gitter, enz.) of onafhankelijk. Bekijk de kamerlijst!", "Noisy": "Luidruchtig", "Failed to get protocol list from Home Server": "Protocollijst ophalen van de homeserver mislukt", "Collecting app version information": "App-versieinformatie verzamelen", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "De alias %(alias)s verwijderen en %(name)s uit de kamerlijst verwijderen?", - "customServer_text": "U kunt de aangepaste serverinstellingen gebruiken om in te loggen bij andere Matrix-servers door een andere homeserver-URL in te voeren.
    Dit maakt het mogelijk om Riot te gebruiken met een bestaand Matrix-account op een andere homeserver.

    U kunt ook een aangepaste identiteitsserver instellen, maar het is dan niet mogelijk om gebruikers uit te nodigen met behulp van een e-mailadres of zelf uitgenodigd te worden met een e-mailadres.", - "Co-ordination for Riot/Web translators": "Coördinatie voor Riot/Web-vertalers", "This will allow you to return to your account after signing out, and sign in on other devices.": "Hiermee kunt u naar uw account terugkeren nadat u zich heeft afgemeld, en u aanmelden op andere apparaten.", - "Dev chat for the Dendrite dev team": "Dev-chat voor het Dendrite-ontwikkelteam", "Keywords": "Trefwoorden", "Enable notifications for this account": "Meldingen voor dit account aanzetten", "Directory": "Kamerlijst", @@ -1093,16 +1067,11 @@ "Direct Chat": "Privégesprek", "The server may be unavailable or overloaded": "De server is misschien niet beschikbaar of overbelast", "Reject": "Afwijzen", - "Riot is not supported on mobile web. Install the app?": "Riot wordt niet ondersteund op het mobiele web. Wil je de app installeren?", - "Discussion of all things Matrix!": "Discussie over alles wat met Matrix te maken heeft!", "Failed to set Direct Message status of room": "Het is mislukt om de directe-berichtenstatus van de kamer in te stellen", "Monday": "Maandag", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Om diagnose van het probleem mogelijk te maken worden logboeken van deze client met het bugrapport meegestuurd. Schakel dit vinkje uit als u slechts de bovenstaande tekst mee wil sturen:", - "Send Custom State Event": "Verzend aangepast State Event", "All messages (noisy)": "Alle berichten (luid)", "Enable them now": "Deze nu aanzetten", "Messages containing my user name": "Berichten die mijn gebruikersnaam bevatten", - "Describe your problem here.": "Beschrijf uw probleem hier.", "Toolbox": "Eigenschappen", "Collecting logs": "Logboeken verzamelen", "more": "meer", @@ -1114,44 +1083,28 @@ "Failed to get public room list": "Lijst met publieke kamers ophalen mislukt", "Send logs": "Logboeken versturen", "All messages": "Alle berichten", - "Implementing VoIP services with Matrix": "Implementatie van VoIP-diensten met Matrix", - "Dev chat for the Riot/Web dev team": "Dev-chat voor het Riot/Web ontwikkelteam", "Call invitation": "Oproep-uitnodiging", - "Riot Desktop on %(platformName)s": "Riot Desktop op %(platformName)s", "Downloading update...": "Update aan het downloaden...", "State Key": "Toestandssleutel", "Failed to send custom event.": "Aangepast Event verzenden mislukt.", "What's new?": "Wat is er nieuw?", - "Discussion of the Identity Service API": "Discussie over de Identity Service API", - "Support for those using and running matrix-appservice-irc": "Ondersteuning voor gebruikers en beheerders van matrix-appservice-irc", - "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk-chat", "Notify me for anything else": "Stuur een melding voor al het andere", "When I'm invited to a room": "Wanneer ik uitgenodigd word voor een kamer", - "Design and implementation of E2E in Matrix": "Ontwerp en implementatie van E2E in Matrix", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Je kan de custom server opties gebruiken om op andere Matrix server in te loggen door een andere Home server URL op te geven.
    Dit laat je toe om Riot te gebruiken met een bestaande Matrix account op een andere home server.

    Je kan ook een custom identiteits-server opzetten maar dan kan je geen gebruikers uitnodigen via hun email adres, of zelf uitgenodigd worden via je email adres.", "Can't update user notification settings": "Het is niet gelukt om de meldingsinstellingen van de gebruiker bij te werken", "Notify for all other messages/rooms": "Stuur een melding voor alle andere berichten/kamers", "Unable to look up room ID from server": "Het is mislukt om de kamer-ID op te halen van de server", "Couldn't find a matching Matrix room": "Het is niet gelukt om een bijbehorende Matrix-kamer te vinden", - "Support for those using the Matrix spec": "Ondersteuning voor gebruikers van Matrix-specificatie", - "Safari and Opera work too.": "Safari en Opera werken ook.", - "Loading bug report module": "Bugrapporteermodule laden", "All Rooms": "Alle kamers", "You cannot delete this message. (%(code)s)": "Je kunt dit bericht niet verwijderen. (%(code)s)", "Thursday": "Donderdag", "Forward Message": "Bericht doorsturen", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s via %(browserName)s op %(osName)s", "Back": "Terug", "Reply": "Beantwoord", "Show message in desktop notification": "Toon boodschap in bureaublad popup", "Unhide Preview": "Zichtbaar maken preview", - "Announcements about Synapse releases": "Aankondigingen over Synapse-uitgaven", - "Search the room directory": "De kamerlijst doorzoeken", - "Please describe the bug and/or send logs.": "Beschrijf de bug en/of verstuur logboeken.", "Unable to join network": "Het is mislukt om toe te treden tot dit netwerk", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Je hebt ze mogelijk ingesteld in een andere client dan Riot. Je kunt ze niet aanpassen in Riot maar ze zijn wel actief", "Sorry, your browser is not able to run Riot.": "Sorry, uw browser werkt niet met Riot.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Gedecentaliseerd en versleuteld chatten & samenwerken mogelijk gemaakt door [matrix]", "Uploaded on %(date)s by %(user)s": "Geüpload op %(date)s door %(user)s", "Messages in group chats": "Berichten in groepsgesprekken", "Yesterday": "Gisteren", @@ -1160,17 +1113,14 @@ "Low Priority": "Lage prioriteit", "Unable to fetch notification target list": "Het is mislukt om de lijst van notificatiedoelen op te halen", "Appear Offline": "Lijk offline", - "Get started with some tips from Riot Bot!": "Begin met enkele tips van Riot Bot!", "Set Password": "Wachtwoord instellen", "Enable audible notifications in web client": "Geluidsmeldingen in de webclient aanzetten", "Permalink": "Permanente link", - "Welcome to Riot.im": "Welkom bij Riot.im", "Off": "Uit", "Riot does not know how to join a room on this network": "Riot weet niet hoe het moet deelnemen in een kamer op dit netwerk", "Mentions only": "Alleen vermeldingen", "Wednesday": "Woensdag", "You can now return to your account after signing out, and sign in on other devices.": "U kunt nu terugkeren naar uw account nadat u bent afgemeld, en u aanmelden op andere apparaten.", - "Please install Chrome or Firefox for the best experience.": "Installeer Chrome of Firefox voor de beste ervaring.", "Enable email notifications": "E-mailmeldingen aanzetten", "Event Type": "Event-type", "Download this file": "Download dit bestand", @@ -1180,13 +1130,10 @@ "%(count)s Members|one": "%(count)s Deelnemer", "Event sent!": "Event verstuurd!", "View Source": "Bekijk bron", - "Matrix technical discussions": "Technische discussies over Matrix", "Event Content": "Event-inhoud", "Thank you!": "Bedankt!", - "Building services on Matrix": "Diensten op Matrix bouwen", "Collapse panel": "Paneel inklappen", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Met uw huidige browser kan de applicatie er volledig incorrect uitzien. Tevens is het mogelijk dat niet alle functies naar behoren werken. U kunt doorgaan als u het toch wil proberen, maar bij problemen bent u volledig op uzelf aangewezen!", "Checking for an update...": "Aan het kijken voor een update...", - "General discussion about Matrix and Riot": "Algemene discussie over Matrix en Riot", "There are advanced notifications which are not shown here": "Er zijn geavanceerde notificaties die hier niet getoond worden" } diff --git a/src/i18n/strings/pl.json b/src/i18n/strings/pl.json index 052fa53907..042df8aebc 100644 --- a/src/i18n/strings/pl.json +++ b/src/i18n/strings/pl.json @@ -138,7 +138,6 @@ "Missing Media Permissions, click here to request.": "Brakuje uprawnień mediów. Kliknij tutaj, aby ich zażądać.", "and %(count)s others...|other": "i %(count)s innych...", "and %(count)s others...|one": "i jeden inny...", - "Bug Report": "Raport błędu", "Bulk Options": "Masowe opcje", "Call Timeout": "Upłynął limit czasu połączenia", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Nie można nawiązać połączenia z serwerem - proszę sprawdź twoje połączenie, upewnij się, że certyfikat SSL serwera jest zaufany, i że dodatki przeglądarki nie blokują żądania.", @@ -257,7 +256,6 @@ "Forgot your password?": "Zapomniałeś hasła?", "For security, this session has been signed out. Please sign in again.": "Ze względów bezpieczeństwa ta sesja została wylogowana. Zaloguj się jeszcze raz.", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Ze względów bezpieczeństwa, wylogowanie skasuje z tej przeglądarki wszystkie klucze szyfrowania końcówka-do-końcówki. Jeśli chcesz móc odszyfrować swoje historie konwersacji z przyszłych sesji Riot-a, proszę wyeksportuj swoje klucze pokojów do bezpiecznego miejsca.", - "Found a bug?": "Znalazłeś błąd?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s z %(fromPowerLevel)s na %(toPowerLevel)s", "Guest access is disabled on this Home Server.": "Dostęp dla gości jest wyłączony na tym serwerze.", "Deops user with given id": "Usuwa prawa administratora użytkownikowi o danym ID", @@ -379,9 +377,7 @@ "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s usunął swoją nazwę ekranową (%(oldDisplayName)s).", "%(senderName)s removed their profile picture.": "%(senderName)s usunął swoje zdjęcie profilowe.", "Remove %(threePid)s?": "Usunąć %(threePid)s?", - "Hide Apps": "Ukryj aplikacje", "%(senderName)s requested a VoIP conference.": "%(senderName)s zażądał grupowego połączenia głosowego VoIP.", - "Report it": "Zgłoś", "Results from DuckDuckGo": "Wyniki z DuckDuckGo", "Return to login screen": "Wróć do ekranu logowania", "Riot does not have permission to send you notifications - please check your browser settings": "Riot nie ma uprawnień, by wysyłać ci powiadomienia - sprawdź ustawienia swojej przeglądarki", @@ -420,7 +416,6 @@ "%(senderName)s set a profile picture.": "%(senderName)s ustawił zdjęcie profilowe.", "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s ustawił swoją nazwę na %(displayName)s.", "Sets the room topic": "Ustaw temat pokoju", - "Show Apps": "Pokaż aplikacje", "Show panel": "Pokaż panel", "Show Text Formatting Toolbar": "Pokaż pasek narzędzi formatowania tekstu", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Pokaż czas w formacie 12-sto godzinnym (n.p. 2:30pm)", @@ -701,8 +696,6 @@ "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "Zapisujemy również każdą stronę, z której korzystasz w aplikacji (obecnie ), twój User Agent () oraz rozdzielczość ekranu twojego urządzenia ().", "Fetching third party location failed": "Pobranie lokalizacji zewnętrznej nie powiodło się", "A new version of Riot is available.": "Dostępna jest nowa wersja Riot.", - "Riot/Android & matrix-android-sdk chat": "Czat o Riot/Android i matrix-android-sdk", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Proszę opisz problem (w miarę możliwości po angielsku). Co doprowadziło do błędu? Jakie było Twoje oczekiwanie, a co stało się zamiast tego?", "Couldn't load home page": "Nie można załadować strony startowej", "Send Account Data": "Wyślij dane konta", "All notifications are currently disabled for all targets.": "Wszystkie powiadomienia są obecnie wyłączone dla wszystkich celów.", @@ -714,12 +707,9 @@ "Failed to set direct chat tag": "Nie udało się ustawić znacznika rozmów bezpośrednich", "Today": "Dzisiaj", "Failed to get protocol list from Home Server": "Nie można pobrać listy protokołów z serwera domowego", - "Report a bug": "Zgłoś błąd", - "Implementing VR services with Matrix": "Implementowanie usług wirtualnej rzeczywistości w oparciu o Matrix", "You are not receiving desktop notifications": "Nie otrzymujesz powiadomień na pulpit", "Friday": "Piątek", "Update": "Uaktualnienie", - "You need to be using HTTPS to place a screen-sharing call.": "Musisz używać bezpiecznego protokołu HTTPS aby użyć połączenia współdzielenia ekranu.", "What's New": "Co nowego", "Add an email address above to configure email notifications": "Dodaj adres e-mail powyżej, aby skonfigurować powiadomienia e-mailowe", "Expand panel": "Rozwiń panel", @@ -727,12 +717,9 @@ "%(count)s Members|other": "%(count)s Członków", "Filter room names": "Filtruj nazwy pokojów", "Changelog": "Dziennik zmian", - "Running Matrix services": "Utrzymywanie usług Matrix", "Waiting for response from server": "Czekam na odpowiedź serwera", "Leave": "Opuść", "Send Custom Event": "Wyślij niestandardowe wydarzenie", - "Failed to send report: ": "Nie udało się wysłać raportu: ", - "Unknown device": "Nieznane urządzenie", "Advanced notification settings": "Zaawansowane ustawienia powiadomień", "Failed to send logs: ": "Niepowodzenie wysyłki zapisu rozmów ", "delete the alias.": "usunąć alias.", @@ -740,7 +727,6 @@ "Forget": "Zapomnij", "World readable": "Całkowicie publiczne", "#example": "#przykład", - "Riot/Web & Desktop chat": "Czat o Riot/Web i Desktop", "Hide panel": "Ukryj panel", "You cannot delete this image. (%(code)s)": "Nie możesz usunąć tego obrazka. (%(code)s)", "Cancel Sending": "Anuluj wysyłanie", @@ -751,9 +737,7 @@ "Error saving email notification preferences": "Wystąpił błąd podczas zapisywania ustawień powiadomień e-mailowych", "Messages containing my display name": "Wiadomości zawierające moją wyświetlaną nazwę", "Messages in one-to-one chats": "Wiadomości w rozmowach jeden-na-jeden", - "Contributing code to Matrix and Riot": "Wspieranie rozwoju Matrix i Riot", "Unavailable": "Niedostępny", - "Community-run support for Synapse": "Wsparcie społeczności dla Synapse", "View Decrypted Source": "Pokaż zdeszyfrowane źródło", "Send": "Wyślij", "Notes:": "Notatki:", @@ -762,9 +746,6 @@ "Safari and Opera work too.": "Safari i Opera również się sprawdzą.", "Please set a password!": "Proszę, ustaw hasło!", "You have successfully set a password!": "Hasło zostało zmienione z powodzeniem!", - "Chat with Riot Bot": "Rozmowa z Botem Riota", - "Support for those using, running and writing other bridges": "Wsparcie dla używających, zapewniających i piszących inne mosty", - "Admin support for Dendrite": "Wsparcie administratorskie dla Dendrite", "An error occurred whilst saving your email notification preferences.": "Podczas zapisywania ustawień powiadomień e-mail wystąpił błąd.", "Explore Room State": "Przeglądaj stan pokoju", "Source URL": "Źródłowy URL", @@ -772,15 +753,11 @@ "Filter results": "Filtruj wyniki", "Members": "Członkowie", "No update available.": "Brak aktualizacji.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Matrix ma wiele, już działających pokoi, połączonych z istniejącymi sieciami, takimi jak Slack, IRC lub Gitter, a także wiele zupełnie niezależnych. Możesz przejrzeć je wszystkie w spisie pokoi!", "Noisy": "Głośny", "Files": "Pliki", "Collecting app version information": "Zbieranie informacji o wersji aplikacji", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Usuń alias %(alias)s i usuń %(name)s z katalogu?", - "customServer_text": "Możesz używać opcji serwera niestandardowego do logowania się na inne serwery Matrix, określając inny adres URL serwera domowego.
    Pozwala to na wykorzystanie Riot z istniejącym kontem Matrix na innym serwerze domowym.

    Można również ustawić niestandardowy serwer tożsamości, ale nie będzie można zapraszać użytkowników adresem e-mail, ani być zaproszonym przez adres e-mailowy.", - "Co-ordination for Riot/Web translators": "Koordynacja tłumaczy Riot/Web", "This will allow you to return to your account after signing out, and sign in on other devices.": "To pozwoli Ci powrócić do Twojego konta po wylogowaniu i ponownym zalogowaniu się na innych urządzeniach.", - "Dev chat for the Dendrite dev team": "Czat deweloperów zespołu Dendrite", "Keywords": "Słowa kluczowe", "Enable notifications for this account": "Włącz powiadomienia na tym koncie", "Directory": "Księga adresowa", @@ -796,7 +773,6 @@ "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot używa wiele zaawansowanych technologii, które nie są dostępne lub są w fazie testów w Twojej przeglądarce.", "Developer Tools": "Narzędzia programistyczne", "Preparing to send logs": "Przygotowywanie do wysłania zapisu rozmów", - "Please install Chrome or Firefox for the best experience.": "Zainstaluj proszę Chrome lub Firefox.", "Unnamed room": "Pokój bez nazwy", "Remember, you can always set an email address in user settings if you change your mind.": "Pamiętaj, że zawsze możesz zmienić swój e-mail lub hasło w panelu ustawień użytkownika.", "Explore Account Data": "Odkryj dane konta", @@ -807,16 +783,11 @@ "Direct Chat": "Rozmowa bezpośrednia", "The server may be unavailable or overloaded": "Serwer jest nieosiągalny lub jest przeciążony", "Reject": "Odrzuć", - "Riot is not supported on mobile web. Install the app?": "Riot nie jest obsługiwany przez przeglądarki mobilne. Zainstaluj aplikację?", - "Discussion of all things Matrix!": "Rozmowa o wszystkim Matrixowym!", "Failed to set Direct Message status of room": "Nie udało się ustawić statusu Rozmów Bezpośrednich dla pokoju", "Monday": "Poniedziałek", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "W celu zdiagnozowania problemów logi z tego klienta zostaną wysłane wraz z tym raportem o błędzie. Jeśli wolisz wysłać tylko tekst powyżej, proszę odznacz:", - "Send Custom State Event": "Wyślij wydarzenie o niestandardowym stanie", "Remove from Directory": "Usuń z katalogu", "Enable them now": "Włącz je teraz", "Messages containing my user name": "Wiadomości zawierające moją nazwę użytkownika", - "Describe your problem here.": "Opisz swój problem tutaj.", "Toolbox": "Przybornik", "Collecting logs": "Zbieranie dzienników", "more": "więcej", @@ -832,47 +803,31 @@ "Failed to update keywords": "Nie udało się zaktualizować słów kluczowych", "Send logs": "Wyślij logi", "All messages": "Wszystkie wiadomości", - "Implementing VoIP services with Matrix": "Implementowanie usług telefonii internetowej VoIP w oparciu o Matrix", - "Dev chat for the Riot/Web dev team": "Czat deweloperów zespołu Riot/Web", "Call invitation": "Zaproszenie do rozmowy", - "Riot Desktop on %(platformName)s": "Riot Desktop na %(platformName)s", "Downloading update...": "Pobieranie aktualizacji...", "State Key": "Klucz stanu", "Failed to send custom event.": "Wysyłanie niestandardowego wydarzenia nie powiodło się.", "What's new?": "Co nowego?", - "Discussion of the Identity Service API": "Dyskusja na temat API Identity Service", - "Support for those using and running matrix-appservice-irc": "Wsparcie dla hostujących i korzystających z matrix-appservice-irc", - "Riot/iOS & matrix-ios-sdk chat": "Czat o Riot/iOS i matrix-ios-sdk", "Notify me for anything else": "Powiadom mnie o całej reszcie", "When I'm invited to a room": "Kiedy zostanę zaproszony do pokoju", - "Design and implementation of E2E in Matrix": "Projektowanie i implementacja szyfrowania klient-klient (end-to-end) w Matrix", "Click here to create a GitHub issue.": "Kliknij tutaj aby założyć wątek na GitHubie dot. problemu.", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Możesz skorzystać z opcji dedykowanego serwera, aby zalogować się na inne serwery Matrix, podając inny adres URL serwera Domowego.
    Pozwala to na używanie Riot z istniejącym kontem Matrix na innym serwerze domowym.

    Możesz również ustawić dedykowany serwer tożsamości, ale nie będziesz w stanie zapraszać użytkowników przez adres email, lub otrzymywać zaproszeń na adres email.", "Can't update user notification settings": "Nie można zaktualizować ustawień powiadomień użytkownika", "Notify for all other messages/rooms": "Powiadamiaj o wszystkich innych wiadomośsciach/pokojach", "Unable to look up room ID from server": "Nie można wyszukać ID pokoju na serwerze", "Couldn't find a matching Matrix room": "Nie można znaleźć pasującego pokoju Matrix", - "Support for those using the Matrix spec": "Wsparcie dla używających specyfikacji Matrix", - "Safari and Opera work too.": "Safari i Opera też działają.", - "Loading bug report module": "Ładowanie modułu raportu błędów", "Invite to this room": "Zaproś do tego pokoju", "Search for a room": "Szukaj pokoju", "Thursday": "Czwartek", "Search…": "Szukaj…", "Logs sent": "Zapis rozmów wysłany", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s przez %(browserName)s na %(osName)s", "Back": "Powrót", "Reply": "Odpowiedz", "Show message in desktop notification": "Pokaż wiadomość w notyfikacji na pulpicie", "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Dziennik błędów zawiera dane użytkowania aplikacji, w tym: twoją nazwę użytkownika, numery ID, aliasy pokojów i grup które odwiedzałeś i loginy innych użytkowników. Nie zawiera wiadomości.", "Unhide Preview": "Odkryj podgląd", - "Announcements about Synapse releases": "Ogłoszenia na temat Synapse", - "Search the room directory": "Wyszukaj katalog pokojów", - "Please describe the bug and/or send logs.": "Proszę opisz błąd i/lub wyślij logi.", "Unable to join network": "Nie można dołączyć do sieci", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Możliwe, że skofigurowałeś je w innym kliencie, niż Riot. Nie możesz ich zmieniać w Riot, ale nadal mają zastosowanie", "Sorry, your browser is not able to run Riot.": "Przepraszamy, Twoja przeglądarka nie jest w stanie uruchomić Riot.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Zdecentralizowany, szyfrowany czat & współpraca wspierana przez [matrix]", "Uploaded on %(date)s by %(user)s": "Wysłane %(date)s przez %(user)s", "Messages in group chats": "Wiadomości w czatach grupowych", "Yesterday": "Wczoraj", @@ -881,11 +836,9 @@ "Low Priority": "Niski priorytet", "Unable to fetch notification target list": "Nie można pobrać listy docelowej dla powiadomień", "Appear Offline": "Ustaw status niedostępny", - "Get started with some tips from Riot Bot!": "Rozpocznij z wskazówkami Riot Bota!", "Set Password": "Ustaw hasło", "Enable audible notifications in web client": "Włącz dźwiękowe powiadomienia w kliencie internetowym", "Permalink": "Odnośnik bezpośredni", - "Welcome to Riot.im": "Witamy w Riot.im", "Off": "Wyłącz", "Riot does not know how to join a room on this network": "Riot nie wie, jak dołączyć do pokoju w tej sieci", "Mentions only": "Tylko, gdy wymienieni", @@ -902,13 +855,10 @@ "%(count)s Members|one": "%(count)s Członek", "Event sent!": "Wydarzenie wysłane!", "View Source": "Pokaż źródło", - "Matrix technical discussions": "Dyskusje techniczne Matrixa", "Event Content": "Zawartość wydarzenia", "Thank you!": "Dziękujemy!", - "Building services on Matrix": "Tworzenie usług w oparciu o Matrix", "Collapse panel": "Ukryj panel", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Z Twoją obecną przeglądarką, wygląd oraz wrażenia z używania aplikacji mogą być niepoprawne, a niektóre funkcje wcale nie działać. Kontynuuj jeśli chcesz spróbować, jednak trudno będzie pomóc w przypadku błędów, które mogą nastąpić!", "Checking for an update...": "Sprawdzanie aktualizacji...", - "General discussion about Matrix and Riot": "Generalna rozmowa o Matrix i Riot", "There are advanced notifications which are not shown here": "Masz zaawansowane powiadomienia, nie pokazane tutaj" } diff --git a/src/i18n/strings/pt.json b/src/i18n/strings/pt.json index f046907637..d8b9d11040 100644 --- a/src/i18n/strings/pt.json +++ b/src/i18n/strings/pt.json @@ -14,7 +14,6 @@ "Banned users": "Usuárias/os banidas/os", "Bans user with given id": "Banir usuários com o identificador informado", "Blacklisted": "Bloqueado", - "Bug Report": "Repotar problemas de funcionamento", "Bulk Options": "Opcões de Batelada", "Can't load user settings": "Não é possível carregar configurações de usuário", "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s mudou o tópico para \"%(topic)s\".", @@ -68,7 +67,6 @@ "Forgot your password?": "Esqueceu sua senha?", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Por segurança, deslogar irá remover qualquer chave de criptografia ponta-a-ponta deste navegador. Caso deseje descriptografar o histórico das suas conversas E2E em sessões Riot futuras, por favor exporte as chaves da sala para sua garantia.", "For security, this session has been signed out. Please sign in again.": "Por questões de segurança, esta sessão foi encerrada. Por gentileza conecte-se novamente.", - "Found a bug?": "Encontrou um problema de funcionamento do sistema?", "Guests cannot join this room even if explicitly invited.": "Visitantes não podem entrar nesta sala, mesmo se forem explicitamente convidadas/os.", "Hangup": "Desligar", "Historical": "Histórico", @@ -405,7 +403,6 @@ "olm version:": "versão do olm:", "Operation failed": "A operação falhou", "Remove %(threePid)s?": "Remover %(threePid)s?", - "Report it": "Reportar", "riot-web version:": "versão do riot-web:", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Mostrar os horários em formato de 12h (p.ex: 2:30pm)", "Unmute": "Tirar do mudo", @@ -632,7 +629,6 @@ "Do you want to load widget from URL:": "Deseja carregar o widget a partir do URL:", "Edit": "Editar", "Enable automatic language detection for syntax highlighting": "Ativar deteção automática da linguagem para o destaque da sintaxe", - "Hide Apps": "Ocultar apps", "Hide join/leave messages (invites/kicks/bans unaffected)": "Ocultar mensagens de entrada/saída (não afeta convites/expulsões/proibições)", "Integrations Error": "Erro de integrações", "Publish this room to the public in %(domain)s's room directory?": "Publicar esta sala ao público no diretório de salas de %(domain)s's?", @@ -642,7 +638,6 @@ "Press to start a chat with someone": "Clique para iniciar uma conversa com alguém", "Revoke widget access": "Revogar o acesso do wiget", "Sets the room topic": "Define o assunto da sala", - "Show Apps": "Mostrar apps", "The maximum permitted number of widgets have already been added to this room.": "O número máximo de widgets permitido já foi adicionado a esta sala.", "To get started, please pick a username!": "Para começar, escolha um nome de utilizador!", "Unable to create widget.": "Não foi possível criar o widget.", @@ -718,8 +713,6 @@ "To send events of type , you must be a": "Para enviar eventos do tipo , tens de ser um(a)", "Fetching third party location failed": "Falha ao obter localização de terceiros", "A new version of Riot is available.": "Uma nova versão do Riot está disponível.", - "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk chat", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Por favor descreva a falha encontrada. O que fez? O que esperava que acontecesse? O que realmente aconteceu?", "I understand the risks and wish to continue": "Entendo os riscos e pretendo continuar", "Couldn't load home page": "Não foi possível carregar a página inicial", "Advanced notification settings": "Configurações avançadas de notificação", @@ -731,31 +724,24 @@ "Failed to set direct chat tag": "Falha ao definir conversa como pessoal", "Today": "Hoje", "Failed to get protocol list from Home Server": "Falha ao obter a lista de protocolos do servidor padrão", - "Report a bug": "Reportar uma falha", - "Implementing VR services with Matrix": "Implementar serviços de realidade virtual (VR) com o Matrix", "You are not receiving desktop notifications": "Não está a receber notificações de desktop", "Friday": "Sexta-feira", "Update": "Atualizar", - "You need to be using HTTPS to place a screen-sharing call.": "Necessita de estar a usar HTTPS para poder iniciar uma chamada com partilha de ecrã.", "What's New": "Novidades", "Add an email address above to configure email notifications": "Insira um endereço de email no campo acima para configurar as notificações por email", "Expand panel": "Expandir o painel", "On": "Ativado", "Filter room names": "Filtrar salas por título", "Changelog": "Histórico de alterações", - "Running Matrix services": "Correr serviços do Matrix", "Waiting for response from server": "À espera de resposta do servidor", "Uploaded on %(date)s by %(user)s": "Enviada em %(date)s por %(user)s", "Send Custom Event": "Enviar evento personalizado", - "Failed to send report: ": "Falha ao enviar o relatório: ", - "Unknown device": "Dispositivo desconhecido", "All notifications are currently disabled for all targets.": "Todas as notificações estão atualmente desativadas para todos os casos.", "delete the alias.": "apagar o apelido da sala.", "To return to your account in future you need to set a password": "Para voltar à sua conta no futuro, necessita de definir uma palavra-passe", "Forget": "Esquecer", "World readable": "Público", "#example": "#exemplo", - "Riot/Web & Desktop chat": "Riot/Web & Desktop chat", "Hide panel": "Ocultar o painel", "You cannot delete this image. (%(code)s)": "Não pode apagar esta imagem. (%(code)s)", "Cancel Sending": "Cancelar o envio", @@ -766,18 +752,13 @@ "Error saving email notification preferences": "Erro ao guardar as preferências de notificação por e-mail", "Messages containing my display name": "Mensagens contendo o meu nome público", "Messages in one-to-one chats": "Mensagens em conversas pessoais", - "Contributing code to Matrix and Riot": "Contribuir código para o Matrix e para o Riot", "Unavailable": "Indisponível", - "Community-run support for Synapse": "Suporte da comunidade para o Synapse", "View Decrypted Source": "Ver a fonte desencriptada", "Failed to update keywords": "Falha ao atualizar as palavras-chave", "remove %(name)s from the directory.": "remover %(name)s da lista pública de salas.", "Notifications on the following keywords follow rules which can’t be displayed here:": "Notificações sobre as seguintes palavras-chave seguem regras que não podem ser exibidas aqui:", "Please set a password!": "Por favor, defina uma palavra-passe!", "You have successfully set a password!": "Palavra-passe definida com sucesso!", - "Chat with Riot Bot": "Falar com o Bot do Riot", - "Support for those using, running and writing other bridges": "Suporte para aqueles a usar, correr e desenvolver outras pontes (bridges)", - "Admin support for Dendrite": "Suporte de administração para o Dendrite", "An error occurred whilst saving your email notification preferences.": "Ocorreu um erro ao guardar as suas preferências de notificação por email.", "Explore Room State": "Explorar estado da sala", "Source URL": "URL fonte", @@ -785,15 +766,11 @@ "Filter results": "Filtrar resultados", "Members": "Membros", "No update available.": "Nenhuma atualização disponível.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Já existem muitas salas no Matrix, ligadas a redes já existentes (Slack, IRC, Gitter, etc) ou independentes. Dê uma vista de olhos no diretório!", "Noisy": "Barulhento", "Files": "Ficheiros", "Collecting app version information": "A recolher informação da versão da app", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Apagar o apelido %(alias)s da sala e remover %(name)s da lista pública?", - "customServer_text": "Pode usar as opções de servidor personalizado para entrar noutros servidores Matrix especificando para isso um URL de outro Servidor de Base.
    Isto permite que use o Riot com uma conta Matrix que exista noutro Servidor de Base.

    Também pode configurar um servidor de Identidade personalizado mas não poderá convidar utilizadores através do endereço de e-mail, ou ser convidado pelo seu endereço de e-mail.", - "Co-ordination for Riot/Web translators": "Coordenação para a equipa de tradutores do Riot/Web", "This will allow you to return to your account after signing out, and sign in on other devices.": "Isto irá permitir-lhe voltar à sua conta depois de terminar sessão, assim como iniciar sessão noutros dispositivos.", - "Dev chat for the Dendrite dev team": "Conversa de desenvolvimento para a equipa do Dendrite", "Keywords": "Palavras-chave", "Enable notifications for this account": "Ativar notificações para esta conta", "Directory": "Diretório", @@ -814,19 +791,13 @@ "Direct Chat": "Conversa pessoal", "The server may be unavailable or overloaded": "O servidor pode estar inacessível ou sobrecarregado", "Reject": "Rejeitar", - "Riot is not supported on mobile web. Install the app?": "O Riot não é suportado na web para dispositivos móveis. Quer instalar a app?", - "Discussion of all things Matrix!": "Discussão de tudo o que envolva o Matrix!", "Failed to set Direct Message status of room": "Falha em definir a mensagem de status da sala", "Monday": "Segunda-feira", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Para diagnosticar problemas, relatórios deste cliente serão enviados juntamente com esta notificação de falha. Se preferir enviar apenas o texto acima, por favor remova a seleção:", - "Send Custom State Event": "Enviar evento personalizado de estado", "All messages (noisy)": "Todas as mensagens (alto)", "Enable them now": "Ativar agora", "Messages containing my user name": "Mensagens contendo o meu nome de utilizador", - "Describe your problem here.": "Descreva o seu problema aqui.", "Collecting logs": "A recolher logs", "more": "mais", - "Support for those using the Matrix spec": "Suporte para os utilizadores da especificação do Matrix", "You must specify an event type!": "Tem que especificar um tipo de evento!", "(HTTP status %(httpStatus)s)": "(Estado HTTP %(httpStatus)s)", "Invite to this room": "Convidar para esta sala", @@ -835,60 +806,42 @@ "Send": "Enviar", "Send logs": "Enviar relatórios de erro", "All messages": "Todas as mensagens", - "Implementing VoIP services with Matrix": "Implementar serviços VoIP com o Matrix", - "Dev chat for the Riot/Web dev team": "Conversa de desenvolvimento para a equipa do Riot/Web", "Call invitation": "Convite para chamada", - "Riot Desktop on %(platformName)s": "Riot para computadores desktop em %(platformName)s", "Downloading update...": "A transferir atualização...", "You have successfully set a password and an email address!": "Palavra passe e endereço de e-mail definidos com sucesso!", "Failed to send custom event.": "Falha ao enviar evento personalizado.", "What's new?": "O que há de novo?", - "Discussion of the Identity Service API": "Discussão da API do serviço de identidade", - "Support for those using and running matrix-appservice-irc": "Suporte para aqueles a correr e a utilizar o matrix-appservice-irc", - "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk chat", "Notify me for anything else": "Notificar-me sobre qualquer outro evento", "When I'm invited to a room": "Quando sou convidado para uma sala", - "Design and implementation of E2E in Matrix": "Design e implementação de encriptação ponto-a-ponto (E2E) no Matrix", "Can't update user notification settings": "Não é possível atualizar as preferências de notificação", "Notify for all other messages/rooms": "Notificar para todas as outras mensagens/salas", "Unable to look up room ID from server": "Não foi possível obter a identificação da sala do servidor", "Couldn't find a matching Matrix room": "Não foi possível encontrar uma sala correspondente no servidor Matrix", "Bug report sent": "Relatório de erros enviado", - "Safari and Opera work too.": "Safari e Opera também funcionam.", - "Loading bug report module": "A carregar o módulo de relato de erros", "All Rooms": "Todas as salas", "You cannot delete this message. (%(code)s)": "Não pode apagar esta mensagem. (%(code)s)", "Thursday": "Quinta-feira", "Forward Message": "Encaminhar", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s via %(browserName)s em %(osName)s", "Back": "Voltar", "Unhide Preview": "Mostrar a pré-visualização novamente", - "Announcements about Synapse releases": "Anúncios acerca de lançamentos do Synapse", - "Search the room directory": "Procurar o diretório de salas", - "Please describe the bug and/or send logs.": "Por favor descreva a falha e/ou envie os logs de erro.", "Unable to join network": "Não foi possível juntar-se à rede", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Pode ter configurado num outro cliente sem ser o Riot. Não pode ajustá-las no Riot, mas ainda assim elas aplicam-se", "Sorry, your browser is not able to run Riot.": "Desculpe, o seu navegador não é capaz de executar o Riot.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Chat descentralizado, encriptado & colaborativo alimentado por [matrix]", - "Building services on Matrix": "Construir serviços no Matrix", "Messages in group chats": "Mensagens em salas", "Yesterday": "Ontem", "Error encountered (%(errorDetail)s).": "Erro encontrado (%(errorDetail)s).", "Login": "Entrar", "Low Priority": "Baixa prioridade", "Unable to fetch notification target list": "Não foi possível obter a lista de alvos de notificação", - "Get started with some tips from Riot Bot!": "Comece com algumas dicas do Bot do Riot", "Set Password": "Definir palavra-passe", "Enable audible notifications in web client": "Ativar notificações de áudio no cliente web", "Permalink": "Link permanente", - "Welcome to Riot.im": "Bem-vindo ao Riot.im", "Off": "Desativado", "Riot does not know how to join a room on this network": "O Riot não sabe como entrar numa sala nesta rede", "Mentions only": "Apenas menções", "Failed to remove tag %(tagName)s from room": "Não foi possível remover a marcação %(tagName)s desta sala", "Wednesday": "Quarta-feira", "You can now return to your account after signing out, and sign in on other devices.": "Pode agora voltar à sua conta no fim de terminar sessão, e iniciar sessão noutros dispositivos.", - "Please install Chrome or Firefox for the best experience.": "Por favor instale Chrome ou Firefox para ter a melhor experiência.", "Enable email notifications": "Ativar notificações por e-mail", "Event Type": "Tipo de evento", "No rooms to show": "Não existem salas a serem exibidas", @@ -896,13 +849,11 @@ "Failed to change settings": "Falha ao alterar as configurações", "Event sent!": "Evento enviado!", "View Source": "Ver a fonte", - "Matrix technical discussions": "Discussões técnicas do Matrix", "Event Content": "Conteúdo do evento", "Thank you!": "Obrigado!", "Quote": "Citar", "Collapse panel": "Colapsar o painel", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Com o seu navegador atual, a aparência e sensação de uso da aplicação podem estar completamente incorretas, e algumas das funcionalidades poderão não funcionar. Se quiser tentar de qualquer maneira pode continuar, mas está por sua conta com algum problema que possa encontrar!", "Checking for an update...": "A procurar uma atualização...", - "General discussion about Matrix and Riot": "Discussão geral acerca do Matrix e do Riot", "There are advanced notifications which are not shown here": "Existem notificações avançadas que não são exibidas aqui" } diff --git a/src/i18n/strings/pt_BR.json b/src/i18n/strings/pt_BR.json index 046617d934..37a9a958a1 100644 --- a/src/i18n/strings/pt_BR.json +++ b/src/i18n/strings/pt_BR.json @@ -14,7 +14,6 @@ "Banned users": "Usuárias/os banidas/os", "Bans user with given id": "Banir usuários com o identificador informado", "Blacklisted": "Bloqueado", - "Bug Report": "Repotar problemas de funcionamento", "Bulk Options": "Opcões de Batelada", "Can't load user settings": "Não é possível carregar configurações de usuário", "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s mudou o tópico para \"%(topic)s\".", @@ -68,7 +67,6 @@ "Forgot your password?": "Esqueceu sua senha?", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Por segurança, deslogar irá remover qualquer chave de criptografia ponta-a-ponta deste navegador. Caso deseje descriptografar o histórico das suas conversas E2E em sessões Riot futuras, por favor exporte as chaves da sala para sua garantia.", "For security, this session has been signed out. Please sign in again.": "Por questões de segurança, esta sessão foi encerrada. Por gentileza conecte-se novamente.", - "Found a bug?": "Encontrou um problema de funcionamento do sistema?", "Guests cannot join this room even if explicitly invited.": "Visitantes não podem entrar nesta sala, mesmo se forem explicitamente convidadas/os.", "Hangup": "Desligar", "Historical": "Histórico", @@ -407,7 +405,6 @@ "olm version:": "versão do olm:", "Operation failed": "A operação falhou", "Remove %(threePid)s?": "Remover %(threePid)s?", - "Report it": "Reportar", "riot-web version:": "versão do riot-web:", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Mostrar os horários em formato de 12h (p.ex: 2:30pm)", "Unmute": "Tirar do mudo", @@ -732,8 +729,6 @@ "Mention": "Mencionar", "Invite": "Convidar", "User Options": "Opções de usuária/o", - "Hide Apps": "Ocultar Apps", - "Show Apps": "Mostrar Apps", "Send an encrypted reply…": "Enviar uma resposta criptografada…", "Send a reply (unencrypted)…": "Enviar uma resposta (não criptografada)…", "Send an encrypted message…": "Enviar mensagem criptografada…", @@ -928,7 +923,6 @@ "Leave Community": "Deixar a comunidade", "Leave %(groupName)s?": "Quer sair da comunidade %(groupName)s?", "Leave": "Sair", - "Unable to leave room": "Não foi possível sair da sala", "Community Settings": "Configurações da comunidade", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Estas salas são exibidas para as/os integrantes da comunidade na página da comunidade. Integrantes da comunidade podem entrar nas salas ao clicar nas mesmas.", "Featured Rooms:": "Salas em destaque:", @@ -943,8 +937,6 @@ "This Home server does not support communities": "Este servidor de base não permite comunidades", "Failed to load %(groupId)s": "Não foi possível carregar a comunidade %(groupId)s", "This room is not public. You will not be able to rejoin without an invite.": "Esta sala não é pública. Você não poderá voltar sem ser convidada/o.", - "Cryptography data migrated": "Dados de criptografia migrados", - "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "Uma migração única de dados criptografados foi realizada. A criptografia ponta-a-ponta não vai funcionar se você voltar para uma versão anterior do Riot. Se você necessitar usar criptografia ponta-a-ponta em uma versão anterior, primeiro faça logout do Riot. Para manter o histórico de mensagens, exporte e reimporte suas chaves.", "Old cryptography data detected": "Dados de criptografia antigos foram detectados", "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Dados de uma versão anterior do Riot foram detectados. Isso fará com que a criptografia ponta-a-ponta não funcione na versão anterior. Mensagens criptografadas ponta-a-ponta que foram trocadas recentemente usando a versão antiga do Riot talvez não possam ser decriptografadas nesta versão. Isso também pode fazer com que mensagens trocadas com esta versão falhem. Se você tiver problemas desta natureza, faça logout e entre novamente. Para manter o histórico de mensagens, exporte e reimporte suas chaves de criptografia.", "Your Communities": "Suas comunidades", @@ -994,11 +986,8 @@ "Key request sent.": "Requisição de chave enviada.", "Re-request encryption keys from your other devices.": "Requisitar novamente chaves de encriptação de seus outros dispositivos.", "%(user)s is a %(userRole)s": "%(user)s é %(userRole)s", - "Changes made to your community might not be seen by other users for up to 30 minutes.": "Mudanças feitas para sua comunidade podem não chegar aos outros usuários por até 30 minutos.", "Fetching third party location failed": "Falha ao acessar localização de terceiros", "A new version of Riot is available.": "Uma nova versão do Riot está disponível.", - "Riot/Android & matrix-android-sdk chat": "Riot/Chat do Android e do matrix-android-sdk", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Por favor, descreva a falha encontrada. O que você estava fazendo? O que você esperava que devia ocorrer? E o que aconteceu efetivamente?", "I understand the risks and wish to continue": "Entendo os riscos e desejo continuar", "Couldn't load home page": "Não foi possível carregar a página inicial", "Send Account Data": "Enviar Dados da Conta", @@ -1008,12 +997,9 @@ "Notification targets": "Alvos de notificação", "Today": "Hoje", "Failed to get protocol list from Home Server": "Falha em acessar a lista de protocolos do servidor padrão", - "Report a bug": "Reportar uma falha", - "Implementing VR services with Matrix": "Implementando serviços de Realidade Virtual (VR) com Matrix", "You are not receiving desktop notifications": "Você não está recebendo notificações desktop", "Friday": "Sexta", "Update": "Atualizar", - "You need to be using HTTPS to place a screen-sharing call.": "Você precisa estar usando HTTPS para poder iniciar uma chamada com compartilhamento de tela.", "What's New": "Novidades", "Add an email address above to configure email notifications": "Insira um endereço de email no campo acima para configurar suas notificações por email", "Expand panel": "Expandir o painel", @@ -1021,18 +1007,14 @@ "%(count)s Members|other": "%(count)s Membros", "Filter room names": "Filtrar salas por título", "Changelog": "Histórico de alterações", - "Running Matrix services": "Rodando serviços Matrix", "Waiting for response from server": "Esperando por resposta do servidor", "Uploaded on %(date)s by %(user)s": "Enviada em %(date)s por %(user)s", "Send Custom Event": "Enviar Evento Customizado", - "Failed to send report: ": "Falha ao enviar o relatório: ", - "Unknown device": "Dispositivo desconhecido", "All notifications are currently disabled for all targets.": "Todas as notificações estão atualmente desabilitadas para todos os casos.", "delete the alias.": "apagar o apelido da sala.", "To return to your account in future you need to set a password": "Para poder, futuramente, retornar à sua conta, você precisa definir uma senha", "Forget": "Esquecer", "#example": "#exemplo", - "Riot/Web & Desktop chat": "Riot/chat da web e do computador desktop", "Hide panel": "Ocultar o painel", "You cannot delete this image. (%(code)s)": "Você não pode apagar esta imagem. (%(code)s)", "Cancel Sending": "Cancelar o envio", @@ -1042,9 +1024,7 @@ "Error saving email notification preferences": "Erro ao salvar as preferências de notificação por email", "Messages containing my display name": "Mensagens contendo meu nome público", "Messages in one-to-one chats": "Mensagens em conversas pessoais", - "Contributing code to Matrix and Riot": "Contribuindo com código para o Matrix e o Riot", "Unavailable": "Indisponível", - "Community-run support for Synapse": "Apoio ao Synapse gerido pela comunidade", "View Decrypted Source": "Ver a fonte descriptografada", "Failed to update keywords": "Falha ao alterar as palavras-chave", "remove %(name)s from the directory.": "remover %(name)s da lista pública de salas.", @@ -1052,9 +1032,6 @@ "Safari and Opera work too.": "Safari e Opera Funciona bem.", "Please set a password!": "Por favor, defina uma senha!", "You have successfully set a password!": "Você definiu sua senha com sucesso!", - "Chat with Riot Bot": "Conversar com o Bot do Riot", - "Support for those using, running and writing other bridges": "Apoio para as pessoas que estejam usando, rodando e escrevendo outras pontes (bridges)", - "Admin support for Dendrite": "Suporte de administração para Dendrite", "An error occurred whilst saving your email notification preferences.": "Um erro ocorreu enquanto o sistema estava salvando suas preferências de notificação por email.", "Explore Room State": "Explorar Estado da Sala", "Source URL": "URL fonte", @@ -1062,15 +1039,11 @@ "Filter results": "Filtrar resultados", "Members": "Membros", "No update available.": "Não há atualizações disponíveis.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Muitas salas já existem no Matrix, algumas independentes, e outras relacionadas a redes existentes (tais como Slack, IRC, Gitter, entre outras). Dê uma olhada na lista de salas públicas!", "Noisy": "Barulhento", "Files": "Arquivos", "Collecting app version information": "Coletando informação sobre a versão do app", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Apagar o apelido %(alias)s da sala e remover %(name)s da lista pública?", - "customServer_text": "Você pode usar as opções de servidor personalizado para entrar em outros servidores Matrix, especificando uma URL de outro Servidor de Base.
    Isso permite que você use Riot com uma conta Matrix que exista em outro Servidor de Base.

    Você também pode configurar um servidor de Identidade personalizado, mas neste caso não poderá convidar usuárias(os) pelo endereço de e-mail, ou ser convidado(a) pelo seu endereço de e-mail.", - "Co-ordination for Riot/Web translators": "Coordenação para tradutoras(es) do Riot/Web", "This will allow you to return to your account after signing out, and sign in on other devices.": "Isso permitirá que você possa retornar à sua conta após fazer logout, e também fazer login em outros dispositivos.", - "Dev chat for the Dendrite dev team": "Chat de desenvolvimento para o time devel do Dendrite", "Keywords": "Palavras-chave", "Enable notifications for this account": "Ativar notificações para esta conta", "Directory": "Diretório", @@ -1094,16 +1067,11 @@ "Direct Chat": "Conversa pessoal", "The server may be unavailable or overloaded": "O servidor pode estar inacessível ou sobrecarregado", "Reject": "Rejeitar", - "Riot is not supported on mobile web. Install the app?": "Riot versão web não é suportado a partir de celular. Quer instalar o app para celular?", - "Discussion of all things Matrix!": "Discussão sobre todas as coisas do Matrix!", "Failed to set Direct Message status of room": "Falha em definir a mensagem de status da sala", "Monday": "Segunda", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Para diagnosticar problemas, relatórios deste cliente serão enviados junto a esta notificação de falha. Se você prefere apenas enviar o seu texto acima, por favor des-selecione:", - "Send Custom State Event": "Enviar Evento de Estado Personalizado", "All messages (noisy)": "Todas as mensagens (alto)", "Enable them now": "Habilitar agora", "Messages containing my user name": "Mensagens contendo meu nome de usuário", - "Describe your problem here.": "Descreva o seu problema aqui.", "Toolbox": "Ferramentas", "Collecting logs": "Coletando logs", "more": "ver mais", @@ -1115,45 +1083,28 @@ "Failed to get public room list": "Falha ao acessar a lista pública de salas", "Send logs": "Enviar relatórios de erro", "All messages": "Todas as mensagens", - "Implementing VoIP services with Matrix": "Implementando serviços VoIP com Matrix", - "Dev chat for the Riot/Web dev team": "Chat de desenvolvimento para o time devel do Riot/Web", "Call invitation": "Convite para chamada", - "Riot Desktop on %(platformName)s": "Riot para computadores desktop em %(platformName)s", "Downloading update...": "Baixando atualização...", "State Key": "Chave do Estado", "Failed to send custom event.": "Falha ao enviar evento personalizado.", "What's new?": "O que há de novidades?", - "Discussion of the Identity Service API": "Discussão do API do Serviço de Identidades", - "Support for those using and running matrix-appservice-irc": "Apoio para as pessoas usando e rodando matrix-appservice-irc", - "Riot/iOS & matrix-ios-sdk chat": "Riot/chat do iOS e do matrix-ios-sdk", "Notify me for anything else": "Notificar-me sobre qualquer outro evento", "When I'm invited to a room": "Quando sou convidada(o) a uma sala", - "Design and implementation of E2E in Matrix": "Design e implementação de criptografia ponta-a-ponta (E2E) no Matrix", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Você pode usar as opções customizadas de servidor para conectar-se a outros servidores Matrix ao especificar uma outra URL de Servidor de Base (homeserver).
    Isso permite que você use o Riot com uma conta Matrix existente em outro servidor de base.

    Você também pode definir um servidor de identidade customizado, mas neste caso você não poderá convidar outras pesoas por endereço de email, ou ser convidada/o pelo seu endereço de email.", "Can't update user notification settings": "Não é possível atualizar as preferências de notificação", "Notify for all other messages/rooms": "Notificar para todas as outras mensagens e salas", "Unable to look up room ID from server": "Não foi possível buscar identificação da sala no servidor", "Couldn't find a matching Matrix room": "Não foi possível encontrar uma sala correspondente no servidor Matrix", - "Support for those using the Matrix spec": "Apoio para as pessoas que estão usando as especificações Matrix", - "Safari and Opera work too.": "Safari e Opera funcionam também.", - "Loading bug report module": "Carregando o módulo de relatórios de erros", "All Rooms": "Todas as salas", "You cannot delete this message. (%(code)s)": "Você não pode apagar esta mensagem. (%(code)s)", "Thursday": "Quinta", "Forward Message": "Encaminhar", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s via %(browserName)s em %(osName)s", "Back": "Voltar", "Reply": "Responder", "Show message in desktop notification": "Mostrar mensagens na notificação", "Unhide Preview": "Mostrar a pré-visualização", - "Announcements about Synapse releases": "Anúncios sobre lançamentos do Synapse", - "Search the room directory": "Buscar na lista pública de salas", - "Please describe the bug and/or send logs.": "Por favor, descreva as falhas e/ou envie os logs de erro.", "Unable to join network": "Não foi possível conectar na rede", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Você pode te-las configurado em outro cliente além do Riot. Você não pode ajustá-las no Riot, mas ainda assim elas se aplicam aqui", "Sorry, your browser is not able to run Riot.": "Perdão. O seu navegador não é capaz de rodar o Riot.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Chat descentralizado, criptografado e colaborativo impulsionado por [matrix]", - "Building services on Matrix": "Construindo serviços no Matrix", "Messages in group chats": "Mensagens em salas", "Yesterday": "Ontem", "Error encountered (%(errorDetail)s).": "Erro encontrado (%(errorDetail)s).", @@ -1161,17 +1112,14 @@ "Low Priority": "Baixa prioridade", "Unable to fetch notification target list": "Não foi possível obter a lista de alvos de notificação", "Appear Offline": "Aparecer Desconectado", - "Get started with some tips from Riot Bot!": "Comece com algumas dicas do Bot do Riot!", "Set Password": "Definir senha", "Enable audible notifications in web client": "Ativar notificações de áudio no cliente web", "Permalink": "Link permanente", - "Welcome to Riot.im": "Seja bem-vinda(o) a Riot.im", "Off": "Desativado", "Riot does not know how to join a room on this network": "O sistema não sabe como entrar na sala desta rede", "Mentions only": "Apenas menções", "Wednesday": "Quarta", "You can now return to your account after signing out, and sign in on other devices.": "Você pode retornar agora para a sua conta depois de fazer logout, e então fazer login em outros dispositivos.", - "Please install Chrome or Firefox for the best experience.": "Por favor instale Chrome ou Firefox para ter a melhor experiência de uso.", "Enable email notifications": "Ativar notificações por email", "Event Type": "Tipo do Evento", "Download this file": "Baixar este arquivo", @@ -1181,13 +1129,11 @@ "%(count)s Members|one": "%(count)s Membros", "Event sent!": "Evento enviado!", "View Source": "Ver a fonte", - "Matrix technical discussions": "Discussões técnicas do Matrix", "Event Content": "Conteúdo do Evento", "Thank you!": "Obrigado!", "Quote": "Citar", "Collapse panel": "Colapsar o painel", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Com o seu navegador atual, a aparência e sensação de uso da aplicação podem estar completamente incorretas, e algumas das funcionalidades poderão não funcionar. Se você quiser tentar de qualquer maneira, pode continuar, mas aí vai ter que se virar sozinho(a) com os problemas que porventura encontrar!", "Checking for an update...": "Verificando se há atualizações...", - "General discussion about Matrix and Riot": "Discussão geral sobre o Matrix e o Riot", "There are advanced notifications which are not shown here": "Existem opções avançadas que não são exibidas aqui" } diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index a77e8605c0..be047da005 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -13,7 +13,6 @@ "Banned users": "Заблокированные пользователи", "Bans user with given id": "Блокирует пользователя с заданным ID", "Blacklisted": "В черном списке", - "Bug Report": "Отчет об ошибке", "Bulk Options": "Групповые параметры", "Can't load user settings": "Невозможно загрузить пользовательские настройки", "Changes to who can read history will only apply to future messages in this room": "Изменения того, кто может прочитать историю, будут применяться только к будущим сообщениям в этой комнате", @@ -61,7 +60,6 @@ "Forget room": "Забыть комнату", "Forgot your password?": "Забыли пароль?", "For security, this session has been signed out. Please sign in again.": "Для обеспечения безопасности ваша сессия была завершена. Пожалуйста, войдите снова.", - "Found a bug?": "Нашли ошибку?", "Hangup": "Закончить", "Historical": "Архив", "Homeserver is": "Домашний сервер это", @@ -314,7 +312,6 @@ "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s удалил свое отображаемое имя (%(oldDisplayName)s).", "%(senderName)s removed their profile picture.": "%(senderName)s удалил свое изображение профиля.", "%(senderName)s requested a VoIP conference.": "%(senderName)s хочет начать VoIP-конференцию.", - "Report it": "Сообщить об этом", "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.": "Сброс пароля на данный момент сбрасывает ключи шифрования на всех устройствах, делая зашифрованную историю чатов нечитаемой. Чтобы избежать этого, экспортируйте ключи комнат и импортируйте их после сброса пароля. В будущем это будет исправлено.", "Riot does not have permission to send you notifications - please check your browser settings": "У Riot нет разрешений на отправку уведомлений - проверьте настройки браузера", "Riot was not given permission to send notifications - please try again": "Riot не получил разрешение на отправку уведомлений, пожалуйста, попробуйте снова", @@ -654,7 +651,6 @@ "Do you want to load widget from URL:": "Загрузить виджет из URL-адреса:", "Edit": "Редактировать", "Enable automatic language detection for syntax highlighting": "Включить автоматическое определение языка для подсветки синтаксиса", - "Hide Apps": "Скрыть приложения", "Hide join/leave messages (invites/kicks/bans unaffected)": "Скрыть сообщения о входе/выходе (не применяется к приглашениям/выкидываниям/банам)", "Integrations Error": "Ошибка интеграции", "AM": "AM", @@ -662,7 +658,6 @@ "NOTE: Apps are not end-to-end encrypted": "ПРИМЕЧАНИЕ: приложения не защищены сквозным шифрованием", "Revoke widget access": "Отозвать доступ к виджетам", "Sets the room topic": "Задать тему комнаты", - "Show Apps": "Показать приложения", "The maximum permitted number of widgets have already been added to this room.": "Максимально допустимое количество виджетов уже добавлено в эту комнату.", "To get started, please pick a username!": "Чтобы начать, выберите имя пользователя!", "Unable to create widget.": "Не удалось создать виджет.", @@ -719,7 +714,6 @@ "Description": "Описание", "Name or matrix ID": "Имя или matrix ID", "Unable to accept invite": "Невозможно принять приглашение", - "Unable to leave room": "Невозможно покинуть комнату", "Leave": "Покинуть", "Failed to invite the following users to %(groupId)s:": "Не удалось пригласить следующих пользователей в %(groupId)s:", "Failed to remove '%(roomName)s' from %(groupId)s": "Не удалось удалить '%(roomName)s' из %(groupId)s", @@ -992,7 +986,6 @@ "%(user)s is a %(userRole)s": "%(user)s является %(userRole)s", "Your key share request has been sent - please check your other devices for key share requests.": "Ваш запрос на передачу ключей отправлен - пожалуйста, проверьте другие ваши устройства на запросы передачи ключей.", "Key share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, click here to request the keys for this session again.": "Запросы передачи ключей автоматически отправляются на другие устройства. Если вы отклонили или отменили запрос на передачу ключей на других устройствах, нажмите здесь, чтобы запросить ключи для этого сеанса повторно.", - "Changes made to your community might not be seen by other users for up to 30 minutes.": "Изменения, сделанные в вашем сообществе, могут не отображаться для других пользователей в течение 30 минут.", "Code": "Код", "Debug Logs Submission": "Отправка журналов отладки", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Если вы отправили ошибку через GitHub, журналы отладки могут помочь нам выявить проблему. Журналы отладки содержат данные об использовании приложения, включая ваше имя пользователя, идентификаторы или псевдонимы комнат или групп, которые вы посетили, а также имена других пользователей. Они не содержат сообщений.", @@ -1004,15 +997,10 @@ "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Изменения имени и аватара, внесенные в ваше сообщество, могут не отображаться другим пользователям в течение 30 минут.", "Join this community": "Присоединиться к сообществу", "Leave this community": "Покинуть это сообщество", - "here": "здесь", - "to add some!": "для добавления!", - "Click": "Нажмите", "Who can join this community?": "Кто может присоединиться к этому сообществу?", "Everyone": "Все", "Fetching third party location failed": "Не удалось извлечь местоположение третьей стороны", "A new version of Riot is available.": "Доступна новая версия Riot.", - "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk чат", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Пожалуйста, опишите ошибку. Что сделали? Чего ожидали? Что на самом деле произошло?", "I understand the risks and wish to continue": "Я понимаю риски и желаю продолжить", "Couldn't load home page": "Не удалось загрузить домашнюю страницу", "Send Account Data": "Отправить данные аккаунта", @@ -1022,12 +1010,9 @@ "Notification targets": "Цели уведомления", "Today": "Сегодня", "Files": "Файлы", - "Report a bug": "Сообщить об ошибке", - "Implementing VR services with Matrix": "Внедрение сервисов виртуальной реальности (VR) с помощью Matrix", "You are not receiving desktop notifications": "Вы не получаете уведомления на рабочем столе", "Friday": "Пятница", "Update": "Обновление", - "You need to be using HTTPS to place a screen-sharing call.": "Требуется использование HTTPS для совместного использования рабочего стола.", "What's New": "Что нового", "Add an email address above to configure email notifications": "Добавьте email адрес для оповещений", "Expand panel": "Развернуть панель", @@ -1035,19 +1020,15 @@ "%(count)s Members|other": "%(count)s членов", "Filter room names": "Фильтр по названию комнат", "Changelog": "История изменений", - "Running Matrix services": "Запуск сервисов Matrix", "Waiting for response from server": "Ожидание ответа от сервера", "Uploaded on %(date)s by %(user)s": "Отправлено %(date)s для %(user)s", "Send Custom Event": "Отправить индивидуальное мероприятие", - "Failed to send report: ": "Не удалось отправить отчет: ", - "Unknown device": "Неизвестное устройство", "Advanced notification settings": "Дополнительные параметры уведомлений", "Failed to send logs: ": "Не удалось отправить журналы: ", "delete the alias.": "удалить псевдоним.", "To return to your account in future you need to set a password": "Чтобы вернуться к учетной записи в будущем, необходимо задать пароль", "Forget": "Забыть", "#example": "#пример", - "Riot/Web & Desktop chat": "Riot/Web & Desktop-чат", "Hide panel": "Скрыть панель", "You cannot delete this image. (%(code)s)": "Это изображение нельзя удалить. (%(code)s)", "Cancel Sending": "Отменить отправку", @@ -1057,9 +1038,7 @@ "Room not found": "Комната не найдена", "Messages containing my display name": "Сообщения, содержащие мое имя", "Messages in one-to-one chats": "Сообщения в индивидуальных чатах", - "Contributing code to Matrix and Riot": "Внести свой вклад в разработку кода Matrix и Riot", "Unavailable": "Недоступен", - "Community-run support for Synapse": "Поддержка Synapse от сообщества", "Error saving email notification preferences": "Ошибка при сохранении настроек уведомлений по email", "View Decrypted Source": "Просмотр расшифрованного источника", "Failed to update keywords": "Не удалось обновить ключевые слова", @@ -1069,9 +1048,6 @@ "Safari and Opera work too.": "Safari и Opera работают тоже.", "Please set a password!": "Пожалуйста, установите пароль!", "You have successfully set a password!": "Вы успешно установили пароль!", - "Chat with Riot Bot": "Пообщаться с ботом Riot", - "Support for those using, running and writing other bridges": "Поддержка для тех, кто использует, разрабатывает и внедряет приложения интеграции для Matrix", - "Admin support for Dendrite": "Административная поддержка Dendrite", "An error occurred whilst saving your email notification preferences.": "Возникла ошибка при сохранении настроек оповещения по email.", "Explore Room State": "Просмотр статуса комнаты", "Source URL": "Исходный URL-адрес", @@ -1079,15 +1055,11 @@ "Filter results": "Фильтрация результатов", "Members": "Участники", "No update available.": "Нет доступных обновлений.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "В Matrix существует множество комнат, как связанных с существующими сетями (Slack, IRC, Gitter и пр.), так и независимых. Ищите в каталоге!", "Resend": "Переотправить", "Failed to get protocol list from Home Server": "Не удалось получить список протоколов с домашнего сервера", "Collecting app version information": "Сбор информации о версии приложения", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Удалить псевдоним комнаты %(alias)s и удалить %(name)s из каталога?", - "customServer_text": "Вы можете использовать настраиваемые параметры сервера для входа на другие серверы Matrix, указав другой URL-адрес домашнего сервера.
    Это позволяет использовать это приложение с существующей учетной записью Matrix на другом домашнем сервере.

    Вы также можете установить другой сервер идентификации, но это, как правило, будет препятствовать взаимодействию с пользователями на основе адреса электронной почты.", - "Co-ordination for Riot/Web translators": "Координация для переводчиков Riot/Web", "This will allow you to return to your account after signing out, and sign in on other devices.": "Это позволит вам вернуться к учетной записи после выхода из системы и войти на других устройствах.", - "Dev chat for the Dendrite dev team": "Чат с командой разработчиков Dendrite", "Keywords": "Ключевые слова", "Enable notifications for this account": "Включить уведомления для этой учетной записи", "Directory": "Каталог", @@ -1112,16 +1084,11 @@ "Direct Chat": "Прямой чат", "The server may be unavailable or overloaded": "Сервер, вероятно, недоступен или перегружен", "Reject": "Отклонить", - "Riot is not supported on mobile web. Install the app?": "Riot не поддерживает версию веб-сайта для мобильных устройств. Установить приложение?", - "Discussion of all things Matrix!": "Дискуссия обо всем, что связано с Matrix!", "Failed to set Direct Message status of room": "Не удалось установить статус прямого сообщения в комнате", "Monday": "Понедельник", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Чтобы диагностировать проблемы, журналы работы этого клиента будут отправлены вместе с сообщением об ошибке. Если вы предпочитаете отправить только текст выше, пожалуйста, снимите отметку:", - "Send Custom State Event": "Отправить статус индивидуального мероприятия", "Remove from Directory": "Удалить из каталога", "Enable them now": "Включить сейчас", "Messages containing my user name": "Сообщение, содержащие мое имя пользователя", - "Describe your problem here.": "Опишите вашу проблему здесь.", "Toolbox": "Панель инструментов", "Collecting logs": "Сбор журналов", "more": "больше", @@ -1134,48 +1101,31 @@ "Failed to get public room list": "Не удалось получить список общедоступных комнат", "Send logs": "Отправка журналов", "All messages": "Все сообщения", - "Implementing VoIP services with Matrix": "Внедрение VoIP-услуг с помощью Matrix", - "Dev chat for the Riot/Web dev team": "Чат с командой разработчиков Riot/Web", "Call invitation": "Пригласительный звонок", - "Riot Desktop on %(platformName)s": "Riot Desktop на %(platformName)s", "Downloading update...": "Загрузка обновления...", "State Key": "Ключ состояния", "Failed to send custom event.": "Не удалось отправить индивидуальное мероприятие.", "What's new?": "Что нового?", - "Discussion of the Identity Service API": "Обсуждение API службы идентификации", - "Support for those using and running matrix-appservice-irc": "Поддержка тех, кто использует и работает с matrix-appservice-irc", - "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk чат", "Notify me for anything else": "Уведомлять во всех остальных случаях", "When I'm invited to a room": "Когда меня приглашают в комнату", - "Design and implementation of E2E in Matrix": "Разработка и внедрение сквозного шифрования (E2E) в Matrix", "Click here to create a GitHub issue.": "Нажмите здесь для создания запроса о проблеме на GitHub.", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Вы можете использовать пользовательские параметры сервера для входа на другие сервера Matrix, указав другой URL-адрес домашнего сервера.
    Это позволяет использовать Riot с существующей учетной записью Matrix на другом домашнем сервере.

    Кроме того, можно установить пользовательский сервер идентификации, однако вы не сможете ни пригласить других пользователей, ни быть приглашенным, используя адрес электронной почты, .", "Can't update user notification settings": "Не удается обновить пользовательские настройки оповещения", "Notify for all other messages/rooms": "Уведомлять обо всех других сообщениях/комнатах", "Unable to look up room ID from server": "Не удалось найти ID комнаты на сервере", "Couldn't find a matching Matrix room": "Не удалось найти подходящую комнату Matrix", - "Support for those using the Matrix spec": "Поддержка пользователей, использующих Matrix spec", - "Safari and Opera work too.": "Safari и Opera работают тоже.", - "Loading bug report module": "Загрузка модуля Отчет об ошибках", "All Rooms": "Все комнаты", "You cannot delete this message. (%(code)s)": "Это сообщение нельзя удалить. (%(code)s)", "Thursday": "Четверг", "Forward Message": "Переслать сообщение", "Logs sent": "Журналы отправлены", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s с %(browserName)s на %(osName)s", "Back": "Назад", "Reply": "Ответить", "Show message in desktop notification": "Показывать сообщение в уведомлении на рабочем столе", "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Журналы отладки содержат данные об использовании приложения, включая ваше имя пользователя, идентификаторы или псевдонимы комнат или групп, которые вы посетили, а также имена других пользователей. Они не содержат сообщений.", "Unhide Preview": "Показать предварительный просмотр", - "Announcements about Synapse releases": "Объявления о выпусках Synapse", - "Search the room directory": "Поиск в каталоге комнат", - "Please describe the bug and/or send logs.": "Опишите ошибку и/или отправьте журналы.", "Unable to join network": "Не удается подключиться к сети", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Возможно вы настроили их не в Riot, а в другом Matrix-клиенте. Настроить их в Riot не удастся, но они будут в нем применяться", "Sorry, your browser is not able to run Riot.": "К сожалению, ваш браузер не способен запустить Riot.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Децентрализованный, зашифрованный чат и совместная работа при поддержке [matrix]", - "Building services on Matrix": "Разработка сервисов на Matrix", "Messages in group chats": "Сообщения в групповых чатах", "Yesterday": "Вчера", "Error encountered (%(errorDetail)s).": "Обнаружена ошибка (%(errorDetail)s).", @@ -1183,17 +1133,14 @@ "Low Priority": "Низкий приоритет", "Unable to fetch notification target list": "Не удалось получить список целей уведомления", "Appear Offline": "Отображать как не в сети", - "Get started with some tips from Riot Bot!": "Начните с некоторых советов от бота Riot!", "Set Password": "Задать пароль", "Enable audible notifications in web client": "Включить звуковые уведомления в веб-клиенте", "Permalink": "Постоянная ссылка", - "Welcome to Riot.im": "Добро пожаловать на Riot.im", "Off": "Выключить", "Riot does not know how to join a room on this network": "Riot не знает, как присоединиться к комнате, принадлежащей к этой сети", "Mentions only": "Только при упоминаниях", "Wednesday": "Среда", "You can now return to your account after signing out, and sign in on other devices.": "Теперь вы сможете вернуться к своей учетной записи после выхода из системы и войти на других устройствах.", - "Please install Chrome or Firefox for the best experience.": "Для получения наилучшего опыта при работе с Riot, пожалуйста, установите Chrome или Firefox.", "Enable email notifications": "Включить уведомления по email", "Event Type": "Тип мероприятия", "Download this file": "Скачать этот файл", @@ -1202,13 +1149,11 @@ "View Community": "Просмотр сообщества", "%(count)s Members|one": "%(count)s член", "Event sent!": "Мероприятие отправлено!", - "Matrix technical discussions": "Технические дискуссии о Matrix", "Event Content": "Содержание мероприятия", "Thank you!": "Спасибо!", "Quote": "Цитата", "Collapse panel": "Свернуть панель", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "В текущем браузере внешний вид приложения может быть полностью неверным, а некоторые или все функции могут не работать. Если вы хотите попробовать в любом случае, то можете продолжить, но с теми проблемами, с которыми вы можете столкнуться вам придется разбираться самостоятельно!", "Checking for an update...": "Проверка обновлений...", - "General discussion about Matrix and Riot": "Общая дискуссия о Matrix и Riot", "There are advanced notifications which are not shown here": "Существуют дополнительные уведомления, которые не показаны здесь" } diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index 40e8ea3367..fb625652ba 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -263,8 +263,6 @@ "Hangup": "Zavesiť", "Voice call": "Audio hovor", "Video call": "Video hovor", - "Hide Apps": "Skryť aplikácie", - "Show Apps": "Zobraziť aplikácie", "Upload file": "Nahrať súbor", "Show Text Formatting Toolbar": "Zobraziť lištu formátovania textu", "You do not have permission to post to this room": "Nemáte udelené právo posielať do tejto miestnosti", @@ -673,7 +671,6 @@ "Leave Community": "Opustiť komunitu", "Leave %(groupName)s?": "Opustiť komunitu %(groupName)s?", "Leave": "Opustiť", - "Unable to leave room": "Nie je možné opustiť miestnosť", "Community Settings": "Nastavenia komunity", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Tieto miestnosti sú zobrazené všetkým členom na stránke komunity. Členovia komunity môžu vstúpiť do miestnosti kliknutím.", "Add rooms to this community": "Pridať miestnosti do tejto komunity", @@ -773,9 +770,6 @@ "Device ID:": "ID zariadenia:", "Device key:": "Kľúč zariadenia:", "Ignored Users": "Ignorovaní používatelia", - "Bug Report": "Hlásenie chyby", - "Found a bug?": "Našli ste chybu?", - "Report it": "Ohláste ju", "Analytics": "Analytické údaje", "Riot collects anonymous analytics to allow us to improve the application.": "Riot zbiera anonymné analytické údaje, čo nám umožňuje aplikáciu ďalej zlepšovať.", "Labs": "Experimenty", @@ -1005,8 +999,6 @@ "Opens the Developer Tools dialog": "Otvorí dialóg nástroje pre vývojárov", "Fetching third party location failed": "Nepodarilo sa získať umiestnenie tretej strany", "A new version of Riot is available.": "Dostupná je nová verzia Riot.", - "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk chat", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Prosím, Napíšte text hlásenia. Čo ste práve robili? Čo ste očakávali? Čo sa v skutočnosti udialo?", "Couldn't load home page": "Nie je možné načítať domovskú stránku", "Send Account Data": "Odoslať Údaje Účtu", "All notifications are currently disabled for all targets.": "Momentálne sú zakázané všetky oznámenia pre všetky ciele.", @@ -1015,12 +1007,9 @@ "Notification targets": "Ciele oznámení", "Today": "Dnes", "Files": "Súbory", - "Report a bug": "Ohlásiť chybu", - "Implementing VR services with Matrix": "Implementácia služieb VR s Matrix", "You are not receiving desktop notifications": "Nedostávate oznámenia na pracovnej ploche", "Friday": "Piatok", "Update": "Aktualizovať", - "You need to be using HTTPS to place a screen-sharing call.": "Ak si želáte spustiť zdieľanie obrazovky, musíte byť pripojení cez protokol HTTPS.", "Unable to fetch notification target list": "Nie je možné získať zoznam cieľov oznámení", "Add an email address above to configure email notifications": "Ak si chcete nastaviť oznamovanie emailom, pridajte si emailovú adresu vyššie", "Expand panel": "Rozbaliť panel", @@ -1028,31 +1017,24 @@ "%(count)s Members|other": "%(count)s Členov", "Filter room names": "Filtrovať názvy miestností", "Changelog": "Zoznam zmien", - "Running Matrix services": "Prevádzka služieb postavených na Matrix", "Waiting for response from server": "Čakanie na odpoveď zo servera", "Uploaded on %(date)s by %(user)s": "Nahral používateľ %(user)s dňa %(date)s", "Send Custom Event": "Odoslať vlastnú udalosť", - "Failed to send report: ": "Nepodarilo sa odoslať hlásenie: ", - "Unknown device": "Neznáme zariadenie", "Advanced notification settings": "Pokročilé nastavenia oznámení", "Failed to send logs: ": "Nepodarilo sa odoslať záznamy: ", "delete the alias.": "vymazať alias.", "To return to your account in future you need to set a password": "Aby ste sa v budúcnosti mohli vrátiť k vašemu účtu mali by ste si teraz nastaviť heslo", "Forget": "Zabudnuť", - "Riot/Web & Desktop chat": "Riot/Web & Desktop chat", "Hide panel": "Skryť panel", "You cannot delete this image. (%(code)s)": "Nemôžete vymazať tento obrázok. (%(code)s)", "Cancel Sending": "Zrušiť odosielanie", "This Room": "V tejto miestnosti", - "Get started with some tips from Riot Bot!": "Začnite zopár tipmi v diskusii s Riot Bot!", "The Home Server may be too old to support third party networks": "Domovský server môže byť natoľko zastaralý, že nepodporuje siete tretíh strán", "Resend": "Poslať znovu", "Room not found": "Miestnosť nenájdená", "Downloading update...": "Sťahovanie aktualizácie...", "Messages in one-to-one chats": "Správy v priamych konverzáciách", - "Contributing code to Matrix and Riot": "Prispievanie kódu projektom Matrix a Riot", "Unavailable": "Nedostupné", - "Community-run support for Synapse": "Komunitná podpora pre Synapse", "View Decrypted Source": "Zobraziť dešifrovaný zdroj", "Failed to update keywords": "Nepodarilo sa aktualizovať kľúčové slová", "Notes:": "Poznámky:", @@ -1061,23 +1043,17 @@ "Safari and Opera work too.": "Správne fungujú aj Safari a Opera.", "Please set a password!": "Prosím, nastavte si heslo!", "You have successfully set a password!": "Ǔspešne ste si nastavili heslo!", - "Chat with Riot Bot": "Konverzácia s Riot Bot", - "Support for those using, running and writing other bridges": "Podpora pre používateľov, prevádzkovateľov a tvorcov premostení do ďalších sietí", - "Admin support for Dendrite": "Administrátorská podpora pre Dendrite", "Explore Room State": "Preskúmať Stav Miestnosti", "Source URL": "Pôvodná URL", "Messages sent by bot": "Správy odosielané robotmi", "Filter results": "Filtrovať výsledky", "Members": "Členovia", "No update available.": "K dispozícii nie je žiadna aktualizácia.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Na Matrixe je k dispozícii množstvo nezávislých diskusných miestností a tiež miestnosti prepojené z iných sietí (Slack, IRC, Gitter atď). Pozrite si adresár!", "Noisy": "Hlučné", "Failed to get protocol list from Home Server": "Nepodarilo sa získať zoznam protokolov z domovského servera", "Collecting app version information": "Získavajú sa informácie o verzii aplikácii", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Vymazať alias %(alias)s a odstrániť miestnosť %(name)s z adresára?", - "Co-ordination for Riot/Web translators": "Koordinácia prekladov Riot/Web", "This will allow you to return to your account after signing out, and sign in on other devices.": "Toto vám v budúcnosti umožní vrátiť sa k vašemu účtu aj po odhlásení, alebo tiež prihlásiť sa na iných zariadeniach.", - "Dev chat for the Dendrite dev team": "Diskusia pre tím vývojárov Dendrite", "Keywords": "Kľúčové slová", "Enable notifications for this account": "Povoliť oznámenia pre tento účet", "Directory": "Adresár", @@ -1102,15 +1078,11 @@ "Direct Chat": "Priama konverzácia", "The server may be unavailable or overloaded": "Server môže byť nedostupný alebo preťažený", "Reject": "Odmietnuť", - "Riot is not supported on mobile web. Install the app?": "Riot nie je podporovaný na mobilných zariadeniach. Želáte si nainštalovať aplikáciu?", - "Discussion of all things Matrix!": "Diskusia o všetkom okolo Matrix!", "Failed to set Direct Message status of room": "Nepodarilo sa nastaviť stav miestnosti priama konverzácia", "Monday": "Pondelok", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "S cieľom lepšej diagnostiky problému sa spolu s vašim hlásením odošlú záznami o činnosti programu Riot. Ak si želáte odoslať len text hlásenia, odškrtnite nasledujúce pole:", "Remove from Directory": "Odstrániť z adresára", "Enable them now": "Povolte si ich teraz", "Messages containing my user name": "Správy obsahujúce moje používateľské meno", - "Describe your problem here.": "Tu popíšte váš problém.", "Toolbox": "Nástroje", "Collecting logs": "Získavajú sa záznamy", "more": "viac", @@ -1125,48 +1097,32 @@ "Quote": "Citácia", "Send logs": "Zahrnúť záznamy", "All messages": "Všetky správy", - "Implementing VoIP services with Matrix": "Implementácia VoIP služieb s Matrix", - "Dev chat for the Riot/Web dev team": "Diskusia pre tím vývojárov Riot/Web", "Call invitation": "Audio / Video hovory", - "Riot Desktop on %(platformName)s": "Riot Desktop pre %(platformName)s", "Messages containing my display name": "Správy obsahujúce moje zobrazované meno", "You have successfully set a password and an email address!": "Úspešne si si nastavili heslo aj emailovú adresu!", "Failed to send custom event.": "Odoslanie vlastnej udalosti zlyhalo.", "What's new?": "Čo je nové?", - "Discussion of the Identity Service API": "Diskusia o API služby totožností", - "Support for those using and running matrix-appservice-irc": "Podpora pre používateľov a prevádzkovateľov matrix-appservice-irc", - "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk chat", "Notify me for anything else": "Oznamovať mi všetko ostatné", "When I'm invited to a room": "Pozvania vstúpiť do miestnosti", - "Design and implementation of E2E in Matrix": "Návrh a implementácia E2E pre Matrix", "Click here to create a GitHub issue.": "Kliknutím sem nám pošlete hlásenie o chybe cez Github.", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Vlastné nastavenia servera môžete použiť na pripojenie k iným serverom Matrix a to zadaním URL adresy domovského servera.
    Umožní vám to použiť Riot s už existujúcim Matrix účtom na akomkoľvek domovskom servery.

    Môžete tiež nastaviť vlastný server totožností, no ak tak urobíte, nebudete môcť do konverzácií pozývať používateľov zadaním ich emailovej adresy, ani ostatní nebudú môcť pozvať vás zadaním vašej emailovej adresy.", "Can't update user notification settings": "Nie je možné aktualizovať používateľské nastavenia oznamovania", "Notify for all other messages/rooms": "oznamovať všetky ostatné správy / miestnosti", "Unable to look up room ID from server": "Nie je možné vyhľadať ID miestnosti na servery", "Couldn't find a matching Matrix room": "Nie je možné nájsť zodpovedajúcu Matrix miestnosť", "Bug report sent": "Hlásenie chyby odoslané", - "Safari and Opera work too.": "Safari a Opera tiež fungujú spoľahlivo.", - "Loading bug report module": "Načítanie modulu hlásenia chýb", "Invite to this room": "Pozvať do tejto miestnosti", "You cannot delete this message. (%(code)s)": "Nemôžete vymazať túto správu. (%(code)s)", "Thursday": "Štvrtok", "I understand the risks and wish to continue": "Rozumiem rizikám a želám si pokračovať", "Logs sent": "Záznamy boli odoslané", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s cez %(browserName)s pre %(osName)s", "Back": "Naspäť", "Reply": "Odpovedať", "Show message in desktop notification": "Zobraziť text správy v oznámení na pracovnej ploche", "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Ladiace záznamy obsahujú údaje o používaní aplikácii, vrátane vašeho používateľského mena, názvy a aliasy miestností a komunít, ku ktorým ste sa pripojili a mená ostatných používateľov. Tieto záznamy neobsahujú samotný obsah vašich správ.", "Unhide Preview": "Zobraziť náhľad", - "Announcements about Synapse releases": "Oznamy o verziách Synapse", - "Search the room directory": "Prehľadať adresár miestností", - "Please describe the bug and/or send logs.": "Prosím, popíšte problém a / alebo pošlite záznamy.", "Unable to join network": "Nie je možné sa pripojiť k sieti", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Tieto nastavenia oznámení sa použijú aj napriek tomu, že ich nemôžete meniť cez Riot. Pravdepodobne ste si ich nastavili v inej aplikácii", "Sorry, your browser is not able to run Riot.": "Prepáčte, vo vašom prehliadači nie je možné spustiť Riot.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Decentralizovaný, šifrovaný chat a spolupráca na platforme [matrix]", - "Building services on Matrix": "Stavba služieb na Matrix", "Messages in group chats": "Správy v skupinových konverzáciách", "Yesterday": "Včera", "Error encountered (%(errorDetail)s).": "Vyskytla sa chyba (%(errorDetail)s).", @@ -1175,16 +1131,13 @@ "What's New": "Čo Je Nové", "Set Password": "Nastaviť Heslo", "Appear Offline": "Zdá sa byť nedostupný", - "Support for those using the Matrix spec": "Podpora pre konzumentov špecifikácie Matrix", "An error occurred whilst saving your email notification preferences.": "Počas ukladania vašich nastavení oznamovania emailom sa vyskytla chyba.", "Enable audible notifications in web client": "Povoliť zvukové oznámenia vo webovom klientovi", "Permalink": "Trvalý odkaz", - "Welcome to Riot.im": "Víta vás Riot.im", "Off": "Zakázané", "Riot does not know how to join a room on this network": "Riot nedokáže vstúpiť do miestnosti na tejto sieti", "Mentions only": "Len zmienky", "You can now return to your account after signing out, and sign in on other devices.": "Odteraz sa budete k svojmu účtu vedieť vrátiť aj po odhlásení, alebo tiež prihlásiť na iných zariadeniach.", - "Please install Chrome or Firefox for the best experience.": "Prosím, nainštalujte si Chrome alebo Firefox , aby bol váš zážitok pri používaní Riot čo možno najlepší.", "Enable email notifications": "Povoliť oznamovanie emailom", "Login": "Prihlásiť", "Download this file": "Stiahnuť tento súbor", @@ -1194,13 +1147,11 @@ "%(count)s Members|one": "%(count)s Člen", "Developer Tools": "Vývojárske Nástroje", "View Source": "Zobraziť zdroj", - "Matrix technical discussions": "Technické diskusie o Matrix", "Event Content": "Obsah Udalosti", "Thank you!": "Ďakujeme!", "#example": "#príklad", "Collapse panel": "Zbaliť panel", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Vo vašom súčasnom prehliadači nemusí Riot vizerať ani fungovať správne a niektoré alebo všetky vlastnosti môžu chýbať. Ak to chcete vyskúšať, môžete pokračovať, no pri riešení problémov s tým spojených si budete musieť poradiť na vlastnú päsť!", "Checking for an update...": "Kontrola dostupnosti aktualizácie...", - "General discussion about Matrix and Riot": "Všeobecná diskusia o Matrix a Riot", "There are advanced notifications which are not shown here": "Niektoré pokročilé oznámenia nemôžu byť zobrazené" } diff --git a/src/i18n/strings/sq.json b/src/i18n/strings/sq.json index 8ec4b34c27..dc26c7c283 100644 --- a/src/i18n/strings/sq.json +++ b/src/i18n/strings/sq.json @@ -119,7 +119,6 @@ "Unignored user": "Përdorues jo më i shpërfillur", "Fetching third party location failed": "Dështoi prurja e vendndodhjes së palës së tretë", "A new version of Riot is available.": "Ka gati një version të ri Riot-it.", - "Riot/Android & matrix-android-sdk chat": "Fjalosje mbi Riot/Android & matrix-android-sdk", "Couldn't load home page": "S’u ngarkua dot faqja hyrëse", "Send Account Data": "Dërgo të Dhëna Llogarie", "All notifications are currently disabled for all targets.": "Krejt njoftimet hëpërhë janë çaktivizuar për krejt objektivat.", @@ -129,12 +128,10 @@ "Notification targets": "Objektiva njoftimesh", "Today": "Sot", "Files": "Kartela", - "Implementing VR services with Matrix": "Sendërtim shërbimesh VR me Matrix-in", "You are not receiving desktop notifications": "Nuk po merrni njoftime për desktop", "Friday": "E premte", "Update": "Përditësoje", "Notifications": "Njoftime", - "You need to be using HTTPS to place a screen-sharing call.": "Që të bëni një thirrje me ndarje ekrani, duhet të jeni duke përdorur HTTPS-në.", "Unable to fetch notification target list": "S’arrihet të sillet listë objektivash njoftimi", "Add an email address above to configure email notifications": "Shtoni më sipër një adresë email që të formësoni njoftime me email", "Expand panel": "Zgjerojeni panelin", @@ -143,13 +140,11 @@ "Filter room names": "Filtroni emra dhomash", "Changelog": "Regjistër ndryshimesh", "Reject": "Hidheni tej", - "Running Matrix services": "Xhirim shërbimesh Matrix", "Waiting for response from server": "Po pritet për përgjigje shërbyesi", "Failed to change password. Is your password correct?": "S’u arrit të ndryshohet fjalëkalimi. A është i saktë fjalëkalimi juaj?", "Uploaded on %(date)s by %(user)s": "Ngarkuar më %(date)s nga %(user)s", "OK": "OK", "Send Custom Event": "Dërgoni Akt Vetjak", - "Unknown device": "Pajisje e panjohur", "Advanced notification settings": "Rregullime të mëtejshme për njoftimet", "Failed to send logs: ": "S’u arrit të dërgohen regjistra: ", "delete the alias.": "fshije aliasin.", @@ -157,7 +152,6 @@ "Forget": "Harroje", "World readable": "E lexueshme nga bota", "Mute": "Pa Zë", - "Riot/Web & Desktop chat": "Fjalosje mbi Riot/Web & Desktop", "Hide panel": "Fshihe panelin", "You cannot delete this image. (%(code)s)": "S’mund ta fshini këtë figurë. (%(code)s)", "Cancel Sending": "Anuloje Dërgimin", @@ -168,21 +162,15 @@ "Room not found": "Dhoma s’u gjet", "Downloading update...": "Po shkarkohet përditësim…", "Messages in one-to-one chats": "Mesazhe në fjalosje tek për tek", - "Contributing code to Matrix and Riot": "Kontribut me kod te Matrix dhe te Riot", "Unavailable": "S’kapet", - "Community-run support for Synapse": "Asistencë për Synapse-in nga bashkësia", "View Decrypted Source": "Shihni Burim të Shfshehtëzuar", "Failed to update keywords": "S’u arrit të përditësohen fjalëkyçe", "Notes:": "Shënime:", - "Welcome to Riot.im": "Mirë se vini te Riot.im", "Notifications on the following keywords follow rules which can’t be displayed here:": "Njoftimet e shkaktuara nga fjalëkyçet vijuese ndjekin rregulla që s’mund të shfaqen këtu:", "Safari and Opera work too.": "Safari dhe Opera bëjnë, po ashtu.", "Please set a password!": "Ju lutemi, caktoni një fjalëkalim!", "powered by Matrix": "bazuar në Matrix", "You have successfully set a password!": "Caktuat me sukses një fjalëkalim!", - "Chat with Riot Bot": "Fjalosuni me Robotin Riot", - "Support for those using, running and writing other bridges": "Asistencë për ata që përdorin, xhirojnë ose programojnë ura të tjera", - "Admin support for Dendrite": "Asistencë përgjegjësi për Dendrite-in", "Favourite": "E parapëlqyer", "All Rooms": "Krejt Dhomat", "Explore Room State": "Eksploroni Gjendje Dhome", @@ -192,14 +180,11 @@ "Filter results": "Filtroni përfundimet", "Members": "Anëtarë", "No update available.": "S’ka përditësim gati.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Ka tashmë plot dhoma në Matrix, të lidhura me rrjete ekzistues (Slack, IRC, Gitter, etj) ose të pavarur. Hidhini një sy listës!", "Noisy": "I zhurmshëm", "Failed to get protocol list from Home Server": "S’u arrit të merrej listë protokollesh nga Shërbyesi Home", "Collecting app version information": "Po grumbullohen të dhëna versioni aplikacioni", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Të fshihet aliasi i dhomës %(alias)s dhe të hiqet %(name)s nga drejtoria?", - "Co-ordination for Riot/Web translators": "Bashkërendim për përkthyesit e Riot/Web-it", "This will allow you to return to your account after signing out, and sign in on other devices.": "Kjo do t’ju lejojë të riktheheni te llogaria juaj pasi të keni bërë daljen, dhe të hyni që nga pajisje të tjera.", - "Dev chat for the Dendrite dev team": "Fjalosje zhvillimi, për ekipin e zhvilluesve të Dendrite-it", "Keywords": "Fjalëkyçe", "Unpin Message": "Shfiksojeni Mesazhin", "Enable notifications for this account": "Aktivizo njoftime për këtë llogari", @@ -228,8 +213,6 @@ "Direct Chat": "Fjalosje e Drejtpërdrejtë", "The server may be unavailable or overloaded": "Shërbyesi mund të jetë i pakapshëm ose i mbingarkuar", "Online": "Në linjë", - "Riot is not supported on mobile web. Install the app?": "Riot-i nuk mbulohet nën web për celularët. Të instalohet aplikacioni?", - "Discussion of all things Matrix!": "Diskutime mbi gjithçka të lidhur me Matrix-in!", "Failed to set Direct Message status of room": "S’u arrit të caktohej gjendje Mesazhesh të Drejtpërdrejtë në dhomë", "Monday": "E hënë", "Download this file": "Shkarkoje këtë kartelë", @@ -253,47 +236,33 @@ "Send logs": "Dërgo regjistra", "All messages": "Krejt mesazhet", "unknown error code": "kod gabimi të panjohur", - "Implementing VoIP services with Matrix": "Sendërtim shërbimesh VoIP me Matrix-in", - "Dev chat for the Riot/Web dev team": "Fjalosje mbi zhvillimin, për ekipin e zhvilluesve të Riot/Web-i", "Call invitation": "Ftesë për thirrje", "Thank you!": "Faleminderit!", - "Riot Desktop on %(platformName)s": "Riot Desktop në %(platformName)s", "Messages containing my display name": "Mesazhe që përmbajnë emrin tim të ekranit", "State Key": "Kyç Gjendjeje", "Failed to send custom event.": "S’u arrit të dërgohet akt vetjak.", "What's new?": "Ç’ka të re?", - "Discussion of the Identity Service API": "Diskutime mbi Identity Service API", - "Support for those using and running matrix-appservice-irc": "Asistencë për ata që përdorin dhe xhirojnë matrix-appservice-irc", - "Riot/iOS & matrix-ios-sdk chat": "Fjalosje mbi Riot/iOS & matrix-android-sdk", "Notify me for anything else": "Njoftomë për gjithçka tjetër", "When I'm invited to a room": "Kur ftohem në një dhomë", - "Design and implementation of E2E in Matrix": "Konceptimi dhe sendërtimi i E2E në Matrix", "Close": "Mbylle", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Mund t’i përdorni mundësitë e shërbyesit vetjak për të hyrë në shërbyes të tjerë Matrix, duke dhënë URL-në e një tjetër shërbyesi Home.
    Kjo ju lejon ta përdorni Riot-in me një llogari Matrix ekzistuese në një tjetër shërbyes vatër.

    Mundeni edhe të caktoni një shërbyes vetjak identitetesh, por s’do të jeni në gjendje të ftoni përdorues përmes adresash email, ose të ftoheni ju vetëm përmes adrese email.", "Can't update user notification settings": "S’përditësohen dot rregullime njoftimi të përdoruesit", "Notify for all other messages/rooms": "Njoftim për krejt mesazhet/dhomat e tjera", "Unable to look up room ID from server": "S’arrihet të kërkohet ID dhome nga shërbyesi", "Click here to create a GitHub issue.": "Klikoni këtu që të hapni një çështje në GitHub.", "Couldn't find a matching Matrix room": "S’u gjet dot një dhomë Matrix me përputhje", - "Support for those using the Matrix spec": "Asistencë për ata që përdorin specifikimet Matrix", "Invite to this room": "Ftoje te kjo dhomë", "You cannot delete this message. (%(code)s)": "S’mund ta fshini këtë mesazh. (%(code)s)", "Thursday": "E enjte", "I understand the risks and wish to continue": "I kuptoj rreziqet dhe dua të vazhdoj", "Logs sent": "Regjistrat u dërguan", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s përmes %(browserName)s nën %(osName)s", "Back": "Mbrapsht", "Reply": "Përgjigjuni", "Show message in desktop notification": "Shfaq mesazh në njoftim për desktop", "You must specify an event type!": "Duhet të përcaktoni një lloj akti!", "Unhide Preview": "Shfshihe Paraparjen", - "Announcements about Synapse releases": "Njoftime rreth hedhjesh në qarkullim të Synapse-it", - "Search the room directory": "Kërkoni te drejtoria e dhomave", "Unable to join network": "S’arrihet të hyhet në rrjet", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Mund t’i keni formësuar në një tjetër klient nga Riot-i. S’mund t’i sintonizoni në Riot, por ata janë ende të vlefshëm", "Sorry, your browser is not able to run Riot.": "Na ndjeni, shfletuesi juaj nuk është në gjendje të xhirojë Riot-in.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Decentralised, encrypted Fjalosje & bashkëpunim i decentralizuar, i fshehtëzuar, bazuar në [matrix]", - "Building services on Matrix": "Ndërtim shërbimesh mbi Matrix", "Messages in group chats": "Mesazhe në fjalosje në grup", "Yesterday": "Dje", "Error encountered (%(errorDetail)s).": "U has gabim (%(errorDetail)s).", @@ -302,7 +271,6 @@ "What's New": "Ç’ka të Re", "Set Password": "Caktoni Fjalëkalim", "Appear Offline": "Shfaqju Si Jo Në Linjë", - "Get started with some tips from Riot Bot!": "Fillojani me disa ndihmëza nga Roboti Riot!", "An error occurred whilst saving your email notification preferences.": "Ndodhi një gabim teksa ruheshin parapëlqimet tuaja për njoftime me email.", "Enable audible notifications in web client": "Aktivizoni njoftime audio te klienti web", "Permalink": "Permalidhje", @@ -326,7 +294,6 @@ "%(count)s Members|one": "%(count)s Anëtar", "Developer Tools": "Mjete Zhvilluesi", "View Source": "Shihini Burimin", - "General discussion about Matrix and Riot": "Diskutime të përgjithshme mbi Matrix-in dhe Riot-in", "Custom Server Options": "Mundësi Vetjake Shërbyesi", "Event Content": "Lëndë Akti", "Rooms": "Dhoma", @@ -334,6 +301,5 @@ "Collapse panel": "Tkurre panelin", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Me shfletuesin tuaj të tanishëm, pamja dhe ndjesitë nga aplikacioni mund të jenë plotësisht të pasakta, dhe disa nga ose krejt veçoritë të mos funksionojnë. Nëse doni ta provoni sido qoftë, mund të vazhdoni, por mos u ankoni për çfarëdo problemesh që mund të hasni!", "Checking for an update...": "Po kontrollohet për një përditësim…", - "Matrix technical discussions": "Diskutime teknike rreth Matrix-it", "There are advanced notifications which are not shown here": "Ka njoftime të thelluara që nuk shfaqen këtu" } diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index 05f50d49a0..8d218f5595 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -304,8 +304,6 @@ "Hangup": "Спусти слушалицу", "Voice call": "Гласовни позив", "Video call": "Видео позив", - "Hide Apps": "Сакриј апликације", - "Show Apps": "Прикажи апликације", "Upload file": "Отпреми датотеку", "Show Text Formatting Toolbar": "Прикажи алатницу за форматирање текста", "Send an encrypted reply…": "Пошаљи шифровани одговор…", @@ -744,7 +742,6 @@ "Leave Community": "Напусти заједницу", "Leave %(groupName)s?": "Напустити %(groupName)s?", "Leave": "Напусти", - "Unable to leave room": "Не могу да напустим собу", "Community Settings": "Подешавања заједнице", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Ове собе су приказане члановима заједнице на страници заједнице. Чланови заједнице могу приступити собама кликом на њих.", "Add rooms to this community": "Додај собе у ову заједницу", @@ -766,8 +763,6 @@ "Failed to leave room": "Нисам успео да напустим собу", "Signed Out": "Одјављен", "For security, this session has been signed out. Please sign in again.": "Зарад безбедности, одјављени сте из ове сесије. Пријавите се поново.", - "Cryptography data migrated": "Криптографски подаци су пренесени", - "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "Једноструко преношење криптографских података је обављено. Шифровање с краја на крај неће радити ако се вратите на старије издање Riot-а. Ако вам треба шифровање с краја на крај на старијем издању, прво се одјавите из Riot-а. Да бисте задржали историјат порука, извезите па поново увезите ваше кључеве.", "Old cryptography data detected": "Нађени су стари криптографски подаци", "The platform you're on": "Платформа коју користите", "The version of Riot.im": "Riot.im издање", @@ -855,9 +850,6 @@ "Device ID:": "ИБ уређаја:", "Device key:": "Кључ уређаја:", "Ignored Users": "Занемарени корисници", - "Bug Report": "Извештај о грешци", - "Found a bug?": "Нашли сте грешку?", - "Report it": "Пријавите је", "Riot collects anonymous analytics to allow us to improve the application.": "Riot прикупља анонимне податке о коришћењу да бисмо побољшали апликацију.", "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Приватност је веома важна нама те не сакупљамо било какве податке личне природе у нашој аналитици.", "Learn more about how we use analytics.": "Сазнајте више о нашем начину употребе аналитике.", @@ -997,8 +989,6 @@ "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Да бисте поставили филтер, повуците аватар заједнице на површ филтрирања скроз на леву страну екрана. Можете кликнути на аватар у површи филтрирања било када да бисте видели само собе и особе везане за ту заједницу.", "Fetching third party location failed": "Добављање локације треће стране није успело", "A new version of Riot is available.": "Ново издање RIot-а је доступно.", - "Riot/Android & matrix-android-sdk chat": "Riot/Андроид и matrix-android-sdk ћаскање", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Опишите грешку. Шта сте урадили? Шта сте очекивали да се догоди? Шта се заправо догодило?", "Couldn't load home page": "Нисам могао да учитам почетну страну", "Send Account Data": "Пошаљи податке налога", "All notifications are currently disabled for all targets.": "Сва обавештења су тренутно онемогућена за све циљеве.", @@ -1007,12 +997,9 @@ "Notification targets": "Циљеви обавештења", "Today": "Данас", "Files": "Датотеке", - "Report a bug": "Пријави грешку", - "Implementing VR services with Matrix": "Израда услуга за ВР уз Матрикс", "You are not receiving desktop notifications": "Не примате стона обавештења", "Friday": "Петак", "Update": "Ажурирај", - "You need to be using HTTPS to place a screen-sharing call.": "Морате користити HTTPS да бисте започели позив са дељењем екрана.", "Unable to fetch notification target list": "Не могу да досегнем списак циљева за обавештења", "Add an email address above to configure email notifications": "Додајте мејл адресу изнад да бисте подесили мејл обавештења", "Expand panel": "Прошири површ", @@ -1020,31 +1007,23 @@ "%(count)s Members|other": "%(count)s чланова", "Filter room names": "Филтрирај називе соба", "Changelog": "Записник о изменама", - "Running Matrix services": "Покренуте Матрикс услуге", "Waiting for response from server": "Чекам на одговор са сервера", "Uploaded on %(date)s by %(user)s": "Отпремљено датума %(date)s од корисника %(user)s", "Send Custom Event": "Пошаљи прилагођени догађај", - "Failed to send report: ": "Нисам успео да пошаљем извештај: ", "Off": "Искључено", - "Unknown device": "Непознати уређај", "Advanced notification settings": "Напредна подешавања обавештења", "delete the alias.": "обриши алијас.", "To return to your account in future you need to set a password": "Да бисте се вратили на ваш налог у будућности, морате поставити лозинку", "Forget": "Заборави", - "Riot/Web & Desktop chat": "Riot/веб и стоно ћаскање", "Hide panel": "Сакриј површ", "You cannot delete this image. (%(code)s)": "Не можете обрисати ову слику. (%(code)s)", "Cancel Sending": "Откажи слање", "This Room": "Ова соба", - "Get started with some tips from Riot Bot!": "Крените уз пар савета од Riot бота!", "The Home Server may be too old to support third party networks": "Кућни сервер је можда сувише застарео да би подржао мреже трећих страна", - "All messages (loud)": "Све поруке (гласно)", "Room not found": "Соба није пронађена", "Downloading update...": "Преузимам ажурирање...", "Messages in one-to-one chats": "Поруке у један-на-један ћаскањима", - "Contributing code to Matrix and Riot": "Додавање кода у Матрикс и Riot", "Unavailable": "Недоступан", - "Community-run support for Synapse": "Подршка од стране заједнице за Synapse", "View Decrypted Source": "Погледај дешифровани извор", "Failed to update keywords": "Нисам успео да ажурирам кључне речи", "remove %(name)s from the directory.": "уклони %(name)s из фасцикле.", @@ -1052,23 +1031,17 @@ "Safari and Opera work too.": "Сафари и Опера такође раде.", "Please set a password!": "Поставите лозинку!", "You have successfully set a password!": "Успешно сте поставили лозинку!", - "Chat with Riot Bot": "Ћаскајте са Riot ботом", - "Support for those using, running and writing other bridges": "Подршка за оне који користе, одржавају и пишу друге мостове", - "Admin support for Dendrite": "Администраторска подршка за Dendrite", "Explore Room State": "Истражи стање собе", "Source URL": "Адреса извора", "Messages sent by bot": "Поруке послате од бота", "Filter results": "Филтрирај резултате", "Members": "Чланови", "No update available.": "Нема нових ажурирања.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Много соба већ постоји у Матриксу, неке су повезане на постојеће мреже (Slack, IRC, Gitter итд.) а неке независне. Погледајте фасциклу!", "Noisy": "Бучно", "Failed to get protocol list from Home Server": "Нисам успео да добијем списак протокола од кућног сервера", "Collecting app version information": "Прикупљам податке о издању апликације", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Обрисати алијас собе %(alias)s и уклонити %(name)s из фасцикле?", - "Co-ordination for Riot/Web translators": "Координација за Riot/веб преводиоце", "This will allow you to return to your account after signing out, and sign in on other devices.": "Ово ће вам омогућити да се вратите у ваш налог након што се одјавите и пријавите, на другим уређајима.", - "Dev chat for the Dendrite dev team": "Програмерско ћаскање за Dendrite програмерски тим", "Keywords": "Кључне речи", "Enable notifications for this account": "Омогући обавештења за овај налог", "Directory": "Фасцикла", @@ -1091,15 +1064,11 @@ "Direct Chat": "Директно ћаскање", "The server may be unavailable or overloaded": "Сервер је можда недоступан или преоптерећен", "Reject": "Одбаци", - "Riot is not supported on mobile web. Install the app?": "RIot не ради на мобилном вебу. Инсталирати апликацију?", - "Discussion of all things Matrix!": "Разговори о свим Матрикс стварима!", "Failed to set Direct Message status of room": "Нисам успео да подесим стање директне поруке собе", "Monday": "Понедељак", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Да бисмо проучили проблеме, послаћемо записнике са овог клијента уз овај извештај о грешци. Уколико само желите да пошаљете текст изнад, дештиклирајте:", "Remove from Directory": "Уклони из фасцикле", "Enable them now": "Омогућите их сада", "Messages containing my user name": "Поруке које садрже моје корисничко име", - "Describe your problem here.": "Опишите ваш проблем овде.", "Toolbox": "Алатница", "Collecting logs": "Прикупљам записнике", "more": "више", @@ -1112,44 +1081,29 @@ "Wednesday": "Среда", "Send logs": "Пошаљи записнике", "All messages": "Све поруке", - "Implementing VoIP services with Matrix": "Израда VoIP услуга уз Матрикс", - "Dev chat for the Riot/Web dev team": "Програмерско ћаскање за Riot/веб програмерски тим", "Call invitation": "Позивница за позив", - "Riot Desktop on %(platformName)s": "Riot стони програм за %(platformName)s", "Messages containing my display name": "Поруке које садрже моје приказно име", "You have successfully set a password and an email address!": "Успешно сте поставили лозинку и мејл адресу!", "Failed to send custom event.": "Нисам успео да пошаљем прилагођени догађај.", "What's new?": "Шта је ново?", - "Discussion of the Identity Service API": "Разговори о API-ју идентитетског сервиса", - "Support for those using and running matrix-appservice-irc": "Подршка за оне који користе и одржавају matrix-appservice-irc", - "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS и matrix-ios-sdk ћаскање", "Notify me for anything else": "Обавести ме за било шта друго", "When I'm invited to a room": "Када сам позван у собу", - "Design and implementation of E2E in Matrix": "Дизајн и имплементација E2E у Матриксу", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Можете користити опције прилагођеног сервера за пријаву у друге Матрикс сервере навођењем другачије адресе кућног сервера.
    Ово вам омогућава да користите Riot са постојећим Матрикс налогомна другом кућном серверу.

    Такође, можете поставити прилагођени идентитески сервер али нећете моћи да позивате кориснике по мејл адреси а ни други вас.", "Can't update user notification settings": "Не могу да ажурирам корисничка подешавања обавештења", "Notify for all other messages/rooms": "Обавести за све друге поруке и собе", "Unable to look up room ID from server": "Не могу да погледам ИБ собе на серверу", "Couldn't find a matching Matrix room": "Не могу да нађем одговарајућу Матрикс собу", "Bug report sent": "Извештај о грешци послат", - "Loading bug report module": "Учитавам модул за извештавање о грешкама", "Invite to this room": "Позови у ову собу", "You cannot delete this message. (%(code)s)": "Не можете обрисати ову поруку. (%(code)s)", "Thursday": "Четвртак", "I understand the risks and wish to continue": "Разумем опасност и желим да наставим", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s преко прегледача %(browserName)s на систему %(osName)s", "Back": "Назад", "Reply": "Одговори", "Show message in desktop notification": "Прикажи поруку у стоном обавештењу", "Unhide Preview": "Откриј преглед", - "Announcements about Synapse releases": "Објаве поводом нових Synapse издања", - "Search the room directory": "Претражи фасциклу са собама", - "Please describe the bug and/or send logs.": "Опишите грешку и/или пошаљите записнике.", "Unable to join network": "Не могу да приступим мрежи", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Можда сте их подесили у неком другом клијенту а не Riot-у. Не можете их преправљати у Riot-у али се и даље примењују", "Sorry, your browser is not able to run Riot.": "Нажалост, ваш прегледач не може да покреће Riot.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Децентрализовано, шифровано ћаскање и сарадња коју покреће [matrix]", - "Building services on Matrix": "Стварање услуга уз помоћ Матрикса", "Messages in group chats": "Поруке у групним ћаскањима", "Yesterday": "Јуче", "Error encountered (%(errorDetail)s).": "Догодила се грешка (%(errorDetail)s).", @@ -1158,11 +1112,9 @@ "What's New": "Шта је ново", "Set Password": "Постави лозинку", "Appear Offline": "Прикажи себе као ван мреже", - "Support for those using the Matrix spec": "Подршка за оне који користе Матрикс спецификацију", "An error occurred whilst saving your email notification preferences.": "Догодила се грешка при чувању ваших поставки мејл обавештења.", "Enable audible notifications in web client": "Омогући звучна обавештења у веб клијенту", "Permalink": "Трајна веза", - "Welcome to Riot.im": "Добродошли у Riot.im", "Resend": "Поново пошаљи", "Riot does not know how to join a room on this network": "Riot не зна како да приступи соби на овој мрежи", "Mentions only": "Само спомињања", @@ -1177,13 +1129,11 @@ "%(count)s Members|one": "%(count)s члан", "Developer Tools": "Програмерске алатке", "View Source": "Погледај извор", - "Matrix technical discussions": "Технички разговори о Матриксу", "Event Content": "Садржај догађаја", "Thank you!": "Хвала вам!", "#example": "#пример", "Collapse panel": "Скупи површ", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Са вашим тренутним прегледачем изглед и угођај ове апликације може бити скроз неправилан и неке могућности можда неће радити. Уколико желите да ипак пробате, можете наставити али ћете бити без подршке за било које проблеме на које налетите!", "Checking for an update...": "Проверавам ажурирања...", - "General discussion about Matrix and Riot": "Општи разговори о Матриксу и Riot-у", "There are advanced notifications which are not shown here": "Постоје напредна обавештења која нису приказана овде" } diff --git a/src/i18n/strings/sv.json b/src/i18n/strings/sv.json index 2296d2178f..cd502e5bb7 100644 --- a/src/i18n/strings/sv.json +++ b/src/i18n/strings/sv.json @@ -37,7 +37,6 @@ "Autoplay GIFs and videos": "Spela automatiskt upp GIFar och videor", "Are you sure you want to reject the invitation?": "Vill du avvisa inbjudan?", "Bulk Options": "Volymhandlingar", - "Bug Report": "Buggrapport", "Blacklisted": "Svartlistad", "%(senderName)s banned %(targetName)s.": "%(senderName)s bannade %(targetName)s.", "Banned users": "Bannade användare", @@ -178,7 +177,6 @@ "Forgot your password?": "Glömt lösenord?", "For security, this session has been signed out. Please sign in again.": "Av säkerhetsskäl har den här sessionen loggats ut. Vänligen logga in igen.", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Av säkerhetsskäl kommer alla krypteringsnycklar att raderas från den här webbläsaren om du loggar ut. Om du vill läsa din krypterade meddelandehistorik från framtida Riot-sessioner, exportera nycklarna till förvar.", - "Found a bug?": "Hittade du en bugg?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s från %(fromPowerLevel)s till %(toPowerLevel)s", "Guest access is disabled on this Home Server.": "Gäståtkomst är inte aktiverat på den här hemservern.", "Guests cannot join this room even if explicitly invited.": "Gäster kan inte gå med i det här rummet fastän de är uttryckligen inbjudna.", @@ -301,7 +299,6 @@ "Remove": "Ta bort", "Remove %(threePid)s?": "Ta bort %(threePid)s?", "%(senderName)s requested a VoIP conference.": "%(senderName)s begärde en VoIP-konferens.", - "Report it": "Rapportera det", "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.": "Om du återställer ditt lösenord kommer alla krypteringsnycklar på alla enheter att återställas, vilket gör krypterad meddelandehistorik oläsbar om du inte först exporterar dina rumsnycklar och sedan importerar dem igen. I framtiden kommer det här att förbättras.", "Results from DuckDuckGo": "Resultat från DuckDuckGo", "Return to login screen": "TIllbaka till login-skärmen", @@ -366,14 +363,12 @@ "Do you want to load widget from URL:": "Vill du ladda widgeten från URL:", "Edit": "Editera", "Enable automatic language detection for syntax highlighting": "Aktivera automatisk språkdetektering för syntaxmarkering", - "Hide Apps": "Dölj Appar", "Integrations Error": "Integrationsfel", "Publish this room to the public in %(domain)s's room directory?": "Publicera rummet i den offentliga rumskatalogen på %(domain)s?", "AM": "a.m.", "PM": "p.m.", "NOTE: Apps are not end-to-end encrypted": "OBS: Apparna är inte end-to-end-krypterade", "Revoke widget access": "Upphäv widget-åtkomst", - "Show Apps": "Visa appar", "Submit": "Lämna", "Tagged as: ": "Taggad som: ", "The default role for new room members is": "Standardrollen för nya medlemmar är", @@ -436,8 +431,6 @@ "You do not have permission to do that in this room.": "Du har inte behörighet att göra det i det här rummet.", "Fetching third party location failed": "Det gick inte att hämta platsdata från tredje part", "A new version of Riot is available.": "En ny version av Riot är tillgänglig.", - "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk-chatt", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Beskriv buggen. Vad gjorde du? Vad förväntade du dig att ska hända? Vad hände?", "Couldn't load home page": "Kunde inte ladda startsidan", "All notifications are currently disabled for all targets.": "Alla aviseringar är för tillfället avstängda för alla mål.", "Uploading report": "Laddar upp rapport", @@ -447,12 +440,9 @@ "Failed to set direct chat tag": "Det gick inte att markera rummet som direkt chatt", "Today": "idag", "Failed to get protocol list from Home Server": "Det gick inte att hämta protokollistan från hemservern", - "Report a bug": "Rapportera en bugg", - "Implementing VR services with Matrix": "Implementation av VR-tjänster med Matrix", "You are not receiving desktop notifications": "Du får inte skrivbordsaviseringar", "Friday": "fredag", "Update": "Uppdatera", - "You need to be using HTTPS to place a screen-sharing call.": "Du måste använda HTTPS för att dela din skärm.", "What's New": "Vad är nytt", "Add an email address above to configure email notifications": "Lägg till en epostadress här för att konfigurera epostaviseringar", "Expand panel": "Öppna panel", @@ -460,18 +450,14 @@ "%(count)s Members|other": "%(count)s 1 Medlemmar", "Filter room names": "Filtrera rumsnamn", "Changelog": "Ändringslogg", - "Running Matrix services": "Driva Matrix-tjänster", "Waiting for response from server": "Väntar på svar från servern", "Leave": "Lämna", "Uploaded on %(date)s by %(user)s": "%(user)s laddade upp %(date)s", - "Failed to send report: ": "Det gick inte att sända rapporten: ", - "Unknown device": "Okänd enhet", "Advanced notification settings": "Avancerade aviseringsinställingar", "delete the alias.": "radera adressen.", "To return to your account in future you need to set a password": "För att återgå till ditt konto i framtiden måste du välja ett lösenord", "Forget": "Glöm bort", "#example": "#exempel", - "Riot/Web & Desktop chat": "Riot/Web & Desktop-chatt", "Hide panel": "Göm panel", "You cannot delete this image. (%(code)s)": "Du kan inte radera den här bilden. (%(code)s)", "Cancel Sending": "Avbryt sändning", @@ -482,18 +468,13 @@ "Room not found": "Rummet hittades inte", "Messages containing my display name": "Meddelanden som innehåller mitt namn", "Messages in one-to-one chats": "Meddelanden i privata chattar", - "Contributing code to Matrix and Riot": "Bidra med kod till Matrix och Riot", "Unavailable": "Inte tillgänglig", - "Community-run support for Synapse": "Gemenskapsdriven användarhjälp för Synapse", "View Decrypted Source": "Visa dekrypterad källa", "Failed to update keywords": "Det gick inte att uppdatera nyckelorden", "remove %(name)s from the directory.": "ta bort %(name)s från katalogen.", "Notifications on the following keywords follow rules which can’t be displayed here:": "Aviseringar för följande nyckelord följer regler som inte kan visas här:", "Please set a password!": "Vänligen välj ett lösenord!", "You have successfully set a password!": "Du har valt ett nytt lösenord!", - "Chat with Riot Bot": "Chatta med Riot Bot", - "Support for those using, running and writing other bridges": "Hjälp för de som använder, driver och utvecklar andra bryggor", - "Admin support for Dendrite": "Hjälp för administratörer av Dendrite", "An error occurred whilst saving your email notification preferences.": "Ett fel uppstod då epostaviseringsinställningarna sparades.", "Explore Room State": "Utforska rumläget", "Source URL": "Käll-URL", @@ -501,15 +482,11 @@ "Filter results": "Filtrera resultaten", "Members": "Medlemmar", "No update available.": "Ingen uppdatering tillgänglig.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Många rum finns redan i Matrix, länkade till andra nätverk (Slack, IRC, Gitter etc.) eller fristående. Kolla in katalogen!", "Resend": "Sänd igen", "Files": "Filer", "Collecting app version information": "Samlar in appversionsinformation", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Radera rumsadressen %(alias)s och ta bort %(name)s från katalogen?", - "customServer_text": "Du kan använda serverinställningarna för att logga in i en annan Matrix-server genom att specifiera en URL till en annan hemserver.
    Så här kan du använda Riot med ett existerande Matrix-konto på en annan hemserver.

    Du kan också specifiera en egen identitetsserver, men du kommer inte att kunna bjuda in andra via epostadress, eller bli inbjuden via epostadress.", - "Co-ordination for Riot/Web translators": "Koordination för översättare av Riot/Web", "This will allow you to return to your account after signing out, and sign in on other devices.": "Detta kommer tillåta dig att återgå till ditt konto efter att ha loggat ut, och logga in på andra enheter.", - "Dev chat for the Dendrite dev team": "Chatt för utvecklare av Dendrite", "Keywords": "Nyckelord", "Enable notifications for this account": "Sätt på aviseringar för det här kontot", "Directory": "Katalog", @@ -530,15 +507,11 @@ "Direct Chat": "Direkt-chatt", "The server may be unavailable or overloaded": "Servern kan vara överbelastad eller inte tillgänglig", "Reject": "Avvisa", - "Riot is not supported on mobile web. Install the app?": "Riot stöds inte på mobil-webb. Installera appen?", - "Discussion of all things Matrix!": "Diskussion om allt gällande Matrix!", "Failed to set Direct Message status of room": "Det gick inte att sätta Direkt meddelande-status på rummet", "Monday": "måndag", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "För att diagnostisera problem kommer loggar från den här klienten att sändas med rapporten. Om du bara vill sända texten ovan, kryssa av rutan:", "Remove from Directory": "Ta bort från katalogen", "Enable them now": "Sätt på nu", "Messages containing my user name": "Meddelanden som innehåller mitt användarnamn", - "Describe your problem here.": "Beskriv problemet här.", "Collecting logs": "Samlar in loggar", "more": "mera", "Bug report sent": "Buggraporten skickades", @@ -549,73 +522,51 @@ "Send": "Sänd", "Send logs": "Sänd loggar", "All messages": "Alla meddelanden", - "Implementing VoIP services with Matrix": "Implementation av VoIP-tjänster med Matrix", - "Dev chat for the Riot/Web dev team": "Chatt för utvecklare av Riot/Web", "Call invitation": "Inbjudan till samtal", - "Riot Desktop on %(platformName)s": "Riot Desktop på %(platformName)s", "Downloading update...": "Laddar ned uppdatering...", "You have successfully set a password and an email address!": "Du har framgångsrikt valt ett lösenord och en e-postadress!", "What's new?": "Vad är nytt?", - "Discussion of the Identity Service API": "Diskussion om Identity Service API:n", - "Support for those using and running matrix-appservice-irc": "Hjälp för de som använder och driver matrix-appservice-irc", - "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk-chatt", "Notify me for anything else": "Avisera för allt annat", "When I'm invited to a room": "När jag bjuds in till ett rum", - "Design and implementation of E2E in Matrix": "Design och implementation av E2E i Matrix", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Du kan använda anpassade serverinställningar för att logga in på andra Matrix-servrar genom att ange en annan hemserver-URL.
    Du kan då använda Riot med ett befintligt Matrix-konto på en annan hemserver.

    Du kan också ange en anpassad identitetsserver men kommer då inte kunna bjuda in användare med epostadress, eller själv bli inbjuden med epostadress.", "Can't update user notification settings": "Kan inte uppdatera aviseringsinställningarna", "Notify for all other messages/rooms": "Avisera för alla andra meddelanden/rum", "Unable to look up room ID from server": "Det gick inte att hämta rums-ID:t från servern", "Couldn't find a matching Matrix room": "Kunde inte hitta ett matchande Matrix-rum", - "Support for those using the Matrix spec": "Hjälp för de som använder Matrix specifikation", - "Safari and Opera work too.": "Safari och Opera fungerar också.", - "Loading bug report module": "Laddar buggrapportsmodul", "Invite to this room": "Bjud in i rummet", "Search for a room": "Sök efter rum", "Thursday": "torsdag", "Forward Message": "Vidarebefordra meddelande", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s via %(browserName)s på %(osName)s", "Back": "Tillbaka", "Reply": "Svara", "Show message in desktop notification": "Visa meddelande i skrivbordsavisering", "Unhide Preview": "Visa förhandsvisning", - "Announcements about Synapse releases": "Meddelanden om Synapse-versioner", - "Search the room directory": "Sök i rumskatalogen", - "Please describe the bug and/or send logs.": "Beskriv buggen och/eller sänd loggar.", "Unable to join network": "Det gick inte att ansluta till nätverket", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Du kan ha konfigurerat dem i en annan klient än Riot. Du kan inte ändra dem i Riot men de tillämpas ändå", "Sorry, your browser is not able to run Riot.": "Beklagar, din webbläsare kan inte köra Riot.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Decentraliserad, krypterad chatt & samarbete möjliggjort med [matrix]", - "Building services on Matrix": "Bygga tjänster med Matrix", "Messages in group chats": "Meddelanden i gruppchattar", "Yesterday": "igår", "Error encountered (%(errorDetail)s).": "Fel påträffat (%(errorDetail)s).", "Low Priority": "Låg prioritet", "Unable to fetch notification target list": "Det gick inte att hämta aviseringsmållistan", "Appear Offline": "Visa som utloggad", - "Get started with some tips from Riot Bot!": "Kom igång med några tips från Riot Bot!", "Set Password": "Välj lösenord", "Enable audible notifications in web client": "Sätt på högljudda aviseringar i webbklienten", "Permalink": "Permanent länk", - "Welcome to Riot.im": "Välkommen till Riot.im", "Off": "Av", "Riot does not know how to join a room on this network": "Riot kan inte gå med i ett rum på det här nätverket", "Mentions only": "Endast omnämnande", "Failed to remove tag %(tagName)s from room": "Det gick inte att radera taggen %(tagName)s från rummet", "You can now return to your account after signing out, and sign in on other devices.": "Du kan nu återgå till ditt konto efter att ha loggat ut och logga in på andra enheter.", - "Please install Chrome or Firefox for the best experience.": "Installera Chrome eller Firefox för den bästa upplevelsen.", "Enable email notifications": "Sätt på epostaviseringar", "Login": "Logga in", "Download this file": "Ladda ner filen", "Failed to change settings": "Det gick inte att spara inställningarna", "%(count)s Members|one": "%(count)s 1 Medlem", "View Source": "Visa källa", - "Matrix technical discussions": "Teknisk diskussion om Matrix", "Thank you!": "Tack!", "Quote": "Citera", "Collapse panel": "Kollapsa panel", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Med din nuvarande webbläsare kan appens utseende vara helt fel, och vissa eller alla egenskaper kommer nödvändigtvis inte att fungera. Om du ändå vill försöka så kan du fortsätta, men gör det på egen risk!", "Checking for an update...": "Letar efter uppdateringar...", - "General discussion about Matrix and Riot": "Allmän diskussion om Matrix och Riot", "There are advanced notifications which are not shown here": "Det finns avancerade aviseringar som inte visas här" } diff --git a/src/i18n/strings/te.json b/src/i18n/strings/te.json index 0c0ff8da9e..b6102a5eb5 100644 --- a/src/i18n/strings/te.json +++ b/src/i18n/strings/te.json @@ -44,7 +44,6 @@ "Banned users": "నిషేధించిన వినియోగదారులు", "Bans user with given id": "ఇచ్చిన ఐడి తో వినియోగదారుని నిషేధించారు", "Blacklisted": "నిరోధిత జాబితాలోని", - "Bug Report": "బగ్ నివేదిక", "Bulk Options": "సమూహ ఐచ్ఛికాలు", "Call Timeout": "కాల్ గడువు ముగిసింది", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "గృహనిర్వాహకులకు కనెక్ట్ చేయలేరు - దయచేసి మీ కనెక్టివిటీని తనిఖీ చేయండి, మీ 1 హోమరుసు యొక్క ఎస్ఎస్ఎల్ సర్టిఫికేట్ 2 ని విశ్వసనీయపరుచుకొని, బ్రౌజర్ పొడిగింపు అభ్యర్థనలను నిరోధించబడదని నిర్ధారించుకోండి.", @@ -170,7 +169,6 @@ "riot-web version:": "రయట్-వెబ్ సంస్కరణ:", "Riot was not given permission to send notifications - please try again": "రయట్ కు ప్రకటనలను పంపడానికి అనుమతి లేదు - దయచేసి మళ్ళీ ప్రయత్నించండి", "Unable to restore session": "సెషన్ను పునరుద్ధరించడానికి సాధ్యపడలేదు", - "Report it": "దానిని నివేదించండి", "Remove": "తొలగించు", "Room directory": "గది వివరము", "Create new room": "క్రొత్త గది సృష్టించండి", @@ -194,7 +192,6 @@ "Failed to set direct chat tag": "ప్రత్యక్ష మాటామంతి బొందు సెట్ చేయడంలో విఫలమైంది", "Today": "ఈ రోజు", "Failed to get protocol list from Home Server": "హోమ్ సర్వర్ నుండి ప్రోటోకాల్ జాబితాను పొందడం విఫలమైంది", - "Report a bug": "లోపమును నివేదించు", "Friday": "శుక్రువారం", "Add an email address above to configure email notifications": "ఇమెయిల్ ప్రకటనలను రూపశిల్పం చేయడానికి ఎగువ ఇమెయిల్ చిరునామాను జోడించండి", "Expand panel": "ప్యానెల్ను విస్తరింపజేయండి", @@ -202,7 +199,6 @@ "Filter room names": "గది పేర్లను ఫిల్టర్ చేయండి", "Changelog": "మార్పు వివరణ", "Leave": "వదిలి", - "Failed to send report: ": "నివేదికను పంపడంలో విఫలమైంది: ", "All notifications are currently disabled for all targets.": "ప్రస్తుతానికి అన్ని చోట్లనుంచి అన్ని ప్రకటనలు ఆగి వున్నాయి.", "delete the alias.": "అలియాస్ తొలగించండి.", "Forget": "మర్చిపో", @@ -216,7 +212,6 @@ "Failed to update keywords": "కీలక పదాలను నవీకరించడంలో విఫలమైంది", "remove %(name)s from the directory.": "వివరము నుండి %(name)s ను తొలిగించు.", "Please set a password!": "దయచేసి మీ రహస్యపదాన్నీ అమర్చండి!", - "Chat with Riot Bot": "రియోట్ బొట్తో మాటామంతి చేయండి", "Cancel Sending": "పంపడాన్ని ఆపేయండి", "Failed to add tag %(tagName)s to room": "%(tagName)s ను బొందు జోడించడంలో విఫలమైంది", "Members": "సభ్యులు", @@ -242,7 +237,6 @@ "All messages (noisy)": "అన్ని సందేశాలు (గట్టిగ)", "Enable them now": "ఇప్పుడే వాటిని ప్రారంభించండి", "Messages containing my user name": "నా వినియోగదారు పేరు కలిగి ఉన్న సందేశాలు", - "Describe your problem here.": "ఇక్కడ మీ సమస్యను వివరించండి.", "Collecting logs": "నమోదు సేకరించడం", "more": "మరింత", "Failed to get public room list": "ప్రజా గది జాబితాను పొందడం విఫలమైంది", @@ -253,19 +247,14 @@ "Send logs": "నమోదును పంపు", "All messages": "అన్ని సందేశాలు", "Call invitation": "మాట్లాడడానికి ఆహ్వానం", - "Riot Desktop on %(platformName)s": "రియట్ రంగస్థలం లో %(platformName)s", "Downloading update...": "నవీకరణను దిగుమతి చేస్తోంది...", "Keywords": "ముఖ్యపదాలు", "Can't update user notification settings": "వినియోగదారు ప్రకటన ప్రాదాన్యాలు నవీకరించదడానేకి రాదు", "Notify for all other messages/rooms": "అన్ని ఇతర సందేశాలు / గదులు కోసం తెలియజేయండి", "Couldn't find a matching Matrix room": "సరిపోలిక మ్యాట్రిక్స్ గదిని కనుగొనలేకపోయాము", - "Safari and Opera work too.": "సఫరిఇంకఒపెరకుద పని చెసతయి.", - "Loading bug report module": "దోష నివేదిక అధిభాగం లోడ్ చేస్తోంది", "Invite to this room": "ఈ గదికి ఆహ్వానించండి", "Thursday": "గురువారం", "Search…": "శోధన…", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s %(browserName)s ద్వర %(osName)s కి", - "Search the room directory": "గది వివరాన్ని శోధించండి", "Sorry, your browser is not able to run Riot.": "క్షమించండి, మీ బ్రౌజర్ రియట్ని అమలు చేయలేరు.", "Messages in group chats": "సమూహ మాటామంతిలో సందేశాలు", "Yesterday": "నిన్న", @@ -274,7 +263,6 @@ "Set Password": "రహస్యపదాన్నీ అమర్చండి", "An error occurred whilst saving your email notification preferences.": "మీ ఇమెయిల్ ప్రకటన ప్రాధాన్యాలు బద్రపరిచేతప్పుడు ఎదో తప్పు జరిగింది.", "Enable audible notifications in web client": "వెబ్ బంట్రౌతు వినిపించే నోటిఫికేషన్లను ప్రారంభించండి", - "Welcome to Riot.im": "రిమోట్.ఇం కి స్వగతం", "Off": "ఆపు", "Mentions only": "మాత్రమే ప్రస్తావిస్తుంది", "Failed to remove tag %(tagName)s from room": "గది నుండి బొందు %(tagName)s తొలగించడంలో విఫలమైంది", diff --git a/src/i18n/strings/th.json b/src/i18n/strings/th.json index 06f205840c..17ba4d461f 100644 --- a/src/i18n/strings/th.json +++ b/src/i18n/strings/th.json @@ -6,7 +6,6 @@ "Camera": "กล้อง", "Advanced": "ขึ้นสูง", "Ban": "แบน", - "Bug Report": "รายงานจุดบกพร่อง", "Change Password": "เปลี่ยนรหัสผ่าน", "Create Room": "สรัางห้อง", "Delete": "ลบ", @@ -23,7 +22,6 @@ "Emoji": "อีโมจิ", "Enable encryption": "เปิดใช้งานการเข้ารหัส", "Error": "ข้อผิดพลาด", - "Found a bug?": "พบจุดบกพร่อง?", "%(displayName)s is typing": "%(displayName)s กำลังพิมพ์", "Kick": "เตะ", "Low priority": "ความสำคัญต่ำ", @@ -49,7 +47,6 @@ "Settings": "การตั้งค่า", "unknown error code": "รหัสข้อผิดพลาดที่ไม่รู้จัก", "olm version:": "เวอร์ชัน olm:", - "Report it": "รายงานเลย", "Remove": "ลบ", "Custom Server Options": "กำหนดเซิร์ฟเวอร์เอง", "Favourite": "รายการโปรด", @@ -438,8 +435,6 @@ "Error decrypting video": "เกิดข้อผิดพลาดในการถอดรหัสวิดิโอ", "Fetching third party location failed": "การเรียกข้อมูลตำแหน่งจากบุคคลที่สามล้มเหลว", "A new version of Riot is available.": "มี Riot เวอร์ชั่นใหม่", - "Riot/Android & matrix-android-sdk chat": "แชทเกี่ยวกับ Riot บน Android และ matrix-android-sdk", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "กรุณาอธิบายจุดบกพร่อง คุณทำอะไร? ควรจะเกิดอะไรขึ้น? แล้วอะไรคือสิ่งที่เกิดขึ้นจริง?", "I understand the risks and wish to continue": "ฉันเข้าใจความเสี่ยงและต้องการดำเนินการต่อ", "Advanced notification settings": "ตั้งค่าการแจ้งเตือนขั้นสูง", "Uploading report": "กำลังอัปโหลดรายงาน", @@ -450,30 +445,23 @@ "Failed to set direct chat tag": "การติดแท็กแชทตรงล้มเหลว", "Today": "วันนี้", "Files": "ไฟล์", - "Report a bug": "รายงานจุดบกพร่อง", - "Implementing VR services with Matrix": "การอิมพลีเมนต์บริการ VR ด้วย Matrix", "You are not receiving desktop notifications": "การแจ้งเตือนบนเดสก์ทอปถูกปิดอยู่", "Friday": "วันศุกร์", "Update": "อัปเดต", - "You need to be using HTTPS to place a screen-sharing call.": "คุณต้องใช้ HTTPS เพื่อเริ่มติดต่อแบบแบ่งปันหน้าจอ", "What's New": "มีอะไรใหม่", "Add an email address above to configure email notifications": "เพิ่มที่อยู่อีเมลข้างบนเพื่อตั้งค่าการแจ้งเตือนทางอีเมล", "Expand panel": "ขยายหน้าต่าง", "On": "เปิด", "Filter room names": "กรองชื่อห้อง", "Changelog": "บันทึกการเปลี่ยนแปลง", - "Running Matrix services": "การติดตั้งบริการ Matrix", "Waiting for response from server": "กำลังรอการตอบสนองจากเซิร์ฟเวอร์", "Leave": "ออกจากห้อง", "Uploaded on %(date)s by %(user)s": "อัปโหลดเมื่อ %(date)s โดย %(user)s", - "Failed to send report: ": "การส่งรายงานล้มเหลว: ", - "Unknown device": "อุปกรณ์ที่ไม่รู้จัก", "All notifications are currently disabled for all targets.": "การแจ้งเตือนทั้งหมดถูกปิดใช้งานสำหรับทุกอุปกรณ์", "delete the alias.": "ลบนามแฝง", "To return to your account in future you need to set a password": "คุณต้องตั้งรหัสผ่านเพื่อจะกลับมาที่บัญชีนี้ในอนาคต", "Forget": "ลืม", "World readable": "ทุกคนอ่านได้", - "Riot/Web & Desktop chat": "แชทเกี่ยวกับ Riot บนเว็บและเดสก์ทอป", "Hide panel": "ซ่อนหน้าต่าง", "You cannot delete this image. (%(code)s)": "คุณไม่สามารถลบรูปนี้ได้ (%(code)s)", "Cancel Sending": "ยกเลิกการส่ง", @@ -484,9 +472,7 @@ "Room not found": "ไม่พบห้อง", "Messages containing my display name": "ข้อความที่มีชื่อของฉัน", "Messages in one-to-one chats": "ข้อความในแชทตัวต่อตัว", - "Contributing code to Matrix and Riot": "สมทบโค๊ดให้ Matrix และ Riot", "Unavailable": "ไม่มี", - "Community-run support for Synapse": "ฝ่ายสนับสนุน Synapse โดยชุมชนผู้ใช้", "Error saving email notification preferences": "การบันทึกการตั้งค่าการแจ้งเตือนทางอีเมลผิดพลาด", "View Decrypted Source": "ดูซอร์สที่ถอดรหัสแล้ว", "Send": "ส่ง", @@ -494,24 +480,16 @@ "Notifications on the following keywords follow rules which can’t be displayed here:": "การแจ้งเตือนจากคีย์เวิร์ดเหล่านี้ เป็นไปตามกฏที่ไม่สามารถแสดงที่นี่ได้:", "Please set a password!": "กรุณาตั้งรหัสผ่าน!", "You have successfully set a password!": "การตั้งรหัสผ่านเสร็จสมบูรณ์!", - "Chat with Riot Bot": "แชทกับบอท Riot", - "Support for those using, running and writing other bridges": "ฝ่ายสนับสนุนสำหรับผู้ใช้หรือพัฒนาตัวเชื่อมอื่น ๆ", - "Admin support for Dendrite": "ฝ่ายสนับสนุน Dendrite จากผู้ดูแล", "An error occurred whilst saving your email notification preferences.": "เกิดข้อผิดพลาดระหว่างบันทึกการตั้งค่าการแจ้งเตือนทางอีเมล", "Source URL": "URL ต้นฉบับ", "Messages sent by bot": "ข้อความจากบอท", "Members": "สมาชิก", "No update available.": "ไม่มีอัปเดตที่ใหม่กว่า", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "มีห้องอยู่มากมายใน Matrix ทั้งห้องที่เชื่อมไปยังเครือข่ายอื่น (Slack, IRC, Gitter ฯลฯ) และห้องที่อยู่ด้วยตัวเอง ลองดูไดเรกทอรีสิ!", "Noisy": "เสียงดัง", "Failed to get protocol list from Home Server": "การขอรายชื่อโปรโตคอลจากเซิร์ฟเวอร์บ้านล้มเหลว", "Collecting app version information": "กำลังรวบรวมข้อมูลเวอร์ชันแอป", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "ลบนามแฝง %(alias)s ของห้องและถอด %(name)s ออกจากไดเรกทอรี?", - "customServer_text": "คุณสามารถกำหนดเซิร์ฟเวอร์บ้านเองได้โดยใส่ URL ของเซิร์ฟเวอร์นั้น เพื่อเข้าสู่ระบบของเซิร์ฟเวอร์ Matrix อื่น
    ทั้งนี่เพื่อให้คุณสามารถใช้ Riot กับบัญชี Matrix ที่มีอยู่แล้วบนเซิร์ฟเวอร์บ้านอื่น ๆ ได้

    คุณอาจเลือกเซิร์ฟเวอร์ระบุตัวตนเองด้วยก็ได้ แต่คุณจะไม่สามารถเชิญผู้ใช้อื่นด้วยที่อยู่อีเมล หรือรับคำเชิญจากผู้ใช้อื่นทางที่อยู่อีเมลได้", - "Co-ordination for Riot/Web translators": "แชทสำหรับประสานงานการแปล Riot บนเว็บ", "This will allow you to return to your account after signing out, and sign in on other devices.": "เพื่อคุณจะได้กลับมายังบัญชีเดิมของคุณได้ หลังจากออกจากระบบ แล้วกลับเข้าสู่ระบบในอุปกรณ์อื่น ๆ", - "Dev chat for the Dendrite dev team": "แชทสำหรับทีมพัฒนา Dendrite", - "Design and implementation of E2E in Matrix": "การออกแบบและใช้งาน E2E ใน Matrix", "Enable notifications for this account": "เปิดใช้งานการแจ้งเตือนสำหรับบัญชีนี้", "Directory": "ไดเรกทอรี", "Search for a room": "ค้นหาห้อง", @@ -522,7 +500,6 @@ "Search…": "ค้นหา…", "Remove %(name)s from the directory?": "ถอด %(name)s ออกจากไดเรกทอรี?", "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot ใช้คุณสมบัติขั้นสูงในเบราว์เซอร์หลายประการ คุณสมบัติบางอย่างอาจยังไม่พร้อมใช้งานหรืออยู่ในขั้นทดลองในเบราว์เซอร์ปัจจุบันของคุณ", - "Please install Chrome or Firefox for the best experience.": "กรุณาติดตั้ง Chrome หรือ Firefox เพื่อประสบการณ์ที่ดีที่สุด", "Unnamed room": "ห้องที่ไม่มีชื่อ", "All messages (noisy)": "ทุกข้อความ (เสียงดัง)", "Saturday": "วันเสาร์", @@ -530,15 +507,11 @@ "Direct Chat": "แชทโดยตรง", "The server may be unavailable or overloaded": "เซิร์ฟเวอร์อาจไม่พร้อมใช้งานหรือทำงานหนักเกินไป", "Reject": "ปฏิเสธ", - "Riot is not supported on mobile web. Install the app?": "Riot ไม่รองรับเว็บบนอุปกรณ์พกพา ติดตั้งแอป?", - "Discussion of all things Matrix!": "พูดคุยทุกเรื่อง เรื่อง Matrix!", "Failed to set Direct Message status of room": "การตั้งสถานะข้อความตรงของห้องล้มเหลว", "Monday": "วันจันทร์", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "ล็อกจากไคลเอนต์จะถูกแนบพร้อมกับรายงานนี้เพื่อวินิจฉัยปัญหา หากคุณต้องการส่งเฉพาะข้อความด้านบน กรุณาเอาเครื่องหมายออก:", "Remove from Directory": "ถอดออกจากไดเรกทอรี", "Enable them now": "เปิดใช้งานเดี๋ยวนี้", "Messages containing my user name": "ข้อความที่มีชื่อผู้ใช้ของฉัน", - "Describe your problem here.": "อธิบายปัญหาที่นี่", "Collecting logs": "กำลังรวบรวมล็อก", "more": "เพิ่มเติม", "Failed to get public room list": "การขอรายชื่อห้องสาธารณะล้มเหลว", @@ -548,16 +521,10 @@ "Failed to update keywords": "การอัปเดตคีย์เวิร์ดล้มเหลว", "Send logs": "ส่งล็อก", "All messages": "ทุกข้อความ", - "Implementing VoIP services with Matrix": "การอิมพลีเมนต์บริการ VoIP ด้วย Matrix", - "Dev chat for the Riot/Web dev team": "แชทสำหรับทีมพัฒนา Riot บนเว็บ", "Call invitation": "คำเชิญเข้าร่วมการโทร", - "Riot Desktop on %(platformName)s": "Riot เดสก์ทอปบน %(platformName)s", "Downloading update...": "กำลังดาวน์โหลดอัปเดต...", "You have successfully set a password and an email address!": "ตั้งรหัสผ่านและที่อยู่อีเมลสำเร็จแล้ว!", "What's new?": "มีอะไรใหม่?", - "Discussion of the Identity Service API": "พูดคุยเกี่ยวกับ Identity Service API", - "Support for those using and running matrix-appservice-irc": "ฝ่ายสนับสนุนสำหรับผู้ใช้ matrix-appservice-irc", - "Riot/iOS & matrix-ios-sdk chat": "แชทเกี่ยวกับ Riot บน iOS และ matrix-ios-sdk", "Notify me for anything else": "แจ้งเตือนสำหรับอย่างอื่นทั้งหมด", "When I'm invited to a room": "เมื่อฉันได้รับคำเชิญเข้าห้อง", "Keywords": "คีย์เวิร์ด", @@ -565,33 +532,22 @@ "Notify for all other messages/rooms": "แจ้งเตือนจากห้อง/ข้อความอื่น ๆ ทั้งหมด", "Unable to look up room ID from server": "ไม่สามารถหา ID ห้องจากเซิร์ฟเวอร์ได้", "Couldn't find a matching Matrix room": "ไม่พบห้อง Matrix ที่ตรงกับคำค้นหา", - "Support for those using the Matrix spec": "ฝ่ายสนับสนุนสำหรับผู้ใช้สเปค Matrix", - "Safari and Opera work too.": "Safari หรือ Opera ก็ใช้ได้", - "Loading bug report module": "กำลังโหลดโมดูลรายงานจุดบกพร่อง", "Invite to this room": "เชิญเข้าห้องนี้", "You cannot delete this message. (%(code)s)": "คุณไม่สามารถลบข้อความนี้ได้ (%(code)s)", "Thursday": "วันพฤหัสบดี", "Forward Message": "ส่งต่อข้อความ", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s ผ่านทาง %(browserName)s บน %(osName)s", "Unhide Preview": "แสดงตัวอย่าง", - "Announcements about Synapse releases": "ประกาศเกี่ยวกับ Synapse รุ่นใหม่", - "Search the room directory": "ค้นหาในไดเรกทอรีห้อง", - "Please describe the bug and/or send logs.": "กรุณาอธิบายจุดบกพร่อง และ/หรือ ส่งล็อก", "Unable to join network": "ไม่สามารถเข้าร่วมเครือข่ายได้", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "คุณอาจมีการตั้งค่าจากไคลเอนต์อื่นนอกจาก Riot การตั้งต่าเหล่านั้นยังถูกใช้งานอยู่แต่คุณจะปรับแต่งจากใน Riot ไม่ได้", "Sorry, your browser is not able to run Riot.": "ขออภัย เบราว์เซอร์ของคุณไม่สามารถ run Riot ได้", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "ระบบแชทและประสานงาน ไร้ศูนย์กลางและเข้ารหัสได้ โดยใช้เทคโนโลยีจาก [matrix]", - "Building services on Matrix": "การพัฒนาบริการบน Matrix", "Messages in group chats": "ข้อความในแชทกลุ่ม", "Yesterday": "เมื่อวานนี้", "Error encountered (%(errorDetail)s).": "เกิดข้อผิดพลาด (%(errorDetail)s)", "Low Priority": "ความสำคัญต่ำ", "Riot does not know how to join a room on this network": "Riot ไม่รู้วิธีเข้าร่วมห้องในเครือข่ายนี้", - "Get started with some tips from Riot Bot!": "มาเริ่มกันด้วยเคล็ดลับเล็กน้อยจากบอท Riot!", "Set Password": "ตั้งรหัสผ่าน", "Enable audible notifications in web client": "เปิดใช้งานเสียงแจ้งเตือนบนเว็บไคลเอนต์", "Permalink": "ลิงก์ถาวร", - "Welcome to Riot.im": "ยินดีต้อนรับสู่ Riot.im", "Off": "ปิด", "#example": "#example", "Mentions only": "เมื่อถูกกล่าวถึงเท่านั้น", @@ -603,12 +559,10 @@ "No rooms to show": "ไม่มีห้องที่จะแสดง", "Download this file": "ดาวน์โหลดไฟล์นี้", "Failed to change settings": "การแก้ไขการตั้งค่าล้มเหลว", - "Matrix technical discussions": "พูดคุยเรื่อง Matrix เชิงเทคนิค", "Unable to fetch notification target list": "ไม่สามารถรับรายชื่ออุปกรณ์แจ้งเตือน", "Quote": "อ้างอิง", "Collapse panel": "ซ่อนหน้าต่าง", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "การแสดงผลของโปรแกรมอาจผิดพลาด ฟังก์ชันบางอย่างหรือทั้งหมดอาจไม่ทำงานในเบราว์เซอร์ปัจจุบันของคุณ หากคุณต้องการลองดำเนินการต่อ คุณต้องรับมือกับปัญหาที่อาจจะเกิดขึ้นด้วยตัวคุณเอง!", "Checking for an update...": "กำลังตรวจหาอัปเดต...", - "General discussion about Matrix and Riot": "พูดคุยเรื่องทั่วไป ทั้ง Matrix และ Riot", "There are advanced notifications which are not shown here": "มีการแจ้งเตือนขั้นสูงที่ไม่ได้แสดงที่นี่" } diff --git a/src/i18n/strings/tr.json b/src/i18n/strings/tr.json index 8ead0231d4..d890ed634e 100644 --- a/src/i18n/strings/tr.json +++ b/src/i18n/strings/tr.json @@ -48,7 +48,6 @@ "Banned users": "Yasaklanan(Banlanan) Kullanıcılar", "Bans user with given id": "Yasaklanan(Banlanan) Kullanıcılar , ID'leri ile birlikte", "Blacklisted": "Kara listeye alınanlar", - "Bug Report": "Hata Raporu", "Bulk Options": "Toplu Seçenekler", "Call Timeout": "Arama Zaman Aşımı", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Ana Sunucu'ya bağlanılamıyor - lütfen bağlantınızı kontrol edin , Ana Sunucu SSL sertifikanızın güvenilir olduğundan ve bir tarayıcı uzantısının istekleri engellemiyor olduğundan emin olun.", @@ -178,7 +177,6 @@ "Forgot your password?": "Şifrenizi mi unuttunuz ?", "For security, this session has been signed out. Please sign in again.": "Güvenlik için , bu oturuma çıkış yapıldı . Lütfen tekrar oturum açın.", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Güvenlik için , çıkış yaparsanız bu tarayıcıdan tüm uçtan uca şifreleme anahtarları silinecek . Konuşma geçmişinizi çözebilmek isterseniz gelecekteki Riot oturumlarında , lütfen Oda Anahtarlarını güvenlik amaçlı Dışa Aktarın.", - "Found a bug?": "Hata buldunuz mu ?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s %(fromPowerLevel)s den %(toPowerLevel)s ' ye", "Guest access is disabled on this Home Server.": "Misafir erişimi bu Ana Sunucu için devre dışı.", "Guests cannot join this room even if explicitly invited.": "Misafirler açıkca davet edilseler bile bu odaya katılamazlar.", @@ -301,7 +299,6 @@ "Remove": "Kaldır", "Remove %(threePid)s?": "%(threePid)s 'i kaldır ?", "%(senderName)s requested a VoIP conference.": "%(senderName)s bir VoIP konferansı talep etti.", - "Report it": "Bunu rapor et", "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.": "Şifrenizi sıfırlamak , eğer Oda Anahtarlarınızı dışa aktarmaz ve daha sonra içe aktarmaz iseniz , şu anda tüm cihazlarda uçtan uca şifreleme anahtarlarını sıfırlayarak şifreli sohbetleri okunamaz hale getirecek . Gelecekte bu iyileştirilecek.", "Results from DuckDuckGo": "DuckDuckGo Sonuçları", "Return to login screen": "Giriş ekranına dön", @@ -644,8 +641,6 @@ "Encryption key request": "Şifreleme anahtarı isteği", "Fetching third party location failed": "Üçüncü parti konumunu çekemedi", "A new version of Riot is available.": "Riot'un yeni bir versiyonu mevcuttur.", - "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk sohbet", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Lütfen hatayı tanımlayın. Ne yaptınız ? Ne gerçekleşmesini beklediniz ? Ne gerçekleşti ?", "All notifications are currently disabled for all targets.": "Tüm bildirimler şu anda tüm hedefler için devre dışı bırakılmıştır.", "Uploading report": "Rapor yükleniyor", "Sunday": "Pazar", @@ -655,29 +650,22 @@ "Failed to set direct chat tag": "Direkt sohbet etiketi ayarlanamadı", "Today": "Bugün", "Failed to get protocol list from Home Server": "Ana Sunucu'dan protokol listesi alınamadı", - "Report a bug": "Hata Bildir", - "Implementing VR services with Matrix": "Matrix'te VR hizmetlerini implement etmek", "You are not receiving desktop notifications": "Masaüstü bildirimleri almıyorsunuz", "Friday": "Cuma", "Update": "Güncelleştirme", - "You need to be using HTTPS to place a screen-sharing call.": "Ekran paylaşımlı arama yapmak için HTTPS kullanıyor olmalısınız.", "What's New": "Yenilikler", "Add an email address above to configure email notifications": "E-posta bildirimlerini yapılandırmak için yukarıya bir e-posta adresi ekleyin", "Expand panel": "Genişletme paneli", "On": "Açık", "Filter room names": "Oda isimlerini filtrele", "Changelog": "Değişiklikler", - "Running Matrix services": "Çalışan Matrix hizmetleri", "Waiting for response from server": "Sunucudan yanıt bekleniyor", "Leave": "Ayrıl", - "Failed to send report: ": "Rapor gönderilemedi: ", - "Unknown device": "Bilinmeyen aygıt", "Advanced notification settings": "Gelişmiş bildirim ayarları", "delete the alias.": "Tüm rumuzları sil.", "Forget": "Unut", "World readable": "Okunabilir dünya", "#example": "örnek", - "Riot/Web & Desktop chat": "Riot/Web & Masaüstü sohbet", "Hide panel": "Paneli gizle", "You cannot delete this image. (%(code)s)": "Bu resmi silemezsiniz. (%(code)s)", "Cancel Sending": "Göndermeyi İptal Et", @@ -686,30 +674,21 @@ "Noisy": "Gürültülü", "Room not found": "Oda bulunamadı", "Messages in one-to-one chats": "Bire bir sohbetlerdeki mesajlar", - "Contributing code to Matrix and Riot": "Matrix ve Riot'a kod katkısı (contribution) sağla", "Unavailable": "Kullanım dışı", - "Community-run support for Synapse": "Synapse için topluluk tarafından işlenen destek", "View Decrypted Source": "Şifresi Çözülmüş(Decrypted) Kaynağı Görüntüle", "Failed to update keywords": "Anahtar kelimeler güncellenemedi", "remove %(name)s from the directory.": "%(name)s'i dizinden kaldır.", "Notifications on the following keywords follow rules which can’t be displayed here:": "Aşağıdaki anahtar kelimeleri ile ilgili bildirimler burada gösterilemeyen kuralları takip eder:", "Please set a password!": "Lütfen bir şifre ayarlayın !", "You have successfully set a password!": "Başarıyla bir şifre ayarladınız!", - "Chat with Riot Bot": "Riot Bot ile Sohbet Et", - "Support for those using, running and writing other bridges": "Diğer köprüleri kullanan , çalıştıran ve yazanlar için destek", - "Admin support for Dendrite": "Dendrite için Admin desteği", "Source URL": "Kaynak URL", "Failed to add tag %(tagName)s to room": "%(tagName)s etiketi odaya eklenemedi", "Members": "Üyeler", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Matrix'te varolan ağlara (Slack , IRC , Gitter vb.) bağlı ya da bağımsız bir çok oda var . Dizini kontrol edin!", "Resend": "Yeniden Gönder", "Files": "Dosyalar", "Collecting app version information": "Uygulama sürümü bilgileri toplanıyor", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "%(alias)s oda rumuzu silinsin ve %(name)s dizinden kaldırılsın mı ?", - "customServer_text": "Farklı bir Ana Sunucu URL'si belirleyerek başka bir Matrix sunucusunda oturum açmak için Özel Sunucu Seçeneklerini kullanabilirsiniz.
    Bu , Riot'u mevcut Matrix hesabı ile farklı bir Ana Sunucuda kullanmanıza olanak tanır.

    Ayrıca Özel Kimlik Sunucu'da ayarlayabilirsiniz ama kullanıcıları e-posta adresleriyle veya kendi e-posta adresinizle davet edemezsiniz.", - "Co-ordination for Riot/Web translators": "Riot/Web çevirmenleri için koordinasyon", "This will allow you to return to your account after signing out, and sign in on other devices.": "Bu oturumunuzu kapattıktan sonra hesabınıza dönmenizi ve diğer cihazlarda oturum açmanızı sağlar.", - "Dev chat for the Dendrite dev team": "Dendrite Geliştirici Takımı için Geliştirici sohbeti", "Keywords": "Anahtar kelimeler", "Enable notifications for this account": "Bu hesap için bildirimleri etkinleştir", "Directory": "Dizin", @@ -729,15 +708,11 @@ "Direct Chat": "Doğrudan Sohbet", "The server may be unavailable or overloaded": "Sunucu kullanılamıyor veya aşırı yüklenmiş olabilir", "Reject": "Reddet", - "Riot is not supported on mobile web. Install the app?": "Riot mobil web'de desteklenmiyor . Uygulamayı yükle ?", - "Discussion of all things Matrix!": "Matrix'in tüm tartışması!", "Failed to set Direct Message status of room": "Odanın Direkt Mesaj durumu ayarlanamadı", "Monday": "Pazartesi", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "Sorunları teşhis etmek için , bu istemciden kayıtlar hata raporu ile beraber gönderilecek . Yalnızca yukarıdaki metni göndermek isterseniz , lütfen işareti kaldırın:", "Remove from Directory": "Dizinden Kaldır", "Enable them now": "Onları şimdi etkinleştir", "Forward Message": "Mesajı İlet", - "Describe your problem here.": "Probleminizi burada açıklayın.", "Messages containing my user name": "Kullanıcı ismimi içeren mesajlar", "Collecting logs": "Kayıtlar toplanıyor", "more": "Daha", @@ -749,65 +724,44 @@ "Send": "Gönder", "Send logs": "Kayıtları gönder", "All messages": "Tüm mesajlar", - "Implementing VoIP services with Matrix": "Matrix'te VoIP hizmetlerini implement etmek", - "Dev chat for the Riot/Web dev team": "Riot/Web Geliştirici takımı için Geliştirici sohbeti", "Call invitation": "Arama davetiyesi", - "Riot Desktop on %(platformName)s": "%(platformName)s platformunda Riot Masaüstü", "Messages containing my display name": "İsmimi içeren mesajlar", "You have successfully set a password and an email address!": "Başarıyla bir şifre ve e-posta adresi ayarladın !", "What's new?": "Yeni olan ne ?", - "Discussion of the Identity Service API": "Kimlik Hizmet API ( Identity Service API ) Tartışması", - "Support for those using and running matrix-appservice-irc": "matrix-appservice-irc kullanan ve çalıştıran kullanıcılar için destek", - "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk sohbet", "Notify me for anything else": "Başka herhangi bir şey için bana bildirim yap", "When I'm invited to a room": "Bir odaya davet edildiğimde", - "Design and implementation of E2E in Matrix": "Matrix'te E2E ' nin Tasarım ve İmplementasyonu", "Can't update user notification settings": "Kullanıcı bildirim ayarları güncellenemiyor", "Notify for all other messages/rooms": "Diğer tüm mesajlar / odalar için bildirim yapın", "Unable to look up room ID from server": "Sunucudan oda ID'si aranamadı", "Couldn't find a matching Matrix room": "Eşleşen bir Matrix odası bulunamadı", - "Support for those using the Matrix spec": "Matrix teknik özelliklerini kullananlar için destek", - "Safari and Opera work too.": " Safari ve Opera da çalışıyor.", - "Loading bug report module": "Hata raporlama modülü yükleniyor", "Invite to this room": "Bu odaya davet et", "You cannot delete this message. (%(code)s)": "Bu mesajı silemezsiniz (%(code)s)", "Thursday": "Perşembe", "Search…": "Arama…", - "%(appName)s via %(browserName)s on %(osName)s": "%(osName)s işletim sisteminde %(browserName)s ile %(appName)s", "Unhide Preview": "Önizlemeyi Göster", - "Announcements about Synapse releases": "Synapse sürümleri hakkında duyurular", - "Search the room directory": "Oda dizinini ara", - "Please describe the bug and/or send logs.": "Lütfen hatayı tanımlayın ve/veya kayıtları gönderin.", "Unable to join network": "Ağa bağlanılamıyor", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Onları Riot dışında bir istemciden yapılandırmış olabilirsiniz . Onları Riot içersinide ayarlayamazsınız ama hala geçerlidirler", "Sorry, your browser is not able to run Riot.": "Üzgünüz , tarayıcınız Riot'u çalıştıramıyor .", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Dağıtık , şifreli sohbet & işbirliği ile Matrix tarafından desteklenmektedir", "Uploaded on %(date)s by %(user)s": "%(user)s tarafında %(date)s e yüklendi", "Messages in group chats": "Grup sohbetlerindeki mesajlar", "Yesterday": "Dün", "Low Priority": "Düşük Öncelikli", "Unable to fetch notification target list": "Bildirim hedef listesi çekilemedi", - "Get started with some tips from Riot Bot!": "Bazı Riot Bot ipuçları ile başlayın !", "An error occurred whilst saving your email notification preferences.": "E-posta bildirim tercihlerinizi kaydetme işlemi sırasında bir hata oluştu.", "Enable audible notifications in web client": "Web istemcisinde sesli bildirimleri etkinleştir", "Permalink": "Kalıcı Bağlantı(permalink)", - "Welcome to Riot.im": "Riot.im'e Hoş Geldiniz", "Off": "Kapalı", "Riot does not know how to join a room on this network": "Riot bu ağdaki bir odaya nasıl gireceğini bilmiyor", "Mentions only": "Sadece Mention'lar", "Failed to remove tag %(tagName)s from room": "Odadan %(tagName)s etiketi kaldırılamadı", "You can now return to your account after signing out, and sign in on other devices.": "Şimdi oturumunuzu iptal ettikten sonra başka cihazda oturum açarak hesabınıza dönebilirsiniz.", - "Please install Chrome or Firefox for the best experience.": "Lütfen Chrome ya da Firefox 'u en iyi deneyim için yükleyin.", "Enable email notifications": "E-posta bildirimlerini etkinleştir", "Login": "Oturum aç", "No rooms to show": "Gösterilecek oda yok", "Download this file": "Bu dosyayı indir", "Failed to change settings": "Ayarlar değiştirilemedi", "View Source": "Kaynağı Görüntüle", - "Matrix technical discussions": "Matrix teknik tartışmalar", - "Building services on Matrix": "Matrix üzerinde Yapı hizmetleri", "Collapse panel": "Katlanır panel", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Geçerli tarayıcınız ile birlikte , uygulamanın görünüş ve kullanım hissi tamamen hatalı olabilir ve bazı ya da tüm özellikler çalışmayabilir. Yine de denemek isterseniz devam edebilirsiniz ancak karşılaşabileceğiniz sorunlar karşısında kendi başınasınız !", - "General discussion about Matrix and Riot": "Matrix ve Riot hakkında genel tartışma", "There are advanced notifications which are not shown here": "Burada gösterilmeyen gelişmiş bildirimler var" } diff --git a/src/i18n/strings/uk.json b/src/i18n/strings/uk.json index 71b6cca767..25a70e0522 100644 --- a/src/i18n/strings/uk.json +++ b/src/i18n/strings/uk.json @@ -73,7 +73,6 @@ "Banned users": "Заблоковані користувачі", "Bans user with given id": "Блокує користувача з заданим ID", "Blacklisted": "В чорному списку", - "Bug Report": "Звіт про помилку", "Bulk Options": "Групові параметри", "Call Timeout": "Час очікування виклика", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Не вдається підключитись до домашнього серверу - перевірте підключення, переконайтесь, що ваш SSL-сертифікат домашнього сервера є довіреним і що розширення браузера не блокує запити.", @@ -100,8 +99,6 @@ "Fetching third party location failed": "Не вдалось отримати стороннє місцеперебування", "Messages in one-to-one chats": "Повідомлення у чатах \"сам на сам\"", "A new version of Riot is available.": "Доступне оновлення для Riot.", - "Riot/Android & matrix-android-sdk chat": "Обговорення Riot/Android та matrix-android-sdk", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Опишіть, будь ласка, ваду. Що ви зробили? На що ви очікували? Що трапилось натомість?", "Couldn't load home page": "Не вдалось завантажити домівку", "Send Account Data": "Відправити данні аккаунта", "Advanced notification settings": "Додаткові налаштування сповіщень", @@ -110,28 +107,21 @@ "Guests can join": "Гості можуть приєднуватися", "Failed to add tag %(tagName)s to room": "Не вдалось додати до кімнати мітку %(tagName)s", "Notification targets": "Цілі сповіщень", - "General discussion about Matrix and Riot": "Загальне обговорення Matrix та Riot", "Failed to set direct chat tag": "Не вдалося встановити мітку прямого чату", "Today": "Сьогодні", "Failed to get protocol list from Home Server": "Не вдалось отримати перелік протоколів з Домашнього серверу", - "Report a bug": "Звітувати про вади", - "Implementing VR services with Matrix": "Впровадження служб віртуальної реальності в рамках Matrix", "You are not receiving desktop notifications": "Ви не отримуєте сповіщення на стільниці", "Friday": "П'ятниця", "Update": "Оновити", - "You need to be using HTTPS to place a screen-sharing call.": "Ви маєте використовувати HTTPS щоб зробити виклик із поширенням екрану.", "What's New": "Що нового", "Add an email address above to configure email notifications": "Додайте вище адресу е-пошти щоб налаштувати сповіщення е-поштою", "Expand panel": "Розгорнути панель", "On": "Увімкнено", "Filter room names": "Відфільтрувати назви кімнат", "Changelog": "Журнал змін", - "Running Matrix services": "Запуск служби Matrix", "Waiting for response from server": "Очікується відповідь від сервера", "Leave": "Вийти", "Send Custom Event": "Відправити приватний захід", - "Failed to send report: ": "Не вдалося надіслати звіт: ", - "Unknown device": "Невідомий пристрій", "All notifications are currently disabled for all targets.": "Сповіщення для усіх цілей на даний момент вимкнені.", "Failed to send logs: ": "Не вдалося відправити журнали: ", "delete the alias.": "видалити псевдонім.", @@ -139,7 +129,6 @@ "Forget": "Забути", "World readable": "Відкрито для світу", "#example": "#зразок", - "Riot/Web & Desktop chat": "Обговорення Riot для оглядачів та стільниці", "Hide panel": "Сховати панель", "You cannot delete this image. (%(code)s)": "Ви не можете видалити це зображення. (%(code)s)", "Cancel Sending": "Скасувати надсилання", @@ -150,9 +139,7 @@ "Error saving email notification preferences": "Помилка при збереженні параметрів сповіщень е-поштою", "Messages containing my display name": "Повідомлення, вміщає моє ім'я", "Remember, you can always set an email address in user settings if you change your mind.": "Пам'ятайте, що ви завжди можете встановити адресу е-пошти у налаштуваннях, якщо передумаєте.", - "Contributing code to Matrix and Riot": "Тим, хто хоче долучитись до розробки Matrix та Riot", "Unavailable": "Нема в наявності", - "Community-run support for Synapse": "Спільнота підтримки Synapse", "View Decrypted Source": "Переглянути розшифроване джерело", "Failed to update keywords": "Не вдалось оновити ключові слова", "remove %(name)s from the directory.": "прибрати %(name)s з каталогу.", @@ -160,9 +147,6 @@ "Safari and Opera work too.": "Safari та Opera працюють теж.", "Please set a password!": "Встановіть пароль, будь ласка!", "You have successfully set a password!": "Пароль успішно встановлено!", - "Chat with Riot Bot": "Розмовляти з Riot-ботом", - "Support for those using, running and writing other bridges": "Підтримка користувачів, адміністраторів та розробників інших Matrix-мостів", - "Admin support for Dendrite": "Адміністрування Dendrite", "An error occurred whilst saving your email notification preferences.": "Під час збереження налаштувань сповіщень е-поштою трапилася помилка.", "Explore Room State": "Перегляд статуса кімнати", "Source URL": "Джерельне посилання", @@ -170,15 +154,11 @@ "Filter results": "Фільтр результатів", "Members": "Члени", "No update available.": "Оновлення відсутні.", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "У мережі Matrix вже існує багато кімнат, що з'єднані як з існуючими мережами (Slack, IRC, Gitter тощо), так і незалежними. Подивіться у каталозі кімнат!", "Resend": "Перенадіслати", "Files": "Файли", "Collecting app version information": "Збір інформації про версію застосунка", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Видалити псевдонім %(alias)s та прибрати з каталогу %(name)s?", - "customServer_text": "Ви можете скористатись нетиповими параметрами сервера щоб увійти в інші сервери Matrix, зазначивши посилання на окремий Домашній сервер
    Це дозволяє вам використовувати Riot із вже існуючою обліковкою Matrix на іншому Домашньому сервері.

    Ви також можете зазначити нетиповий сервер ідентифікації, але ви не матимете змоги ані запрошувати користувачів за е-поштою, ані бути запрошеними за е-поштою самі.", - "Co-ordination for Riot/Web translators": "Координація для перекладачів Riot/Web", "This will allow you to return to your account after signing out, and sign in on other devices.": "Це дозволить вам повернутися до своєї обліковки після виходу з неї, та заходити з інших пристроїв.", - "Dev chat for the Dendrite dev team": "Чат команди розробників Dendrite", "Keywords": "Ключові слова", "Enable notifications for this account": "Увімкнути сповіщення для цієї обліковки", "Directory": "Каталог", @@ -194,7 +174,6 @@ "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot використовує багато новітніх функцій, деякі з яких не доступні або є експериментальними у вашому оглядачі.", "Developer Tools": "Інструменти розробника", "Preparing to send logs": "Підготовка до відправки журланлу", - "Please install Chrome or Firefox for the best experience.": "Для більшої зручності у використанні встановіть, будь ласка, Chrome або Firefox.", "Unnamed room": "Неназвана кімната", "Explore Account Data": "Продивитись данні аккаунта", "All messages (noisy)": "Усі повідомлення (гучно)", @@ -205,16 +184,11 @@ "The server may be unavailable or overloaded": "Сервер може бути недосяжним або перевантаженим", "Room not found": "Кімнату не знайдено", "Reject": "Відмовитись", - "Riot is not supported on mobile web. Install the app?": "Riot не працює через оглядач на мобільних пристроях. Встановити застосунок?", - "Discussion of all things Matrix!": "Обговорення усіх деталей про Matrix!", "Failed to set Direct Message status of room": "Не вдалось встановити статус прямого спілкування в кімнаті", "Monday": "Понеділок", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "З метою діагностики проблем журнали з цього застосунку будуть надіслані разом зі звітом про вади. Якщо ви бажаєте надіслати лише вищенаведений текст, відозначте, будь ласка:", - "Send Custom State Event": "Відправити статус приватного заходу", "Remove from Directory": "Прибрати з каталогу", "Enable them now": "Увімкнути їх зараз", "Messages containing my user name": "Повідомлення, що містять моє ім'я користувача", - "Describe your problem here.": "Опишіть вашу проблему тут.", "Toolbox": "Панель інструментів", "Collecting logs": "Збір журналів", "more": "докладніше", @@ -229,45 +203,29 @@ "Send": "Надіслати", "Send logs": "Надіслати журнали", "All messages": "Усі повідомлення", - "Implementing VoIP services with Matrix": "Впровадження служб VoIP через Matrix", - "Dev chat for the Riot/Web dev team": "Чат команди розробників Riot/Web", "Call invitation": "Запрошення до виклику", - "Riot Desktop on %(platformName)s": "Riot Desktop на %(platformName)s", "Downloading update...": "Звантаженя оновлення…", "State Key": "Ключ стану", "Failed to send custom event.": "Не вдалося відправити приватний захід.", "What's new?": "Що нового?", - "Discussion of the Identity Service API": "Обговорення Identity Service API", - "Support for those using and running matrix-appservice-irc": "Підтримка користувачів matrix-appservice-irc", - "Riot/iOS & matrix-ios-sdk chat": "Обговорення Riot/iOS та matrix-ios-sdk", "Notify me for anything else": "Сповіщати мене про будь-що інше", "View Source": "Переглянути джерело", - "Design and implementation of E2E in Matrix": "Планування та впровадження E2E шифрування у Matrix", "Click here to create a GitHub issue.": "Нажміть тут для створення запитання по проблемі на GitHub.", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Ви можете використовувати параметри користувача сервера для входа на другі сервера Matrix, вказав другий URL-адресу домашнього сервера.
    Це дозволяє використовувати Riot з обліковим записом Matrix який існує на другому домашньому сервері.

    Окрім цього, можливо встановити ідентифікаційний сервер користувача, але ви не зможете запросити других користувачів та бути запрошенному використовуючи адресу електронної пошти.", "Can't update user notification settings": "Неможливо оновити налаштування користувацьких сповіщень", "Notify for all other messages/rooms": "Сповіщати щодо всіх повідомлень/кімнат", "Unable to look up room ID from server": "Неможливо знайти ID кімнати на сервері", "Couldn't find a matching Matrix room": "Неможливо знайти відповідну кімнату", - "Support for those using the Matrix spec": "Підтримка користувачів специфікацій Matrix", - "Safari and Opera work too.": "Safari та Opera також підтримуються.", - "Loading bug report module": "Завантаження модуля звітів про вади", "Invite to this room": "Запросити до цієї кімнати", "Search for a room": "Пошук кімнати", "Thursday": "Четвер", "Search…": "Пошук…", "Logs sent": "Журнали відправленні", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s через %(browserName)s на %(osName)s", "Back": "Назад", "Reply": "Відповісти", "Show message in desktop notification": "Показати повідомлення в сповіщення на робочому столі", - "Announcements about Synapse releases": "Оголошення випусків Synapse", - "Search the room directory": "Шукати у каталозі кімнат", - "Please describe the bug and/or send logs.": "Опишіть, будь ласка, ваду та/або надішліть журнали.", "Unable to join network": "Неможливо приєднатись до мережі", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Можливо, ви налаштували їх не у Riot, а у іншому застосунку. Ви не можете регулювати їх у Riot, але вони все ще мають силу", "Sorry, your browser is not able to run Riot.": "Вибачте, ваш оглядач не спроможний запустити Riot.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "Децентралізований, шифрований чат та засіб для співробітництва, що працює на [matrix]", "Uploaded on %(date)s by %(user)s": "Завантажено %(date)s користувачем %(user)s", "Messages in group chats": "Повідомлення у групових чатах", "Yesterday": "Вчора", @@ -276,11 +234,9 @@ "Low Priority": "Неважливі", "Unable to fetch notification target list": "Неможливо отримати перелік цілей сповіщення", "Appear Offline": "Відображати як не в мережі", - "Get started with some tips from Riot Bot!": "Розпочніть за допомогою декількох підказок від Riot-боту!", "Set Password": "Задати пароль", "Enable audible notifications in web client": "Увімкнути звукові сповіщення у мережевому застосунку", "Permalink": "Постійне посилання", - "Welcome to Riot.im": "Ласкаво просимо до Riot.im", "Off": "Вимкнено", "Riot does not know how to join a room on this network": "Riot не знає як приєднатись до кімнати у цій мережі", "Mentions only": "Тільки згадки", @@ -297,10 +253,8 @@ "Unhide Preview": "Відкрити попередній перегляд", "Event Content": "Зміст заходу", "Thank you!": "Дякую!", - "Building services on Matrix": "Створення служб на основі Matrix", "Collapse panel": "Згорнути панель", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "У вашому оглядачі вигляд застосунку може бути повністю іншим, а деякі або навіть усі функції можуть не працювати. Якщо ви наполягаєте, то можете продовжити користування, але ви маєте впоратись з усіма можливими проблемами власноруч!", "Checking for an update...": "Перевірка оновлень…", - "Matrix technical discussions": "Технічні обговорення Matrix", "There are advanced notifications which are not shown here": "Є додаткові сповіщення, що не показуються тут" } diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index ad5387ad40..89709bf97f 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -65,7 +65,6 @@ "Forgot your password?": "忘记密码?", "For security, this session has been signed out. Please sign in again.": "出于安全考虑,此会话已被注销。请重新登录。.", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "出于安全考虑,用户注销时会清除浏览器里的端到端加密密钥。如果你想要下次登录 Riot 时能解密过去的聊天记录,请导出你的聊天室密钥。", - "Found a bug?": "发现漏洞?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s 从 %(fromPowerLevel)s 变为 %(toPowerLevel)s", "Guests cannot join this room even if explicitly invited.": "游客不能加入此聊天室,即使有人主动邀请。.", "Hangup": "挂断", @@ -82,7 +81,6 @@ "Invalid address format": "地址格式错误", "Invalid Email Address": "邮箱地址格式错误", "Invalid file%(extra)s": "非法文件%(extra)s", - "Report it": "报告", "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.": "重设密码会导致所有设备上的端到端加密密钥被重置,使得加密的聊天记录不可读,除非你事先导出密钥,修改密码后再导入。此问题将来会得到改善。.", "Return to login screen": "返回登录页面", "Riot does not have permission to send you notifications - please check your browser settings": "Riot 未被允许向你推送消息 - 请检查浏览器设置", @@ -184,7 +182,6 @@ "Are you sure you want to upload the following files?": "你确定要上传这些文件吗?", "Bans user with given id": "封禁指定 ID 的用户", "Blacklisted": "已列入黑名单", - "Bug Report": "反馈漏洞", "Bulk Options": "批量操作", "Call Timeout": "通话超时", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "无法连接主服务器 - 请检查网络连接,确保你的主服务器 SSL 证书被信任,且没有浏览器插件拦截请求。", @@ -294,7 +291,6 @@ "Could not connect to the integration server": "无法连接集成服务器", "Curve25519 identity key": "Curve25519 认证密钥", "Edit": "编辑", - "Hide Apps": "隐藏应用", "Joins room with given alias": "以指定的别名加入聊天室", "Labs": "实验室", "%(targetName)s left the room.": "%(targetName)s 离开了聊天室。", @@ -467,7 +463,6 @@ "%(senderName)s removed their profile picture.": "%(senderName)s 移除了他们的头像。", "%(senderName)s requested a VoIP conference.": "%(senderName)s 请求一个 VoIP 会议。", "Seen by %(userName)s at %(dateTime)s": "在 %(dateTime)s 被 %(userName)s 看到", - "Show Apps": "显示应用", "Tagged as: ": "标记为:", "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "验证码将发送到+%(msisdn)s,请输入接收到的验证码", "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s 接受了 %(displayName)s 的邀请。", @@ -727,7 +722,6 @@ "You have entered an invalid address.": "你输入了一个无效地址。", "Advanced options": "高级选项", "Leave": "离开", - "Unable to leave room": "无法离开聊天室", "Description": "描述", "Warning": "警告", "Light theme": "浅色主题", @@ -806,8 +800,6 @@ "Submit debug logs": "提交调试日志", "Fetching third party location failed": "获取第三方位置失败", "A new version of Riot is available.": "Riot 有更新可用。", - "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk 聊天", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "请描述这个 bug,您做了什么动作?预期会发生的状况?以及实际发生的?", "Couldn't load home page": "不能加载首页", "Send Account Data": "发送账户数据", "All notifications are currently disabled for all targets.": "当前所有目标的通知均已禁用。", @@ -816,12 +808,9 @@ "Notification targets": "通知目标", "Today": "今天", "Failed to get protocol list from Home Server": "无法从主服务器取得协议列表", - "Report a bug": "报告一个 bug", - "Implementing VR services with Matrix": "使用 Matrix 实现虚拟现实服务", "You are not receiving desktop notifications": "您将不会收到桌面通知", "Friday": "星期五", "Update": "更新", - "You need to be using HTTPS to place a screen-sharing call.": "你需要使用 HTTPS 来放置屏幕分享通话。", "What's New": "新鲜事", "Add an email address above to configure email notifications": "请在上方输入电子邮件地址以接收邮件通知", "Expand panel": "展开面板", @@ -829,18 +818,14 @@ "%(count)s Members|other": "%(count)s 位成员", "Filter room names": "过滤聊天室名称", "Changelog": "变更日志", - "Running Matrix services": "正在运行 Matrix 服务", "Waiting for response from server": "正在等待服务器响应", "Send Custom Event": "发送自定义事件", - "Failed to send report: ": "无法发送报告: ", - "Unknown device": "未知设备", "Advanced notification settings": "通知高级设置", "Failed to send logs: ": "无法发送日志: ", "delete the alias.": "删除别名。", "To return to your account in future you need to set a password": "要在未来回到您的账号,您需要 设置密码", "Forget": "忘记", "#example": "#例子", - "Riot/Web & Desktop chat": "Riot/Web & 桌面聊天", "Hide panel": "隐藏面板", "You cannot delete this image. (%(code)s)": "您不能删除这个图片。(%(code)s)", "Cancel Sending": "取消发送", @@ -850,9 +835,7 @@ "Error saving email notification preferences": "保存电子邮件通知的首选项时出错", "Messages containing my display name": "消息中含有我的显示名称", "Messages in one-to-one chats": "一对一聊天种的消息", - "Contributing code to Matrix and Riot": "贡献程序代码给 Matrix 与 Riot", "Unavailable": "无法获得", - "Community-run support for Synapse": "运行 Synapse 的社区支持", "View Decrypted Source": "查看解密的来源", "Failed to update keywords": "无法更新关键字", "Notes:": "记录:", @@ -861,9 +844,6 @@ "Safari and Opera work too.": "SafariOpera 也能工作。", "Please set a password!": "请设置密码!", "You have successfully set a password!": "您已成功设置密码!", - "Chat with Riot Bot": "与 Riot 机器人聊天", - "Support for those using, running and writing other bridges": "那些使用、运行并撰写其他桥接应用的支持", - "Admin support for Dendrite": "Dendrite 的管理员支持", "An error occurred whilst saving your email notification preferences.": "保存邮件通知首选项设定时出现错误。", "Explore Room State": "探索聊天室状态", "Source URL": "源网址", @@ -871,15 +851,11 @@ "Filter results": "过滤结果", "Members": "成员", "No update available.": "没有可用更新。", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Matrix 中已有许多聊天室,连接到已有的网络(Slack、IRC 与 Gitter 等)或独立的网络,请查看目录!", "Resend": "重新发送", "Files": "文件", "Collecting app version information": "正在收集应用版本信息", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "确定要删除聊天室别名 %(alias)s 并将 %(name)s 从列表中删除吗?", - "customServer_text": "你可以通过指定自定义服务器选项中的其他主服务器的 URL 来登录其他 Matrix 服务器。
    该选项允许你在 Riot 上使用其他主服务器上的帐号。

    你也可以自定义身份验证服务器,但你将不能通过邮件邀请其他用户,同样的,你也不能通过邮件被其他用户邀请。", - "Co-ordination for Riot/Web translators": "Riot/Web 翻译者的协调区", "This will allow you to return to your account after signing out, and sign in on other devices.": "这让您可以在注销后回到您的账号,并在其他设备上登录。", - "Dev chat for the Dendrite dev team": "Dendrite 的开发团队的开发聊天", "Keywords": "关键字", "Enable notifications for this account": "为本账号启用通知", "Directory": "聊天室目录", @@ -905,16 +881,11 @@ "Direct Chat": "私聊", "The server may be unavailable or overloaded": "服务器可能无法使用或超过负载", "Reject": "拒绝", - "Riot is not supported on mobile web. Install the app?": "Riot 不支持浏览器网页,要安装 app 吗?", - "Discussion of all things Matrix!": "讨论所有关于 Matrix 的事情!", "Failed to set Direct Message status of room": "无法设置聊天室的私聊状态", "Monday": "星期一", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "为了诊断问题,来自客户端的活动记录会随着这个程序 bug 报告一并发出。如果你只想送出以上文字,请取消勾选:", - "Send Custom State Event": "发送自定义状态事件", "Remove from Directory": "从目录中移除", "Enable them now": "现在启用", "Messages containing my user name": "消息中包含我的用户名", - "Describe your problem here.": "在这里描述你的问题。", "Toolbox": "工具箱", "Collecting logs": "正在收集日志", "more": "更多", @@ -929,47 +900,31 @@ "Quote": "引述", "Send logs": "发送日志", "All messages": "全部消息", - "Implementing VoIP services with Matrix": "使用 Matrix 实现 VoIP 服务", - "Dev chat for the Riot/Web dev team": "Riot/Web 开发团队的开发聊天", "Call invitation": "语音邀请", - "Riot Desktop on %(platformName)s": "Riot 桌面版在 %(platformName)s", "Downloading update...": "正在下载更新…", "State Key": "状态密钥", "Failed to send custom event.": "发送自定义事件失败。", "What's new?": "有什么新闻?", - "Discussion of the Identity Service API": "识别服务 API 的讨论", - "Support for those using and running matrix-appservice-irc": "使用与执行 matrix-appservice-irc 的支持", - "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk 聊天", "Notify me for anything else": "所有消息都通知我", "When I'm invited to a room": "当我被邀请进入聊天室", - "Design and implementation of E2E in Matrix": "在 Matrix 中 E2E 的设计与实现", "Click here to create a GitHub issue.": "点击这里 创建一个 GitHub issue.", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "您可以使用自订的服务器选项,并指定不同的主服务器 URL 来登录其他的 Matrix 服务器。
    这让您可以在不同的服务器上以既有的 Matrix 帐号使用 Riot。

    您也可以设置一个自订的身份服务器,但您可能无法透过电子邮件地址来邀请用户,或是让别人透过电子邮件邀请您。", "Can't update user notification settings": "不能更新用户通知设置", "Notify for all other messages/rooms": "为所有其他消息/聊天室显示通知", "Unable to look up room ID from server": "无法在服务器上找到聊天室 ID", "Couldn't find a matching Matrix room": "未找到符合的 Matrix 聊天室", - "Support for those using the Matrix spec": "使用 Matrix 规范的支持", - "Safari and Opera work too.": "SafariOpera 均可运行。", - "Loading bug report module": "正在载入 bug 报告模块", "Invite to this room": "邀请别人加入此聊天室", "Search for a room": "搜索聊天室", "Thursday": "星期四", "Search…": "搜索…", "Logs sent": "记录已发送", - "%(appName)s via %(browserName)s on %(osName)s": "应用 %(appName)s 通过 %(osName)s 上的 %(browserName)s 浏览器运行", "Back": "返回", "Reply": "回复", "Show message in desktop notification": "在桌面通知中显示信息", "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "调试日志包含使用数据(包括您的用户名,您访问过的聊天室 / 小组的 ID 或别名以及其他用户的用户名)。它们不包含聊天信息。", "Unhide Preview": "取消隐藏预览", - "Announcements about Synapse releases": "Synapse 的发布公告", - "Search the room directory": "搜索聊天室目录", - "Please describe the bug and/or send logs.": "请描述这个 bug 和/或发送日志。", "Unable to join network": "无法加入网络", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "您也许不曾在其他 Riot 之外的客户端设置它们。在 Riot 下你无法调整他们但仍然可用", "Sorry, your browser is not able to run Riot.": "抱歉,您的浏览器 无法 运行 Riot.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "去中心化,加密聊天 & 由 [matrix] 提供", "Uploaded on %(date)s by %(user)s": "由 %(user)s 在 %(date)s 上传", "Messages in group chats": "群组聊天中的消息", "Yesterday": "昨天", @@ -978,16 +933,13 @@ "Low Priority": "低优先级", "Unable to fetch notification target list": "无法获取通知目标列表", "Appear Offline": "似乎离线了", - "Get started with some tips from Riot Bot!": "使用从 Riot 机器人学来的小窍门开始!", "Set Password": "设置密码", "Enable audible notifications in web client": "在网页客户端启用音频通知", "Permalink": "永久链接", - "Welcome to Riot.im": "欢迎来到 Riot.im", "Off": "关闭", "Riot does not know how to join a room on this network": "Riot 不知道如何在此网络中加入聊天室", "Mentions only": "只限提及", "You can now return to your account after signing out, and sign in on other devices.": "您可以在注销后回到您的账号,并在其他设备上登录。", - "Please install Chrome or Firefox for the best experience.": "请安装 ChromeFirefox 来得到最佳体验。", "Enable email notifications": "启用电子邮件通知", "Event Type": "事件类型", "Download this file": "下载该文件", @@ -997,13 +949,10 @@ "%(count)s Members|one": "%(count)s 位成员", "Event sent!": "事件已发出!", "View Source": "查看源码", - "Matrix technical discussions": "Matrix 技术讨论", "Event Content": "事件内容", "Thank you!": "谢谢!", - "Building services on Matrix": "正在 Matrix 上建立服务", "Collapse panel": "折叠面板", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "您目前的浏览器,应用程序的外观和感觉完全不正确,有些或全部功能可能无法使用。如果您仍想继续尝试,可以继续,但请自行负担其后果!", "Checking for an update...": "正在检查更新…", - "General discussion about Matrix and Riot": "关于 Matrix 与 Riot 的一般讨论", "There are advanced notifications which are not shown here": "更多的通知并没有在此显示出来" } diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 3ed45061f4..a404604ec2 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -12,7 +12,6 @@ "Ban": "封鎖", "Banned users": "被封鎖的用戶", "Blacklisted": "已列入黑名單", - "Bug Report": "臭蟲回報", "Call Timeout": "通話超時", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "當瀏覽器網址列裡有 HTTPS URL 時,不能使用 HTTP 連線到家伺服器。請採用 HTTPS 或者允許不安全的指令稿。", "Can't load user settings": "無法載入使用者設定", @@ -102,7 +101,6 @@ "Forgot your password?": "忘記密碼?", "For security, this session has been signed out. Please sign in again.": "因為安全因素,此工作階段已被登出。請重新登入。", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "因為安全因素,登出將會從此瀏覽器刪除任何端到端加密的金鑰。若您想要在未來的 Riot 工作階段中解密您的對話紀錄,請將您的聊天室金鑰匯出並好好存放。", - "Found a bug?": "發現漏洞?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s 從 %(fromPowerLevel)s 變為 %(toPowerLevel)s", "Guests cannot join this room even if explicitly invited.": "游客不能加入此聊天室,即使有人主動邀請。.", "Hangup": "掛斷", @@ -127,7 +125,6 @@ "Leave room": "離開聊天室", "Login as guest": "以游客的身份登錄", "New password": "新密碼", - "Report it": "報告", "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.": "重設密碼目前會把所有裝置上的端到端加密金鑰重設,讓已加密的聊天歷史不可讀,除非您先匯出您的聊天室金鑰並在稍後重新匯入。這會在未來改進。", "Return to login screen": "返回到登入畫面", "Riot does not have permission to send you notifications - please check your browser settings": "Riot 未被允許向你推送通知 ── 請檢查您的瀏覽器設定", @@ -653,7 +650,6 @@ "Do you want to load widget from URL:": "您想要載入小工具的 URL:", "Edit": "編輯", "Enable automatic language detection for syntax highlighting": "啟用語法突顯的自動語言偵測", - "Hide Apps": "隱藏應用程式", "Hide join/leave messages (invites/kicks/bans unaffected)": "隱藏加入/離開訊息(邀請/踢出/封鎖不受影響)", "Integrations Error": "整合錯誤", "Publish this room to the public in %(domain)s's room directory?": "將這個聊天室公開到 %(domain)s 的聊天室目錄中?", @@ -662,7 +658,6 @@ "NOTE: Apps are not end-to-end encrypted": "注意:應用程式並未端到端加密", "Revoke widget access": "撤銷小工具存取", "Sets the room topic": "設定聊天室主題", - "Show Apps": "顯示應用程式", "The maximum permitted number of widgets have already been added to this room.": "這個聊天室已經有可加入的最大量的小工具了。", "To get started, please pick a username!": "要開始,請先取一個使用者名稱!", "Unable to create widget.": "無法建立小工具。", @@ -923,7 +918,6 @@ "Leave Community": "離開社群", "Leave %(groupName)s?": "離開 %(groupName)s?", "Leave": "離開", - "Unable to leave room": "無法離開聊天室", "Community Settings": "社群設定", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "這些聊天室在社群頁面上顯示給社群成員。社群成員可以透過點按它們來加入聊天室。", "%(inviter)s has invited you to join this community": "%(inviter)s 已經邀請您加入此社群", @@ -992,7 +986,6 @@ "Key request sent.": "金鑰請求已傳送。", "Re-request encryption keys from your other devices.": "從您的其他裝置重新請求加密金鑰。", "%(user)s is a %(userRole)s": "%(user)s 是 %(userRole)s", - "Changes made to your community might not be seen by other users for up to 30 minutes.": "其他使用者在最多 30 分鐘內可能不會慨到您對社群所做的變更。", "Code": "代碼", "Debug Logs Submission": "除錯訊息傳送", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "如果您透過 GitHub 來回報錯誤,除錯訊息可以用來追蹤問題。除錯訊息包含應用程式的使用資料,包括您的使用者名稱、您所造訪的房間/群組的 ID 或別名、其他使用者的使用者名稱等,其中不包含訊息本身。", @@ -1007,19 +1000,13 @@ "Stickerpack": "貼圖包", "Sticker Messages": "貼圖訊息", "You don't currently have any stickerpacks enabled": "您目前未啟用任何貼圖包", - "Click": "點按", - "here": "這裡", - "to add some!": "來新增一些!", "Add a stickerpack": "新增貼圖包", "Hide Stickers": "隱藏貼圖", "Show Stickers": "顯示貼圖", - "Manage sticker packs": "管理貼圖包", "Who can join this community?": "誰可以加入此社群?", "Everyone": "每個人", "Fetching third party location failed": "抓取第三方位置失敗", "A new version of Riot is available.": "Riot 釋出了新版本。", - "Riot/Android & matrix-android-sdk chat": "Riot/Android 與 matrix-android-sdk 的討論", - "Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "請描述這個程式臭蟲,您做了什麼動作?您預期會發生什麼狀況?以及實際發生的狀況為何?", "I understand the risks and wish to continue": "我了解這些風險並願意繼續", "Couldn't load home page": "無法載入首頁", "Send Account Data": "傳送帳號資料", @@ -1029,12 +1016,9 @@ "Notification targets": "通知目標", "Today": "今天", "Failed to get protocol list from Home Server": "無法從主機伺服器取得協定清單", - "Report a bug": "回報程式臭蟲", - "Implementing VR services with Matrix": "使用 Matrix 實作虛擬實境服務的討論", "You are not receiving desktop notifications": "你將不會收到桌面通知", "Friday": "星期五", "Update": "更新", - "You need to be using HTTPS to place a screen-sharing call.": "你需要使用 HTTPS 來放置螢幕分享的通話。", "Unable to fetch notification target list": "無法抓取通知的目標清單", "Add an email address above to configure email notifications": "在上面新增電子郵件以設定電子郵件通知", "Expand panel": "展開面板", @@ -1042,18 +1026,14 @@ "%(count)s Members|other": "%(count)s 個成員", "Filter room names": "過濾聊天室名稱", "Changelog": "變更記錄", - "Running Matrix services": "關於 Matrix 服務營運", "Waiting for response from server": "正在等待來自伺服器的回應", "Uploaded on %(date)s by %(user)s": "由 %(user)s 在 %(date)s 上傳", "Send Custom Event": "傳送自訂事件", - "Failed to send report: ": "無法傳送報告: ", - "Unknown device": "未知裝置", "All notifications are currently disabled for all targets.": "目前所有的通知功能已停用。", "Failed to send logs: ": "無法傳送除錯訊息: ", "delete the alias.": "刪除別名。", "To return to your account in future you need to set a password": "未來若需回來使用您的帳號,您需要 設定密碼", "Forget": "忘記", - "Riot/Web & Desktop chat": "Riot/Web 與桌面版的討論", "Hide panel": "隱藏面板", "You cannot delete this image. (%(code)s)": "你不能刪除這個圖片。(%(code)s)", "Cancel Sending": "取消傳送", @@ -1063,9 +1043,7 @@ "Room not found": "找不到聊天室", "Messages containing my display name": "訊息中有包含我的顯示名稱", "Messages in one-to-one chats": "在一對一聊天中的訊息", - "Contributing code to Matrix and Riot": "關於貢獻 Matrix 和 Riot", "Unavailable": "無法取得", - "Community-run support for Synapse": "Synapse 社群支援聊天室", "Error saving email notification preferences": "儲存電子郵件通知偏好設定時出錯", "View Decrypted Source": "檢視解密的來源", "Failed to update keywords": "無法更新關鍵字", @@ -1075,9 +1053,6 @@ "Safari and Opera work too.": "SafariOpera 也可以運作。", "Please set a password!": "請設定密碼!", "You have successfully set a password!": "您已經成功設定密碼!", - "Chat with Riot Bot": "與 Riot 機器人聊天", - "Support for those using, running and writing other bridges": "使用、執行與撰寫其他橋接服務的支援聊天室", - "Admin support for Dendrite": "Dendrite 管理員支援聊天室", "An error occurred whilst saving your email notification preferences.": "在儲存你的電子郵件通知偏好時發生錯誤。", "Explore Room State": "探索聊天室狀態", "Source URL": "來源網址", @@ -1085,16 +1060,11 @@ "Filter results": "過濾結果", "Members": "成員", "No update available.": "沒有可用的更新。", - "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Matrix 中已有許多聊天室,連結到已有的網路(Slack、IRC 與 Gitter 等等)或是獨立的網路。來看看聊天室目錄吧!", "Noisy": "吵鬧", "Files": "檔案", "Collecting app version information": "收集應用程式版本資訊", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "刪除聊天室別名 %(alias)s 並從目錄移除 %(name)s?", - "customServer_text": "你可以使用自訂伺服器選項來登入其它的 Matrix 伺服器,只要在在主機伺服器網址上指定其網址資料。
    這可讓你透過已有的 Matrix 帳號在不同的主機伺服器上使用 Riot。

    你也可以設定自定的識別伺服器但你將無法透過電子郵件來邀請用戶或是以自己的電子郵件來接受別人的邀請。", - "Co-ordination for Riot/Web translators": "Riot/Web 翻譯者的協調聊天室", "This will allow you to return to your account after signing out, and sign in on other devices.": "這讓您可以在登入後回到您帳號,並在其他裝置上登入。", - "Dev chat for the Dendrite dev team": "Dendrite 開發團隊的開發聊天室", - "Design and implementation of E2E in Matrix": "Matrix 中點對點加密的設計與實作討論", "Enable notifications for this account": "本帳號啟用通知", "Directory": "目錄", "Invite to this community": "邀請至此社群", @@ -1118,16 +1088,11 @@ "Direct Chat": "私人聊天", "The server may be unavailable or overloaded": "伺服器可能無法使用或是超過負載", "Reject": "拒絕", - "Riot is not supported on mobile web. Install the app?": "Riot 不支援行動版網頁,要安裝應用程式嗎?", - "Discussion of all things Matrix!": "所有 Matrix 相關的一般討論", "Failed to set Direct Message status of room": "無法設定聊天室的私人訊息狀態", "Monday": "星期一", - "In order to diagnose problems, logs from this client will be sent with this bug report. If you would prefer to only send the text above, please untick:": "為了診斷問題,來自客戶端的活動記錄會隨著這個程式臭蟲報告一起送出。如果你只想送出以上文字,請取消勾選:", - "Send Custom State Event": "傳送自訂狀態事件", "Remove from Directory": "自目錄中移除", "Enable them now": "現在啟用", "Messages containing my user name": "訊息中有我的使用者名稱", - "Describe your problem here.": "在此描述你的問題。", "Toolbox": "工具箱", "Collecting logs": "收集記錄", "more": "更多", @@ -1141,48 +1106,32 @@ "Failed to get public room list": "無法取得公開的聊天室清單", "Send logs": "傳送記錄", "All messages": "所有訊息", - "Implementing VoIP services with Matrix": "使用 Matrix 實作 VoIP 服務的討論", - "Dev chat for the Riot/Web dev team": "Riot/Web 開發團隊的開發聊天室", "Call invitation": "通話邀請", - "Riot Desktop on %(platformName)s": "Riot 桌面版在 %(platformName)s", "Downloading update...": "正在下䵧更新...", "State Key": "狀態金鑰", "Failed to send custom event.": "傳送自訂式件失敗。", "What's new?": "有什麼新聞?", - "Discussion of the Identity Service API": "識別服務 API 的討論", - "Support for those using and running matrix-appservice-irc": "matrix-appservice-irc 使用者與營運的支援", - "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS 與 matrix-ios-sdk 的討論", "Notify me for anything else": "所有消息都通知我", "View Source": "檢視來源", "Keywords": "關鍵字", "Click here to create a GitHub issue.": "點選這裡來建立 GitHub 問題回報。", - "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.
    This allows you to use Riot with an existing Matrix account on a different home server.

    You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "您可以使用自訂的伺服器選項,並指定不同的家伺服器 URL 來登入其他的 Matrix 伺服器。
    這讓您可以在不同的伺服器上以既有的 Matrix 帳號使用 Riot。

    您也可以設定一個自訂的識別伺服器,但您可能無法透過電子郵件地址來邀請使用者,或是讓別人透過電子郵件邀請您。", "Can't update user notification settings": "無法更新使用者的通知設定", "Notify for all other messages/rooms": "通知其他所有的訊息/聊天室", "Unable to look up room ID from server": "無法從伺服器找到聊天室 ID", "Couldn't find a matching Matrix room": "不能找到符合 Matrix 的聊天室", - "Support for those using the Matrix spec": "Matrix 規格使用者支援聊天室", - "Safari and Opera work too.": "SafariOpera 也能使用。", - "Loading bug report module": "正在載入程式臭蟲報告模組", "Invite to this room": "邀請加入這個聊天室", "You cannot delete this message. (%(code)s)": "你不能刪除這個訊息。(%(code)s)", "Thursday": "星期四", "Search…": "搜尋…", "Logs sent": "除錯訊息已經傳送", - "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s 透過 %(browserName)s 在 %(osName)s", "Back": "返回", "Reply": "回覆", "Show message in desktop notification": "在桌面通知中顯示訊息", "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "除錯訊息包含應用程式的使用資料,包括您的使用者名稱、您所造訪的房間/群組的 ID 或別名、其他使用者的使用者名稱等,其中不包含訊息本身。", "Unhide Preview": "取消隱藏預覽", - "Announcements about Synapse releases": "Synapse 發行公告", - "Search the room directory": "搜尋聊天室目錄", - "Please describe the bug and/or send logs.": "請描述這個程式臭蟲以及/或送出活動記錄。", "Unable to join network": "無法加入網路", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "你也許不曾在其它 Riot 之外的客戶端設定它們。在 Riot 底下你無法調整它們但其仍然可用", "Sorry, your browser is not able to run Riot.": "可惜,您的瀏覽器 無法 執行 Riot.", - "Decentralised, encrypted chat & collaboration powered by [matrix]": "去中心化、保密的聊天與協作,由 [matrix] 出品", - "Building services on Matrix": "關於在 Matrix 上開發服務", "Messages in group chats": "在群組聊天中的訊息", "Yesterday": "昨天", "Error encountered (%(errorDetail)s).": "遇到錯誤 (%(errorDetail)s)。", @@ -1190,17 +1139,14 @@ "Low Priority": "低優先度", "Riot does not know how to join a room on this network": "Riot 不知道如何在此網路中加入聊天室", "Appear Offline": "顯示為離線", - "Get started with some tips from Riot Bot!": "從 Riot 機器人了解使用 Riot 的訣竅吧!", "Set Password": "設定密碼", "Enable audible notifications in web client": "在網頁客戶端啟用音訊通知", "Permalink": "永久連結", - "Welcome to Riot.im": "歡迎來到 Riot.im", "Off": "關閉", "#example": "#範例", "Mentions only": "僅提及", "Wednesday": "星期三", "You can now return to your account after signing out, and sign in on other devices.": "您可以在登出後回到您的帳號,並在其他裝置上登入。", - "Please install Chrome or Firefox for the best experience.": "諘安裝 ChromeFirefox 來取得最佳體驗。", "Enable email notifications": "啟用電子郵件通知", "Event Type": "事件類型", "Download this file": "下載這個檔案", @@ -1209,13 +1155,11 @@ "View Community": "檢視社群", "%(count)s Members|one": "%(count)s 個成員", "Event sent!": "事件已傳送!", - "Matrix technical discussions": "Matrix 技術討論", "Event Content": "事件內容", "Thank you!": "感謝您!", "Quote": "引用", "Collapse panel": "摺疊面板", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "您目前的瀏覽器,其應用程式的外觀和感覺可能完全不正確,有些或全部功能可以無法使用。如果您仍想要繼續嘗試,可以繼續,但必須自行承擔後果!", "Checking for an update...": "正在檢查更新...", - "General discussion about Matrix and Riot": "Matrix 與 Riot 的一般討論", "There are advanced notifications which are not shown here": "有些進階的通知並未在此顯示" } From fe5e68de290dd9f4ec76180dad1709e8b15201fc Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 15 Apr 2018 23:48:52 +0100 Subject: [PATCH 0787/1160] fix tests --- test/notifications/ContentRules-test.js | 4 ++-- test/notifications/PushRuleVectorState-test.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/notifications/ContentRules-test.js b/test/notifications/ContentRules-test.js index c1cdc40a8b..b58667fee9 100644 --- a/test/notifications/ContentRules-test.js +++ b/test/notifications/ContentRules-test.js @@ -14,13 +14,13 @@ See the License for the specific language governing permissions and limitations under the License. */ -var notifications = require('../../../src/notifications'); +var notifications = require('../../src/notifications'); var ContentRules = notifications.ContentRules; var PushRuleVectorState = notifications.PushRuleVectorState; var expect = require('expect'); -var test_utils = require('../../test-utils'); +var test_utils = require('../test-utils'); var NORMAL_RULE = { actions: [ diff --git a/test/notifications/PushRuleVectorState-test.js b/test/notifications/PushRuleVectorState-test.js index 68e7044f60..ff0de3e470 100644 --- a/test/notifications/PushRuleVectorState-test.js +++ b/test/notifications/PushRuleVectorState-test.js @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -var notifications = require('../../../src/notifications'); +var notifications = require('../../src/notifications'); var prvs = notifications.PushRuleVectorState; From 32dd7f976f11f7f2aefa741467120c0c0663f897 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 16 Apr 2018 00:04:04 +0100 Subject: [PATCH 0788/1160] merge vector-im/riot-web#5881 into matrix-react-sdk --- .../views/avatars/_MemberPresenceAvatar.scss | 43 -------- .../_PresenceContextMenuOption.scss | 42 -------- .../context_menus/PresenceContextMenu.js | 101 ------------------ 3 files changed, 186 deletions(-) delete mode 100644 res/css/views/avatars/_MemberPresenceAvatar.scss delete mode 100644 res/css/views/context_menus/_PresenceContextMenuOption.scss delete mode 100644 src/components/views/context_menus/PresenceContextMenu.js diff --git a/res/css/views/avatars/_MemberPresenceAvatar.scss b/res/css/views/avatars/_MemberPresenceAvatar.scss deleted file mode 100644 index a15f8eaa65..0000000000 --- a/res/css/views/avatars/_MemberPresenceAvatar.scss +++ /dev/null @@ -1,43 +0,0 @@ -/* -Copyright 2017 Travis Ralston - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -.mx_MemberPresenceAvatar { - display: inline-block; - position: relative; -} - -.mx_MemberPresenceAvatar_status { - display: block; - width: 10px; - height: 10px; - border-radius: 10px; - - position: absolute; - bottom: -2px; - right: -3px; -} - -.mx_MemberPresenceAvatar_status_online { - background-color: $presence-online; -} - -.mx_MemberPresenceAvatar_status_unavailable { - background-color: $presence-unavailable; -} - -.mx_MemberPresenceAvatar_status_offline { - background-color: $presence-offline; -} diff --git a/res/css/views/context_menus/_PresenceContextMenuOption.scss b/res/css/views/context_menus/_PresenceContextMenuOption.scss deleted file mode 100644 index bfe81125e0..0000000000 --- a/res/css/views/context_menus/_PresenceContextMenuOption.scss +++ /dev/null @@ -1,42 +0,0 @@ -/* -Copyright 2017 Travis Ralston - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ -.mx_PresenceContextMenuOption_indicator { - width: 10px; - height: 10px; - border-radius: 10px; - display: inline-block; - margin-right: 5px; -} - -.mx_PresenceContextMenuOption_indicator.mx_PresenceContextMenuOption_indicator_online { - background-color: $presence-online; -} - -.mx_PresenceContextMenuOption_indicator.mx_PresenceContextMenuOption_indicator_unavailable { - background-color: $presence-unavailable; -} - -.mx_PresenceContextMenuOption_indicator.mx_PresenceContextMenuOption_indicator_offline { - background-color: $presence-offline; -} - -.mx_PresenceContextMenuOption { - padding: 2px; -} - -.mx_PresenceContextMenuOption.mx_PresenceContextMenuOption_current { - font-weight: 700; -} diff --git a/src/components/views/context_menus/PresenceContextMenu.js b/src/components/views/context_menus/PresenceContextMenu.js deleted file mode 100644 index 9b10598511..0000000000 --- a/src/components/views/context_menus/PresenceContextMenu.js +++ /dev/null @@ -1,101 +0,0 @@ -/* -Copyright 2017 Travis Ralston - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import React from 'react'; -import { _t, _td } from '../../../languageHandler'; -import sdk from '../../../index'; - -const STATUS_LABELS = { - "online": _td("Online"), - "unavailable": _td("Away"), - "offline": _td("Appear Offline"), -}; - -const PresenceContextMenuOption = React.createClass({ - displayName: 'PresenceContextMenuOption', - - propTypes: { - forStatus: React.PropTypes.string.isRequired, - isCurrent: React.PropTypes.bool, - onChange: React.PropTypes.func.isRequired, - }, - - onClick: function() { - if (this.isCurrent) return; - this.props.onChange(this.props.forStatus); - }, - - render: function() { - const AccessibleButton = sdk.getComponent("elements.AccessibleButton"); - - const indicatorClasses = "mx_PresenceContextMenuOption_indicator " - + "mx_PresenceContextMenuOption_indicator_" + this.props.forStatus; - - let classNames = "mx_PresenceContextMenuOption"; - if (this.props.isCurrent) classNames += " mx_PresenceContextMenuOption_current"; - - return ( - -
    - { _t(STATUS_LABELS[this.props.forStatus]) } -
    - ); - }, -}); - -module.exports = React.createClass({ - displayName: 'PresenceContextMenu', - - propTypes: { - // "online", "unavailable", or "offline" - currentStatus: React.PropTypes.string.isRequired, - - // Called when the user wants to change their status. - // Args: (newStatus:string) - onChange: React.PropTypes.func.isRequired, - - // callback called when the menu is dismissed - onFinished: React.PropTypes.func, - }, - - getInitialState() { - return { - currentStatus: this.props.currentStatus, - }; - }, - - onChange: function(newStatus) { - this.props.onChange(newStatus); - this.setState({currentStatus: newStatus}); - }, - - render: function() { - const statusElements = []; - for (let status of Object.keys(STATUS_LABELS)) { - statusElements.push(( - - )); - } - - return ( -
    - { statusElements } -
    - ); - }, -}); From f1f7673037a67c9f5b1812e8b67cfee00b5f148f Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 16 Apr 2018 01:12:41 +0100 Subject: [PATCH 0789/1160] ignore lint errors in stuff moved over from vector-web for now --- .eslintignore.errorfiles | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/.eslintignore.errorfiles b/.eslintignore.errorfiles index f501f373cd..42818244b3 100644 --- a/.eslintignore.errorfiles +++ b/.eslintignore.errorfiles @@ -6,39 +6,57 @@ src/autocomplete/EmojiProvider.js src/autocomplete/UserProvider.js src/CallHandler.js src/component-index.js -src/components/structures/ContextualMenu.js +src/components/structures/BottomLeftMenu.js +src/components/structures/CompatibilityPage.js src/components/structures/CreateRoom.js +src/components/structures/HomePage.js +src/components/structures/LeftPanel.js src/components/structures/LoggedInView.js src/components/structures/login/ForgotPassword.js src/components/structures/login/Login.js src/components/structures/login/Registration.js +src/components/structures/LoginBox.js src/components/structures/MessagePanel.js src/components/structures/NotificationPanel.js +src/components/structures/RoomDirectory.js src/components/structures/RoomStatusBar.js +src/components/structures/RoomSubList.js src/components/structures/RoomView.js src/components/structures/ScrollPanel.js +src/components/structures/SearchBox.js src/components/structures/TimelinePanel.js src/components/structures/UploadBar.js +src/components/structures/ViewSource.js src/components/views/avatars/BaseAvatar.js +src/components/views/avatars/GroupAvatar.js src/components/views/avatars/MemberAvatar.js src/components/views/create_room/RoomAlias.js +src/components/views/dialogs/BugReportDialog.js +src/components/views/dialogs/ChangelogDialog.js src/components/views/dialogs/ChatCreateOrReuseDialog.js src/components/views/dialogs/DeactivateAccountDialog.js +src/components/views/dialogs/SetPasswordDialog.js src/components/views/dialogs/UnknownDeviceDialog.js +src/components/views/directory/NetworkDropdown.js src/components/views/elements/AddressSelector.js src/components/views/elements/DeviceVerifyButtons.js src/components/views/elements/DirectorySearchBox.js src/components/views/elements/EditableText.js +src/components/views/elements/ImageView.js +src/components/views/elements/InlineSpinner.js src/components/views/elements/MemberEventListSummary.js +src/components/views/elements/Spinner.js src/components/views/elements/TintableSvg.js src/components/views/elements/UserSelector.js +src/components/views/globals/MatrixToolbar.js +src/components/views/globals/NewVersionBar.js +src/components/views/globals/UpdateCheckBar.js src/components/views/login/CountryDropdown.js src/components/views/login/InteractiveAuthEntryComponents.js src/components/views/login/PasswordLogin.js src/components/views/login/RegistrationForm.js src/components/views/login/ServerConfig.js src/components/views/messages/MFileBody.js -src/components/views/messages/MImageBody.js src/components/views/messages/RoomAvatarEvent.js src/components/views/messages/TextualBody.js src/components/views/room_settings/AliasSettings.js @@ -55,12 +73,14 @@ src/components/views/rooms/MemberList.js src/components/views/rooms/MemberTile.js src/components/views/rooms/MessageComposer.js src/components/views/rooms/MessageComposerInput.js -src/components/views/rooms/ReadReceiptMarker.js +src/components/views/rooms/RoomDropTarget.js src/components/views/rooms/RoomList.js src/components/views/rooms/RoomPreviewBar.js src/components/views/rooms/RoomSettings.js src/components/views/rooms/RoomTile.js +src/components/views/rooms/RoomTooltip.js src/components/views/rooms/SearchableEntityList.js +src/components/views/rooms/SearchBar.js src/components/views/rooms/SearchResultTile.js src/components/views/rooms/TopUnreadMessagesBar.js src/components/views/rooms/UserTile.js @@ -69,6 +89,8 @@ src/components/views/settings/ChangeAvatar.js src/components/views/settings/ChangeDisplayName.js src/components/views/settings/ChangePassword.js src/components/views/settings/DevicesPanel.js +src/components/views/settings/IntegrationsManager.js +src/components/views/settings/Notifications.js src/ContentMessages.js src/HtmlUtils.js src/ImageUtils.js @@ -78,9 +100,16 @@ src/Login.js src/Markdown.js src/MatrixClientPeg.js src/Modal.js +src/notifications/ContentRules.js +src/notifications/NotificationUtils.js +src/notifications/PushRuleVectorState.js +src/notifications/StandardActions.js +src/notifications/VectorPushRulesDefinitions.js src/Notifier.js src/PlatformPeg.js src/Presence.js +src/rageshake/rageshake.js +src/rageshake/submit-rageshake.js src/ratelimitedfunc.js src/RichText.js src/Roles.js @@ -89,10 +118,12 @@ src/ScalarAuthClient.js src/UiEffects.js src/Unread.js src/utils/DecryptFile.js +src/utils/DirectoryUtils.js src/utils/DMRoomMap.js src/utils/FormattingUtils.js src/utils/MultiInviter.js src/utils/Receipt.js +src/VectorConferenceHandler.js src/Velociraptor.js src/VelocityBounce.js src/WhoIsTyping.js @@ -102,8 +133,9 @@ test/components/structures/MessagePanel-test.js test/components/structures/ScrollPanel-test.js test/components/structures/TimelinePanel-test.js test/components/views/dialogs/InteractiveAuthDialog-test.js -test/components/views/elements/MemberEventListSummary-test.js test/components/views/login/RegistrationForm-test.js test/components/views/rooms/MessageComposerInput-test.js test/mock-clock.js +test/notifications/ContentRules-test.js +test/notifications/PushRuleVectorState-test.js test/stores/RoomViewStore-test.js From 46f5c0d2054a02e76ffea41793002e84f88e955a Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 16 Apr 2018 01:13:03 +0100 Subject: [PATCH 0790/1160] finish merging vector-im/riot-web#5881 into matrix-react-sdk --- res/css/_components.scss | 2 -- res/themes/light/css/_base.scss | 5 ----- 2 files changed, 7 deletions(-) diff --git a/res/css/_components.scss b/res/css/_components.scss index b62c08f763..9770010324 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -24,9 +24,7 @@ @import "./structures/_ViewSource.scss"; @import "./structures/login/_Login.scss"; @import "./views/avatars/_BaseAvatar.scss"; -@import "./views/avatars/_MemberPresenceAvatar.scss"; @import "./views/context_menus/_MessageContextMenu.scss"; -@import "./views/context_menus/_PresenceContextMenuOption.scss"; @import "./views/context_menus/_RoomTileContextMenu.scss"; @import "./views/context_menus/_TagTileContextMenu.scss"; @import "./views/dialogs/_BugReportDialog.scss"; diff --git a/res/themes/light/css/_base.scss b/res/themes/light/css/_base.scss index 51d2f70f78..5d5f5d7c90 100644 --- a/res/themes/light/css/_base.scss +++ b/res/themes/light/css/_base.scss @@ -139,11 +139,6 @@ $e2e-verified-color: #76cfa5; // N.B. *NOT* the same as $accent-color $e2e-unverified-color: #e8bf37; $e2e-warning-color: #ba6363; -// presence -$presence-online: #60de00; -$presence-unavailable: #deb800; -$presence-offline: #b7b7b7; - /*** ImageView ***/ $lightbox-bg-color: #454545; $lightbox-fg-color: #ffffff; From 22f5d5ba6a3f9928287c310401174c23553428e0 Mon Sep 17 00:00:00 2001 From: Nathan van Beelen Date: Mon, 16 Apr 2018 08:27:28 +0000 Subject: [PATCH 0791/1160] Translated using Weblate (Dutch) Currently translated at 100.0% (1011 of 1011 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/nl/ --- src/i18n/strings/nl.json | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index d4bda9c6da..516fc9dd21 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -994,5 +994,28 @@ "Clear filter": "Filter vrijmaken", "Failed to set direct chat tag": "Het is niet gelukt om de 'privégesprek' label in te stellen", "Failed to remove tag %(tagName)s from room": "Het is niet gelukt om de label %(tagName)s van de ruimte te verwijderen", - "Failed to add tag %(tagName)s to room": "Het is niet gelukt om de label %(tagName)s aan deze ruimte toe te voegen" + "Failed to add tag %(tagName)s to room": "Het is niet gelukt om de label %(tagName)s aan deze ruimte toe te voegen", + "Stickerpack": "Stickerpakket", + "Sticker Messages": "Sticker Berichten", + "You don't currently have any stickerpacks enabled": "Je hebt momenteel geen stickerpakketten aan staan", + "Click": "Klik", + "here": "hier", + "to add some!": "om wat toe te voegen!", + "Add a stickerpack": "Stickerpakket toevoegen", + "Hide Stickers": "Stickers verbergen", + "Show Stickers": "Stickers weergeven", + "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Gezien door %(displayName)s (%(userName)s) op %(dateTime)s", + "Code": "Code", + "Manage sticker packs": "Stickerpakketten beheren", + "Unable to join community": "Je kon niet tot de gemeenschap toetreden", + "Unable to leave community": "Je kon de gemeenschap niet verlaten", + "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Veranderingen die aan je gemeenschap naam en avatar zijn aangebracht zullen misschien niet gezien worden door anderen tot maximaal 30 minuten.", + "Join this community": "Tot deze gemeenschap toetreden", + "Who can join this community?": "Wie kan tot deze gemeenschap toetreden?", + "Everyone": "Iedereen", + "Leave this community": "Deze gemeenschap verlaten", + "Debug Logs Submission": "Debug Logs Indienen", + "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Als je een bug via Github hebt ingediend kunnen debug logs ons helpen om het probleem te vinden. Debug logs bevatten applicatie-gebruik data inclusief je gebruikersnaam, de ID's of namen van de ruimtes en groepen die je hebt bezocht en de gebruikersnamen van andere gebruikers. Ze bevatten geen berichten.", + "Submit debug logs": "Debug logs indienen", + "Opens the Developer Tools dialog": "Opent het Ontwikkelaars Gereedschappen dialoog" } From 1e6109142343fdf665db2c860625f6f448bb635c Mon Sep 17 00:00:00 2001 From: Osoitz Date: Tue, 17 Apr 2018 08:56:06 +0000 Subject: [PATCH 0792/1160] Translated using Weblate (Basque) Currently translated at 100.0% (1011 of 1011 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eu/ --- src/i18n/strings/eu.json | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index 276baab771..20fc14acad 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -1003,5 +1003,17 @@ "Unable to leave community": "Ezinezkoa komunitatetik ateratzea", "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Zure komunitatearen izen eta abatarari egindako aldaketak 30 minutu behar ditzakete beste erabiltzaileek ikusi arte.", "Join this community": "Elkartu komunitate honetara", - "Leave this community": "Atera komunitate honetatik" + "Leave this community": "Atera komunitate honetatik", + "Stickerpack": "Eranskailu-multzoa", + "Sticker Messages": "Eranskailu mezuak", + "You don't currently have any stickerpacks enabled": "Ez duzu eranskailu multzorik aktibatuta", + "Click": "Klik", + "here": "hemen", + "to add some!": "batzuk gehitzeko!", + "Add a stickerpack": "Gehitu eranskailu-multzoa", + "Hide Stickers": "Ezkutatu eranskailuak", + "Show Stickers": "Erakutsi eranskailuak", + "Manage sticker packs": "Kudeatu eranskailu-multzoak", + "Who can join this community?": "Nor elkartu daiteke komunitate honetara?", + "Everyone": "Edonor" } From e746fc99d37ccd8e7ad106f291bb406b99aad83d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Tue, 17 Apr 2018 14:04:03 +0000 Subject: [PATCH 0793/1160] Translated using Weblate (Slovak) Currently translated at 100.0% (1011 of 1011 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sk/ --- src/i18n/strings/sk.json | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index 72ba11b6d4..5682c1008e 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -1002,5 +1002,17 @@ "Debug Logs Submission": "Odoslanie ladiacich záznamov", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Ak ste nám poslali hlásenie o chybe cez Github, ladiace záznamy nám môžu pomôcť lepšie identifikovať chybu. Ladiace záznamy obsahujú údaje o používaní aplikácii, vrátane vašeho používateľského mena, názvy a aliasy miestností a komunít, ku ktorým ste sa pripojili a mená ostatných používateľov. Tieto záznamy neobsahujú samotný obsah vašich správ.", "Submit debug logs": "Odoslať ladiace záznamy", - "Opens the Developer Tools dialog": "Otvorí dialóg nástroje pre vývojárov" + "Opens the Developer Tools dialog": "Otvorí dialóg nástroje pre vývojárov", + "Stickerpack": "Balíček nálepiek", + "Sticker Messages": "Správy s nálepkami", + "You don't currently have any stickerpacks enabled": "Momentálne nemáte aktívne žiadne balíčky s nálepkami", + "Click": "Kliknutím", + "here": "sem", + "to add some!": "si nejaké pridajte!", + "Add a stickerpack": "Pridať balíček s nálepkami", + "Hide Stickers": "Skryť nálepky", + "Show Stickers": "Zobraziť nálepky", + "Manage sticker packs": "Spravovať balíčky s nálepkami", + "Who can join this community?": "Kto môže vstúpiť do tejto komunity?", + "Everyone": "Ktokoľvek" } From eca5a965c59e62dc3c689964f9eb7943f9b8148c Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 17 Apr 2018 16:50:24 +0100 Subject: [PATCH 0794/1160] add i18n which weren't correctly copied over from vector-web by copy-i18n --- src/i18n/strings/az.json | 28 +++++++ src/i18n/strings/bn_BD.json | 1 + src/i18n/strings/bn_IN.json | 1 + src/i18n/strings/bs.json | 1 + src/i18n/strings/hi.json | 8 ++ src/i18n/strings/ne.json | 1 + src/i18n/strings/ta.json | 150 ++++++++++++++++++++++++++++++++++++ 7 files changed, 190 insertions(+) create mode 100644 src/i18n/strings/az.json create mode 100644 src/i18n/strings/bn_BD.json create mode 100644 src/i18n/strings/bn_IN.json create mode 100644 src/i18n/strings/bs.json create mode 100644 src/i18n/strings/hi.json create mode 100644 src/i18n/strings/ne.json create mode 100644 src/i18n/strings/ta.json diff --git a/src/i18n/strings/az.json b/src/i18n/strings/az.json new file mode 100644 index 0000000000..24f19a9ce6 --- /dev/null +++ b/src/i18n/strings/az.json @@ -0,0 +1,28 @@ +{ + "Collecting app version information": "Proqramın versiyası haqqında məlumatın yığılması", + "Collecting logs": "Jurnalların bir yığım", + "Uploading report": "Hesabatın göndərilməsi", + "Waiting for response from server": "Serverdən cavabın gözlənməsi", + "Messages containing my display name": "Mənim adımı özündə saxlayan mesajlar", + "Messages containing my user name": "Mənim istifadəçinin adımı özündə saxlayan mesaj", + "Messages in one-to-one chats": "Fərdi çatlarda mesajlar", + "Messages in group chats": "Qrup çatlarında mesajlar", + "When I'm invited to a room": "Nə vaxt ki, məni otağa dəvət edirlər", + "Call invitation": "Dəvət zəngi", + "Messages sent by bot": "Botla göndərilmiş mesajlar", + "Error saving email notification preferences": "Email üzrə xəbərdarlıqların qurmalarının saxlanılması səhv", + "An error occurred whilst saving your email notification preferences.": "Email üzrə bildirişin qurmalarının saxlanılması səhv yarandı.", + "Keywords": "Açar sözlər", + "Enter keywords separated by a comma:": "Vergül bölünmüş açar sözləri daxil edin:", + "OK": "OK", + "Failed to change settings": "Qurmaları dəyişdirməyi bacarmadı", + "Operation failed": "Əməliyyatın nasazlığı", + "Can't update user notification settings": "Bildirişin istifadəçi qurmalarını yeniləməyə müvəffəq olmur", + "Failed to update keywords": "Açar sözləri yeniləməyi bacarmadı", + "Messages containing keywords": "Müəyyən açar sözləri özündə saxlayan mesajlar", + "Notify for all other messages/rooms": "Bütün başqa mesajdan/otaqlardan xəbər vermək", + "Notify me for anything else": "Bütün qalan hadisələrdə xəbər vermək", + "Enable notifications for this account": "Bu hesab üçün xəbərdarlıqları qoşmaq", + "All notifications are currently disabled for all targets.": "Bütün qurğular üçün bütün bildirişlər kəsilmişdir.", + "Add an email address above to configure email notifications": "Email-i bildirişlər üçün ünvanı əlavə edin" +} diff --git a/src/i18n/strings/bn_BD.json b/src/i18n/strings/bn_BD.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/src/i18n/strings/bn_BD.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/src/i18n/strings/bn_IN.json b/src/i18n/strings/bn_IN.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/src/i18n/strings/bn_IN.json @@ -0,0 +1 @@ +{} diff --git a/src/i18n/strings/bs.json b/src/i18n/strings/bs.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/src/i18n/strings/bs.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/src/i18n/strings/hi.json b/src/i18n/strings/hi.json new file mode 100644 index 0000000000..f8bfb088a8 --- /dev/null +++ b/src/i18n/strings/hi.json @@ -0,0 +1,8 @@ +{ + "A new version of Riot is available.": "रायट के एक नया वर्शन उपलब्ध है।", + "All messages": "सारे संदेश", + "All Rooms": "सारे कमरे", + "Please set a password!": "कृपया एक पासवर्ड सेट करें!", + "Continue": "आगे बढ़ें", + "You have successfully set a password and an email address!": "आपने सफलतापूर्वक एक पासवर्ड और एक ईमेल एड्रेस सेट कर लिया है!" +} diff --git a/src/i18n/strings/ne.json b/src/i18n/strings/ne.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/src/i18n/strings/ne.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/src/i18n/strings/ta.json b/src/i18n/strings/ta.json new file mode 100644 index 0000000000..202e5326f0 --- /dev/null +++ b/src/i18n/strings/ta.json @@ -0,0 +1,150 @@ +{ + "A new version of Riot is available.": "Riot-ன் புதிய பதிப்பு உள்ளது.", + "Add an email address above to configure email notifications": "மின்னஞ்சல் மூலம் அறிவிப்புகளை பெற உங்கள் மின்னஞ்சல் முகவரியை மேலே இணைக்கவும்", + "Advanced notification settings": "மேம்பட்ட அறிவிப்பிற்கான அமைப்புகள்", + "All messages": "அனைத்து செய்திகள்", + "All messages (noisy)": "அனைத்து செய்திகள் (உரக்க)", + "All Rooms": "அனைத்து அறைகள்", + "All notifications are currently disabled for all targets.": "அனைத்து இலக்குகளுக்கான அனைத்து அறிவுப்புகளும் தற்போது முடக்கி வைக்கப்பட்டுள்ளது.", + "An error occurred whilst saving your email notification preferences.": "உங்கள் மின்னஞ்சல் அறிவிப்பு விருப்பங்களை சேமிப்பதில் ஏதோ பிழை ஏற்பட்டுள்ளது.", + "Cancel": "ரத்து", + "Cancel Sending": "அனுப்புதலை ரத்து செய்", + "Changelog": "மாற்றப்பதிவு", + "Close": "மூடு", + "Collapse panel": "பலகத்தை மாற்று", + "Collecting app version information": "செயலியின் பதிப்பு தகவல்கள் சேகரிக்கப்படுகிறது", + "Collecting logs": "பதிவுகள் சேகரிக்கப்படுகிறது", + "Call invitation": "அழைப்பிற்கான விண்ணப்பம்", + "Can't update user notification settings": "பயனர் அறிவிப்பு அமைப்புகளை மாற்ற முடியவில்லை", + "Couldn't find a matching Matrix room": "பொருத்தமான Matrix அறை கிடைக்கவில்லை", + "Custom Server Options": "விருப்பிற்கேற்ற வழங்கி இடப்புகள்", + "delete the alias.": "மாற்றை அழி.", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "அறை மாற்று %(alias)s -ஐ அழித்து, %(name)s -ஐ அடைவிலிருந்து நீக்க வேண்டுமா?", + "Direct Chat": "நேரடி அரட்டை", + "Directory": "அடைவு", + "Dismiss": "நீக்கு", + "Download this file": "இந்த கோப்பைத் தரவிறக்கு", + "Enable audible notifications in web client": "இணைய வாங்கியில் ஒலி அறிவிப்புகளை ஏதுவாக்கு", + "Enable desktop notifications": "திரை அறிவிப்புகளை ஏதுவாக்கு", + "Enable email notifications": "மின்னஞ்சல் அறிவிப்புகளை ஏதுவாக்கு", + "Enable notifications for this account": "இந்த கணக்கிற்கான அறிவிப்புகளை ஏதுவாக்கு", + "Enable them now": "இப்போது அவற்றை ஏதுவாக்கு", + "Error": "கோளாறு", + "Expand panel": "பலகத்தை விரிவாக்கு", + "Failed to add tag %(tagName)s to room": "%(tagName)s எனும் குறிச்சொல்லை அறையில் சேர்ப்பதில் தோல்வி", + "Failed to change settings": "அமைப்புகள் மாற்றத்தில் தோல்வி", + "Failed to forget room %(errCode)s": "அறையை மறப்பதில் தோல்வி %(errCode)s", + "Failed to update keywords": "முக்கிய வார்த்தைகளை புதுப்பித்தலில் தோல்வி", + "Failed to get public room list": "பொது அறைப் பட்டியலை பெறுவதில் தோல்வி", + "Favourite": "விருப்பமான", + "Files": "கோப்புகள்", + "Filter room names": "அறை பெயர்களை வடிகட்டு", + "Forget": "மற", + "Guests can join": "விருந்தினர்கள் சேரலாம்", + "Hide panel": "பலகத்தை மறை", + "Invite to this room": "இந்த அறைக்கு அழை", + "Keywords": "முக்கிய வார்த்தைகள்", + "Leave": "வெளியேறு", + "Login": "உள்நுழை", + "Low Priority": "குறைந்த முன்னுரிமை", + "Members": "உறுப்பினர்கள்", + "Mentions only": "குறிப்பிடுகள் மட்டும்", + "#example": "#உதாரணமாக", + "Enter keywords separated by a comma:": "ஒரு comma மூலம் முக்கிய வார்த்தைகளை உள்ளிடவும்:", + "Error saving email notification preferences": "மின்னஞ்சல் அறிவிப்பு விருப்பங்களை சேமிப்பதில் கோளாறு", + "Failed to get protocol list from Home Server": "முகப்பு சேவையகத்திலிருந்து நெறிமுறை பட்டியலைப் பெறுவதில் தோல்வி", + "Failed to remove tag %(tagName)s from room": "அறையில் இருந்து குறிச்சொல் %(tagName)s களை அகற்றுவது தோல்வியடைந்தது", + "Failed to set direct chat tag": "நேரடி அரட்டை குறியை அமைப்பதில் தோல்வி", + "Failed to set Direct Message status of room": "அறையின் நேரடி செய்தி நிலையை அமைக்க தவறிவிட்டது", + "Fetching third party location failed": "மூன்றாம் இடத்தில் உள்ள இடம் தோல்வி", + "Forward Message": "முன்னோடி செய்தி", + "(HTTP status %(httpStatus)s)": "(HTTP நிலைகள் %(httpStatus)s)", + "I understand the risks and wish to continue": "நான் அபாயங்களைப் புரிந்துகொண்டு தொடர விரும்புகிறேன்", + "Messages containing my display name": "என் காட்சி பெயர் கொண்ட செய்திகள்", + "more": "அதிகம்", + "Mute": "முடக்கு", + "No rooms to show": "காண்பிக்க எந்த அறையும் இல்லை", + "Messages containing keywords": "முக்கிய கொண்ட செய்திகள்", + "Messages containing my user name": "என் பயனர் பெயர் கொண்ட செய்திகள்", + "Messages in group chats": "குழு அரட்டைகளில் உள்ள செய்திகள்", + "Messages in one-to-one chats": "ஒரு-க்கு-ஒரு அரட்டைகளில் உள்ள செய்திகள்", + "Messages sent by bot": "bot மூலம் அனுப்பிய செய்திகள்", + "Noisy": "சத்தம்", + "Notification targets": "அறிவிப்பு இலக்குகள்", + "Notifications": "அறிவிப்புகள்", + "Notifications on the following keywords follow rules which can’t be displayed here:": "பின்வரும் முக்கிய வார்த்தைகளில் அறிவிப்புகள் இங்கே காட்டப்பட முடியாத விதிகள் பின்பற்றப்படுகின்றன:", + "Notify for all other messages/rooms": "மற்ற எல்லா செய்திகளுக்கும் அறைகளுக்கும் தெரிவிக்கவும்", + "Notify me for anything else": "வேறு எதையும் எனக்கு தெரிவி", + "Off": "அமை", + "On": "மீது", + "Operation failed": "செயல்பாடு தோல்வியுற்றது", + "Permalink": "நிரந்தரத் தொடுப்பு", + "powered by Matrix": "Matrix-ஆல் ஆனது", + "Quote": "மேற்கோள்", + "Reject": "நிராகரி", + "Remove %(name)s from the directory?": "அடைவிலிருந்து %(name)s-ஐ நீக்கலாமா?", + "Remove": "நீக்கு", + "remove %(name)s from the directory.": "அடைவிலிருந்து %(name)s-ஐ நீக்கு.", + "Remove from Directory": "அடைவிலிருந்து நீக்கு", + "Resend": "மீண்டும் அனுப்பு", + "Room not found": "அறை காணவில்லை", + "Search": "தேடு", + "Search…": "தேடு…", + "Search for a room": "அறையைத் தேடு", + "Send": "அனுப்பு", + "Send logs": "பதிவுகளை அனுப்பு", + "Source URL": "மூல முகவரி", + "This Room": "இந்த அறை", + "Unable to join network": "முனையங்களில் சேர இயலவில்லை", + "Unavailable": "இல்லை", + "unknown error code": "தெரியாத பிழை குறி", + "Unnamed room": "பெயரிடப்படாத அறை", + "Update": "புதுப்பி", + "Uploaded on %(date)s by %(user)s": "%(date)s அன்று %(user)s ஆல் பதிவேற்றப்பட்டது", + "Uploading report": "அறிக்கை பதிவேற்றப்படுகிறது", + "Riot does not know how to join a room on this network": "இந்த வலையமைப்பில் உள்ள அறையில் எப்படி சேர்வதென்று Riotற்க்கு தெரியவில்லை", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot பல மேம்பட்ட உலாவி வசதிகளைப் பயன்படுத்துகிறது, அதில் சிலவற்றைக் காணவில்லை அல்லது உங்கள் உலாவியில் பரிசோதனைக்காக உள்ளது.", + "There are advanced notifications which are not shown here": "இங்கு காண்பிக்கப்படாத மேம்பட்ட அறிவிப்புகள் உள்ளது", + "The server may be unavailable or overloaded": "வழங்கி அளவுமீறிய சுமையில் உள்ளது அல்லது செயல்பாட்டில் இல்லை", + "Unable to fetch notification target list": "அறிவிப்பு பட்டியலை பெற முடியவில்லை", + "Unable to look up room ID from server": "வழங்கியிலிருந்து அறை ID யை காண முடியவில்லை", + "Unhide Preview": "முன்னோட்டத்தைக் காண்பி", + "View Decrypted Source": "மறையீடு நீக்கப்பட்ட மூலத்தைக் காண்பி", + "View Source": "மூலத்தைக் காட்டு", + "What's New": "புதிதாக வந்தவை", + "What's new?": "புதிதாக என்ன?", + "Waiting for response from server": "வழங்கியின் பதிலுக்காக காத்திருக்கிறது", + "When I'm invited to a room": "நான் அறைக்கு அழைக்கப்பட்ட போது", + "World readable": "உலகமே படிக்கும்படி", + "You cannot delete this image. (%(code)s)": "இந்த படத்தை நீங்கள் அழிக்க முடியாது. (%(code)s)", + "You cannot delete this message. (%(code)s)": "இந்த செய்தியை நீங்கள் அழிக்க முடியாது. (%(code)s)", + "You are not receiving desktop notifications": "திரை அறிவிப்புகளை நீங்கள் பெறவில்லை", + "Bug report sent": "வழு அறிக்கை அனுப்பப்பட்டது", + "OK": "சரி", + "Show message in desktop notification": "திரை அறிவிப்புகளில் செய்தியை காண்பிக்கவும்", + "Sunday": "ஞாயிறு", + "Monday": "திங்கள்", + "Tuesday": "செவ்வாய்", + "Wednesday": "புதன்", + "Thursday": "வியாழன்", + "Friday": "வெள்ளி", + "Saturday": "சனி", + "Today": "இன்று", + "Yesterday": "நேற்று", + "No update available.": "எந்த புதுப்பிப்பும் இல்லை.", + "Warning": "எச்சரிக்கை", + "Thank you!": "உங்களுக்கு நன்றி", + "Back": "பின்", + "Event sent!": "நிகழ்வு அனுப்பப்பட்டது", + "Event Type": "நிகழ்வு வகை", + "Event Content": "நிகழ்வு உள்ளடக்கம்", + "Edit": "தொகு", + "You have successfully set a password!": "நீங்கள் வெற்றிகரமாக கடவுச்சொல்லை அமைத்துவிட்டீர்கள்", + "You have successfully set a password and an email address!": "நீங்கள் வெற்றிகரமாக கடவுச்சொல் மற்றும் மின்னஞ்சல் முகவரியை அமைத்துவிட்டீர்கள்", + "Continue": "தொடரவும்", + "Please set a password!": "தயவு செய்து கடவுச்சொல்லை அமைக்கவும்", + "Couldn't load home page": "முதற்பக்கத்தை நிரலேற்ற முடியவில்லை", + "Register": "பதிவு செய்", + "Rooms": "அறைகள்", + "Add rooms to this community": "அறைகளை இந்த சமூகத்தில் சேர்க்கவும்" +} From ce809e16d91617a202452eb8727e24c00f6a9f44 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 17 Apr 2018 16:51:17 +0100 Subject: [PATCH 0795/1160] fix i18n thinko on createTrackedDialog --- src/components/views/dialogs/BugReportDialog.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/views/dialogs/BugReportDialog.js b/src/components/views/dialogs/BugReportDialog.js index 086cb98cde..2025b6fc81 100644 --- a/src/components/views/dialogs/BugReportDialog.js +++ b/src/components/views/dialogs/BugReportDialog.js @@ -65,7 +65,8 @@ export default class BugReportDialog extends React.Component { if (!this._unmounted) { this.props.onFinished(false); const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - Modal.createTrackedDialog(_t('Bug report sent'), '', QuestionDialog, { + // N.B. first param is passed to piwik and so doesn't want i18n + Modal.createTrackedDialog('Bug report sent', '', QuestionDialog, { title: _t('Logs sent'), description: _t('Thank you!'), hasCancelButton: false, From d91c7f5e541f59134a98655df132915f05da0286 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 17 Apr 2018 16:53:11 +0100 Subject: [PATCH 0796/1160] Add comment about enum hijinks --- src/components/views/globals/UpdateCheckBar.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/views/globals/UpdateCheckBar.js b/src/components/views/globals/UpdateCheckBar.js index db01746340..53801311d8 100644 --- a/src/components/views/globals/UpdateCheckBar.js +++ b/src/components/views/globals/UpdateCheckBar.js @@ -23,7 +23,7 @@ import AccessibleButton from '../../../components/views/elements/AccessibleButto export default React.createClass({ propTypes: { - status: React.PropTypes.string, // oneOf(Object.values(updateCheckStatusEnum)).isRequired, + status: React.PropTypes.string.isRequired, // Currently for error detail but will be usable for download progress // once that is a thing that squirrel passes through electron. detail: React.PropTypes.string, @@ -36,6 +36,8 @@ export default React.createClass({ }, getStatusText: function() { + // we can't import the enum from riot-web as we don't want matrix-react-sdk + // to depend on riot-web. so we grab it as a normal object via API instead. const updateCheckStatusEnum = PlatformPeg.get().getUpdateCheckStatusEnum(); switch(this.props.status) { case updateCheckStatusEnum.ERROR: From 7b53e3669846e660a9a8d42cd84803fe4678b0ad Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 17 Apr 2018 16:55:32 +0100 Subject: [PATCH 0797/1160] retheming commentary --- res/css/rethemendex.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/res/css/rethemendex.sh b/res/css/rethemendex.sh index f2e60a1e46..13be73f9a9 100755 --- a/res/css/rethemendex.sh +++ b/res/css/rethemendex.sh @@ -5,6 +5,9 @@ cd `dirname $0` { echo "// autogenerated by rethemendex.sh" + # we used to have exclude /themes from the find at this point. + # as themes are no longer a spurious subdirectory of css/, we don't + # need it any more. find . -iname _\*.scss | fgrep -v _components.scss | LC_ALL=C sort | while read i; do echo "@import \"$i\";" From 6d1563449d2b8105c19b9755b45c792f50d2d7b1 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 17 Apr 2018 16:57:08 +0100 Subject: [PATCH 0798/1160] fix missing NLs --- res/themes/dark/css/dark.scss | 3 ++- res/themes/light/css/light.scss | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/res/themes/dark/css/dark.scss b/res/themes/dark/css/dark.scss index f7e78c86c3..b69f096db7 100644 --- a/res/themes/dark/css/dark.scss +++ b/res/themes/dark/css/dark.scss @@ -1,3 +1,4 @@ @import "../../light/css/_base.scss"; @import "_dark.scss"; -@import "../../../../res/css/_components.scss"; \ No newline at end of file +@import "../../../../res/css/_components.scss"; + diff --git a/res/themes/light/css/light.scss b/res/themes/light/css/light.scss index e2c553f30d..2099f41f60 100644 --- a/res/themes/light/css/light.scss +++ b/res/themes/light/css/light.scss @@ -1,2 +1,3 @@ @import "_base.scss"; -@import "../../../../res/css/_components.scss"; \ No newline at end of file +@import "../../../../res/css/_components.scss"; + From f84573ec9fbd1f1b250114aa1ffbaccbd7a412b5 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Wed, 18 Apr 2018 10:23:32 +0100 Subject: [PATCH 0799/1160] convert HomePage to ES6 and split out the vectory bit --- src/components/structures/HomePage.js | 46 +++++++++++++-------------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/src/components/structures/HomePage.js b/src/components/structures/HomePage.js index 27a0b6bf49..5df58305e6 100644 --- a/src/components/structures/HomePage.js +++ b/src/components/structures/HomePage.js @@ -18,40 +18,36 @@ limitations under the License. 'use strict'; import React from 'react'; +import PropTypes from 'prop-types'; import request from 'browser-request'; import { _t } from '../../languageHandler'; import sanitizeHtml from 'sanitize-html'; import sdk from '../../index'; -module.exports = React.createClass({ - displayName: 'HomePage', +class HomePage extends React.Component { + displayName = 'HomePage'; - propTypes: { + static propTypes = { // URL base of the team server. Optional. - teamServerUrl: React.PropTypes.string, + teamServerUrl: PropTypes.string, // Team token. Optional. If set, used to get the static homepage of the team // associated. If unset, homePageUrl will be used. - teamToken: React.PropTypes.string, + teamToken: PropTypes.string, // URL to use as the iFrame src. Defaults to /home.html. - homePageUrl: React.PropTypes.string, - }, + homePageUrl: PropTypes.string, + }; - getInitialState: function() { - return { + state = { iframeSrc: '', page: '', - }; - }, + }; - translate: function(s) { - s = sanitizeHtml(_t(s)); - // ugly fix for https://github.com/vector-im/riot-web/issues/4243 - s = s.replace(/Riot\.im/, 'Riot.im'); - s = s.replace(/\[matrix\]/, '[matrix]'); - return s; - }, + translate(s) { + // default implementation - skins may wish to extend this + return sanitizeHtml(_t(s)); + } - componentWillMount: function() { + componentWillMount() { this._unmounted = false; if (this.props.teamToken && this.props.teamServerUrl) { @@ -84,13 +80,13 @@ module.exports = React.createClass({ } ); } - }, + } - componentWillUnmount: function() { + componentWillUnmount() { this._unmounted = true; - }, + } - render: function() { + render() { if (this.state.iframeSrc) { return (
    @@ -108,4 +104,6 @@ module.exports = React.createClass({ ); } } -}); +} + +module.exports = HomePage; \ No newline at end of file From 0571c596e3f0695da275ffb899ae802bf52b4f33 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Wed, 18 Apr 2018 10:53:01 +0100 Subject: [PATCH 0800/1160] move deps from vector-web to sdk; resolve version mismatches... --- package.json | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 9ca8a293cd..77338b4874 100644 --- a/package.json +++ b/package.json @@ -67,19 +67,22 @@ "flux": "2.1.1", "focus-trap-react": "^3.0.5", "fuse.js": "^2.2.0", + "gemini-scrollbar": "matrix-org/gemini-scrollbar#b302279", + "gfm.css": "^1.1.1", "glob": "^5.0.14", - "highlight.js": "^8.9.1", + "highlight.js": "^9.0.0", "isomorphic-fetch": "^2.2.1", "linkifyjs": "^2.1.3", "lodash": "^4.13.1", "matrix-js-sdk": "0.10.1", "optimist": "^0.6.1", + "pako": "^1.0.5", "prop-types": "^15.5.8", "querystring": "^0.2.0", - "react": "^15.4.0", + "react": "^15.6.0", "react-addons-css-transition-group": "15.3.2", - "react-beautiful-dnd": "^4.0.0", - "react-dom": "^15.4.0", + "react-beautiful-dnd": "^4.0.1", + "react-dom": "^15.6.0", "react-gemini-scrollbar": "matrix-org/react-gemini-scrollbar#5e97aef", "sanitize-html": "^1.14.1", "text-encoding-utf-8": "^1.0.1", From 92c98aa3e514a0f5365242ef51eee3c33b05e6a6 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Wed, 18 Apr 2018 16:19:37 +0100 Subject: [PATCH 0801/1160] displayName should be tracked as static --- src/components/structures/HomePage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/HomePage.js b/src/components/structures/HomePage.js index 5df58305e6..457796f5dc 100644 --- a/src/components/structures/HomePage.js +++ b/src/components/structures/HomePage.js @@ -25,7 +25,7 @@ import sanitizeHtml from 'sanitize-html'; import sdk from '../../index'; class HomePage extends React.Component { - displayName = 'HomePage'; + static displayName = 'HomePage'; static propTypes = { // URL base of the team server. Optional. From 895521f0e849c1ba21a54af0a6f02f32845cf15a Mon Sep 17 00:00:00 2001 From: RainSlide Date: Wed, 18 Apr 2018 12:59:36 +0000 Subject: [PATCH 0802/1160] Translated using Weblate (Chinese (Simplified)) Currently translated at 90.8% (918 of 1011 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hans/ --- src/i18n/strings/zh_Hans.json | 108 ++++++++++++++++++++++++++++++++-- 1 file changed, 104 insertions(+), 4 deletions(-) diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index c03b463b02..3b49ac1658 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -194,7 +194,7 @@ "%(senderName)s changed their profile picture.": "%(senderName)s 修改了头像。", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s 将聊天室名称改为 %(roomName)s。", "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s 移除了聊天室名称。", - "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s 把话题修改为 “%(topic)s”。", + "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s 将话题修改为 “%(topic)s”。", "Changes to who can read history will only apply to future messages in this room": "修改阅读历史的权限仅对此聊天室以后的消息有效", "Changes your display nickname": "修改昵称", "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "目前,修改密码会导致所有设备上的端到端密钥被重置,使得加密的聊天记录不再可读。除非你事先导出聊天室密钥,修改密码后再导入。这个问题未来会改善。", @@ -632,7 +632,7 @@ "You added a new device '%(displayName)s', which is requesting encryption keys.": "你添加了一个新的设备 '%(displayName)s',它正在请求加密密钥。", "Your unverified device '%(displayName)s' is requesting encryption keys.": "你的未验证的设备 '%(displayName)s' 正在请求加密密钥。", "Encryption key request": "加密密钥请求", - "Autocomplete Delay (ms):": "自动完成延迟(毫秒):", + "Autocomplete Delay (ms):": "自动补全延迟(毫秒):", "%(widgetName)s widget added by %(senderName)s": "%(widgetName)s 小组建被 %(senderName)s 添加", "%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s 小组建被 %(senderName)s 移除", "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s 小组建被 %(senderName)s 修改", @@ -817,9 +817,109 @@ "Opt out of analytics": "禁用开发数据上传", "Stickerpack": "贴图集", "Sticker Messages": "贴图消息", - "You don't currently have any stickerpacks enabled": "您目前没有启用任何贴图集", + "You don't currently have any stickerpacks enabled": "您目前没有启用任何贴纸包", "Click": "点击", "here": "这里", "to add some!": "以添加一些贴图集!", - "Add a stickerpack": "添加贴图集" + "Add a stickerpack": "添加贴图集", + "Your key share request has been sent - please check your other devices for key share requests.": "已请求共享密钥 - 请在您的其他设备上进行确认。", + "Key share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, click here to request the keys for this session again.": "密钥共享请求将会自动发送到您的其他设备上。如果您在其他设备上拒绝了请求,请点击此处以再次请求此会话的密钥。", + "If your other devices do not have the key for this message you will not be able to decrypt them.": "如果您的其他设备上没有此消息的密钥,您将依然无法解密。", + "Key request sent.": "已请求共享密钥。", + "Re-request encryption keys from your other devices.": "在您的其他设备上 重新请求加密密钥。", + "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "如果您是房间中最后一位有权限的用户,在您降低自己的权限等级后将无法撤回此修改,因为你将无法重新获得权限。", + "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "你将无法撤回此修改,因为您正在将此用户的权限提升至和你相同的级别。", + "No devices with registered encryption keys": "没有设备有已注册的加密密钥", + "Unmute": "取消静音", + "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s(权限级别 %(powerLevelNumber)s)", + "Hide Stickers": "隐藏贴图", + "Show Stickers": "显示贴图", + "%(duration)ss": "%(duration)s 秒", + "%(duration)sm": "%(duration)s 分钟", + "%(duration)sh": "%(duration)s 小时", + "%(duration)sd": "%(duration)s 天", + "Online for %(duration)s": "已上线 %(duration)s", + "Idle for %(duration)s": "已 idle %(duration)s", + "Offline for %(duration)s": "已离线 %(duration)s", + "Unknown for %(duration)s": "在线状态未知 %(duration)s", + "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "%(displayName)s (%(userName)s) 在 %(dateTime)s 看到这里", + "Remove avatar": "移除头像", + "Drop here to favourite": "拖动到这里以加入收藏", + "Drop here to tag direct chat": "拖动到这里以加入私聊", + "Drop here to restore": "拖动到这里以还原", + "Drop here to demote": "拖动到这里以加入低优先级", + "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "无法确定此邀请发送给的邮件地址是否和与您的帐户相关的邮件地址相匹配。", + "You have been kicked from this room by %(userName)s.": "您已被 %(userName)s 从此聊天室中移除。", + "'%(groupId)s' is not a valid community ID": "“%(groupId)s” 不是有效的社区 ID", + "Flair": "Flair", + "Message removed by %(userId)s": "此消息已被 %(userId)s 移除", + "Sign in with CAS": "使用 CAS 登录", + "Code": "代码", + "%(serverName)s Matrix ID": "%(serverName)s Matrix ID", + "You are registering with %(SelectedTeamName)s": "你将注册为 %(SelectedTeamName)s", + "Remove from community": "从社区中移除", + "Disinvite this user from community?": "是否要取消邀请此用户加入社区?", + "Remove this user from community?": "是否要从社区中移除此用户?", + "Failed to withdraw invitation": "撤回邀请失败", + "Failed to remove user from community": "移除用户失败", + "Filter community members": "过滤社区成员", + "Flair will not appear": "将不会显示 Flair", + "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "你确定要从 %(groupId)s 中删除1吗?", + "Removing a room from the community will also remove it from the community page.": "从社区中移除房间时,同时也会将其从社区页面中移除。", + "Failed to remove room from community": "从社区中移除聊天室失败", + "Failed to remove '%(roomName)s' from %(groupId)s": "从 %(groupId)s 中移除 “%(roomName)s” 失败", + "Only visible to community members": "仅对社区成员可见", + "Filter community rooms": "过滤社区聊天室", + "Manage sticker packs": "管理贴纸包", + "You're not currently a member of any communities.": "您目前不是任何一个社区的成员。", + "Communities": "社区", + "%(nameList)s %(transitionList)s": "%(nameList)s %(transitionList)s", + "%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)s 已加入 %(count)s 次", + "%(severalUsers)sjoined %(count)s times|one": "%(severalUsers)s 已加入", + "%(oneUser)sjoined %(count)s times|other": "%(oneUser)s 已加入 %(count)s 次", + "%(oneUser)sjoined %(count)s times|one": "%(oneUser)s 已加入", + "%(severalUsers)sleft %(count)s times|other": "%(severalUsers)s 已离开 %(count)s 次", + "%(severalUsers)sleft %(count)s times|one": "%(severalUsers)s 已离开", + "%(oneUser)sleft %(count)s times|other": "%(oneUser)s 已离开 %(count)s 次", + "%(oneUser)sleft %(count)s times|one": "%(oneUser)s 已离开", + "%(severalUsers)sjoined and left %(count)s times|other": "%(severalUsers)s 已加入&已离开 %(count)s 次", + "%(severalUsers)sjoined and left %(count)s times|one": "%(severalUsers)s 已加入&已离开", + "%(oneUser)sjoined and left %(count)s times|other": "%(oneUser)s 已加入&已离开 %(count)s 次", + "%(oneUser)sjoined and left %(count)s times|one": "%(oneUser)s 已加入&已离开", + "%(severalUsers)sleft and rejoined %(count)s times|other": "%(severalUsers)s 离开并重新加入了 %(count)s 次", + "%(severalUsers)sleft and rejoined %(count)s times|one": "%(severalUsers)s 离开并重新加入了", + "%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)s 离开并重新加入了 %(count)s 次", + "%(oneUser)sleft and rejoined %(count)s times|one": "%(oneUser)s 离开并重新加入了", + "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)s 拒绝了他们的邀请", + "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)s 拒绝了他们的邀请共 %(count)s 次", + "%(oneUser)srejected their invitation %(count)s times|other": "%(oneUser)s 拒绝了他们的邀请共 %(count)s 次", + "%(oneUser)srejected their invitation %(count)s times|one": "%(oneUser)s 拒绝了他们的邀请", + "%(severalUsers)shad their invitations withdrawn %(count)s times|other": "%(severalUsers)s 撤回了他们的邀请共 %(count)s 次", + "%(severalUsers)shad their invitations withdrawn %(count)s times|one": "%(severalUsers)s 撤回了他们的邀请", + "%(oneUser)shad their invitation withdrawn %(count)s times|other": "%(oneUser)s 撤回了他们的邀请共 %(count)s 次", + "%(oneUser)shad their invitation withdrawn %(count)s times|one": "%(oneUser)s 撤回了他们的邀请", + "Custom of %(powerLevel)s": "", + "In reply to ": "回复给 ", + "Community IDs cannot not be empty.": "社区 ID 不能为空。", + "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "社区 ID 只能包含 a-z、0-9 或 “=_-./” 等字符", + "Something went wrong whilst creating your community": "创建社区时出现问题", + "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "您目前默认将未验证的设备列入黑名单;在发送消息到这些设备上之前,您必须先验证它们。", + "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "如果您之前使用过较新版本的 Riot,则您的会话可能与当前版本不兼容。请关闭此窗口并使用最新版本。", + "Presence Management": "在线状态管理", + "To change the room's avatar, you must be a": "无法修改此聊天室的头像,因为您不是此聊天室的", + "To change the room's name, you must be a": "无法修改此聊天室的名称,因为您不是此聊天室的", + "To change the room's main address, you must be a": "无法修改此聊天室的主地址,因为您不是此聊天室的", + "To change the room's history visibility, you must be a": "无法修改此聊天室的历史聊天记录可见性,因为您不是此聊天室的", + "To change the permissions in the room, you must be a": "无法修改此聊天室中的权限情况,因为您不是此聊天室的", + "Showing flair for these communities:": "为这些社区显示 flair:", + "This room is not showing flair for any communities": "此聊天室没有对任何社区显示 flair", + "New community ID (e.g. +foo:%(localDomain)s)": "新社区 ID(例子:+foo:%(localDomain)s)", + "URL previews are enabled by default for participants in this room.": "此聊天室默认启用链接预览。", + "URL previews are disabled by default for participants in this room.": "此聊天室默认禁用链接预览。", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s 将聊天室的头像更改为 ", + "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "您也可以自定义身份验证服务器,但这通常会阻止基于电子邮件地址的与用户的交互。", + "Please enter the code it contains:": "请输入它包含的代码:", + "Flair will appear if enabled in room settings": "如果在聊天室设置中启用, flair 将会显示", + "Matrix ID": "Matrix ID", + "Matrix Room ID": "Matrix 聊天室 ID" } From 249edb7b769ddb5667ad4f64ea5cac996815ec1c Mon Sep 17 00:00:00 2001 From: Xose M Date: Sun, 15 Apr 2018 19:15:39 +0000 Subject: [PATCH 0803/1160] Translated using Weblate (Galician) Currently translated at 100.0% (1011 of 1011 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/gl/ --- src/i18n/strings/gl.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/gl.json b/src/i18n/strings/gl.json index 8151f253b6..f1f541d850 100644 --- a/src/i18n/strings/gl.json +++ b/src/i18n/strings/gl.json @@ -236,7 +236,7 @@ "Enable Notifications": "Habilitar notificacións", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(day)s %(monthName)s %(fullYear)s", "Message Replies": "Respostas a mensaxe", - "Mirror local video feed": "Espellar fonte de vídeo local", + "Mirror local video feed": "Copiar fonte de vídeo local", "Opt out of analytics": "Saírse de analytics", "Cannot add any more widgets": "Non pode engadir máis widgets", "The maximum permitted number of widgets have already been added to this room.": "Xa se engadeu o número máximo de widgets a esta sala.", From 8fc7cc4075cb5655dc833dc9f8cbde5edaaaa65b Mon Sep 17 00:00:00 2001 From: random Date: Mon, 16 Apr 2018 08:37:06 +0000 Subject: [PATCH 0804/1160] Translated using Weblate (Italian) Currently translated at 99.5% (1006 of 1011 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/it/ --- src/i18n/strings/it.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/it.json b/src/i18n/strings/it.json index 84b6a357e2..b918dce1ee 100644 --- a/src/i18n/strings/it.json +++ b/src/i18n/strings/it.json @@ -1005,5 +1005,7 @@ "Leave this community": "Esci da questa comunità", "Sticker Messages": "Messaggi adesivi", "You don't currently have any stickerpacks enabled": "Non hai ancora alcun pacchetto di adesivi attivato", - "Add a stickerpack": "Aggiungi un pacchetto di adesivi" + "Add a stickerpack": "Aggiungi un pacchetto di adesivi", + "Who can join this community?": "Chi può unirsi a questa comunità?", + "Everyone": "Tutti" } From 7700df4c2dc651bd6532bb830c23ff75ade1dc29 Mon Sep 17 00:00:00 2001 From: toriko Date: Tue, 17 Apr 2018 08:09:26 +0000 Subject: [PATCH 0805/1160] Translated using Weblate (Japanese) Currently translated at 7.4% (75 of 1011 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ja/ --- src/i18n/strings/ja.json | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ja.json b/src/i18n/strings/ja.json index 032dacd1aa..b4445af879 100644 --- a/src/i18n/strings/ja.json +++ b/src/i18n/strings/ja.json @@ -54,5 +54,24 @@ "Camera": "カメラ", "Are you sure?": "本当によろしいですか?", "OK": "OK", - "Operation failed": "操作に失敗しました" + "Operation failed": "操作に失敗しました", + "Custom Server Options": "カスタムサーバのオプション", + "Dismiss": "やめる", + "powered by Matrix": "Matrixによって動作しています", + "Error": "エラー", + "Remove": "取り除く", + "Submit debug logs": "デバッグログを送信する", + "Edit": "編集", + "Continue": "続ける", + "Unpin Message": "メッセージの固定を外す", + "Online": "オンライン", + "unknown error code": "不明なエラーコード", + "Failed to forget room %(errCode)s": "部屋の記憶を消すのに失敗しました %(errCode)s", + "Register": "登録", + "Rooms": "部屋", + "Add rooms to this community": "このコミュニティに部屋を追加する", + "Unnamed room": "名前のない部屋", + "World readable": "誰でも読むことができます", + "Guests can join": "ゲストが参加できます", + "No rooms to show": "表示する部屋がありません" } From 7934c50407ac8347fd432ea632df32f0a63306c7 Mon Sep 17 00:00:00 2001 From: Walter Date: Mon, 16 Apr 2018 20:41:50 +0000 Subject: [PATCH 0806/1160] Translated using Weblate (Russian) Currently translated at 99.9% (1010 of 1011 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index d732be55da..854b85cf23 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -958,7 +958,7 @@ "Send a reply (unencrypted)…": "Отправить ответ (незашифрованный)…", "Send an encrypted message…": "Отправить зашифрованное сообщение…", "Send a message (unencrypted)…": "Отправить сообщение (незашифрованное)…", - "Replying": "Отвечая", + "Replying": "Отвечает", "Minimize apps": "Свернуть приложения", "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Конфиденциальность важна для нас, поэтому мы не собираем никаких личных или идентифицируемых данных для нашей аналитики.", "Learn more about how we use analytics.": "Подробнее о том, как мы используем аналитику.", @@ -1008,5 +1008,11 @@ "to add some!": "для добавления!", "Click": "Нажмите", "Who can join this community?": "Кто может присоединиться к этому сообществу?", - "Everyone": "Все" + "Everyone": "Все", + "Stickerpack": "Этикетки", + "Sticker Messages": "Сообщения этикеткой", + "Add a stickerpack": "Добавить этикетки", + "Hide Stickers": "Скрыть этикетки", + "Show Stickers": "Показать этикетки", + "Manage sticker packs": "Упорядочить этикетки" } From b0eb350c41b4f75666f9dc284f469aca1724653f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Tue, 17 Apr 2018 14:13:42 +0000 Subject: [PATCH 0807/1160] Translated using Weblate (Slovak) Currently translated at 100.0% (1011 of 1011 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sk/ --- src/i18n/strings/sk.json | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index 5682c1008e..6baadea1a6 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -296,15 +296,15 @@ "Seen by %(userName)s at %(dateTime)s": "%(userName)s videl %(dateTime)s", "Unnamed room": "Nepomenovaná miestnosť", "World readable": "Viditeľné pre každého", - "Guests can join": "Aj hostia môžu vstúpiť", + "Guests can join": "Môžu vstúpiť aj hostia", "No rooms to show": "Žiadne miestnosti na zobrazenie", - "Failed to set avatar.": "Nepodarilo sa nastaviť avatara.", + "Failed to set avatar.": "Nepodarilo sa nastaviť obrázok.", "Save": "Uložiť", "(~%(count)s results)|other": "(~%(count)s výsledkov)", "(~%(count)s results)|one": "(~%(count)s výsledok)", "Join Room": "Vstúpiť do miestnosti", - "Upload avatar": "Nahrať avatara", - "Remove avatar": "Odstrániť avatara", + "Upload avatar": "Nahrať obrázok", + "Remove avatar": "Odstrániť obrázok", "Settings": "Nastavenia", "Forget room": "Zabudnúť miestnosť", "Search": "Hľadať", @@ -341,7 +341,7 @@ "You are trying to access a room.": "Pristupujete k miestnosti.", "Click here to join the discussion!": "Kliknutím sem vstúpite do diskusie!", "This is a preview of this room. Room interactions have been disabled": "Toto je náhľad na miestnosť. Všetky akcie pre túto miestnosť sú zakázané", - "To change the room's avatar, you must be a": "Aby ste mohli meniť avatara miestnosti, musíte byť", + "To change the room's avatar, you must be a": "Aby ste mohli meniť obrázok miestnosti, musíte byť", "To change the room's name, you must be a": "Aby ste mohli meniť názov miestnosti, musíte byť", "To change the room's main address, you must be a": "Aby ste mohli meniť hlavnú adresu miestnosti, musíte byť", "To change the room's history visibility, you must be a": "Aby ste mohli meniť viditeľnosť histórie miestnosti, musíte byť", @@ -428,9 +428,9 @@ "Image '%(Body)s' cannot be displayed.": "Nie je možné zobraziť obrázok '%(Body)s'.", "This image cannot be displayed.": "Tento obrázok nie je možné zobraziť.", "Error decrypting video": "Chyba pri dešifrovaní videa", - "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s zmenil avatara pre %(roomName)s", - "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s z miestnosti odstránil avatara.", - "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s zmenil avatara miestnosti na ", + "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s zmenil obrázok miestnosti %(roomName)s", + "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s odstránil obrázok miestnosti.", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s zmenil obrázok miestnosti ", "Copied!": "Skopírované!", "Failed to copy": "Nepodarilo sa skopírovať", "Add an Integration": "Pridať integráciu", @@ -553,10 +553,10 @@ "%(severalUsers)schanged their name %(count)s times|one": "%(severalUsers)ssi zmenili meno", "%(oneUser)schanged their name %(count)s times|other": "%(oneUser)ssi %(count)s krát zmenil meno", "%(oneUser)schanged their name %(count)s times|one": "%(oneUser)ssi zmenil meno", - "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)ssi %(count)s krát zmenili avatara", - "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)ssi zmenili avatara", - "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)ssi %(count)s krát zmenil avatara", - "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)ssi zmenil avatara", + "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)ssi %(count)s krát zmenili obrázok v profile", + "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)ssi zmenili obrázok v profile", + "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)ssi %(count)s krát zmenil obrázok v profile", + "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)ssi zmenil obrázok v profile", "%(items)s and %(count)s others|other": "%(items)s a %(count)s ďalší", "%(items)s and %(count)s others|one": "%(items)s a jeden ďalší", "%(items)s and %(lastItem)s": "%(items)s a tiež %(lastItem)s", @@ -837,9 +837,9 @@ "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "K domovskému serveru nie je možné pripojiť sa použitím protokolu HTTP keďže v adresnom riadku prehliadača máte HTTPS adresu. Použite protokol HTTPS alebo povolte nezabezpečené skripty.", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Nie je možné pripojiť sa k domovskému serveru - skontrolujte prosím funkčnosť vašeho pripojenia na internet, uistite sa že certifikát domovského servera je dôverihodný, a že žiaden doplnok nainštalovaný v prehliadači nemôže blokovať požiadavky.", "Login as guest": "Prihlásiť sa ako hosť", - "Failed to fetch avatar URL": "Nepodarilo sa získať URL adresu avatara", + "Failed to fetch avatar URL": "Nepodarilo sa získať URL adresu obrázka", "Set a display name:": "Nastaviť zobrazované meno:", - "Upload an avatar:": "Nahrať avatara:", + "Upload an avatar:": "Nahrať obrázok:", "This server does not support authentication with a phone number.": "Tento server nepodporuje overenie telefónnym číslom.", "Missing password.": "Chýba heslo.", "Passwords don't match.": "Heslá sa nezhodujú.", @@ -906,7 +906,7 @@ "Username on %(hs)s": "Meno používateľa na servery %(hs)s", "Restricted": "Obmedzené", "Presence Management": "Spravovanie prítomnosti", - "Hide avatar changes": "Skryť zmeny avatara", + "Hide avatar changes": "Skryť zmeny obrázka v profile", "Hide display name changes": "Skryť zmeny zobrazovaného mena", "Enable inline URL previews by default": "Predvolene povoliť náhľady URL adries", "Enable URL previews for this room (only affects you)": "Povoliť náhľady URL adries pre túto miestnosť (ovplyvňuje len vás)", @@ -993,11 +993,11 @@ "Code": "Kód", "Unable to join community": "Nie je možné vstúpiť do komunity", "Unable to leave community": "Nie je možné opustiť komunitu", - "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Zmeny vykonané vo vašej komunite name and avatar nemusia byť nasledujúcich 30 minút viditeľné všetkými používateľmi.", + "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Zmeny vykonané vo vašej komunite názov a obrázok nemusia byť nasledujúcich 30 minút viditeľné všetkými používateľmi.", "Join this community": "Vstúpiť do tejto komunity", "Leave this community": "Opustiť túto komunitu", "Did you know: you can use communities to filter your Riot.im experience!": "Vedeli ste: Že prácu s Riot.im si môžete spríjemníť použitím komunít!", - "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Ak si chcete nastaviť filter, pretiahnite avatara komunity na panel filtrovania úplne na ľavej strane obrazovky. Potom môžete kedykoľvek kliknúť na avatara komunity na tomto panely a Riot.im vám bude zobrazovať len miestnosti a ľudí z komunity, na ktorej avatar ste klikli.", + "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Ak si chcete nastaviť filter, pretiahnite obrázok komunity na panel filtrovania úplne na ľavej strane obrazovky. Potom môžete kedykoľvek kliknúť na obrázok komunity na tomto panely a Riot.im vám bude zobrazovať len miestnosti a ľudí z komunity, na ktorej obrázok ste klikli.", "Clear filter": "Zrušiť filter", "Debug Logs Submission": "Odoslanie ladiacich záznamov", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Ak ste nám poslali hlásenie o chybe cez Github, ladiace záznamy nám môžu pomôcť lepšie identifikovať chybu. Ladiace záznamy obsahujú údaje o používaní aplikácii, vrátane vašeho používateľského mena, názvy a aliasy miestností a komunít, ku ktorým ste sa pripojili a mená ostatných používateľov. Tieto záznamy neobsahujú samotný obsah vašich správ.", From ccd295bc00c1d0be6aff308d9ae01f187f604711 Mon Sep 17 00:00:00 2001 From: Val Date: Thu, 19 Apr 2018 22:07:45 +0000 Subject: [PATCH 0808/1160] Translated using Weblate (French) Currently translated at 100.0% (1011 of 1011 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 25cfc6cc82..e8dfc87fb3 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -93,8 +93,8 @@ "Current password": "Mot de passe actuel", "Curve25519 identity key": "Clé d’identité Curve25519", "/ddg is not a command": "/ddg n'est pas une commande", - "Deactivate Account": "Supprimer le compte", - "Deactivate my account": "Supprimer mon compte", + "Deactivate Account": "Désactiver le compte", + "Deactivate my account": "désactiver mon compte", "Decrypt %(text)s": "Déchiffrer %(text)s", "Decryption error": "Erreur de déchiffrement", "Delete": "Supprimer", From 06408f843b1b652ee1d28ddbeb23409cc1c915c6 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 20 Apr 2018 09:23:27 +0100 Subject: [PATCH 0809/1160] post BigMerge fixup - merge in stuff from riot-web PR Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- res/css/_components.scss | 4 +- .../{_Quote.scss => _ReplyThread.scss} | 12 +++-- res/css/views/rooms/_EventTile.scss | 39 ++++++-------- res/css/views/rooms/_QuotePreview.scss | 36 ------------- res/css/views/rooms/_ReplyPreview.scss | 52 +++++++++++++++++++ .../views/context_menus/MessageContextMenu.js | 26 ++++++++-- 6 files changed, 102 insertions(+), 67 deletions(-) rename res/css/views/elements/{_Quote.scss => _ReplyThread.scss} (74%) delete mode 100644 res/css/views/rooms/_QuotePreview.scss create mode 100644 res/css/views/rooms/_ReplyPreview.scss diff --git a/res/css/_components.scss b/res/css/_components.scss index 9770010324..50e8eb11d1 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -53,7 +53,7 @@ @import "./views/elements/_InlineSpinner.scss"; @import "./views/elements/_MemberEventListSummary.scss"; @import "./views/elements/_ProgressBar.scss"; -@import "./views/elements/_Quote.scss"; +@import "./views/elements/_ReplyThread.scss"; @import "./views/elements/_RichText.scss"; @import "./views/elements/_RoleButton.scss"; @import "./views/elements/_Spinner.scss"; @@ -89,7 +89,7 @@ @import "./views/rooms/_PinnedEventTile.scss"; @import "./views/rooms/_PinnedEventsPanel.scss"; @import "./views/rooms/_PresenceLabel.scss"; -@import "./views/rooms/_QuotePreview.scss"; +@import "./views/rooms/_ReplyPreview.scss"; @import "./views/rooms/_RoomDropTarget.scss"; @import "./views/rooms/_RoomHeader.scss"; @import "./views/rooms/_RoomList.scss"; diff --git a/res/css/views/elements/_Quote.scss b/res/css/views/elements/_ReplyThread.scss similarity index 74% rename from res/css/views/elements/_Quote.scss rename to res/css/views/elements/_ReplyThread.scss index 0af555b5aa..a02f42751c 100644 --- a/res/css/views/elements/_Quote.scss +++ b/res/css/views/elements/_ReplyThread.scss @@ -1,5 +1,5 @@ /* -Copyright 2017 Vector Creations Ltd +Copyright 2018 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. @@ -14,13 +14,19 @@ See the License for the specific language governing permissions and limitations under the License. */ -.mx_Quote .mx_DateSeparator { +.mx_ReplyThread .mx_DateSeparator { font-size: 1em !important; margin-bottom: 0; padding-bottom: 1px; bottom: -5px; } -.mx_Quote_show { +.mx_ReplyThread_show { cursor: pointer; } + +blockquote.mx_ReplyThread { + margin-left: 0; + padding-left: 10px; + border-left: 4px solid $blockquote-bar-color; +} diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index 4bb81a2e53..d721e1f7cd 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -84,7 +84,7 @@ limitations under the License. position: absolute; } -.mx_EventTile_line { +.mx_EventTile_line, .mx_EventTile_reply { position: relative; /* ideally should be 100px, but 95px gives us a max thumbnail size of 800x600, which is nice */ margin-right: 110px; @@ -96,7 +96,7 @@ limitations under the License. line-height: 22px; } -.mx_EventTile_quote { +.mx_EventTile_reply { margin-right: 10px; } @@ -119,7 +119,7 @@ limitations under the License. background-color: $event-selected-color; } -.mx_EventTile:hover .mx_EventTile_line:not(.mx_EventTile_quote), +..mx_EventTile:hover .mx_EventTile_line, .mx_EventTile.menu .mx_EventTile_line { background-color: $event-selected-color; @@ -157,7 +157,8 @@ limitations under the License. color: $event-notsent-color; } -.mx_EventTile_redacted .mx_EventTile_line .mx_UnknownBody { +.mx_EventTile_redacted .mx_EventTile_line .mx_UnknownBody, +.mx_EventTile_redacted .mx_EventTile_reply .mx_UnknownBody { display: block; width: 100%; height: 22px; @@ -202,10 +203,9 @@ limitations under the License. text-decoration: none; } -.mx_EventTile_last .mx_MessageTimestamp, -.mx_EventTile:hover .mx_MessageTimestamp, -.mx_EventTile.menu .mx_MessageTimestamp -{ +.mx_EventTile_last > div > a > .mx_MessageTimestamp, +.mx_EventTile:hover > div > a > .mx_MessageTimestamp, +.mx_EventTile.menu > div > a > .mx_MessageTimestamp { visibility: visible; } @@ -235,12 +235,7 @@ limitations under the License. } .mx_EventTile:hover .mx_EventTile_editButton, -.mx_EventTile.menu .mx_EventTile_editButton -{ - visibility: visible; -} - -.mx_EventTile.menu .mx_MessageTimestamp { +.mx_EventTile.menu .mx_EventTile_editButton { visibility: visible; } @@ -348,8 +343,8 @@ limitations under the License. border-left: $e2e-unverified-color 5px solid; } -.mx_EventTile:hover.mx_EventTile_verified .mx_MessageTimestamp, -.mx_EventTile:hover.mx_EventTile_unverified .mx_MessageTimestamp { +.mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_line > a > .mx_MessageTimestamp, +.mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_line > a > .mx_MessageTimestamp { left: 3px; width: auto; } @@ -360,8 +355,8 @@ limitations under the License. } */ -.mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_e2eIcon, -.mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_e2eIcon { +.mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_line > .mx_EventTile_e2eIcon, +.mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_line > .mx_EventTile_e2eIcon { display: block; left: 41px; } @@ -456,7 +451,7 @@ limitations under the License. // same as the padding for non-compact .mx_EventTile.mx_EventTile_info padding-top: 0px; font-size: 13px; - .mx_EventTile_line { + .mx_EventTile_line, .mx_EventTile_reply { line-height: 20px; } .mx_EventTile_avatar { @@ -474,7 +469,7 @@ limitations under the License. .mx_EventTile_avatar { top: 2px; } - .mx_EventTile_line { + .mx_EventTile_line, .mx_EventTile_reply { padding-top: 0px; padding-bottom: 1px; } @@ -482,13 +477,13 @@ limitations under the License. .mx_EventTile.mx_EventTile_emote.mx_EventTile_continuation { padding-top: 0; - .mx_EventTile_line { + .mx_EventTile_line, .mx_EventTile_reply { padding-top: 0px; padding-bottom: 0px; } } - .mx_EventTile_line { + .mx_EventTile_line, .mx_EventTile_reply { padding-top: 0px; padding-bottom: 0px; } diff --git a/res/css/views/rooms/_QuotePreview.scss b/res/css/views/rooms/_QuotePreview.scss deleted file mode 100644 index 86fd79d473..0000000000 --- a/res/css/views/rooms/_QuotePreview.scss +++ /dev/null @@ -1,36 +0,0 @@ -.mx_QuotePreview { - position: absolute; - bottom: 0; - z-index: 1000; - width: 100%; - border: 1px solid $primary-hairline-color; - background: $primary-bg-color; - border-bottom: none; - border-radius: 4px 4px 0 0; - max-height: 50vh; - overflow: auto -} - -.mx_QuotePreview_section { - border-bottom: 1px solid $primary-hairline-color; -} - -.mx_QuotePreview_header { - margin: 12px; - color: $primary-fg-color; - font-weight: 400; - opacity: 0.4; -} - -.mx_QuotePreview_title { - float: left; -} - -.mx_QuotePreview_cancel { - float: right; - cursor: pointer; -} - -.mx_QuotePreview_clear { - clear: both; -} diff --git a/res/css/views/rooms/_ReplyPreview.scss b/res/css/views/rooms/_ReplyPreview.scss new file mode 100644 index 0000000000..5bf4adff27 --- /dev/null +++ b/res/css/views/rooms/_ReplyPreview.scss @@ -0,0 +1,52 @@ +/* +Copyright 2018 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. +*/ + +.mx_ReplyPreview { + position: absolute; + bottom: 0; + z-index: 1000; + width: 100%; + border: 1px solid $primary-hairline-color; + background: $primary-bg-color; + border-bottom: none; + border-radius: 4px 4px 0 0; + max-height: 50vh; + overflow: auto +} + +.mx_ReplyPreview_section { + border-bottom: 1px solid $primary-hairline-color; +} + +.mx_ReplyPreview_header { + margin: 12px; + color: $primary-fg-color; + font-weight: 400; + opacity: 0.4; +} + +.mx_ReplyPreview_title { + float: left; +} + +.mx_ReplyPreview_cancel { + float: right; + cursor: pointer; +} + +.mx_ReplyPreview_clear { + clear: both; +} diff --git a/src/components/views/context_menus/MessageContextMenu.js b/src/components/views/context_menus/MessageContextMenu.js index 860d94ea0e..dc6f4d45d0 100644 --- a/src/components/views/context_menus/MessageContextMenu.js +++ b/src/components/views/context_menus/MessageContextMenu.js @@ -18,6 +18,7 @@ limitations under the License. 'use strict'; import React from 'react'; +import PropTypes from 'prop-types'; import MatrixClientPeg from '../../../MatrixClientPeg'; import dis from '../../../dispatcher'; @@ -34,13 +35,16 @@ module.exports = React.createClass({ propTypes: { /* the MatrixEvent associated with the context menu */ - mxEvent: React.PropTypes.object.isRequired, + mxEvent: PropTypes.object.isRequired, /* an optional EventTileOps implementation that can be used to unhide preview widgets */ - eventTileOps: React.PropTypes.object, + eventTileOps: PropTypes.object, + + /* an optional function which allows to collapse reply thread */ + collapseReplyThread: PropTypes.func, /* callback called when the menu is dismissed */ - onFinished: React.PropTypes.func, + onFinished: PropTypes.func, }, getInitialState: function() { @@ -182,12 +186,17 @@ module.exports = React.createClass({ onReplyClick: function() { dis.dispatch({ - action: 'quote_event', + action: 'reply_to_event', event: this.props.mxEvent, }); this.closeMenu(); }, + onCollapseReplyThreadClick: function() { + this.props.collapseReplyThread(); + this.closeMenu(); + }, + render: function() { const eventStatus = this.props.mxEvent.status; let resendButton; @@ -200,6 +209,7 @@ module.exports = React.createClass({ let externalURLButton; let quoteButton; let replyButton; + let collapseReplyThread; if (eventStatus === 'not_sent') { resendButton = ( @@ -305,6 +315,13 @@ module.exports = React.createClass({ ); } + if (this.props.collapseReplyThread) { + collapseReplyThread = ( +
    + { _t('Collapse Reply Thread') } +
    + ); + } return (
    @@ -320,6 +337,7 @@ module.exports = React.createClass({ { quoteButton } { replyButton } { externalURLButton } + { collapseReplyThread }
    ); }, From 563fc9adc767fd87da3333c926dcd8e13f10ee9b Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 20 Apr 2018 09:37:25 +0100 Subject: [PATCH 0810/1160] fix bad copy-paste from other diff Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- res/css/views/rooms/_EventTile.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index d721e1f7cd..9217a64040 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -119,7 +119,7 @@ limitations under the License. background-color: $event-selected-color; } -..mx_EventTile:hover .mx_EventTile_line, +.mx_EventTile:hover .mx_EventTile_line, .mx_EventTile.menu .mx_EventTile_line { background-color: $event-selected-color; From 7e8288f7ae12cc5c83843fcd07ef19378efef77c Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 20 Apr 2018 09:39:14 +0100 Subject: [PATCH 0811/1160] i18n-gen, i18n-prune Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/i18n/strings/ar.json | 1 - src/i18n/strings/bg.json | 4 ---- src/i18n/strings/ca.json | 4 ---- src/i18n/strings/cs.json | 4 ---- src/i18n/strings/da.json | 3 --- src/i18n/strings/de_DE.json | 4 ---- src/i18n/strings/en_EN.json | 6 +----- src/i18n/strings/eo.json | 4 ---- src/i18n/strings/es.json | 3 --- src/i18n/strings/eu.json | 4 ---- src/i18n/strings/fi.json | 5 ----- src/i18n/strings/fr.json | 4 ---- src/i18n/strings/gl.json | 4 ---- src/i18n/strings/he.json | 2 -- src/i18n/strings/hu.json | 4 ---- src/i18n/strings/id.json | 1 - src/i18n/strings/it.json | 4 ---- src/i18n/strings/ko.json | 2 -- src/i18n/strings/lt.json | 3 --- src/i18n/strings/lv.json | 4 ---- src/i18n/strings/ml.json | 1 - src/i18n/strings/nl.json | 4 ---- src/i18n/strings/pl.json | 3 --- src/i18n/strings/pt.json | 1 - src/i18n/strings/pt_BR.json | 4 ---- src/i18n/strings/ru.json | 4 ---- src/i18n/strings/sk.json | 4 ---- src/i18n/strings/sq.json | 2 -- src/i18n/strings/sr.json | 4 ---- src/i18n/strings/sv.json | 3 --- src/i18n/strings/ta.json | 1 - src/i18n/strings/uk.json | 3 --- src/i18n/strings/zh_Hans.json | 3 --- src/i18n/strings/zh_Hant.json | 4 ---- 34 files changed, 1 insertion(+), 110 deletions(-) diff --git a/src/i18n/strings/ar.json b/src/i18n/strings/ar.json index cb223f5aaf..d461240e4b 100644 --- a/src/i18n/strings/ar.json +++ b/src/i18n/strings/ar.json @@ -43,7 +43,6 @@ "Collecting logs": "تجميع السجلات", "No update available.": "لا يوجد هناك أي تحديث.", "An error occurred whilst saving your email notification preferences.": "حدث خطأ ما أثناء عملية حفظ إعدادات الإشعارات عبر البريد الإلكتروني.", - "Bug report sent": "تم إرسال تقرير الأخطاء", "Collecting app version information": "تجميع المعلومات حول نسخة التطبيق", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "إلغاء مُعرف الغرفة %(alias)s وحذف %(name)s من الدليل؟", "Changelog": "سِجل التغييرات", diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 55cc648535..ede5624d88 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -206,7 +206,6 @@ "Failed to join room": "Неуспешно присъединяване към стаята", "Message Replies": "Отговори на съобщението", "Message Pinning": "Функция за закачане на съобщения", - "Presence Management": "Управление на присъствието", "Disable Emoji suggestions while typing": "Изключване на предложенията за емотиконите при писане", "Use compact timeline layout": "Използване на компактно оформление за списъка със съобщения", "Hide removed messages": "Скриване на премахнати съобщения", @@ -1070,7 +1069,6 @@ "Preparing to send logs": "Подготовка за изпращане на логове", "Explore Account Data": "Преглед на данните от профила", "All messages (noisy)": "Всички съобщения (шумно)", - "Away": "Отсъстващ", "Saturday": "Събота", "Remember, you can always set an email address in user settings if you change your mind.": "Ако си промените мнението, винаги може да зададете имейл адрес в настройки на потребителя.", "Direct Chat": "Директен чат", @@ -1107,7 +1105,6 @@ "Notify for all other messages/rooms": "Извести ме за всички други съобщения/стаи", "Unable to look up room ID from server": "Стая с такъв идентификатор не е намерена на сървъра", "Couldn't find a matching Matrix room": "Не успяхме да намерим съответната Matrix стая", - "Bug report sent": "Докладът за грешки е изпратен", "Invite to this room": "Покани в тази стая", "You cannot delete this message. (%(code)s)": "Това съобщение не може да бъде изтрито. (%(code)s)", "Thursday": "Четвъртък", @@ -1128,7 +1125,6 @@ "Low Priority": "Нисък приоритет", "What's New": "Какво ново", "Set Password": "Задаване на парола", - "Appear Offline": "Показване като офлайн", "An error occurred whilst saving your email notification preferences.": "Възникна грешка при запазване на настройките за имейл известяване.", "Enable audible notifications in web client": "Включване на звукови известия в уеб клиент", "Permalink": "Permalink", diff --git a/src/i18n/strings/ca.json b/src/i18n/strings/ca.json index d85b88ddf1..f2cb1c713b 100644 --- a/src/i18n/strings/ca.json +++ b/src/i18n/strings/ca.json @@ -213,7 +213,6 @@ "Failed to join room": "No s'ha pogut entrar a la sala", "Message Replies": "Respostes del missatge", "Message Pinning": "Fixació de missatges", - "Presence Management": "Gestió de presència", "Disable Emoji suggestions while typing": "Desactiva els suggeriments d'Emoji mentre s'escriu", "Use compact timeline layout": "Utilitza el disseny compacte de la línia de temps", "Hide join/leave messages (invites/kicks/bans unaffected)": "Amaga els missatges d'entrada i sortida (no afecta a les invitacions, expulsions o prohibicions)", @@ -955,7 +954,6 @@ "Preparing to send logs": "Preparant l'enviament de logs", "Explore Account Data": "Explora les dades del compte", "Remove from Directory": "Elimina del directori", - "Away": "Absent", "Saturday": "Dissabte", "Remember, you can always set an email address in user settings if you change your mind.": "Recordeu-ho, si canvieu d'idea, sempre podreu establir una adreça de correu electrònic a las vostra configuració d'usuari.", "Direct Chat": "Xat directe", @@ -992,7 +990,6 @@ "Notify for all other messages/rooms": "Notifica per a tots els altres missatges o sales", "Unable to look up room ID from server": "No s'ha pogut cercar l'ID de la sala en el servidor", "Couldn't find a matching Matrix room": "No s'ha pogut trobar una sala de Matrix que coincideixi", - "Bug report sent": "S'ha enviat l'informe d'error", "Invite to this room": "Convida a aquesta sala", "You cannot delete this message. (%(code)s)": "No podeu eliminar aquest missatge. (%(code)s)", "Thursday": "Dijous", @@ -1013,7 +1010,6 @@ "Login": "Inicia sessió", "Low Priority": "Baixa prioritat", "Unable to fetch notification target list": "No s'ha pogut obtenir la llista d'objectius de les notificacions", - "Appear Offline": "Apareix sense connexió", "Set Password": "Establiu una contrasenya", "Enable audible notifications in web client": "Habilita les notificacions d'àudio al client web", "Permalink": "Enllaç permanent", diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index 4bac6cd5d2..11dd85ba50 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -643,7 +643,6 @@ "%(senderName)s placed a %(callType)s call.": "%(senderName)s uskutečnil %(callType)s hovor.", "%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s zpřístupnil budoucí historii místnosti neznámým (%(visibility)s).", "Not a valid Riot keyfile": "Neplatný soubor s klíčem Riot", - "Presence Management": "Správce účasti", "Disable Emoji suggestions while typing": "Zakázat návrhy Emoji během psaní", "Hide avatar changes": "Skrýt změny avatara", "Hide display name changes": "Skrýt změny zobrazovaného jména", @@ -1017,7 +1016,6 @@ "Enable desktop notifications": "Zapnout upozornění na ploše", "Explore Account Data": "Prozkoumat data o účtu", "Remove from Directory": "Odebrat z adresáře", - "Away": "Pryč", "Saturday": "Sobota", "Messages in one-to-one chats": "Zprávy v individuálních chatech", "Direct Chat": "Přímý chat", @@ -1031,7 +1029,6 @@ "Toolbox": "Sada nástrojů", "Collecting logs": "Sbírání logů", "more": "více", - "Bug report sent": "Hlášení o chybě bylo odesláno", "You must specify an event type!": "Musíte určit typ události!", "(HTTP status %(httpStatus)s)": "(HTTP status %(httpStatus)s)", "Invite to this room": "Pozvat do této místnosti", @@ -1070,7 +1067,6 @@ "Low Priority": "Nízká priorita", "Riot does not know how to join a room on this network": "Riot neví, jak vstoupit do místosti na této síti", "Set Password": "Nastavit heslo", - "Appear Offline": "Jevit se offline", "An error occurred whilst saving your email notification preferences.": "Při ukládání nastavení e-mailových upozornění nastala chyba.", "Enable audible notifications in web client": "Povolit zvuková upozornění ve webové aplikaci", "Permalink": "Trvalý odkaz", diff --git a/src/i18n/strings/da.json b/src/i18n/strings/da.json index 044c251e94..ed49d32ebe 100644 --- a/src/i18n/strings/da.json +++ b/src/i18n/strings/da.json @@ -317,7 +317,6 @@ "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot bruger mange avancerede browser funktioner, hvoraf nogle af dem ikke er tilgængelige eller er eksperimentelle i din browser.", "Event sent!": "Begivenhed sendt!", "Explore Account Data": "Udforsk Konto Data", - "Away": "Ikke til stede", "Saturday": "Lørdag", "Remember, you can always set an email address in user settings if you change your mind.": "Husk, du kan altid indstille en emailadresse i dine bruger indstillinger hvis du ombestemmer dig.", "Direct Chat": "Personlig Chat", @@ -351,7 +350,6 @@ "Notify for all other messages/rooms": "Underret om alle andre meddelelser / rum", "Unable to look up room ID from server": "Kunne ikke slå rum-id op på server", "Couldn't find a matching Matrix room": "Kunne ikke finde et matchende Matrix-rum", - "Bug report sent": "Fejl rapporteret", "All Rooms": "Alle rum", "You cannot delete this message. (%(code)s)": "Du kan ikke slette denne besked. (%(code)s)", "Thursday": "Torsdag", @@ -369,7 +367,6 @@ "Event Type": "Begivenhedstype", "Low Priority": "Lav prioritet", "Unable to fetch notification target list": "Kan ikke hente meddelelsesmålliste", - "Appear Offline": "Fremstå Offline", "Set Password": "Indstil Password", "Enable audible notifications in web client": "Aktivér hørbare underretninger i webklienten", "Permalink": "Permanent link", diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 831e3c5d6f..b709c283c3 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -907,7 +907,6 @@ "URL previews are disabled by default for participants in this room.": "URL-Vorschau ist für Mitglieder dieses Raumes standardmäßig deaktiviert.", "URL previews are enabled by default for participants in this room.": "URL-Vorschau ist für Mitglieder dieses Raumes standardmäßig aktiviert.", "Restricted": "Eingeschränkt", - "Presence Management": "Anwesenheitsmanagement", "Status.im theme": "Status.im-Thema", "%(duration)ss": "%(duration)ss", "%(duration)sm": "%(duration)sm", @@ -1073,7 +1072,6 @@ "Remember, you can always set an email address in user settings if you change your mind.": "Vergiss nicht, dass du in den Benutzereinstellungen jederzeit eine E-Mail-Adresse setzen kannst, wenn du deine Meinung änderst.", "Explore Account Data": "Benutzerkonto-Daten analysieren", "All messages (noisy)": "Alle Nachrichten (laut)", - "Away": "Abwesend", "Saturday": "Samstag", "I understand the risks and wish to continue": "Ich verstehe das Risiko und möchte fortfahren", "Direct Chat": "Direkt-Chat", @@ -1088,7 +1086,6 @@ "Collecting logs": "Protokolle werden abgerufen", "more": "mehr", "GitHub issue link:": "Link des GitHub-Problems:", - "Bug report sent": "Fehlerbericht wurde gesendet", "You must specify an event type!": "Du musst einen Event-Typ spezifizieren!", "(HTTP status %(httpStatus)s)": "(HTTP-Status %(httpStatus)s)", "Invite to this room": "In diesen Raum einladen", @@ -1129,7 +1126,6 @@ "Login": "Anmeldung", "Low Priority": "Niedrige Priorität", "Unable to fetch notification target list": "Liste der Benachrichtigungsempfänger konnte nicht abgerufen werden", - "Appear Offline": "Als offline anzeigen", "Set Password": "Passwort einrichten", "Enable audible notifications in web client": "Audio-Benachrichtigungen im Web-Client aktivieren", "Permalink": "Permanenter Link", diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 1317736fcf..1e2f51f513 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -171,7 +171,6 @@ "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s widget modified by %(senderName)s", "%(widgetName)s widget added by %(senderName)s": "%(widgetName)s widget added by %(senderName)s", "%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s widget removed by %(senderName)s", - "Message Pinning": "Message Pinning", "%(displayName)s is typing": "%(displayName)s is typing", "%(names)s and %(count)s others are typing|other": "%(names)s and %(count)s others are typing", "%(names)s and %(count)s others are typing|one": "%(names)s and one other is typing", @@ -187,7 +186,6 @@ "Failed to join room": "Failed to join room", "Message Replies": "Message Replies", "Message Pinning": "Message Pinning", - "Presence Management": "Presence Management", "Tag Panel": "Tag Panel", "Sticker Messages": "Sticker Messages", "Disable Emoji suggestions while typing": "Disable Emoji suggestions while typing", @@ -742,7 +740,6 @@ "Try using one of the following valid address types: %(validTypesList)s.": "Try using one of the following valid address types: %(validTypesList)s.", "You have entered an invalid address.": "You have entered an invalid address.", "Preparing to send logs": "Preparing to send logs", - "Bug report sent": "Bug report sent", "Logs sent": "Logs sent", "Thank you!": "Thank you!", "Failed to send logs: ": "Failed to send logs: ", @@ -860,8 +857,7 @@ "Permalink": "Permalink", "Quote": "Quote", "Source URL": "Source URL", - "Away": "Away", - "Appear Offline": "Appear Offline", + "Collapse Reply Thread": "Collapse Reply Thread", "Failed to set Direct Message status of room": "Failed to set Direct Message status of room", "All messages (noisy)": "All messages (noisy)", "All messages": "All messages", diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index 4a90bb8c0b..928caf9243 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -165,7 +165,6 @@ "Authentication check failed: incorrect password?": "Aŭtentiga kontrolo malsukcesis: ĉu pro malĝusta pasvorto?", "Failed to join room": "Malsukcesis aliĝi al ĉambro", "Message Pinning": "Fikso de mesaĝoj", - "Presence Management": "Ĉeesta administrado", "Disable Emoji suggestions while typing": "Malŝalti mienetajn sugestojn dum tajpado", "Use compact timeline layout": "Uzi densan okazordan aranĝon", "Hide removed messages": "Kaŝi forigitajn mesaĝojn", @@ -1030,7 +1029,6 @@ "Event sent!": "Okazo sendiĝis!", "Explore Account Data": "Esplori kontajn datumojn", "All messages (noisy)": "Ĉiuj mesaĝoj (lauta)", - "Away": "Foresta", "Saturday": "Sabato", "Remember, you can always set an email address in user settings if you change your mind.": "Memoru: vi ĉiam povas agordi retpoŝtadreson en viaj agordoj por uzantoj.", "Direct Chat": "Rekta babilo", @@ -1044,7 +1042,6 @@ "Toolbox": "Ilaro", "Collecting logs": "Kolektante protokolon", "more": "pli", - "Bug report sent": "Cimraporto sendiĝis", "You must specify an event type!": "Vi devas specifi tipon de okazo!", "(HTTP status %(httpStatus)s)": "(stato de HTTP %(httpStatus)s)", "Invite to this room": "Inviti al ĉi tiu ĉambro", @@ -1085,7 +1082,6 @@ "Login": "Saluti", "Low Priority": "Malalta prioritato", "Unable to fetch notification target list": "Malsukcesis akiri la liston de celoj por sciigoj", - "Appear Offline": "Montriĝi kiel eksterreta", "Set Password": "Agordi pasvorton", "Enable audible notifications in web client": "Ŝalti aŭdeblajn sciigojn en la retkliento", "Permalink": "Konstanta ligilo", diff --git a/src/i18n/strings/es.json b/src/i18n/strings/es.json index 36bf4b7b3b..07b38d7566 100644 --- a/src/i18n/strings/es.json +++ b/src/i18n/strings/es.json @@ -666,7 +666,6 @@ "Unnamed room": "Sala sin nombre", "Explore Account Data": "Explorar Datos de la Cuenta", "Remove from Directory": "Retirar del Directorio", - "Away": "Ausente", "Saturday": "Sábado", "Remember, you can always set an email address in user settings if you change your mind.": "Recuerda que si es necesario puedes establecer una dirección de email en las preferencias de usuario.", "Direct Chat": "Conversación directa", @@ -681,7 +680,6 @@ "Collecting logs": "Recolectando registros", "more": "más", "GitHub issue link:": "Enlace de incidencia en GitHub:", - "Bug report sent": "Informe de fallo enviado", "You must specify an event type!": "Debes especificar un tipo de evento!", "(HTTP status %(httpStatus)s)": "(estado HTTP %(httpStatus)s)", "Invite to this room": "Invitar a esta sala", @@ -722,7 +720,6 @@ "Login": "Iniciar sesión", "Low Priority": "Baja Prioridad", "Riot does not know how to join a room on this network": "Riot no sabe cómo unirse a una sala en esta red", - "Appear Offline": "Mostrarse Desconectado", "Set Password": "Establecer contraseña", "Enable audible notifications in web client": "Habilitar notificaciones audibles en el cliente web", "Permalink": "Enlace permanente", diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index 538a3c2c1c..83995ea723 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -731,7 +731,6 @@ "%(names)s and %(count)s others are typing|one": "%(names)s eta beste bat idazten ari dira", "Send": "Bidali", "Message Pinning": "Mezuak finkatzea", - "Presence Management": "Presentzia-kudeaketa", "Hide avatar changes": "Ezkutatu abatar aldaketak", "Hide display name changes": "Ezkutatu pantaila izenen aldaketak", "Disable big emoji in chat": "Desgaitu emoji handiak txatean", @@ -1073,7 +1072,6 @@ "Remember, you can always set an email address in user settings if you change your mind.": "Gogoratu, e-mail helbide bat ezarri dezakezu erabiltzaile-ezarpenetan iritzia aldatzen baduzu.", "Explore Account Data": "Miatu kantuaren datuak", "All messages (noisy)": "Mezu guztiak (ozen)", - "Away": "Teklatutik at", "Saturday": "Larunbata", "I understand the risks and wish to continue": "Arriskua ulertzen dut eta jarraitu nahi dut", "Direct Chat": "Txat zuzena", @@ -1088,7 +1086,6 @@ "Collecting logs": "Egunkariak biltzen", "more": "gehiago", "GitHub issue link:": "Arazoaren esteka GitHuben:", - "Bug report sent": "Arazte-txostena bidali da", "You must specify an event type!": "Gertaera mota bat zehaztu behar duzu!", "(HTTP status %(httpStatus)s)": "(HTTP egoera %(httpStatus)s)", "All Rooms": "Gela guztiak", @@ -1130,7 +1127,6 @@ "Login": "Hasi saioa", "Low Priority": "Lehentasun baxua", "Unable to fetch notification target list": "Ezin izan da jakinarazpen helburuen zerrenda eskuratu", - "Appear Offline": "Agertu deskonektatuta", "Set Password": "Ezarri pasahitza", "Enable audible notifications in web client": "Gaitu jakinarazpen entzungarriak web bezeroan", "Permalink": "Esteka iraunkorra", diff --git a/src/i18n/strings/fi.json b/src/i18n/strings/fi.json index 9bcf0a64e3..7f532c542c 100644 --- a/src/i18n/strings/fi.json +++ b/src/i18n/strings/fi.json @@ -165,7 +165,6 @@ "Forgot your password?": "Unohditko salasanasi?", "For security, this session has been signed out. Please sign in again.": "Turvallisuussyistä tämä istunto on vanhentunut. Ole hyvä ja kirjaudu uudestaan.", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Turvallusuussyistä uloskirjautuminen poistaa kaikki päästä päähän-salausavaimet tästä selaimesta. Jos haluat purkaa keskustelujen salaukset tulevaisuudessa pitää sinun viedä purkuavaimet ja pitää ne turvallisesti tallessa.", - "Hide Apps": "Piilota sovellukset", "Hide read receipts": "Piilota lukukuittaukset", "Hide Text Formatting Toolbar": "Piilota tekstinmuotoilutyökalupalkki", "Homeserver is": "Kotipalvelin on", @@ -832,7 +831,6 @@ "%(widgetName)s widget added by %(senderName)s": "%(widgetName)s pienoisohjelman lisännyt %(senderName)s", "%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s pienoisohjelman poistanut %(senderName)s", "Send": "Lähetä", - "Presence Management": "Tilanhallinta", "Delete %(count)s devices|other": "Poista %(count)s laitetta", "Delete %(count)s devices|one": "Poista laite", "Select devices": "Valitse laitteet", @@ -1004,7 +1002,6 @@ "Enable desktop notifications": "Ota käyttöön työpöytäilmoitukset", "Explore Account Data": "Tilitiedot", "All messages (noisy)": "Kaikki viestit (äänekkäästi)", - "Away": "Poissa", "Saturday": "Lauantai", "Remember, you can always set an email address in user settings if you change your mind.": "Muista että voit aina asettaa sähköpostiosoitteen käyttäjäasetuksista jos muutat mielesi.", "Direct Chat": "Suora viestittely", @@ -1019,7 +1016,6 @@ "Toolbox": "Työkalut", "Collecting logs": "Haetaan lokitietoja", "more": "lisää", - "Bug report sent": "Virheraportti lähetetty", "You must specify an event type!": "Sinun on määritettävä tapahtuman tyyppi!", "(HTTP status %(httpStatus)s)": "(HTTP tila %(httpStatus)s)", "All Rooms": "Kaikki huoneet", @@ -1058,7 +1054,6 @@ "Low Priority": "Matala prioriteetti", "Unable to fetch notification target list": "Ilmoituskohdelistan haku epäonnistui", "Set Password": "Aseta salasana", - "Appear Offline": "Offline-tila", "An error occurred whilst saving your email notification preferences.": "Sähköposti-ilmoitusasetuksia tallettaessa tapahtui virhe.", "Enable audible notifications in web client": "Ota käyttöön äänelliset ilmoitukset", "Permalink": "Pysyvä linkki", diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 562e601ab1..4b01c65e1d 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -900,7 +900,6 @@ "Username on %(hs)s": "Nom d'utilisateur sur %(hs)s", "Restricted": "Restreint", "Custom of %(powerLevel)s": "Personnalisé de %(powerLevel)s", - "Presence Management": "Gestion de présence", "Hide avatar changes": "Masquer les changements d'avatar", "Hide display name changes": "Masquer les changements de nom affiché", "Enable inline URL previews by default": "Activer l'aperçu des URL par défaut", @@ -1078,7 +1077,6 @@ "Remember, you can always set an email address in user settings if you change your mind.": "Souvenez-vous que vous pourrez toujours définir une adresse e-mail dans les paramètres de l'utilisateur si vous changez d’avis.", "Explore Account Data": "Explorer les données du compte", "Remove from Directory": "Supprimer du répertoire", - "Away": "Absent", "Saturday": "Samedi", "I understand the risks and wish to continue": "Je comprends les risques et souhaite continuer", "Direct Chat": "Discussion directe", @@ -1092,7 +1090,6 @@ "Toolbox": "Boîte à outils", "Collecting logs": "Récupération des journaux", "more": "plus", - "Bug report sent": "Rapport d'erreur envoyé", "You must specify an event type!": "Vous devez spécifier un type d'événement !", "(HTTP status %(httpStatus)s)": "(état HTTP %(httpStatus)s)", "Invite to this room": "Inviter dans ce salon", @@ -1131,7 +1128,6 @@ "Login": "Connexion", "Low Priority": "Priorité basse", "Unable to fetch notification target list": "Impossible de récupérer la liste des appareils recevant les notifications", - "Appear Offline": "Apparaître Hors ligne", "Set Password": "Définir un mot de passe", "Enable audible notifications in web client": "Activer les notifications sonores pour le client web", "Permalink": "Permalien", diff --git a/src/i18n/strings/gl.json b/src/i18n/strings/gl.json index aca58e2e23..c2e451f814 100644 --- a/src/i18n/strings/gl.json +++ b/src/i18n/strings/gl.json @@ -169,7 +169,6 @@ "Authentication check failed: incorrect password?": "Fallou a comprobación de autenticación: contrasinal incorrecto?", "Failed to join room": "Non se puido unir a sala", "Message Pinning": "Fixando mensaxe", - "Presence Management": "Xestión da presenza", "Disable Emoji suggestions while typing": "Deshabilitar a suxestión de Emoji mentras escribe", "Use compact timeline layout": "Utilizar a disposición compacta da liña temporal", "Hide removed messages": "Ocultar mensaxes eliminadas", @@ -1073,7 +1072,6 @@ "Remember, you can always set an email address in user settings if you change your mind.": "Lembre, sempre poderá poñer un enderezo de correo nos axustes de usuario si cambia de idea.", "Explore Account Data": "Explorar datos da conta", "All messages (noisy)": "Todas as mensaxes (alto)", - "Away": "Fóra", "Saturday": "Sábado", "I understand the risks and wish to continue": "Entendos os riscos e desexo continuar", "Direct Chat": "Chat directo", @@ -1088,7 +1086,6 @@ "Collecting logs": "Obtendo rexistros", "more": "máis", "GitHub issue link:": "Ligazón ao reporte en GitHub:", - "Bug report sent": "Enviado o informe de fallo", "You must specify an event type!": "Debe indicar un tipo de evento!", "(HTTP status %(httpStatus)s)": "(Estado HTTP %(httpStatus)s)", "All Rooms": "Todas as Salas", @@ -1130,7 +1127,6 @@ "Login": "Conectar", "Low Priority": "Baixa prioridade", "Unable to fetch notification target list": "Non se puido procesar a lista de obxetivo de notificacións", - "Appear Offline": "Aparecer fora de liña", "Set Password": "Establecer contrasinal", "Enable audible notifications in web client": "Habilitar notificacións audibles no cliente web", "Permalink": "Ligazón permanente", diff --git a/src/i18n/strings/he.json b/src/i18n/strings/he.json index 9543a64b8f..7e747428a6 100644 --- a/src/i18n/strings/he.json +++ b/src/i18n/strings/he.json @@ -164,7 +164,6 @@ "Remember, you can always set an email address in user settings if you change your mind.": "להזכירך: תמיד ניתן לשנות כתובת אימייל בהגדרות משתש. למקרה שתתחרט/י.", "Explore Account Data": "גלה פרטי משתמש", "All messages (noisy)": "כל ההודעות (רועש)", - "Away": "מרוחק", "Saturday": "שבת", "I understand the risks and wish to continue": "אני מבין את הסיכונים אבל מבקש להמשיך", "Direct Chat": "שיחה ישירה", @@ -221,7 +220,6 @@ "Login": "התחבר", "Low Priority": "עדיפות נמוכה", "Unable to fetch notification target list": "לא ניתן לאחזר רשימת יעדי התראה", - "Appear Offline": "מופיע מקוון", "Set Password": "הגדר סיסמא", "Enable audible notifications in web client": "אפשר התראות קוליות בדפדפן", "Permalink": "קישור קבוע", diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 6eeafe57db..64bdbbc7c3 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -900,7 +900,6 @@ "Username on %(hs)s": "Felhasználónév a %(hs)s szerveren", "Restricted": "Korlátozott", "Custom of %(powerLevel)s": "Egyedi beállítás: %(powerLevel)s", - "Presence Management": "Jelenlét menedzsment", "Hide avatar changes": "Avatar változások elrejtése", "Hide display name changes": "Név változások elrejtése", "Enable inline URL previews by default": "Beágyazott URL előnézetek alapértelmezett engedélyezése", @@ -1081,7 +1080,6 @@ "Remember, you can always set an email address in user settings if you change your mind.": "Ha meggondolod magad, bármikor beállíthatod az e-mail címed a felhasználói beállításoknál.", "Explore Account Data": "Fiókadatok felderítése", "Remove from Directory": "Törlés a listából", - "Away": "Távol", "Saturday": "Szombat", "I understand the risks and wish to continue": "Megértettem a kockázatot és folytatom", "Direct Chat": "Közvetlen csevegés", @@ -1096,7 +1094,6 @@ "Collecting logs": "Naplók összegyűjtése", "more": "tovább", "GitHub issue link:": "GitHub hibajegy hivatkozás:", - "Bug report sent": "Hibajelentés elküldve", "You must specify an event type!": "Meg kell jelölnöd az eseménytípust!", "(HTTP status %(httpStatus)s)": "(HTTP állapot: %(httpStatus)s)", "Invite to this room": "Meghívás a szobába", @@ -1137,7 +1134,6 @@ "Login": "Bejelentkezés", "Low Priority": "Alacsony prioritás", "Unable to fetch notification target list": "Nem sikerült letölteni az értesítési célok listáját", - "Appear Offline": "Offline látszik", "Set Password": "Jelszó beállítása", "Enable audible notifications in web client": "Hangértesítések engedélyezése a webkliensben", "Permalink": "Állandó hivatkozás", diff --git a/src/i18n/strings/id.json b/src/i18n/strings/id.json index 5eccf72100..9db1a4a99c 100644 --- a/src/i18n/strings/id.json +++ b/src/i18n/strings/id.json @@ -285,7 +285,6 @@ "Messages containing my user name": "Pesan mengandung nama pengguna saya", "Collecting logs": "Mengumpulkan catatan", "more": "lagi", - "Bug report sent": "Laporan bug terkirim", "(HTTP status %(httpStatus)s)": "(status HTTP %(httpStatus)s)", "Failed to forget room %(errCode)s": "Gagal melupakan ruang %(errCode)s", "Wednesday": "Rabu", diff --git a/src/i18n/strings/it.json b/src/i18n/strings/it.json index fad64d496f..3a4691bae7 100644 --- a/src/i18n/strings/it.json +++ b/src/i18n/strings/it.json @@ -232,7 +232,6 @@ "Not a valid Riot keyfile": "Non è una chiave di Riot valida", "Authentication check failed: incorrect password?": "Controllo di autenticazione fallito: password sbagliata?", "Failed to join room": "Accesso alla stanza fallito", - "Presence Management": "Gestione della presenza", "Disable Emoji suggestions while typing": "Disattiva i suggerimenti delle emoji durante la digitazione", "Use compact timeline layout": "Usa impaginazione cronologia compatta", "Hide join/leave messages (invites/kicks/bans unaffected)": "Nascondi i messaggi di entrata/uscita (inviti/kick/ban esclusi)", @@ -1073,7 +1072,6 @@ "Remember, you can always set an email address in user settings if you change your mind.": "Ricorda, puoi sempre specificare un indirizzo email nelle impostazioni utente se cambi idea.", "Explore Account Data": "Esplora dati account", "All messages (noisy)": "Tutti i messaggi (rumoroso)", - "Away": "Assente", "Saturday": "Sabato", "I understand the risks and wish to continue": "Sono consapevole dei rischi e vorrei continuare", "Direct Chat": "Chat Diretta", @@ -1088,7 +1086,6 @@ "Collecting logs": "Sto recuperando i log", "more": "altro", "GitHub issue link:": "Link segnalazione su GitHub:", - "Bug report sent": "Rapporto inviato", "You must specify an event type!": "Devi specificare un tipo di evento!", "(HTTP status %(httpStatus)s)": "(stato HTTP %(httpStatus)s)", "All Rooms": "Tutte le stanze", @@ -1131,7 +1128,6 @@ "Login": "Entra", "Low Priority": "Priorità bassa", "What's New": "Novità", - "Appear Offline": "Appari offline", "Set Password": "Imposta Password", "Enable audible notifications in web client": "Abilita notifiche audio nel client web", "Permalink": "Link permanente", diff --git a/src/i18n/strings/ko.json b/src/i18n/strings/ko.json index 32ca09aee1..ff5ebd72d7 100644 --- a/src/i18n/strings/ko.json +++ b/src/i18n/strings/ko.json @@ -725,7 +725,6 @@ "Toolbox": "도구상자", "Collecting logs": "로그 수집 중", "more": "더 보기", - "Bug report sent": "오류 보고서를 보냈어요", "(HTTP status %(httpStatus)s)": "(HTTP 상태 %(httpStatus)s)", "All Rooms": "모든 방", "Failed to get public room list": "공개한 방 목록을 얻지 못했어요", @@ -761,7 +760,6 @@ "Error encountered (%(errorDetail)s).": "오류가 일어났어요 (%(errorDetail)s).", "Low Priority": "낮은 우선순위", "Riot does not know how to join a room on this network": "라이엇이 이 네트워크에서 방에 들어가는 법을 알 수 없어요", - "Appear Offline": "미접속으로 표시하기", "Set Password": "비밀번호 설정", "Enable audible notifications in web client": "웹 클라이언트에서 알림 소리 켜기", "Permalink": "고유주소", diff --git a/src/i18n/strings/lt.json b/src/i18n/strings/lt.json index 277b0cf427..efa5cf9d5e 100644 --- a/src/i18n/strings/lt.json +++ b/src/i18n/strings/lt.json @@ -97,12 +97,10 @@ "Remove %(name)s from the directory?": "Ar ištrinti %(name)s iš katalogo?", "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot naudoja daug išplėstinių naršyklės funkcionalumų, kai kurie iš jų yra neprieinami ar eksperimentinei Jūsų naršyklėje.", "Event sent!": "Įvykis išsiųstas!", - "Bug report sent": "Klaidos ataskaita išsiųsta", "Unnamed room": "Kambarys be pavadinimo", "Dismiss": "Nutraukti", "Explore Account Data": "Peržiūrėti paskyros duomenis", "Remove from Directory": "Šalinti iš katalogo", - "Away": "Neaktyvus", "Download this file": "Atsisiųsti šį failą", "Saturday": "Šeštadienis", "Remember, you can always set an email address in user settings if you change your mind.": "Nepamirškite, kad galite, bet kada įrašyti savo el. pašto adresą paskyros nustatymuose.", @@ -162,7 +160,6 @@ "Low Priority": "Nesvarbūs", "Riot does not know how to join a room on this network": "Riot nežino kaip prisijungti prie kambario šiame tinkle", "Set Password": "Nustatyti slaptažodį", - "Appear Offline": "Neprisijungęs", "An error occurred whilst saving your email notification preferences.": "Įrašant pranešimų el. paštu nuostatas, įvyko klaida.", "Unable to join network": "Nepavyko prisijungti prie tinklo", "Permalink": "Pastovioji nuoroda", diff --git a/src/i18n/strings/lv.json b/src/i18n/strings/lv.json index bb4225216f..35ffa35b14 100644 --- a/src/i18n/strings/lv.json +++ b/src/i18n/strings/lv.json @@ -731,7 +731,6 @@ "%(names)s and %(count)s others are typing|one": "%(names)s un vēl kāds raksta", "Message Replies": "Atbildes uz ziņām", "Message Pinning": "Ziņu piekabināšana", - "Presence Management": "Klātesamības vadība", "Disable Emoji suggestions while typing": "Atspējot Emoji ieteikumus teksta rakstīšanas laikā", "Hide avatar changes": "Slēpt avatara izmaiņas", "Hide display name changes": "Slēpt attēlojamā/redzamā vārda izmaiņas", @@ -1067,7 +1066,6 @@ "Enable desktop notifications": "Iespējot darbvirsmas paziņojumus", "Explore Account Data": "Aplūkot konta datus", "All messages (noisy)": "Visas ziņas (ar skaņu)", - "Away": "Prom (nav uz vietas)", "Saturday": "sestdiena", "Remember, you can always set an email address in user settings if you change your mind.": "Atceries, ka vienmēr vari iestatīt epasta adresi lietotāja uzstādījumos, ja pārdomā.", "Direct Chat": "Tiešais čats", @@ -1083,7 +1081,6 @@ "Collecting logs": "Tiek iegūti logfaili", "more": "vairāk", "GitHub issue link:": "GitHub problēmpaziņojuma saite:", - "Bug report sent": "Kļūdas atskaite nosūtīta", "You must specify an event type!": "Jānorāda notikuma tips!", "(HTTP status %(httpStatus)s)": "(HTTP statuss %(httpStatus)s)", "All Rooms": "visās istabās", @@ -1125,7 +1122,6 @@ "Login": "Ierakstīties", "Low Priority": "Zemas prioritātes", "Unable to fetch notification target list": "Neizdevās iegūt paziņojumu mērķu sarakstu", - "Appear Offline": "Šķiet nesaistē (oflainā)", "Set Password": "Iestatīt paroli", "Enable audible notifications in web client": "Iespējot skaņus paziņojumus web klientā", "Permalink": "Pastāvīgā saite", diff --git a/src/i18n/strings/ml.json b/src/i18n/strings/ml.json index 098c062006..6de7e92df7 100644 --- a/src/i18n/strings/ml.json +++ b/src/i18n/strings/ml.json @@ -102,7 +102,6 @@ "Messages containing my user name": "എന്റെ യൂസര്‍ നെയിം അടങ്ങിയിരിക്കുന്ന സന്ദേശങ്ങള്‍ക്ക്", "Collecting logs": "നാള്‍വഴി ശേഖരിക്കുന്നു", "more": "കൂടുതല്‍", - "Bug report sent": "ബഗ് റിപ്പോർട്ട് അയയ്ക്കുക", "(HTTP status %(httpStatus)s)": "(HTTP സ്റ്റാറ്റസ് %(httpStatus)s)", "All Rooms": "എല്ലാ മുറികളും കാണുക", "Wednesday": "ബുധന്‍", diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index d272e628f0..c41ab7899d 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -717,7 +717,6 @@ "Send": "Verstuur", "Message Pinning": "Boodschap vastpinnen", "Message Replies": "Antwoorden op bericht", - "Presence Management": "Presentie Beheer", "Disable Emoji suggestions while typing": "Emoji suggesties tijdens het typen uitzetten", "Hide avatar changes": "Avatar veranderingen verbergen", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(day)s %(monthName)s %(fullYear)s", @@ -1059,7 +1058,6 @@ "Enable desktop notifications": "Desktopmeldingen aanzetten", "Explore Account Data": "Bekijk account informatie", "Remove from Directory": "Uit de kamerlijst verwijderen", - "Away": "Afwezig", "Saturday": "Zaterdag", "Remember, you can always set an email address in user settings if you change your mind.": "Onthoud dat u altijd een e-mailadres in kan stellen in de gebruikersinstellingen als u zich bedenkt.", "Direct Chat": "Privégesprek", @@ -1073,7 +1071,6 @@ "Toolbox": "Eigenschappen", "Collecting logs": "Logboeken verzamelen", "more": "meer", - "Bug report sent": "Bug report verzonden", "You must specify an event type!": "Je moet een event-type specificeren!", "(HTTP status %(httpStatus)s)": "(HTTP-status %(httpStatus)s)", "Invite to this room": "Uitnodigen voor deze kamer", @@ -1110,7 +1107,6 @@ "Login": "Aanmelden", "Low Priority": "Lage prioriteit", "Unable to fetch notification target list": "Het is mislukt om de lijst van notificatiedoelen op te halen", - "Appear Offline": "Lijk offline", "Set Password": "Wachtwoord instellen", "Enable audible notifications in web client": "Geluidsmeldingen in de webclient aanzetten", "Permalink": "Permanente link", diff --git a/src/i18n/strings/pl.json b/src/i18n/strings/pl.json index 042df8aebc..f39edb4972 100644 --- a/src/i18n/strings/pl.json +++ b/src/i18n/strings/pl.json @@ -777,7 +777,6 @@ "Remember, you can always set an email address in user settings if you change your mind.": "Pamiętaj, że zawsze możesz zmienić swój e-mail lub hasło w panelu ustawień użytkownika.", "Explore Account Data": "Odkryj dane konta", "All messages (noisy)": "Wszystkie wiadomości (głośno)", - "Away": "Niedostępny", "Saturday": "Sobota", "I understand the risks and wish to continue": "Rozumiem ryzyko i chcę kontynuować", "Direct Chat": "Rozmowa bezpośrednia", @@ -792,7 +791,6 @@ "Collecting logs": "Zbieranie dzienników", "more": "więcej", "GitHub issue link:": "Link do wątku na GitHubie:", - "Bug report sent": "Raport błędu wysłany", "You must specify an event type!": "Musisz określić typ wydarzenia!", "(HTTP status %(httpStatus)s)": "(status HTTP %(httpStatus)s)", "All Rooms": "Wszystkie pokoje", @@ -835,7 +833,6 @@ "Login": "Logowanie", "Low Priority": "Niski priorytet", "Unable to fetch notification target list": "Nie można pobrać listy docelowej dla powiadomień", - "Appear Offline": "Ustaw status niedostępny", "Set Password": "Ustaw hasło", "Enable audible notifications in web client": "Włącz dźwiękowe powiadomienia w kliencie internetowym", "Permalink": "Odnośnik bezpośredni", diff --git a/src/i18n/strings/pt.json b/src/i18n/strings/pt.json index d8b9d11040..12339e6757 100644 --- a/src/i18n/strings/pt.json +++ b/src/i18n/strings/pt.json @@ -817,7 +817,6 @@ "Notify for all other messages/rooms": "Notificar para todas as outras mensagens/salas", "Unable to look up room ID from server": "Não foi possível obter a identificação da sala do servidor", "Couldn't find a matching Matrix room": "Não foi possível encontrar uma sala correspondente no servidor Matrix", - "Bug report sent": "Relatório de erros enviado", "All Rooms": "Todas as salas", "You cannot delete this message. (%(code)s)": "Não pode apagar esta mensagem. (%(code)s)", "Thursday": "Quinta-feira", diff --git a/src/i18n/strings/pt_BR.json b/src/i18n/strings/pt_BR.json index eccce3d2a0..0abb10edce 100644 --- a/src/i18n/strings/pt_BR.json +++ b/src/i18n/strings/pt_BR.json @@ -695,7 +695,6 @@ "Send": "Enviar", "Message Replies": "Respostas", "Message Pinning": "Fixar mensagem", - "Presence Management": "Gestão da presença", "Disable Emoji suggestions while typing": "Desativar sugestões de emojis enquanto estiver escrevendo", "Hide join/leave messages (invites/kicks/bans unaffected)": "Ocultar mensagens de entrada e de saída (não afeta convites, expulsões e banimentos)", "Hide avatar changes": "Ocultar alterações da imagem de perfil", @@ -1060,7 +1059,6 @@ "Enable desktop notifications": "Ativar notificações no desktop", "Explore Account Data": "Explorar Dados da Conta", "Remove from Directory": "Remover da lista pública de salas", - "Away": "Ausente", "Saturday": "Sábado", "Remember, you can always set an email address in user settings if you change your mind.": "Lembre-se: você pode sempre definir um endereço de e-mail nas configurações de usuário, se mudar de ideia.", "Direct Chat": "Conversa pessoal", @@ -1074,7 +1072,6 @@ "Toolbox": "Ferramentas", "Collecting logs": "Coletando logs", "more": "ver mais", - "Bug report sent": "Relatório do bug enviado", "You must specify an event type!": "Você precisa especificar um tipo do evento!", "(HTTP status %(httpStatus)s)": "(Status HTTP %(httpStatus)s)", "Invite to this room": "Convidar para esta sala", @@ -1110,7 +1107,6 @@ "Login": "Fazer login", "Low Priority": "Baixa prioridade", "Unable to fetch notification target list": "Não foi possível obter a lista de alvos de notificação", - "Appear Offline": "Aparecer Desconectado", "Set Password": "Definir senha", "Enable audible notifications in web client": "Ativar notificações de áudio no cliente web", "Permalink": "Link permanente", diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 955920bd0a..d3a283d6d7 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -884,7 +884,6 @@ "Visibility in Room List": "Видимость в списке комнат", "Visible to everyone": "Видимый для всех", "Only visible to community members": "Только участникам сообщества", - "Presence Management": "Управление присутствием", "Hide avatar changes": "Скрыть изменения аватара", "Hide display name changes": "Скрыть изменения отображаемого имени", "Enable inline URL previews by default": "Включить просмотр URL-адресов по умолчанию", @@ -1077,7 +1076,6 @@ "Enable desktop notifications": "Включить оповещения на рабочем столе", "Explore Account Data": "Просмотр данных аккаунта", "All messages (noisy)": "Все сообщения (со звуком)", - "Away": "Нет на месте", "Saturday": "Суббота", "Remember, you can always set an email address in user settings if you change your mind.": "Помните, что вы всегда сможете задать адрес email в настройках пользователя, если передумаете.", "Direct Chat": "Прямой чат", @@ -1092,7 +1090,6 @@ "Collecting logs": "Сбор журналов", "more": "больше", "GitHub issue link:": "Ссылка на проблему в GitHub:", - "Bug report sent": "Отчет об ошибке отправлен", "You must specify an event type!": "Необходимо указать тип мероприятия!", "(HTTP status %(httpStatus)s)": "(статус HTTP %(httpStatus)s)", "Invite to this room": "Пригласить в комнату", @@ -1131,7 +1128,6 @@ "Login": "Войти", "Low Priority": "Низкий приоритет", "Unable to fetch notification target list": "Не удалось получить список целей уведомления", - "Appear Offline": "Отображать как не в сети", "Set Password": "Задать пароль", "Enable audible notifications in web client": "Включить звуковые уведомления в веб-клиенте", "Permalink": "Постоянная ссылка", diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index db08989273..5daa56e0fe 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -899,7 +899,6 @@ "Please note you are logging into the %(hs)s server, not matrix.org.": "Všimnite si: Práve sa prihlasujete na server %(hs)s, nie na server matrix.org.", "Username on %(hs)s": "Meno používateľa na servery %(hs)s", "Restricted": "Obmedzené", - "Presence Management": "Spravovanie prítomnosti", "Hide avatar changes": "Skryť zmeny avatara", "Hide display name changes": "Skryť zmeny zobrazovaného mena", "Enable inline URL previews by default": "Predvolene povoliť náhľady URL adries", @@ -1071,7 +1070,6 @@ "Enable desktop notifications": "Povoliť oznámenia na pracovnej ploche", "Explore Account Data": "Preskúmať Údaje účtu", "All messages (noisy)": "Všetky správy (hlučné)", - "Away": "Preč", "Saturday": "Sobota", "Remember, you can always set an email address in user settings if you change your mind.": "Všimnite si, Emailovú adresu môžete pridať aj neskôr v časti nastavenia, ak zmeníte svoj názor.", "Direct Chat": "Priama konverzácia", @@ -1108,7 +1106,6 @@ "Notify for all other messages/rooms": "oznamovať všetky ostatné správy / miestnosti", "Unable to look up room ID from server": "Nie je možné vyhľadať ID miestnosti na servery", "Couldn't find a matching Matrix room": "Nie je možné nájsť zodpovedajúcu Matrix miestnosť", - "Bug report sent": "Hlásenie chyby odoslané", "Invite to this room": "Pozvať do tejto miestnosti", "You cannot delete this message. (%(code)s)": "Nemôžete vymazať túto správu. (%(code)s)", "Thursday": "Štvrtok", @@ -1129,7 +1126,6 @@ "Low Priority": "Nízka priorita", "What's New": "Čo Je Nové", "Set Password": "Nastaviť Heslo", - "Appear Offline": "Zdá sa byť nedostupný", "An error occurred whilst saving your email notification preferences.": "Počas ukladania vašich nastavení oznamovania emailom sa vyskytla chyba.", "Enable audible notifications in web client": "Povoliť zvukové oznámenia vo webovom klientovi", "Permalink": "Trvalý odkaz", diff --git a/src/i18n/strings/sq.json b/src/i18n/strings/sq.json index dc26c7c283..d36995bc5b 100644 --- a/src/i18n/strings/sq.json +++ b/src/i18n/strings/sq.json @@ -207,7 +207,6 @@ "Dismiss": "Mos e merr parasysh", "Explore Account Data": "Eksploroni të Dhëna Llogarie", "All messages (noisy)": "Tërë Mesazhet (e zhurmshme)", - "Away": "Larguar", "Saturday": "E shtunë", "Remember, you can always set an email address in user settings if you change your mind.": "Mos harroni, mundeni përherë të caktoni një adresë email te rregullimet e përdoruesit, nëse ndërroni mendje.", "Direct Chat": "Fjalosje e Drejtpërdrejtë", @@ -270,7 +269,6 @@ "Low Priority": "Përparësi e Ulët", "What's New": "Ç’ka të Re", "Set Password": "Caktoni Fjalëkalim", - "Appear Offline": "Shfaqju Si Jo Në Linjë", "An error occurred whilst saving your email notification preferences.": "Ndodhi një gabim teksa ruheshin parapëlqimet tuaja për njoftime me email.", "Enable audible notifications in web client": "Aktivizoni njoftime audio te klienti web", "Permalink": "Permalidhje", diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index c11a058adc..3ea5c9c8c9 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -172,7 +172,6 @@ "Failed to join room": "Нисам успео да уђем у собу", "Message Replies": "Одговори", "Message Pinning": "Закачене поруке", - "Presence Management": "Управљање присутношћу", "Disable Emoji suggestions while typing": "Онемогући предлагање емоџија приликом куцања", "Use compact timeline layout": "Користи збијени распоред временске линије", "Hide removed messages": "Сакриј уклоњене поруке", @@ -1056,7 +1055,6 @@ "Event sent!": "Догађај је послат!", "Explore Account Data": "Истражи податке налога", "All messages (noisy)": "Све поруке (гласно)", - "Away": "Одустан", "Saturday": "Субота", "Remember, you can always set an email address in user settings if you change your mind.": "Запамтите, увек можете поставити мејл адресу у корисничким подешавањима, уколико се предомислите.", "Direct Chat": "Директно ћаскање", @@ -1090,7 +1088,6 @@ "Notify for all other messages/rooms": "Обавести за све друге поруке и собе", "Unable to look up room ID from server": "Не могу да погледам ИБ собе на серверу", "Couldn't find a matching Matrix room": "Не могу да нађем одговарајућу Матрикс собу", - "Bug report sent": "Извештај о грешци послат", "Invite to this room": "Позови у ову собу", "You cannot delete this message. (%(code)s)": "Не можете обрисати ову поруку. (%(code)s)", "Thursday": "Четвртак", @@ -1109,7 +1106,6 @@ "Low Priority": "Најмања важност", "What's New": "Шта је ново", "Set Password": "Постави лозинку", - "Appear Offline": "Прикажи себе као ван мреже", "An error occurred whilst saving your email notification preferences.": "Догодила се грешка при чувању ваших поставки мејл обавештења.", "Enable audible notifications in web client": "Омогући звучна обавештења у веб клијенту", "Permalink": "Трајна веза", diff --git a/src/i18n/strings/sv.json b/src/i18n/strings/sv.json index cd502e5bb7..c55ee40cba 100644 --- a/src/i18n/strings/sv.json +++ b/src/i18n/strings/sv.json @@ -501,7 +501,6 @@ "Enable desktop notifications": "Sätt på skrivbordsaviseringar", "Remember, you can always set an email address in user settings if you change your mind.": "Kom ihåg att du alltid kan välja en e-postadress i dina användarinställningar om du ändrar dig.", "All messages (noisy)": "Alla meddelanden (högljudd)", - "Away": "Borta", "Saturday": "lördag", "I understand the risks and wish to continue": "Jag förstår riskerna och vill fortsätta", "Direct Chat": "Direkt-chatt", @@ -514,7 +513,6 @@ "Messages containing my user name": "Meddelanden som innehåller mitt användarnamn", "Collecting logs": "Samlar in loggar", "more": "mera", - "Bug report sent": "Buggraporten skickades", "(HTTP status %(httpStatus)s)": "(HTTP-status %(httpStatus)s)", "All Rooms": "Alla rum", "Wednesday": "onsdag", @@ -548,7 +546,6 @@ "Error encountered (%(errorDetail)s).": "Fel påträffat (%(errorDetail)s).", "Low Priority": "Låg prioritet", "Unable to fetch notification target list": "Det gick inte att hämta aviseringsmållistan", - "Appear Offline": "Visa som utloggad", "Set Password": "Välj lösenord", "Enable audible notifications in web client": "Sätt på högljudda aviseringar i webbklienten", "Permalink": "Permanent länk", diff --git a/src/i18n/strings/ta.json b/src/i18n/strings/ta.json index 202e5326f0..6aecb54bfd 100644 --- a/src/i18n/strings/ta.json +++ b/src/i18n/strings/ta.json @@ -119,7 +119,6 @@ "You cannot delete this image. (%(code)s)": "இந்த படத்தை நீங்கள் அழிக்க முடியாது. (%(code)s)", "You cannot delete this message. (%(code)s)": "இந்த செய்தியை நீங்கள் அழிக்க முடியாது. (%(code)s)", "You are not receiving desktop notifications": "திரை அறிவிப்புகளை நீங்கள் பெறவில்லை", - "Bug report sent": "வழு அறிக்கை அனுப்பப்பட்டது", "OK": "சரி", "Show message in desktop notification": "திரை அறிவிப்புகளில் செய்தியை காண்பிக்கவும்", "Sunday": "ஞாயிறு", diff --git a/src/i18n/strings/uk.json b/src/i18n/strings/uk.json index 25a70e0522..02a650ac3a 100644 --- a/src/i18n/strings/uk.json +++ b/src/i18n/strings/uk.json @@ -177,7 +177,6 @@ "Unnamed room": "Неназвана кімната", "Explore Account Data": "Продивитись данні аккаунта", "All messages (noisy)": "Усі повідомлення (гучно)", - "Away": "Нема на місці", "Saturday": "Субота", "I understand the risks and wish to continue": "Я ознайомлений з ризиками і хочу продовжити", "Direct Chat": "Прямий чат", @@ -192,7 +191,6 @@ "Toolbox": "Панель інструментів", "Collecting logs": "Збір журналів", "more": "докладніше", - "Bug report sent": "Звіт про помилки відправлений", "You must specify an event type!": "Необхідно вказати тип захода!", "(HTTP status %(httpStatus)s)": "(статус HTTP %(httpStatus)s)", "All Rooms": "Усі кімнати", @@ -233,7 +231,6 @@ "Login": "Зайти", "Low Priority": "Неважливі", "Unable to fetch notification target list": "Неможливо отримати перелік цілей сповіщення", - "Appear Offline": "Відображати як не в мережі", "Set Password": "Задати пароль", "Enable audible notifications in web client": "Увімкнути звукові сповіщення у мережевому застосунку", "Permalink": "Постійне посилання", diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index 89709bf97f..b5e4d76454 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -875,7 +875,6 @@ "Remember, you can always set an email address in user settings if you change your mind.": "请记住,如果您改变想法,您永远可以在用户设置中设置电子邮件。", "Explore Account Data": "探索账户数据", "All messages (noisy)": "全部消息(高亮)", - "Away": "离开", "Saturday": "星期六", "I understand the risks and wish to continue": "我了解这些风险并愿意继续", "Direct Chat": "私聊", @@ -890,7 +889,6 @@ "Collecting logs": "正在收集日志", "more": "更多", "GitHub issue link:": "Github issue 链接:", - "Bug report sent": "发送DEBUG报告", "You must specify an event type!": "你必须制定一个事件类型!", "(HTTP status %(httpStatus)s)": "(HTTP 状态 %(httpStatus)s)", "All Rooms": "全部聊天室", @@ -932,7 +930,6 @@ "Login": "登录", "Low Priority": "低优先级", "Unable to fetch notification target list": "无法获取通知目标列表", - "Appear Offline": "似乎离线了", "Set Password": "设置密码", "Enable audible notifications in web client": "在网页客户端启用音频通知", "Permalink": "永久链接", diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 9157a92331..2bfe08a2a1 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -713,7 +713,6 @@ "Send": "傳送", "Message Replies": "訊息回覆", "Message Pinning": "訊息釘選", - "Presence Management": "出席管理", "Disable Emoji suggestions while typing": "在輸入時停用繪文字建議", "Hide avatar changes": "隱藏大頭貼變更", "Hide display name changes": "隱藏顯示名稱變更", @@ -1081,7 +1080,6 @@ "Enable desktop notifications": "啟用桌面通知", "Explore Account Data": "探索帳號資料", "All messages (noisy)": "所有訊息(吵鬧)", - "Away": "離開", "Saturday": "星期六", "Remember, you can always set an email address in user settings if you change your mind.": "記住,如果您改變心意了,您永遠可以在使用者設定中設定電子郵件地址。", "Direct Chat": "私人聊天", @@ -1096,7 +1094,6 @@ "Collecting logs": "收集記錄", "more": "更多", "GitHub issue link:": "GitHub 問題回報連結:", - "Bug report sent": "已傳送臭蟲回報", "You must specify an event type!": "您必須指定事件類型!", "(HTTP status %(httpStatus)s)": "(HTTP 狀態 %(httpStatus)s)", "All Rooms": "所有的聊天室", @@ -1137,7 +1134,6 @@ "Login": "登入", "Low Priority": "低優先度", "Riot does not know how to join a room on this network": "Riot 不知道如何在此網路中加入聊天室", - "Appear Offline": "顯示為離線", "Set Password": "設定密碼", "Enable audible notifications in web client": "在網頁客戶端啟用音訊通知", "Permalink": "永久連結", From 941bb94234fbaae2c7c9aee93ac0c906839b0ada Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 20 Apr 2018 10:15:15 +0100 Subject: [PATCH 0812/1160] fix reply fallback blunder Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 6796e2bcc7..57401a03f2 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -192,22 +192,22 @@ export default class ReplyThread extends React.Component { case 'm.image': html = `
    In reply to ${mxid}` + `
    sent an image.
    `; - body = `> <${mxid}> sent an image.\n\n${body}`; + body = `> <${mxid}> sent an image.\n\n`; break; case 'm.video': html = `
    In reply to ${mxid}` + `
    sent a video.
    `; - body = `> <${mxid}> sent a video.\n\n${body}`; + body = `> <${mxid}> sent a video.\n\n`; break; case 'm.audio': html = `
    In reply to ${mxid}` + `
    sent an audio file.
    `; - body = `> <${mxid}> sent an audio file.\n\n${body}`; + body = `> <${mxid}> sent an audio file.\n\n`; break; case 'm.file': html = `
    In reply to ${mxid}` + `
    sent a file.
    `; - body = `> <${mxid}> sent a file.\n\n${body}`; + body = `> <${mxid}> sent a file.\n\n`; break; case 'm.emote': { html = `
    In reply to * ` From 6177a42dbfce05b8c669baac834b49c84b94071b Mon Sep 17 00:00:00 2001 From: Krombel Date: Fri, 20 Apr 2018 12:07:09 +0000 Subject: [PATCH 0813/1160] Translated using Weblate (German) Currently translated at 100.0% (1011 of 1011 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index e67c9fcaaa..b90376f2e4 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -1003,5 +1003,17 @@ "Unable to leave community": "Community konnte nicht verlassen werden", "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Änderungen am Namen und Bild deiner Community werden evtl. erst nach 30 Minuten von anderen Nutzern gesehen werden.", "Join this community": "Community beitreten", - "Leave this community": "Community verlassen" + "Leave this community": "Community verlassen", + "Sticker Messages": "Sticker-Nachrichten", + "You don't currently have any stickerpacks enabled": "Du hast aktuell keine Stickerpacks aktiviert", + "Click": "Klick", + "here": "hier", + "to add some!": "um einige hinzuzufügen!", + "Add a stickerpack": "Füge ein Stickerpack hinzu", + "Hide Stickers": "Sticker verbergen", + "Show Stickers": "Sticker zeigen", + "Manage sticker packs": "Verwalte Stickerpacks", + "Who can join this community?": "Wer kann dieser Community beitreten?", + "Everyone": "Jeder", + "Stickerpack": "Stickerpack" } From 3ea5fc9185c9d8a54ed6c09730b6989e44103e15 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 20 Apr 2018 14:06:09 +0100 Subject: [PATCH 0814/1160] Fix rageshake aka. Module Variables Are Not Global Variables pt. 319 --- src/rageshake/rageshake.js | 39 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/src/rageshake/rageshake.js b/src/rageshake/rageshake.js index 11e19a709e..93a52ba1aa 100644 --- a/src/rageshake/rageshake.js +++ b/src/rageshake/rageshake.js @@ -395,9 +395,6 @@ function selectQuery(store, keyRange, resultMapper) { } -let store = null; -let logger = null; -let initPromise = null; module.exports = { /** @@ -406,11 +403,11 @@ module.exports = { * @return {Promise} Resolves when set up. */ init: function() { - if (initPromise) { - return initPromise; + if (global.mx_rage_initPromise) { + return global.mx_rage_initPromise; } - logger = new ConsoleLogger(); - logger.monkeyPatch(window.console); + global.mx_rage_logger = new ConsoleLogger(); + global.mx_rage_logger.monkeyPatch(window.console); // just *accessing* indexedDB throws an exception in firefox with // indexeddb disabled. @@ -420,19 +417,19 @@ module.exports = { } catch(e) {} if (indexedDB) { - store = new IndexedDBLogStore(indexedDB, logger); - initPromise = store.connect(); - return initPromise; + global.mx_rage_store = new IndexedDBLogStore(indexedDB, global.mx_rage_logger); + global.mx_rage_initPromise = global.mx_rage_store.connect(); + return global.mx_rage_initPromise; } - initPromise = Promise.resolve(); - return initPromise; + global.mx_rage_initPromise = Promise.resolve(); + return global.mx_rage_initPromise; }, flush: function() { - if (!store) { + if (!global.mx_rage_store) { return; } - store.flush(); + global.mx_rage_store.flush(); }, /** @@ -440,10 +437,10 @@ module.exports = { * @return Promise Resolves if cleaned logs. */ cleanup: async function() { - if (!store) { + if (!global.mx_rage_store) { return; } - await store.consume(); + await global.mx_rage_store.consume(); }, /** @@ -452,21 +449,21 @@ module.exports = { * @return {Array<{lines: string, id, string}>} list of log data */ getLogsForReport: async function() { - if (!logger) { + if (!global.mx_rage_logger) { throw new Error( "No console logger, did you forget to call init()?" ); } // If in incognito mode, store is null, but we still want bug report // sending to work going off the in-memory console logs. - if (store) { + if (global.mx_rage_store) { // flush most recent logs - await store.flush(); - return await store.consume(); + await global.mx_rage_store.flush(); + return await global.mx_rage_store.consume(); } else { return [{ - lines: logger.flush(true), + lines: global.mx_rage_logger.flush(true), id: "-", }]; } From 3b859204245ec6ec99ed8cd9f2d8ada2a0170308 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 20 Apr 2018 14:28:20 +0100 Subject: [PATCH 0815/1160] Use mxid as sender name on set display name As it was, " set their display name to " which is unhelpful because you never knew them as "" before. They would previously have been displayed with their matrix ID, so that's what should be here. --- src/TextForEvent.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TextForEvent.js b/src/TextForEvent.js index e60bde4094..712150af4d 100644 --- a/src/TextForEvent.js +++ b/src/TextForEvent.js @@ -58,7 +58,7 @@ function textForMemberEvent(ev) { }); } else if (!prevContent.displayname && content.displayname) { return _t('%(senderName)s set their display name to %(displayName)s.', { - senderName, + senderName: ev.getSender(), displayName: content.displayname, }); } else if (prevContent.displayname && !content.displayname) { From 9685118f1609e91cf4a0f4d2d0e711c897ab9f6a Mon Sep 17 00:00:00 2001 From: RainSlide Date: Fri, 20 Apr 2018 07:27:11 +0000 Subject: [PATCH 0816/1160] Translated using Weblate (Chinese (Simplified)) Currently translated at 97.0% (981 of 1011 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hans/ --- src/i18n/strings/zh_Hans.json | 67 ++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index 3b49ac1658..2024ae50f8 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -921,5 +921,70 @@ "Please enter the code it contains:": "请输入它包含的代码:", "Flair will appear if enabled in room settings": "如果在聊天室设置中启用, flair 将会显示", "Matrix ID": "Matrix ID", - "Matrix Room ID": "Matrix 聊天室 ID" + "Matrix Room ID": "Matrix 聊天室 ID", + "Block users on other matrix homeservers from joining this room": "禁止其他 Matrix 主服务器上的用户加入此聊天室", + "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "要验证此设备是否可信,请通过其他方式(例如面对面交换或拨打电话)与其拥有者联系,并询问他们该设备的用户设置中的密钥是否与以下密钥匹配:", + "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "如果匹配,请点击下面的验证按钮。 如果不匹配,那么这可能说明其他人正在盗用此设备,而您应当点击黑名单按钮。", + "In future this verification process will be more sophisticated.": "在未来,这个验证过程将会更加精致、巧妙一些。", + "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "我们建议您对每台设备进行验证以保证它们属于其合法所有者,但是您可以在不验证它们的情况下重新发送消息。", + "

    HTML for your community's page

    \n

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

    \n

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

    \n": "

    社区页面的 HTML 代码

    \n

    \n 你可以给社区的新成员们写些长长的社区简介来引导他们,或者放置\n 一些重要的链接\n

    \n

    \n 你甚至可以使用 标签\n

    \n", + "Add rooms to the community summary": "将聊天室添加到社区简介", + "Which rooms would you like to add to this summary?": "您想要将哪个聊天室添加到社区简介?", + "Add to summary": "添加到简介", + "Failed to add the following rooms to the summary of %(groupId)s:": "添加以下聊天室到 %(groupId)s 的简介时失败:", + "Failed to remove the room from the summary of %(groupId)s": "从 %(groupId)s 的简介中移除此聊天室时失败", + "The room '%(roomName)s' could not be removed from the summary.": "聊天室 “%(roomName)s” 无法从社区简介中移除。", + "Failed to update community": "更新社区简介失败", + "Unable to leave community": "无法退出社区", + "Leave %(groupName)s?": "退出 %(groupName)s?", + "Featured Rooms:": "核心聊天室:", + "Featured Users:": "核心用户:", + "Join this community": "加入此社区", + "%(inviter)s has invited you to join this community": "%(inviter)s 邀请您加入此社区", + "Failed to add the following users to the summary of %(groupId)s:": "", + "Failed to remove a user from the summary of %(groupId)s": "", + "You are an administrator of this community": "你是此社区的管理员", + "You are a member of this community": "你是此社区的成员", + "Who can join this community?": "谁可以加入此社区?", + "Everyone": "所有人", + "Leave this community": "退出此社区", + "Long Description (HTML)": "长描述(HTML)", + "This Home server does not support communities": "该主服务器不支持社区", + "Old cryptography data detected": "检测到旧的加密数据", + "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "已检测到旧版Riot的数据,这将导致端到端加密在旧版本中发生故障。在此版本中,使用旧版本交换的端对端加密消息可能无法解密。这也可能导致与此版本交换的消息失败。如果您遇到问题,请退出并重新登录。要保留历史消息,请先导出并在重新登录后导入您的密钥。", + "Did you know: you can use communities to filter your Riot.im experience!": "你知道吗:你可以将社区用作过滤器以增强你的 Riot.im 使用体验!", + "Create a new community": "创建新社区", + "Error whilst fetching joined communities": "获取已加入社区列表时出现错误", + "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "创建社区,将用户与聊天室整合在一起!搭建自定义社区主页以在 Matrix 宇宙之中标记出您的私人空间。", + "Join an existing community": "加入已有的社区", + "Show devices, send anyway or cancel.": "显示未信任的设备不经信任直接发送取消发送。", + "%(count)s of your messages have not been sent.|one": "您的消息尚未发送。", + "Uploading %(filename)s and %(count)s others|other": "正在上传 %(filename)s 与其他 %(count)s 个文件", + "Uploading %(filename)s and %(count)s others|zero": "正在上传 %(filename)s", + "Uploading %(filename)s and %(count)s others|one": "正在上传 %(filename)s 与其他 %(count)s 个文件", + "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "隐私对我们而言重要至极,所以我们不会在分析统计服务中收集任何个人信息或者可用于识别身份的数据。", + "Learn more about how we use analytics.": "进一步了解我们如何使用分析统计服务。", + "Please note you are logging into the %(hs)s server, not matrix.org.": "请注意,您正在登录的服务器是 %(hs)s,不是 matrix.org。", + "This homeserver doesn't offer any login flows which are supported by this client.": "此主服务器不兼容本客户端支持的任何登录方式。", + "Sign in to get started": "登录以开始使用", + "Unbans user with given id": "使用 ID 解封特定的用户", + "Opens the Developer Tools dialog": "打开开发者工具窗口", + "Notify the whole room": "通知聊天室全体成员", + "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "此操作允许您将加密聊天室中收到的消息的密钥导出为本地文件。您可以将文件导入其他 Matrix 客户端,以便让别的客户端在未收到密钥的情况下解密这些消息。", + "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "导出的文件将允许任何可以读取它的人解密任何他们可以看到的加密消息,因此您应该小心以确保其安全。为了解决这个问题,您应该在下面输入一个密码,用于加密导出的数据。只有输入相同的密码才能导入数据。", + "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "导出文件有密码保护。你需要在此输入密码以解密此文件。", + "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "此操作允许您导入之前从另一个 Matrix 客户端中导出的加密密钥文件。导入完成后,您将能够解密那个客户端可以解密的加密消息。", + "Ignores a user, hiding their messages from you": "忽略用户,隐藏他们的消息", + "Stops ignoring a user, showing their messages going forward": "解除忽略用户,显示他们的消息", + "To return to your account in future you need to set a password": "如果你想再次使用账号,您得为它设置一个密码", + "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "如果你在 GitHub 提交了一个 bug,调试日志可以帮助我们追踪这个问题。 调试日志包含应用程序使用数据,这包括您的用户名、您访问的房间或社区的 ID 或名称以及其他用户的用户名,不包扩聊天记录。", + "Debug Logs Submission": "发送调试日志", + "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "密码修改成功。在您在其他设备上重新登录之前,其他设备不会收到推送通知", + "Tried to load a specific point in this room's timeline, but was unable to find it.": "尝试加载此房间的时间线的特定时间点,但是无法找到。", + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "现在 重新发送消息取消发送 。", + "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "現在 重新发送消息取消发送 。你也可以单独选择消息以重新发送或取消。", + "To join an existing community you'll have to know its community identifier; this will look something like +example:matrix.org.": "要加入已有的社区,你需要知道它的社区链接,比如 +example:matrix.org。", + "Visibility in Room List": "是否在聊天室目录中可见", + "Something went wrong when trying to get your communities.": "获取你加入的社区时发生错误。", + "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "删除小部件后,此聊天室中的所有用户的这个小部件都会被删除。你确定要删除这个小部件吗?" } From a5f4782964daa7cecddf95191cadd4ceefffb6d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Fri, 20 Apr 2018 06:21:09 +0000 Subject: [PATCH 0817/1160] Translated using Weblate (French) Currently translated at 100.0% (1011 of 1011 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index e8dfc87fb3..9b7bf87a6a 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -94,7 +94,7 @@ "Curve25519 identity key": "Clé d’identité Curve25519", "/ddg is not a command": "/ddg n'est pas une commande", "Deactivate Account": "Désactiver le compte", - "Deactivate my account": "désactiver mon compte", + "Deactivate my account": "Désactiver mon compte", "Decrypt %(text)s": "Déchiffrer %(text)s", "Decryption error": "Erreur de déchiffrement", "Delete": "Supprimer", From e04c762a50512b126ed1b0fd515207cb0e6f57ed Mon Sep 17 00:00:00 2001 From: Gergely Bakos Date: Wed, 18 Apr 2018 19:34:28 +0000 Subject: [PATCH 0818/1160] Translated using Weblate (Hungarian) Currently translated at 100.0% (1011 of 1011 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index b7f20d52f7..23ab91215e 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -10,7 +10,7 @@ "Mute": "Elnémít", "Notifications": "Értesítések", "Operation failed": "Sikertelen művelet", - "powered by Matrix": "A Matrix hajtja", + "powered by Matrix": "Matrix hajtja", "Remove": "Eltávolítás", "Settings": "Beállítások", "unknown error code": "ismeretlen hibakód", @@ -702,7 +702,7 @@ "Disable Emoji suggestions while typing": "Emoji ajánlások kikapcsolása gépelés közben", "Banned by %(displayName)s": "Kitiltotta: %(displayName)s", "Message removed by %(userId)s": "Üzenetet törölte: %(userId)s", - "To send messages, you must be a": "Ahhoz, hogy üzenetet tudj küldeni, neked ilyen szinten kell lenned:", + "To send messages, you must be a": "Ahhoz, hogy üzenetet tudj küldeni, ilyen szinten kell lenned:", "To invite users into the room, you must be a": "Hogy meghívj valakit a szobába, ilyen szinten kell lenned:", "To configure the room, you must be a": "A szoba beállításához ilyen szinten kell lenned:", "To kick users, you must be a": "Felhasználó kirúgásához ilyen szinten kell lenned:", @@ -712,7 +712,7 @@ "To change the room's avatar, you must be a": "A szoba avatarjának a megváltoztatásához ilyen szinten kell lenned:", "To change the room's name, you must be a": "A szoba nevének megváltoztatásához ilyen szinten kell lenned:", "To change the room's main address, you must be a": "A szoba elsődleges címének a megváltoztatásához ilyen szinten kell lenned:", - "To change the room's history visibility, you must be a": "A szoba naplója elérhetőségének a megváltoztatásához ilyen szinten kell lenned:", + "To change the room's history visibility, you must be a": "A szoba napló elérhetőségének a megváltoztatásához ilyen szinten kell lenned:", "To change the permissions in the room, you must be a": "A szobában a jogosultság megváltoztatásához ilyen szinten kell lenned:", "To change the topic, you must be a": "A téma megváltoztatásához ilyen szinten kell lenned:", "To modify widgets in the room, you must be a": "A szoba kisalkalmazásainak megváltoztatásához ilyen szinten kell lenned:", @@ -736,7 +736,7 @@ "Failed to remove the room from the summary of %(groupId)s": "Az alábbi szobákat nem sikerült eltávolítani a(z) %(groupId)s csoport összefoglalójából", "The room '%(roomName)s' could not be removed from the summary.": "Nem sikerült törölni az összefoglalóból ezt a szobát: '%(roomName)s'.", "Failed to remove a user from the summary of %(groupId)s": "Nem sikerült törölni az összefoglalóból ezt a felhasználót: %(groupId)s", - "The user '%(displayName)s' could not be removed from the summary.": "Nem sikerült törölni az összefoglalóból ezt a felhasználót: %(groupId)s.", + "The user '%(displayName)s' could not be removed from the summary.": "Nem sikerült törölni az összefoglalóból a(z) %(displayName)s felhasználót", "Light theme": "Világos téma", "Dark theme": "Sötét téma", "Unknown": "Ismeretlen", @@ -984,7 +984,7 @@ "Failed to add tag %(tagName)s to room": "Nem sikerült hozzáadni a szobához ezt: %(tagName)s", "Clear filter": "Szűrő törlése", "Disable Community Filter Panel": "Közösség keresési panel tiltása", - "Did you know: you can use communities to filter your Riot.im experience!": "Tudtad, hogy a közösségeket használhatod a Riot.im élmény fokozásához?", + "Did you know: you can use communities to filter your Riot.im experience!": "Tudtad, hogy a Riot.im élmény fokozásához használhatsz közösségeket?", "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "A szűrő beállításához húzd a közösség avatarját a szűrő panel fölé a képernyő bal szélén. A szűrő panelen az avatarra kattintva bármikor leszűrheted azokat a szobákat és embereket akik a megadott közösséghez tartoznak.", "Your key share request has been sent - please check your other devices for key share requests.": "A kulcs megosztási kérést elküldtük - ellenőrizd a többi eszközödön a kulcs megosztási kéréseket.", "Key share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, click here to request the keys for this session again.": "A kulcs megosztási kérelem automatikusan el lett küldve a többi eszközödre. Ha elutasítottad vagy törölted a kérést a másik eszközön ide kattintva újra kérheted a kulcsokat.", From 53889706d7e17334c36f60ee5307e80649a81973 Mon Sep 17 00:00:00 2001 From: toriko Date: Thu, 19 Apr 2018 05:30:33 +0000 Subject: [PATCH 0819/1160] Translated using Weblate (Japanese) Currently translated at 8.8% (89 of 1011 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ja/ --- src/i18n/strings/ja.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ja.json b/src/i18n/strings/ja.json index b4445af879..ce77c0b994 100644 --- a/src/i18n/strings/ja.json +++ b/src/i18n/strings/ja.json @@ -73,5 +73,19 @@ "Unnamed room": "名前のない部屋", "World readable": "誰でも読むことができます", "Guests can join": "ゲストが参加できます", - "No rooms to show": "表示する部屋がありません" + "No rooms to show": "表示する部屋がありません", + "This email address is already in use": "このメールアドレスは既に使われています", + "This phone number is already in use": "この電話番号は既に使われています", + "Failed to verify email address: make sure you clicked the link in the email": "メールアドレスの認証に失敗しました。メール中のリンクをクリックしたか、確認してください", + "The platform you're on": "利用中のプラットフォーム", + "The version of Riot.im": "Riot.imのバージョン", + "Whether or not you're logged in (we don't record your user name)": "ログインしているか否か(私達はあなたのユーザ名を記録しません)", + "Your language of choice": "選択した言語", + "Which officially provided instance you are using, if any": "どの公式に提供されたインスタンスを利用していますか(もしあれば)", + "Whether or not you're using the Richtext mode of the Rich Text Editor": "リッチテキストエディタのリッチテキストモードを利用しているか否か", + "Your homeserver's URL": "あなたのホームサーバのURL", + "Your identity server's URL": "あなたのアイデンティティサーバのURL", + "Analytics": "分析", + "The information being sent to us to help make Riot.im better includes:": "Riot.imをよりよくするために私達に送信される情報は以下を含みます:", + "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "私達はこのアプリであなたが利用したページ(現在は)、あなたのユーザエージェント(現在は)、並びにあなたの端末の解像度(現在の端末では)も記録します。" } From 105a0d6891ce65135c9eff5aa66d93ea2d41bf48 Mon Sep 17 00:00:00 2001 From: adrian-007 Date: Thu, 19 Apr 2018 14:28:10 +0000 Subject: [PATCH 0820/1160] Translated using Weblate (Polish) Currently translated at 76.9% (778 of 1011 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/pl/ --- src/i18n/strings/pl.json | 87 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/pl.json b/src/i18n/strings/pl.json index 9f672277f6..e031f78394 100644 --- a/src/i18n/strings/pl.json +++ b/src/i18n/strings/pl.json @@ -444,8 +444,8 @@ "This email address was not found": "Podany adres e-mail nie został znaleziony", "Must be viewing a room": "Musi być w trakcie wyświetlania pokoju", "The email address linked to your account must be entered.": "Musisz wpisać adres e-mail połączony z twoim kontem.", - "The file '%(fileName)s' exceeds this home server's size limit for uploads": "Rozmiar folderu '%(fileName)s' przekracza możliwy limit do przesłania na serwer domowy", - "The file '%(fileName)s' failed to upload": "Przesyłanie folderu '%(fileName)s' nie powiodło się", + "The file '%(fileName)s' exceeds this home server's size limit for uploads": "Rozmiar pliku '%(fileName)s' przekracza możliwy limit do przesłania na serwer domowy", + "The file '%(fileName)s' failed to upload": "Przesyłanie pliku '%(fileName)s' nie powiodło się", "The remote side failed to pick up": "Strona zdalna nie odebrała", "This room has no local addresses": "Ten pokój nie ma lokalnych adresów", "This room is not recognised.": "Ten pokój nie został rozpoznany.", @@ -698,5 +698,86 @@ "Your homeserver's URL": "Adres URL twojego serwera domowego", "Your identity server's URL": "Adres URL twojego serwera tożsamości", "The information being sent to us to help make Riot.im better includes:": "Oto informacje przesyłane do nas, służące do poprawy Riot.im:", - "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "Zapisujemy również każdą stronę, z której korzystasz w aplikacji (obecnie ), twój User Agent () oraz rozdzielczość ekranu twojego urządzenia ()." + "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "Zapisujemy również każdą stronę, z której korzystasz w aplikacji (obecnie ), twój User Agent () oraz rozdzielczość ekranu twojego urządzenia ().", + "The platform you're on": "Platforma na której jesteś", + "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "W tym pokoju są nieznane urządzenia: jeżeli będziesz kontynuować bez ich weryfikacji, możliwe będzie podsłuchiwanie Twojego połączenia.", + "Answer": "Odbierz", + "Review Devices": "Przegląd urządzeń", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(day)s %(monthName)s %(fullYear)s", + "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Uwaga: każda osoba dodana do Społeczności będzie publicznie widoczna dla każdego, go zna identyfikator społeczności", + "Invite new community members": "Zaproś nowych członków Społeczności", + "Name or matrix ID": "Nazwa lub matrix ID", + "Show these rooms to non-members on the community page and room list?": "Pokazać te pokoje dla osób niebędących członkami na stronie Społeczności oraz liście pokoi?", + "Add rooms to the community": "Dodaj pokoje do Społeczności", + "Failed to invite the following users to %(groupId)s:": "Nie udało się zaprosić poniższych użytkowników do %(groupId)s:", + "Failed to invite users to community": "Nie udało się zaprosić użytkowników do Społeczności", + "Failed to invite users to %(groupId)s": "Nie udało się zaprosić użytkowników do %(groupId)s", + "Failed to add the following rooms to %(groupId)s:": "Nie udało się dodać poniższych pokoi do %(groupId)s:", + "Restricted": "Ograniczony", + "Ignored user": "Użytkownik ignorowany", + "You are now ignoring %(userId)s": "Ignorujesz teraz %(userId)s", + "You are no longer ignoring %(userId)s": "Nie ignorujesz już %(userId)s", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s zmienił swoją wyświetlaną nazwę na %(displayName)s.", + "%(senderName)s changed the pinned messages for the room.": "%(senderName)s zmienił przypiętą wiadomość dla tego pokoju.", + "Message Pinning": "Przypinanie wiadomości", + "%(names)s and %(count)s others are typing|other": "%(names)s oraz %(count)s innych piszą", + "%(names)s and %(count)s others are typing|one": "%(names)s oraz jedna inna osoba piszą", + "Send": "Wyślij", + "Disable Emoji suggestions while typing": "Wyłącz podpowiedzi Emoji podczas pisania", + "Hide avatar changes": "Ukryj zmiany awatarów", + "Hide display name changes": "Ukryj zmiany wyświetlanych nazw", + "Disable big emoji in chat": "Wyłącz duże Emoji w czacie", + "Mirror local video feed": "Powiel lokalne wideo", + "Disable Community Filter Panel": "Wyłącz Panel Filtra Społeczności", + "Enable inline URL previews by default": "Włącz domyślny podgląd URL w tekście", + "Enable URL previews for this room (only affects you)": "Włącz podgląd URL dla tego pokoju (dotyczy tylko Ciebie)", + "Enable URL previews by default for participants in this room": "Włącz domyślny podgląd URL dla uczestników w tym pokoju", + "Delete %(count)s devices|other": "Usunięto %(count)s urządzeń", + "Delete %(count)s devices|one": "Usunięto urządzenie", + "Select devices": "Wybierz urządzenia", + "Click": "Kliknij", + "here": "tutaj", + "%(senderName)s sent an image": "%(senderName)s wysłał(a) obrazek", + "%(senderName)s sent a video": "%(senderName)s wysłał(a) wideo", + "%(senderName)s uploaded a file": "%(senderName)s wysłał(a) plik", + "Your key share request has been sent - please check your other devices for key share requests.": "Twoja prośba o podzielenie się kluczem została wysłana - sprawdź swoje inne urządzenie w celu spełnienia prośby.", + "Key share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, click here to request the keys for this session again.": "Prośby o podzielenie się kluczem są wysyłane do Twoich innych urządzeń automatycznie. Jeżeli prośba została odrzucona na innym urządzeniu, kliknij tutaj aby ponownie poprosić o podzielenie się kluczem dla tej sesji.", + "If your other devices do not have the key for this message you will not be able to decrypt them.": "Jeżeli inne Twoje urządzenia nie mają klucza dla tej wiadomości, nie będziesz w stanie ich odszyfrować.", + "Key request sent.": "Prośba o klucz wysłana.", + "Re-request encryption keys from your other devices.": "Poproś ponownie o klucze szyfrujące z Twojego innego urządzenia.", + "Kick this user?": "Wyrzucić tego użytkownika?", + "Unban this user?": "Odbanować tego użytkownika?", + "Ban this user?": "Zbanować tego użytkownika?", + "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Nie będziesz w stanie odwrócić tej zmiany, ponieważ degradujesz się sam(a), jeżeli jesteś ostatnim użytkownikiem z uprawnieniami w tym pokoju, niemożliwe będzie odzyskanie uprawnień.", + "Ignore": "Ignoruj", + "Mention": "Wspomnij", + "Invite": "Zaproś", + "User Options": "Opcje Użytkownika", + "Send an encrypted reply…": "Wyślij zaszyfrowaną odpowiedź…", + "Send a reply (unencrypted)…": "Wyślij odpowiedź (nieszyfrowaną)…", + "Send an encrypted message…": "Wyślij zaszyfrowaną wiadomość…", + "Send a message (unencrypted)…": "Wyślij wiadomość (niezaszyfrowaną)…", + "Jump to message": "Skocz do wiadomości", + "No pinned messages.": "Brak przypiętych wiadomości.", + "Loading...": "Ładowanie...", + "Pinned Messages": "Przypięte Wiadomości", + "Online for %(duration)s": "Online przez %(duration)s", + "Idle for %(duration)s": "Nieaktywny przez %(duration)s", + "Offline for %(duration)s": "Offline przez %(duration)s", + "Unknown for %(duration)s": "Nieznany przez %(duration)s", + "Unknown": "Nieznany", + "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Widziane przez %(displayName)s (%(userName)s) o %(dateTime)s", + "No rooms to show": "Brak pokoi do pokazania", + "Unnamed room": "Nienazwany pokój", + "Guests can join": "Goście mogą dołączyć", + "Remove avatar": "Usuń awatar", + "Drop here to favourite": "Upuść to aby dodać do ulubionych", + "Drop here to restore": "Upuść tu aby przywrócić", + "Drop here to demote": "Upuść tu aby zdegradować", + "You have been kicked from this room by %(userName)s.": "Zostałeś usunięty z tego pokoju przez %(userName)s.", + "You have been banned from this room by %(userName)s.": "Zostałeś zbanowany z tego pokoju przez %(userName)s.", + "You are trying to access a room.": "Próbujesz uzyskać dostęp do pokoju.", + "To change the room's avatar, you must be a": "Aby zmienić awatar pokoju, musisz być", + "To change the room's name, you must be a": "Aby zmienić nazwę pokoju, musisz być", + "To change the room's main address, you must be a": "Aby zmienić główny adres pokoju, musisz być" } From 6154c13c95c57045e9475c29ad050961daf47712 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 20 Apr 2018 15:35:31 +0100 Subject: [PATCH 0821/1160] Re-run npm run i18n --- src/i18n/strings/en_EN.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 4422c754d5..d90b120bad 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -171,7 +171,6 @@ "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s widget modified by %(senderName)s", "%(widgetName)s widget added by %(senderName)s": "%(widgetName)s widget added by %(senderName)s", "%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s widget removed by %(senderName)s", - "Message Pinning": "Message Pinning", "%(displayName)s is typing": "%(displayName)s is typing", "%(names)s and %(count)s others are typing|other": "%(names)s and %(count)s others are typing", "%(names)s and %(count)s others are typing|one": "%(names)s and one other is typing", @@ -187,7 +186,6 @@ "Failed to join room": "Failed to join room", "Message Replies": "Message Replies", "Message Pinning": "Message Pinning", - "Presence Management": "Presence Management", "Tag Panel": "Tag Panel", "Sticker Messages": "Sticker Messages", "Disable Emoji suggestions while typing": "Disable Emoji suggestions while typing", @@ -738,7 +736,6 @@ "Try using one of the following valid address types: %(validTypesList)s.": "Try using one of the following valid address types: %(validTypesList)s.", "You have entered an invalid address.": "You have entered an invalid address.", "Preparing to send logs": "Preparing to send logs", - "Bug report sent": "Bug report sent", "Logs sent": "Logs sent", "Thank you!": "Thank you!", "Failed to send logs: ": "Failed to send logs: ", @@ -856,8 +853,6 @@ "Permalink": "Permalink", "Quote": "Quote", "Source URL": "Source URL", - "Away": "Away", - "Appear Offline": "Appear Offline", "Failed to set Direct Message status of room": "Failed to set Direct Message status of room", "All messages (noisy)": "All messages (noisy)", "All messages": "All messages", From ce3d813c1291ee9e34bd697238187b5dcf607425 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 20 Apr 2018 15:37:19 +0100 Subject: [PATCH 0822/1160] Prune i18n --- src/i18n/strings/ar.json | 1 - src/i18n/strings/bg.json | 8 -------- src/i18n/strings/ca.json | 4 ---- src/i18n/strings/cs.json | 4 ---- src/i18n/strings/da.json | 3 --- src/i18n/strings/de_DE.json | 8 -------- src/i18n/strings/eo.json | 4 ---- src/i18n/strings/es.json | 3 --- src/i18n/strings/eu.json | 8 -------- src/i18n/strings/fi.json | 4 ---- src/i18n/strings/fr.json | 4 ---- src/i18n/strings/gl.json | 8 -------- src/i18n/strings/he.json | 2 -- src/i18n/strings/hu.json | 4 ---- src/i18n/strings/id.json | 1 - src/i18n/strings/it.json | 4 ---- src/i18n/strings/ko.json | 2 -- src/i18n/strings/lt.json | 3 --- src/i18n/strings/lv.json | 4 ---- src/i18n/strings/ml.json | 1 - src/i18n/strings/nl.json | 8 -------- src/i18n/strings/pl.json | 13 ++----------- src/i18n/strings/pt.json | 1 - src/i18n/strings/pt_BR.json | 4 ---- src/i18n/strings/ru.json | 5 ----- src/i18n/strings/sk.json | 8 -------- src/i18n/strings/sq.json | 2 -- src/i18n/strings/sr.json | 4 ---- src/i18n/strings/sv.json | 3 --- src/i18n/strings/ta.json | 1 - src/i18n/strings/uk.json | 3 --- src/i18n/strings/zh_Hans.json | 9 --------- src/i18n/strings/zh_Hant.json | 4 ---- 33 files changed, 2 insertions(+), 143 deletions(-) diff --git a/src/i18n/strings/ar.json b/src/i18n/strings/ar.json index cb223f5aaf..d461240e4b 100644 --- a/src/i18n/strings/ar.json +++ b/src/i18n/strings/ar.json @@ -43,7 +43,6 @@ "Collecting logs": "تجميع السجلات", "No update available.": "لا يوجد هناك أي تحديث.", "An error occurred whilst saving your email notification preferences.": "حدث خطأ ما أثناء عملية حفظ إعدادات الإشعارات عبر البريد الإلكتروني.", - "Bug report sent": "تم إرسال تقرير الأخطاء", "Collecting app version information": "تجميع المعلومات حول نسخة التطبيق", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "إلغاء مُعرف الغرفة %(alias)s وحذف %(name)s من الدليل؟", "Changelog": "سِجل التغييرات", diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 0992d550f1..88d70777f1 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -206,7 +206,6 @@ "Failed to join room": "Неуспешно присъединяване към стаята", "Message Replies": "Отговори на съобщението", "Message Pinning": "Функция за закачане на съобщения", - "Presence Management": "Управление на присъствието", "Tag Panel": "Панел с етикети", "Disable Emoji suggestions while typing": "Изключване на предложенията за емотиконите при писане", "Use compact timeline layout": "Използване на компактно оформление за списъка със съобщения", @@ -1000,13 +999,9 @@ "Stickerpack": "Пакет със стикери", "Sticker Messages": "Съобщения със стикери", "You don't currently have any stickerpacks enabled": "В момента нямате включени пакети със стикери", - "Click": "Кликнете", - "here": "тук,", - "to add some!": "за да добавите такива!", "Add a stickerpack": "Добави пакет със стикери", "Hide Stickers": "Скрий стикери", "Show Stickers": "Покажи стикери", - "Manage sticker packs": "Управляване на пакети със стикери", "Who can join this community?": "Кой може да се присъедини към тази общност?", "Everyone": "Всеки", "Fetching third party location failed": "Неуспешно извличане на адреса на стаята от друга мрежа", @@ -1083,7 +1078,6 @@ "Preparing to send logs": "Подготовка за изпращане на логове", "Explore Account Data": "Преглед на данните от профила", "All messages (noisy)": "Всички съобщения (шумно)", - "Away": "Отсъстващ", "Saturday": "Събота", "Remember, you can always set an email address in user settings if you change your mind.": "Ако си промените мнението, винаги може да зададете имейл адрес в настройки на потребителя.", "Direct Chat": "Директен чат", @@ -1120,7 +1114,6 @@ "Notify for all other messages/rooms": "Извести ме за всички други съобщения/стаи", "Unable to look up room ID from server": "Стая с такъв идентификатор не е намерена на сървъра", "Couldn't find a matching Matrix room": "Не успяхме да намерим съответната Matrix стая", - "Bug report sent": "Докладът за грешки е изпратен", "Invite to this room": "Покани в тази стая", "You cannot delete this message. (%(code)s)": "Това съобщение не може да бъде изтрито. (%(code)s)", "Thursday": "Четвъртък", @@ -1141,7 +1134,6 @@ "Low Priority": "Нисък приоритет", "What's New": "Какво ново", "Set Password": "Задаване на парола", - "Appear Offline": "Показване като офлайн", "An error occurred whilst saving your email notification preferences.": "Възникна грешка при запазване на настройките за имейл известяване.", "Enable audible notifications in web client": "Включване на звукови известия в уеб клиент", "Permalink": "Permalink", diff --git a/src/i18n/strings/ca.json b/src/i18n/strings/ca.json index 9774b5bb20..b95c4914b1 100644 --- a/src/i18n/strings/ca.json +++ b/src/i18n/strings/ca.json @@ -213,7 +213,6 @@ "Failed to join room": "No s'ha pogut entrar a la sala", "Message Replies": "Respostes del missatge", "Message Pinning": "Fixació de missatges", - "Presence Management": "Gestió de presència", "Tag Panel": "Tauler d'etiquetes", "Disable Emoji suggestions while typing": "Desactiva els suggeriments d'Emoji mentre s'escriu", "Use compact timeline layout": "Utilitza el disseny compacte de la línia de temps", @@ -956,7 +955,6 @@ "Preparing to send logs": "Preparant l'enviament de logs", "Explore Account Data": "Explora les dades del compte", "Remove from Directory": "Elimina del directori", - "Away": "Absent", "Saturday": "Dissabte", "Remember, you can always set an email address in user settings if you change your mind.": "Recordeu-ho, si canvieu d'idea, sempre podreu establir una adreça de correu electrònic a las vostra configuració d'usuari.", "Direct Chat": "Xat directe", @@ -993,7 +991,6 @@ "Notify for all other messages/rooms": "Notifica per a tots els altres missatges o sales", "Unable to look up room ID from server": "No s'ha pogut cercar l'ID de la sala en el servidor", "Couldn't find a matching Matrix room": "No s'ha pogut trobar una sala de Matrix que coincideixi", - "Bug report sent": "S'ha enviat l'informe d'error", "Invite to this room": "Convida a aquesta sala", "You cannot delete this message. (%(code)s)": "No podeu eliminar aquest missatge. (%(code)s)", "Thursday": "Dijous", @@ -1014,7 +1011,6 @@ "Login": "Inicia sessió", "Low Priority": "Baixa prioritat", "Unable to fetch notification target list": "No s'ha pogut obtenir la llista d'objectius de les notificacions", - "Appear Offline": "Apareix sense connexió", "Set Password": "Establiu una contrasenya", "Enable audible notifications in web client": "Habilita les notificacions d'àudio al client web", "Permalink": "Enllaç permanent", diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index 920c77dd25..d19f17e097 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -643,7 +643,6 @@ "%(senderName)s placed a %(callType)s call.": "%(senderName)s uskutečnil %(callType)s hovor.", "%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s zpřístupnil budoucí historii místnosti neznámým (%(visibility)s).", "Not a valid Riot keyfile": "Neplatný soubor s klíčem Riot", - "Presence Management": "Správce účasti", "Disable Emoji suggestions while typing": "Zakázat návrhy Emoji během psaní", "Hide avatar changes": "Skrýt změny avatara", "Hide display name changes": "Skrýt změny zobrazovaného jména", @@ -1018,7 +1017,6 @@ "Enable desktop notifications": "Zapnout upozornění na ploše", "Explore Account Data": "Prozkoumat data o účtu", "Remove from Directory": "Odebrat z adresáře", - "Away": "Pryč", "Saturday": "Sobota", "Messages in one-to-one chats": "Zprávy v individuálních chatech", "Direct Chat": "Přímý chat", @@ -1032,7 +1030,6 @@ "Toolbox": "Sada nástrojů", "Collecting logs": "Sbírání logů", "more": "více", - "Bug report sent": "Hlášení o chybě bylo odesláno", "You must specify an event type!": "Musíte určit typ události!", "(HTTP status %(httpStatus)s)": "(HTTP status %(httpStatus)s)", "Invite to this room": "Pozvat do této místnosti", @@ -1071,7 +1068,6 @@ "Low Priority": "Nízká priorita", "Riot does not know how to join a room on this network": "Riot neví, jak vstoupit do místosti na této síti", "Set Password": "Nastavit heslo", - "Appear Offline": "Jevit se offline", "An error occurred whilst saving your email notification preferences.": "Při ukládání nastavení e-mailových upozornění nastala chyba.", "Enable audible notifications in web client": "Povolit zvuková upozornění ve webové aplikaci", "Permalink": "Trvalý odkaz", diff --git a/src/i18n/strings/da.json b/src/i18n/strings/da.json index cc3ef49b55..d1393c1947 100644 --- a/src/i18n/strings/da.json +++ b/src/i18n/strings/da.json @@ -319,7 +319,6 @@ "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot bruger mange avancerede browser funktioner, hvoraf nogle af dem ikke er tilgængelige eller er eksperimentelle i din browser.", "Event sent!": "Begivenhed sendt!", "Explore Account Data": "Udforsk Konto Data", - "Away": "Ikke til stede", "Saturday": "Lørdag", "Remember, you can always set an email address in user settings if you change your mind.": "Husk, du kan altid indstille en emailadresse i dine bruger indstillinger hvis du ombestemmer dig.", "Direct Chat": "Personlig Chat", @@ -353,7 +352,6 @@ "Notify for all other messages/rooms": "Underret om alle andre meddelelser / rum", "Unable to look up room ID from server": "Kunne ikke slå rum-id op på server", "Couldn't find a matching Matrix room": "Kunne ikke finde et matchende Matrix-rum", - "Bug report sent": "Fejl rapporteret", "All Rooms": "Alle rum", "You cannot delete this message. (%(code)s)": "Du kan ikke slette denne besked. (%(code)s)", "Thursday": "Torsdag", @@ -371,7 +369,6 @@ "Event Type": "Begivenhedstype", "Low Priority": "Lav prioritet", "Unable to fetch notification target list": "Kan ikke hente meddelelsesmålliste", - "Appear Offline": "Fremstå Offline", "Set Password": "Indstil Password", "Enable audible notifications in web client": "Aktivér hørbare underretninger i webklienten", "Permalink": "Permanent link", diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 521cd3a4ab..2030b4285a 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -907,7 +907,6 @@ "URL previews are disabled by default for participants in this room.": "URL-Vorschau ist für Mitglieder dieses Raumes standardmäßig deaktiviert.", "URL previews are enabled by default for participants in this room.": "URL-Vorschau ist für Mitglieder dieses Raumes standardmäßig aktiviert.", "Restricted": "Eingeschränkt", - "Presence Management": "Anwesenheitsmanagement", "Status.im theme": "Status.im-Thema", "%(duration)ss": "%(duration)ss", "%(duration)sm": "%(duration)sm", @@ -999,13 +998,9 @@ "Leave this community": "Community verlassen", "Sticker Messages": "Sticker-Nachrichten", "You don't currently have any stickerpacks enabled": "Du hast aktuell keine Stickerpacks aktiviert", - "Click": "Klick", - "here": "hier", - "to add some!": "um einige hinzuzufügen!", "Add a stickerpack": "Füge ein Stickerpack hinzu", "Hide Stickers": "Sticker verbergen", "Show Stickers": "Sticker zeigen", - "Manage sticker packs": "Verwalte Stickerpacks", "Who can join this community?": "Wer kann dieser Community beitreten?", "Everyone": "Jeder", "Stickerpack": "Stickerpack", @@ -1086,7 +1081,6 @@ "Remember, you can always set an email address in user settings if you change your mind.": "Vergiss nicht, dass du in den Benutzereinstellungen jederzeit eine E-Mail-Adresse setzen kannst, wenn du deine Meinung änderst.", "Explore Account Data": "Benutzerkonto-Daten analysieren", "All messages (noisy)": "Alle Nachrichten (laut)", - "Away": "Abwesend", "Saturday": "Samstag", "I understand the risks and wish to continue": "Ich verstehe das Risiko und möchte fortfahren", "Direct Chat": "Direkt-Chat", @@ -1101,7 +1095,6 @@ "Collecting logs": "Protokolle werden abgerufen", "more": "mehr", "GitHub issue link:": "Link des GitHub-Problems:", - "Bug report sent": "Fehlerbericht wurde gesendet", "You must specify an event type!": "Du musst einen Event-Typ spezifizieren!", "(HTTP status %(httpStatus)s)": "(HTTP-Status %(httpStatus)s)", "Invite to this room": "In diesen Raum einladen", @@ -1142,7 +1135,6 @@ "Login": "Anmeldung", "Low Priority": "Niedrige Priorität", "Unable to fetch notification target list": "Liste der Benachrichtigungsempfänger konnte nicht abgerufen werden", - "Appear Offline": "Als offline anzeigen", "Set Password": "Passwort einrichten", "Enable audible notifications in web client": "Audio-Benachrichtigungen im Web-Client aktivieren", "Permalink": "Permanenter Link", diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index f62c4b7c2d..cad55cf662 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -165,7 +165,6 @@ "Authentication check failed: incorrect password?": "Aŭtentiga kontrolo malsukcesis: ĉu pro malĝusta pasvorto?", "Failed to join room": "Malsukcesis aliĝi al ĉambro", "Message Pinning": "Fikso de mesaĝoj", - "Presence Management": "Ĉeesta administrado", "Tag Panel": "Etikeda panelo", "Disable Emoji suggestions while typing": "Malŝalti mienetajn sugestojn dum tajpado", "Use compact timeline layout": "Uzi densan okazordan aranĝon", @@ -1032,7 +1031,6 @@ "Event sent!": "Okazo sendiĝis!", "Explore Account Data": "Esplori kontajn datumojn", "All messages (noisy)": "Ĉiuj mesaĝoj (lauta)", - "Away": "Foresta", "Saturday": "Sabato", "Remember, you can always set an email address in user settings if you change your mind.": "Memoru: vi ĉiam povas agordi retpoŝtadreson en viaj agordoj por uzantoj.", "Direct Chat": "Rekta babilo", @@ -1046,7 +1044,6 @@ "Toolbox": "Ilaro", "Collecting logs": "Kolektante protokolon", "more": "pli", - "Bug report sent": "Cimraporto sendiĝis", "You must specify an event type!": "Vi devas specifi tipon de okazo!", "(HTTP status %(httpStatus)s)": "(stato de HTTP %(httpStatus)s)", "Invite to this room": "Inviti al ĉi tiu ĉambro", @@ -1087,7 +1084,6 @@ "Login": "Saluti", "Low Priority": "Malalta prioritato", "Unable to fetch notification target list": "Malsukcesis akiri la liston de celoj por sciigoj", - "Appear Offline": "Montriĝi kiel eksterreta", "Set Password": "Agordi pasvorton", "Enable audible notifications in web client": "Ŝalti aŭdeblajn sciigojn en la retkliento", "Permalink": "Konstanta ligilo", diff --git a/src/i18n/strings/es.json b/src/i18n/strings/es.json index 36bf4b7b3b..07b38d7566 100644 --- a/src/i18n/strings/es.json +++ b/src/i18n/strings/es.json @@ -666,7 +666,6 @@ "Unnamed room": "Sala sin nombre", "Explore Account Data": "Explorar Datos de la Cuenta", "Remove from Directory": "Retirar del Directorio", - "Away": "Ausente", "Saturday": "Sábado", "Remember, you can always set an email address in user settings if you change your mind.": "Recuerda que si es necesario puedes establecer una dirección de email en las preferencias de usuario.", "Direct Chat": "Conversación directa", @@ -681,7 +680,6 @@ "Collecting logs": "Recolectando registros", "more": "más", "GitHub issue link:": "Enlace de incidencia en GitHub:", - "Bug report sent": "Informe de fallo enviado", "You must specify an event type!": "Debes especificar un tipo de evento!", "(HTTP status %(httpStatus)s)": "(estado HTTP %(httpStatus)s)", "Invite to this room": "Invitar a esta sala", @@ -722,7 +720,6 @@ "Login": "Iniciar sesión", "Low Priority": "Baja Prioridad", "Riot does not know how to join a room on this network": "Riot no sabe cómo unirse a una sala en esta red", - "Appear Offline": "Mostrarse Desconectado", "Set Password": "Establecer contraseña", "Enable audible notifications in web client": "Habilitar notificaciones audibles en el cliente web", "Permalink": "Enlace permanente", diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index 93f150294d..853a2de6c0 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -731,7 +731,6 @@ "%(names)s and %(count)s others are typing|one": "%(names)s eta beste bat idazten ari dira", "Send": "Bidali", "Message Pinning": "Mezuak finkatzea", - "Presence Management": "Presentzia-kudeaketa", "Tag Panel": "Etiketen panela", "Hide avatar changes": "Ezkutatu abatar aldaketak", "Hide display name changes": "Ezkutatu pantaila izenen aldaketak", @@ -1000,13 +999,9 @@ "Stickerpack": "Eranskailu-multzoa", "Sticker Messages": "Eranskailu mezuak", "You don't currently have any stickerpacks enabled": "Ez duzu eranskailu multzorik aktibatuta", - "Click": "Klik", - "here": "hemen", - "to add some!": "batzuk gehitzeko!", "Add a stickerpack": "Gehitu eranskailu-multzoa", "Hide Stickers": "Ezkutatu eranskailuak", "Show Stickers": "Erakutsi eranskailuak", - "Manage sticker packs": "Kudeatu eranskailu-multzoak", "Who can join this community?": "Nor elkartu daiteke komunitate honetara?", "Everyone": "Edonor", "Fetching third party location failed": "Huts egin du hirugarrengoen kokalekua eskuratzean", @@ -1086,7 +1081,6 @@ "Remember, you can always set an email address in user settings if you change your mind.": "Gogoratu, e-mail helbide bat ezarri dezakezu erabiltzaile-ezarpenetan iritzia aldatzen baduzu.", "Explore Account Data": "Miatu kantuaren datuak", "All messages (noisy)": "Mezu guztiak (ozen)", - "Away": "Teklatutik at", "Saturday": "Larunbata", "I understand the risks and wish to continue": "Arriskua ulertzen dut eta jarraitu nahi dut", "Direct Chat": "Txat zuzena", @@ -1101,7 +1095,6 @@ "Collecting logs": "Egunkariak biltzen", "more": "gehiago", "GitHub issue link:": "Arazoaren esteka GitHuben:", - "Bug report sent": "Arazte-txostena bidali da", "You must specify an event type!": "Gertaera mota bat zehaztu behar duzu!", "(HTTP status %(httpStatus)s)": "(HTTP egoera %(httpStatus)s)", "All Rooms": "Gela guztiak", @@ -1143,7 +1136,6 @@ "Login": "Hasi saioa", "Low Priority": "Lehentasun baxua", "Unable to fetch notification target list": "Ezin izan da jakinarazpen helburuen zerrenda eskuratu", - "Appear Offline": "Agertu deskonektatuta", "Set Password": "Ezarri pasahitza", "Enable audible notifications in web client": "Gaitu jakinarazpen entzungarriak web bezeroan", "Permalink": "Esteka iraunkorra", diff --git a/src/i18n/strings/fi.json b/src/i18n/strings/fi.json index 4a83f456c7..7f7ac9729f 100644 --- a/src/i18n/strings/fi.json +++ b/src/i18n/strings/fi.json @@ -831,7 +831,6 @@ "%(widgetName)s widget added by %(senderName)s": "%(widgetName)s pienoisohjelman lisännyt %(senderName)s", "%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s pienoisohjelman poistanut %(senderName)s", "Send": "Lähetä", - "Presence Management": "Tilanhallinta", "Tag Panel": "Tagit", "Delete %(count)s devices|other": "Poista %(count)s laitetta", "Delete %(count)s devices|one": "Poista laite", @@ -1004,7 +1003,6 @@ "Enable desktop notifications": "Ota käyttöön työpöytäilmoitukset", "Explore Account Data": "Tilitiedot", "All messages (noisy)": "Kaikki viestit (äänekkäästi)", - "Away": "Poissa", "Saturday": "Lauantai", "Remember, you can always set an email address in user settings if you change your mind.": "Muista että voit aina asettaa sähköpostiosoitteen käyttäjäasetuksista jos muutat mielesi.", "Direct Chat": "Suora viestittely", @@ -1019,7 +1017,6 @@ "Toolbox": "Työkalut", "Collecting logs": "Haetaan lokitietoja", "more": "lisää", - "Bug report sent": "Virheraportti lähetetty", "You must specify an event type!": "Sinun on määritettävä tapahtuman tyyppi!", "(HTTP status %(httpStatus)s)": "(HTTP tila %(httpStatus)s)", "All Rooms": "Kaikki huoneet", @@ -1058,7 +1055,6 @@ "Low Priority": "Matala prioriteetti", "Unable to fetch notification target list": "Ilmoituskohdelistan haku epäonnistui", "Set Password": "Aseta salasana", - "Appear Offline": "Offline-tila", "An error occurred whilst saving your email notification preferences.": "Sähköposti-ilmoitusasetuksia tallettaessa tapahtui virhe.", "Enable audible notifications in web client": "Ota käyttöön äänelliset ilmoitukset", "Permalink": "Pysyvä linkki", diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 1800476c46..ca47cd52a8 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -900,7 +900,6 @@ "Username on %(hs)s": "Nom d'utilisateur sur %(hs)s", "Restricted": "Restreint", "Custom of %(powerLevel)s": "Personnalisé de %(powerLevel)s", - "Presence Management": "Gestion de présence", "Hide avatar changes": "Masquer les changements d'avatar", "Hide display name changes": "Masquer les changements de nom affiché", "Enable inline URL previews by default": "Activer l'aperçu des URL par défaut", @@ -1079,7 +1078,6 @@ "Remember, you can always set an email address in user settings if you change your mind.": "Souvenez-vous que vous pourrez toujours définir une adresse e-mail dans les paramètres de l'utilisateur si vous changez d’avis.", "Explore Account Data": "Explorer les données du compte", "Remove from Directory": "Supprimer du répertoire", - "Away": "Absent", "Saturday": "Samedi", "I understand the risks and wish to continue": "Je comprends les risques et souhaite continuer", "Direct Chat": "Discussion directe", @@ -1093,7 +1091,6 @@ "Toolbox": "Boîte à outils", "Collecting logs": "Récupération des journaux", "more": "plus", - "Bug report sent": "Rapport d'erreur envoyé", "You must specify an event type!": "Vous devez spécifier un type d'événement !", "(HTTP status %(httpStatus)s)": "(état HTTP %(httpStatus)s)", "Invite to this room": "Inviter dans ce salon", @@ -1132,7 +1129,6 @@ "Login": "Connexion", "Low Priority": "Priorité basse", "Unable to fetch notification target list": "Impossible de récupérer la liste des appareils recevant les notifications", - "Appear Offline": "Apparaître Hors ligne", "Set Password": "Définir un mot de passe", "Enable audible notifications in web client": "Activer les notifications sonores pour le client web", "Permalink": "Permalien", diff --git a/src/i18n/strings/gl.json b/src/i18n/strings/gl.json index 1883d29bb2..95363334fb 100644 --- a/src/i18n/strings/gl.json +++ b/src/i18n/strings/gl.json @@ -169,7 +169,6 @@ "Authentication check failed: incorrect password?": "Fallou a comprobación de autenticación: contrasinal incorrecto?", "Failed to join room": "Non se puido unir a sala", "Message Pinning": "Fixando mensaxe", - "Presence Management": "Xestión da presenza", "Tag Panel": "Panel de etiquetas", "Disable Emoji suggestions while typing": "Deshabilitar a suxestión de Emoji mentras escribe", "Use compact timeline layout": "Utilizar a disposición compacta da liña temporal", @@ -1000,13 +999,9 @@ "Stickerpack": "Peganitas", "Sticker Messages": "Mensaxes pegadas", "You don't currently have any stickerpacks enabled": "Non ten paquetes de pegatinas habilitados", - "Click": "Clicar", - "here": "aquí", - "to add some!": "engada algún!", "Add a stickerpack": "Engadir un paquete de pegatinas", "Hide Stickers": "Agochar pegatinas", "Show Stickers": "Mostrar pegatinas", - "Manage sticker packs": "Xestionar os paquetes de pegatinas", "Who can join this community?": "Quén pode unirse a esta comunidade?", "Everyone": "Todo o mundo", "Fetching third party location failed": "Fallo ao obter a localización de terceiros", @@ -1086,7 +1081,6 @@ "Remember, you can always set an email address in user settings if you change your mind.": "Lembre, sempre poderá poñer un enderezo de correo nos axustes de usuario si cambia de idea.", "Explore Account Data": "Explorar datos da conta", "All messages (noisy)": "Todas as mensaxes (alto)", - "Away": "Fóra", "Saturday": "Sábado", "I understand the risks and wish to continue": "Entendos os riscos e desexo continuar", "Direct Chat": "Chat directo", @@ -1101,7 +1095,6 @@ "Collecting logs": "Obtendo rexistros", "more": "máis", "GitHub issue link:": "Ligazón ao reporte en GitHub:", - "Bug report sent": "Enviado o informe de fallo", "You must specify an event type!": "Debe indicar un tipo de evento!", "(HTTP status %(httpStatus)s)": "(Estado HTTP %(httpStatus)s)", "All Rooms": "Todas as Salas", @@ -1143,7 +1136,6 @@ "Login": "Conectar", "Low Priority": "Baixa prioridade", "Unable to fetch notification target list": "Non se puido procesar a lista de obxetivo de notificacións", - "Appear Offline": "Aparecer fora de liña", "Set Password": "Establecer contrasinal", "Enable audible notifications in web client": "Habilitar notificacións audibles no cliente web", "Permalink": "Ligazón permanente", diff --git a/src/i18n/strings/he.json b/src/i18n/strings/he.json index 9543a64b8f..7e747428a6 100644 --- a/src/i18n/strings/he.json +++ b/src/i18n/strings/he.json @@ -164,7 +164,6 @@ "Remember, you can always set an email address in user settings if you change your mind.": "להזכירך: תמיד ניתן לשנות כתובת אימייל בהגדרות משתש. למקרה שתתחרט/י.", "Explore Account Data": "גלה פרטי משתמש", "All messages (noisy)": "כל ההודעות (רועש)", - "Away": "מרוחק", "Saturday": "שבת", "I understand the risks and wish to continue": "אני מבין את הסיכונים אבל מבקש להמשיך", "Direct Chat": "שיחה ישירה", @@ -221,7 +220,6 @@ "Login": "התחבר", "Low Priority": "עדיפות נמוכה", "Unable to fetch notification target list": "לא ניתן לאחזר רשימת יעדי התראה", - "Appear Offline": "מופיע מקוון", "Set Password": "הגדר סיסמא", "Enable audible notifications in web client": "אפשר התראות קוליות בדפדפן", "Permalink": "קישור קבוע", diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 88e0fa22db..5fe1e90163 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -900,7 +900,6 @@ "Username on %(hs)s": "Felhasználónév a %(hs)s szerveren", "Restricted": "Korlátozott", "Custom of %(powerLevel)s": "Egyedi beállítás: %(powerLevel)s", - "Presence Management": "Jelenlét menedzsment", "Hide avatar changes": "Avatar változások elrejtése", "Hide display name changes": "Név változások elrejtése", "Enable inline URL previews by default": "Beágyazott URL előnézetek alapértelmezett engedélyezése", @@ -1082,7 +1081,6 @@ "Remember, you can always set an email address in user settings if you change your mind.": "Ha meggondolod magad, bármikor beállíthatod az e-mail címed a felhasználói beállításoknál.", "Explore Account Data": "Fiókadatok felderítése", "Remove from Directory": "Törlés a listából", - "Away": "Távol", "Saturday": "Szombat", "I understand the risks and wish to continue": "Megértettem a kockázatot és folytatom", "Direct Chat": "Közvetlen csevegés", @@ -1097,7 +1095,6 @@ "Collecting logs": "Naplók összegyűjtése", "more": "tovább", "GitHub issue link:": "GitHub hibajegy hivatkozás:", - "Bug report sent": "Hibajelentés elküldve", "You must specify an event type!": "Meg kell jelölnöd az eseménytípust!", "(HTTP status %(httpStatus)s)": "(HTTP állapot: %(httpStatus)s)", "Invite to this room": "Meghívás a szobába", @@ -1138,7 +1135,6 @@ "Login": "Bejelentkezés", "Low Priority": "Alacsony prioritás", "Unable to fetch notification target list": "Nem sikerült letölteni az értesítési célok listáját", - "Appear Offline": "Offline látszik", "Set Password": "Jelszó beállítása", "Enable audible notifications in web client": "Hangértesítések engedélyezése a webkliensben", "Permalink": "Állandó hivatkozás", diff --git a/src/i18n/strings/id.json b/src/i18n/strings/id.json index 5eccf72100..9db1a4a99c 100644 --- a/src/i18n/strings/id.json +++ b/src/i18n/strings/id.json @@ -285,7 +285,6 @@ "Messages containing my user name": "Pesan mengandung nama pengguna saya", "Collecting logs": "Mengumpulkan catatan", "more": "lagi", - "Bug report sent": "Laporan bug terkirim", "(HTTP status %(httpStatus)s)": "(status HTTP %(httpStatus)s)", "Failed to forget room %(errCode)s": "Gagal melupakan ruang %(errCode)s", "Wednesday": "Rabu", diff --git a/src/i18n/strings/it.json b/src/i18n/strings/it.json index 0f7851621f..27d1cde38d 100644 --- a/src/i18n/strings/it.json +++ b/src/i18n/strings/it.json @@ -232,7 +232,6 @@ "Not a valid Riot keyfile": "Non è una chiave di Riot valida", "Authentication check failed: incorrect password?": "Controllo di autenticazione fallito: password sbagliata?", "Failed to join room": "Accesso alla stanza fallito", - "Presence Management": "Gestione della presenza", "Tag Panel": "Pannello etichette", "Disable Emoji suggestions while typing": "Disattiva i suggerimenti delle emoji durante la digitazione", "Use compact timeline layout": "Usa impaginazione cronologia compatta", @@ -1076,7 +1075,6 @@ "Remember, you can always set an email address in user settings if you change your mind.": "Ricorda, puoi sempre specificare un indirizzo email nelle impostazioni utente se cambi idea.", "Explore Account Data": "Esplora dati account", "All messages (noisy)": "Tutti i messaggi (rumoroso)", - "Away": "Assente", "Saturday": "Sabato", "I understand the risks and wish to continue": "Sono consapevole dei rischi e vorrei continuare", "Direct Chat": "Chat Diretta", @@ -1091,7 +1089,6 @@ "Collecting logs": "Sto recuperando i log", "more": "altro", "GitHub issue link:": "Link segnalazione su GitHub:", - "Bug report sent": "Rapporto inviato", "You must specify an event type!": "Devi specificare un tipo di evento!", "(HTTP status %(httpStatus)s)": "(stato HTTP %(httpStatus)s)", "All Rooms": "Tutte le stanze", @@ -1134,7 +1131,6 @@ "Login": "Entra", "Low Priority": "Priorità bassa", "What's New": "Novità", - "Appear Offline": "Appari offline", "Set Password": "Imposta Password", "Enable audible notifications in web client": "Abilita notifiche audio nel client web", "Permalink": "Link permanente", diff --git a/src/i18n/strings/ko.json b/src/i18n/strings/ko.json index 32ca09aee1..ff5ebd72d7 100644 --- a/src/i18n/strings/ko.json +++ b/src/i18n/strings/ko.json @@ -725,7 +725,6 @@ "Toolbox": "도구상자", "Collecting logs": "로그 수집 중", "more": "더 보기", - "Bug report sent": "오류 보고서를 보냈어요", "(HTTP status %(httpStatus)s)": "(HTTP 상태 %(httpStatus)s)", "All Rooms": "모든 방", "Failed to get public room list": "공개한 방 목록을 얻지 못했어요", @@ -761,7 +760,6 @@ "Error encountered (%(errorDetail)s).": "오류가 일어났어요 (%(errorDetail)s).", "Low Priority": "낮은 우선순위", "Riot does not know how to join a room on this network": "라이엇이 이 네트워크에서 방에 들어가는 법을 알 수 없어요", - "Appear Offline": "미접속으로 표시하기", "Set Password": "비밀번호 설정", "Enable audible notifications in web client": "웹 클라이언트에서 알림 소리 켜기", "Permalink": "고유주소", diff --git a/src/i18n/strings/lt.json b/src/i18n/strings/lt.json index 277b0cf427..efa5cf9d5e 100644 --- a/src/i18n/strings/lt.json +++ b/src/i18n/strings/lt.json @@ -97,12 +97,10 @@ "Remove %(name)s from the directory?": "Ar ištrinti %(name)s iš katalogo?", "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot naudoja daug išplėstinių naršyklės funkcionalumų, kai kurie iš jų yra neprieinami ar eksperimentinei Jūsų naršyklėje.", "Event sent!": "Įvykis išsiųstas!", - "Bug report sent": "Klaidos ataskaita išsiųsta", "Unnamed room": "Kambarys be pavadinimo", "Dismiss": "Nutraukti", "Explore Account Data": "Peržiūrėti paskyros duomenis", "Remove from Directory": "Šalinti iš katalogo", - "Away": "Neaktyvus", "Download this file": "Atsisiųsti šį failą", "Saturday": "Šeštadienis", "Remember, you can always set an email address in user settings if you change your mind.": "Nepamirškite, kad galite, bet kada įrašyti savo el. pašto adresą paskyros nustatymuose.", @@ -162,7 +160,6 @@ "Low Priority": "Nesvarbūs", "Riot does not know how to join a room on this network": "Riot nežino kaip prisijungti prie kambario šiame tinkle", "Set Password": "Nustatyti slaptažodį", - "Appear Offline": "Neprisijungęs", "An error occurred whilst saving your email notification preferences.": "Įrašant pranešimų el. paštu nuostatas, įvyko klaida.", "Unable to join network": "Nepavyko prisijungti prie tinklo", "Permalink": "Pastovioji nuoroda", diff --git a/src/i18n/strings/lv.json b/src/i18n/strings/lv.json index a4a222a602..5c10bec7b9 100644 --- a/src/i18n/strings/lv.json +++ b/src/i18n/strings/lv.json @@ -731,7 +731,6 @@ "%(names)s and %(count)s others are typing|one": "%(names)s un vēl kāds raksta", "Message Replies": "Atbildes uz ziņām", "Message Pinning": "Ziņu piekabināšana", - "Presence Management": "Klātesamības vadība", "Tag Panel": "Birku panelis", "Disable Emoji suggestions while typing": "Atspējot Emoji ieteikumus teksta rakstīšanas laikā", "Hide avatar changes": "Slēpt avatara izmaiņas", @@ -1068,7 +1067,6 @@ "Enable desktop notifications": "Iespējot darbvirsmas paziņojumus", "Explore Account Data": "Aplūkot konta datus", "All messages (noisy)": "Visas ziņas (ar skaņu)", - "Away": "Prom (nav uz vietas)", "Saturday": "sestdiena", "Remember, you can always set an email address in user settings if you change your mind.": "Atceries, ka vienmēr vari iestatīt epasta adresi lietotāja uzstādījumos, ja pārdomā.", "Direct Chat": "Tiešais čats", @@ -1084,7 +1082,6 @@ "Collecting logs": "Tiek iegūti logfaili", "more": "vairāk", "GitHub issue link:": "GitHub problēmpaziņojuma saite:", - "Bug report sent": "Kļūdas atskaite nosūtīta", "You must specify an event type!": "Jānorāda notikuma tips!", "(HTTP status %(httpStatus)s)": "(HTTP statuss %(httpStatus)s)", "All Rooms": "visās istabās", @@ -1126,7 +1123,6 @@ "Login": "Ierakstīties", "Low Priority": "Zemas prioritātes", "Unable to fetch notification target list": "Neizdevās iegūt paziņojumu mērķu sarakstu", - "Appear Offline": "Šķiet nesaistē (oflainā)", "Set Password": "Iestatīt paroli", "Enable audible notifications in web client": "Iespējot skaņus paziņojumus web klientā", "Permalink": "Pastāvīgā saite", diff --git a/src/i18n/strings/ml.json b/src/i18n/strings/ml.json index 098c062006..6de7e92df7 100644 --- a/src/i18n/strings/ml.json +++ b/src/i18n/strings/ml.json @@ -102,7 +102,6 @@ "Messages containing my user name": "എന്റെ യൂസര്‍ നെയിം അടങ്ങിയിരിക്കുന്ന സന്ദേശങ്ങള്‍ക്ക്", "Collecting logs": "നാള്‍വഴി ശേഖരിക്കുന്നു", "more": "കൂടുതല്‍", - "Bug report sent": "ബഗ് റിപ്പോർട്ട് അയയ്ക്കുക", "(HTTP status %(httpStatus)s)": "(HTTP സ്റ്റാറ്റസ് %(httpStatus)s)", "All Rooms": "എല്ലാ മുറികളും കാണുക", "Wednesday": "ബുധന്‍", diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index 61e22d3996..ce7577733c 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -717,7 +717,6 @@ "Send": "Verstuur", "Message Pinning": "Boodschap vastpinnen", "Message Replies": "Antwoorden op bericht", - "Presence Management": "Presentie Beheer", "Tag Panel": "Label Paneel", "Disable Emoji suggestions while typing": "Emoji suggesties tijdens het typen uitzetten", "Hide avatar changes": "Avatar veranderingen verbergen", @@ -990,15 +989,11 @@ "Stickerpack": "Stickerpakket", "Sticker Messages": "Sticker Berichten", "You don't currently have any stickerpacks enabled": "Je hebt momenteel geen stickerpakketten aan staan", - "Click": "Klik", - "here": "hier", - "to add some!": "om wat toe te voegen!", "Add a stickerpack": "Stickerpakket toevoegen", "Hide Stickers": "Stickers verbergen", "Show Stickers": "Stickers weergeven", "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Gezien door %(displayName)s (%(userName)s) op %(dateTime)s", "Code": "Code", - "Manage sticker packs": "Stickerpakketten beheren", "Unable to join community": "Je kon niet tot de gemeenschap toetreden", "Unable to leave community": "Je kon de gemeenschap niet verlaten", "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Veranderingen die aan je gemeenschap naam en avatar zijn aangebracht zullen misschien niet gezien worden door anderen tot maximaal 30 minuten.", @@ -1084,7 +1079,6 @@ "Enable desktop notifications": "Desktopmeldingen aanzetten", "Explore Account Data": "Bekijk account informatie", "Remove from Directory": "Uit de kamerlijst verwijderen", - "Away": "Afwezig", "Saturday": "Zaterdag", "Remember, you can always set an email address in user settings if you change your mind.": "Onthoud dat u altijd een e-mailadres in kan stellen in de gebruikersinstellingen als u zich bedenkt.", "Direct Chat": "Privégesprek", @@ -1098,7 +1092,6 @@ "Toolbox": "Eigenschappen", "Collecting logs": "Logboeken verzamelen", "more": "meer", - "Bug report sent": "Bug report verzonden", "You must specify an event type!": "Je moet een event-type specificeren!", "(HTTP status %(httpStatus)s)": "(HTTP-status %(httpStatus)s)", "Invite to this room": "Uitnodigen voor deze kamer", @@ -1135,7 +1128,6 @@ "Login": "Aanmelden", "Low Priority": "Lage prioriteit", "Unable to fetch notification target list": "Het is mislukt om de lijst van notificatiedoelen op te halen", - "Appear Offline": "Lijk offline", "Set Password": "Wachtwoord instellen", "Enable audible notifications in web client": "Geluidsmeldingen in de webclient aanzetten", "Permalink": "Permanente link", diff --git a/src/i18n/strings/pl.json b/src/i18n/strings/pl.json index 2345164987..3d6d026945 100644 --- a/src/i18n/strings/pl.json +++ b/src/i18n/strings/pl.json @@ -730,8 +730,6 @@ "Delete %(count)s devices|other": "Usunięto %(count)s urządzeń", "Delete %(count)s devices|one": "Usunięto urządzenie", "Select devices": "Wybierz urządzenia", - "Click": "Kliknij", - "here": "tutaj", "%(senderName)s sent an image": "%(senderName)s wysłał(a) obrazek", "%(senderName)s sent a video": "%(senderName)s wysłał(a) wideo", "%(senderName)s uploaded a file": "%(senderName)s wysłał(a) plik", @@ -762,8 +760,8 @@ "Unknown for %(duration)s": "Nieznany przez %(duration)s", "Unknown": "Nieznany", "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Widziane przez %(displayName)s (%(userName)s) o %(dateTime)s", - "No rooms to show": "Brak pokoi do pokazania", - "Unnamed room": "Nienazwany pokój", + "No rooms to show": "Brak pokoi do wyświetlenia", + "Unnamed room": "Pokój bez nazwy", "Guests can join": "Goście mogą dołączyć", "Remove avatar": "Usuń awatar", "Drop here to favourite": "Upuść to aby dodać do ulubionych", @@ -782,7 +780,6 @@ "All notifications are currently disabled for all targets.": "Wszystkie powiadomienia są obecnie wyłączone dla wszystkich celów.", "Uploading report": "Raport wysyłania", "Sunday": "Niedziela", - "Guests can join": "Goście mogą dołączyć", "Failed to add tag %(tagName)s to room": "Nie można dodać tagu %(tagName)s do pokoju", "Notification targets": "Cele powiadomień", "Failed to set direct chat tag": "Nie udało się ustawić znacznika rozmów bezpośrednich", @@ -820,7 +817,6 @@ "Messages in one-to-one chats": "Wiadomości w rozmowach jeden-na-jeden", "Unavailable": "Niedostępny", "View Decrypted Source": "Pokaż zdeszyfrowane źródło", - "Send": "Wyślij", "Notes:": "Notatki:", "remove %(name)s from the directory.": "usuń %(name)s z katalogu.", "Notifications on the following keywords follow rules which can’t be displayed here:": "Powiadomienia o słowach kluczowych spełniają reguły, które nie mogą być tu wyświetlone:", @@ -854,11 +850,9 @@ "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot używa wiele zaawansowanych technologii, które nie są dostępne lub są w fazie testów w Twojej przeglądarce.", "Developer Tools": "Narzędzia programistyczne", "Preparing to send logs": "Przygotowywanie do wysłania zapisu rozmów", - "Unnamed room": "Pokój bez nazwy", "Remember, you can always set an email address in user settings if you change your mind.": "Pamiętaj, że zawsze możesz zmienić swój e-mail lub hasło w panelu ustawień użytkownika.", "Explore Account Data": "Odkryj dane konta", "All messages (noisy)": "Wszystkie wiadomości (głośno)", - "Away": "Niedostępny", "Saturday": "Sobota", "I understand the risks and wish to continue": "Rozumiem ryzyko i chcę kontynuować", "Direct Chat": "Rozmowa bezpośrednia", @@ -873,7 +867,6 @@ "Collecting logs": "Zbieranie dzienników", "more": "więcej", "GitHub issue link:": "Link do wątku na GitHubie:", - "Bug report sent": "Raport błędu wysłany", "You must specify an event type!": "Musisz określić typ wydarzenia!", "(HTTP status %(httpStatus)s)": "(status HTTP %(httpStatus)s)", "All Rooms": "Wszystkie pokoje", @@ -916,7 +909,6 @@ "Login": "Logowanie", "Low Priority": "Niski priorytet", "Unable to fetch notification target list": "Nie można pobrać listy docelowej dla powiadomień", - "Appear Offline": "Ustaw status niedostępny", "Set Password": "Ustaw hasło", "Enable audible notifications in web client": "Włącz dźwiękowe powiadomienia w kliencie internetowym", "Permalink": "Odnośnik bezpośredni", @@ -928,7 +920,6 @@ "Enable desktop notifications": "Włącz powiadomienia", "Enable email notifications": "Włącz powiadomienia e-mailowe", "Event Type": "Typ wydarzenia", - "No rooms to show": "Brak pokoi do wyświetlenia", "Download this file": "Pobierz plik", "Pin Message": "Przypnij Wiadomość", "Failed to change settings": "Nie udało się zmienić ustawień", diff --git a/src/i18n/strings/pt.json b/src/i18n/strings/pt.json index d8b9d11040..12339e6757 100644 --- a/src/i18n/strings/pt.json +++ b/src/i18n/strings/pt.json @@ -817,7 +817,6 @@ "Notify for all other messages/rooms": "Notificar para todas as outras mensagens/salas", "Unable to look up room ID from server": "Não foi possível obter a identificação da sala do servidor", "Couldn't find a matching Matrix room": "Não foi possível encontrar uma sala correspondente no servidor Matrix", - "Bug report sent": "Relatório de erros enviado", "All Rooms": "Todas as salas", "You cannot delete this message. (%(code)s)": "Não pode apagar esta mensagem. (%(code)s)", "Thursday": "Quinta-feira", diff --git a/src/i18n/strings/pt_BR.json b/src/i18n/strings/pt_BR.json index 37a9a958a1..631eed1c98 100644 --- a/src/i18n/strings/pt_BR.json +++ b/src/i18n/strings/pt_BR.json @@ -695,7 +695,6 @@ "Send": "Enviar", "Message Replies": "Respostas", "Message Pinning": "Fixar mensagem", - "Presence Management": "Gestão da presença", "Tag Panel": "Painel de tags", "Disable Emoji suggestions while typing": "Desativar sugestões de emojis enquanto estiver escrevendo", "Hide join/leave messages (invites/kicks/bans unaffected)": "Ocultar mensagens de entrada e de saída (não afeta convites, expulsões e banimentos)", @@ -1061,7 +1060,6 @@ "Enable desktop notifications": "Ativar notificações no desktop", "Explore Account Data": "Explorar Dados da Conta", "Remove from Directory": "Remover da lista pública de salas", - "Away": "Ausente", "Saturday": "Sábado", "Remember, you can always set an email address in user settings if you change your mind.": "Lembre-se: você pode sempre definir um endereço de e-mail nas configurações de usuário, se mudar de ideia.", "Direct Chat": "Conversa pessoal", @@ -1075,7 +1073,6 @@ "Toolbox": "Ferramentas", "Collecting logs": "Coletando logs", "more": "ver mais", - "Bug report sent": "Relatório do bug enviado", "You must specify an event type!": "Você precisa especificar um tipo do evento!", "(HTTP status %(httpStatus)s)": "(Status HTTP %(httpStatus)s)", "Invite to this room": "Convidar para esta sala", @@ -1111,7 +1108,6 @@ "Login": "Fazer login", "Low Priority": "Baixa prioridade", "Unable to fetch notification target list": "Não foi possível obter a lista de alvos de notificação", - "Appear Offline": "Aparecer Desconectado", "Set Password": "Definir senha", "Enable audible notifications in web client": "Ativar notificações de áudio no cliente web", "Permalink": "Link permanente", diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index d1e828a1d6..8de9983f22 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -884,7 +884,6 @@ "Visibility in Room List": "Видимость в списке комнат", "Visible to everyone": "Видимый для всех", "Only visible to community members": "Только участникам сообщества", - "Presence Management": "Управление присутствием", "Hide avatar changes": "Скрыть изменения аватара", "Hide display name changes": "Скрыть изменения отображаемого имени", "Enable inline URL previews by default": "Включить просмотр URL-адресов по умолчанию", @@ -1004,7 +1003,6 @@ "Add a stickerpack": "Добавить этикетки", "Hide Stickers": "Скрыть этикетки", "Show Stickers": "Показать этикетки", - "Manage sticker packs": "Упорядочить этикетки", "Fetching third party location failed": "Не удалось извлечь местоположение третьей стороны", "A new version of Riot is available.": "Доступна новая версия Riot.", "I understand the risks and wish to continue": "Я понимаю риски и желаю продолжить", @@ -1084,7 +1082,6 @@ "Enable desktop notifications": "Включить оповещения на рабочем столе", "Explore Account Data": "Просмотр данных аккаунта", "All messages (noisy)": "Все сообщения (со звуком)", - "Away": "Нет на месте", "Saturday": "Суббота", "Remember, you can always set an email address in user settings if you change your mind.": "Помните, что вы всегда сможете задать адрес email в настройках пользователя, если передумаете.", "Direct Chat": "Прямой чат", @@ -1099,7 +1096,6 @@ "Collecting logs": "Сбор журналов", "more": "больше", "GitHub issue link:": "Ссылка на проблему в GitHub:", - "Bug report sent": "Отчет об ошибке отправлен", "You must specify an event type!": "Необходимо указать тип мероприятия!", "(HTTP status %(httpStatus)s)": "(статус HTTP %(httpStatus)s)", "Invite to this room": "Пригласить в комнату", @@ -1138,7 +1134,6 @@ "Login": "Войти", "Low Priority": "Низкий приоритет", "Unable to fetch notification target list": "Не удалось получить список целей уведомления", - "Appear Offline": "Отображать как не в сети", "Set Password": "Задать пароль", "Enable audible notifications in web client": "Включить звуковые уведомления в веб-клиенте", "Permalink": "Постоянная ссылка", diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index 3422c364c4..c915ae04b4 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -899,7 +899,6 @@ "Please note you are logging into the %(hs)s server, not matrix.org.": "Všimnite si: Práve sa prihlasujete na server %(hs)s, nie na server matrix.org.", "Username on %(hs)s": "Meno používateľa na servery %(hs)s", "Restricted": "Obmedzené", - "Presence Management": "Spravovanie prítomnosti", "Hide avatar changes": "Skryť zmeny obrázka v profile", "Hide display name changes": "Skryť zmeny zobrazovaného mena", "Enable inline URL previews by default": "Predvolene povoliť náhľady URL adries", @@ -1000,13 +999,9 @@ "Stickerpack": "Balíček nálepiek", "Sticker Messages": "Správy s nálepkami", "You don't currently have any stickerpacks enabled": "Momentálne nemáte aktívne žiadne balíčky s nálepkami", - "Click": "Kliknutím", - "here": "sem", - "to add some!": "si nejaké pridajte!", "Add a stickerpack": "Pridať balíček s nálepkami", "Hide Stickers": "Skryť nálepky", "Show Stickers": "Zobraziť nálepky", - "Manage sticker packs": "Spravovať balíčky s nálepkami", "Who can join this community?": "Kto môže vstúpiť do tejto komunity?", "Everyone": "Ktokoľvek", "Fetching third party location failed": "Nepodarilo sa získať umiestnenie tretej strany", @@ -1084,7 +1079,6 @@ "Enable desktop notifications": "Povoliť oznámenia na pracovnej ploche", "Explore Account Data": "Preskúmať Údaje účtu", "All messages (noisy)": "Všetky správy (hlučné)", - "Away": "Preč", "Saturday": "Sobota", "Remember, you can always set an email address in user settings if you change your mind.": "Všimnite si, Emailovú adresu môžete pridať aj neskôr v časti nastavenia, ak zmeníte svoj názor.", "Direct Chat": "Priama konverzácia", @@ -1121,7 +1115,6 @@ "Notify for all other messages/rooms": "oznamovať všetky ostatné správy / miestnosti", "Unable to look up room ID from server": "Nie je možné vyhľadať ID miestnosti na servery", "Couldn't find a matching Matrix room": "Nie je možné nájsť zodpovedajúcu Matrix miestnosť", - "Bug report sent": "Hlásenie chyby odoslané", "Invite to this room": "Pozvať do tejto miestnosti", "You cannot delete this message. (%(code)s)": "Nemôžete vymazať túto správu. (%(code)s)", "Thursday": "Štvrtok", @@ -1142,7 +1135,6 @@ "Low Priority": "Nízka priorita", "What's New": "Čo Je Nové", "Set Password": "Nastaviť Heslo", - "Appear Offline": "Zdá sa byť nedostupný", "An error occurred whilst saving your email notification preferences.": "Počas ukladania vašich nastavení oznamovania emailom sa vyskytla chyba.", "Enable audible notifications in web client": "Povoliť zvukové oznámenia vo webovom klientovi", "Permalink": "Trvalý odkaz", diff --git a/src/i18n/strings/sq.json b/src/i18n/strings/sq.json index dc26c7c283..d36995bc5b 100644 --- a/src/i18n/strings/sq.json +++ b/src/i18n/strings/sq.json @@ -207,7 +207,6 @@ "Dismiss": "Mos e merr parasysh", "Explore Account Data": "Eksploroni të Dhëna Llogarie", "All messages (noisy)": "Tërë Mesazhet (e zhurmshme)", - "Away": "Larguar", "Saturday": "E shtunë", "Remember, you can always set an email address in user settings if you change your mind.": "Mos harroni, mundeni përherë të caktoni një adresë email te rregullimet e përdoruesit, nëse ndërroni mendje.", "Direct Chat": "Fjalosje e Drejtpërdrejtë", @@ -270,7 +269,6 @@ "Low Priority": "Përparësi e Ulët", "What's New": "Ç’ka të Re", "Set Password": "Caktoni Fjalëkalim", - "Appear Offline": "Shfaqju Si Jo Në Linjë", "An error occurred whilst saving your email notification preferences.": "Ndodhi një gabim teksa ruheshin parapëlqimet tuaja për njoftime me email.", "Enable audible notifications in web client": "Aktivizoni njoftime audio te klienti web", "Permalink": "Permalidhje", diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index 8d218f5595..87d5ec782e 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -172,7 +172,6 @@ "Failed to join room": "Нисам успео да уђем у собу", "Message Replies": "Одговори", "Message Pinning": "Закачене поруке", - "Presence Management": "Управљање присутношћу", "Tag Panel": "Означи површ", "Disable Emoji suggestions while typing": "Онемогући предлагање емоџија приликом куцања", "Use compact timeline layout": "Користи збијени распоред временске линије", @@ -1058,7 +1057,6 @@ "Event sent!": "Догађај је послат!", "Explore Account Data": "Истражи податке налога", "All messages (noisy)": "Све поруке (гласно)", - "Away": "Одустан", "Saturday": "Субота", "Remember, you can always set an email address in user settings if you change your mind.": "Запамтите, увек можете поставити мејл адресу у корисничким подешавањима, уколико се предомислите.", "Direct Chat": "Директно ћаскање", @@ -1092,7 +1090,6 @@ "Notify for all other messages/rooms": "Обавести за све друге поруке и собе", "Unable to look up room ID from server": "Не могу да погледам ИБ собе на серверу", "Couldn't find a matching Matrix room": "Не могу да нађем одговарајућу Матрикс собу", - "Bug report sent": "Извештај о грешци послат", "Invite to this room": "Позови у ову собу", "You cannot delete this message. (%(code)s)": "Не можете обрисати ову поруку. (%(code)s)", "Thursday": "Четвртак", @@ -1111,7 +1108,6 @@ "Low Priority": "Најмања важност", "What's New": "Шта је ново", "Set Password": "Постави лозинку", - "Appear Offline": "Прикажи себе као ван мреже", "An error occurred whilst saving your email notification preferences.": "Догодила се грешка при чувању ваших поставки мејл обавештења.", "Enable audible notifications in web client": "Омогући звучна обавештења у веб клијенту", "Permalink": "Трајна веза", diff --git a/src/i18n/strings/sv.json b/src/i18n/strings/sv.json index cd502e5bb7..c55ee40cba 100644 --- a/src/i18n/strings/sv.json +++ b/src/i18n/strings/sv.json @@ -501,7 +501,6 @@ "Enable desktop notifications": "Sätt på skrivbordsaviseringar", "Remember, you can always set an email address in user settings if you change your mind.": "Kom ihåg att du alltid kan välja en e-postadress i dina användarinställningar om du ändrar dig.", "All messages (noisy)": "Alla meddelanden (högljudd)", - "Away": "Borta", "Saturday": "lördag", "I understand the risks and wish to continue": "Jag förstår riskerna och vill fortsätta", "Direct Chat": "Direkt-chatt", @@ -514,7 +513,6 @@ "Messages containing my user name": "Meddelanden som innehåller mitt användarnamn", "Collecting logs": "Samlar in loggar", "more": "mera", - "Bug report sent": "Buggraporten skickades", "(HTTP status %(httpStatus)s)": "(HTTP-status %(httpStatus)s)", "All Rooms": "Alla rum", "Wednesday": "onsdag", @@ -548,7 +546,6 @@ "Error encountered (%(errorDetail)s).": "Fel påträffat (%(errorDetail)s).", "Low Priority": "Låg prioritet", "Unable to fetch notification target list": "Det gick inte att hämta aviseringsmållistan", - "Appear Offline": "Visa som utloggad", "Set Password": "Välj lösenord", "Enable audible notifications in web client": "Sätt på högljudda aviseringar i webbklienten", "Permalink": "Permanent länk", diff --git a/src/i18n/strings/ta.json b/src/i18n/strings/ta.json index 202e5326f0..6aecb54bfd 100644 --- a/src/i18n/strings/ta.json +++ b/src/i18n/strings/ta.json @@ -119,7 +119,6 @@ "You cannot delete this image. (%(code)s)": "இந்த படத்தை நீங்கள் அழிக்க முடியாது. (%(code)s)", "You cannot delete this message. (%(code)s)": "இந்த செய்தியை நீங்கள் அழிக்க முடியாது. (%(code)s)", "You are not receiving desktop notifications": "திரை அறிவிப்புகளை நீங்கள் பெறவில்லை", - "Bug report sent": "வழு அறிக்கை அனுப்பப்பட்டது", "OK": "சரி", "Show message in desktop notification": "திரை அறிவிப்புகளில் செய்தியை காண்பிக்கவும்", "Sunday": "ஞாயிறு", diff --git a/src/i18n/strings/uk.json b/src/i18n/strings/uk.json index 25a70e0522..02a650ac3a 100644 --- a/src/i18n/strings/uk.json +++ b/src/i18n/strings/uk.json @@ -177,7 +177,6 @@ "Unnamed room": "Неназвана кімната", "Explore Account Data": "Продивитись данні аккаунта", "All messages (noisy)": "Усі повідомлення (гучно)", - "Away": "Нема на місці", "Saturday": "Субота", "I understand the risks and wish to continue": "Я ознайомлений з ризиками і хочу продовжити", "Direct Chat": "Прямий чат", @@ -192,7 +191,6 @@ "Toolbox": "Панель інструментів", "Collecting logs": "Збір журналів", "more": "докладніше", - "Bug report sent": "Звіт про помилки відправлений", "You must specify an event type!": "Необхідно вказати тип захода!", "(HTTP status %(httpStatus)s)": "(статус HTTP %(httpStatus)s)", "All Rooms": "Усі кімнати", @@ -233,7 +231,6 @@ "Login": "Зайти", "Low Priority": "Неважливі", "Unable to fetch notification target list": "Неможливо отримати перелік цілей сповіщення", - "Appear Offline": "Відображати як не в мережі", "Set Password": "Задати пароль", "Enable audible notifications in web client": "Увімкнути звукові сповіщення у мережевому застосунку", "Permalink": "Постійне посилання", diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index 3c960c44c6..fe8ef8c16f 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -463,7 +463,6 @@ "%(senderName)s removed their profile picture.": "%(senderName)s 移除了他们的头像。", "%(senderName)s requested a VoIP conference.": "%(senderName)s 请求一个 VoIP 会议。", "Seen by %(userName)s at %(dateTime)s": "在 %(dateTime)s 被 %(userName)s 看到", - "Show Apps": "显示应用", "Tagged as: ": "标记为: ", "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "验证码将发送到+%(msisdn)s,请输入接收到的验证码", "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s 接受了 %(displayName)s 的邀请。", @@ -813,9 +812,6 @@ "Stickerpack": "贴图集", "Sticker Messages": "贴图消息", "You don't currently have any stickerpacks enabled": "您目前没有启用任何贴纸包", - "Click": "点击", - "here": "这里", - "to add some!": "以添加一些贴图集!", "Add a stickerpack": "添加贴图集", "Your key share request has been sent - please check your other devices for key share requests.": "已请求共享密钥 - 请在您的其他设备上进行确认。", "Key share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, click here to request the keys for this session again.": "密钥共享请求将会自动发送到您的其他设备上。如果您在其他设备上拒绝了请求,请点击此处以再次请求此会话的密钥。", @@ -865,7 +861,6 @@ "Failed to remove '%(roomName)s' from %(groupId)s": "从 %(groupId)s 中移除 “%(roomName)s” 失败", "Only visible to community members": "仅对社区成员可见", "Filter community rooms": "过滤社区聊天室", - "Manage sticker packs": "管理贴纸包", "You're not currently a member of any communities.": "您目前不是任何一个社区的成员。", "Communities": "社区", "%(nameList)s %(transitionList)s": "%(nameList)s %(transitionList)s", @@ -900,7 +895,6 @@ "Something went wrong whilst creating your community": "创建社区时出现问题", "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "您目前默认将未验证的设备列入黑名单;在发送消息到这些设备上之前,您必须先验证它们。", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "如果您之前使用过较新版本的 Riot,则您的会话可能与当前版本不兼容。请关闭此窗口并使用最新版本。", - "Presence Management": "在线状态管理", "To change the room's avatar, you must be a": "无法修改此聊天室的头像,因为您不是此聊天室的", "To change the room's name, you must be a": "无法修改此聊天室的名称,因为您不是此聊天室的", "To change the room's main address, you must be a": "无法修改此聊天室的主地址,因为您不是此聊天室的", @@ -1059,7 +1053,6 @@ "Remember, you can always set an email address in user settings if you change your mind.": "请记住,如果您改变想法,您永远可以在用户设置中设置电子邮件。", "Explore Account Data": "探索账户数据", "All messages (noisy)": "全部消息(高亮)", - "Away": "离开", "Saturday": "星期六", "I understand the risks and wish to continue": "我了解这些风险并愿意继续", "Direct Chat": "私聊", @@ -1074,7 +1067,6 @@ "Collecting logs": "正在收集日志", "more": "更多", "GitHub issue link:": "Github issue 链接:", - "Bug report sent": "发送DEBUG报告", "You must specify an event type!": "你必须制定一个事件类型!", "(HTTP status %(httpStatus)s)": "(HTTP 状态 %(httpStatus)s)", "All Rooms": "全部聊天室", @@ -1116,7 +1108,6 @@ "Login": "登录", "Low Priority": "低优先级", "Unable to fetch notification target list": "无法获取通知目标列表", - "Appear Offline": "似乎离线了", "Set Password": "设置密码", "Enable audible notifications in web client": "在网页客户端启用音频通知", "Permalink": "永久链接", diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index a404604ec2..10844783cc 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -713,7 +713,6 @@ "Send": "傳送", "Message Replies": "訊息回覆", "Message Pinning": "訊息釘選", - "Presence Management": "出席管理", "Tag Panel": "標籤面板", "Disable Emoji suggestions while typing": "在輸入時停用繪文字建議", "Hide avatar changes": "隱藏大頭貼變更", @@ -1082,7 +1081,6 @@ "Enable desktop notifications": "啟用桌面通知", "Explore Account Data": "探索帳號資料", "All messages (noisy)": "所有訊息(吵鬧)", - "Away": "離開", "Saturday": "星期六", "Remember, you can always set an email address in user settings if you change your mind.": "記住,如果您改變心意了,您永遠可以在使用者設定中設定電子郵件地址。", "Direct Chat": "私人聊天", @@ -1097,7 +1095,6 @@ "Collecting logs": "收集記錄", "more": "更多", "GitHub issue link:": "GitHub 問題回報連結:", - "Bug report sent": "已傳送臭蟲回報", "You must specify an event type!": "您必須指定事件類型!", "(HTTP status %(httpStatus)s)": "(HTTP 狀態 %(httpStatus)s)", "All Rooms": "所有的聊天室", @@ -1138,7 +1135,6 @@ "Login": "登入", "Low Priority": "低優先度", "Riot does not know how to join a room on this network": "Riot 不知道如何在此網路中加入聊天室", - "Appear Offline": "顯示為離線", "Set Password": "設定密碼", "Enable audible notifications in web client": "在網頁客戶端啟用音訊通知", "Permalink": "永久連結", From 196b855cd5287ae28bc7c0fa2cccf9ab85793b6d Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 20 Apr 2018 15:50:23 +0100 Subject: [PATCH 0823/1160] Merge translations from riot-web Translations that were added to the riot-web repo after the containing files had been moved here. --- src/i18n/strings/da.json | 14 +++++- src/i18n/strings/eo.json | 9 +++- src/i18n/strings/fr.json | 8 +++- src/i18n/strings/ja.json | 97 +++++++++++++++++++++++++++++++++++++++- src/i18n/strings/nl.json | 9 +++- 5 files changed, 132 insertions(+), 5 deletions(-) diff --git a/src/i18n/strings/da.json b/src/i18n/strings/da.json index d1393c1947..19fc7d06c6 100644 --- a/src/i18n/strings/da.json +++ b/src/i18n/strings/da.json @@ -390,5 +390,17 @@ "Collapse panel": "Slå panel sammen", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Med din nuværnde broser kan udseendet og fornemmelsen af programmet være helt forkert og nogle funktioner virker måske ikke. Hvis du alligevel vil prøve så kan du fortsætte, men det er på egen risiko!", "Checking for an update...": "Checker om der er en opdatering...", - "There are advanced notifications which are not shown here": "Der er avancerede meddelelser, som ikke vises her" + "There are advanced notifications which are not shown here": "Der er avancerede meddelelser, som ikke vises her", + "%(count)s Members|other": "%(count)s medlemmer", + "Logs sent": "Logfiler sendt", + "Click here to create a GitHub issue.": "Klik her for at oprette et GitHub-issue.", + "Reply": "Besvar", + "All messages (noisy)": "Alle meddelelser (højlydt)", + "GitHub issue link:": "Link til GitHub issue:", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Debug-logfiler indeholder brugerdata såsom brugernavn, ID'er eller aliaser for de rum eller grupper, du har besøgt, og andres brugernavne. De indeholder ikke meddelelser.", + "Failed to send logs: ": "Kunne ikke sende logfiler: ", + "View Community": "Vis community", + "%(count)s Members|one": "%(count)s medlem", + "Notes:": "Noter:", + "Preparing to send logs": "Forbereder afsendelse af logfiler" } diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index cad55cf662..500d20e0f4 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -1106,5 +1106,12 @@ "Collapse panel": "Maletendi panelon", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Kun via nuna foliumilo, la aspekto kaj funkciado de la aplikaĵo povas esti tute malĝusta, kaj kelkaj aŭ ĉiu funkcioj eble ne tute funkcios. Se vi tamen volas provi, vi povas daŭrigi, sed vi ricevos nenian subtenon se vi renkontos problemojn!", "Checking for an update...": "Serĉanta ĝisdatigojn…", - "There are advanced notifications which are not shown here": "Ekzistas specialaj sciigoj, kiuj ne montriĝas ĉi tie" + "There are advanced notifications which are not shown here": "Ekzistas specialaj sciigoj, kiuj ne montriĝas ĉi tie", + "Logs sent": "Protokolo sendiĝis", + "Click here to create a GitHub issue.": "Klaku ĉi tie por krei raporton ĉe GitHub.", + "GitHub issue link:": "Ligilo al raporto ĉe GitHub:", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Sencimigaj protokoloj enhavas informojn pri uzo de aplikaĵo, inkluzive vian salutnomon, la identigilojn aŭ nomojn de la ĉambroj aŭ grupoj kiujn vi vizitis, kaj la salutnomojn de aliaj uzantoj. Ili ne enhavas mesaĝojn.", + "Failed to send logs: ": "Malsukcesis sendi protokolon: ", + "Notes:": "Rimarkoj:", + "Preparing to send logs": "Pretiganta sendon de protokolo" } diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index ca47cd52a8..d9fc51ce28 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -1150,5 +1150,11 @@ "Collapse panel": "Cacher le panneau", "When I'm invited to a room": "Quand je suis invité dans un salon", "Checking for an update...": "Recherche de mise à jour...", - "There are advanced notifications which are not shown here": "Il existe une configuration avancée des notifications qui ne peut être affichée ici" + "There are advanced notifications which are not shown here": "Il existe une configuration avancée des notifications qui ne peut être affichée ici", + "Logs sent": "Rapports envoyés", + "GitHub issue link:": "Lien du signalement GitHub :", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Les rapports de débogage contiennent des données d'usage de l'application qui incluent votre nom d'utilisateur, les identifiants ou alias des salons ou groupes auxquels vous avez rendu visite ainsi que les noms des autres utilisateurs. Ils ne contiennent aucun message.", + "Failed to send logs: ": "Échec lors de l'envoi des rapports : ", + "Notes:": "Notes :", + "Preparing to send logs": "Préparation d'envoi des rapports" } diff --git a/src/i18n/strings/ja.json b/src/i18n/strings/ja.json index e8d1353c3b..cb386cc409 100644 --- a/src/i18n/strings/ja.json +++ b/src/i18n/strings/ja.json @@ -147,5 +147,100 @@ "Resend": "再送信", "Can't update user notification settings": "ユーザー通知の設定を更新できません", "Messages containing my display name": "自身の表示名を含むメッセージ", - "Enable desktop notifications": "デスクトップ画面に通知を行う" + "Enable desktop notifications": "デスクトップ画面に通知を行う", + "Fetching third party location failed": "サードパーティの記憶場所の取得に失敗しました", + "Couldn't load home page": "ホームページを読み込めませんでした", + "Send Account Data": "アカウントのデータを送信する", + "Advanced notification settings": "通知の詳細設定", + "Notification targets": "通知先", + "Failed to get protocol list from Home Server": "ホームサーバからのプロトコル一覧の入手に失敗しました", + "You are not receiving desktop notifications": "デスクトップ通知を受け取っていません", + "Update": "アップデート", + "Unable to fetch notification target list": "通知先リストを取得できませんでした", + "Expand panel": "パネルを展開する", + "%(count)s Members|other": "%(count)s 名の参加者", + "Uploaded on %(date)s by %(user)s": "%(date)s に %(user)s によりアップロードされました", + "Send Custom Event": "カスタムイベントを送信する", + "All notifications are currently disabled for all targets.": "現在すべての対象についての全通知が無効です。", + "Failed to send logs: ": "ログの送信に失敗しました: ", + "delete the alias.": "エイリアスを削除する。", + "To return to your account in future you need to set a password": "今後アカウントを回復するには、 パスワードを設定 する必要があります", + "You cannot delete this image. (%(code)s)": "この画像を消すことはできません。 (%(code)s)", + "Cancel Sending": "送信を取り消す", + "The Home Server may be too old to support third party networks": "ホームサーバがサードパーティネットワークをサポートするには古すぎる可能性があります", + "Remember, you can always set an email address in user settings if you change your mind.": "利用者設定でいつでもメールアドレスを設定できます。", + "Unavailable": "使用できません", + "View Decrypted Source": "復号されたソースを表示する", + "Notes:": "注:", + "Notifications on the following keywords follow rules which can’t be displayed here:": "ルールにより、次のキーワードについての通知はここに表示されません:", + "Safari and Opera work too.": "SafariOpera でも機能します。", + "Please set a password!": "パスワードを設定してください!", + "You have successfully set a password!": "パスワードの設定に成功しました!", + "Explore Room State": "部屋の状態を調べる", + "Source URL": "ソースのURL", + "Filter results": "フィルター結果", + "Noisy": "音量大", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "部屋のエイリアス %(alias)s を削除し、ディレクトリから %(name)s を消去しますか?", + "This will allow you to return to your account after signing out, and sign in on other devices.": "これにより、サインアウト後にあなたのアカウントに戻る、また、他の端末でサインインすることができます。", + "Invite to this community": "このコミュニティに招待する", + "Search for a room": "部屋を検索", + "View Source": "ソースコードを表示する", + "Back": "戻る", + "Remove %(name)s from the directory?": "ディレクトリから %(name)s を消去しますか?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riotは多くの高度なブラウザの機能を使用しています。そのうちのいくつかはご使用のブラウザでは使えないか、実験的な機能です。", + "Event sent!": "イベントが送信されました!", + "Preparing to send logs": "ログを送信する準備をしています", + "Explore Account Data": "アカウントのデータを調べる", + "The server may be unavailable or overloaded": "サーバは使用できないか、オーバーロードされています", + "Reject": "やめる", + "Failed to set Direct Message status of room": "部屋のダイレクトメッセージステータスの設定に失敗しました", + "Remove from Directory": "ディレクトリから消去する", + "Enable them now": "今有効化する", + "Forward Message": "メッセージを転送する", + "Toolbox": "ツールボックス", + "more": "もっと", + "GitHub issue link:": "Githubの問題へのリンク:", + "You must specify an event type!": "イベントの形式を特定してください!", + "(HTTP status %(httpStatus)s)": "(HTTPステータス %(httpStatus)s)", + "State Key": "ステータスキー", + "Please install Chrome or Firefox for the best experience.": "最高のエクスペリエンスのために Chrome または Firefox をインストールしてください。", + "Quote": "引用", + "Send logs": "ログを送信する", + "Downloading update...": "アップデート、ダウンロードしています…", + "You have successfully set a password and an email address!": "パスワードとメールアドレスの設定に成功しました!", + "Failed to send custom event.": "カスタムイベントの送信に失敗しました。", + "What's new?": "新着", + "Notify me for anything else": "他の場合についても通知する", + "Click here to create a GitHub issue.": "ここをクリック してGithubの問題を報告してください。", + "Notify for all other messages/rooms": "他のすべてのメッセージ又は部屋について通知する", + "Unable to look up room ID from server": "サーバから部屋IDを検索できません", + "Couldn't find a matching Matrix room": "一致するMatrixの部屋を見つけることができませんでした", + "I understand the risks and wish to continue": "リスクを理解し続ける", + "Logs sent": "ログが送信されました", + "Reply": "返信", + "Show message in desktop notification": "デスクトップ通知にメッセージ内容を表示する", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "デバッグログはあなたのユーザ名、訪問した部屋やグループのIDやエイリアス、他のユーザのユーザ名を含むアプリの使用データを含みます。メッセージは含みません。", + "Unable to join network": "ネットワークに接続できません", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Riot以外のクライアントで設定した可能性があります。Riotで設定することはできませんが、引き続き使用可能です", + "Error encountered (%(errorDetail)s).": "エラーが発生しました (%(errorDetail)s)。", + "Event Type": "イベントの形式", + "What's New": "新着", + "Enable audible notifications in web client": "ウェブクライアントで音による通知を有効化", + "Permalink": "パーマリンク", + "remove %(name)s from the directory.": "ディレクトリから %(name)s を消去する。", + "Riot does not know how to join a room on this network": "Riotはこのネットワークで部屋に参加する方法を知りません", + "You can now return to your account after signing out, and sign in on other devices.": "サインアウト後にあなたの\nアカウントに戻る、また、他の端末でサインインすることができます。", + "Login": "ログイン", + "Pin Message": "メッセージを固定する", + "Thank you!": "ありがとうございます!", + "View Community": "コミュニティを表示する", + "%(count)s Members|one": "%(count)s 名の参加者", + "Developer Tools": "開発者ツール", + "Unhide Preview": "プレビューを表示する", + "Event Content": "イベントの内容", + "#example": "#例", + "Collapse panel": "パネルを折りたたむ", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "現在ご使用のブラウザでは、アプリの外見や使い心地が正常でない可能性があります。また、一部または全部の機能がご使用いただけない可能性があります。このままご使用いただけますが、問題が発生した場合は対応しかねます!", + "Checking for an update...": "アップデートを確認しています…", + "There are advanced notifications which are not shown here": "ここに表示されない詳細な通知があります" } diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index ce7577733c..6c78265a4d 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -1150,5 +1150,12 @@ "Collapse panel": "Paneel inklappen", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Met uw huidige browser kan de applicatie er volledig incorrect uitzien. Tevens is het mogelijk dat niet alle functies naar behoren werken. U kunt doorgaan als u het toch wil proberen, maar bij problemen bent u volledig op uzelf aangewezen!", "Checking for an update...": "Aan het kijken voor een update...", - "There are advanced notifications which are not shown here": "Er zijn geavanceerde notificaties die hier niet getoond worden" + "There are advanced notifications which are not shown here": "Er zijn geavanceerde notificaties die hier niet getoond worden", + "Logs sent": "Logs verstuurd", + "Click here to create a GitHub issue.": "Klik hier om een Github opgave in te dienen.", + "GitHub issue link:": "GitHub opgave link:", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Debug logs bevatten applicatie-gebruik data inclusief je gebruikersnaam, de ID's of namen van de ruimtes en groepen die je hebt bezocht en de gebruikersnamen van andere gebruikers. Ze bevatten geen berichten.", + "Failed to send logs: ": "Het is niet gelukt om de logs te versturen: ", + "Notes:": "Constateringen:", + "Preparing to send logs": "Voorbereiden om logs te versturen" } From ffba7e0d32a63b0c8e63a91a291f2afc10085fbb Mon Sep 17 00:00:00 2001 From: Krombel Date: Fri, 20 Apr 2018 14:57:39 +0000 Subject: [PATCH 0824/1160] Translated using Weblate (German) Currently translated at 100.0% (1161 of 1161 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 2030b4285a..41c9353a52 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -1157,5 +1157,7 @@ "Collapse panel": "Panel einklappen", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "In deinem aktuell verwendeten Browser können Aussehen und Handhabung der Anwendung unter Umständen noch komplett fehlerhaft sein, so dass einige bzw. im Extremfall alle Funktionen nicht zur Verfügung stehen. Du kannst es trotzdem versuchen und fortfahren, bist dabei aber bezüglich aller auftretenden Probleme auf dich allein gestellt!", "Checking for an update...": "Nach Updates suchen...", - "There are advanced notifications which are not shown here": "Es existieren erweiterte Benachrichtigungen, welche hier nicht angezeigt werden" + "There are advanced notifications which are not shown here": "Es existieren erweiterte Benachrichtigungen, welche hier nicht angezeigt werden", + "Missing roomId.": "Fehlende Raum-ID.", + "Picture": "Bild" } From 144ba30e6b10f601287bea20fec0b3c2f4933ee7 Mon Sep 17 00:00:00 2001 From: Andrey Date: Fri, 20 Apr 2018 18:58:59 +0000 Subject: [PATCH 0825/1160] Translated using Weblate (Russian) Currently translated at 100.0% (1161 of 1161 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 8de9983f22..e1d2cde38c 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -1156,5 +1156,8 @@ "Collapse panel": "Свернуть панель", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "В текущем браузере внешний вид приложения может быть полностью неверным, а некоторые или все функции могут не работать. Если вы хотите попробовать в любом случае, то можете продолжить, но с теми проблемами, с которыми вы можете столкнуться вам придется разбираться самостоятельно!", "Checking for an update...": "Проверка обновлений...", - "There are advanced notifications which are not shown here": "Существуют дополнительные уведомления, которые не показаны здесь" + "There are advanced notifications which are not shown here": "Существуют дополнительные уведомления, которые не показаны здесь", + "Missing roomId.": "Отсутствует идентификатор комнаты.", + "You don't currently have any stickerpacks enabled": "У вас нет доступных стикеров", + "Picture": "Изображение" } From 99c49510744e12893f6ac61fb9a4293ae016178b Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Sat, 21 Apr 2018 02:44:20 +0000 Subject: [PATCH 0826/1160] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (1161 of 1161 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hant/ --- src/i18n/strings/zh_Hant.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 10844783cc..458e801c9f 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -1157,5 +1157,7 @@ "Collapse panel": "摺疊面板", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "您目前的瀏覽器,其應用程式的外觀和感覺可能完全不正確,有些或全部功能可以無法使用。如果您仍想要繼續嘗試,可以繼續,但必須自行承擔後果!", "Checking for an update...": "正在檢查更新...", - "There are advanced notifications which are not shown here": "有些進階的通知並未在此顯示" + "There are advanced notifications which are not shown here": "有些進階的通知並未在此顯示", + "Missing roomId.": "缺少 roomid。", + "Picture": "圖片" } From 6a918861bb77c22bb09db28d79c2b77b327c0636 Mon Sep 17 00:00:00 2001 From: Aidan Gauland Date: Sat, 21 Apr 2018 15:47:31 +1200 Subject: [PATCH 0827/1160] Add UI for displaying room avatars full size Change the onClick action on the RoomAvatar inside RoomHeader so that it brings up a lightbox with the full-size avatar. --- src/components/views/avatars/RoomAvatar.js | 18 +++++++++++++++++- src/components/views/rooms/RoomHeader.js | 5 ++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/components/views/avatars/RoomAvatar.js b/src/components/views/avatars/RoomAvatar.js index 876f40c52f..499e575227 100644 --- a/src/components/views/avatars/RoomAvatar.js +++ b/src/components/views/avatars/RoomAvatar.js @@ -17,6 +17,7 @@ import React from "react"; import PropTypes from 'prop-types'; import {ContentRepo} from "matrix-js-sdk"; import MatrixClientPeg from "../../../MatrixClientPeg"; +import Modal from '../../../Modal'; import sdk from "../../../index"; module.exports = React.createClass({ @@ -31,6 +32,7 @@ module.exports = React.createClass({ width: PropTypes.number, height: PropTypes.number, resizeMethod: PropTypes.string, + viewAvatarOnClick: PropTypes.bool, }, getDefaultProps: function() { @@ -159,6 +161,19 @@ module.exports = React.createClass({ } }, + onRoomAvatarClick: function() { + const avatarUrl = this.props.room.getAvatarUrl( + MatrixClientPeg.get().getHomeserverUrl(), + null, null, null, false); + const ImageView = sdk.getComponent("elements.ImageView"); + const params = { + src: avatarUrl, + name: this.props.room.name, + }; + + Modal.createDialog(ImageView, params, "mx_Dialog_lightbox"); + }, + render: function() { const BaseAvatar = sdk.getComponent("avatars.BaseAvatar"); @@ -169,7 +184,8 @@ module.exports = React.createClass({ return ( + urls={this.state.urls} + onClick={this.props.viewAvatarOnClick ? this.onRoomAvatarClick : null} /> ); }, }); diff --git a/src/components/views/rooms/RoomHeader.js b/src/components/views/rooms/RoomHeader.js index 19162c60cd..1851e03383 100644 --- a/src/components/views/rooms/RoomHeader.js +++ b/src/components/views/rooms/RoomHeader.js @@ -327,9 +327,8 @@ module.exports = React.createClass({ ); } else if (this.props.room || (this.props.oobData && this.props.oobData.name)) { roomAvatar = ( -
    - -
    + ); } From 8ed2dadc3b6ce7bca5a8e4a7bfd2dd74744dbbdc Mon Sep 17 00:00:00 2001 From: Szimszon Date: Sat, 21 Apr 2018 06:31:59 +0000 Subject: [PATCH 0828/1160] Translated using Weblate (Hungarian) Currently translated at 100.0% (1161 of 1161 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 5fe1e90163..c65379496d 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -1157,5 +1157,7 @@ "Collapse panel": "Panel becsukása", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Ebben a böngészőben az alkalmazás felülete tele lehet hibával, és az is lehet, hogy egyáltalán nem működik. Ha így is ki szeretnéd próbálni, megteheted, de ha valami gondod van, nem tudunk segíteni!", "Checking for an update...": "Frissítés keresése...", - "There are advanced notifications which are not shown here": "Vannak itt nem látható, haladó értesítések" + "There are advanced notifications which are not shown here": "Vannak itt nem látható, haladó értesítések", + "Missing roomId.": "Hiányzó szoba azonosító.", + "Picture": "Kép" } From 269190266a600360bf8d175882e98e338e592ad0 Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Sat, 21 Apr 2018 11:38:56 +0000 Subject: [PATCH 0829/1160] Translated using Weblate (Bulgarian) Currently translated at 100.0% (1161 of 1161 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 88d70777f1..7745e988aa 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -1157,5 +1157,7 @@ "Collapse panel": "Свий панела", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "С текущия Ви браузър, изглеждането и усещането на приложението може да бъде неточно, и някои или всички от функциите може да не функционират,работят......... Ако искате може да продължите така или иначе, но сте сами по отношение на евентуалните проблеми, които може да срещнете!", "Checking for an update...": "Проверяване за нова версия...", - "There are advanced notifications which are not shown here": "Съществуват разширени настройки за известия, които не са показани тук" + "There are advanced notifications which are not shown here": "Съществуват разширени настройки за известия, които не са показани тук", + "Missing roomId.": "Липсва идентификатор на стая.", + "Picture": "Изображение" } From 9d27cb0751729824aa74b462deb15aba4d65728a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Sat, 21 Apr 2018 13:09:18 +0000 Subject: [PATCH 0830/1160] Translated using Weblate (French) Currently translated at 99.9% (1160 of 1161 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index d9fc51ce28..cd42533b2c 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -1156,5 +1156,7 @@ "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Les rapports de débogage contiennent des données d'usage de l'application qui incluent votre nom d'utilisateur, les identifiants ou alias des salons ou groupes auxquels vous avez rendu visite ainsi que les noms des autres utilisateurs. Ils ne contiennent aucun message.", "Failed to send logs: ": "Échec lors de l'envoi des rapports : ", "Notes:": "Notes :", - "Preparing to send logs": "Préparation d'envoi des rapports" + "Preparing to send logs": "Préparation d'envoi des rapports", + "Missing roomId.": "Identifiant de salon manquant.", + "Picture": "Image" } From 03b46e766b877507cfb17230b8d27263f106fce9 Mon Sep 17 00:00:00 2001 From: Val Date: Sat, 21 Apr 2018 13:09:39 +0000 Subject: [PATCH 0831/1160] Translated using Weblate (French) Currently translated at 99.9% (1161 of 1161 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index cd42533b2c..9b4d2f16c5 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -1158,5 +1158,6 @@ "Notes:": "Notes :", "Preparing to send logs": "Préparation d'envoi des rapports", "Missing roomId.": "Identifiant de salon manquant.", - "Picture": "Image" + "Picture": "Image", + "Click here to create a GitHub issue.": "Cliquez ici pour créer un signalement sur GitHub." } From 301798a7f54ce90f331361556cac079bc2c46887 Mon Sep 17 00:00:00 2001 From: RainSlide Date: Fri, 20 Apr 2018 18:12:20 +0000 Subject: [PATCH 0832/1160] Translated using Weblate (Chinese (Simplified)) Currently translated at 97.5% (1132 of 1161 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hans/ --- src/i18n/strings/zh_Hans.json | 172 +++++++++++++++++----------------- 1 file changed, 88 insertions(+), 84 deletions(-) diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index fe8ef8c16f..ab299837c9 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -10,7 +10,7 @@ "Decryption error": "解密出错", "Delete": "删除", "Default": "默认", - "Device ID": "设备识别码", + "Device ID": "设备 ID", "Devices": "设备列表", "Devices will not yet be able to decrypt history from before they joined the room": "新加入聊天室的设备不能解密加入之前的聊天记录", "Direct chats": "私聊", @@ -20,8 +20,8 @@ "Don't send typing notifications": "不要发送我的打字状态", "Download %(text)s": "下载 %(text)s", "Email": "电子邮箱", - "Email address": "电子邮箱地址", - "Email, name or matrix ID": "电子邮箱,姓名或者matrix ID", + "Email address": "邮箱地址", + "Email, name or matrix ID": "邮箱地址,名称或者Matrix ID", "Emoji": "表情", "Enable encryption": "启用加密", "Encrypted messages will not be visible on clients that do not yet implement encryption": "不支持加密的客户端将看不到加密的消息", @@ -29,7 +29,7 @@ "%(senderName)s ended the call.": "%(senderName)s 结束了通话。.", "End-to-end encryption information": "端到端加密信息", "End-to-end encryption is in beta and may not be reliable": "端到端加密现为 beta 版,不一定可靠", - "Enter Code": "输入代码", + "Enter Code": "输入验证码", "Error": "错误", "Error decrypting attachment": "解密附件时出错", "Event information": "事件信息", @@ -40,7 +40,7 @@ "Failed to forget room %(errCode)s": "忘记聊天室失败,错误代码: %(errCode)s", "Failed to join room": "无法加入聊天室", "Failed to kick": "踢人失败", - "Failed to leave room": "无法离开聊天室", + "Failed to leave room": "无法退出聊天室", "Failed to load timeline position": "无法加载时间轴位置", "Failed to lookup current room": "找不到当前聊天室", "Failed to mute user": "禁言用户失败", @@ -48,7 +48,7 @@ "Failed to reject invitation": "拒绝邀请失败", "Failed to save settings": "保存设置失败", "Failed to send email": "发送邮件失败", - "Failed to send request.": "发送请求失败。", + "Failed to send request.": "请求发送失败。", "Failed to set avatar.": "设置头像失败。.", "Failed to set display name": "设置昵称失败", "Failed to set up conference call": "无法启动群组通话", @@ -129,7 +129,7 @@ "The file '%(fileName)s' exceeds this home server's size limit for uploads": "文件 '%(fileName)s' 超过了此主服务器的上传大小限制", "The file '%(fileName)s' failed to upload": "文件 '%(fileName)s' 上传失败", "Add email address": "添加邮件地址", - "Add phone number": "添加电话号码", + "Add phone number": "添加手机号码", "Advanced": "高级", "Algorithm": "算法", "Always show message timestamps": "总是显示消息时间戳", @@ -152,7 +152,7 @@ "%(targetName)s joined the room.": "%(targetName)s 已加入聊天室。", "Jump to first unread message.": "跳到第一条未读消息。", "%(senderName)s kicked %(targetName)s.": "%(senderName)s 把 %(targetName)s 踢出了聊天室。.", - "Leave room": "离开聊天室", + "Leave room": "退出聊天室", "Login as guest": "以游客的身份登录", "New password": "新密码", "Add a topic": "添加一个主题", @@ -177,10 +177,10 @@ "Anyone who knows the room's link, apart from guests": "任何知道聊天室链接的人,游客除外", "Anyone who knows the room's link, including guests": "任何知道聊天室链接的人,包括游客", "Are you sure?": "你确定吗?", - "Are you sure you want to leave the room '%(roomName)s'?": "你确定要离开聊天室 “%(roomName)s” 吗?", + "Are you sure you want to leave the room '%(roomName)s'?": "你确定要退出聊天室 “%(roomName)s” 吗?", "Are you sure you want to reject the invitation?": "你确定要拒绝邀请吗?", "Are you sure you want to upload the following files?": "你确定要上传这些文件吗?", - "Bans user with given id": "封禁指定 ID 的用户", + "Bans user with given id": "按照 ID 封禁指定的用户", "Blacklisted": "已列入黑名单", "Bulk Options": "批量操作", "Call Timeout": "通话超时", @@ -210,8 +210,8 @@ "Conference calling is in development and may not be reliable.": "视频会议功能还在开发状态,可能不稳定。", "Conference calls are not supported in encrypted rooms": "加密聊天室不支持视频会议", "Conference calls are not supported in this client": "此客户端不支持视频会议", - "%(count)s new messages|one": "%(count)s 条新消息", - "%(count)s new messages|other": "%(count)s 新消息", + "%(count)s new messages|one": "%(count)s 条未读消息", + "%(count)s new messages|other": "%(count)s 未读消息", "Create a new chat or reuse an existing one": "创建新聊天或使用已有的聊天", "Custom": "自定义", "Custom level": "自定义级别", @@ -222,7 +222,7 @@ "Device key:": "设备密钥 :", "Disable Notifications": "关闭消息通知", "Drop File Here": "把文件拖拽到这里", - "Email address (optional)": "电子邮件地址 (可选)", + "Email address (optional)": "邮箱地址 (可选)", "Enable Notifications": "启用消息通知", "Encrypted by a verified device": "由一个已验证的设备加密", "Encrypted by an unverified device": "由一个未经验证的设备加密", @@ -232,31 +232,31 @@ "Error: Problem communicating with the given homeserver.": "错误: 与指定的主服务器通信时出错。", "Export": "导出", "Failed to fetch avatar URL": "获取 Avatar URL 失败", - "Failed to upload profile picture!": "无法上传头像!", + "Failed to upload profile picture!": "头像上传失败!", "Guest access is disabled on this Home Server.": "此服务器禁用了游客访问。", "Home": "主页面", "Import": "导入", "Incoming call from %(name)s": "来自 %(name)s 的通话", "Incoming video call from %(name)s": "来自 %(name)s 的视频通话", - "Incoming voice call from %(name)s": "来自 %(name)s 的视频通话", + "Incoming voice call from %(name)s": "来自 %(name)s 的语音通话", "Incorrect username and/or password.": "用户名或密码错误。", "%(senderName)s invited %(targetName)s.": "%(senderName)s 邀请了 %(targetName)s。", "Invited": "已邀请", "Invites": "邀请", - "Invites user with given id to current room": "邀请指定 ID 的用户加入当前聊天室", - "'%(alias)s' is not a valid format for an address": "'%(alias)s' 不是一个合法的电子邮件地址格式", + "Invites user with given id to current room": "按照 ID 邀请指定用户加入当前聊天室", + "'%(alias)s' is not a valid format for an address": "'%(alias)s' 不是一个合法的邮箱地址格式", "'%(alias)s' is not a valid format for an alias": "'%(alias)s' 不是一个合法的昵称格式", "%(displayName)s is typing": "%(displayName)s 正在打字", "Sign in with": "第三方登录", "Message not sent due to unknown devices being present": "消息未发送,因为有未知的设备存在", - "Missing room_id in request": "请求中没有 room_id", + "Missing room_id in request": "请求中没有 聊天室 ID", "Missing user_id in request": "请求中没有 user_id", "Mobile phone number": "手机号码", "Mobile phone number (optional)": "手机号码 (可选)", "Moderator": "协管员", "Mute": "静音", "Name": "姓名", - "Never send encrypted messages to unverified devices from this device": "不要从此设备向未验证的设备发送消息", + "Never send encrypted messages to unverified devices from this device": "在此设备上不向未经验证的设备发送消息", "New passwords don't match": "两次输入的新密码不符", "none": "无", "not set": "未设置", @@ -274,7 +274,7 @@ "Password:": "密码:", "Passwords can't be empty": "密码不能为空", "Permissions": "权限", - "Phone": "电话", + "Phone": "手机号码", "Cancel": "取消", "Create new room": "创建新聊天室", "Custom Server Options": "自定义服务器选项", @@ -293,7 +293,7 @@ "Edit": "编辑", "Joins room with given alias": "以指定的别名加入聊天室", "Labs": "实验室", - "%(targetName)s left the room.": "%(targetName)s 离开了聊天室。", + "%(targetName)s left the room.": "%(targetName)s 退出了聊天室。", "Logged in as:": "登录为:", "Logout": "登出", "Low priority": "低优先级", @@ -365,11 +365,11 @@ "Unverify": "取消验证", "ex. @bob:example.com": "例如 @bob:example.com", "Add User": "添加用户", - "This Home Server would like to make sure you are not a robot": "这个Home Server想要确认你不是一个机器人", + "This Home Server would like to make sure you are not a robot": "此主服务器想确认你不是机器人", "Token incorrect": "令牌错误", "Default server": "默认服务器", "Custom server": "自定义服务器", - "URL Previews": "URL 预览", + "URL Previews": "链接预览", "Drop file here to upload": "把文件拖到这里以上传", "Online": "在线", "Idle": "空闲", @@ -396,7 +396,7 @@ "Enable automatic language detection for syntax highlighting": "启用自动语言检测用于语法高亮", "Failed to change power level": "修改特权级别失败", "Kick": "踢出", - "Kicks user with given id": "踢出指定 ID 的用户", + "Kicks user with given id": "按照 ID 移除特定的用户", "Last seen": "上次看见", "Level:": "级别:", "Local addresses for this room:": "这个聊天室的本地地址:", @@ -416,9 +416,9 @@ "Sets the room topic": "设置聊天室主题", "Show Text Formatting Toolbar": "显示文字格式工具栏", "This room has no local addresses": "这个聊天室没有本地地址", - "This doesn't appear to be a valid email address": "这看起来不是一个合法的电子邮件地址", + "This doesn't appear to be a valid email address": "这看起来不是一个合法的邮箱地址", "This is a preview of this room. Room interactions have been disabled": "这是这个聊天室的一个预览。聊天室交互已禁用", - "This phone number is already in use": "此电话号码已被使用", + "This phone number is already in use": "此手机号码已被使用", "This room": "这个聊天室", "This room is not accessible by remote Matrix servers": "这个聊天室无法被远程 Matrix 服务器访问", "This room's internal ID is": "这个聊天室的内部 ID 是", @@ -433,7 +433,7 @@ "Unencrypted room": "未加密的聊天室", "unencrypted": "未加密的", "Unencrypted message": "未加密的消息", - "unknown caller": "未知的呼叫者", + "unknown caller": "未知呼叫者", "unknown device": "未知设备", "Unnamed Room": "未命名的聊天室", "Unverified": "未验证", @@ -452,7 +452,7 @@ "Not a valid Riot keyfile": "不是一个合法的 Riot 密钥文件", "%(targetName)s accepted an invitation.": "%(targetName)s 接受了一个邀请。", "Do you want to load widget from URL:": "你想从此 URL 加载小组件吗:", - "Hide join/leave messages (invites/kicks/bans unaffected)": "隐藏加入/离开消息(邀请/踢出/封禁不受影响)", + "Hide join/leave messages (invites/kicks/bans unaffected)": "隐藏加入/退出消息(邀请/踢出/封禁不受影响)", "Integrations Error": "集成错误", "Publish this room to the public in %(domain)s's room directory?": "把这个聊天室发布到 %(domain)s 的聊天室目录吗?", "Manage Integrations": "管理集成", @@ -464,12 +464,12 @@ "%(senderName)s requested a VoIP conference.": "%(senderName)s 请求一个 VoIP 会议。", "Seen by %(userName)s at %(dateTime)s": "在 %(dateTime)s 被 %(userName)s 看到", "Tagged as: ": "标记为: ", - "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "验证码将发送到+%(msisdn)s,请输入接收到的验证码", + "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "验证码将发送至 +%(msisdn)s,请输入收到的验证码", "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s 接受了 %(displayName)s 的邀请。", - "Active call (%(roomName)s)": "%(roomName)s 的呼叫", + "Active call (%(roomName)s)": "当前通话 (来自聊天室 %(roomName)s)", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s 将级别调整到%(powerLevelDiffText)s 。", "Changes colour scheme of current room": "修改了样式", - "Deops user with given id": "Deops user", + "Deops user with given id": "按照 ID 取消特定用户的管理员权限", "Join as voice or video.": "通过 语言 或者 视频加入.", "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s 设定历史浏览功能为 所有聊天室成员,从他们被邀请开始.", "%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s 设定历史浏览功能为 所有聊天室成员,从他们加入开始.", @@ -486,16 +486,16 @@ "%(roomName)s is not accessible at this time.": "%(roomName)s 此时无法访问。", "Start authentication": "开始认证", "The maximum permitted number of widgets have already been added to this room.": "小部件的最大允许数量已经添加到这个聊天室了。", - "The phone number entered looks invalid": "输入的电话号码看起来无效", + "The phone number entered looks invalid": "输入的手机号码看起来无效", "The remote side failed to pick up": "远端未能接收到", - "This Home Server does not support login using email address.": "HS不支持使用电子邮件地址登陆。", - "This invitation was sent to an email address which is not associated with this account:": "此邀请被发送到与此帐户不相关的电子邮件地址:", + "This Home Server does not support login using email address.": "HS不支持使用邮箱地址登陆。", + "This invitation was sent to an email address which is not associated with this account:": "此邀请被发送到与此帐户不相关的邮箱地址:", "This room is not recognised.": "无法识别此聊天室。", "To get started, please pick a username!": "请点击用户名!", - "Unable to add email address": "无法添加电子邮件地址", + "Unable to add email address": "无法添加邮箱地址", "Automatically replace plain text Emoji": "文字、表情自动转换", - "To reset your password, enter the email address linked to your account": "要重置你的密码,请输入关联你的帐号的电子邮箱地址", - "Unable to verify email address.": "无法验证电子邮箱地址。", + "To reset your password, enter the email address linked to your account": "要重置你的密码,请输入关联你的帐号的邮箱地址", + "Unable to verify email address.": "无法验证邮箱地址。", "Unknown room %(roomId)s": "未知聊天室 %(roomId)s", "Unknown (user, device) pair:": "未知(用户,设备)对:", "Unrecognised command:": "无法识别的命令:", @@ -515,18 +515,18 @@ "You cannot place VoIP calls in this browser.": "你不能在这个浏览器中发起 VoIP 通话。", "You do not have permission to post to this room": "你没有发送到这个聊天室的权限", "You have been invited to join this room by %(inviterName)s": "你已经被 %(inviterName)s 邀请加入这个聊天室", - "You seem to be in a call, are you sure you want to quit?": "你好像在一个通话中,你确定要退出吗?", - "You seem to be uploading files, are you sure you want to quit?": "你好像正在上传文件,你确定要退出吗?", + "You seem to be in a call, are you sure you want to quit?": "您似乎正在进行通话,确定要退出吗?", + "You seem to be uploading files, are you sure you want to quit?": "您似乎正在上传文件,确定要退出吗?", "You should not yet trust it to secure data": "你不应该相信它来保护你的数据", "Upload an avatar:": "上传一个头像:", - "This doesn't look like a valid email address.": "这看起来不是一个合法的电子邮件地址。", - "This doesn't look like a valid phone number.": "这看起来不是一个合法的电话号码。", + "This doesn't look like a valid email address.": "这看起来不是一个合法的邮箱地址。", + "This doesn't look like a valid phone number.": "这看起来不是一个合法的手机号码。", "User names may only contain letters, numbers, dots, hyphens and underscores.": "用户名只可以包含字母、数字、点、连字号和下划线。", "An unknown error occurred.": "一个未知错误出现了。", "An error occurred: %(error_string)s": "一个错误出现了: %(error_string)s", "Encrypt room": "加密聊天室", "There are no visible files in this room": "这个聊天室里面没有可见的文件", - "Active call": "活跃的通话", + "Active call": "当前通话", "Verify...": "验证...", "Error decrypting audio": "解密音频时出错", "Error decrypting image": "解密图像时出错", @@ -537,7 +537,7 @@ "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s 移除了聊天室头像。", "Something went wrong!": "出了点问题!", "If you already have a Matrix account you can log in instead.": "如果你已经有一个 Matrix 帐号,你可以登录。", - "Do you want to set an email address?": "你要设置一个电子邮箱地址吗?", + "Do you want to set an email address?": "你要设置一个邮箱地址吗?", "New address (e.g. #foo:%(localDomain)s)": "新的地址(例如 #foo:%(localDomain)s)", "Upload new:": "上传新的:", "User ID": "用户 ID", @@ -552,11 +552,11 @@ "You cannot place a call with yourself.": "你不能和你自己发起一个通话。", "You have been kicked from %(roomName)s by %(userName)s.": "你已经被 %(userName)s 踢出了 %(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": "你已经登出了所有的设备并不再接收推送通知。要重新启用通知,请再在每个设备上登录", - "You have disabled URL previews by default.": "你已经默认 禁用 URL 预览。", - "You have enabled URL previews by default.": "你已经默认 启用 URL 预览。", + "You have disabled URL previews by default.": "你已经默认 禁用 链接预览。", + "You have enabled URL previews by default.": "你已经默认 启用 链接预览。", "Your home server does not support device management.": "你的 home server 不支持设备管理。", "Set a display name:": "设置一个昵称:", - "This server does not support authentication with a phone number.": "这个服务器不支持用电话号码认证。", + "This server does not support authentication with a phone number.": "这个服务器不支持用手机号码认证。", "Password too short (min %(MIN_PASSWORD_LENGTH)s).": "密码过短(最短为 %(MIN_PASSWORD_LENGTH)s)。", "Make this room private": "使这个聊天室私密", "Share message history with new users": "和新用户共享消息历史", @@ -593,7 +593,7 @@ "You must join the room to see its files": "你必须加入聊天室以看到它的文件", "Failed to invite the following users to the %(roomName)s room:": "邀请以下用户到 %(roomName)s 聊天室失败:", "Confirm Removal": "确认移除", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "这会让你的账户永远不可用。你无法重新注册同一个用户 ID.", + "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "这将会导致您的账户永远无法使用。你将无法重新注册同样的用户 ID。", "Verifies a user, device, and pubkey tuple": "验证一个用户、设备和密钥元组", "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "我们在尝试恢复你之前的会话时遇到了一个错误。如果你继续,你将需要重新登录,加密的聊天历史将会不可读。", "Unknown devices": "未知设备", @@ -609,9 +609,9 @@ "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.": "你可以使用自定义的服务器选项来通过指定一个不同的主服务器 URL 来登录其他 Matrix 服务器。", "This allows you to use this app with an existing Matrix account on a different home server.": "这允许你用一个已有在不同主服务器的 Matrix 账户使用这个应用。", "Please check your email to continue registration.": "请查看你的电子邮件以继续注册。", - "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "如果你不指定一个电子邮箱地址,你将不能重置你的密码。你确定吗?", + "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "如果你不指定一个邮箱地址,你将不能重置你的密码。你确定吗?", "Home server URL": "主服务器 URL", - "Identity server URL": "身份服务器 URL", + "Identity server URL": "身份认证服务器 URL", "What does this mean?": "这是什么意思?", "Image '%(Body)s' cannot be displayed.": "图像 '%(Body)s' 无法显示。", "This image cannot be displayed.": "图像无法显示。", @@ -625,7 +625,7 @@ "This will allow you to reset your password and receive notifications.": "这将允许你重置你的密码和接收通知。", "Share without verifying": "不验证就分享", "You added a new device '%(displayName)s', which is requesting encryption keys.": "你添加了一个新的设备 '%(displayName)s',它正在请求加密密钥。", - "Your unverified device '%(displayName)s' is requesting encryption keys.": "你的未验证的设备 '%(displayName)s' 正在请求加密密钥。", + "Your unverified device '%(displayName)s' is requesting encryption keys.": "你的未经验证的设备 '%(displayName)s' 正在请求加密密钥。", "Encryption key request": "加密密钥请求", "Autocomplete Delay (ms):": "自动补全延迟(毫秒):", "%(widgetName)s widget added by %(senderName)s": "%(widgetName)s 小组建被 %(senderName)s 添加", @@ -659,9 +659,9 @@ "Hide avatar changes": "隐藏头像修改", "Hide display name changes": "隐藏昵称的修改", "Disable big emoji in chat": "禁用聊天中的大Emoji", - "Never send encrypted messages to unverified devices in this room from this device": "在这个聊天室永不从这个设备发送加密消息到未验证的设备", - "Enable URL previews for this room (only affects you)": "在这个聊天室启用 URL 预览(只影响你)", - "Enable URL previews by default for participants in this room": "对这个聊天室的参与者默认启用 URL 预览", + "Never send encrypted messages to unverified devices in this room from this device": "在此设备上,在此聊天室中不向未经验证的设备发送加密的消息", + "Enable URL previews for this room (only affects you)": "在此聊天室启用链接预览(只影响你)", + "Enable URL previews by default for participants in this room": "对这个聊天室的参与者默认启用 链接预览", "Delete %(count)s devices|other": "删除了 %(count)s 个设备", "Delete %(count)s devices|one": "删除设备", "Select devices": "选择设备", @@ -706,10 +706,10 @@ "were kicked %(count)s times|one": "被踢出", "was kicked %(count)s times|other": "被踢出 %(count)s 次", "was kicked %(count)s times|one": "被踢出", - "%(severalUsers)schanged their name %(count)s times|other": "%(severalUsers)s 改了他们的名字 %(count)s 次", - "%(severalUsers)schanged their name %(count)s times|one": "%(severalUsers)s 改了他们的名字", - "%(oneUser)schanged their name %(count)s times|other": "%(oneUser)s 改了他们的名字 %(count)s 次", - "%(oneUser)schanged their name %(count)s times|one": "%(oneUser)s 改了他们的名字", + "%(severalUsers)schanged their name %(count)s times|other": "%(severalUsers)s 改了他们的名称 %(count)s 次", + "%(severalUsers)schanged their name %(count)s times|one": "%(severalUsers)s 改了他们的名称", + "%(oneUser)schanged their name %(count)s times|other": "%(oneUser)s 改了他们的名称 %(count)s 次", + "%(oneUser)schanged their name %(count)s times|one": "%(oneUser)s 改了他们的名称", "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)s 更换了他们的的头像 %(count)s 次", "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)s 更换了他们的头像", "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)s 更换了他们的头像 %(count)s 次", @@ -718,10 +718,10 @@ "%(items)s and %(count)s others|one": "%(items)s 和另一个人", "collapse": "折叠", "expand": "展开", - "email address": "电子邮箱地址", + "email address": "邮箱地址", "You have entered an invalid address.": "你输入了一个无效地址。", "Advanced options": "高级选项", - "Leave": "离开", + "Leave": "退出", "Description": "描述", "Warning": "警告", "Light theme": "浅色主题", @@ -745,7 +745,7 @@ "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s,%(monthName)s %(day)s %(fullYear)s", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s": "%(weekDayName)s,%(monthName)s %(day)s %(fullYear)s %(time)s", "Who would you like to add to this community?": "您想把谁添加到这个社区内?", - "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "警告:您添加的用户对一切知道这个社区的 ID 的人公开", + "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "警告:您添加的一切用户都将会对一切知道此社区的 ID 的人公开", "Name or matrix ID": "名称或 Matrix ID", "Which rooms would you like to add to this community?": "您想把哪个聊天室添加到这个社区中?", "Add rooms to the community": "添加聊天室到社区", @@ -753,7 +753,7 @@ "Failed to invite users to community": "邀请用户到社区失败", "Message Replies": "消息回复", "Disable Peer-to-Peer for 1:1 calls": "在1:1通话中禁用点到点", - "Enable inline URL previews by default": "默认启用自动网址预览", + "Enable inline URL previews by default": "默认启用网址预览", "Disinvite this user?": "取消邀请这个用户?", "Kick this user?": "踢出这个用户?", "Unban this user?": "解除这个用户的封禁?", @@ -790,7 +790,7 @@ "Add a User": "添加一个用户", "Unable to accept invite": "无法接受邀请", "Unable to reject invite": "无法拒绝邀请", - "Leave Community": "离开社区", + "Leave Community": "退出社区", "Community Settings": "社区设置", "Community %(groupId)s not found": "找不到社区 %(groupId)s", "Your Communities": "你的社区", @@ -802,13 +802,13 @@ "Failed to invite users to %(groupId)s": "邀请用户到 %(groupId)s 失败", "Failed to invite the following users to %(groupId)s:": "邀请下列用户到 %(groupId)s 失败:", "Failed to add the following rooms to %(groupId)s:": "添加以下聊天室到 %(groupId)s 失败:", - "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "你似乎没有将此邮箱地址同在此主服务器上的任何一个 Matrix 账号相关联。", + "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "你似乎没有将此邮箱地址同在此主服务器上的任何一个 Matrix 账号绑定。", "Restricted": "受限用户", "To use it, just wait for autocomplete results to load and tab through them.": "若要使用自动补全,只要等待自动补全结果加载完成,按 Tab 键切换即可。", "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s 将他们的昵称修改成了 %(displayName)s 。", "Hide avatars in user and room mentions": "隐藏头像", "Disable Community Filter Panel": "停用社区面板", - "Opt out of analytics": "禁用开发数据上传", + "Opt out of analytics": "退出统计分析服务", "Stickerpack": "贴图集", "Sticker Messages": "贴图消息", "You don't currently have any stickerpacks enabled": "您目前没有启用任何贴纸包", @@ -849,13 +849,13 @@ "%(serverName)s Matrix ID": "%(serverName)s Matrix ID", "You are registering with %(SelectedTeamName)s": "你将注册为 %(SelectedTeamName)s", "Remove from community": "从社区中移除", - "Disinvite this user from community?": "是否要取消邀请此用户加入社区?", + "Disinvite this user from community?": "是否不再邀请此用户加入本社区?", "Remove this user from community?": "是否要从社区中移除此用户?", "Failed to withdraw invitation": "撤回邀请失败", "Failed to remove user from community": "移除用户失败", "Filter community members": "过滤社区成员", "Flair will not appear": "将不会显示 Flair", - "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "你确定要从 %(groupId)s 中删除1吗?", + "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "你确定要从 %(groupId)s 中移除 %(roomName)s 吗?", "Removing a room from the community will also remove it from the community page.": "从社区中移除房间时,同时也会将其从社区页面中移除。", "Failed to remove room from community": "从社区中移除聊天室失败", "Failed to remove '%(roomName)s' from %(groupId)s": "从 %(groupId)s 中移除 “%(roomName)s” 失败", @@ -868,18 +868,18 @@ "%(severalUsers)sjoined %(count)s times|one": "%(severalUsers)s 已加入", "%(oneUser)sjoined %(count)s times|other": "%(oneUser)s 已加入 %(count)s 次", "%(oneUser)sjoined %(count)s times|one": "%(oneUser)s 已加入", - "%(severalUsers)sleft %(count)s times|other": "%(severalUsers)s 已离开 %(count)s 次", - "%(severalUsers)sleft %(count)s times|one": "%(severalUsers)s 已离开", - "%(oneUser)sleft %(count)s times|other": "%(oneUser)s 已离开 %(count)s 次", - "%(oneUser)sleft %(count)s times|one": "%(oneUser)s 已离开", - "%(severalUsers)sjoined and left %(count)s times|other": "%(severalUsers)s 已加入&已离开 %(count)s 次", - "%(severalUsers)sjoined and left %(count)s times|one": "%(severalUsers)s 已加入&已离开", - "%(oneUser)sjoined and left %(count)s times|other": "%(oneUser)s 已加入&已离开 %(count)s 次", - "%(oneUser)sjoined and left %(count)s times|one": "%(oneUser)s 已加入&已离开", - "%(severalUsers)sleft and rejoined %(count)s times|other": "%(severalUsers)s 离开并重新加入了 %(count)s 次", - "%(severalUsers)sleft and rejoined %(count)s times|one": "%(severalUsers)s 离开并重新加入了", - "%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)s 离开并重新加入了 %(count)s 次", - "%(oneUser)sleft and rejoined %(count)s times|one": "%(oneUser)s 离开并重新加入了", + "%(severalUsers)sleft %(count)s times|other": "%(severalUsers)s 已退出 %(count)s 次", + "%(severalUsers)sleft %(count)s times|one": "%(severalUsers)s 已退出", + "%(oneUser)sleft %(count)s times|other": "%(oneUser)s 已退出 %(count)s 次", + "%(oneUser)sleft %(count)s times|one": "%(oneUser)s 已退出", + "%(severalUsers)sjoined and left %(count)s times|other": "%(severalUsers)s 已加入&已退出 %(count)s 次", + "%(severalUsers)sjoined and left %(count)s times|one": "%(severalUsers)s 已加入&已退出", + "%(oneUser)sjoined and left %(count)s times|other": "%(oneUser)s 已加入&已退出 %(count)s 次", + "%(oneUser)sjoined and left %(count)s times|one": "%(oneUser)s 已加入&已退出", + "%(severalUsers)sleft and rejoined %(count)s times|other": "%(severalUsers)s 退出并重新加入了 %(count)s 次", + "%(severalUsers)sleft and rejoined %(count)s times|one": "%(severalUsers)s 退出并重新加入了", + "%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)s 退出并重新加入了 %(count)s 次", + "%(oneUser)sleft and rejoined %(count)s times|one": "%(oneUser)s 退出并重新加入了", "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)s 拒绝了他们的邀请", "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)s 拒绝了他们的邀请共 %(count)s 次", "%(oneUser)srejected their invitation %(count)s times|other": "%(oneUser)s 拒绝了他们的邀请共 %(count)s 次", @@ -893,7 +893,7 @@ "Community IDs cannot not be empty.": "社区 ID 不能为空。", "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "社区 ID 只能包含 a-z、0-9 或 “=_-./” 等字符", "Something went wrong whilst creating your community": "创建社区时出现问题", - "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "您目前默认将未验证的设备列入黑名单;在发送消息到这些设备上之前,您必须先验证它们。", + "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "您目前默认将未经验证的设备列入黑名单;在发送消息到这些设备上之前,您必须先验证它们。", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "如果您之前使用过较新版本的 Riot,则您的会话可能与当前版本不兼容。请关闭此窗口并使用最新版本。", "To change the room's avatar, you must be a": "无法修改此聊天室的头像,因为您不是此聊天室的", "To change the room's name, you must be a": "无法修改此聊天室的名称,因为您不是此聊天室的", @@ -906,7 +906,7 @@ "URL previews are enabled by default for participants in this room.": "此聊天室默认启用链接预览。", "URL previews are disabled by default for participants in this room.": "此聊天室默认禁用链接预览。", "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s 将聊天室的头像更改为 ", - "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "您也可以自定义身份验证服务器,但这通常会阻止基于电子邮件地址的与用户的交互。", + "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "您也可以自定义身份认证服务器,但这通常会阻止基于邮箱地址的与用户的交互。", "Please enter the code it contains:": "请输入它包含的代码:", "Flair will appear if enabled in room settings": "如果在聊天室设置中启用, flair 将会显示", "Matrix ID": "Matrix ID", @@ -956,7 +956,7 @@ "Please note you are logging into the %(hs)s server, not matrix.org.": "请注意,您正在登录的服务器是 %(hs)s,不是 matrix.org。", "This homeserver doesn't offer any login flows which are supported by this client.": "此主服务器不兼容本客户端支持的任何登录方式。", "Sign in to get started": "登录以开始使用", - "Unbans user with given id": "使用 ID 解封特定的用户", + "Unbans user with given id": "按照 ID 解封特定的用户", "Opens the Developer Tools dialog": "打开开发者工具窗口", "Notify the whole room": "通知聊天室全体成员", "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "此操作允许您将加密聊天室中收到的消息的密钥导出为本地文件。您可以将文件导入其他 Matrix 客户端,以便让别的客户端在未收到密钥的情况下解密这些消息。", @@ -990,7 +990,7 @@ "Friday": "星期五", "Update": "更新", "What's New": "新鲜事", - "Add an email address above to configure email notifications": "请在上方输入电子邮件地址以接收邮件通知", + "Add an email address above to configure email notifications": "请在上方输入邮箱地址以接收邮件通知", "Expand panel": "展开面板", "On": "打开", "%(count)s Members|other": "%(count)s 位成员", @@ -1044,7 +1044,7 @@ "Tuesday": "星期二", "Enter keywords separated by a comma:": "输入以逗号间隔的关键字:", "Forward Message": "转发消息", - "You have successfully set a password and an email address!": "您已经成功设置了密码和电子邮件地址!", + "You have successfully set a password and an email address!": "您已经成功设置了密码和邮箱地址!", "Remove %(name)s from the directory?": "从目录中移除 %(name)s 吗?", "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot 使用了许多先进的浏览器功能,有些在你目前所用的浏览器上无法使用或仅为实验性的功能。", "Developer Tools": "开发者工具", @@ -1129,5 +1129,9 @@ "Collapse panel": "折叠面板", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "您目前的浏览器,应用程序的外观和感觉完全不正确,有些或全部功能可能无法使用。如果您仍想继续尝试,可以继续,但请自行负担其后果!", "Checking for an update...": "正在检查更新…", - "There are advanced notifications which are not shown here": "更多的通知并没有在此显示出来" + "There are advanced notifications which are not shown here": "更多的通知并没有在此显示出来", + "There's no one else here! Would you like to invite others or stop warning about the empty room?": "这里没有其他人了!你是想 邀请用户 还是 不再提示?", + "You need to be able to invite users to do that.": "你需要有邀请用户的权限才能进行此操作。", + "Missing roomId.": "找不到此聊天室 ID 所对应的聊天室。", + "Tag Panel": "标签面板" } From 3d58474295568f43c1dc38140a9dd0856ebdefe9 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Sat, 21 Apr 2018 06:40:36 +0000 Subject: [PATCH 0833/1160] Translated using Weblate (Hungarian) Currently translated at 100.0% (1161 of 1161 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index c65379496d..792fa2735f 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -362,7 +362,7 @@ "This email address was not found": "Az e-mail cím nem található", "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", + "Privacy warning": "Titoktartási figyelmeztetés", "The file '%(fileName)s' exceeds this home server's size limit for uploads": "'%(fileName)s' fájl túllépte a Saját 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", From d42fa9d17a3db14bcc78291a216c20c95fe696e5 Mon Sep 17 00:00:00 2001 From: Eric Newport Date: Sun, 22 Apr 2018 22:30:37 -0400 Subject: [PATCH 0834/1160] Hide inline encryption icons except when hovering over a message Closes https://github.com/vector-im/riot-web/issues/2882 This is a redo of https://github.com/matrix-org/matrix-react-sdk/pull/1707 (see associated discussion there and here: https://github.com/vector-im/riot-web/pull/5988) I tried several times to resolve the conflicts correctly, but could not. Thus, fresh PR. --- res/css/views/rooms/_EventTile.scss | 10 ++++++++++ src/components/structures/UserSettings.js | 1 + src/components/views/rooms/EventTile.js | 6 +++++- src/i18n/strings/en_EN.json | 1 + src/settings/Settings.js | 5 +++++ 5 files changed, 22 insertions(+), 1 deletion(-) diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index 4bb81a2e53..3aa1622e05 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -298,6 +298,16 @@ limitations under the License. cursor: pointer; } +.mx_EventTile_e2eIcon[hidden] { + display: none; +} + +/* always override hidden attribute for blocked and warning */ +.mx_EventTile_e2eIcon[hidden][src="img/e2e-blocked.svg"], +.mx_EventTile_e2eIcon[hidden][src="img/e2e-warning.svg"] { + display: block; +} + .mx_EventTile_keyRequestInfo { font-size: 12px; } diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 85223c4eef..d0a7275da2 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -63,6 +63,7 @@ const gHVersionLabel = function(repo, token='') { const SIMPLE_SETTINGS = [ { id: "urlPreviewsEnabled" }, { id: "autoplayGifsAndVideos" }, + { id: "alwaysShowEncryptionIcons" }, { id: "hideReadReceipts" }, { id: "dontSendTypingNotifications" }, { id: "alwaysShowTimestamps" }, diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index ed7851bf2d..565c8b5977 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -742,7 +742,11 @@ function E2ePadlockUnencrypted(props) { } function E2ePadlock(props) { - return ; + if (SettingsStore.getValue("alwaysShowEncryptionIcons")) { + return ; + } else { + return ; + } } module.exports.getHandlerTile = getHandlerTile; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index d90b120bad..33acb04f31 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -198,6 +198,7 @@ "Show timestamps in 12 hour format (e.g. 2:30pm)": "Show timestamps in 12 hour format (e.g. 2:30pm)", "Always show message timestamps": "Always show message timestamps", "Autoplay GIFs and videos": "Autoplay GIFs and videos", + "Always show encryption icons": "Always show encryption icons", "Enable automatic language detection for syntax highlighting": "Enable automatic language detection for syntax highlighting", "Hide avatars in user and room mentions": "Hide avatars in user and room mentions", "Disable big emoji in chat": "Disable big emoji in chat", diff --git a/src/settings/Settings.js b/src/settings/Settings.js index 8e94be3be1..d214d5417f 100644 --- a/src/settings/Settings.js +++ b/src/settings/Settings.js @@ -150,6 +150,11 @@ export const SETTINGS = { displayName: _td('Autoplay GIFs and videos'), default: false, }, + "alwaysShowEncryptionIcons": { + supportedLevels: LEVELS_ACCOUNT_SETTINGS, + displayName: _td('Always show encryption icons'), + default: true, + }, "enableSyntaxHighlightLanguageDetection": { supportedLevels: LEVELS_ACCOUNT_SETTINGS, displayName: _td('Enable automatic language detection for syntax highlighting'), From c32fc677b2615f43eeb4a6c4afdd43e59c826173 Mon Sep 17 00:00:00 2001 From: Osoitz Date: Mon, 23 Apr 2018 04:18:28 +0000 Subject: [PATCH 0835/1160] Translated using Weblate (Basque) Currently translated at 100.0% (1161 of 1161 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eu/ --- src/i18n/strings/eu.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index 853a2de6c0..d0d035f40b 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -1157,5 +1157,7 @@ "Collapse panel": "Tolestu panela", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Zure oraingo nabigatzailearekin aplikazioaren itxura eta portaera guztiz okerra izan daiteke, eta funtzio batzuk ez dira ibiliko. Hala ere aurrera jarraitu dezakezu saiatu nahi baduzu, baina zure erantzukizunaren menpe geratzen dira aurkitu ditzakezun arazoak!", "Checking for an update...": "Eguneraketarik dagoen egiaztatzen...", - "There are advanced notifications which are not shown here": "Hemen erakusten ez diren jakinarazpen aurreratuak daude" + "There are advanced notifications which are not shown here": "Hemen erakusten ez diren jakinarazpen aurreratuak daude", + "Missing roomId.": "Gelaren ID-a falta da.", + "Picture": "Irudia" } From 057815ac9ff807acffd976fa3d4087c944d110f2 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 23 Apr 2018 10:30:14 +0100 Subject: [PATCH 0836/1160] Reset accidental merge changes Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/i18n/strings/cs.json | 160 ++-------------------------- src/i18n/strings/de_DE.json | 173 ++---------------------------- src/i18n/strings/fr.json | 172 +++--------------------------- src/i18n/strings/hu.json | 179 ++++--------------------------- src/i18n/strings/nl.json | 184 ++------------------------------ src/i18n/strings/ru.json | 175 +++--------------------------- src/i18n/strings/sk.json | 206 +++++------------------------------- src/i18n/strings/sr.json | 158 ++------------------------- 8 files changed, 116 insertions(+), 1291 deletions(-) diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index 11dd85ba50..4267954d4c 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -90,6 +90,7 @@ "Are you sure you want to upload the following files?": "Určitě chcete nahrát následující soubory?", "Attachment": "Příloha", "Autoplay GIFs and videos": "Automaticky přehrávat GIFy a videa", + "Bug Report": "Hlášení o chybě", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Nelze se připojit k domovskému serveru – zkontrolujte prosím své připojení, prověřte, zdali je SSL certifikát vašeho domovského serveru důvěryhodný, a že některé z rozšíření prohlížeče neblokuje komunikaci.", "Anyone who knows the room's link, apart from guests": "Kdokoliv, kdo má odkaz na místnost, kromě hostů", "Anyone who knows the room's link, including guests": "Kdokoliv, kdo má odkaz na místnost, a to i hosté", @@ -206,6 +207,7 @@ "%(senderName)s answered the call.": "%(senderName)s přijal/a hovor.", "Click to mute audio": "Kliknutím ztlumíte zvuk", "Failed to verify email address: make sure you clicked the link in the email": "E-mailovou adresu se nepodařilo ověřit. Přesvědčte se, že jste kliknul/a na zaslaný odkaz", + "Found a bug?": "Našli jste chybu?", "Guest access is disabled on this Home Server.": "Na tomto domovském serveru je hostům vstup odepřen.", "Guests cannot join this room even if explicitly invited.": "Hosté nemohou vstoupit do této místnosti, i když jsou přímo pozváni.", "Hide read receipts": "Skrýt potvrzení o přečtení", @@ -276,6 +278,7 @@ "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Tuto změnu nepůjde vrátit zpět, protože tomuto uživateli nastavujete stejnou úroveň moci, jakou máte vy.", "Alias (optional)": "Alias (nepovinný)", "Room name (optional)": "Název místnosti (nepovinný)", + "Report it": "Nahlásit to", "Results from DuckDuckGo": "Výsledky z DuckDuckGo", "Return to login screen": "Vrátit k přihlašovací obrazovce", "Riot does not have permission to send you notifications - please check your browser settings": "Riot není oprávněn posílat vám upozornění – zkontrolujte prosím nastavení svého prohlížeče", @@ -303,6 +306,7 @@ "%(senderName)s set a profile picture.": "%(senderName)s si nastavil/a profilový obrázek.", "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s si změnil/a zobrazované jméno na %(displayName)s.", "Sets the room topic": "Nastavuje téma místnosti", + "Show Apps": "Zobrazit aplikace", "Show panel": "Zobrazit panel", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Zobrazovat časové značky v 12hodinovém formátu (např. 2:30 odp.)", "Sign in": "Přihlásit", @@ -526,6 +530,7 @@ "Make Moderator": "Udělit moderátorství", "and %(count)s others...|one": "a někdo další...", "Hangup": "Zavěsit", + "Hide Apps": "Skrýt aplikace", "Show Text Formatting Toolbar": "Zobrazit nástroje formátování textu", "Hide Text Formatting Toolbar": "Skrýt nástroje formátování textu", "Jump to message": "Přeskočit na zprávu", @@ -555,6 +560,7 @@ "Leave Community": "Odejít ze skupiny", "Leave %(groupName)s?": "Odejít z %(groupName)s?", "Leave": "Odejít", + "Unable to leave room": "Nepodařilo se odejít z místnosti", "Hide join/leave messages (invites/kicks/bans unaffected)": "Skrýt zprávy o vstupu či odejití (pozvánky, vykopnutí a vykázání zůstanou)", "Failed to remove user from community": "Nepodařilo se odebrat uživatele ze skupiny", "Failed to remove room from community": "Nepodařilo se odebrat místnost ze skupiny", @@ -643,6 +649,7 @@ "%(senderName)s placed a %(callType)s call.": "%(senderName)s uskutečnil %(callType)s hovor.", "%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s zpřístupnil budoucí historii místnosti neznámým (%(visibility)s).", "Not a valid Riot keyfile": "Neplatný soubor s klíčem Riot", + "Presence Management": "Správce účasti", "Disable Emoji suggestions while typing": "Zakázat návrhy Emoji během psaní", "Hide avatar changes": "Skrýt změny avatara", "Hide display name changes": "Skrýt změny zobrazovaného jména", @@ -927,6 +934,7 @@ "Claimed Ed25519 fingerprint key": "Údajný klíč s otiskem prstu Ed25519", "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Tento proces vás provede importem šifrovacích klíčů, které jste si stáhli z jiného Matrix klienta. Po úspěšném naimportování budete v tomto klientovi moci dešifrovat všechny zprávy, které jste mohli dešifrovat v původním klientovi.", "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Stažený soubor je chráněn heslem. Soubor můžete naimportovat pouze pokud zadáte odpovídající heslo.", + "Tag Panel": "Připnout panel", "Call Failed": "Hovor selhal", "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "V této místnosti jsou neznámá zařízení: Pokud budete pokračovat bez jejich ověření, někdo může Váš hovor odposlouchávat.", "Review Devices": "Ověřit zařízení", @@ -940,155 +948,5 @@ "expand": "rozbalit", "Old cryptography data detected": "Nalezeny starší šifrované datové zprávy", "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Nalezeny datové zprávy ze starší verze Riot. Důsledkem bude, že E2E šifrování nebude ve starší verzi Riot správně fungovat. Šifrované zprávy ze starší verze nemusí být čitelné v nové verzi. Může dojít i k selhání zasílaní zpráv s touto verzí Riot. Pokud zaznamenáte některý z uvedených problému, odhlaste se a přihlaste znovu. Pro zachování historie zpráv exportujte a znovu importujte vaše klíče.", - "Warning": "Upozornění", - "Fetching third party location failed": "Nepodařilo se zjistit umístění třetí strany", - "A new version of Riot is available.": "Je dostupná nová verze Riotu.", - "I understand the risks and wish to continue": "Rozumím rizikům a přeji si pokračovat", - "Couldn't load home page": "Nepodařilo se nahrát úvodní stránku", - "Send Account Data": "Poslat data o účtu", - "Advanced notification settings": "Pokročilé nastavení upozornění", - "Uploading report": "Nahrávám hlášení", - "Sunday": "Neděle", - "Messages sent by bot": "Zprávy poslané robotem", - "Notification targets": "Cíle upozornění", - "Failed to set direct chat tag": "Nepodařilo se nastavit štítek přímého chatu", - "Today": "Dnes", - "Files": "Soubory", - "You are not receiving desktop notifications": "Nedostáváte upozornění na desktopu", - "Friday": "Pátek", - "Update": "Aktualizace", - "What's New": "Co je nového", - "Add an email address above to configure email notifications": "Abyste mohli nastavovat e-mailová upozornění, musíte uvést svoji e-mailovou adresu v kolonce výše", - "Expand panel": "Rozbalit panel", - "On": "Zapnout", - "%(count)s Members|other": "%(count)s Členů", - "Filter room names": "Filtrovat místnosti dle názvu", - "Changelog": "Seznam změn", - "Waiting for response from server": "Čekám na odezvu ze serveru", - "Send Custom Event": "Odeslat vlastní událost", - "All notifications are currently disabled for all targets.": "Veškeré notifikace jsou aktuálně pro všechny cíle vypnuty.", - "delete the alias.": "smazat alias.", - "To return to your account in future you need to set a password": "Abyste se mohli ke svému účtu v budoucnu vrátit, musíte si nastavit heslo", - "Forget": "Zapomenout", - "Hide panel": "Skrýt panel", - "You cannot delete this image. (%(code)s)": "Tento obrázek nemůžete smazat. (%(code)s)", - "Cancel Sending": "Zrušit odesílání", - "This Room": "Tato místnost", - "The Home Server may be too old to support third party networks": "Tento domovský server může být příliš zastaralý na to, aby podporoval sítě třetích stran", - "Noisy": "Hlučný", - "Room not found": "Místnost nenalezena", - "Messages containing my display name": "Zprávy obsahující mé zobrazované jméno", - "Remember, you can always set an email address in user settings if you change your mind.": "Vězte, že kdybyste si to rozmysleli, e-mailovou adresu můžete kdykoliv doplnit v uživatelském nastavení.", - "Unavailable": "Nedostupné", - "Error saving email notification preferences": "Chyba při ukládání nastavení e-mailových upozornění", - "View Decrypted Source": "Zobrazit dešifrovaný zdroj", - "Failed to update keywords": "Nepodařilo se aktualizovat klíčová slova", - "remove %(name)s from the directory.": "odebrat %(name)s z adresáře.", - "Notifications on the following keywords follow rules which can’t be displayed here:": "Upozornění na následující klíčová slova se řídí pravidly, která zde nelze zobrazit:", - "Safari and Opera work too.": "Safari a Opera fungují taky.", - "Please set a password!": "Prosím nastavte si heslo!", - "You have successfully set a password!": "Úspěšně jste si nastavili heslo!", - "Explore Room State": "Prohlížet stav místnosti", - "Source URL": "Zdrojová URL", - "Failed to add tag %(tagName)s to room": "Nepodařilo se přidat štítek %(tagName)s k místnosti", - "Filter results": "Filtrovat výsledky", - "Members": "Členové", - "No update available.": "Není dostupná žádná aktualizace.", - "Resend": "Poslat znovu", - "Failed to get protocol list from Home Server": "Z domovského serveru se nepodařilo získat seznam protokolů", - "Collecting app version information": "Sbírání informací o verzi aplikace", - "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Smazat alias místnosti %(alias)s a odstranit %(name)s z adresáře?", - "This will allow you to return to your account after signing out, and sign in on other devices.": "Toto vám umožní vrátit se po odhlášení ke svému účtu a používat jej na ostatních zařízeních.", - "Keywords": "Klíčová slova", - "Enable notifications for this account": "Zapnout upozornění na tomto účtu", - "Directory": "Adresář", - "Invite to this community": "Pozvat do této komunity", - "Search for a room": "Hledat místnost", - "Messages containing keywords": "Zprávy obsahující klíčová slova", - "View Source": "Zobrazit zdroj", - "Tuesday": "Úterý", - "Enter keywords separated by a comma:": "Vložte klíčová slova oddělená čárkou:", - "Forward Message": "Přeposlat zprávu", - "You have successfully set a password and an email address!": "Úspěšně jste si nastavili heslo a e-mailovou adresu!", - "Remove %(name)s from the directory?": "Odebrat %(name)s z adresáře?", - "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot používá mnoho pokročilých funkcí, z nichž některé jsou ve vašem současném prohlížeči nedostupné nebo experimentální.", - "Developer Tools": "Nástroje pro vývojáře", - "Enable desktop notifications": "Zapnout upozornění na ploše", - "Explore Account Data": "Prozkoumat data o účtu", - "Remove from Directory": "Odebrat z adresáře", - "Saturday": "Sobota", - "Messages in one-to-one chats": "Zprávy v individuálních chatech", - "Direct Chat": "Přímý chat", - "The server may be unavailable or overloaded": "Server může být nedostupný nebo přetížený", - "Reject": "Odmítnout", - "Failed to set Direct Message status of room": "Nepodařilo se přiřadit místnosti status Přímé zprávy", - "Monday": "Pondělí", - "All messages (noisy)": "Všechny zprávy (hlasitě)", - "Enable them now": "Povolit nyní", - "Messages containing my user name": "Zprávy obsahující mé uživatelské jméno", - "Toolbox": "Sada nástrojů", - "Collecting logs": "Sbírání logů", - "more": "více", - "You must specify an event type!": "Musíte určit typ události!", - "(HTTP status %(httpStatus)s)": "(HTTP status %(httpStatus)s)", - "Invite to this room": "Pozvat do této místnosti", - "Please install Chrome or Firefox for the best experience.": "Pro nejlepší zážitek si prosím nainstalujte Chrome nebo Firefox.", - "Failed to get public room list": "Nepodařilo se získat seznam veřejných místností", - "Send logs": "Odeslat záznamy", - "All messages": "Všechny zprávy", - "Call invitation": "Pozvánka k hovoru", - "Downloading update...": "Stahování aktualizace...", - "State Key": "Stavový klíč", - "Failed to send custom event.": "Nepodařilo se odeslat vlastní událost.", - "What's new?": "Co je nového?", - "Notify me for anything else": "Upozorni mě na cokoliv jiného", - "When I'm invited to a room": "Pokud jsem pozván do místnosti", - "Can't update user notification settings": "Nelze aktualizovat uživatelské nastavení upozornění", - "Notify for all other messages/rooms": "Upozorni na všechny ostatní zprávy/místnosti", - "Unable to look up room ID from server": "Nelze získat ID místnosti ze serveru", - "Couldn't find a matching Matrix room": "Odpovídající Matrix místost nenalezena", - "All Rooms": "Všechny místnosti", - "You cannot delete this message. (%(code)s)": "Tuto zprávu nemůžete smazat. (%(code)s)", - "Thursday": "Čtvrtek", - "Search…": "Vyhledat…", - "Back": "Zpět", - "Failed to change settings": "Nepodařilo se změnit nastavení", - "Reply": "Odpovědět", - "Show message in desktop notification": "Zobrazovat zprávu v upozornění na ploše", - "Unhide Preview": "Zobrazit náhled", - "Unable to join network": "Nelze se připojit k síti", - "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Snad jste je nastavili v jiném klientu než Riot. V Riotu je nemůžete upravit, ale přesto platí", - "Sorry, your browser is not able to run Riot.": "Omlouváme se, váš prohlížeč není schopný spustit Riot.", - "Uploaded on %(date)s by %(user)s": "Nahráno %(date)s uživatelem %(user)s", - "Messages in group chats": "Zprávy ve skupinových chatech", - "Yesterday": "Včera", - "Error encountered (%(errorDetail)s).": "Nastala chyba (%(errorDetail)s).", - "Login": "Přihlásit", - "Low Priority": "Nízká priorita", - "Riot does not know how to join a room on this network": "Riot neví, jak vstoupit do místosti na této síti", - "Set Password": "Nastavit heslo", - "An error occurred whilst saving your email notification preferences.": "Při ukládání nastavení e-mailových upozornění nastala chyba.", - "Enable audible notifications in web client": "Povolit zvuková upozornění ve webové aplikaci", - "Permalink": "Trvalý odkaz", - "Off": "Vypnout", - "#example": "#příklad", - "Mentions only": "Pouze zmínky", - "Failed to remove tag %(tagName)s from room": "Nepodařilo se odstranit štítek %(tagName)s z místnosti", - "Wednesday": "Středa", - "You can now return to your account after signing out, and sign in on other devices.": "Nyní se můžete ke svému účtu vrátit i po odhlášení a používat jej na ostatních zařízeních.", - "Enable email notifications": "Zapnout upozornění přes e-mail", - "Event Type": "Typ události", - "Download this file": "Stáhnout tento soubor", - "Pin Message": "Připíchnout zprávu", - "Thank you!": "Děkujeme vám!", - "View Community": "Zobrazit Komunitu", - "%(count)s Members|one": "%(count)s Člen", - "Event sent!": "Událost odeslána!", - "Event Content": "Obsah události", - "Unable to fetch notification target list": "Nepodařilo se získat seznam cílů upozornění", - "Quote": "Citace", - "Collapse panel": "Sbalit panel", - "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Vzhled a chování aplikace může být ve vašem aktuální prohlížeči nesprávné a některé nebo všechny funkce mohou být chybné. Chcete-li i přes to pokračovat, nebudeme vám bránit, ale se všemi problémy, na které narazíte, si musíte poradit sami!", - "Checking for an update...": "Kontrola aktualizací...", - "There are advanced notifications which are not shown here": "Jsou k dispozici pokročilá upozornění, která zde nejsou zobrazena" + "Warning": "Upozornění" } diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 724ec8d11e..e67c9fcaaa 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -51,6 +51,7 @@ "Are you sure you want to reject the invitation?": "Bist du sicher, dass du die Einladung ablehnen willst?", "Are you sure you want to upload the following files?": "Bist du sicher, dass du die folgenden Dateien hochladen möchtest?", "Banned users": "Verbannte Benutzer", + "Bug Report": "Fehlerbericht", "Changes to who can read history will only apply to future messages in this room": "Änderungen, die bestimmen, wer den Chatverlauf lesen kann, gelten nur für zukünftige Nachrichten in diesem Raum", "Clear Cache and Reload": "Cache leeren und neu laden", "Confirm your new password": "Neues Passwort bestätigen", @@ -88,6 +89,7 @@ "Forgot your password?": "Passwort vergessen?", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Aus Sicherheitsgründen werden beim Ausloggen alle Ende-zu-Ende-Verschlüsselungs-Schlüssel in diesem Browser gelöscht. Wenn du in späteren Riot-Sitzungen den bisherigen Chatverlauf entschlüsseln möchtest, exportiere bitte deine Schlüssel zur sicheren Aufbewahrung.", "For security, this session has been signed out. Please sign in again.": "Aus Sicherheitsgründen wurde diese Sitzung beendet. Bitte melde dich erneut an.", + "Found a bug?": "Fehler gefunden?", "Guests cannot join this room even if explicitly invited.": "Gäste können diesem Raum nicht beitreten, auch wenn sie explizit eingeladen wurden.", "Hangup": "Auflegen", "Homeserver is": "Home-Server:", @@ -396,6 +398,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": "Melden", "riot-web version:": "Version von riot-web:", "Scroll to bottom of page": "Zum Seitenende springen", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Zeitstempel im 12-Stunden-Format anzeigen (z. B. 2:30pm)", @@ -650,9 +653,11 @@ "Define the power level of a user": "Setze das Berechtigungslevel eines Benutzers", "Edit": "Editieren", "Enable automatic language detection for syntax highlighting": "Automatische Spracherkennung für die Syntax-Hervorhebung aktivieren", + "Hide Apps": "Apps verbergen", "Hide join/leave messages (invites/kicks/bans unaffected)": "Betreten-/Verlassen-Benachrichtigungen verbergen (gilt nicht für Einladungen/Kicks/Bans)", "Revoke widget access": "Ziehe Widget-Zugriff zurück", "Sets the room topic": "Setzt das Raum-Thema", + "Show Apps": "Apps anzeigen", "To get started, please pick a username!": "Um zu starten, wähle bitte einen Nutzernamen!", "Unable to create widget.": "Widget kann nicht erstellt werden.", "Unbans user with given id": "Verbannung aufheben für Benutzer mit angegebener ID", @@ -687,6 +692,7 @@ "You are no longer ignoring %(userId)s": "%(userId)s wird nicht mehr ignoriert", "Message removed by %(userId)s": "Nachricht wurde von %(userId)s entfernt", "Name or matrix ID": "Name oder Matrix-ID", + "Unable to leave room": "Verlassen des Raumes fehlgeschlagen", "Leave": "Verlassen", "Failed to invite the following users to %(groupId)s:": "Die folgenden Benutzer konnten nicht in die Gruppe %(groupId)s eingeladen werden:", "Leave %(groupName)s?": "%(groupName)s verlassen?", @@ -907,6 +913,7 @@ "URL previews are disabled by default for participants in this room.": "URL-Vorschau ist für Mitglieder dieses Raumes standardmäßig deaktiviert.", "URL previews are enabled by default for participants in this room.": "URL-Vorschau ist für Mitglieder dieses Raumes standardmäßig aktiviert.", "Restricted": "Eingeschränkt", + "Presence Management": "Anwesenheitsmanagement", "Status.im theme": "Status.im-Thema", "%(duration)ss": "%(duration)ss", "%(duration)sm": "%(duration)sm", @@ -960,6 +967,7 @@ "Your homeserver's URL": "Die URL deines Homeservers", "Your identity server's URL": "Die URL deines Identitätsservers", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s", + "Tag Panel": "Beschriftungsfeld", "Message Replies": "Antworten auf Nachrichten", "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Du wirst nicht in der Lage sein, die Änderung zurückzusetzen, da du dich degradierst. Wenn du der letze Nutzer mit Berechtigungen bist, wird es unmöglich sein die Privilegien zurückzubekommen.", "Community IDs cannot not be empty.": "Community-IDs können nicht leer sein.", @@ -984,6 +992,7 @@ "Key request sent.": "Schlüssel-Anfragen gesendet.", "Re-request encryption keys from your other devices.": "Verschlüsselungs-Schlüssel von deinen anderen Geräten erneut anfragen.", "%(user)s is a %(userRole)s": "%(user)s ist ein %(userRole)s", + "Changes made to your community might not be seen by other users for up to 30 minutes.": "Änderungen, die an deiner Community gemacht werden, können bis zu 30 Minuten brauchen, bis sie für andere sichtbar sind.", "Debug Logs Submission": "Einsenden des Fehlerprotokolls", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Wenn du einen Fehler via GitHub gemeldet hast, können Fehlerberichte uns helfen um das Problem zu finden. Sie enthalten Anwendungsdaten wie deinen Nutzernamen, Raum- und Gruppen-ID's und Aliase die du besucht hast und Nutzernamen anderer Nutzer. Sie enthalten keine Nachrichten.", "Submit debug logs": "Fehlerberichte einreichen", @@ -994,167 +1003,5 @@ "Unable to leave community": "Community konnte nicht verlassen werden", "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Änderungen am Namen und Bild deiner Community werden evtl. erst nach 30 Minuten von anderen Nutzern gesehen werden.", "Join this community": "Community beitreten", - "Leave this community": "Community verlassen", - "Sticker Messages": "Sticker-Nachrichten", - "You don't currently have any stickerpacks enabled": "Du hast aktuell keine Stickerpacks aktiviert", - "Add a stickerpack": "Füge ein Stickerpack hinzu", - "Hide Stickers": "Sticker verbergen", - "Show Stickers": "Sticker zeigen", - "Who can join this community?": "Wer kann dieser Community beitreten?", - "Everyone": "Jeder", - "Stickerpack": "Stickerpack", - "Fetching third party location failed": "Das Abrufen des Drittanbieterstandorts ist fehlgeschlagen", - "A new version of Riot is available.": "Eine neue Version von Riot ist verfügbar.", - "Couldn't load home page": "Startseite konnte nicht geladen werden", - "Send Account Data": "Benutzerkonto-Daten senden", - "All notifications are currently disabled for all targets.": "Aktuell sind alle Benachrichtigungen für alle Ziele deaktiviert.", - "Uploading report": "Lade Bericht hoch", - "Sunday": "Sonntag", - "Notification targets": "Benachrichtigungsziele", - "Today": "Heute", - "Files": "Dateien", - "You are not receiving desktop notifications": "Du erhältst keine Desktop-Benachrichtigungen", - "Friday": "Freitag", - "Update": "Aktualisieren", - "What's New": "Was ist neu", - "Add an email address above to configure email notifications": "Füge oben eine E-Mail-Adresse hinzu, um die E-Mail-Benachrichtigungseinstellungen zu konfigurieren", - "Expand panel": "Panel ausklappen", - "On": "An", - "%(count)s Members|other": "%(count)s Mitglieder", - "Filter room names": "Raum-Namen filtern", - "Changelog": "Änderungsprotokoll", - "Waiting for response from server": "Auf Antwort vom Server warten", - "Send Custom Event": "Benutzerdefiniertes Event senden", - "Advanced notification settings": "Erweiterte Benachrichtigungs-Einstellungen", - "Failed to send logs: ": "Senden von Logs fehlgeschlagen: ", - "delete the alias.": "Lösche den Alias.", - "To return to your account in future you need to set a password": "Um in Zukunft auf dein Benutzerkonto zugreifen zu können, musst du ein Passwort setzen", - "Forget": "Entfernen", - "#example": "#Beispiel", - "Hide panel": "Panel verbergen", - "You cannot delete this image. (%(code)s)": "Das Bild kann nicht gelöscht werden. (%(code)s)", - "Cancel Sending": "Senden abbrechen", - "This Room": "In diesem Raum", - "The Home Server may be too old to support third party networks": "Der Home-Server ist eventuell zu alt, um Drittanbieter-Netzwerke zu unterstützen", - "Resend": "Erneut senden", - "Room not found": "Raum nicht gefunden", - "Messages containing my display name": "Nachrichten, die meinen Anzeigenamen enthalten", - "Messages in one-to-one chats": "Nachrichten in Einzel-Chats", - "Unavailable": "Nicht verfügbar", - "View Decrypted Source": "Entschlüsselten Quellcode ansehen", - "Failed to update keywords": "Schlüsselwörter konnten nicht aktualisiert werden", - "Notes:": "Notizen:", - "remove %(name)s from the directory.": "entferne %(name)s aus dem Verzeichnis.", - "Notifications on the following keywords follow rules which can’t be displayed here:": "Die Benachrichtigungen zu den folgenden Schlüsselwörtern folgen Regeln, die hier nicht angezeigt werden können:", - "Safari and Opera work too.": "Safari und Opera sind weitere Alternativen.", - "Please set a password!": "Bitte setze ein Passwort!", - "You have successfully set a password!": "Du hast erfolgreich ein Passwort gesetzt!", - "An error occurred whilst saving your email notification preferences.": "Beim Speichern deiner E-Mail-Benachrichtigungseinstellungen ist ein Fehler aufgetreten.", - "Explore Room State": "Raum-Status erkunden", - "Source URL": "Quell-URL", - "Messages sent by bot": "Nachrichten von Bots", - "Filter results": "Ergebnisse filtern", - "Members": "Mitglieder", - "No update available.": "Kein Update verfügbar.", - "Noisy": "Laut", - "Failed to get protocol list from Home Server": "Fehler beim Abrufen der Protokoll-Liste vom Home-Server", - "Collecting app version information": "App-Versionsinformationen werden abgerufen", - "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Soll der Raum-Alias %(alias)s gelöscht und der %(name)s aus dem Verzeichnis entfernt werden?", - "This will allow you to return to your account after signing out, and sign in on other devices.": "Dies erlaubt dir, dich wieder an deinem Konto anzumelden, nachdem du dich abgemeldet hast.", - "Keywords": "Schlüsselwörter", - "Enable notifications for this account": "Benachrichtigungen für dieses Benutzerkonto aktivieren", - "Directory": "Raum-Verzeichnis", - "Invite to this community": "In diese Community einladen", - "Failed to get public room list": "Die Liste der öffentlichen Räume konnte nicht geladen werden", - "Messages containing keywords": "Nachrichten, die Schlüsselwörter enthalten", - "Error saving email notification preferences": "Fehler beim Speichern der E-Mail-Benachrichtigungseinstellungen", - "Tuesday": "Dienstag", - "Enter keywords separated by a comma:": "Schlüsselwörter kommagetrennt eingeben:", - "Forward Message": "Nachricht weiterleiten", - "You have successfully set a password and an email address!": "Du hast erfolgreich ein Passwort und eine E-Mail-Adresse gesetzt!", - "Remove %(name)s from the directory?": "Soll der Raum %(name)s aus dem Verzeichnis entfernt werden?", - "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot nutzt zahlreiche fortgeschrittene Browser-Funktionen, die teilweise in deinem aktuell verwendeten Browser noch nicht verfügbar sind oder sich noch im experimentellen Status befinden.", - "Developer Tools": "Entwicklerwerkzeuge", - "Preparing to send logs": "Senden von Logs wird vorbereitet", - "Enable desktop notifications": "Desktop-Benachrichtigungen aktivieren", - "Remember, you can always set an email address in user settings if you change your mind.": "Vergiss nicht, dass du in den Benutzereinstellungen jederzeit eine E-Mail-Adresse setzen kannst, wenn du deine Meinung änderst.", - "Explore Account Data": "Benutzerkonto-Daten analysieren", - "All messages (noisy)": "Alle Nachrichten (laut)", - "Saturday": "Samstag", - "I understand the risks and wish to continue": "Ich verstehe das Risiko und möchte fortfahren", - "Direct Chat": "Direkt-Chat", - "The server may be unavailable or overloaded": "Der Server ist vermutlich nicht erreichbar oder überlastet", - "Reject": "Ablehnen", - "Failed to set Direct Message status of room": "Konnte den direkten Benachrichtigungsstatus nicht setzen", - "Monday": "Montag", - "Remove from Directory": "Aus dem Raum-Verzeichnis entfernen", - "Enable them now": "Aktiviere diese jetzt", - "Messages containing my user name": "Nachrichten, die meinen Benutzernamen enthalten", - "Toolbox": "Werkzeugkasten", - "Collecting logs": "Protokolle werden abgerufen", - "more": "mehr", - "GitHub issue link:": "Link des GitHub-Problems:", - "You must specify an event type!": "Du musst einen Event-Typ spezifizieren!", - "(HTTP status %(httpStatus)s)": "(HTTP-Status %(httpStatus)s)", - "Invite to this room": "In diesen Raum einladen", - "Please install Chrome or Firefox for the best experience.": "Bitte installiere Chrome oder Firefox für ein optimales Anwendungsergebnis.", - "Wednesday": "Mittwoch", - "You cannot delete this message. (%(code)s)": "Diese Nachricht kann nicht gelöscht werden. (%(code)s)", - "Quote": "Zitat", - "Send logs": "Logdateien übermitteln", - "All messages": "Alle Nachrichten", - "Call invitation": "Anruf-Einladung", - "Downloading update...": "Update wird heruntergeladen...", - "State Key": "Status-Schlüssel", - "Failed to send custom event.": "Senden des benutzerdefinierten Events fehlgeschlagen.", - "What's new?": "Was ist neu?", - "Notify me for anything else": "Über alles andere benachrichtigen", - "When I'm invited to a room": "Wenn ich in einen Raum eingeladen werde", - "Click here to create a GitHub issue.": "Klicke hier um ein GithHub-Problem zu erstellen.", - "Can't update user notification settings": "Benachrichtigungs-Einstellungen des Benutzers konnten nicht aktualisiert werden", - "Notify for all other messages/rooms": "Benachrichtigungen für alle anderen Mitteilungen/Räume aktivieren", - "Unable to look up room ID from server": "Es ist nicht möglich, die Raum-ID auf dem Server nachzuschlagen", - "Couldn't find a matching Matrix room": "Konnte keinen entsprechenden Matrix-Raum finden", - "All Rooms": "In allen Räumen", - "Search for a room": "Nach einem Raum suchen", - "Thursday": "Donnerstag", - "Search…": "Suchen…", - "Logs sent": "Logs gesendet", - "Back": "Zurück", - "Reply": "Antworten", - "Show message in desktop notification": "Nachricht in der Desktop-Benachrichtigung anzeigen", - "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Fehlerberichte enthalten Anwendungsdaten wie deinen Nutzernamen, Raum- und Gruppen-ID's und Aliase die du besucht hast sowie Nutzernamen anderer Nutzer. Sie enthalten keine Nachrichten.", - "Unhide Preview": "Vorschau wieder anzeigen", - "Unable to join network": "Es ist nicht möglich, dem Netzwerk beizutreten", - "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Du hast sie eventuell auf einem anderen Matrix-Client und nicht in Riot konfiguriert. Sie können in Riot nicht verändert werden, gelten aber trotzdem", - "Sorry, your browser is not able to run Riot.": "Es tut uns leid, aber dein Browser kann Riot nicht ausführen.", - "Messages in group chats": "Nachrichten in Gruppen-Chats", - "Yesterday": "Gestern", - "Error encountered (%(errorDetail)s).": "Es ist ein Fehler aufgetreten (%(errorDetail)s).", - "Login": "Anmeldung", - "Low Priority": "Niedrige Priorität", - "Unable to fetch notification target list": "Liste der Benachrichtigungsempfänger konnte nicht abgerufen werden", - "Set Password": "Passwort einrichten", - "Enable audible notifications in web client": "Audio-Benachrichtigungen im Web-Client aktivieren", - "Permalink": "Permanenter Link", - "Off": "Aus", - "Riot does not know how to join a room on this network": "Riot weiß nicht, wie es einem Raum auf diesem Netzwerk beitreten soll", - "Mentions only": "Nur, wenn du erwähnt wirst", - "You can now return to your account after signing out, and sign in on other devices.": "Du kannst nun zu deinem Benutzerkonto zurückkehren, nachdem du dich abgemeldet hast. Anschließend kannst du dich an anderen Geräten anmelden.", - "Enable email notifications": "E-Mail-Benachrichtigungen aktivieren", - "Event Type": "Event-Typ", - "Download this file": "Datei herunterladen", - "Pin Message": "Nachricht anheften", - "Failed to change settings": "Einstellungen konnten nicht geändert werden", - "View Community": "Community ansehen", - "%(count)s Members|one": "%(count)s Mitglied", - "Event sent!": "Event gesendet!", - "View Source": "Quellcode ansehen", - "Event Content": "Event-Inhalt", - "Thank you!": "Danke!", - "Uploaded on %(date)s by %(user)s": "Hochgeladen: %(date)s von %(user)s", - "Collapse panel": "Panel einklappen", - "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "In deinem aktuell verwendeten Browser können Aussehen und Handhabung der Anwendung unter Umständen noch komplett fehlerhaft sein, so dass einige bzw. im Extremfall alle Funktionen nicht zur Verfügung stehen. Du kannst es trotzdem versuchen und fortfahren, bist dabei aber bezüglich aller auftretenden Probleme auf dich allein gestellt!", - "Checking for an update...": "Nach Updates suchen...", - "There are advanced notifications which are not shown here": "Es existieren erweiterte Benachrichtigungen, welche hier nicht angezeigt werden" + "Leave this community": "Community verlassen" } diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index cadf232ecf..25cfc6cc82 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -57,6 +57,7 @@ "Banned users": "Utilisateurs bannis", "Bans user with given id": "Bannit l'utilisateur à partir de son identifiant", "Blacklisted": "Sur liste noire", + "Bug Report": "Rapport d'erreur", "Call Timeout": "Délai d’appel expiré", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Impossible de se connecter au serveur d'accueil en HTTP si l'URL dans la barre de votre explorateur est en HTTPS. Utilisez HTTPS ou activez le support des scripts non-vérifiés.", "Can't load user settings": "Impossible de charger les paramètres de l'utilisateur", @@ -92,8 +93,8 @@ "Current password": "Mot de passe actuel", "Curve25519 identity key": "Clé d’identité Curve25519", "/ddg is not a command": "/ddg n'est pas une commande", - "Deactivate Account": "Désactiver le compte", - "Deactivate my account": "Désactiver mon compte", + "Deactivate Account": "Supprimer le compte", + "Deactivate my account": "Supprimer mon compte", "Decrypt %(text)s": "Déchiffrer %(text)s", "Decryption error": "Erreur de déchiffrement", "Delete": "Supprimer", @@ -132,6 +133,7 @@ "Forget room": "Oublier le salon", "Forgot your password?": "Mot de passe oublié ?", "For security, this session has been signed out. Please sign in again.": "Par mesure de sécurité, la session a expiré. Merci de vous authentifier à nouveau.", + "Found a bug?": "Vous avez trouvé un problème ?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s de %(fromPowerLevel)s à %(toPowerLevel)s", "Hangup": "Raccrocher", "Hide read receipts": "Cacher les accusés de lecture", @@ -239,6 +241,7 @@ "%(senderName)s removed their profile picture.": "%(senderName)s a supprimé son image de profil.", "Remove %(threePid)s?": "Supprimer %(threePid)s ?", "%(senderName)s requested a VoIP conference.": "%(senderName)s a demandé une téléconférence audio.", + "Report it": "Le signaler", "Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Pour le moment, réinitialiser le mot de passe va réinitialiser les clés de chiffrement sur tous les appareils, rendant l’historique des salons chiffrés illisible, à moins que vous exportiez d'abord les clés de salon puis que vous les ré-importiez après. Cela sera amélioré prochainement.", "Return to login screen": "Retourner à l’écran de connexion", "Riot does not have permission to send you notifications - please check your browser settings": "Riot n’a pas la permission de vous envoyer des notifications - merci de vérifier les paramètres de votre navigateur", @@ -648,9 +651,11 @@ "Define the power level of a user": "Définir le rang d'un utilisateur", "Edit": "Modifier", "Enable automatic language detection for syntax highlighting": "Activer la détection automatique de la langue pour la correction orthographique", + "Hide Apps": "Masquer les applications", "Hide join/leave messages (invites/kicks/bans unaffected)": "Masquer les messages d'arrivée/départ (n'affecte pas les invitations/exclusions/bannissements)", "Revoke widget access": "Révoquer les accès du widget", "Sets the room topic": "Défini le sujet du salon", + "Show Apps": "Afficher les applications", "To get started, please pick a username!": "Pour commencer, choisissez un nom d'utilisateur !", "Unable to create widget.": "Impossible de créer un widget.", "Unbans user with given id": "Révoque le bannissement de l'utilisateur à partir de son identifiant", @@ -857,6 +862,7 @@ "Leave Community": "Quitter la communauté", "Leave %(groupName)s?": "Quitter %(groupName)s ?", "Leave": "Quitter", + "Unable to leave room": "Impossible de partir du salon", "Community Settings": "Paramètres de la communauté", "Add rooms to this community": "Ajouter des salons à cette communauté", "%(inviter)s has invited you to join this community": "%(inviter)s vous a invité à rejoindre cette communauté", @@ -900,6 +906,7 @@ "Username on %(hs)s": "Nom d'utilisateur sur %(hs)s", "Restricted": "Restreint", "Custom of %(powerLevel)s": "Personnalisé de %(powerLevel)s", + "Presence Management": "Gestion de présence", "Hide avatar changes": "Masquer les changements d'avatar", "Hide display name changes": "Masquer les changements de nom affiché", "Enable inline URL previews by default": "Activer l'aperçu des URL par défaut", @@ -927,6 +934,7 @@ "Flair will appear if enabled in room settings": "Les badges n'apparaîtront que s'ils sont activés dans les paramètres de chaque salon", "Flair will not appear": "Les badges n'apparaîtront pas", "Display your community flair in rooms configured to show it.": "Sélectionnez les badges dans les paramètres de chaque salon pour les afficher.", + "Tag Panel": "Panneau des étiquettes", "Addresses": "Adresses", "expand": "développer", "collapse": "réduire", @@ -984,6 +992,7 @@ "Key request sent.": "Demande de clé envoyée.", "Re-request encryption keys from your other devices.": "Re-demander les clés de chiffrement depuis vos autres appareils.", "%(user)s is a %(userRole)s": "%(user)s est %(userRole)s", + "Changes made to your community might not be seen by other users for up to 30 minutes.": "Les changements effectués sur votre communauté peuvent ne pas apparaître pour les autres utilisateurs avant 30 minutes.", "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Vu par %(displayName)s (%(userName)s) à %(dateTime)s", "Code": "Code", "Debug Logs Submission": "Envoi des journaux de débogage", @@ -998,162 +1007,13 @@ "Stickerpack": "Pack de stickers", "Sticker Messages": "Messages sticker", "You don't currently have any stickerpacks enabled": "Vous n'avez activé aucun pack de stickers pour l'instant", + "Click": "Cliquer", + "here": "ici", + "to add some!": "pour en ajouter !", "Add a stickerpack": "Ajouter un pack de stickers", "Hide Stickers": "Masquer les stickers", "Show Stickers": "Afficher les stickers", + "Manage sticker packs": "Gérer les packs de stickers", "Who can join this community?": "Qui peut rejoindre cette communauté ?", - "Everyone": "Tout le monde", - "Fetching third party location failed": "Échec de la récupération de la localisation tierce", - "A new version of Riot is available.": "Une nouvelle version de Riot est disponible.", - "Couldn't load home page": "Impossible de charger la page d'accueil", - "Send Account Data": "Envoyer les données du compte", - "All notifications are currently disabled for all targets.": "Toutes les notifications sont désactivées pour tous les appareils.", - "Uploading report": "Envoi du rapport", - "Sunday": "Dimanche", - "Notification targets": "Appareils recevant les notifications", - "Today": "Aujourd'hui", - "Files": "Fichiers", - "You are not receiving desktop notifications": "Vous ne recevez pas les notifications sur votre bureau", - "Friday": "Vendredi", - "Update": "Mettre à jour", - "What's New": "Nouveautés", - "Add an email address above to configure email notifications": "Ajouter une adresse e-mail pour la configuration des notifications par e-mail", - "Expand panel": "Dévoiler le panneau", - "On": "Activé", - "%(count)s Members|other": "%(count)s membres", - "Filter room names": "Filtrer les salons par nom", - "Changelog": "Journal des modifications", - "Waiting for response from server": "En attente d’une réponse du serveur", - "Send Custom Event": "Envoyer l'événement personnalisé", - "Advanced notification settings": "Paramètres de notification avancés", - "delete the alias.": "supprimer l'alias.", - "To return to your account in future you need to set a password": "Pour pouvoir retrouver votre compte dans le futur, vous devez définir un mot de passe", - "Forget": "Oublier", - "#example": "#exemple", - "Hide panel": "Cacher le panneau", - "You cannot delete this image. (%(code)s)": "Vous ne pouvez pas supprimer cette image. (%(code)s)", - "Cancel Sending": "Annuler l'envoi", - "This Room": "Ce salon", - "The Home Server may be too old to support third party networks": "Le serveur d'accueil semble trop ancien pour supporter des réseaux tiers", - "Noisy": "Bruyant", - "Room not found": "Salon non trouvé", - "Messages containing my display name": "Messages contenant mon nom affiché", - "Messages in one-to-one chats": "Messages dans les discussions directes", - "Unavailable": "Indisponible", - "View Decrypted Source": "Voir la source déchiffrée", - "Failed to update keywords": "Échec dans la mise à jour des mots-clés", - "remove %(name)s from the directory.": "supprimer %(name)s du répertoire.", - "Notifications on the following keywords follow rules which can’t be displayed here:": "Les notifications pour les mots-clés suivant répondent à des critères qui ne peuvent pas être affichés ici :", - "Safari and Opera work too.": "Safari et Opera fonctionnent également.", - "Please set a password!": "Veuillez définir un mot de passe !", - "You have successfully set a password!": "Vous avez défini un mot de passe avec succès !", - "An error occurred whilst saving your email notification preferences.": "Une erreur est survenue lors de la sauvegarde de vos préférences de notification par e-mail.", - "Explore Room State": "Parcourir l'état du salon", - "Source URL": "URL de la source", - "Messages sent by bot": "Messages envoyés par des robots", - "Filter results": "Filtrer les résultats", - "Members": "Membres", - "No update available.": "Aucune mise à jour disponible.", - "Resend": "Renvoyer", - "Failed to get protocol list from Home Server": "Échec lors de la récupération de la liste sur le serveur", - "Collecting app version information": "Récupération des informations de version de l’application", - "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Supprimer l'alias %(alias)s du salon et supprimer %(name)s du répertoire ?", - "This will allow you to return to your account after signing out, and sign in on other devices.": "Cela vous permettra de retourner sur votre compte après vous être déconnecté, et de vous identifier sur d'autres appareils.", - "Keywords": "Mots-clés", - "Enable notifications for this account": "Activer les notifications pour ce compte", - "Directory": "Répertoire", - "Invite to this community": "Inviter à cette communauté", - "Failed to get public room list": "Échec lors de la récupération de la liste des salons publics", - "Messages containing keywords": "Messages contenant des mots-clés", - "Error saving email notification preferences": "Erreur lors de la sauvegarde des préférences de notification par e-mail", - "Tuesday": "Mardi", - "Enter keywords separated by a comma:": "Entrez les mots-clés séparés par une virgule :", - "Search…": "Rechercher…", - "You have successfully set a password and an email address!": "Vous avez défini un mot de passe et une adresse e-mail avec succès !", - "Remove %(name)s from the directory?": "Supprimer %(name)s du répertoire ?", - "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot utilise de nombreuses fonctionnalités avancées du navigateur, certaines ne sont pas disponibles ou expérimentales dans votre navigateur actuel.", - "Developer Tools": "Outils de développement", - "Enable desktop notifications": "Activer les notifications de bureau", - "Remember, you can always set an email address in user settings if you change your mind.": "Souvenez-vous que vous pourrez toujours définir une adresse e-mail dans les paramètres de l'utilisateur si vous changez d’avis.", - "Explore Account Data": "Explorer les données du compte", - "Remove from Directory": "Supprimer du répertoire", - "Saturday": "Samedi", - "I understand the risks and wish to continue": "Je comprends les risques et souhaite continuer", - "Direct Chat": "Discussion directe", - "The server may be unavailable or overloaded": "Le serveur est indisponible ou surchargé", - "Reject": "Rejeter", - "Failed to set Direct Message status of room": "Échec du réglage de l'état du salon en Discussion directe", - "Monday": "Lundi", - "All messages (noisy)": "Tous les messages (fort)", - "Enable them now": "Les activer maintenant", - "Messages containing my user name": "Message contenant mon nom d'utilisateur", - "Toolbox": "Boîte à outils", - "Collecting logs": "Récupération des journaux", - "more": "plus", - "You must specify an event type!": "Vous devez spécifier un type d'événement !", - "(HTTP status %(httpStatus)s)": "(état HTTP %(httpStatus)s)", - "Invite to this room": "Inviter dans ce salon", - "Please install Chrome or Firefox for the best experience.": "Veuillez installer Chrome ou Firefox pour une expérience optimale.", - "Wednesday": "Mercredi", - "You cannot delete this message. (%(code)s)": "Vous ne pouvez pas supprimer ce message. (%(code)s)", - "Quote": "Citer", - "Send logs": "Envoyer les journaux", - "All messages": "Tous les messages", - "Call invitation": "Appel entrant", - "Downloading update...": "Mise à jour en cours de téléchargement...", - "State Key": "Clé d'état", - "Failed to send custom event.": "Échec de l'envoi de l'événement personnalisé.", - "What's new?": "Nouveautés ?", - "Notify me for anything else": "Me notifier pour tout le reste", - "View Source": "Voir la source", - "Can't update user notification settings": "Impossible de mettre à jour les paramètres de notification de l'utilisateur", - "Notify for all other messages/rooms": "Me notifier pour tous les autres messages/salons", - "Unable to look up room ID from server": "Impossible de récupérer l'ID du salon sur le serveur", - "Couldn't find a matching Matrix room": "Impossible de trouver un salon Matrix correspondant", - "All Rooms": "Tous les salons", - "Search for a room": "Rechercher un salon", - "Thursday": "Jeudi", - "Forward Message": "Transférer le message", - "Back": "Retour", - "Reply": "Répondre", - "Show message in desktop notification": "Afficher le message dans les notifications de bureau", - "Unhide Preview": "Dévoiler l'aperçu", - "Unable to join network": "Impossible de rejoindre le réseau", - "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Vous les avez probablement configurées dans un autre client que Riot. Vous ne pouvez pas les configurer dans Riot mais elles s'appliquent quand même", - "Sorry, your browser is not able to run Riot.": "Désolé, Riot n'est pas supporté par votre navigateur.", - "Uploaded on %(date)s by %(user)s": "Téléchargé le %(date)s par %(user)s", - "Messages in group chats": "Messages dans les discussions de groupe", - "Yesterday": "Hier", - "Error encountered (%(errorDetail)s).": "Erreur rencontrée (%(errorDetail)s).", - "Login": "Connexion", - "Low Priority": "Priorité basse", - "Unable to fetch notification target list": "Impossible de récupérer la liste des appareils recevant les notifications", - "Set Password": "Définir un mot de passe", - "Enable audible notifications in web client": "Activer les notifications sonores pour le client web", - "Permalink": "Permalien", - "Off": "Désactivé", - "Riot does not know how to join a room on this network": "Riot ne peut pas joindre un salon sur ce réseau", - "Mentions only": "Seulement les mentions", - "You can now return to your account after signing out, and sign in on other devices.": "Vous pouvez maintenant revenir sur votre compte après vous être déconnecté, et vous identifier sur d'autres appareils.", - "Enable email notifications": "Activer les notifications par e-mail", - "Event Type": "Type d'événement", - "Download this file": "Télécharger ce fichier", - "Pin Message": "Épingler le message", - "Failed to change settings": "Échec de la mise à jour des paramètres", - "View Community": "Voir la communauté", - "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Depuis votre navigateur actuel, le visuel et le ressenti de l'application pourraient être complètement erronés, et certaines fonctionnalités pourraient ne pas être supportées. Vous pouvez continuer malgré tout, mais vous n'aurez aucune aide si vous rencontrez des problèmes !", - "%(count)s Members|one": "%(count)s membre", - "Event sent!": "Événement envoyé !", - "Event Content": "Contenu de l'événement", - "Thank you!": "Merci !", - "Collapse panel": "Cacher le panneau", - "When I'm invited to a room": "Quand je suis invité dans un salon", - "Checking for an update...": "Recherche de mise à jour...", - "There are advanced notifications which are not shown here": "Il existe une configuration avancée des notifications qui ne peut être affichée ici", - "Logs sent": "Rapports envoyés", - "GitHub issue link:": "Lien du signalement GitHub :", - "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Les rapports de débogage contiennent des données d'usage de l'application qui incluent votre nom d'utilisateur, les identifiants ou alias des salons ou groupes auxquels vous avez rendu visite ainsi que les noms des autres utilisateurs. Ils ne contiennent aucun message.", - "Failed to send logs: ": "Échec lors de l'envoi des rapports : ", - "Notes:": "Notes :", - "Preparing to send logs": "Préparation d'envoi des rapports" + "Everyone": "Tout le monde" } diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 35dd348378..b7f20d52f7 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -10,7 +10,7 @@ "Mute": "Elnémít", "Notifications": "Értesítések", "Operation failed": "Sikertelen művelet", - "powered by Matrix": "Matrix hajtja", + "powered by Matrix": "A Matrix hajtja", "Remove": "Eltávolítás", "Settings": "Beállítások", "unknown error code": "ismeretlen hibakód", @@ -69,6 +69,7 @@ "Banned users": "Kitiltott felhasználók", "Bans user with given id": "Kitiltja a felhasználót a megadott ID-vel", "Blacklisted": "Fekete listára téve", + "Bug Report": "Hiba jelentés", "Bulk Options": "Tömeges beállítások", "Call Timeout": "Hívás időtúllépés", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Nem lehet kapcsolódni a saját szerverhez - ellenőrizd a kapcsolatot, biztosítsd, hogy a saját szerver tanúsítványa hiteles legyen, és a böngésző kiterjesztések ne blokkolják a kéréseket.", @@ -191,6 +192,7 @@ "Forgot your password?": "Elfelejtetted a jelszavad?", "For security, this session has been signed out. Please sign in again.": "A biztonság érdekében ez a kapcsolat le lesz bontva. Légy szíves jelentkezz be újra.", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "A biztonság érdekében a kilépéskor a ponttól pontig való (E2E) titkosításhoz szükséges kulcsok törlésre kerülnek a böngészőből. Ha a régi üzeneteket továbbra is el szeretnéd olvasni, kérlek mentsed ki a szobákhoz tartozó kulcsot.", + "Found a bug?": "Hibát találtál?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s : %(fromPowerLevel)s -> %(toPowerLevel)s", "Guest access is disabled on this Home Server.": "Vendég belépés tiltva van a Saját szerveren.", "Guests cannot join this room even if explicitly invited.": "Vendégek akkor sem csatlakozhatnak ehhez a szobához ha külön meghívók kaptak.", @@ -307,6 +309,7 @@ "%(senderName)s removed their profile picture.": "%(senderName)s törölte a profil képét.", "Remove %(threePid)s?": "Töröl: %(threePid)s?", "%(senderName)s requested a VoIP conference.": "%(senderName)s VoIP konferenciát kezdeményez.", + "Report it": "Jelent", "Results from DuckDuckGo": "Eredmények a DuckDuckGo-ból", "Return to login screen": "Vissza a bejelentkezési képernyőre", "Riot does not have permission to send you notifications - please check your browser settings": "Riotnak nincs jogosultsága értesítést küldeni neked - ellenőrizd a böngésző beállításait", @@ -649,11 +652,13 @@ "Define the power level of a user": "A felhasználó szintjének meghatározása", "Edit": "Szerkeszt", "Enable automatic language detection for syntax highlighting": "Nyelv automatikus felismerése szintaxis kiemeléshez", + "Hide Apps": "Alkalmazások elrejtése", "Hide join/leave messages (invites/kicks/bans unaffected)": "Belép/kilép üzenetek elrejtése (meghívók, kirúgások, kitiltások nem érintettek)", "AM": "de", "PM": "du", "Revoke widget access": "Kisalkalmazás hozzáférésének visszavonása", "Sets the room topic": "Szoba téma beállítás", + "Show Apps": "Alkalmazások mutatása", "To get started, please pick a username!": "Az induláshoz válassz egy felhasználói nevet!", "Unable to create widget.": "Nem lehet kisalkalmazást létrehozni.", "Unbans user with given id": "Visszaengedi a megadott azonosítójú felhasználót", @@ -697,7 +702,7 @@ "Disable Emoji suggestions while typing": "Emoji ajánlások kikapcsolása gépelés közben", "Banned by %(displayName)s": "Kitiltotta: %(displayName)s", "Message removed by %(userId)s": "Üzenetet törölte: %(userId)s", - "To send messages, you must be a": "Ahhoz, hogy üzenetet tudj küldeni, ilyen szinten kell lenned:", + "To send messages, you must be a": "Ahhoz, hogy üzenetet tudj küldeni, neked ilyen szinten kell lenned:", "To invite users into the room, you must be a": "Hogy meghívj valakit a szobába, ilyen szinten kell lenned:", "To configure the room, you must be a": "A szoba beállításához ilyen szinten kell lenned:", "To kick users, you must be a": "Felhasználó kirúgásához ilyen szinten kell lenned:", @@ -707,13 +712,14 @@ "To change the room's avatar, you must be a": "A szoba avatarjának a megváltoztatásához ilyen szinten kell lenned:", "To change the room's name, you must be a": "A szoba nevének megváltoztatásához ilyen szinten kell lenned:", "To change the room's main address, you must be a": "A szoba elsődleges címének a megváltoztatásához ilyen szinten kell lenned:", - "To change the room's history visibility, you must be a": "A szoba napló elérhetőségének a megváltoztatásához ilyen szinten kell lenned:", + "To change the room's history visibility, you must be a": "A szoba naplója elérhetőségének a megváltoztatásához ilyen szinten kell lenned:", "To change the permissions in the room, you must be a": "A szobában a jogosultság megváltoztatásához ilyen szinten kell lenned:", "To change the topic, you must be a": "A téma megváltoztatásához ilyen szinten kell lenned:", "To modify widgets in the room, you must be a": "A szoba kisalkalmazásainak megváltoztatásához ilyen szinten kell lenned:", "Description": "Leírás", "Name or matrix ID": "Név vagy Matrix azonosító", "Unable to accept invite": "A meghívót nem lehet elfogadni", + "Unable to leave room": "A szobát nem lehet elhagyni", "Leave": "Elhagy", "Failed to invite the following users to %(groupId)s:": "Az alábbi felhasználókat nem sikerült meghívni a(z) %(groupId)s:", "Failed to invite users to %(groupId)s": "Nem sikerült meghívni a felhasználókat ebbe a csoportba: %(groupId)s", @@ -730,7 +736,7 @@ "Failed to remove the room from the summary of %(groupId)s": "Az alábbi szobákat nem sikerült eltávolítani a(z) %(groupId)s csoport összefoglalójából", "The room '%(roomName)s' could not be removed from the summary.": "Nem sikerült törölni az összefoglalóból ezt a szobát: '%(roomName)s'.", "Failed to remove a user from the summary of %(groupId)s": "Nem sikerült törölni az összefoglalóból ezt a felhasználót: %(groupId)s", - "The user '%(displayName)s' could not be removed from the summary.": "Nem sikerült törölni az összefoglalóból a(z) %(displayName)s felhasználót", + "The user '%(displayName)s' could not be removed from the summary.": "Nem sikerült törölni az összefoglalóból ezt a felhasználót: %(groupId)s.", "Light theme": "Világos téma", "Dark theme": "Sötét téma", "Unknown": "Ismeretlen", @@ -900,6 +906,7 @@ "Username on %(hs)s": "Felhasználónév a %(hs)s szerveren", "Restricted": "Korlátozott", "Custom of %(powerLevel)s": "Egyedi beállítás: %(powerLevel)s", + "Presence Management": "Jelenlét menedzsment", "Hide avatar changes": "Avatar változások elrejtése", "Hide display name changes": "Név változások elrejtése", "Enable inline URL previews by default": "Beágyazott URL előnézetek alapértelmezett engedélyezése", @@ -927,6 +934,7 @@ "Something went wrong when trying to get your communities.": "Valami nem sikerült a közösségeid elérésénél.", "Display your community flair in rooms configured to show it.": "Közösségi jelvényeid megjelenítése azokban a szobákban ahol ez engedélyezett.", "This homeserver doesn't offer any login flows which are supported by this client.": "Ez a saját szerver egyetlen bejelentkezési metódust sem támogat amit ez a kliens ismer.", + "Tag Panel": "Címke panel", "Addresses": "Címek", "collapse": "becsuk", "expand": "kinyit", @@ -976,7 +984,7 @@ "Failed to add tag %(tagName)s to room": "Nem sikerült hozzáadni a szobához ezt: %(tagName)s", "Clear filter": "Szűrő törlése", "Disable Community Filter Panel": "Közösség keresési panel tiltása", - "Did you know: you can use communities to filter your Riot.im experience!": "Tudtad, hogy a Riot.im élmény fokozásához használhatsz közösségeket?", + "Did you know: you can use communities to filter your Riot.im experience!": "Tudtad, hogy a közösségeket használhatod a Riot.im élmény fokozásához?", "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "A szűrő beállításához húzd a közösség avatarját a szűrő panel fölé a képernyő bal szélén. A szűrő panelen az avatarra kattintva bármikor leszűrheted azokat a szobákat és embereket akik a megadott közösséghez tartoznak.", "Your key share request has been sent - please check your other devices for key share requests.": "A kulcs megosztási kérést elküldtük - ellenőrizd a többi eszközödön a kulcs megosztási kéréseket.", "Key share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, click here to request the keys for this session again.": "A kulcs megosztási kérelem automatikusan el lett küldve a többi eszközödre. Ha elutasítottad vagy törölted a kérést a másik eszközön ide kattintva újra kérheted a kulcsokat.", @@ -984,6 +992,7 @@ "Key request sent.": "Kulcs kérés elküldve.", "Re-request encryption keys from your other devices.": "Kulcsok újrakérése a többi eszközödtől.", "%(user)s is a %(userRole)s": "%(user)s egy %(userRole)s", + "Changes made to your community might not be seen by other users for up to 30 minutes.": "A közösségedben végrehajtott változtatás valószínűleg legalább 30 percig nem lesz látható mások számára.", "Code": "Kód", "Debug Logs Submission": "Hibakeresési napló elküldése", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Ha a GitHubon keresztül küldted be a hibát, a hibakeresési napló segíthet nekünk a javításban. A napló felhasználási adatokat tartalmaz mint a felhasználói neved, az általad meglátogatott szobák vagy csoportok azonosítóját vagy alternatív nevét és mások felhasználói nevét. De nem tartalmazzák az üzeneteket.", @@ -998,163 +1007,13 @@ "Stickerpack": "Matrica csomag", "Sticker Messages": "Matrica üzenetek", "You don't currently have any stickerpacks enabled": "Nincs engedélyezett matrica csomagod", + "Click": "Kattints", + "here": "ide", + "to add some!": "hogy adj hozzá párat!", "Add a stickerpack": "Matrica csomag hozzáadása", "Hide Stickers": "Matricák elrejtése", "Show Stickers": "Matricák megjelenítése", + "Manage sticker packs": "Matrica csomagok kezelése", "Who can join this community?": "Ki tud csatlakozni ehhez a közösséghez?", - "Everyone": "Mindenki", - "Fetching third party location failed": "Nem sikerült lekérdezni a harmadik fél helyét", - "A new version of Riot is available.": "Elérhető egy új Riot verzió.", - "Couldn't load home page": "Nem sikerült betölteni a kezdőlapot", - "Send Account Data": "Fiókadatok küldése", - "All notifications are currently disabled for all targets.": "Minden céleszközön minden értesítés tiltva van.", - "Uploading report": "Jelentés feltöltése", - "Sunday": "Vasárnap", - "Notification targets": "Értesítések célpontja", - "Today": "Ma", - "Files": "Fájlok", - "You are not receiving desktop notifications": "Nem fogadsz asztali értesítéseket", - "Friday": "Péntek", - "Update": "Frissítés", - "What's New": "Újdonságok", - "Add an email address above to configure email notifications": "E-mail értesítések beállításához adj meg egy e-mail címet", - "Expand panel": "Panel kinyitása", - "On": "Be", - "%(count)s Members|other": "%(count)s tag", - "Filter room names": "Szobanevek szűrése", - "Changelog": "Változások", - "Waiting for response from server": "Várakozás a szerver válaszára", - "Send Custom Event": "Egyéni esemény elküldése", - "Advanced notification settings": "Haladó értesítési beállítások", - "Failed to send logs: ": "Hiba a napló küldésénél: ", - "delete the alias.": "becenév törlése.", - "To return to your account in future you need to set a password": "Hogy később visszaléphess a fiókodba, be kell állítanod egy jelszót", - "Forget": "Elfelejt", - "#example": "#példa", - "Hide panel": "Panel elrejtése", - "You cannot delete this image. (%(code)s)": "Nem törölheted ezt a képet. (%(code)s)", - "Cancel Sending": "Küldés megszakítása", - "This Room": "Ebben a szobában", - "The Home Server may be too old to support third party networks": "Lehet, hogy a saját szerver túl régi és nem támogatja a csatlakozást más hálózatokhoz", - "Resend": "Küldés újra", - "Room not found": "A szoba nem található", - "Messages containing my display name": "A profilnevemet tartalmazó üzenetek", - "Messages in one-to-one chats": "Személyes beszélgetések üzenetei", - "Unavailable": "Elérhetetlen", - "View Decrypted Source": "Visszafejtett forrás megjelenítése", - "Failed to update keywords": "Nem lehet frissíteni a kulcsszavakat", - "Notes:": "Jegyzetek:", - "remove %(name)s from the directory.": "%(name)s szoba törlése a listából.", - "Notifications on the following keywords follow rules which can’t be displayed here:": "Az alábbi kulcsszavakról jövő értesítések szabályait nem lehet itt megjeleníteni:", - "Safari and Opera work too.": "Safarival és Operával is működik.", - "Please set a password!": "Állíts be egy jelszót!", - "You have successfully set a password!": "Sikerült beállítani a jelszót!", - "An error occurred whilst saving your email notification preferences.": "Hiba történt az e-mail értesítési beállításaid mentése közben.", - "Explore Room State": "Szoba állapot felderítése", - "Source URL": "Forrás URL", - "Messages sent by bot": "Botok üzenetei", - "Filter results": "Találatok szűrése", - "Members": "Résztvevők", - "No update available.": "Nincs elérhető frissítés.", - "Noisy": "Hangos", - "Failed to get protocol list from Home Server": "Nem sikerült a protokoll listát lekérni a saját szerverről", - "Collecting app version information": "Alkalmazás verzió információk összegyűjtése", - "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Törlöd a szoba nevét (%(alias)s) és eltávolítod a listából ezt: %(name)s?", - "This will allow you to return to your account after signing out, and sign in on other devices.": "Így kijelentkezés után is vissza tudsz lépni a fiókodba, illetve más készülékekről is be tudsz lépni.", - "Keywords": "Kulcsszavak", - "Enable notifications for this account": "Értesítések engedélyezése ehhez a fiókhoz", - "Directory": "Könyvtár", - "Invite to this community": "Meghívás ebbe a közösségbe", - "Search for a room": "Szoba keresése", - "Messages containing keywords": "Kulcsszavakat tartalmazó üzenetek", - "Error saving email notification preferences": "Hiba az e-mail értesítési beállítások mentésekor", - "Tuesday": "Kedd", - "Enter keywords separated by a comma:": "Kulcsszavak vesszővel elválasztva:", - "Forward Message": "Üzenet továbbítása", - "You have successfully set a password and an email address!": "Sikerült beállítani a jelszavad és e-mail címed!", - "Remove %(name)s from the directory?": "Törlöd ezt a szobát a listából: %(name)s?", - "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "A Riot sok fejlett böngészőfunkciót használ, amelyeknek egy része egyáltalán nem, vagy csak kísérleti jelleggel érhető el a jelenlegi böngésződben.", - "Developer Tools": "Fejlesztői eszközök", - "Preparing to send logs": "Előkészülés napló küldéshez", - "Enable desktop notifications": "Asztali értesítések engedélyezése", - "Remember, you can always set an email address in user settings if you change your mind.": "Ha meggondolod magad, bármikor beállíthatod az e-mail címed a felhasználói beállításoknál.", - "Explore Account Data": "Fiókadatok felderítése", - "Remove from Directory": "Törlés a listából", - "Saturday": "Szombat", - "I understand the risks and wish to continue": "Megértettem a kockázatot és folytatom", - "Direct Chat": "Közvetlen csevegés", - "The server may be unavailable or overloaded": "A szerver nem elérhető vagy túlterhelt", - "Reject": "Elutasít", - "Failed to set Direct Message status of room": "Nem lehet beállítani a szoba közvetlen beszélgetés státuszát", - "Monday": "Hétfő", - "All messages (noisy)": "Minden üzenet (hangos)", - "Enable them now": "Engedélyezés most", - "Messages containing my user name": "A felhasználónevemet tartalmazó üzenetek", - "Toolbox": "Eszköztár", - "Collecting logs": "Naplók összegyűjtése", - "more": "tovább", - "GitHub issue link:": "GitHub hibajegy hivatkozás:", - "You must specify an event type!": "Meg kell jelölnöd az eseménytípust!", - "(HTTP status %(httpStatus)s)": "(HTTP állapot: %(httpStatus)s)", - "Invite to this room": "Meghívás a szobába", - "Please install Chrome or Firefox for the best experience.": "A legjobb élmény érdekében telepíts Chrome vagy Firefox böngészőt.", - "Failed to get public room list": "Nem sikerült lekérdezni a nyilvános szobák listáját", - "Quote": "Idéz", - "Send logs": "Naplófájlok elküldése", - "All messages": "Minden üzenet", - "Call invitation": "Hívás meghívó", - "Downloading update...": "Frissítés letöltése...", - "State Key": "Állapotkulcs", - "Failed to send custom event.": "Nem sikerült elküldeni az egyéni eseményt.", - "What's new?": "Mik az újdonságok?", - "Notify me for anything else": "Értesíts minden egyéb esetben", - "When I'm invited to a room": "Amikor meghívnak egy szobába", - "Click here to create a GitHub issue.": "Kattints ide GitHub hibajegy nyitásához .", - "Can't update user notification settings": "Nem lehet frissíteni az értesítési beállításokat", - "Notify for all other messages/rooms": "Értesítés minden más üzenethez/szobához", - "Unable to look up room ID from server": "Nem lehet a szoba azonosítóját megkeresni a szerveren", - "Couldn't find a matching Matrix room": "Nem található a keresett Matrix szoba", - "All Rooms": "Minden szobában", - "You cannot delete this message. (%(code)s)": "Nem törölheted ezt az üzenetet. (%(code)s)", - "Thursday": "Csütörtök", - "Search…": "Keresés…", - "Logs sent": "Napló elküldve", - "Back": "Vissza", - "Reply": "Válasz", - "Show message in desktop notification": "Üzenetek megjelenítése az asztali értesítéseknél", - "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "A hibakereső napló alkalmazás használati adatokat tartalmaz beleértve a felhasználói nevedet, az általad meglátogatott szobák és csoportok azonosítóit alternatív neveit és más felhasználói neveket. Csevegés üzenetek szövegét nem tartalmazza.", - "Unhide Preview": "Előnézet mutatása", - "Unable to join network": "Nem sikerült kapcsolódni a hálózathoz", - "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Egy másik, nem Riot-klienssel állítothattad be. A Riotban módosítani nem tudod ezeket, de érvényben vannak", - "Sorry, your browser is not able to run Riot.": "Elnézést, a böngésződben nem fut a Riot.", - "Uploaded on %(date)s by %(user)s": "Feltöltötte %(user)s ekkor: %(date)s", - "Messages in group chats": "Csoportszobák üzenetei", - "Yesterday": "Tegnap", - "Error encountered (%(errorDetail)s).": "Hiba történt (%(errorDetail)s).", - "Login": "Bejelentkezés", - "Low Priority": "Alacsony prioritás", - "Unable to fetch notification target list": "Nem sikerült letölteni az értesítési célok listáját", - "Set Password": "Jelszó beállítása", - "Enable audible notifications in web client": "Hangértesítések engedélyezése a webkliensben", - "Permalink": "Állandó hivatkozás", - "Off": "Ki", - "Riot does not know how to join a room on this network": "A Riot nem tud csatlakozni szobához ezen a hálózaton", - "Mentions only": "Csak ha megemlítenek", - "Wednesday": "Szerda", - "You can now return to your account after signing out, and sign in on other devices.": "Most már kijelentkezés után is vissza tudsz lépni a fiókodba, és más készülékekről is be tudsz lépni.", - "Enable email notifications": "E-mail értesítések engedélyezése", - "Event Type": "Esemény típusa", - "Download this file": "Fájl letöltése", - "Pin Message": "Üzenet rögzítése", - "Failed to change settings": "A beállítások megváltoztatása nem sikerült", - "View Community": "Közösség megtekintése", - "%(count)s Members|one": "%(count)s tag", - "Event sent!": "Az esemény elküldve!", - "View Source": "Forrás megjelenítése", - "Event Content": "Esemény tartalma", - "Thank you!": "Köszönjük!", - "Collapse panel": "Panel becsukása", - "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Ebben a böngészőben az alkalmazás felülete tele lehet hibával, és az is lehet, hogy egyáltalán nem működik. Ha így is ki szeretnéd próbálni, megteheted, de ha valami gondod van, nem tudunk segíteni!", - "Checking for an update...": "Frissítés keresése...", - "There are advanced notifications which are not shown here": "Vannak itt nem látható, haladó értesítések" + "Everyone": "Mindenki" } diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index 5f0b3fc683..d4bda9c6da 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -29,6 +29,7 @@ "Banned users": "Verbannen gebruikers", "Bans user with given id": "Verbant de gebruiker met het gegeven ID", "Blacklisted": "Buitengesloten", + "Bug Report": "Bug report", "Bulk Options": "Bulk opties", "Call Timeout": "Gesprek time-out", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Kan niet met de thuisserver verbinden via HTTP wanneer er een HTTPS-URL in je browser balk staat. Gebruik HTTPS of activeer onveilige scripts.", @@ -261,6 +262,7 @@ "Forgot your password?": "Wachtwoord vergeten?", "For security, this session has been signed out. Please sign in again.": "Voor veiligheidsredenen is deze sessie uitgelogd. Log alsjeblieft opnieuw in.", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "In verband met veiligheidsredenen zullen alle end-to-endbeveiligingsleutels van deze browser verwijderd worden. Als je je gespreksgeschiedenis van toekomstige Riot sessies wilt kunnen ontsleutelen, exporteer en bewaar dan de ruimte sleutels.", + "Found a bug?": "Een fout gevonden?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s van %(fromPowerLevel)s naar %(toPowerLevel)s", "Guest access is disabled on this Home Server.": "Gasttoegang is uitgeschakeld op deze thuisserver.", "Guests cannot join this room even if explicitly invited.": "Gasten kunnen niet tot deze ruimte toetreden, zelfs als ze expliciet uitgenodigd zijn.", @@ -338,6 +340,7 @@ "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 end-to-endbeveiligingssleutels 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.", "Results from DuckDuckGo": "Resultaten van DuckDuckGo", "Return to login screen": "Naar het inlogscherm terugkeren", @@ -651,6 +654,7 @@ "Do you want to load widget from URL:": "Wil je de widget laden van de URL:", "Edit": "Aanpassen", "Enable automatic language detection for syntax highlighting": "Automatische taaldetectie voor zinsbouwmarkeringen aanzetten", + "Hide Apps": "Apps verbergen", "Hide join/leave messages (invites/kicks/bans unaffected)": "Toetreed/verlaat berichten verbergen (uitnodigingen/verwijderingen/verbanningen zullen ongeschonden blijven)", "Integrations Error": "Integratiesfout", "Publish this room to the public in %(domain)s's room directory?": "Deze ruimte publiekelijk maken in %(domain)s's ruimte catalogus?", @@ -659,6 +663,7 @@ "NOTE: Apps are not end-to-end encrypted": "OPMERKING: Apps zijn niet end-to-endbeveiligd", "Revoke widget access": "Toegang tot widget intrekken", "Sets the room topic": "Wijzigt het ruimte-onderwerp", + "Show Apps": "Apps Weergeven", "The maximum permitted number of widgets have already been added to this room.": "Het maximum aantal toegestane widgets is al aan deze ruimte toegevoegd.", "To get started, please pick a username!": "Om te beginnen, kies een gebruikersnaam!", "Unable to create widget.": "Niet in staat om een widget te maken.", @@ -717,6 +722,7 @@ "Send": "Verstuur", "Message Pinning": "Boodschap vastpinnen", "Message Replies": "Antwoorden op bericht", + "Presence Management": "Presentie Beheer", "Tag Panel": "Label Paneel", "Disable Emoji suggestions while typing": "Emoji suggesties tijdens het typen uitzetten", "Hide avatar changes": "Avatar veranderingen verbergen", @@ -882,6 +888,7 @@ "collapse": "inklappen", "expand": "openklappen", "Custom of %(powerLevel)s": "Aangepast rank van %(powerLevel)s", + "Quote": "Citeren", "And %(count)s more...|other": "En %(count)s meer...", "Matrix ID": "Matrix ID", "Matrix Room ID": "Matrix Ruimte ID", @@ -918,6 +925,7 @@ "Leave Community": "Gemeenschap Verlaten", "Leave %(groupName)s?": "%(groupName)s verlaten?", "Leave": "Verlaten", + "Unable to leave room": "De ruimte kon niet verlaten worden", "Community Settings": "Gemeenschapsinstellingen", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Deze ruimtes worden aan gemeenschapsleden getoond op de gemeenschapspagina. Gemeenschapsleden kunnen tot de ruimtes toetreden door er op te klikken.", "%(inviter)s has invited you to join this community": "%(inviter)s heeft jou uitgenodigd om tot deze gemeenschap toe te treden", @@ -929,6 +937,8 @@ "Community %(groupId)s not found": "Gemeenschap %(groupId)s is niet gevonden", "This Home server does not support communities": "Deze Thuisserver ondersteunt geen gemeenschappen", "Failed to load %(groupId)s": "Het is niet gelukt om %(groupId)s te laden", + "Cryptography data migrated": "Cryptografie gegevens zijn gemigreerd", + "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "Een eenmalige migratie van cryptografie gegevens heeft plaatsgevonden. Eind-tot-eind versleuteling zal niet werken als je terug gaat naar een oudere versie van Riot. Log eerst uit op Riot als je eind-tot-eind versleuteling wil gebruiken op een oudere versie. Exporteer je sleutels en importeer ze achteraf weer als je de berichtgeschiedenis wilt behouden.", "Old cryptography data detected": "Oude cryptografie gegevens gedetecteerd", "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Er zijn gegevens van een oudere versie van Riot gedetecteerd. Dit zal eind-tot-eind versleuteling laten storen in de oudere versie. Eind-tot-eind berichten dat recent zijn uitgewisseld zal misschien niet ontsleutelbaar zijn in deze versie. Dit zou er misschien ook voor kunnen zorgen dat berichten die zijn uitgewisseld in deze versie falen. Indien je problemen ervaart, log opnieuw in. Om de berichtgeschiedenis te behouden, exporteer de sleutels en importeer ze achteraf weer.", "Your Communities": "Jouw Gemeenschappen", @@ -984,177 +994,5 @@ "Clear filter": "Filter vrijmaken", "Failed to set direct chat tag": "Het is niet gelukt om de 'privégesprek' label in te stellen", "Failed to remove tag %(tagName)s from room": "Het is niet gelukt om de label %(tagName)s van de ruimte te verwijderen", - "Failed to add tag %(tagName)s to room": "Het is niet gelukt om de label %(tagName)s aan deze ruimte toe te voegen", - "Stickerpack": "Stickerpakket", - "Sticker Messages": "Sticker Berichten", - "You don't currently have any stickerpacks enabled": "Je hebt momenteel geen stickerpakketten aan staan", - "Add a stickerpack": "Stickerpakket toevoegen", - "Hide Stickers": "Stickers verbergen", - "Show Stickers": "Stickers weergeven", - "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Gezien door %(displayName)s (%(userName)s) op %(dateTime)s", - "Code": "Code", - "Unable to join community": "Je kon niet tot de gemeenschap toetreden", - "Unable to leave community": "Je kon de gemeenschap niet verlaten", - "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Veranderingen die aan je gemeenschap naam en avatar zijn aangebracht zullen misschien niet gezien worden door anderen tot maximaal 30 minuten.", - "Join this community": "Tot deze gemeenschap toetreden", - "Who can join this community?": "Wie kan tot deze gemeenschap toetreden?", - "Everyone": "Iedereen", - "Leave this community": "Deze gemeenschap verlaten", - "Debug Logs Submission": "Debug Logs Indienen", - "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Als je een bug via Github hebt ingediend kunnen debug logs ons helpen om het probleem te vinden. Debug logs bevatten applicatie-gebruik data inclusief je gebruikersnaam, de ID's of namen van de ruimtes en groepen die je hebt bezocht en de gebruikersnamen van andere gebruikers. Ze bevatten geen berichten.", - "Submit debug logs": "Debug logs indienen", - "Opens the Developer Tools dialog": "Opent het Ontwikkelaars Gereedschappen dialoog", - "Fetching third party location failed": "Het ophalen van de locatie van de derde partij is mislukt", - "A new version of Riot is available.": "Er is een nieuwe versie van Riot beschikbaar.", - "I understand the risks and wish to continue": "Ik begrijp de risico's en wil graag verder gaan", - "Couldn't load home page": "Kon de home pagina niet laden", - "Send Account Data": "Stuur account informatie", - "All notifications are currently disabled for all targets.": "Alle meldingen zijn momenteel uitgeschakeld voor alle doelen.", - "Uploading report": "Rapport uploaden", - "Sunday": "Zondag", - "Notification targets": "Meldingsdoelen", - "Today": "Vandaag", - "Files": "Bestanden", - "You are not receiving desktop notifications": "Je ontvangt momenteel geen desktopmeldingen", - "Friday": "Vrijdag", - "Update": "Bijwerken", - "What's New": "Wat is er nieuw", - "Add an email address above to configure email notifications": "Voeg een e-mailadres toe om e-mailmeldingen te ontvangen", - "Expand panel": "Paneel uitklappen", - "On": "Aan", - "%(count)s Members|other": "%(count)s Deelnemers", - "Filter room names": "Filter kamernamen", - "Changelog": "Logboek van wijzigingen", - "Waiting for response from server": "Wachten op antwoord van de server", - "Send Custom Event": "Verzend aangepast evenement", - "Advanced notification settings": "Geavanceerde meldingsinstellingen", - "delete the alias.": "verwijder de alias.", - "To return to your account in future you need to set a password": "Om in de toekomst naar je account terug te gaan moet je een wachtwoord instellen", - "Forget": "Vergeten", - "#example": "#voorbeeld", - "Hide panel": "Paneel verbergen", - "You cannot delete this image. (%(code)s)": "Je kunt deze afbeelding niet verwijderen. (%(code)s)", - "Cancel Sending": "Versturen annuleren", - "This Room": "Deze kamer", - "The Home Server may be too old to support third party networks": "De thuisserver is misschien te oud om netwerken van derde partijen te ondersteunen", - "Resend": "Opnieuw verzenden", - "Error saving email notification preferences": "Fout bij het opslaan van de meldingsvoorkeuren voor e-mail", - "Messages containing my display name": "Berichten die mijn weergavenaam bevatten", - "Messages in one-to-one chats": "Berichten in één-op-één-gesprekken", - "Unavailable": "Niet beschikbaar", - "View Decrypted Source": "Bekijk ontsleutelde bron", - "Failed to update keywords": "Trefwoorden bijwerken mislukt", - "remove %(name)s from the directory.": "verwijder %(name)s uit de kamerlijst.", - "Notifications on the following keywords follow rules which can’t be displayed here:": "Meldingen op de volgende trefwoorden volgen regels die hier niet kunnen worden getoond:", - "Safari and Opera work too.": "Safari en Opera werken ook.", - "Please set a password!": "Stel een wachtwoord in!", - "You have successfully set a password!": "U heeft met succes een wachtwoord ingesteld!", - "An error occurred whilst saving your email notification preferences.": "Er is een fout opgetreden tijdens het opslaan van uw e-mailmeldingsvoorkeuren.", - "Explore Room State": "Verken Ruimtetoestand", - "Source URL": "Bron-URL", - "Messages sent by bot": "Berichten verzonden door een bot", - "Filter results": "Resultaten filteren", - "Members": "Leden", - "No update available.": "Geen update beschikbaar.", - "Noisy": "Luidruchtig", - "Failed to get protocol list from Home Server": "Protocollijst ophalen van de homeserver mislukt", - "Collecting app version information": "App-versieinformatie verzamelen", - "Delete the room alias %(alias)s and remove %(name)s from the directory?": "De alias %(alias)s verwijderen en %(name)s uit de kamerlijst verwijderen?", - "This will allow you to return to your account after signing out, and sign in on other devices.": "Hiermee kunt u naar uw account terugkeren nadat u zich heeft afgemeld, en u aanmelden op andere apparaten.", - "Keywords": "Trefwoorden", - "Enable notifications for this account": "Meldingen voor dit account aanzetten", - "Directory": "Kamerlijst", - "Invite to this community": "Nodig uit in deze community", - "Search for a room": "Een kamer opzoeken", - "Messages containing keywords": "Berichten die trefwoorden bevatten", - "Room not found": "De kamer is niet gevonden", - "Tuesday": "Dinsdag", - "Enter keywords separated by a comma:": "Voeg trefwoorden toe, gescheiden door een komma:", - "Search…": "Zoeken…", - "You have successfully set a password and an email address!": "Het instellen van een wachtwoord en e-mailadres is geslaagd!", - "Remove %(name)s from the directory?": "%(name)s uit de kamerlijst verwijderen?", - "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot gebrukt veel geavanceerde browserfuncties, waarvan enkele niet (of experimenteel) in uw webbrowser beschikbaar zijn.", - "Developer Tools": "Ontwikkelaarsgereedschap", - "Enable desktop notifications": "Desktopmeldingen aanzetten", - "Explore Account Data": "Bekijk account informatie", - "Remove from Directory": "Uit de kamerlijst verwijderen", - "Saturday": "Zaterdag", - "Remember, you can always set an email address in user settings if you change your mind.": "Onthoud dat u altijd een e-mailadres in kan stellen in de gebruikersinstellingen als u zich bedenkt.", - "Direct Chat": "Privégesprek", - "The server may be unavailable or overloaded": "De server is misschien niet beschikbaar of overbelast", - "Reject": "Afwijzen", - "Failed to set Direct Message status of room": "Het is mislukt om de directe-berichtenstatus van de kamer in te stellen", - "Monday": "Maandag", - "All messages (noisy)": "Alle berichten (luid)", - "Enable them now": "Deze nu aanzetten", - "Messages containing my user name": "Berichten die mijn gebruikersnaam bevatten", - "Toolbox": "Eigenschappen", - "Collecting logs": "Logboeken verzamelen", - "more": "meer", - "You must specify an event type!": "Je moet een event-type specificeren!", - "(HTTP status %(httpStatus)s)": "(HTTP-status %(httpStatus)s)", - "Invite to this room": "Uitnodigen voor deze kamer", - "Please install Chrome or Firefox for the best experience.": "Installeer alstublieft Chrome of Firefox voor de beste gebruikerservaring.", - "Failed to get public room list": "Lijst met publieke kamers ophalen mislukt", - "Send logs": "Logboeken versturen", - "All messages": "Alle berichten", - "Call invitation": "Oproep-uitnodiging", - "Downloading update...": "Update aan het downloaden...", - "State Key": "Toestandssleutel", - "Failed to send custom event.": "Aangepast Event verzenden mislukt.", - "What's new?": "Wat is er nieuw?", - "Notify me for anything else": "Stuur een melding voor al het andere", - "When I'm invited to a room": "Wanneer ik uitgenodigd word voor een kamer", - "Can't update user notification settings": "Het is niet gelukt om de meldingsinstellingen van de gebruiker bij te werken", - "Notify for all other messages/rooms": "Stuur een melding voor alle andere berichten/kamers", - "Unable to look up room ID from server": "Het is mislukt om de kamer-ID op te halen van de server", - "Couldn't find a matching Matrix room": "Het is niet gelukt om een bijbehorende Matrix-kamer te vinden", - "All Rooms": "Alle kamers", - "You cannot delete this message. (%(code)s)": "Je kunt dit bericht niet verwijderen. (%(code)s)", - "Thursday": "Donderdag", - "Forward Message": "Bericht doorsturen", - "Back": "Terug", - "Reply": "Beantwoord", - "Show message in desktop notification": "Toon boodschap in bureaublad popup", - "Unhide Preview": "Zichtbaar maken preview", - "Unable to join network": "Het is mislukt om toe te treden tot dit netwerk", - "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Je hebt ze mogelijk ingesteld in een andere client dan Riot. Je kunt ze niet aanpassen in Riot maar ze zijn wel actief", - "Sorry, your browser is not able to run Riot.": "Sorry, uw browser werkt niet met Riot.", - "Uploaded on %(date)s by %(user)s": "Geüpload op %(date)s door %(user)s", - "Messages in group chats": "Berichten in groepsgesprekken", - "Yesterday": "Gisteren", - "Error encountered (%(errorDetail)s).": "Fout ondervonden (%(errorDetail)s).", - "Login": "Aanmelden", - "Low Priority": "Lage prioriteit", - "Unable to fetch notification target list": "Het is mislukt om de lijst van notificatiedoelen op te halen", - "Set Password": "Wachtwoord instellen", - "Enable audible notifications in web client": "Geluidsmeldingen in de webclient aanzetten", - "Permalink": "Permanente link", - "Off": "Uit", - "Riot does not know how to join a room on this network": "Riot weet niet hoe het moet deelnemen in een kamer op dit netwerk", - "Mentions only": "Alleen vermeldingen", - "Wednesday": "Woensdag", - "You can now return to your account after signing out, and sign in on other devices.": "U kunt nu terugkeren naar uw account nadat u bent afgemeld, en u aanmelden op andere apparaten.", - "Enable email notifications": "E-mailmeldingen aanzetten", - "Event Type": "Event-type", - "Download this file": "Download dit bestand", - "Pin Message": "Bericht vastpinnen", - "Failed to change settings": "Instellingen wijzigen mislukt", - "View Community": "Gemeenschap Weergeven", - "%(count)s Members|one": "%(count)s Deelnemer", - "Event sent!": "Event verstuurd!", - "View Source": "Bekijk bron", - "Event Content": "Event-inhoud", - "Thank you!": "Bedankt!", - "Collapse panel": "Paneel inklappen", - "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Met uw huidige browser kan de applicatie er volledig incorrect uitzien. Tevens is het mogelijk dat niet alle functies naar behoren werken. U kunt doorgaan als u het toch wil proberen, maar bij problemen bent u volledig op uzelf aangewezen!", - "Checking for an update...": "Aan het kijken voor een update...", - "There are advanced notifications which are not shown here": "Er zijn geavanceerde notificaties die hier niet getoond worden", - "Logs sent": "Logs verstuurd", - "Click here to create a GitHub issue.": "Klik hier om een Github opgave in te dienen.", - "GitHub issue link:": "GitHub opgave link:", - "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Debug logs bevatten applicatie-gebruik data inclusief je gebruikersnaam, de ID's of namen van de ruimtes en groepen die je hebt bezocht en de gebruikersnamen van andere gebruikers. Ze bevatten geen berichten.", - "Failed to send logs: ": "Het is niet gelukt om de logs te versturen: ", - "Notes:": "Constateringen:", - "Preparing to send logs": "Voorbereiden om logs te versturen" + "Failed to add tag %(tagName)s to room": "Het is niet gelukt om de label %(tagName)s aan deze ruimte toe te voegen" } diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index a68e612155..d732be55da 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -13,6 +13,7 @@ "Banned users": "Заблокированные пользователи", "Bans user with given id": "Блокирует пользователя с заданным ID", "Blacklisted": "В черном списке", + "Bug Report": "Отчет об ошибке", "Bulk Options": "Групповые параметры", "Can't load user settings": "Невозможно загрузить пользовательские настройки", "Changes to who can read history will only apply to future messages in this room": "Изменения того, кто может прочитать историю, будут применяться только к будущим сообщениям в этой комнате", @@ -60,6 +61,7 @@ "Forget room": "Забыть комнату", "Forgot your password?": "Забыли пароль?", "For security, this session has been signed out. Please sign in again.": "Для обеспечения безопасности ваша сессия была завершена. Пожалуйста, войдите снова.", + "Found a bug?": "Нашли ошибку?", "Hangup": "Закончить", "Historical": "Архив", "Homeserver is": "Домашний сервер это", @@ -312,6 +314,7 @@ "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s удалил свое отображаемое имя (%(oldDisplayName)s).", "%(senderName)s removed their profile picture.": "%(senderName)s удалил свое изображение профиля.", "%(senderName)s requested a VoIP conference.": "%(senderName)s хочет начать VoIP-конференцию.", + "Report it": "Сообщить об этом", "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.": "Сброс пароля на данный момент сбрасывает ключи шифрования на всех устройствах, делая зашифрованную историю чатов нечитаемой. Чтобы избежать этого, экспортируйте ключи комнат и импортируйте их после сброса пароля. В будущем это будет исправлено.", "Riot does not have permission to send you notifications - please check your browser settings": "У Riot нет разрешений на отправку уведомлений - проверьте настройки браузера", "Riot was not given permission to send notifications - please try again": "Riot не получил разрешение на отправку уведомлений, пожалуйста, попробуйте снова", @@ -651,6 +654,7 @@ "Do you want to load widget from URL:": "Загрузить виджет из URL-адреса:", "Edit": "Редактировать", "Enable automatic language detection for syntax highlighting": "Включить автоматическое определение языка для подсветки синтаксиса", + "Hide Apps": "Скрыть приложения", "Hide join/leave messages (invites/kicks/bans unaffected)": "Скрыть сообщения о входе/выходе (не применяется к приглашениям/выкидываниям/банам)", "Integrations Error": "Ошибка интеграции", "AM": "AM", @@ -658,6 +662,7 @@ "NOTE: Apps are not end-to-end encrypted": "ПРИМЕЧАНИЕ: приложения не защищены сквозным шифрованием", "Revoke widget access": "Отозвать доступ к виджетам", "Sets the room topic": "Задать тему комнаты", + "Show Apps": "Показать приложения", "The maximum permitted number of widgets have already been added to this room.": "Максимально допустимое количество виджетов уже добавлено в эту комнату.", "To get started, please pick a username!": "Чтобы начать, выберите имя пользователя!", "Unable to create widget.": "Не удалось создать виджет.", @@ -714,6 +719,7 @@ "Description": "Описание", "Name or matrix ID": "Имя или matrix ID", "Unable to accept invite": "Невозможно принять приглашение", + "Unable to leave room": "Невозможно покинуть комнату", "Leave": "Покинуть", "Failed to invite the following users to %(groupId)s:": "Не удалось пригласить следующих пользователей в %(groupId)s:", "Failed to remove '%(roomName)s' from %(groupId)s": "Не удалось удалить '%(roomName)s' из %(groupId)s", @@ -884,6 +890,7 @@ "Visibility in Room List": "Видимость в списке комнат", "Visible to everyone": "Видимый для всех", "Only visible to community members": "Только участникам сообщества", + "Presence Management": "Управление присутствием", "Hide avatar changes": "Скрыть изменения аватара", "Hide display name changes": "Скрыть изменения отображаемого имени", "Enable inline URL previews by default": "Включить просмотр URL-адресов по умолчанию", @@ -917,6 +924,7 @@ "Unknown for %(duration)s": "Неизвестно %(duration)s", "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Здесь никого нет! Хотите пригласить кого-нибудь или выключить предупреждение о пустой комнате?", "Something went wrong when trying to get your communities.": "Что-то пошло не так, во время отображения ваших сообществ.", + "Tag Panel": "Панель тегов", "Delete %(count)s devices|other": "Удалить %(count)s устройств", "Delete %(count)s devices|one": "Удалить устройство", "Select devices": "Выбрать устройства", @@ -950,7 +958,7 @@ "Send a reply (unencrypted)…": "Отправить ответ (незашифрованный)…", "Send an encrypted message…": "Отправить зашифрованное сообщение…", "Send a message (unencrypted)…": "Отправить сообщение (незашифрованное)…", - "Replying": "Отвечает", + "Replying": "Отвечая", "Minimize apps": "Свернуть приложения", "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Конфиденциальность важна для нас, поэтому мы не собираем никаких личных или идентифицируемых данных для нашей аналитики.", "Learn more about how we use analytics.": "Подробнее о том, как мы используем аналитику.", @@ -984,6 +992,7 @@ "%(user)s is a %(userRole)s": "%(user)s является %(userRole)s", "Your key share request has been sent - please check your other devices for key share requests.": "Ваш запрос на передачу ключей отправлен - пожалуйста, проверьте другие ваши устройства на запросы передачи ключей.", "Key share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, click here to request the keys for this session again.": "Запросы передачи ключей автоматически отправляются на другие устройства. Если вы отклонили или отменили запрос на передачу ключей на других устройствах, нажмите здесь, чтобы запросить ключи для этого сеанса повторно.", + "Changes made to your community might not be seen by other users for up to 30 minutes.": "Изменения, сделанные в вашем сообществе, могут не отображаться для других пользователей в течение 30 минут.", "Code": "Код", "Debug Logs Submission": "Отправка журналов отладки", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Если вы отправили ошибку через GitHub, журналы отладки могут помочь нам выявить проблему. Журналы отладки содержат данные об использовании приложения, включая ваше имя пользователя, идентификаторы или псевдонимы комнат или групп, которые вы посетили, а также имена других пользователей. Они не содержат сообщений.", @@ -995,165 +1004,9 @@ "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Изменения имени и аватара, внесенные в ваше сообщество, могут не отображаться другим пользователям в течение 30 минут.", "Join this community": "Присоединиться к сообществу", "Leave this community": "Покинуть это сообщество", + "here": "здесь", + "to add some!": "для добавления!", + "Click": "Нажмите", "Who can join this community?": "Кто может присоединиться к этому сообществу?", - "Everyone": "Все", - "Stickerpack": "Этикетки", - "Sticker Messages": "Сообщения этикеткой", - "Add a stickerpack": "Добавить этикетки", - "Hide Stickers": "Скрыть этикетки", - "Show Stickers": "Показать этикетки", - "Fetching third party location failed": "Не удалось извлечь местоположение третьей стороны", - "A new version of Riot is available.": "Доступна новая версия Riot.", - "I understand the risks and wish to continue": "Я понимаю риски и желаю продолжить", - "Couldn't load home page": "Не удалось загрузить домашнюю страницу", - "Send Account Data": "Отправить данные аккаунта", - "All notifications are currently disabled for all targets.": "Все оповещения для всех устройств отключены.", - "Uploading report": "Отправка отчета", - "Sunday": "Воскресенье", - "Notification targets": "Цели уведомления", - "Today": "Сегодня", - "Files": "Файлы", - "You are not receiving desktop notifications": "Вы не получаете уведомления на рабочем столе", - "Friday": "Пятница", - "Update": "Обновление", - "What's New": "Что нового", - "Add an email address above to configure email notifications": "Добавьте email адрес для оповещений", - "Expand panel": "Развернуть панель", - "On": "Включить", - "%(count)s Members|other": "%(count)s членов", - "Filter room names": "Фильтр по названию комнат", - "Changelog": "История изменений", - "Waiting for response from server": "Ожидание ответа от сервера", - "Uploaded on %(date)s by %(user)s": "Отправлено %(date)s для %(user)s", - "Send Custom Event": "Отправить индивидуальное мероприятие", - "Advanced notification settings": "Дополнительные параметры уведомлений", - "Failed to send logs: ": "Не удалось отправить журналы: ", - "delete the alias.": "удалить псевдоним.", - "To return to your account in future you need to set a password": "Чтобы вернуться к учетной записи в будущем, необходимо задать пароль", - "Forget": "Забыть", - "#example": "#пример", - "Hide panel": "Скрыть панель", - "You cannot delete this image. (%(code)s)": "Это изображение нельзя удалить. (%(code)s)", - "Cancel Sending": "Отменить отправку", - "This Room": "Эта комната", - "The Home Server may be too old to support third party networks": "Домашний сервер может быть слишком старым для поддержки сетей сторонних производителей", - "Noisy": "Со звуком", - "Room not found": "Комната не найдена", - "Messages containing my display name": "Сообщения, содержащие мое имя", - "Messages in one-to-one chats": "Сообщения в индивидуальных чатах", - "Unavailable": "Недоступен", - "Error saving email notification preferences": "Ошибка при сохранении настроек уведомлений по email", - "View Decrypted Source": "Просмотр расшифрованного источника", - "Failed to update keywords": "Не удалось обновить ключевые слова", - "Notes:": "Заметки:", - "remove %(name)s from the directory.": "удалить %(name)s из каталога.", - "Notifications on the following keywords follow rules which can’t be displayed here:": "Уведомления по следующим ключевым словам соответствуют правилам, которые нельзя отобразить здесь:", - "Safari and Opera work too.": "Safari и Opera работают тоже.", - "Please set a password!": "Пожалуйста, установите пароль!", - "You have successfully set a password!": "Вы успешно установили пароль!", - "An error occurred whilst saving your email notification preferences.": "Возникла ошибка при сохранении настроек оповещения по email.", - "Explore Room State": "Просмотр статуса комнаты", - "Source URL": "Исходный URL-адрес", - "Messages sent by bot": "Сообщения, отправленные ботом", - "Filter results": "Фильтрация результатов", - "Members": "Участники", - "No update available.": "Нет доступных обновлений.", - "Resend": "Переотправить", - "Failed to get protocol list from Home Server": "Не удалось получить список протоколов с домашнего сервера", - "Collecting app version information": "Сбор информации о версии приложения", - "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Удалить псевдоним комнаты %(alias)s и удалить %(name)s из каталога?", - "This will allow you to return to your account after signing out, and sign in on other devices.": "Это позволит вам вернуться к учетной записи после выхода из системы и войти на других устройствах.", - "Keywords": "Ключевые слова", - "Enable notifications for this account": "Включить уведомления для этой учетной записи", - "Directory": "Каталог", - "Invite to this community": "Пригласить в это сообщество", - "Search for a room": "Поиск комнаты", - "Messages containing keywords": "Сообщения, содержащие определенные ключевые слова", - "View Source": "Просмотр источника", - "Tuesday": "Вторник", - "Enter keywords separated by a comma:": "Введите ключевые слова, разделенные запятой:", - "Search…": "Поиск.…", - "You have successfully set a password and an email address!": "Вы успешно установили пароль и адрес email!", - "Remove %(name)s from the directory?": "Удалить %(name)s из каталога?", - "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot использует многие передовые возможности браузера, некоторые из которых недоступны или являются экспериментальным в вашем текущем браузере.", - "Developer Tools": "Инструменты разработчика", - "Preparing to send logs": "Подготовка к отправке журналов", - "Enable desktop notifications": "Включить оповещения на рабочем столе", - "Explore Account Data": "Просмотр данных аккаунта", - "All messages (noisy)": "Все сообщения (со звуком)", - "Saturday": "Суббота", - "Remember, you can always set an email address in user settings if you change your mind.": "Помните, что вы всегда сможете задать адрес email в настройках пользователя, если передумаете.", - "Direct Chat": "Прямой чат", - "The server may be unavailable or overloaded": "Сервер, вероятно, недоступен или перегружен", - "Reject": "Отклонить", - "Failed to set Direct Message status of room": "Не удалось установить статус прямого сообщения в комнате", - "Monday": "Понедельник", - "Remove from Directory": "Удалить из каталога", - "Enable them now": "Включить сейчас", - "Messages containing my user name": "Сообщение, содержащие мое имя пользователя", - "Toolbox": "Панель инструментов", - "Collecting logs": "Сбор журналов", - "more": "больше", - "GitHub issue link:": "Ссылка на проблему в GitHub:", - "You must specify an event type!": "Необходимо указать тип мероприятия!", - "(HTTP status %(httpStatus)s)": "(статус HTTP %(httpStatus)s)", - "Invite to this room": "Пригласить в комнату", - "Please install Chrome or Firefox for the best experience.": "Лучший опыт вы получите, установив Chrome или Firefox.", - "Failed to get public room list": "Не удалось получить список общедоступных комнат", - "Send logs": "Отправка журналов", - "All messages": "Все сообщения", - "Call invitation": "Пригласительный звонок", - "Downloading update...": "Загрузка обновления...", - "State Key": "Ключ состояния", - "Failed to send custom event.": "Не удалось отправить индивидуальное мероприятие.", - "What's new?": "Что нового?", - "Notify me for anything else": "Уведомлять во всех остальных случаях", - "When I'm invited to a room": "Когда меня приглашают в комнату", - "Click here to create a GitHub issue.": "Нажмите здесь для создания запроса о проблеме на GitHub.", - "Can't update user notification settings": "Не удается обновить пользовательские настройки оповещения", - "Notify for all other messages/rooms": "Уведомлять обо всех других сообщениях/комнатах", - "Unable to look up room ID from server": "Не удалось найти ID комнаты на сервере", - "Couldn't find a matching Matrix room": "Не удалось найти подходящую комнату Matrix", - "All Rooms": "Все комнаты", - "You cannot delete this message. (%(code)s)": "Это сообщение нельзя удалить. (%(code)s)", - "Thursday": "Четверг", - "Forward Message": "Переслать сообщение", - "Logs sent": "Журналы отправлены", - "Back": "Назад", - "Reply": "Ответить", - "Show message in desktop notification": "Показывать сообщение в уведомлении на рабочем столе", - "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Журналы отладки содержат данные об использовании приложения, включая ваше имя пользователя, идентификаторы или псевдонимы комнат или групп, которые вы посетили, а также имена других пользователей. Они не содержат сообщений.", - "Unhide Preview": "Показать предварительный просмотр", - "Unable to join network": "Не удается подключиться к сети", - "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Возможно вы настроили их не в Riot, а в другом Matrix-клиенте. Настроить их в Riot не удастся, но они будут в нем применяться", - "Sorry, your browser is not able to run Riot.": "К сожалению, ваш браузер не способен запустить Riot.", - "Messages in group chats": "Сообщения в групповых чатах", - "Yesterday": "Вчера", - "Error encountered (%(errorDetail)s).": "Обнаружена ошибка (%(errorDetail)s).", - "Login": "Войти", - "Low Priority": "Низкий приоритет", - "Unable to fetch notification target list": "Не удалось получить список целей уведомления", - "Set Password": "Задать пароль", - "Enable audible notifications in web client": "Включить звуковые уведомления в веб-клиенте", - "Permalink": "Постоянная ссылка", - "Off": "Выключить", - "Riot does not know how to join a room on this network": "Riot не знает, как присоединиться к комнате, принадлежащей к этой сети", - "Mentions only": "Только при упоминаниях", - "Wednesday": "Среда", - "You can now return to your account after signing out, and sign in on other devices.": "Теперь вы сможете вернуться к своей учетной записи после выхода из системы и войти на других устройствах.", - "Enable email notifications": "Включить уведомления по email", - "Event Type": "Тип мероприятия", - "Download this file": "Скачать этот файл", - "Pin Message": "Закрепить сообщение", - "Failed to change settings": "Не удалось изменить настройки", - "View Community": "Просмотр сообщества", - "%(count)s Members|one": "%(count)s член", - "Event sent!": "Мероприятие отправлено!", - "Event Content": "Содержание мероприятия", - "Thank you!": "Спасибо!", - "Quote": "Цитата", - "Collapse panel": "Свернуть панель", - "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "В текущем браузере внешний вид приложения может быть полностью неверным, а некоторые или все функции могут не работать. Если вы хотите попробовать в любом случае, то можете продолжить, но с теми проблемами, с которыми вы можете столкнуться вам придется разбираться самостоятельно!", - "Checking for an update...": "Проверка обновлений...", - "There are advanced notifications which are not shown here": "Существуют дополнительные уведомления, которые не показаны здесь" + "Everyone": "Все" } diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index 537d7d5069..72ba11b6d4 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -263,6 +263,8 @@ "Hangup": "Zavesiť", "Voice call": "Audio hovor", "Video call": "Video hovor", + "Hide Apps": "Skryť aplikácie", + "Show Apps": "Zobraziť aplikácie", "Upload file": "Nahrať súbor", "Show Text Formatting Toolbar": "Zobraziť lištu formátovania textu", "You do not have permission to post to this room": "Nemáte udelené právo posielať do tejto miestnosti", @@ -294,15 +296,15 @@ "Seen by %(userName)s at %(dateTime)s": "%(userName)s videl %(dateTime)s", "Unnamed room": "Nepomenovaná miestnosť", "World readable": "Viditeľné pre každého", - "Guests can join": "Môžu vstúpiť aj hostia", + "Guests can join": "Aj hostia môžu vstúpiť", "No rooms to show": "Žiadne miestnosti na zobrazenie", - "Failed to set avatar.": "Nepodarilo sa nastaviť obrázok.", + "Failed to set avatar.": "Nepodarilo sa nastaviť avatara.", "Save": "Uložiť", "(~%(count)s results)|other": "(~%(count)s výsledkov)", "(~%(count)s results)|one": "(~%(count)s výsledok)", "Join Room": "Vstúpiť do miestnosti", - "Upload avatar": "Nahrať obrázok", - "Remove avatar": "Odstrániť obrázok", + "Upload avatar": "Nahrať avatara", + "Remove avatar": "Odstrániť avatara", "Settings": "Nastavenia", "Forget room": "Zabudnúť miestnosť", "Search": "Hľadať", @@ -339,7 +341,7 @@ "You are trying to access a room.": "Pristupujete k miestnosti.", "Click here to join the discussion!": "Kliknutím sem vstúpite do diskusie!", "This is a preview of this room. Room interactions have been disabled": "Toto je náhľad na miestnosť. Všetky akcie pre túto miestnosť sú zakázané", - "To change the room's avatar, you must be a": "Aby ste mohli meniť obrázok miestnosti, musíte byť", + "To change the room's avatar, you must be a": "Aby ste mohli meniť avatara miestnosti, musíte byť", "To change the room's name, you must be a": "Aby ste mohli meniť názov miestnosti, musíte byť", "To change the room's main address, you must be a": "Aby ste mohli meniť hlavnú adresu miestnosti, musíte byť", "To change the room's history visibility, you must be a": "Aby ste mohli meniť viditeľnosť histórie miestnosti, musíte byť", @@ -426,9 +428,9 @@ "Image '%(Body)s' cannot be displayed.": "Nie je možné zobraziť obrázok '%(Body)s'.", "This image cannot be displayed.": "Tento obrázok nie je možné zobraziť.", "Error decrypting video": "Chyba pri dešifrovaní videa", - "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s zmenil obrázok miestnosti %(roomName)s", - "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s odstránil obrázok miestnosti.", - "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s zmenil obrázok miestnosti ", + "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s zmenil avatara pre %(roomName)s", + "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s z miestnosti odstránil avatara.", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s zmenil avatara miestnosti na ", "Copied!": "Skopírované!", "Failed to copy": "Nepodarilo sa skopírovať", "Add an Integration": "Pridať integráciu", @@ -551,10 +553,10 @@ "%(severalUsers)schanged their name %(count)s times|one": "%(severalUsers)ssi zmenili meno", "%(oneUser)schanged their name %(count)s times|other": "%(oneUser)ssi %(count)s krát zmenil meno", "%(oneUser)schanged their name %(count)s times|one": "%(oneUser)ssi zmenil meno", - "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)ssi %(count)s krát zmenili obrázok v profile", - "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)ssi zmenili obrázok v profile", - "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)ssi %(count)s krát zmenil obrázok v profile", - "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)ssi zmenil obrázok v profile", + "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)ssi %(count)s krát zmenili avatara", + "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)ssi zmenili avatara", + "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)ssi %(count)s krát zmenil avatara", + "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)ssi zmenil avatara", "%(items)s and %(count)s others|other": "%(items)s a %(count)s ďalší", "%(items)s and %(count)s others|one": "%(items)s a jeden ďalší", "%(items)s and %(lastItem)s": "%(items)s a tiež %(lastItem)s", @@ -671,6 +673,7 @@ "Leave Community": "Opustiť komunitu", "Leave %(groupName)s?": "Opustiť komunitu %(groupName)s?", "Leave": "Opustiť", + "Unable to leave room": "Nie je možné opustiť miestnosť", "Community Settings": "Nastavenia komunity", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Tieto miestnosti sú zobrazené všetkým členom na stránke komunity. Členovia komunity môžu vstúpiť do miestnosti kliknutím.", "Add rooms to this community": "Pridať miestnosti do tejto komunity", @@ -770,6 +773,9 @@ "Device ID:": "ID zariadenia:", "Device key:": "Kľúč zariadenia:", "Ignored Users": "Ignorovaní používatelia", + "Bug Report": "Hlásenie chyby", + "Found a bug?": "Našli ste chybu?", + "Report it": "Ohláste ju", "Analytics": "Analytické údaje", "Riot collects anonymous analytics to allow us to improve the application.": "Riot zbiera anonymné analytické údaje, čo nám umožňuje aplikáciu ďalej zlepšovať.", "Labs": "Experimenty", @@ -831,9 +837,9 @@ "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "K domovskému serveru nie je možné pripojiť sa použitím protokolu HTTP keďže v adresnom riadku prehliadača máte HTTPS adresu. Použite protokol HTTPS alebo povolte nezabezpečené skripty.", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Nie je možné pripojiť sa k domovskému serveru - skontrolujte prosím funkčnosť vašeho pripojenia na internet, uistite sa že certifikát domovského servera je dôverihodný, a že žiaden doplnok nainštalovaný v prehliadači nemôže blokovať požiadavky.", "Login as guest": "Prihlásiť sa ako hosť", - "Failed to fetch avatar URL": "Nepodarilo sa získať URL adresu obrázka", + "Failed to fetch avatar URL": "Nepodarilo sa získať URL adresu avatara", "Set a display name:": "Nastaviť zobrazované meno:", - "Upload an avatar:": "Nahrať obrázok:", + "Upload an avatar:": "Nahrať avatara:", "This server does not support authentication with a phone number.": "Tento server nepodporuje overenie telefónnym číslom.", "Missing password.": "Chýba heslo.", "Passwords don't match.": "Heslá sa nezhodujú.", @@ -899,7 +905,8 @@ "Please note you are logging into the %(hs)s server, not matrix.org.": "Všimnite si: Práve sa prihlasujete na server %(hs)s, nie na server matrix.org.", "Username on %(hs)s": "Meno používateľa na servery %(hs)s", "Restricted": "Obmedzené", - "Hide avatar changes": "Skryť zmeny obrázka v profile", + "Presence Management": "Spravovanie prítomnosti", + "Hide avatar changes": "Skryť zmeny avatara", "Hide display name changes": "Skryť zmeny zobrazovaného mena", "Enable inline URL previews by default": "Predvolene povoliť náhľady URL adries", "Enable URL previews for this room (only affects you)": "Povoliť náhľady URL adries pre túto miestnosť (ovplyvňuje len vás)", @@ -916,6 +923,7 @@ "Call": "Hovor", "Answer": "Prijať", "Send": "Odoslať", + "Tag Panel": "Panel so značkami", "Delete %(count)s devices|other": "Vymazať %(count)s zariadení", "Delete %(count)s devices|one": "Vymazať zariadenie", "Select devices": "Vybrať zariadenia", @@ -985,176 +993,14 @@ "Code": "Kód", "Unable to join community": "Nie je možné vstúpiť do komunity", "Unable to leave community": "Nie je možné opustiť komunitu", - "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Zmeny vykonané vo vašej komunite názov a obrázok nemusia byť nasledujúcich 30 minút viditeľné všetkými používateľmi.", + "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Zmeny vykonané vo vašej komunite name and avatar nemusia byť nasledujúcich 30 minút viditeľné všetkými používateľmi.", "Join this community": "Vstúpiť do tejto komunity", "Leave this community": "Opustiť túto komunitu", "Did you know: you can use communities to filter your Riot.im experience!": "Vedeli ste: Že prácu s Riot.im si môžete spríjemníť použitím komunít!", - "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Ak si chcete nastaviť filter, pretiahnite obrázok komunity na panel filtrovania úplne na ľavej strane obrazovky. Potom môžete kedykoľvek kliknúť na obrázok komunity na tomto panely a Riot.im vám bude zobrazovať len miestnosti a ľudí z komunity, na ktorej obrázok ste klikli.", + "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Ak si chcete nastaviť filter, pretiahnite avatara komunity na panel filtrovania úplne na ľavej strane obrazovky. Potom môžete kedykoľvek kliknúť na avatara komunity na tomto panely a Riot.im vám bude zobrazovať len miestnosti a ľudí z komunity, na ktorej avatar ste klikli.", "Clear filter": "Zrušiť filter", "Debug Logs Submission": "Odoslanie ladiacich záznamov", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Ak ste nám poslali hlásenie o chybe cez Github, ladiace záznamy nám môžu pomôcť lepšie identifikovať chybu. Ladiace záznamy obsahujú údaje o používaní aplikácii, vrátane vašeho používateľského mena, názvy a aliasy miestností a komunít, ku ktorým ste sa pripojili a mená ostatných používateľov. Tieto záznamy neobsahujú samotný obsah vašich správ.", "Submit debug logs": "Odoslať ladiace záznamy", - "Opens the Developer Tools dialog": "Otvorí dialóg nástroje pre vývojárov", - "Stickerpack": "Balíček nálepiek", - "Sticker Messages": "Správy s nálepkami", - "You don't currently have any stickerpacks enabled": "Momentálne nemáte aktívne žiadne balíčky s nálepkami", - "Add a stickerpack": "Pridať balíček s nálepkami", - "Hide Stickers": "Skryť nálepky", - "Show Stickers": "Zobraziť nálepky", - "Who can join this community?": "Kto môže vstúpiť do tejto komunity?", - "Everyone": "Ktokoľvek", - "Fetching third party location failed": "Nepodarilo sa získať umiestnenie tretej strany", - "A new version of Riot is available.": "Dostupná je nová verzia Riot.", - "Couldn't load home page": "Nie je možné načítať domovskú stránku", - "Send Account Data": "Odoslať Údaje Účtu", - "All notifications are currently disabled for all targets.": "Momentálne sú zakázané všetky oznámenia pre všetky ciele.", - "Uploading report": "Prebieha odovzdanie hlásenia", - "Sunday": "Nedeľa", - "Notification targets": "Ciele oznámení", - "Today": "Dnes", - "Files": "Súbory", - "You are not receiving desktop notifications": "Nedostávate oznámenia na pracovnej ploche", - "Friday": "Piatok", - "Update": "Aktualizovať", - "Unable to fetch notification target list": "Nie je možné získať zoznam cieľov oznámení", - "Add an email address above to configure email notifications": "Ak si chcete nastaviť oznamovanie emailom, pridajte si emailovú adresu vyššie", - "Expand panel": "Rozbaliť panel", - "On": "Povolené", - "%(count)s Members|other": "%(count)s Členov", - "Filter room names": "Filtrovať názvy miestností", - "Changelog": "Zoznam zmien", - "Waiting for response from server": "Čakanie na odpoveď zo servera", - "Uploaded on %(date)s by %(user)s": "Nahral používateľ %(user)s dňa %(date)s", - "Send Custom Event": "Odoslať vlastnú udalosť", - "Advanced notification settings": "Pokročilé nastavenia oznámení", - "Failed to send logs: ": "Nepodarilo sa odoslať záznamy: ", - "delete the alias.": "vymazať alias.", - "To return to your account in future you need to set a password": "Aby ste sa v budúcnosti mohli vrátiť k vašemu účtu mali by ste si teraz nastaviť heslo", - "Forget": "Zabudnuť", - "Hide panel": "Skryť panel", - "You cannot delete this image. (%(code)s)": "Nemôžete vymazať tento obrázok. (%(code)s)", - "Cancel Sending": "Zrušiť odosielanie", - "This Room": "V tejto miestnosti", - "The Home Server may be too old to support third party networks": "Domovský server môže byť natoľko zastaralý, že nepodporuje siete tretíh strán", - "Resend": "Poslať znovu", - "Room not found": "Miestnosť nenájdená", - "Downloading update...": "Sťahovanie aktualizácie...", - "Messages in one-to-one chats": "Správy v priamych konverzáciách", - "Unavailable": "Nedostupné", - "View Decrypted Source": "Zobraziť dešifrovaný zdroj", - "Failed to update keywords": "Nepodarilo sa aktualizovať kľúčové slová", - "Notes:": "Poznámky:", - "remove %(name)s from the directory.": "odstrániť %(name)s z adresára.", - "Notifications on the following keywords follow rules which can’t be displayed here:": "Oznámenia nasledujúcich kľúčových slov sa riadia pravidlami, ktoré nie je možné zobraziť na tomto mieste:", - "Safari and Opera work too.": "Správne fungujú aj Safari a Opera.", - "Please set a password!": "Prosím, nastavte si heslo!", - "You have successfully set a password!": "Ǔspešne ste si nastavili heslo!", - "Explore Room State": "Preskúmať Stav Miestnosti", - "Source URL": "Pôvodná URL", - "Messages sent by bot": "Správy odosielané robotmi", - "Filter results": "Filtrovať výsledky", - "Members": "Členovia", - "No update available.": "K dispozícii nie je žiadna aktualizácia.", - "Noisy": "Hlučné", - "Failed to get protocol list from Home Server": "Nepodarilo sa získať zoznam protokolov z domovského servera", - "Collecting app version information": "Získavajú sa informácie o verzii aplikácii", - "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Vymazať alias %(alias)s a odstrániť miestnosť %(name)s z adresára?", - "This will allow you to return to your account after signing out, and sign in on other devices.": "Toto vám v budúcnosti umožní vrátiť sa k vašemu účtu aj po odhlásení, alebo tiež prihlásiť sa na iných zariadeniach.", - "Keywords": "Kľúčové slová", - "Enable notifications for this account": "Povoliť oznámenia pre tento účet", - "Directory": "Adresár", - "Invite to this community": "Pozvať do tejto komunity", - "Failed to get public room list": "Nepodarilo sa získať zoznam verejných miestností", - "Search…": "Hľadať…", - "Messages containing keywords": "Správy obsahujúce kľúčové slová", - "Error saving email notification preferences": "Chyba pri ukladaní nastavení oznamovania emailom", - "Tuesday": "Utorok", - "Enter keywords separated by a comma:": "Zadajte kľúčové slová oddelené čiarkou:", - "Forward Message": "Preposlať správu", - "Remove %(name)s from the directory?": "Odstrániť miestnosť %(name)s z adresára?", - "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot sa spolieha na mnohé pokročilé vlastnosti prehliadača internetu, a niektoré z nich sú vo vašom prehliadači experimentálne alebo nie sú k dispozícii vôbec.", - "Event sent!": "Udalosť odoslaná!", - "Preparing to send logs": "príprava odoslania záznamov", - "Enable desktop notifications": "Povoliť oznámenia na pracovnej ploche", - "Explore Account Data": "Preskúmať Údaje účtu", - "All messages (noisy)": "Všetky správy (hlučné)", - "Saturday": "Sobota", - "Remember, you can always set an email address in user settings if you change your mind.": "Všimnite si, Emailovú adresu môžete pridať aj neskôr v časti nastavenia, ak zmeníte svoj názor.", - "Direct Chat": "Priama konverzácia", - "The server may be unavailable or overloaded": "Server môže byť nedostupný alebo preťažený", - "Reject": "Odmietnuť", - "Failed to set Direct Message status of room": "Nepodarilo sa nastaviť stav miestnosti priama konverzácia", - "Monday": "Pondelok", - "Remove from Directory": "Odstrániť z adresára", - "Enable them now": "Povolte si ich teraz", - "Messages containing my user name": "Správy obsahujúce moje používateľské meno", - "Toolbox": "Nástroje", - "Collecting logs": "Získavajú sa záznamy", - "more": "viac", - "GitHub issue link:": "Odkaz hlásenia na Github:", - "Search for a room": "Vyhľadať miestnosť", - "You must specify an event type!": "Musíte nastaviť typ udalosti!", - "(HTTP status %(httpStatus)s)": "(HTTP status %(httpStatus)s)", - "All Rooms": "Vo všetkych miestnostiach", - "State Key": "State Key", - "Please install Chrome or Firefox for the best experience.": "Aby ste s používania mali čo možno najlepší dojem, nainštalujte si Chrome alebo Firefox.", - "Wednesday": "Streda", - "Quote": "Citácia", - "Send logs": "Zahrnúť záznamy", - "All messages": "Všetky správy", - "Call invitation": "Audio / Video hovory", - "Messages containing my display name": "Správy obsahujúce moje zobrazované meno", - "You have successfully set a password and an email address!": "Úspešne si si nastavili heslo aj emailovú adresu!", - "Failed to send custom event.": "Odoslanie vlastnej udalosti zlyhalo.", - "What's new?": "Čo je nové?", - "Notify me for anything else": "Oznamovať mi všetko ostatné", - "When I'm invited to a room": "Pozvania vstúpiť do miestnosti", - "Click here to create a GitHub issue.": "Kliknutím sem nám pošlete hlásenie o chybe cez Github.", - "Can't update user notification settings": "Nie je možné aktualizovať používateľské nastavenia oznamovania", - "Notify for all other messages/rooms": "oznamovať všetky ostatné správy / miestnosti", - "Unable to look up room ID from server": "Nie je možné vyhľadať ID miestnosti na servery", - "Couldn't find a matching Matrix room": "Nie je možné nájsť zodpovedajúcu Matrix miestnosť", - "Invite to this room": "Pozvať do tejto miestnosti", - "You cannot delete this message. (%(code)s)": "Nemôžete vymazať túto správu. (%(code)s)", - "Thursday": "Štvrtok", - "I understand the risks and wish to continue": "Rozumiem rizikám a želám si pokračovať", - "Logs sent": "Záznamy boli odoslané", - "Back": "Naspäť", - "Reply": "Odpovedať", - "Show message in desktop notification": "Zobraziť text správy v oznámení na pracovnej ploche", - "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Ladiace záznamy obsahujú údaje o používaní aplikácii, vrátane vašeho používateľského mena, názvy a aliasy miestností a komunít, ku ktorým ste sa pripojili a mená ostatných používateľov. Tieto záznamy neobsahujú samotný obsah vašich správ.", - "Unhide Preview": "Zobraziť náhľad", - "Unable to join network": "Nie je možné sa pripojiť k sieti", - "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Tieto nastavenia oznámení sa použijú aj napriek tomu, že ich nemôžete meniť cez Riot. Pravdepodobne ste si ich nastavili v inej aplikácii", - "Sorry, your browser is not able to run Riot.": "Prepáčte, vo vašom prehliadači nie je možné spustiť Riot.", - "Messages in group chats": "Správy v skupinových konverzáciách", - "Yesterday": "Včera", - "Error encountered (%(errorDetail)s).": "Vyskytla sa chyba (%(errorDetail)s).", - "Event Type": "Typ Udalosti", - "Low Priority": "Nízka priorita", - "What's New": "Čo Je Nové", - "Set Password": "Nastaviť Heslo", - "An error occurred whilst saving your email notification preferences.": "Počas ukladania vašich nastavení oznamovania emailom sa vyskytla chyba.", - "Enable audible notifications in web client": "Povoliť zvukové oznámenia vo webovom klientovi", - "Permalink": "Trvalý odkaz", - "Off": "Zakázané", - "Riot does not know how to join a room on this network": "Riot nedokáže vstúpiť do miestnosti na tejto sieti", - "Mentions only": "Len zmienky", - "You can now return to your account after signing out, and sign in on other devices.": "Odteraz sa budete k svojmu účtu vedieť vrátiť aj po odhlásení, alebo tiež prihlásiť na iných zariadeniach.", - "Enable email notifications": "Povoliť oznamovanie emailom", - "Login": "Prihlásiť", - "Download this file": "Stiahnuť tento súbor", - "Pin Message": "Pripnúť správu", - "Failed to change settings": "Nepodarilo sa zmeniť nastavenia", - "View Community": "Zobraziť komunitu", - "%(count)s Members|one": "%(count)s Člen", - "Developer Tools": "Vývojárske Nástroje", - "View Source": "Zobraziť zdroj", - "Event Content": "Obsah Udalosti", - "Thank you!": "Ďakujeme!", - "#example": "#príklad", - "Collapse panel": "Zbaliť panel", - "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Vo vašom súčasnom prehliadači nemusí Riot vizerať ani fungovať správne a niektoré alebo všetky vlastnosti môžu chýbať. Ak to chcete vyskúšať, môžete pokračovať, no pri riešení problémov s tým spojených si budete musieť poradiť na vlastnú päsť!", - "Checking for an update...": "Kontrola dostupnosti aktualizácie...", - "There are advanced notifications which are not shown here": "Niektoré pokročilé oznámenia nemôžu byť zobrazené" + "Opens the Developer Tools dialog": "Otvorí dialóg nástroje pre vývojárov" } diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index 3c1a8a1f20..a6d8ab8540 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -172,6 +172,7 @@ "Failed to join room": "Нисам успео да уђем у собу", "Message Replies": "Одговори", "Message Pinning": "Закачене поруке", + "Presence Management": "Управљање присутношћу", "Tag Panel": "Означи површ", "Disable Emoji suggestions while typing": "Онемогући предлагање емоџија приликом куцања", "Use compact timeline layout": "Користи збијени распоред временске линије", @@ -303,6 +304,8 @@ "Hangup": "Спусти слушалицу", "Voice call": "Гласовни позив", "Video call": "Видео позив", + "Hide Apps": "Сакриј апликације", + "Show Apps": "Прикажи апликације", "Upload file": "Отпреми датотеку", "Show Text Formatting Toolbar": "Прикажи алатницу за форматирање текста", "Send an encrypted reply…": "Пошаљи шифровани одговор…", @@ -628,6 +631,7 @@ "expand": "рашири", "Custom of %(powerLevel)s": "Прилагођени ниво %(powerLevel)s", "Custom level": "Прилагођени ниво", + "Quote": "Цитат", "Room directory": "Фасцикла са собама", "Start chat": "Започни ћаскање", "And %(count)s more...|other": "И %(count)s других...", @@ -740,6 +744,7 @@ "Leave Community": "Напусти заједницу", "Leave %(groupName)s?": "Напустити %(groupName)s?", "Leave": "Напусти", + "Unable to leave room": "Не могу да напустим собу", "Community Settings": "Подешавања заједнице", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Ове собе су приказане члановима заједнице на страници заједнице. Чланови заједнице могу приступити собама кликом на њих.", "Add rooms to this community": "Додај собе у ову заједницу", @@ -761,6 +766,8 @@ "Failed to leave room": "Нисам успео да напустим собу", "Signed Out": "Одјављен", "For security, this session has been signed out. Please sign in again.": "Зарад безбедности, одјављени сте из ове сесије. Пријавите се поново.", + "Cryptography data migrated": "Криптографски подаци су пренесени", + "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "Једноструко преношење криптографских података је обављено. Шифровање с краја на крај неће радити ако се вратите на старије издање Riot-а. Ако вам треба шифровање с краја на крај на старијем издању, прво се одјавите из Riot-а. Да бисте задржали историјат порука, извезите па поново увезите ваше кључеве.", "Old cryptography data detected": "Нађени су стари криптографски подаци", "The platform you're on": "Платформа коју користите", "The version of Riot.im": "Riot.im издање", @@ -848,6 +855,9 @@ "Device ID:": "ИБ уређаја:", "Device key:": "Кључ уређаја:", "Ignored Users": "Занемарени корисници", + "Bug Report": "Извештај о грешци", + "Found a bug?": "Нашли сте грешку?", + "Report it": "Пријавите је", "Riot collects anonymous analytics to allow us to improve the application.": "Riot прикупља анонимне податке о коришћењу да бисмо побољшали апликацију.", "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Приватност је веома важна нама те не сакупљамо било какве податке личне природе у нашој аналитици.", "Learn more about how we use analytics.": "Сазнајте више о нашем начину употребе аналитике.", @@ -984,151 +994,5 @@ "Key request sent.": "Захтев за дељење кључа послат.", "Re-request encryption keys from your other devices.": "Поново затражи кључеве за шифровање са осталих ваших уређаја.", "%(user)s is a %(userRole)s": "Корисник %(user)s је у улози %(userRole)s", - "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Да бисте поставили филтер, повуците аватар заједнице на површ филтрирања скроз на леву страну екрана. Можете кликнути на аватар у површи филтрирања било када да бисте видели само собе и особе везане за ту заједницу.", - "Fetching third party location failed": "Добављање локације треће стране није успело", - "A new version of Riot is available.": "Ново издање RIot-а је доступно.", - "Couldn't load home page": "Нисам могао да учитам почетну страну", - "Send Account Data": "Пошаљи податке налога", - "All notifications are currently disabled for all targets.": "Сва обавештења су тренутно онемогућена за све циљеве.", - "Uploading report": "Отпремам извештај", - "Sunday": "Недеља", - "Notification targets": "Циљеви обавештења", - "Today": "Данас", - "Files": "Датотеке", - "You are not receiving desktop notifications": "Не примате стона обавештења", - "Friday": "Петак", - "Update": "Ажурирај", - "Unable to fetch notification target list": "Не могу да досегнем списак циљева за обавештења", - "Add an email address above to configure email notifications": "Додајте мејл адресу изнад да бисте подесили мејл обавештења", - "Expand panel": "Прошири површ", - "On": "Укључено", - "%(count)s Members|other": "%(count)s чланова", - "Filter room names": "Филтрирај називе соба", - "Changelog": "Записник о изменама", - "Waiting for response from server": "Чекам на одговор са сервера", - "Uploaded on %(date)s by %(user)s": "Отпремљено датума %(date)s од корисника %(user)s", - "Send Custom Event": "Пошаљи прилагођени догађај", - "Off": "Искључено", - "Advanced notification settings": "Напредна подешавања обавештења", - "delete the alias.": "обриши алијас.", - "To return to your account in future you need to set a password": "Да бисте се вратили на ваш налог у будућности, морате поставити лозинку", - "Forget": "Заборави", - "Hide panel": "Сакриј површ", - "You cannot delete this image. (%(code)s)": "Не можете обрисати ову слику. (%(code)s)", - "Cancel Sending": "Откажи слање", - "This Room": "Ова соба", - "The Home Server may be too old to support third party networks": "Кућни сервер је можда сувише застарео да би подржао мреже трећих страна", - "Room not found": "Соба није пронађена", - "Downloading update...": "Преузимам ажурирање...", - "Messages in one-to-one chats": "Поруке у један-на-један ћаскањима", - "Unavailable": "Недоступан", - "View Decrypted Source": "Погледај дешифровани извор", - "Failed to update keywords": "Нисам успео да ажурирам кључне речи", - "remove %(name)s from the directory.": "уклони %(name)s из фасцикле.", - "Notifications on the following keywords follow rules which can’t be displayed here:": "Обавештења за следеће кључне речи прате правила која не могу бити приказана овде:", - "Safari and Opera work too.": "Сафари и Опера такође раде.", - "Please set a password!": "Поставите лозинку!", - "You have successfully set a password!": "Успешно сте поставили лозинку!", - "Explore Room State": "Истражи стање собе", - "Source URL": "Адреса извора", - "Messages sent by bot": "Поруке послате од бота", - "Filter results": "Филтрирај резултате", - "Members": "Чланови", - "No update available.": "Нема нових ажурирања.", - "Noisy": "Бучно", - "Failed to get protocol list from Home Server": "Нисам успео да добијем списак протокола од кућног сервера", - "Collecting app version information": "Прикупљам податке о издању апликације", - "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Обрисати алијас собе %(alias)s и уклонити %(name)s из фасцикле?", - "This will allow you to return to your account after signing out, and sign in on other devices.": "Ово ће вам омогућити да се вратите у ваш налог након што се одјавите и пријавите, на другим уређајима.", - "Keywords": "Кључне речи", - "Enable notifications for this account": "Омогући обавештења за овај налог", - "Directory": "Фасцикла", - "Invite to this community": "Позови у ову заједницу", - "Failed to get public room list": "Нисам успео да добавим списак јавних соба", - "Search…": "Претрага…", - "Messages containing keywords": "Поруке које садрже кључне речи", - "Error saving email notification preferences": "Грешка при чувању поставки мејл обавештења", - "Tuesday": "Уторак", - "Enter keywords separated by a comma:": "Унесите кључне речи одвојене зарезима:", - "Forward Message": "Проследи поруку", - "Remove %(name)s from the directory?": "Уклонити %(name)s из фасцикле?", - "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot користи напредне могућности прегледача од којих неке нису доступне или су у пробној фази, у вашем прегледачу.", - "Event sent!": "Догађај је послат!", - "Explore Account Data": "Истражи податке налога", - "All messages (noisy)": "Све поруке (гласно)", - "Saturday": "Субота", - "Remember, you can always set an email address in user settings if you change your mind.": "Запамтите, увек можете поставити мејл адресу у корисничким подешавањима, уколико се предомислите.", - "Direct Chat": "Директно ћаскање", - "The server may be unavailable or overloaded": "Сервер је можда недоступан или преоптерећен", - "Reject": "Одбаци", - "Failed to set Direct Message status of room": "Нисам успео да подесим стање директне поруке собе", - "Monday": "Понедељак", - "Remove from Directory": "Уклони из фасцикле", - "Enable them now": "Омогућите их сада", - "Messages containing my user name": "Поруке које садрже моје корисничко име", - "Toolbox": "Алатница", - "Collecting logs": "Прикупљам записнике", - "more": "више", - "Search for a room": "Потражи собу", - "You must specify an event type!": "Морате навести врсту догађаја!", - "(HTTP status %(httpStatus)s)": "(HTTP стање %(httpStatus)s)", - "All Rooms": "Све собе", - "State Key": "Кључ стања", - "Please install Chrome or Firefox for the best experience.": "Инсталирајте Хром (Chrome) или Фајерфокс (Firefox) за најбољи угођај.", - "Wednesday": "Среда", - "Send logs": "Пошаљи записнике", - "All messages": "Све поруке", - "Call invitation": "Позивница за позив", - "Messages containing my display name": "Поруке које садрже моје приказно име", - "You have successfully set a password and an email address!": "Успешно сте поставили лозинку и мејл адресу!", - "Failed to send custom event.": "Нисам успео да пошаљем прилагођени догађај.", - "What's new?": "Шта је ново?", - "Notify me for anything else": "Обавести ме за било шта друго", - "When I'm invited to a room": "Када сам позван у собу", - "Can't update user notification settings": "Не могу да ажурирам корисничка подешавања обавештења", - "Notify for all other messages/rooms": "Обавести за све друге поруке и собе", - "Unable to look up room ID from server": "Не могу да погледам ИБ собе на серверу", - "Couldn't find a matching Matrix room": "Не могу да нађем одговарајућу Матрикс собу", - "Invite to this room": "Позови у ову собу", - "You cannot delete this message. (%(code)s)": "Не можете обрисати ову поруку. (%(code)s)", - "Thursday": "Четвртак", - "I understand the risks and wish to continue": "Разумем опасност и желим да наставим", - "Back": "Назад", - "Reply": "Одговори", - "Show message in desktop notification": "Прикажи поруку у стоном обавештењу", - "Unhide Preview": "Откриј преглед", - "Unable to join network": "Не могу да приступим мрежи", - "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Можда сте их подесили у неком другом клијенту а не Riot-у. Не можете их преправљати у Riot-у али се и даље примењују", - "Sorry, your browser is not able to run Riot.": "Нажалост, ваш прегледач не може да покреће Riot.", - "Messages in group chats": "Поруке у групним ћаскањима", - "Yesterday": "Јуче", - "Error encountered (%(errorDetail)s).": "Догодила се грешка (%(errorDetail)s).", - "Event Type": "Врста догађаја", - "Low Priority": "Најмања важност", - "What's New": "Шта је ново", - "Set Password": "Постави лозинку", - "An error occurred whilst saving your email notification preferences.": "Догодила се грешка при чувању ваших поставки мејл обавештења.", - "Enable audible notifications in web client": "Омогући звучна обавештења у веб клијенту", - "Permalink": "Трајна веза", - "Resend": "Поново пошаљи", - "Riot does not know how to join a room on this network": "Riot не зна како да приступи соби на овој мрежи", - "Mentions only": "Само спомињања", - "You can now return to your account after signing out, and sign in on other devices.": "Можете се вратити у ваш налог након што се одјавите и пријавите поново, на другим уређајима.", - "Enable desktop notifications": "Омогући стона обавештења", - "Enable email notifications": "Омогући мејл обавештења", - "Login": "Пријава", - "Download this file": "Преузми ову датотеку", - "Pin Message": "Закачи поруку", - "Failed to change settings": "Нисам успео да променим подешавања", - "View Community": "Погледај заједницу", - "%(count)s Members|one": "%(count)s члан", - "Developer Tools": "Програмерске алатке", - "View Source": "Погледај извор", - "Event Content": "Садржај догађаја", - "Thank you!": "Хвала вам!", - "#example": "#пример", - "Collapse panel": "Скупи површ", - "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Са вашим тренутним прегледачем изглед и угођај ове апликације може бити скроз неправилан и неке могућности можда неће радити. Уколико желите да ипак пробате, можете наставити али ћете бити без подршке за било које проблеме на које налетите!", - "Checking for an update...": "Проверавам ажурирања...", - "There are advanced notifications which are not shown here": "Постоје напредна обавештења која нису приказана овде" + "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Да бисте поставили филтер, повуците аватар заједнице на површ филтрирања скроз на леву страну екрана. Можете кликнути на аватар у површи филтрирања било када да бисте видели само собе и особе везане за ту заједницу." } From 5f920f729bf0331818a2eab014c3cf0f003f5a62 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 23 Apr 2018 10:35:02 +0100 Subject: [PATCH 0837/1160] Reset accidental merge changes 2.0 Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/i18n/strings/cs.json | 159 ++++++++++++++++++++++++++-- src/i18n/strings/de_DE.json | 172 ++++++++++++++++++++++++++++-- src/i18n/strings/fr.json | 171 +++++++++++++++++++++++++++--- src/i18n/strings/hu.json | 178 +++++++++++++++++++++++++++---- src/i18n/strings/nl.json | 183 ++++++++++++++++++++++++++++++-- src/i18n/strings/ru.json | 174 +++++++++++++++++++++++++++--- src/i18n/strings/sk.json | 205 +++++++++++++++++++++++++++++++----- src/i18n/strings/sr.json | 157 +++++++++++++++++++++++++-- 8 files changed, 1291 insertions(+), 108 deletions(-) diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index 4267954d4c..d19f17e097 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -90,7 +90,6 @@ "Are you sure you want to upload the following files?": "Určitě chcete nahrát následující soubory?", "Attachment": "Příloha", "Autoplay GIFs and videos": "Automaticky přehrávat GIFy a videa", - "Bug Report": "Hlášení o chybě", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Nelze se připojit k domovskému serveru – zkontrolujte prosím své připojení, prověřte, zdali je SSL certifikát vašeho domovského serveru důvěryhodný, a že některé z rozšíření prohlížeče neblokuje komunikaci.", "Anyone who knows the room's link, apart from guests": "Kdokoliv, kdo má odkaz na místnost, kromě hostů", "Anyone who knows the room's link, including guests": "Kdokoliv, kdo má odkaz na místnost, a to i hosté", @@ -207,7 +206,6 @@ "%(senderName)s answered the call.": "%(senderName)s přijal/a hovor.", "Click to mute audio": "Kliknutím ztlumíte zvuk", "Failed to verify email address: make sure you clicked the link in the email": "E-mailovou adresu se nepodařilo ověřit. Přesvědčte se, že jste kliknul/a na zaslaný odkaz", - "Found a bug?": "Našli jste chybu?", "Guest access is disabled on this Home Server.": "Na tomto domovském serveru je hostům vstup odepřen.", "Guests cannot join this room even if explicitly invited.": "Hosté nemohou vstoupit do této místnosti, i když jsou přímo pozváni.", "Hide read receipts": "Skrýt potvrzení o přečtení", @@ -278,7 +276,6 @@ "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Tuto změnu nepůjde vrátit zpět, protože tomuto uživateli nastavujete stejnou úroveň moci, jakou máte vy.", "Alias (optional)": "Alias (nepovinný)", "Room name (optional)": "Název místnosti (nepovinný)", - "Report it": "Nahlásit to", "Results from DuckDuckGo": "Výsledky z DuckDuckGo", "Return to login screen": "Vrátit k přihlašovací obrazovce", "Riot does not have permission to send you notifications - please check your browser settings": "Riot není oprávněn posílat vám upozornění – zkontrolujte prosím nastavení svého prohlížeče", @@ -306,7 +303,6 @@ "%(senderName)s set a profile picture.": "%(senderName)s si nastavil/a profilový obrázek.", "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s si změnil/a zobrazované jméno na %(displayName)s.", "Sets the room topic": "Nastavuje téma místnosti", - "Show Apps": "Zobrazit aplikace", "Show panel": "Zobrazit panel", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Zobrazovat časové značky v 12hodinovém formátu (např. 2:30 odp.)", "Sign in": "Přihlásit", @@ -530,7 +526,6 @@ "Make Moderator": "Udělit moderátorství", "and %(count)s others...|one": "a někdo další...", "Hangup": "Zavěsit", - "Hide Apps": "Skrýt aplikace", "Show Text Formatting Toolbar": "Zobrazit nástroje formátování textu", "Hide Text Formatting Toolbar": "Skrýt nástroje formátování textu", "Jump to message": "Přeskočit na zprávu", @@ -560,7 +555,6 @@ "Leave Community": "Odejít ze skupiny", "Leave %(groupName)s?": "Odejít z %(groupName)s?", "Leave": "Odejít", - "Unable to leave room": "Nepodařilo se odejít z místnosti", "Hide join/leave messages (invites/kicks/bans unaffected)": "Skrýt zprávy o vstupu či odejití (pozvánky, vykopnutí a vykázání zůstanou)", "Failed to remove user from community": "Nepodařilo se odebrat uživatele ze skupiny", "Failed to remove room from community": "Nepodařilo se odebrat místnost ze skupiny", @@ -649,7 +643,6 @@ "%(senderName)s placed a %(callType)s call.": "%(senderName)s uskutečnil %(callType)s hovor.", "%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s zpřístupnil budoucí historii místnosti neznámým (%(visibility)s).", "Not a valid Riot keyfile": "Neplatný soubor s klíčem Riot", - "Presence Management": "Správce účasti", "Disable Emoji suggestions while typing": "Zakázat návrhy Emoji během psaní", "Hide avatar changes": "Skrýt změny avatara", "Hide display name changes": "Skrýt změny zobrazovaného jména", @@ -948,5 +941,155 @@ "expand": "rozbalit", "Old cryptography data detected": "Nalezeny starší šifrované datové zprávy", "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Nalezeny datové zprávy ze starší verze Riot. Důsledkem bude, že E2E šifrování nebude ve starší verzi Riot správně fungovat. Šifrované zprávy ze starší verze nemusí být čitelné v nové verzi. Může dojít i k selhání zasílaní zpráv s touto verzí Riot. Pokud zaznamenáte některý z uvedených problému, odhlaste se a přihlaste znovu. Pro zachování historie zpráv exportujte a znovu importujte vaše klíče.", - "Warning": "Upozornění" + "Warning": "Upozornění", + "Fetching third party location failed": "Nepodařilo se zjistit umístění třetí strany", + "A new version of Riot is available.": "Je dostupná nová verze Riotu.", + "I understand the risks and wish to continue": "Rozumím rizikům a přeji si pokračovat", + "Couldn't load home page": "Nepodařilo se nahrát úvodní stránku", + "Send Account Data": "Poslat data o účtu", + "Advanced notification settings": "Pokročilé nastavení upozornění", + "Uploading report": "Nahrávám hlášení", + "Sunday": "Neděle", + "Messages sent by bot": "Zprávy poslané robotem", + "Notification targets": "Cíle upozornění", + "Failed to set direct chat tag": "Nepodařilo se nastavit štítek přímého chatu", + "Today": "Dnes", + "Files": "Soubory", + "You are not receiving desktop notifications": "Nedostáváte upozornění na desktopu", + "Friday": "Pátek", + "Update": "Aktualizace", + "What's New": "Co je nového", + "Add an email address above to configure email notifications": "Abyste mohli nastavovat e-mailová upozornění, musíte uvést svoji e-mailovou adresu v kolonce výše", + "Expand panel": "Rozbalit panel", + "On": "Zapnout", + "%(count)s Members|other": "%(count)s Členů", + "Filter room names": "Filtrovat místnosti dle názvu", + "Changelog": "Seznam změn", + "Waiting for response from server": "Čekám na odezvu ze serveru", + "Send Custom Event": "Odeslat vlastní událost", + "All notifications are currently disabled for all targets.": "Veškeré notifikace jsou aktuálně pro všechny cíle vypnuty.", + "delete the alias.": "smazat alias.", + "To return to your account in future you need to set a password": "Abyste se mohli ke svému účtu v budoucnu vrátit, musíte si nastavit heslo", + "Forget": "Zapomenout", + "Hide panel": "Skrýt panel", + "You cannot delete this image. (%(code)s)": "Tento obrázek nemůžete smazat. (%(code)s)", + "Cancel Sending": "Zrušit odesílání", + "This Room": "Tato místnost", + "The Home Server may be too old to support third party networks": "Tento domovský server může být příliš zastaralý na to, aby podporoval sítě třetích stran", + "Noisy": "Hlučný", + "Room not found": "Místnost nenalezena", + "Messages containing my display name": "Zprávy obsahující mé zobrazované jméno", + "Remember, you can always set an email address in user settings if you change your mind.": "Vězte, že kdybyste si to rozmysleli, e-mailovou adresu můžete kdykoliv doplnit v uživatelském nastavení.", + "Unavailable": "Nedostupné", + "Error saving email notification preferences": "Chyba při ukládání nastavení e-mailových upozornění", + "View Decrypted Source": "Zobrazit dešifrovaný zdroj", + "Failed to update keywords": "Nepodařilo se aktualizovat klíčová slova", + "remove %(name)s from the directory.": "odebrat %(name)s z adresáře.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Upozornění na následující klíčová slova se řídí pravidly, která zde nelze zobrazit:", + "Safari and Opera work too.": "Safari a Opera fungují taky.", + "Please set a password!": "Prosím nastavte si heslo!", + "You have successfully set a password!": "Úspěšně jste si nastavili heslo!", + "Explore Room State": "Prohlížet stav místnosti", + "Source URL": "Zdrojová URL", + "Failed to add tag %(tagName)s to room": "Nepodařilo se přidat štítek %(tagName)s k místnosti", + "Filter results": "Filtrovat výsledky", + "Members": "Členové", + "No update available.": "Není dostupná žádná aktualizace.", + "Resend": "Poslat znovu", + "Failed to get protocol list from Home Server": "Z domovského serveru se nepodařilo získat seznam protokolů", + "Collecting app version information": "Sbírání informací o verzi aplikace", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Smazat alias místnosti %(alias)s a odstranit %(name)s z adresáře?", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Toto vám umožní vrátit se po odhlášení ke svému účtu a používat jej na ostatních zařízeních.", + "Keywords": "Klíčová slova", + "Enable notifications for this account": "Zapnout upozornění na tomto účtu", + "Directory": "Adresář", + "Invite to this community": "Pozvat do této komunity", + "Search for a room": "Hledat místnost", + "Messages containing keywords": "Zprávy obsahující klíčová slova", + "View Source": "Zobrazit zdroj", + "Tuesday": "Úterý", + "Enter keywords separated by a comma:": "Vložte klíčová slova oddělená čárkou:", + "Forward Message": "Přeposlat zprávu", + "You have successfully set a password and an email address!": "Úspěšně jste si nastavili heslo a e-mailovou adresu!", + "Remove %(name)s from the directory?": "Odebrat %(name)s z adresáře?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot používá mnoho pokročilých funkcí, z nichž některé jsou ve vašem současném prohlížeči nedostupné nebo experimentální.", + "Developer Tools": "Nástroje pro vývojáře", + "Enable desktop notifications": "Zapnout upozornění na ploše", + "Explore Account Data": "Prozkoumat data o účtu", + "Remove from Directory": "Odebrat z adresáře", + "Saturday": "Sobota", + "Messages in one-to-one chats": "Zprávy v individuálních chatech", + "Direct Chat": "Přímý chat", + "The server may be unavailable or overloaded": "Server může být nedostupný nebo přetížený", + "Reject": "Odmítnout", + "Failed to set Direct Message status of room": "Nepodařilo se přiřadit místnosti status Přímé zprávy", + "Monday": "Pondělí", + "All messages (noisy)": "Všechny zprávy (hlasitě)", + "Enable them now": "Povolit nyní", + "Messages containing my user name": "Zprávy obsahující mé uživatelské jméno", + "Toolbox": "Sada nástrojů", + "Collecting logs": "Sbírání logů", + "more": "více", + "You must specify an event type!": "Musíte určit typ události!", + "(HTTP status %(httpStatus)s)": "(HTTP status %(httpStatus)s)", + "Invite to this room": "Pozvat do této místnosti", + "Please install Chrome or Firefox for the best experience.": "Pro nejlepší zážitek si prosím nainstalujte Chrome nebo Firefox.", + "Failed to get public room list": "Nepodařilo se získat seznam veřejných místností", + "Send logs": "Odeslat záznamy", + "All messages": "Všechny zprávy", + "Call invitation": "Pozvánka k hovoru", + "Downloading update...": "Stahování aktualizace...", + "State Key": "Stavový klíč", + "Failed to send custom event.": "Nepodařilo se odeslat vlastní událost.", + "What's new?": "Co je nového?", + "Notify me for anything else": "Upozorni mě na cokoliv jiného", + "When I'm invited to a room": "Pokud jsem pozván do místnosti", + "Can't update user notification settings": "Nelze aktualizovat uživatelské nastavení upozornění", + "Notify for all other messages/rooms": "Upozorni na všechny ostatní zprávy/místnosti", + "Unable to look up room ID from server": "Nelze získat ID místnosti ze serveru", + "Couldn't find a matching Matrix room": "Odpovídající Matrix místost nenalezena", + "All Rooms": "Všechny místnosti", + "You cannot delete this message. (%(code)s)": "Tuto zprávu nemůžete smazat. (%(code)s)", + "Thursday": "Čtvrtek", + "Search…": "Vyhledat…", + "Back": "Zpět", + "Failed to change settings": "Nepodařilo se změnit nastavení", + "Reply": "Odpovědět", + "Show message in desktop notification": "Zobrazovat zprávu v upozornění na ploše", + "Unhide Preview": "Zobrazit náhled", + "Unable to join network": "Nelze se připojit k síti", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Snad jste je nastavili v jiném klientu než Riot. V Riotu je nemůžete upravit, ale přesto platí", + "Sorry, your browser is not able to run Riot.": "Omlouváme se, váš prohlížeč není schopný spustit Riot.", + "Uploaded on %(date)s by %(user)s": "Nahráno %(date)s uživatelem %(user)s", + "Messages in group chats": "Zprávy ve skupinových chatech", + "Yesterday": "Včera", + "Error encountered (%(errorDetail)s).": "Nastala chyba (%(errorDetail)s).", + "Login": "Přihlásit", + "Low Priority": "Nízká priorita", + "Riot does not know how to join a room on this network": "Riot neví, jak vstoupit do místosti na této síti", + "Set Password": "Nastavit heslo", + "An error occurred whilst saving your email notification preferences.": "Při ukládání nastavení e-mailových upozornění nastala chyba.", + "Enable audible notifications in web client": "Povolit zvuková upozornění ve webové aplikaci", + "Permalink": "Trvalý odkaz", + "Off": "Vypnout", + "#example": "#příklad", + "Mentions only": "Pouze zmínky", + "Failed to remove tag %(tagName)s from room": "Nepodařilo se odstranit štítek %(tagName)s z místnosti", + "Wednesday": "Středa", + "You can now return to your account after signing out, and sign in on other devices.": "Nyní se můžete ke svému účtu vrátit i po odhlášení a používat jej na ostatních zařízeních.", + "Enable email notifications": "Zapnout upozornění přes e-mail", + "Event Type": "Typ události", + "Download this file": "Stáhnout tento soubor", + "Pin Message": "Připíchnout zprávu", + "Thank you!": "Děkujeme vám!", + "View Community": "Zobrazit Komunitu", + "%(count)s Members|one": "%(count)s Člen", + "Event sent!": "Událost odeslána!", + "Event Content": "Obsah události", + "Unable to fetch notification target list": "Nepodařilo se získat seznam cílů upozornění", + "Quote": "Citace", + "Collapse panel": "Sbalit panel", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Vzhled a chování aplikace může být ve vašem aktuální prohlížeči nesprávné a některé nebo všechny funkce mohou být chybné. Chcete-li i přes to pokračovat, nebudeme vám bránit, ale se všemi problémy, na které narazíte, si musíte poradit sami!", + "Checking for an update...": "Kontrola aktualizací...", + "There are advanced notifications which are not shown here": "Jsou k dispozici pokročilá upozornění, která zde nejsou zobrazena" } diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index e67c9fcaaa..2030b4285a 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -51,7 +51,6 @@ "Are you sure you want to reject the invitation?": "Bist du sicher, dass du die Einladung ablehnen willst?", "Are you sure you want to upload the following files?": "Bist du sicher, dass du die folgenden Dateien hochladen möchtest?", "Banned users": "Verbannte Benutzer", - "Bug Report": "Fehlerbericht", "Changes to who can read history will only apply to future messages in this room": "Änderungen, die bestimmen, wer den Chatverlauf lesen kann, gelten nur für zukünftige Nachrichten in diesem Raum", "Clear Cache and Reload": "Cache leeren und neu laden", "Confirm your new password": "Neues Passwort bestätigen", @@ -89,7 +88,6 @@ "Forgot your password?": "Passwort vergessen?", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Aus Sicherheitsgründen werden beim Ausloggen alle Ende-zu-Ende-Verschlüsselungs-Schlüssel in diesem Browser gelöscht. Wenn du in späteren Riot-Sitzungen den bisherigen Chatverlauf entschlüsseln möchtest, exportiere bitte deine Schlüssel zur sicheren Aufbewahrung.", "For security, this session has been signed out. Please sign in again.": "Aus Sicherheitsgründen wurde diese Sitzung beendet. Bitte melde dich erneut an.", - "Found a bug?": "Fehler gefunden?", "Guests cannot join this room even if explicitly invited.": "Gäste können diesem Raum nicht beitreten, auch wenn sie explizit eingeladen wurden.", "Hangup": "Auflegen", "Homeserver is": "Home-Server:", @@ -398,7 +396,6 @@ "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": "Melden", "riot-web version:": "Version von riot-web:", "Scroll to bottom of page": "Zum Seitenende springen", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Zeitstempel im 12-Stunden-Format anzeigen (z. B. 2:30pm)", @@ -653,11 +650,9 @@ "Define the power level of a user": "Setze das Berechtigungslevel eines Benutzers", "Edit": "Editieren", "Enable automatic language detection for syntax highlighting": "Automatische Spracherkennung für die Syntax-Hervorhebung aktivieren", - "Hide Apps": "Apps verbergen", "Hide join/leave messages (invites/kicks/bans unaffected)": "Betreten-/Verlassen-Benachrichtigungen verbergen (gilt nicht für Einladungen/Kicks/Bans)", "Revoke widget access": "Ziehe Widget-Zugriff zurück", "Sets the room topic": "Setzt das Raum-Thema", - "Show Apps": "Apps anzeigen", "To get started, please pick a username!": "Um zu starten, wähle bitte einen Nutzernamen!", "Unable to create widget.": "Widget kann nicht erstellt werden.", "Unbans user with given id": "Verbannung aufheben für Benutzer mit angegebener ID", @@ -692,7 +687,6 @@ "You are no longer ignoring %(userId)s": "%(userId)s wird nicht mehr ignoriert", "Message removed by %(userId)s": "Nachricht wurde von %(userId)s entfernt", "Name or matrix ID": "Name oder Matrix-ID", - "Unable to leave room": "Verlassen des Raumes fehlgeschlagen", "Leave": "Verlassen", "Failed to invite the following users to %(groupId)s:": "Die folgenden Benutzer konnten nicht in die Gruppe %(groupId)s eingeladen werden:", "Leave %(groupName)s?": "%(groupName)s verlassen?", @@ -913,7 +907,6 @@ "URL previews are disabled by default for participants in this room.": "URL-Vorschau ist für Mitglieder dieses Raumes standardmäßig deaktiviert.", "URL previews are enabled by default for participants in this room.": "URL-Vorschau ist für Mitglieder dieses Raumes standardmäßig aktiviert.", "Restricted": "Eingeschränkt", - "Presence Management": "Anwesenheitsmanagement", "Status.im theme": "Status.im-Thema", "%(duration)ss": "%(duration)ss", "%(duration)sm": "%(duration)sm", @@ -992,7 +985,6 @@ "Key request sent.": "Schlüssel-Anfragen gesendet.", "Re-request encryption keys from your other devices.": "Verschlüsselungs-Schlüssel von deinen anderen Geräten erneut anfragen.", "%(user)s is a %(userRole)s": "%(user)s ist ein %(userRole)s", - "Changes made to your community might not be seen by other users for up to 30 minutes.": "Änderungen, die an deiner Community gemacht werden, können bis zu 30 Minuten brauchen, bis sie für andere sichtbar sind.", "Debug Logs Submission": "Einsenden des Fehlerprotokolls", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Wenn du einen Fehler via GitHub gemeldet hast, können Fehlerberichte uns helfen um das Problem zu finden. Sie enthalten Anwendungsdaten wie deinen Nutzernamen, Raum- und Gruppen-ID's und Aliase die du besucht hast und Nutzernamen anderer Nutzer. Sie enthalten keine Nachrichten.", "Submit debug logs": "Fehlerberichte einreichen", @@ -1003,5 +995,167 @@ "Unable to leave community": "Community konnte nicht verlassen werden", "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Änderungen am Namen und Bild deiner Community werden evtl. erst nach 30 Minuten von anderen Nutzern gesehen werden.", "Join this community": "Community beitreten", - "Leave this community": "Community verlassen" + "Leave this community": "Community verlassen", + "Sticker Messages": "Sticker-Nachrichten", + "You don't currently have any stickerpacks enabled": "Du hast aktuell keine Stickerpacks aktiviert", + "Add a stickerpack": "Füge ein Stickerpack hinzu", + "Hide Stickers": "Sticker verbergen", + "Show Stickers": "Sticker zeigen", + "Who can join this community?": "Wer kann dieser Community beitreten?", + "Everyone": "Jeder", + "Stickerpack": "Stickerpack", + "Fetching third party location failed": "Das Abrufen des Drittanbieterstandorts ist fehlgeschlagen", + "A new version of Riot is available.": "Eine neue Version von Riot ist verfügbar.", + "Couldn't load home page": "Startseite konnte nicht geladen werden", + "Send Account Data": "Benutzerkonto-Daten senden", + "All notifications are currently disabled for all targets.": "Aktuell sind alle Benachrichtigungen für alle Ziele deaktiviert.", + "Uploading report": "Lade Bericht hoch", + "Sunday": "Sonntag", + "Notification targets": "Benachrichtigungsziele", + "Today": "Heute", + "Files": "Dateien", + "You are not receiving desktop notifications": "Du erhältst keine Desktop-Benachrichtigungen", + "Friday": "Freitag", + "Update": "Aktualisieren", + "What's New": "Was ist neu", + "Add an email address above to configure email notifications": "Füge oben eine E-Mail-Adresse hinzu, um die E-Mail-Benachrichtigungseinstellungen zu konfigurieren", + "Expand panel": "Panel ausklappen", + "On": "An", + "%(count)s Members|other": "%(count)s Mitglieder", + "Filter room names": "Raum-Namen filtern", + "Changelog": "Änderungsprotokoll", + "Waiting for response from server": "Auf Antwort vom Server warten", + "Send Custom Event": "Benutzerdefiniertes Event senden", + "Advanced notification settings": "Erweiterte Benachrichtigungs-Einstellungen", + "Failed to send logs: ": "Senden von Logs fehlgeschlagen: ", + "delete the alias.": "Lösche den Alias.", + "To return to your account in future you need to set a password": "Um in Zukunft auf dein Benutzerkonto zugreifen zu können, musst du ein Passwort setzen", + "Forget": "Entfernen", + "#example": "#Beispiel", + "Hide panel": "Panel verbergen", + "You cannot delete this image. (%(code)s)": "Das Bild kann nicht gelöscht werden. (%(code)s)", + "Cancel Sending": "Senden abbrechen", + "This Room": "In diesem Raum", + "The Home Server may be too old to support third party networks": "Der Home-Server ist eventuell zu alt, um Drittanbieter-Netzwerke zu unterstützen", + "Resend": "Erneut senden", + "Room not found": "Raum nicht gefunden", + "Messages containing my display name": "Nachrichten, die meinen Anzeigenamen enthalten", + "Messages in one-to-one chats": "Nachrichten in Einzel-Chats", + "Unavailable": "Nicht verfügbar", + "View Decrypted Source": "Entschlüsselten Quellcode ansehen", + "Failed to update keywords": "Schlüsselwörter konnten nicht aktualisiert werden", + "Notes:": "Notizen:", + "remove %(name)s from the directory.": "entferne %(name)s aus dem Verzeichnis.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Die Benachrichtigungen zu den folgenden Schlüsselwörtern folgen Regeln, die hier nicht angezeigt werden können:", + "Safari and Opera work too.": "Safari und Opera sind weitere Alternativen.", + "Please set a password!": "Bitte setze ein Passwort!", + "You have successfully set a password!": "Du hast erfolgreich ein Passwort gesetzt!", + "An error occurred whilst saving your email notification preferences.": "Beim Speichern deiner E-Mail-Benachrichtigungseinstellungen ist ein Fehler aufgetreten.", + "Explore Room State": "Raum-Status erkunden", + "Source URL": "Quell-URL", + "Messages sent by bot": "Nachrichten von Bots", + "Filter results": "Ergebnisse filtern", + "Members": "Mitglieder", + "No update available.": "Kein Update verfügbar.", + "Noisy": "Laut", + "Failed to get protocol list from Home Server": "Fehler beim Abrufen der Protokoll-Liste vom Home-Server", + "Collecting app version information": "App-Versionsinformationen werden abgerufen", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Soll der Raum-Alias %(alias)s gelöscht und der %(name)s aus dem Verzeichnis entfernt werden?", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Dies erlaubt dir, dich wieder an deinem Konto anzumelden, nachdem du dich abgemeldet hast.", + "Keywords": "Schlüsselwörter", + "Enable notifications for this account": "Benachrichtigungen für dieses Benutzerkonto aktivieren", + "Directory": "Raum-Verzeichnis", + "Invite to this community": "In diese Community einladen", + "Failed to get public room list": "Die Liste der öffentlichen Räume konnte nicht geladen werden", + "Messages containing keywords": "Nachrichten, die Schlüsselwörter enthalten", + "Error saving email notification preferences": "Fehler beim Speichern der E-Mail-Benachrichtigungseinstellungen", + "Tuesday": "Dienstag", + "Enter keywords separated by a comma:": "Schlüsselwörter kommagetrennt eingeben:", + "Forward Message": "Nachricht weiterleiten", + "You have successfully set a password and an email address!": "Du hast erfolgreich ein Passwort und eine E-Mail-Adresse gesetzt!", + "Remove %(name)s from the directory?": "Soll der Raum %(name)s aus dem Verzeichnis entfernt werden?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot nutzt zahlreiche fortgeschrittene Browser-Funktionen, die teilweise in deinem aktuell verwendeten Browser noch nicht verfügbar sind oder sich noch im experimentellen Status befinden.", + "Developer Tools": "Entwicklerwerkzeuge", + "Preparing to send logs": "Senden von Logs wird vorbereitet", + "Enable desktop notifications": "Desktop-Benachrichtigungen aktivieren", + "Remember, you can always set an email address in user settings if you change your mind.": "Vergiss nicht, dass du in den Benutzereinstellungen jederzeit eine E-Mail-Adresse setzen kannst, wenn du deine Meinung änderst.", + "Explore Account Data": "Benutzerkonto-Daten analysieren", + "All messages (noisy)": "Alle Nachrichten (laut)", + "Saturday": "Samstag", + "I understand the risks and wish to continue": "Ich verstehe das Risiko und möchte fortfahren", + "Direct Chat": "Direkt-Chat", + "The server may be unavailable or overloaded": "Der Server ist vermutlich nicht erreichbar oder überlastet", + "Reject": "Ablehnen", + "Failed to set Direct Message status of room": "Konnte den direkten Benachrichtigungsstatus nicht setzen", + "Monday": "Montag", + "Remove from Directory": "Aus dem Raum-Verzeichnis entfernen", + "Enable them now": "Aktiviere diese jetzt", + "Messages containing my user name": "Nachrichten, die meinen Benutzernamen enthalten", + "Toolbox": "Werkzeugkasten", + "Collecting logs": "Protokolle werden abgerufen", + "more": "mehr", + "GitHub issue link:": "Link des GitHub-Problems:", + "You must specify an event type!": "Du musst einen Event-Typ spezifizieren!", + "(HTTP status %(httpStatus)s)": "(HTTP-Status %(httpStatus)s)", + "Invite to this room": "In diesen Raum einladen", + "Please install Chrome or Firefox for the best experience.": "Bitte installiere Chrome oder Firefox für ein optimales Anwendungsergebnis.", + "Wednesday": "Mittwoch", + "You cannot delete this message. (%(code)s)": "Diese Nachricht kann nicht gelöscht werden. (%(code)s)", + "Quote": "Zitat", + "Send logs": "Logdateien übermitteln", + "All messages": "Alle Nachrichten", + "Call invitation": "Anruf-Einladung", + "Downloading update...": "Update wird heruntergeladen...", + "State Key": "Status-Schlüssel", + "Failed to send custom event.": "Senden des benutzerdefinierten Events fehlgeschlagen.", + "What's new?": "Was ist neu?", + "Notify me for anything else": "Über alles andere benachrichtigen", + "When I'm invited to a room": "Wenn ich in einen Raum eingeladen werde", + "Click here to create a GitHub issue.": "Klicke hier um ein GithHub-Problem zu erstellen.", + "Can't update user notification settings": "Benachrichtigungs-Einstellungen des Benutzers konnten nicht aktualisiert werden", + "Notify for all other messages/rooms": "Benachrichtigungen für alle anderen Mitteilungen/Räume aktivieren", + "Unable to look up room ID from server": "Es ist nicht möglich, die Raum-ID auf dem Server nachzuschlagen", + "Couldn't find a matching Matrix room": "Konnte keinen entsprechenden Matrix-Raum finden", + "All Rooms": "In allen Räumen", + "Search for a room": "Nach einem Raum suchen", + "Thursday": "Donnerstag", + "Search…": "Suchen…", + "Logs sent": "Logs gesendet", + "Back": "Zurück", + "Reply": "Antworten", + "Show message in desktop notification": "Nachricht in der Desktop-Benachrichtigung anzeigen", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Fehlerberichte enthalten Anwendungsdaten wie deinen Nutzernamen, Raum- und Gruppen-ID's und Aliase die du besucht hast sowie Nutzernamen anderer Nutzer. Sie enthalten keine Nachrichten.", + "Unhide Preview": "Vorschau wieder anzeigen", + "Unable to join network": "Es ist nicht möglich, dem Netzwerk beizutreten", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Du hast sie eventuell auf einem anderen Matrix-Client und nicht in Riot konfiguriert. Sie können in Riot nicht verändert werden, gelten aber trotzdem", + "Sorry, your browser is not able to run Riot.": "Es tut uns leid, aber dein Browser kann Riot nicht ausführen.", + "Messages in group chats": "Nachrichten in Gruppen-Chats", + "Yesterday": "Gestern", + "Error encountered (%(errorDetail)s).": "Es ist ein Fehler aufgetreten (%(errorDetail)s).", + "Login": "Anmeldung", + "Low Priority": "Niedrige Priorität", + "Unable to fetch notification target list": "Liste der Benachrichtigungsempfänger konnte nicht abgerufen werden", + "Set Password": "Passwort einrichten", + "Enable audible notifications in web client": "Audio-Benachrichtigungen im Web-Client aktivieren", + "Permalink": "Permanenter Link", + "Off": "Aus", + "Riot does not know how to join a room on this network": "Riot weiß nicht, wie es einem Raum auf diesem Netzwerk beitreten soll", + "Mentions only": "Nur, wenn du erwähnt wirst", + "You can now return to your account after signing out, and sign in on other devices.": "Du kannst nun zu deinem Benutzerkonto zurückkehren, nachdem du dich abgemeldet hast. Anschließend kannst du dich an anderen Geräten anmelden.", + "Enable email notifications": "E-Mail-Benachrichtigungen aktivieren", + "Event Type": "Event-Typ", + "Download this file": "Datei herunterladen", + "Pin Message": "Nachricht anheften", + "Failed to change settings": "Einstellungen konnten nicht geändert werden", + "View Community": "Community ansehen", + "%(count)s Members|one": "%(count)s Mitglied", + "Event sent!": "Event gesendet!", + "View Source": "Quellcode ansehen", + "Event Content": "Event-Inhalt", + "Thank you!": "Danke!", + "Uploaded on %(date)s by %(user)s": "Hochgeladen: %(date)s von %(user)s", + "Collapse panel": "Panel einklappen", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "In deinem aktuell verwendeten Browser können Aussehen und Handhabung der Anwendung unter Umständen noch komplett fehlerhaft sein, so dass einige bzw. im Extremfall alle Funktionen nicht zur Verfügung stehen. Du kannst es trotzdem versuchen und fortfahren, bist dabei aber bezüglich aller auftretenden Probleme auf dich allein gestellt!", + "Checking for an update...": "Nach Updates suchen...", + "There are advanced notifications which are not shown here": "Es existieren erweiterte Benachrichtigungen, welche hier nicht angezeigt werden" } diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 25cfc6cc82..d9fc51ce28 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -57,7 +57,6 @@ "Banned users": "Utilisateurs bannis", "Bans user with given id": "Bannit l'utilisateur à partir de son identifiant", "Blacklisted": "Sur liste noire", - "Bug Report": "Rapport d'erreur", "Call Timeout": "Délai d’appel expiré", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Impossible de se connecter au serveur d'accueil en HTTP si l'URL dans la barre de votre explorateur est en HTTPS. Utilisez HTTPS ou activez le support des scripts non-vérifiés.", "Can't load user settings": "Impossible de charger les paramètres de l'utilisateur", @@ -93,8 +92,8 @@ "Current password": "Mot de passe actuel", "Curve25519 identity key": "Clé d’identité Curve25519", "/ddg is not a command": "/ddg n'est pas une commande", - "Deactivate Account": "Supprimer le compte", - "Deactivate my account": "Supprimer mon compte", + "Deactivate Account": "Désactiver le compte", + "Deactivate my account": "Désactiver mon compte", "Decrypt %(text)s": "Déchiffrer %(text)s", "Decryption error": "Erreur de déchiffrement", "Delete": "Supprimer", @@ -133,7 +132,6 @@ "Forget room": "Oublier le salon", "Forgot your password?": "Mot de passe oublié ?", "For security, this session has been signed out. Please sign in again.": "Par mesure de sécurité, la session a expiré. Merci de vous authentifier à nouveau.", - "Found a bug?": "Vous avez trouvé un problème ?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s de %(fromPowerLevel)s à %(toPowerLevel)s", "Hangup": "Raccrocher", "Hide read receipts": "Cacher les accusés de lecture", @@ -241,7 +239,6 @@ "%(senderName)s removed their profile picture.": "%(senderName)s a supprimé son image de profil.", "Remove %(threePid)s?": "Supprimer %(threePid)s ?", "%(senderName)s requested a VoIP conference.": "%(senderName)s a demandé une téléconférence audio.", - "Report it": "Le signaler", "Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Pour le moment, réinitialiser le mot de passe va réinitialiser les clés de chiffrement sur tous les appareils, rendant l’historique des salons chiffrés illisible, à moins que vous exportiez d'abord les clés de salon puis que vous les ré-importiez après. Cela sera amélioré prochainement.", "Return to login screen": "Retourner à l’écran de connexion", "Riot does not have permission to send you notifications - please check your browser settings": "Riot n’a pas la permission de vous envoyer des notifications - merci de vérifier les paramètres de votre navigateur", @@ -651,11 +648,9 @@ "Define the power level of a user": "Définir le rang d'un utilisateur", "Edit": "Modifier", "Enable automatic language detection for syntax highlighting": "Activer la détection automatique de la langue pour la correction orthographique", - "Hide Apps": "Masquer les applications", "Hide join/leave messages (invites/kicks/bans unaffected)": "Masquer les messages d'arrivée/départ (n'affecte pas les invitations/exclusions/bannissements)", "Revoke widget access": "Révoquer les accès du widget", "Sets the room topic": "Défini le sujet du salon", - "Show Apps": "Afficher les applications", "To get started, please pick a username!": "Pour commencer, choisissez un nom d'utilisateur !", "Unable to create widget.": "Impossible de créer un widget.", "Unbans user with given id": "Révoque le bannissement de l'utilisateur à partir de son identifiant", @@ -862,7 +857,6 @@ "Leave Community": "Quitter la communauté", "Leave %(groupName)s?": "Quitter %(groupName)s ?", "Leave": "Quitter", - "Unable to leave room": "Impossible de partir du salon", "Community Settings": "Paramètres de la communauté", "Add rooms to this community": "Ajouter des salons à cette communauté", "%(inviter)s has invited you to join this community": "%(inviter)s vous a invité à rejoindre cette communauté", @@ -906,7 +900,6 @@ "Username on %(hs)s": "Nom d'utilisateur sur %(hs)s", "Restricted": "Restreint", "Custom of %(powerLevel)s": "Personnalisé de %(powerLevel)s", - "Presence Management": "Gestion de présence", "Hide avatar changes": "Masquer les changements d'avatar", "Hide display name changes": "Masquer les changements de nom affiché", "Enable inline URL previews by default": "Activer l'aperçu des URL par défaut", @@ -992,7 +985,6 @@ "Key request sent.": "Demande de clé envoyée.", "Re-request encryption keys from your other devices.": "Re-demander les clés de chiffrement depuis vos autres appareils.", "%(user)s is a %(userRole)s": "%(user)s est %(userRole)s", - "Changes made to your community might not be seen by other users for up to 30 minutes.": "Les changements effectués sur votre communauté peuvent ne pas apparaître pour les autres utilisateurs avant 30 minutes.", "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Vu par %(displayName)s (%(userName)s) à %(dateTime)s", "Code": "Code", "Debug Logs Submission": "Envoi des journaux de débogage", @@ -1007,13 +999,162 @@ "Stickerpack": "Pack de stickers", "Sticker Messages": "Messages sticker", "You don't currently have any stickerpacks enabled": "Vous n'avez activé aucun pack de stickers pour l'instant", - "Click": "Cliquer", - "here": "ici", - "to add some!": "pour en ajouter !", "Add a stickerpack": "Ajouter un pack de stickers", "Hide Stickers": "Masquer les stickers", "Show Stickers": "Afficher les stickers", - "Manage sticker packs": "Gérer les packs de stickers", "Who can join this community?": "Qui peut rejoindre cette communauté ?", - "Everyone": "Tout le monde" + "Everyone": "Tout le monde", + "Fetching third party location failed": "Échec de la récupération de la localisation tierce", + "A new version of Riot is available.": "Une nouvelle version de Riot est disponible.", + "Couldn't load home page": "Impossible de charger la page d'accueil", + "Send Account Data": "Envoyer les données du compte", + "All notifications are currently disabled for all targets.": "Toutes les notifications sont désactivées pour tous les appareils.", + "Uploading report": "Envoi du rapport", + "Sunday": "Dimanche", + "Notification targets": "Appareils recevant les notifications", + "Today": "Aujourd'hui", + "Files": "Fichiers", + "You are not receiving desktop notifications": "Vous ne recevez pas les notifications sur votre bureau", + "Friday": "Vendredi", + "Update": "Mettre à jour", + "What's New": "Nouveautés", + "Add an email address above to configure email notifications": "Ajouter une adresse e-mail pour la configuration des notifications par e-mail", + "Expand panel": "Dévoiler le panneau", + "On": "Activé", + "%(count)s Members|other": "%(count)s membres", + "Filter room names": "Filtrer les salons par nom", + "Changelog": "Journal des modifications", + "Waiting for response from server": "En attente d’une réponse du serveur", + "Send Custom Event": "Envoyer l'événement personnalisé", + "Advanced notification settings": "Paramètres de notification avancés", + "delete the alias.": "supprimer l'alias.", + "To return to your account in future you need to set a password": "Pour pouvoir retrouver votre compte dans le futur, vous devez définir un mot de passe", + "Forget": "Oublier", + "#example": "#exemple", + "Hide panel": "Cacher le panneau", + "You cannot delete this image. (%(code)s)": "Vous ne pouvez pas supprimer cette image. (%(code)s)", + "Cancel Sending": "Annuler l'envoi", + "This Room": "Ce salon", + "The Home Server may be too old to support third party networks": "Le serveur d'accueil semble trop ancien pour supporter des réseaux tiers", + "Noisy": "Bruyant", + "Room not found": "Salon non trouvé", + "Messages containing my display name": "Messages contenant mon nom affiché", + "Messages in one-to-one chats": "Messages dans les discussions directes", + "Unavailable": "Indisponible", + "View Decrypted Source": "Voir la source déchiffrée", + "Failed to update keywords": "Échec dans la mise à jour des mots-clés", + "remove %(name)s from the directory.": "supprimer %(name)s du répertoire.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Les notifications pour les mots-clés suivant répondent à des critères qui ne peuvent pas être affichés ici :", + "Safari and Opera work too.": "Safari et Opera fonctionnent également.", + "Please set a password!": "Veuillez définir un mot de passe !", + "You have successfully set a password!": "Vous avez défini un mot de passe avec succès !", + "An error occurred whilst saving your email notification preferences.": "Une erreur est survenue lors de la sauvegarde de vos préférences de notification par e-mail.", + "Explore Room State": "Parcourir l'état du salon", + "Source URL": "URL de la source", + "Messages sent by bot": "Messages envoyés par des robots", + "Filter results": "Filtrer les résultats", + "Members": "Membres", + "No update available.": "Aucune mise à jour disponible.", + "Resend": "Renvoyer", + "Failed to get protocol list from Home Server": "Échec lors de la récupération de la liste sur le serveur", + "Collecting app version information": "Récupération des informations de version de l’application", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Supprimer l'alias %(alias)s du salon et supprimer %(name)s du répertoire ?", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Cela vous permettra de retourner sur votre compte après vous être déconnecté, et de vous identifier sur d'autres appareils.", + "Keywords": "Mots-clés", + "Enable notifications for this account": "Activer les notifications pour ce compte", + "Directory": "Répertoire", + "Invite to this community": "Inviter à cette communauté", + "Failed to get public room list": "Échec lors de la récupération de la liste des salons publics", + "Messages containing keywords": "Messages contenant des mots-clés", + "Error saving email notification preferences": "Erreur lors de la sauvegarde des préférences de notification par e-mail", + "Tuesday": "Mardi", + "Enter keywords separated by a comma:": "Entrez les mots-clés séparés par une virgule :", + "Search…": "Rechercher…", + "You have successfully set a password and an email address!": "Vous avez défini un mot de passe et une adresse e-mail avec succès !", + "Remove %(name)s from the directory?": "Supprimer %(name)s du répertoire ?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot utilise de nombreuses fonctionnalités avancées du navigateur, certaines ne sont pas disponibles ou expérimentales dans votre navigateur actuel.", + "Developer Tools": "Outils de développement", + "Enable desktop notifications": "Activer les notifications de bureau", + "Remember, you can always set an email address in user settings if you change your mind.": "Souvenez-vous que vous pourrez toujours définir une adresse e-mail dans les paramètres de l'utilisateur si vous changez d’avis.", + "Explore Account Data": "Explorer les données du compte", + "Remove from Directory": "Supprimer du répertoire", + "Saturday": "Samedi", + "I understand the risks and wish to continue": "Je comprends les risques et souhaite continuer", + "Direct Chat": "Discussion directe", + "The server may be unavailable or overloaded": "Le serveur est indisponible ou surchargé", + "Reject": "Rejeter", + "Failed to set Direct Message status of room": "Échec du réglage de l'état du salon en Discussion directe", + "Monday": "Lundi", + "All messages (noisy)": "Tous les messages (fort)", + "Enable them now": "Les activer maintenant", + "Messages containing my user name": "Message contenant mon nom d'utilisateur", + "Toolbox": "Boîte à outils", + "Collecting logs": "Récupération des journaux", + "more": "plus", + "You must specify an event type!": "Vous devez spécifier un type d'événement !", + "(HTTP status %(httpStatus)s)": "(état HTTP %(httpStatus)s)", + "Invite to this room": "Inviter dans ce salon", + "Please install Chrome or Firefox for the best experience.": "Veuillez installer Chrome ou Firefox pour une expérience optimale.", + "Wednesday": "Mercredi", + "You cannot delete this message. (%(code)s)": "Vous ne pouvez pas supprimer ce message. (%(code)s)", + "Quote": "Citer", + "Send logs": "Envoyer les journaux", + "All messages": "Tous les messages", + "Call invitation": "Appel entrant", + "Downloading update...": "Mise à jour en cours de téléchargement...", + "State Key": "Clé d'état", + "Failed to send custom event.": "Échec de l'envoi de l'événement personnalisé.", + "What's new?": "Nouveautés ?", + "Notify me for anything else": "Me notifier pour tout le reste", + "View Source": "Voir la source", + "Can't update user notification settings": "Impossible de mettre à jour les paramètres de notification de l'utilisateur", + "Notify for all other messages/rooms": "Me notifier pour tous les autres messages/salons", + "Unable to look up room ID from server": "Impossible de récupérer l'ID du salon sur le serveur", + "Couldn't find a matching Matrix room": "Impossible de trouver un salon Matrix correspondant", + "All Rooms": "Tous les salons", + "Search for a room": "Rechercher un salon", + "Thursday": "Jeudi", + "Forward Message": "Transférer le message", + "Back": "Retour", + "Reply": "Répondre", + "Show message in desktop notification": "Afficher le message dans les notifications de bureau", + "Unhide Preview": "Dévoiler l'aperçu", + "Unable to join network": "Impossible de rejoindre le réseau", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Vous les avez probablement configurées dans un autre client que Riot. Vous ne pouvez pas les configurer dans Riot mais elles s'appliquent quand même", + "Sorry, your browser is not able to run Riot.": "Désolé, Riot n'est pas supporté par votre navigateur.", + "Uploaded on %(date)s by %(user)s": "Téléchargé le %(date)s par %(user)s", + "Messages in group chats": "Messages dans les discussions de groupe", + "Yesterday": "Hier", + "Error encountered (%(errorDetail)s).": "Erreur rencontrée (%(errorDetail)s).", + "Login": "Connexion", + "Low Priority": "Priorité basse", + "Unable to fetch notification target list": "Impossible de récupérer la liste des appareils recevant les notifications", + "Set Password": "Définir un mot de passe", + "Enable audible notifications in web client": "Activer les notifications sonores pour le client web", + "Permalink": "Permalien", + "Off": "Désactivé", + "Riot does not know how to join a room on this network": "Riot ne peut pas joindre un salon sur ce réseau", + "Mentions only": "Seulement les mentions", + "You can now return to your account after signing out, and sign in on other devices.": "Vous pouvez maintenant revenir sur votre compte après vous être déconnecté, et vous identifier sur d'autres appareils.", + "Enable email notifications": "Activer les notifications par e-mail", + "Event Type": "Type d'événement", + "Download this file": "Télécharger ce fichier", + "Pin Message": "Épingler le message", + "Failed to change settings": "Échec de la mise à jour des paramètres", + "View Community": "Voir la communauté", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Depuis votre navigateur actuel, le visuel et le ressenti de l'application pourraient être complètement erronés, et certaines fonctionnalités pourraient ne pas être supportées. Vous pouvez continuer malgré tout, mais vous n'aurez aucune aide si vous rencontrez des problèmes !", + "%(count)s Members|one": "%(count)s membre", + "Event sent!": "Événement envoyé !", + "Event Content": "Contenu de l'événement", + "Thank you!": "Merci !", + "Collapse panel": "Cacher le panneau", + "When I'm invited to a room": "Quand je suis invité dans un salon", + "Checking for an update...": "Recherche de mise à jour...", + "There are advanced notifications which are not shown here": "Il existe une configuration avancée des notifications qui ne peut être affichée ici", + "Logs sent": "Rapports envoyés", + "GitHub issue link:": "Lien du signalement GitHub :", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Les rapports de débogage contiennent des données d'usage de l'application qui incluent votre nom d'utilisateur, les identifiants ou alias des salons ou groupes auxquels vous avez rendu visite ainsi que les noms des autres utilisateurs. Ils ne contiennent aucun message.", + "Failed to send logs: ": "Échec lors de l'envoi des rapports : ", + "Notes:": "Notes :", + "Preparing to send logs": "Préparation d'envoi des rapports" } diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index b7f20d52f7..5fe1e90163 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -10,7 +10,7 @@ "Mute": "Elnémít", "Notifications": "Értesítések", "Operation failed": "Sikertelen művelet", - "powered by Matrix": "A Matrix hajtja", + "powered by Matrix": "Matrix hajtja", "Remove": "Eltávolítás", "Settings": "Beállítások", "unknown error code": "ismeretlen hibakód", @@ -69,7 +69,6 @@ "Banned users": "Kitiltott felhasználók", "Bans user with given id": "Kitiltja a felhasználót a megadott ID-vel", "Blacklisted": "Fekete listára téve", - "Bug Report": "Hiba jelentés", "Bulk Options": "Tömeges beállítások", "Call Timeout": "Hívás időtúllépés", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Nem lehet kapcsolódni a saját szerverhez - ellenőrizd a kapcsolatot, biztosítsd, hogy a saját szerver tanúsítványa hiteles legyen, és a böngésző kiterjesztések ne blokkolják a kéréseket.", @@ -192,7 +191,6 @@ "Forgot your password?": "Elfelejtetted a jelszavad?", "For security, this session has been signed out. Please sign in again.": "A biztonság érdekében ez a kapcsolat le lesz bontva. Légy szíves jelentkezz be újra.", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "A biztonság érdekében a kilépéskor a ponttól pontig való (E2E) titkosításhoz szükséges kulcsok törlésre kerülnek a böngészőből. Ha a régi üzeneteket továbbra is el szeretnéd olvasni, kérlek mentsed ki a szobákhoz tartozó kulcsot.", - "Found a bug?": "Hibát találtál?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s : %(fromPowerLevel)s -> %(toPowerLevel)s", "Guest access is disabled on this Home Server.": "Vendég belépés tiltva van a Saját szerveren.", "Guests cannot join this room even if explicitly invited.": "Vendégek akkor sem csatlakozhatnak ehhez a szobához ha külön meghívók kaptak.", @@ -309,7 +307,6 @@ "%(senderName)s removed their profile picture.": "%(senderName)s törölte a profil képét.", "Remove %(threePid)s?": "Töröl: %(threePid)s?", "%(senderName)s requested a VoIP conference.": "%(senderName)s VoIP konferenciát kezdeményez.", - "Report it": "Jelent", "Results from DuckDuckGo": "Eredmények a DuckDuckGo-ból", "Return to login screen": "Vissza a bejelentkezési képernyőre", "Riot does not have permission to send you notifications - please check your browser settings": "Riotnak nincs jogosultsága értesítést küldeni neked - ellenőrizd a böngésző beállításait", @@ -652,13 +649,11 @@ "Define the power level of a user": "A felhasználó szintjének meghatározása", "Edit": "Szerkeszt", "Enable automatic language detection for syntax highlighting": "Nyelv automatikus felismerése szintaxis kiemeléshez", - "Hide Apps": "Alkalmazások elrejtése", "Hide join/leave messages (invites/kicks/bans unaffected)": "Belép/kilép üzenetek elrejtése (meghívók, kirúgások, kitiltások nem érintettek)", "AM": "de", "PM": "du", "Revoke widget access": "Kisalkalmazás hozzáférésének visszavonása", "Sets the room topic": "Szoba téma beállítás", - "Show Apps": "Alkalmazások mutatása", "To get started, please pick a username!": "Az induláshoz válassz egy felhasználói nevet!", "Unable to create widget.": "Nem lehet kisalkalmazást létrehozni.", "Unbans user with given id": "Visszaengedi a megadott azonosítójú felhasználót", @@ -702,7 +697,7 @@ "Disable Emoji suggestions while typing": "Emoji ajánlások kikapcsolása gépelés közben", "Banned by %(displayName)s": "Kitiltotta: %(displayName)s", "Message removed by %(userId)s": "Üzenetet törölte: %(userId)s", - "To send messages, you must be a": "Ahhoz, hogy üzenetet tudj küldeni, neked ilyen szinten kell lenned:", + "To send messages, you must be a": "Ahhoz, hogy üzenetet tudj küldeni, ilyen szinten kell lenned:", "To invite users into the room, you must be a": "Hogy meghívj valakit a szobába, ilyen szinten kell lenned:", "To configure the room, you must be a": "A szoba beállításához ilyen szinten kell lenned:", "To kick users, you must be a": "Felhasználó kirúgásához ilyen szinten kell lenned:", @@ -712,14 +707,13 @@ "To change the room's avatar, you must be a": "A szoba avatarjának a megváltoztatásához ilyen szinten kell lenned:", "To change the room's name, you must be a": "A szoba nevének megváltoztatásához ilyen szinten kell lenned:", "To change the room's main address, you must be a": "A szoba elsődleges címének a megváltoztatásához ilyen szinten kell lenned:", - "To change the room's history visibility, you must be a": "A szoba naplója elérhetőségének a megváltoztatásához ilyen szinten kell lenned:", + "To change the room's history visibility, you must be a": "A szoba napló elérhetőségének a megváltoztatásához ilyen szinten kell lenned:", "To change the permissions in the room, you must be a": "A szobában a jogosultság megváltoztatásához ilyen szinten kell lenned:", "To change the topic, you must be a": "A téma megváltoztatásához ilyen szinten kell lenned:", "To modify widgets in the room, you must be a": "A szoba kisalkalmazásainak megváltoztatásához ilyen szinten kell lenned:", "Description": "Leírás", "Name or matrix ID": "Név vagy Matrix azonosító", "Unable to accept invite": "A meghívót nem lehet elfogadni", - "Unable to leave room": "A szobát nem lehet elhagyni", "Leave": "Elhagy", "Failed to invite the following users to %(groupId)s:": "Az alábbi felhasználókat nem sikerült meghívni a(z) %(groupId)s:", "Failed to invite users to %(groupId)s": "Nem sikerült meghívni a felhasználókat ebbe a csoportba: %(groupId)s", @@ -736,7 +730,7 @@ "Failed to remove the room from the summary of %(groupId)s": "Az alábbi szobákat nem sikerült eltávolítani a(z) %(groupId)s csoport összefoglalójából", "The room '%(roomName)s' could not be removed from the summary.": "Nem sikerült törölni az összefoglalóból ezt a szobát: '%(roomName)s'.", "Failed to remove a user from the summary of %(groupId)s": "Nem sikerült törölni az összefoglalóból ezt a felhasználót: %(groupId)s", - "The user '%(displayName)s' could not be removed from the summary.": "Nem sikerült törölni az összefoglalóból ezt a felhasználót: %(groupId)s.", + "The user '%(displayName)s' could not be removed from the summary.": "Nem sikerült törölni az összefoglalóból a(z) %(displayName)s felhasználót", "Light theme": "Világos téma", "Dark theme": "Sötét téma", "Unknown": "Ismeretlen", @@ -906,7 +900,6 @@ "Username on %(hs)s": "Felhasználónév a %(hs)s szerveren", "Restricted": "Korlátozott", "Custom of %(powerLevel)s": "Egyedi beállítás: %(powerLevel)s", - "Presence Management": "Jelenlét menedzsment", "Hide avatar changes": "Avatar változások elrejtése", "Hide display name changes": "Név változások elrejtése", "Enable inline URL previews by default": "Beágyazott URL előnézetek alapértelmezett engedélyezése", @@ -984,7 +977,7 @@ "Failed to add tag %(tagName)s to room": "Nem sikerült hozzáadni a szobához ezt: %(tagName)s", "Clear filter": "Szűrő törlése", "Disable Community Filter Panel": "Közösség keresési panel tiltása", - "Did you know: you can use communities to filter your Riot.im experience!": "Tudtad, hogy a közösségeket használhatod a Riot.im élmény fokozásához?", + "Did you know: you can use communities to filter your Riot.im experience!": "Tudtad, hogy a Riot.im élmény fokozásához használhatsz közösségeket?", "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "A szűrő beállításához húzd a közösség avatarját a szűrő panel fölé a képernyő bal szélén. A szűrő panelen az avatarra kattintva bármikor leszűrheted azokat a szobákat és embereket akik a megadott közösséghez tartoznak.", "Your key share request has been sent - please check your other devices for key share requests.": "A kulcs megosztási kérést elküldtük - ellenőrizd a többi eszközödön a kulcs megosztási kéréseket.", "Key share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, click here to request the keys for this session again.": "A kulcs megosztási kérelem automatikusan el lett küldve a többi eszközödre. Ha elutasítottad vagy törölted a kérést a másik eszközön ide kattintva újra kérheted a kulcsokat.", @@ -992,7 +985,6 @@ "Key request sent.": "Kulcs kérés elküldve.", "Re-request encryption keys from your other devices.": "Kulcsok újrakérése a többi eszközödtől.", "%(user)s is a %(userRole)s": "%(user)s egy %(userRole)s", - "Changes made to your community might not be seen by other users for up to 30 minutes.": "A közösségedben végrehajtott változtatás valószínűleg legalább 30 percig nem lesz látható mások számára.", "Code": "Kód", "Debug Logs Submission": "Hibakeresési napló elküldése", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Ha a GitHubon keresztül küldted be a hibát, a hibakeresési napló segíthet nekünk a javításban. A napló felhasználási adatokat tartalmaz mint a felhasználói neved, az általad meglátogatott szobák vagy csoportok azonosítóját vagy alternatív nevét és mások felhasználói nevét. De nem tartalmazzák az üzeneteket.", @@ -1007,13 +999,163 @@ "Stickerpack": "Matrica csomag", "Sticker Messages": "Matrica üzenetek", "You don't currently have any stickerpacks enabled": "Nincs engedélyezett matrica csomagod", - "Click": "Kattints", - "here": "ide", - "to add some!": "hogy adj hozzá párat!", "Add a stickerpack": "Matrica csomag hozzáadása", "Hide Stickers": "Matricák elrejtése", "Show Stickers": "Matricák megjelenítése", - "Manage sticker packs": "Matrica csomagok kezelése", "Who can join this community?": "Ki tud csatlakozni ehhez a közösséghez?", - "Everyone": "Mindenki" + "Everyone": "Mindenki", + "Fetching third party location failed": "Nem sikerült lekérdezni a harmadik fél helyét", + "A new version of Riot is available.": "Elérhető egy új Riot verzió.", + "Couldn't load home page": "Nem sikerült betölteni a kezdőlapot", + "Send Account Data": "Fiókadatok küldése", + "All notifications are currently disabled for all targets.": "Minden céleszközön minden értesítés tiltva van.", + "Uploading report": "Jelentés feltöltése", + "Sunday": "Vasárnap", + "Notification targets": "Értesítések célpontja", + "Today": "Ma", + "Files": "Fájlok", + "You are not receiving desktop notifications": "Nem fogadsz asztali értesítéseket", + "Friday": "Péntek", + "Update": "Frissítés", + "What's New": "Újdonságok", + "Add an email address above to configure email notifications": "E-mail értesítések beállításához adj meg egy e-mail címet", + "Expand panel": "Panel kinyitása", + "On": "Be", + "%(count)s Members|other": "%(count)s tag", + "Filter room names": "Szobanevek szűrése", + "Changelog": "Változások", + "Waiting for response from server": "Várakozás a szerver válaszára", + "Send Custom Event": "Egyéni esemény elküldése", + "Advanced notification settings": "Haladó értesítési beállítások", + "Failed to send logs: ": "Hiba a napló küldésénél: ", + "delete the alias.": "becenév törlése.", + "To return to your account in future you need to set a password": "Hogy később visszaléphess a fiókodba, be kell állítanod egy jelszót", + "Forget": "Elfelejt", + "#example": "#példa", + "Hide panel": "Panel elrejtése", + "You cannot delete this image. (%(code)s)": "Nem törölheted ezt a képet. (%(code)s)", + "Cancel Sending": "Küldés megszakítása", + "This Room": "Ebben a szobában", + "The Home Server may be too old to support third party networks": "Lehet, hogy a saját szerver túl régi és nem támogatja a csatlakozást más hálózatokhoz", + "Resend": "Küldés újra", + "Room not found": "A szoba nem található", + "Messages containing my display name": "A profilnevemet tartalmazó üzenetek", + "Messages in one-to-one chats": "Személyes beszélgetések üzenetei", + "Unavailable": "Elérhetetlen", + "View Decrypted Source": "Visszafejtett forrás megjelenítése", + "Failed to update keywords": "Nem lehet frissíteni a kulcsszavakat", + "Notes:": "Jegyzetek:", + "remove %(name)s from the directory.": "%(name)s szoba törlése a listából.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Az alábbi kulcsszavakról jövő értesítések szabályait nem lehet itt megjeleníteni:", + "Safari and Opera work too.": "Safarival és Operával is működik.", + "Please set a password!": "Állíts be egy jelszót!", + "You have successfully set a password!": "Sikerült beállítani a jelszót!", + "An error occurred whilst saving your email notification preferences.": "Hiba történt az e-mail értesítési beállításaid mentése közben.", + "Explore Room State": "Szoba állapot felderítése", + "Source URL": "Forrás URL", + "Messages sent by bot": "Botok üzenetei", + "Filter results": "Találatok szűrése", + "Members": "Résztvevők", + "No update available.": "Nincs elérhető frissítés.", + "Noisy": "Hangos", + "Failed to get protocol list from Home Server": "Nem sikerült a protokoll listát lekérni a saját szerverről", + "Collecting app version information": "Alkalmazás verzió információk összegyűjtése", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Törlöd a szoba nevét (%(alias)s) és eltávolítod a listából ezt: %(name)s?", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Így kijelentkezés után is vissza tudsz lépni a fiókodba, illetve más készülékekről is be tudsz lépni.", + "Keywords": "Kulcsszavak", + "Enable notifications for this account": "Értesítések engedélyezése ehhez a fiókhoz", + "Directory": "Könyvtár", + "Invite to this community": "Meghívás ebbe a közösségbe", + "Search for a room": "Szoba keresése", + "Messages containing keywords": "Kulcsszavakat tartalmazó üzenetek", + "Error saving email notification preferences": "Hiba az e-mail értesítési beállítások mentésekor", + "Tuesday": "Kedd", + "Enter keywords separated by a comma:": "Kulcsszavak vesszővel elválasztva:", + "Forward Message": "Üzenet továbbítása", + "You have successfully set a password and an email address!": "Sikerült beállítani a jelszavad és e-mail címed!", + "Remove %(name)s from the directory?": "Törlöd ezt a szobát a listából: %(name)s?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "A Riot sok fejlett böngészőfunkciót használ, amelyeknek egy része egyáltalán nem, vagy csak kísérleti jelleggel érhető el a jelenlegi böngésződben.", + "Developer Tools": "Fejlesztői eszközök", + "Preparing to send logs": "Előkészülés napló küldéshez", + "Enable desktop notifications": "Asztali értesítések engedélyezése", + "Remember, you can always set an email address in user settings if you change your mind.": "Ha meggondolod magad, bármikor beállíthatod az e-mail címed a felhasználói beállításoknál.", + "Explore Account Data": "Fiókadatok felderítése", + "Remove from Directory": "Törlés a listából", + "Saturday": "Szombat", + "I understand the risks and wish to continue": "Megértettem a kockázatot és folytatom", + "Direct Chat": "Közvetlen csevegés", + "The server may be unavailable or overloaded": "A szerver nem elérhető vagy túlterhelt", + "Reject": "Elutasít", + "Failed to set Direct Message status of room": "Nem lehet beállítani a szoba közvetlen beszélgetés státuszát", + "Monday": "Hétfő", + "All messages (noisy)": "Minden üzenet (hangos)", + "Enable them now": "Engedélyezés most", + "Messages containing my user name": "A felhasználónevemet tartalmazó üzenetek", + "Toolbox": "Eszköztár", + "Collecting logs": "Naplók összegyűjtése", + "more": "tovább", + "GitHub issue link:": "GitHub hibajegy hivatkozás:", + "You must specify an event type!": "Meg kell jelölnöd az eseménytípust!", + "(HTTP status %(httpStatus)s)": "(HTTP állapot: %(httpStatus)s)", + "Invite to this room": "Meghívás a szobába", + "Please install Chrome or Firefox for the best experience.": "A legjobb élmény érdekében telepíts Chrome vagy Firefox böngészőt.", + "Failed to get public room list": "Nem sikerült lekérdezni a nyilvános szobák listáját", + "Quote": "Idéz", + "Send logs": "Naplófájlok elküldése", + "All messages": "Minden üzenet", + "Call invitation": "Hívás meghívó", + "Downloading update...": "Frissítés letöltése...", + "State Key": "Állapotkulcs", + "Failed to send custom event.": "Nem sikerült elküldeni az egyéni eseményt.", + "What's new?": "Mik az újdonságok?", + "Notify me for anything else": "Értesíts minden egyéb esetben", + "When I'm invited to a room": "Amikor meghívnak egy szobába", + "Click here to create a GitHub issue.": "Kattints ide GitHub hibajegy nyitásához .", + "Can't update user notification settings": "Nem lehet frissíteni az értesítési beállításokat", + "Notify for all other messages/rooms": "Értesítés minden más üzenethez/szobához", + "Unable to look up room ID from server": "Nem lehet a szoba azonosítóját megkeresni a szerveren", + "Couldn't find a matching Matrix room": "Nem található a keresett Matrix szoba", + "All Rooms": "Minden szobában", + "You cannot delete this message. (%(code)s)": "Nem törölheted ezt az üzenetet. (%(code)s)", + "Thursday": "Csütörtök", + "Search…": "Keresés…", + "Logs sent": "Napló elküldve", + "Back": "Vissza", + "Reply": "Válasz", + "Show message in desktop notification": "Üzenetek megjelenítése az asztali értesítéseknél", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "A hibakereső napló alkalmazás használati adatokat tartalmaz beleértve a felhasználói nevedet, az általad meglátogatott szobák és csoportok azonosítóit alternatív neveit és más felhasználói neveket. Csevegés üzenetek szövegét nem tartalmazza.", + "Unhide Preview": "Előnézet mutatása", + "Unable to join network": "Nem sikerült kapcsolódni a hálózathoz", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Egy másik, nem Riot-klienssel állítothattad be. A Riotban módosítani nem tudod ezeket, de érvényben vannak", + "Sorry, your browser is not able to run Riot.": "Elnézést, a böngésződben nem fut a Riot.", + "Uploaded on %(date)s by %(user)s": "Feltöltötte %(user)s ekkor: %(date)s", + "Messages in group chats": "Csoportszobák üzenetei", + "Yesterday": "Tegnap", + "Error encountered (%(errorDetail)s).": "Hiba történt (%(errorDetail)s).", + "Login": "Bejelentkezés", + "Low Priority": "Alacsony prioritás", + "Unable to fetch notification target list": "Nem sikerült letölteni az értesítési célok listáját", + "Set Password": "Jelszó beállítása", + "Enable audible notifications in web client": "Hangértesítések engedélyezése a webkliensben", + "Permalink": "Állandó hivatkozás", + "Off": "Ki", + "Riot does not know how to join a room on this network": "A Riot nem tud csatlakozni szobához ezen a hálózaton", + "Mentions only": "Csak ha megemlítenek", + "Wednesday": "Szerda", + "You can now return to your account after signing out, and sign in on other devices.": "Most már kijelentkezés után is vissza tudsz lépni a fiókodba, és más készülékekről is be tudsz lépni.", + "Enable email notifications": "E-mail értesítések engedélyezése", + "Event Type": "Esemény típusa", + "Download this file": "Fájl letöltése", + "Pin Message": "Üzenet rögzítése", + "Failed to change settings": "A beállítások megváltoztatása nem sikerült", + "View Community": "Közösség megtekintése", + "%(count)s Members|one": "%(count)s tag", + "Event sent!": "Az esemény elküldve!", + "View Source": "Forrás megjelenítése", + "Event Content": "Esemény tartalma", + "Thank you!": "Köszönjük!", + "Collapse panel": "Panel becsukása", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Ebben a böngészőben az alkalmazás felülete tele lehet hibával, és az is lehet, hogy egyáltalán nem működik. Ha így is ki szeretnéd próbálni, megteheted, de ha valami gondod van, nem tudunk segíteni!", + "Checking for an update...": "Frissítés keresése...", + "There are advanced notifications which are not shown here": "Vannak itt nem látható, haladó értesítések" } diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index d4bda9c6da..6c78265a4d 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -29,7 +29,6 @@ "Banned users": "Verbannen gebruikers", "Bans user with given id": "Verbant de gebruiker met het gegeven ID", "Blacklisted": "Buitengesloten", - "Bug Report": "Bug report", "Bulk Options": "Bulk opties", "Call Timeout": "Gesprek time-out", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Kan niet met de thuisserver verbinden via HTTP wanneer er een HTTPS-URL in je browser balk staat. Gebruik HTTPS of activeer onveilige scripts.", @@ -262,7 +261,6 @@ "Forgot your password?": "Wachtwoord vergeten?", "For security, this session has been signed out. Please sign in again.": "Voor veiligheidsredenen is deze sessie uitgelogd. Log alsjeblieft opnieuw in.", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "In verband met veiligheidsredenen zullen alle end-to-endbeveiligingsleutels van deze browser verwijderd worden. Als je je gespreksgeschiedenis van toekomstige Riot sessies wilt kunnen ontsleutelen, exporteer en bewaar dan de ruimte sleutels.", - "Found a bug?": "Een fout gevonden?", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s van %(fromPowerLevel)s naar %(toPowerLevel)s", "Guest access is disabled on this Home Server.": "Gasttoegang is uitgeschakeld op deze thuisserver.", "Guests cannot join this room even if explicitly invited.": "Gasten kunnen niet tot deze ruimte toetreden, zelfs als ze expliciet uitgenodigd zijn.", @@ -340,7 +338,6 @@ "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 end-to-endbeveiligingssleutels 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.", "Results from DuckDuckGo": "Resultaten van DuckDuckGo", "Return to login screen": "Naar het inlogscherm terugkeren", @@ -654,7 +651,6 @@ "Do you want to load widget from URL:": "Wil je de widget laden van de URL:", "Edit": "Aanpassen", "Enable automatic language detection for syntax highlighting": "Automatische taaldetectie voor zinsbouwmarkeringen aanzetten", - "Hide Apps": "Apps verbergen", "Hide join/leave messages (invites/kicks/bans unaffected)": "Toetreed/verlaat berichten verbergen (uitnodigingen/verwijderingen/verbanningen zullen ongeschonden blijven)", "Integrations Error": "Integratiesfout", "Publish this room to the public in %(domain)s's room directory?": "Deze ruimte publiekelijk maken in %(domain)s's ruimte catalogus?", @@ -663,7 +659,6 @@ "NOTE: Apps are not end-to-end encrypted": "OPMERKING: Apps zijn niet end-to-endbeveiligd", "Revoke widget access": "Toegang tot widget intrekken", "Sets the room topic": "Wijzigt het ruimte-onderwerp", - "Show Apps": "Apps Weergeven", "The maximum permitted number of widgets have already been added to this room.": "Het maximum aantal toegestane widgets is al aan deze ruimte toegevoegd.", "To get started, please pick a username!": "Om te beginnen, kies een gebruikersnaam!", "Unable to create widget.": "Niet in staat om een widget te maken.", @@ -722,7 +717,6 @@ "Send": "Verstuur", "Message Pinning": "Boodschap vastpinnen", "Message Replies": "Antwoorden op bericht", - "Presence Management": "Presentie Beheer", "Tag Panel": "Label Paneel", "Disable Emoji suggestions while typing": "Emoji suggesties tijdens het typen uitzetten", "Hide avatar changes": "Avatar veranderingen verbergen", @@ -925,7 +919,6 @@ "Leave Community": "Gemeenschap Verlaten", "Leave %(groupName)s?": "%(groupName)s verlaten?", "Leave": "Verlaten", - "Unable to leave room": "De ruimte kon niet verlaten worden", "Community Settings": "Gemeenschapsinstellingen", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Deze ruimtes worden aan gemeenschapsleden getoond op de gemeenschapspagina. Gemeenschapsleden kunnen tot de ruimtes toetreden door er op te klikken.", "%(inviter)s has invited you to join this community": "%(inviter)s heeft jou uitgenodigd om tot deze gemeenschap toe te treden", @@ -937,8 +930,6 @@ "Community %(groupId)s not found": "Gemeenschap %(groupId)s is niet gevonden", "This Home server does not support communities": "Deze Thuisserver ondersteunt geen gemeenschappen", "Failed to load %(groupId)s": "Het is niet gelukt om %(groupId)s te laden", - "Cryptography data migrated": "Cryptografie gegevens zijn gemigreerd", - "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "Een eenmalige migratie van cryptografie gegevens heeft plaatsgevonden. Eind-tot-eind versleuteling zal niet werken als je terug gaat naar een oudere versie van Riot. Log eerst uit op Riot als je eind-tot-eind versleuteling wil gebruiken op een oudere versie. Exporteer je sleutels en importeer ze achteraf weer als je de berichtgeschiedenis wilt behouden.", "Old cryptography data detected": "Oude cryptografie gegevens gedetecteerd", "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Er zijn gegevens van een oudere versie van Riot gedetecteerd. Dit zal eind-tot-eind versleuteling laten storen in de oudere versie. Eind-tot-eind berichten dat recent zijn uitgewisseld zal misschien niet ontsleutelbaar zijn in deze versie. Dit zou er misschien ook voor kunnen zorgen dat berichten die zijn uitgewisseld in deze versie falen. Indien je problemen ervaart, log opnieuw in. Om de berichtgeschiedenis te behouden, exporteer de sleutels en importeer ze achteraf weer.", "Your Communities": "Jouw Gemeenschappen", @@ -994,5 +985,177 @@ "Clear filter": "Filter vrijmaken", "Failed to set direct chat tag": "Het is niet gelukt om de 'privégesprek' label in te stellen", "Failed to remove tag %(tagName)s from room": "Het is niet gelukt om de label %(tagName)s van de ruimte te verwijderen", - "Failed to add tag %(tagName)s to room": "Het is niet gelukt om de label %(tagName)s aan deze ruimte toe te voegen" + "Failed to add tag %(tagName)s to room": "Het is niet gelukt om de label %(tagName)s aan deze ruimte toe te voegen", + "Stickerpack": "Stickerpakket", + "Sticker Messages": "Sticker Berichten", + "You don't currently have any stickerpacks enabled": "Je hebt momenteel geen stickerpakketten aan staan", + "Add a stickerpack": "Stickerpakket toevoegen", + "Hide Stickers": "Stickers verbergen", + "Show Stickers": "Stickers weergeven", + "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Gezien door %(displayName)s (%(userName)s) op %(dateTime)s", + "Code": "Code", + "Unable to join community": "Je kon niet tot de gemeenschap toetreden", + "Unable to leave community": "Je kon de gemeenschap niet verlaten", + "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Veranderingen die aan je gemeenschap naam en avatar zijn aangebracht zullen misschien niet gezien worden door anderen tot maximaal 30 minuten.", + "Join this community": "Tot deze gemeenschap toetreden", + "Who can join this community?": "Wie kan tot deze gemeenschap toetreden?", + "Everyone": "Iedereen", + "Leave this community": "Deze gemeenschap verlaten", + "Debug Logs Submission": "Debug Logs Indienen", + "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Als je een bug via Github hebt ingediend kunnen debug logs ons helpen om het probleem te vinden. Debug logs bevatten applicatie-gebruik data inclusief je gebruikersnaam, de ID's of namen van de ruimtes en groepen die je hebt bezocht en de gebruikersnamen van andere gebruikers. Ze bevatten geen berichten.", + "Submit debug logs": "Debug logs indienen", + "Opens the Developer Tools dialog": "Opent het Ontwikkelaars Gereedschappen dialoog", + "Fetching third party location failed": "Het ophalen van de locatie van de derde partij is mislukt", + "A new version of Riot is available.": "Er is een nieuwe versie van Riot beschikbaar.", + "I understand the risks and wish to continue": "Ik begrijp de risico's en wil graag verder gaan", + "Couldn't load home page": "Kon de home pagina niet laden", + "Send Account Data": "Stuur account informatie", + "All notifications are currently disabled for all targets.": "Alle meldingen zijn momenteel uitgeschakeld voor alle doelen.", + "Uploading report": "Rapport uploaden", + "Sunday": "Zondag", + "Notification targets": "Meldingsdoelen", + "Today": "Vandaag", + "Files": "Bestanden", + "You are not receiving desktop notifications": "Je ontvangt momenteel geen desktopmeldingen", + "Friday": "Vrijdag", + "Update": "Bijwerken", + "What's New": "Wat is er nieuw", + "Add an email address above to configure email notifications": "Voeg een e-mailadres toe om e-mailmeldingen te ontvangen", + "Expand panel": "Paneel uitklappen", + "On": "Aan", + "%(count)s Members|other": "%(count)s Deelnemers", + "Filter room names": "Filter kamernamen", + "Changelog": "Logboek van wijzigingen", + "Waiting for response from server": "Wachten op antwoord van de server", + "Send Custom Event": "Verzend aangepast evenement", + "Advanced notification settings": "Geavanceerde meldingsinstellingen", + "delete the alias.": "verwijder de alias.", + "To return to your account in future you need to set a password": "Om in de toekomst naar je account terug te gaan moet je een wachtwoord instellen", + "Forget": "Vergeten", + "#example": "#voorbeeld", + "Hide panel": "Paneel verbergen", + "You cannot delete this image. (%(code)s)": "Je kunt deze afbeelding niet verwijderen. (%(code)s)", + "Cancel Sending": "Versturen annuleren", + "This Room": "Deze kamer", + "The Home Server may be too old to support third party networks": "De thuisserver is misschien te oud om netwerken van derde partijen te ondersteunen", + "Resend": "Opnieuw verzenden", + "Error saving email notification preferences": "Fout bij het opslaan van de meldingsvoorkeuren voor e-mail", + "Messages containing my display name": "Berichten die mijn weergavenaam bevatten", + "Messages in one-to-one chats": "Berichten in één-op-één-gesprekken", + "Unavailable": "Niet beschikbaar", + "View Decrypted Source": "Bekijk ontsleutelde bron", + "Failed to update keywords": "Trefwoorden bijwerken mislukt", + "remove %(name)s from the directory.": "verwijder %(name)s uit de kamerlijst.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Meldingen op de volgende trefwoorden volgen regels die hier niet kunnen worden getoond:", + "Safari and Opera work too.": "Safari en Opera werken ook.", + "Please set a password!": "Stel een wachtwoord in!", + "You have successfully set a password!": "U heeft met succes een wachtwoord ingesteld!", + "An error occurred whilst saving your email notification preferences.": "Er is een fout opgetreden tijdens het opslaan van uw e-mailmeldingsvoorkeuren.", + "Explore Room State": "Verken Ruimtetoestand", + "Source URL": "Bron-URL", + "Messages sent by bot": "Berichten verzonden door een bot", + "Filter results": "Resultaten filteren", + "Members": "Leden", + "No update available.": "Geen update beschikbaar.", + "Noisy": "Luidruchtig", + "Failed to get protocol list from Home Server": "Protocollijst ophalen van de homeserver mislukt", + "Collecting app version information": "App-versieinformatie verzamelen", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "De alias %(alias)s verwijderen en %(name)s uit de kamerlijst verwijderen?", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Hiermee kunt u naar uw account terugkeren nadat u zich heeft afgemeld, en u aanmelden op andere apparaten.", + "Keywords": "Trefwoorden", + "Enable notifications for this account": "Meldingen voor dit account aanzetten", + "Directory": "Kamerlijst", + "Invite to this community": "Nodig uit in deze community", + "Search for a room": "Een kamer opzoeken", + "Messages containing keywords": "Berichten die trefwoorden bevatten", + "Room not found": "De kamer is niet gevonden", + "Tuesday": "Dinsdag", + "Enter keywords separated by a comma:": "Voeg trefwoorden toe, gescheiden door een komma:", + "Search…": "Zoeken…", + "You have successfully set a password and an email address!": "Het instellen van een wachtwoord en e-mailadres is geslaagd!", + "Remove %(name)s from the directory?": "%(name)s uit de kamerlijst verwijderen?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot gebrukt veel geavanceerde browserfuncties, waarvan enkele niet (of experimenteel) in uw webbrowser beschikbaar zijn.", + "Developer Tools": "Ontwikkelaarsgereedschap", + "Enable desktop notifications": "Desktopmeldingen aanzetten", + "Explore Account Data": "Bekijk account informatie", + "Remove from Directory": "Uit de kamerlijst verwijderen", + "Saturday": "Zaterdag", + "Remember, you can always set an email address in user settings if you change your mind.": "Onthoud dat u altijd een e-mailadres in kan stellen in de gebruikersinstellingen als u zich bedenkt.", + "Direct Chat": "Privégesprek", + "The server may be unavailable or overloaded": "De server is misschien niet beschikbaar of overbelast", + "Reject": "Afwijzen", + "Failed to set Direct Message status of room": "Het is mislukt om de directe-berichtenstatus van de kamer in te stellen", + "Monday": "Maandag", + "All messages (noisy)": "Alle berichten (luid)", + "Enable them now": "Deze nu aanzetten", + "Messages containing my user name": "Berichten die mijn gebruikersnaam bevatten", + "Toolbox": "Eigenschappen", + "Collecting logs": "Logboeken verzamelen", + "more": "meer", + "You must specify an event type!": "Je moet een event-type specificeren!", + "(HTTP status %(httpStatus)s)": "(HTTP-status %(httpStatus)s)", + "Invite to this room": "Uitnodigen voor deze kamer", + "Please install Chrome or Firefox for the best experience.": "Installeer alstublieft Chrome of Firefox voor de beste gebruikerservaring.", + "Failed to get public room list": "Lijst met publieke kamers ophalen mislukt", + "Send logs": "Logboeken versturen", + "All messages": "Alle berichten", + "Call invitation": "Oproep-uitnodiging", + "Downloading update...": "Update aan het downloaden...", + "State Key": "Toestandssleutel", + "Failed to send custom event.": "Aangepast Event verzenden mislukt.", + "What's new?": "Wat is er nieuw?", + "Notify me for anything else": "Stuur een melding voor al het andere", + "When I'm invited to a room": "Wanneer ik uitgenodigd word voor een kamer", + "Can't update user notification settings": "Het is niet gelukt om de meldingsinstellingen van de gebruiker bij te werken", + "Notify for all other messages/rooms": "Stuur een melding voor alle andere berichten/kamers", + "Unable to look up room ID from server": "Het is mislukt om de kamer-ID op te halen van de server", + "Couldn't find a matching Matrix room": "Het is niet gelukt om een bijbehorende Matrix-kamer te vinden", + "All Rooms": "Alle kamers", + "You cannot delete this message. (%(code)s)": "Je kunt dit bericht niet verwijderen. (%(code)s)", + "Thursday": "Donderdag", + "Forward Message": "Bericht doorsturen", + "Back": "Terug", + "Reply": "Beantwoord", + "Show message in desktop notification": "Toon boodschap in bureaublad popup", + "Unhide Preview": "Zichtbaar maken preview", + "Unable to join network": "Het is mislukt om toe te treden tot dit netwerk", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Je hebt ze mogelijk ingesteld in een andere client dan Riot. Je kunt ze niet aanpassen in Riot maar ze zijn wel actief", + "Sorry, your browser is not able to run Riot.": "Sorry, uw browser werkt niet met Riot.", + "Uploaded on %(date)s by %(user)s": "Geüpload op %(date)s door %(user)s", + "Messages in group chats": "Berichten in groepsgesprekken", + "Yesterday": "Gisteren", + "Error encountered (%(errorDetail)s).": "Fout ondervonden (%(errorDetail)s).", + "Login": "Aanmelden", + "Low Priority": "Lage prioriteit", + "Unable to fetch notification target list": "Het is mislukt om de lijst van notificatiedoelen op te halen", + "Set Password": "Wachtwoord instellen", + "Enable audible notifications in web client": "Geluidsmeldingen in de webclient aanzetten", + "Permalink": "Permanente link", + "Off": "Uit", + "Riot does not know how to join a room on this network": "Riot weet niet hoe het moet deelnemen in een kamer op dit netwerk", + "Mentions only": "Alleen vermeldingen", + "Wednesday": "Woensdag", + "You can now return to your account after signing out, and sign in on other devices.": "U kunt nu terugkeren naar uw account nadat u bent afgemeld, en u aanmelden op andere apparaten.", + "Enable email notifications": "E-mailmeldingen aanzetten", + "Event Type": "Event-type", + "Download this file": "Download dit bestand", + "Pin Message": "Bericht vastpinnen", + "Failed to change settings": "Instellingen wijzigen mislukt", + "View Community": "Gemeenschap Weergeven", + "%(count)s Members|one": "%(count)s Deelnemer", + "Event sent!": "Event verstuurd!", + "View Source": "Bekijk bron", + "Event Content": "Event-inhoud", + "Thank you!": "Bedankt!", + "Collapse panel": "Paneel inklappen", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Met uw huidige browser kan de applicatie er volledig incorrect uitzien. Tevens is het mogelijk dat niet alle functies naar behoren werken. U kunt doorgaan als u het toch wil proberen, maar bij problemen bent u volledig op uzelf aangewezen!", + "Checking for an update...": "Aan het kijken voor een update...", + "There are advanced notifications which are not shown here": "Er zijn geavanceerde notificaties die hier niet getoond worden", + "Logs sent": "Logs verstuurd", + "Click here to create a GitHub issue.": "Klik hier om een Github opgave in te dienen.", + "GitHub issue link:": "GitHub opgave link:", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Debug logs bevatten applicatie-gebruik data inclusief je gebruikersnaam, de ID's of namen van de ruimtes en groepen die je hebt bezocht en de gebruikersnamen van andere gebruikers. Ze bevatten geen berichten.", + "Failed to send logs: ": "Het is niet gelukt om de logs te versturen: ", + "Notes:": "Constateringen:", + "Preparing to send logs": "Voorbereiden om logs te versturen" } diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index d732be55da..8de9983f22 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -13,7 +13,6 @@ "Banned users": "Заблокированные пользователи", "Bans user with given id": "Блокирует пользователя с заданным ID", "Blacklisted": "В черном списке", - "Bug Report": "Отчет об ошибке", "Bulk Options": "Групповые параметры", "Can't load user settings": "Невозможно загрузить пользовательские настройки", "Changes to who can read history will only apply to future messages in this room": "Изменения того, кто может прочитать историю, будут применяться только к будущим сообщениям в этой комнате", @@ -61,7 +60,6 @@ "Forget room": "Забыть комнату", "Forgot your password?": "Забыли пароль?", "For security, this session has been signed out. Please sign in again.": "Для обеспечения безопасности ваша сессия была завершена. Пожалуйста, войдите снова.", - "Found a bug?": "Нашли ошибку?", "Hangup": "Закончить", "Historical": "Архив", "Homeserver is": "Домашний сервер это", @@ -314,7 +312,6 @@ "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s удалил свое отображаемое имя (%(oldDisplayName)s).", "%(senderName)s removed their profile picture.": "%(senderName)s удалил свое изображение профиля.", "%(senderName)s requested a VoIP conference.": "%(senderName)s хочет начать VoIP-конференцию.", - "Report it": "Сообщить об этом", "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.": "Сброс пароля на данный момент сбрасывает ключи шифрования на всех устройствах, делая зашифрованную историю чатов нечитаемой. Чтобы избежать этого, экспортируйте ключи комнат и импортируйте их после сброса пароля. В будущем это будет исправлено.", "Riot does not have permission to send you notifications - please check your browser settings": "У Riot нет разрешений на отправку уведомлений - проверьте настройки браузера", "Riot was not given permission to send notifications - please try again": "Riot не получил разрешение на отправку уведомлений, пожалуйста, попробуйте снова", @@ -654,7 +651,6 @@ "Do you want to load widget from URL:": "Загрузить виджет из URL-адреса:", "Edit": "Редактировать", "Enable automatic language detection for syntax highlighting": "Включить автоматическое определение языка для подсветки синтаксиса", - "Hide Apps": "Скрыть приложения", "Hide join/leave messages (invites/kicks/bans unaffected)": "Скрыть сообщения о входе/выходе (не применяется к приглашениям/выкидываниям/банам)", "Integrations Error": "Ошибка интеграции", "AM": "AM", @@ -662,7 +658,6 @@ "NOTE: Apps are not end-to-end encrypted": "ПРИМЕЧАНИЕ: приложения не защищены сквозным шифрованием", "Revoke widget access": "Отозвать доступ к виджетам", "Sets the room topic": "Задать тему комнаты", - "Show Apps": "Показать приложения", "The maximum permitted number of widgets have already been added to this room.": "Максимально допустимое количество виджетов уже добавлено в эту комнату.", "To get started, please pick a username!": "Чтобы начать, выберите имя пользователя!", "Unable to create widget.": "Не удалось создать виджет.", @@ -719,7 +714,6 @@ "Description": "Описание", "Name or matrix ID": "Имя или matrix ID", "Unable to accept invite": "Невозможно принять приглашение", - "Unable to leave room": "Невозможно покинуть комнату", "Leave": "Покинуть", "Failed to invite the following users to %(groupId)s:": "Не удалось пригласить следующих пользователей в %(groupId)s:", "Failed to remove '%(roomName)s' from %(groupId)s": "Не удалось удалить '%(roomName)s' из %(groupId)s", @@ -890,7 +884,6 @@ "Visibility in Room List": "Видимость в списке комнат", "Visible to everyone": "Видимый для всех", "Only visible to community members": "Только участникам сообщества", - "Presence Management": "Управление присутствием", "Hide avatar changes": "Скрыть изменения аватара", "Hide display name changes": "Скрыть изменения отображаемого имени", "Enable inline URL previews by default": "Включить просмотр URL-адресов по умолчанию", @@ -958,7 +951,7 @@ "Send a reply (unencrypted)…": "Отправить ответ (незашифрованный)…", "Send an encrypted message…": "Отправить зашифрованное сообщение…", "Send a message (unencrypted)…": "Отправить сообщение (незашифрованное)…", - "Replying": "Отвечая", + "Replying": "Отвечает", "Minimize apps": "Свернуть приложения", "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Конфиденциальность важна для нас, поэтому мы не собираем никаких личных или идентифицируемых данных для нашей аналитики.", "Learn more about how we use analytics.": "Подробнее о том, как мы используем аналитику.", @@ -992,7 +985,6 @@ "%(user)s is a %(userRole)s": "%(user)s является %(userRole)s", "Your key share request has been sent - please check your other devices for key share requests.": "Ваш запрос на передачу ключей отправлен - пожалуйста, проверьте другие ваши устройства на запросы передачи ключей.", "Key share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, click here to request the keys for this session again.": "Запросы передачи ключей автоматически отправляются на другие устройства. Если вы отклонили или отменили запрос на передачу ключей на других устройствах, нажмите здесь, чтобы запросить ключи для этого сеанса повторно.", - "Changes made to your community might not be seen by other users for up to 30 minutes.": "Изменения, сделанные в вашем сообществе, могут не отображаться для других пользователей в течение 30 минут.", "Code": "Код", "Debug Logs Submission": "Отправка журналов отладки", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Если вы отправили ошибку через GitHub, журналы отладки могут помочь нам выявить проблему. Журналы отладки содержат данные об использовании приложения, включая ваше имя пользователя, идентификаторы или псевдонимы комнат или групп, которые вы посетили, а также имена других пользователей. Они не содержат сообщений.", @@ -1004,9 +996,165 @@ "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Изменения имени и аватара, внесенные в ваше сообщество, могут не отображаться другим пользователям в течение 30 минут.", "Join this community": "Присоединиться к сообществу", "Leave this community": "Покинуть это сообщество", - "here": "здесь", - "to add some!": "для добавления!", - "Click": "Нажмите", "Who can join this community?": "Кто может присоединиться к этому сообществу?", - "Everyone": "Все" + "Everyone": "Все", + "Stickerpack": "Этикетки", + "Sticker Messages": "Сообщения этикеткой", + "Add a stickerpack": "Добавить этикетки", + "Hide Stickers": "Скрыть этикетки", + "Show Stickers": "Показать этикетки", + "Fetching third party location failed": "Не удалось извлечь местоположение третьей стороны", + "A new version of Riot is available.": "Доступна новая версия Riot.", + "I understand the risks and wish to continue": "Я понимаю риски и желаю продолжить", + "Couldn't load home page": "Не удалось загрузить домашнюю страницу", + "Send Account Data": "Отправить данные аккаунта", + "All notifications are currently disabled for all targets.": "Все оповещения для всех устройств отключены.", + "Uploading report": "Отправка отчета", + "Sunday": "Воскресенье", + "Notification targets": "Цели уведомления", + "Today": "Сегодня", + "Files": "Файлы", + "You are not receiving desktop notifications": "Вы не получаете уведомления на рабочем столе", + "Friday": "Пятница", + "Update": "Обновление", + "What's New": "Что нового", + "Add an email address above to configure email notifications": "Добавьте email адрес для оповещений", + "Expand panel": "Развернуть панель", + "On": "Включить", + "%(count)s Members|other": "%(count)s членов", + "Filter room names": "Фильтр по названию комнат", + "Changelog": "История изменений", + "Waiting for response from server": "Ожидание ответа от сервера", + "Uploaded on %(date)s by %(user)s": "Отправлено %(date)s для %(user)s", + "Send Custom Event": "Отправить индивидуальное мероприятие", + "Advanced notification settings": "Дополнительные параметры уведомлений", + "Failed to send logs: ": "Не удалось отправить журналы: ", + "delete the alias.": "удалить псевдоним.", + "To return to your account in future you need to set a password": "Чтобы вернуться к учетной записи в будущем, необходимо задать пароль", + "Forget": "Забыть", + "#example": "#пример", + "Hide panel": "Скрыть панель", + "You cannot delete this image. (%(code)s)": "Это изображение нельзя удалить. (%(code)s)", + "Cancel Sending": "Отменить отправку", + "This Room": "Эта комната", + "The Home Server may be too old to support third party networks": "Домашний сервер может быть слишком старым для поддержки сетей сторонних производителей", + "Noisy": "Со звуком", + "Room not found": "Комната не найдена", + "Messages containing my display name": "Сообщения, содержащие мое имя", + "Messages in one-to-one chats": "Сообщения в индивидуальных чатах", + "Unavailable": "Недоступен", + "Error saving email notification preferences": "Ошибка при сохранении настроек уведомлений по email", + "View Decrypted Source": "Просмотр расшифрованного источника", + "Failed to update keywords": "Не удалось обновить ключевые слова", + "Notes:": "Заметки:", + "remove %(name)s from the directory.": "удалить %(name)s из каталога.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Уведомления по следующим ключевым словам соответствуют правилам, которые нельзя отобразить здесь:", + "Safari and Opera work too.": "Safari и Opera работают тоже.", + "Please set a password!": "Пожалуйста, установите пароль!", + "You have successfully set a password!": "Вы успешно установили пароль!", + "An error occurred whilst saving your email notification preferences.": "Возникла ошибка при сохранении настроек оповещения по email.", + "Explore Room State": "Просмотр статуса комнаты", + "Source URL": "Исходный URL-адрес", + "Messages sent by bot": "Сообщения, отправленные ботом", + "Filter results": "Фильтрация результатов", + "Members": "Участники", + "No update available.": "Нет доступных обновлений.", + "Resend": "Переотправить", + "Failed to get protocol list from Home Server": "Не удалось получить список протоколов с домашнего сервера", + "Collecting app version information": "Сбор информации о версии приложения", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Удалить псевдоним комнаты %(alias)s и удалить %(name)s из каталога?", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Это позволит вам вернуться к учетной записи после выхода из системы и войти на других устройствах.", + "Keywords": "Ключевые слова", + "Enable notifications for this account": "Включить уведомления для этой учетной записи", + "Directory": "Каталог", + "Invite to this community": "Пригласить в это сообщество", + "Search for a room": "Поиск комнаты", + "Messages containing keywords": "Сообщения, содержащие определенные ключевые слова", + "View Source": "Просмотр источника", + "Tuesday": "Вторник", + "Enter keywords separated by a comma:": "Введите ключевые слова, разделенные запятой:", + "Search…": "Поиск.…", + "You have successfully set a password and an email address!": "Вы успешно установили пароль и адрес email!", + "Remove %(name)s from the directory?": "Удалить %(name)s из каталога?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot использует многие передовые возможности браузера, некоторые из которых недоступны или являются экспериментальным в вашем текущем браузере.", + "Developer Tools": "Инструменты разработчика", + "Preparing to send logs": "Подготовка к отправке журналов", + "Enable desktop notifications": "Включить оповещения на рабочем столе", + "Explore Account Data": "Просмотр данных аккаунта", + "All messages (noisy)": "Все сообщения (со звуком)", + "Saturday": "Суббота", + "Remember, you can always set an email address in user settings if you change your mind.": "Помните, что вы всегда сможете задать адрес email в настройках пользователя, если передумаете.", + "Direct Chat": "Прямой чат", + "The server may be unavailable or overloaded": "Сервер, вероятно, недоступен или перегружен", + "Reject": "Отклонить", + "Failed to set Direct Message status of room": "Не удалось установить статус прямого сообщения в комнате", + "Monday": "Понедельник", + "Remove from Directory": "Удалить из каталога", + "Enable them now": "Включить сейчас", + "Messages containing my user name": "Сообщение, содержащие мое имя пользователя", + "Toolbox": "Панель инструментов", + "Collecting logs": "Сбор журналов", + "more": "больше", + "GitHub issue link:": "Ссылка на проблему в GitHub:", + "You must specify an event type!": "Необходимо указать тип мероприятия!", + "(HTTP status %(httpStatus)s)": "(статус HTTP %(httpStatus)s)", + "Invite to this room": "Пригласить в комнату", + "Please install Chrome or Firefox for the best experience.": "Лучший опыт вы получите, установив Chrome или Firefox.", + "Failed to get public room list": "Не удалось получить список общедоступных комнат", + "Send logs": "Отправка журналов", + "All messages": "Все сообщения", + "Call invitation": "Пригласительный звонок", + "Downloading update...": "Загрузка обновления...", + "State Key": "Ключ состояния", + "Failed to send custom event.": "Не удалось отправить индивидуальное мероприятие.", + "What's new?": "Что нового?", + "Notify me for anything else": "Уведомлять во всех остальных случаях", + "When I'm invited to a room": "Когда меня приглашают в комнату", + "Click here to create a GitHub issue.": "Нажмите здесь для создания запроса о проблеме на GitHub.", + "Can't update user notification settings": "Не удается обновить пользовательские настройки оповещения", + "Notify for all other messages/rooms": "Уведомлять обо всех других сообщениях/комнатах", + "Unable to look up room ID from server": "Не удалось найти ID комнаты на сервере", + "Couldn't find a matching Matrix room": "Не удалось найти подходящую комнату Matrix", + "All Rooms": "Все комнаты", + "You cannot delete this message. (%(code)s)": "Это сообщение нельзя удалить. (%(code)s)", + "Thursday": "Четверг", + "Forward Message": "Переслать сообщение", + "Logs sent": "Журналы отправлены", + "Back": "Назад", + "Reply": "Ответить", + "Show message in desktop notification": "Показывать сообщение в уведомлении на рабочем столе", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Журналы отладки содержат данные об использовании приложения, включая ваше имя пользователя, идентификаторы или псевдонимы комнат или групп, которые вы посетили, а также имена других пользователей. Они не содержат сообщений.", + "Unhide Preview": "Показать предварительный просмотр", + "Unable to join network": "Не удается подключиться к сети", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Возможно вы настроили их не в Riot, а в другом Matrix-клиенте. Настроить их в Riot не удастся, но они будут в нем применяться", + "Sorry, your browser is not able to run Riot.": "К сожалению, ваш браузер не способен запустить Riot.", + "Messages in group chats": "Сообщения в групповых чатах", + "Yesterday": "Вчера", + "Error encountered (%(errorDetail)s).": "Обнаружена ошибка (%(errorDetail)s).", + "Login": "Войти", + "Low Priority": "Низкий приоритет", + "Unable to fetch notification target list": "Не удалось получить список целей уведомления", + "Set Password": "Задать пароль", + "Enable audible notifications in web client": "Включить звуковые уведомления в веб-клиенте", + "Permalink": "Постоянная ссылка", + "Off": "Выключить", + "Riot does not know how to join a room on this network": "Riot не знает, как присоединиться к комнате, принадлежащей к этой сети", + "Mentions only": "Только при упоминаниях", + "Wednesday": "Среда", + "You can now return to your account after signing out, and sign in on other devices.": "Теперь вы сможете вернуться к своей учетной записи после выхода из системы и войти на других устройствах.", + "Enable email notifications": "Включить уведомления по email", + "Event Type": "Тип мероприятия", + "Download this file": "Скачать этот файл", + "Pin Message": "Закрепить сообщение", + "Failed to change settings": "Не удалось изменить настройки", + "View Community": "Просмотр сообщества", + "%(count)s Members|one": "%(count)s член", + "Event sent!": "Мероприятие отправлено!", + "Event Content": "Содержание мероприятия", + "Thank you!": "Спасибо!", + "Quote": "Цитата", + "Collapse panel": "Свернуть панель", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "В текущем браузере внешний вид приложения может быть полностью неверным, а некоторые или все функции могут не работать. Если вы хотите попробовать в любом случае, то можете продолжить, но с теми проблемами, с которыми вы можете столкнуться вам придется разбираться самостоятельно!", + "Checking for an update...": "Проверка обновлений...", + "There are advanced notifications which are not shown here": "Существуют дополнительные уведомления, которые не показаны здесь" } diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index 72ba11b6d4..c915ae04b4 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -263,8 +263,6 @@ "Hangup": "Zavesiť", "Voice call": "Audio hovor", "Video call": "Video hovor", - "Hide Apps": "Skryť aplikácie", - "Show Apps": "Zobraziť aplikácie", "Upload file": "Nahrať súbor", "Show Text Formatting Toolbar": "Zobraziť lištu formátovania textu", "You do not have permission to post to this room": "Nemáte udelené právo posielať do tejto miestnosti", @@ -296,15 +294,15 @@ "Seen by %(userName)s at %(dateTime)s": "%(userName)s videl %(dateTime)s", "Unnamed room": "Nepomenovaná miestnosť", "World readable": "Viditeľné pre každého", - "Guests can join": "Aj hostia môžu vstúpiť", + "Guests can join": "Môžu vstúpiť aj hostia", "No rooms to show": "Žiadne miestnosti na zobrazenie", - "Failed to set avatar.": "Nepodarilo sa nastaviť avatara.", + "Failed to set avatar.": "Nepodarilo sa nastaviť obrázok.", "Save": "Uložiť", "(~%(count)s results)|other": "(~%(count)s výsledkov)", "(~%(count)s results)|one": "(~%(count)s výsledok)", "Join Room": "Vstúpiť do miestnosti", - "Upload avatar": "Nahrať avatara", - "Remove avatar": "Odstrániť avatara", + "Upload avatar": "Nahrať obrázok", + "Remove avatar": "Odstrániť obrázok", "Settings": "Nastavenia", "Forget room": "Zabudnúť miestnosť", "Search": "Hľadať", @@ -341,7 +339,7 @@ "You are trying to access a room.": "Pristupujete k miestnosti.", "Click here to join the discussion!": "Kliknutím sem vstúpite do diskusie!", "This is a preview of this room. Room interactions have been disabled": "Toto je náhľad na miestnosť. Všetky akcie pre túto miestnosť sú zakázané", - "To change the room's avatar, you must be a": "Aby ste mohli meniť avatara miestnosti, musíte byť", + "To change the room's avatar, you must be a": "Aby ste mohli meniť obrázok miestnosti, musíte byť", "To change the room's name, you must be a": "Aby ste mohli meniť názov miestnosti, musíte byť", "To change the room's main address, you must be a": "Aby ste mohli meniť hlavnú adresu miestnosti, musíte byť", "To change the room's history visibility, you must be a": "Aby ste mohli meniť viditeľnosť histórie miestnosti, musíte byť", @@ -428,9 +426,9 @@ "Image '%(Body)s' cannot be displayed.": "Nie je možné zobraziť obrázok '%(Body)s'.", "This image cannot be displayed.": "Tento obrázok nie je možné zobraziť.", "Error decrypting video": "Chyba pri dešifrovaní videa", - "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s zmenil avatara pre %(roomName)s", - "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s z miestnosti odstránil avatara.", - "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s zmenil avatara miestnosti na ", + "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s zmenil obrázok miestnosti %(roomName)s", + "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s odstránil obrázok miestnosti.", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s zmenil obrázok miestnosti ", "Copied!": "Skopírované!", "Failed to copy": "Nepodarilo sa skopírovať", "Add an Integration": "Pridať integráciu", @@ -553,10 +551,10 @@ "%(severalUsers)schanged their name %(count)s times|one": "%(severalUsers)ssi zmenili meno", "%(oneUser)schanged their name %(count)s times|other": "%(oneUser)ssi %(count)s krát zmenil meno", "%(oneUser)schanged their name %(count)s times|one": "%(oneUser)ssi zmenil meno", - "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)ssi %(count)s krát zmenili avatara", - "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)ssi zmenili avatara", - "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)ssi %(count)s krát zmenil avatara", - "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)ssi zmenil avatara", + "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)ssi %(count)s krát zmenili obrázok v profile", + "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)ssi zmenili obrázok v profile", + "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)ssi %(count)s krát zmenil obrázok v profile", + "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)ssi zmenil obrázok v profile", "%(items)s and %(count)s others|other": "%(items)s a %(count)s ďalší", "%(items)s and %(count)s others|one": "%(items)s a jeden ďalší", "%(items)s and %(lastItem)s": "%(items)s a tiež %(lastItem)s", @@ -673,7 +671,6 @@ "Leave Community": "Opustiť komunitu", "Leave %(groupName)s?": "Opustiť komunitu %(groupName)s?", "Leave": "Opustiť", - "Unable to leave room": "Nie je možné opustiť miestnosť", "Community Settings": "Nastavenia komunity", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Tieto miestnosti sú zobrazené všetkým členom na stránke komunity. Členovia komunity môžu vstúpiť do miestnosti kliknutím.", "Add rooms to this community": "Pridať miestnosti do tejto komunity", @@ -773,9 +770,6 @@ "Device ID:": "ID zariadenia:", "Device key:": "Kľúč zariadenia:", "Ignored Users": "Ignorovaní používatelia", - "Bug Report": "Hlásenie chyby", - "Found a bug?": "Našli ste chybu?", - "Report it": "Ohláste ju", "Analytics": "Analytické údaje", "Riot collects anonymous analytics to allow us to improve the application.": "Riot zbiera anonymné analytické údaje, čo nám umožňuje aplikáciu ďalej zlepšovať.", "Labs": "Experimenty", @@ -837,9 +831,9 @@ "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "K domovskému serveru nie je možné pripojiť sa použitím protokolu HTTP keďže v adresnom riadku prehliadača máte HTTPS adresu. Použite protokol HTTPS alebo povolte nezabezpečené skripty.", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Nie je možné pripojiť sa k domovskému serveru - skontrolujte prosím funkčnosť vašeho pripojenia na internet, uistite sa že certifikát domovského servera je dôverihodný, a že žiaden doplnok nainštalovaný v prehliadači nemôže blokovať požiadavky.", "Login as guest": "Prihlásiť sa ako hosť", - "Failed to fetch avatar URL": "Nepodarilo sa získať URL adresu avatara", + "Failed to fetch avatar URL": "Nepodarilo sa získať URL adresu obrázka", "Set a display name:": "Nastaviť zobrazované meno:", - "Upload an avatar:": "Nahrať avatara:", + "Upload an avatar:": "Nahrať obrázok:", "This server does not support authentication with a phone number.": "Tento server nepodporuje overenie telefónnym číslom.", "Missing password.": "Chýba heslo.", "Passwords don't match.": "Heslá sa nezhodujú.", @@ -905,8 +899,7 @@ "Please note you are logging into the %(hs)s server, not matrix.org.": "Všimnite si: Práve sa prihlasujete na server %(hs)s, nie na server matrix.org.", "Username on %(hs)s": "Meno používateľa na servery %(hs)s", "Restricted": "Obmedzené", - "Presence Management": "Spravovanie prítomnosti", - "Hide avatar changes": "Skryť zmeny avatara", + "Hide avatar changes": "Skryť zmeny obrázka v profile", "Hide display name changes": "Skryť zmeny zobrazovaného mena", "Enable inline URL previews by default": "Predvolene povoliť náhľady URL adries", "Enable URL previews for this room (only affects you)": "Povoliť náhľady URL adries pre túto miestnosť (ovplyvňuje len vás)", @@ -993,14 +986,176 @@ "Code": "Kód", "Unable to join community": "Nie je možné vstúpiť do komunity", "Unable to leave community": "Nie je možné opustiť komunitu", - "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Zmeny vykonané vo vašej komunite name and avatar nemusia byť nasledujúcich 30 minút viditeľné všetkými používateľmi.", + "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Zmeny vykonané vo vašej komunite názov a obrázok nemusia byť nasledujúcich 30 minút viditeľné všetkými používateľmi.", "Join this community": "Vstúpiť do tejto komunity", "Leave this community": "Opustiť túto komunitu", "Did you know: you can use communities to filter your Riot.im experience!": "Vedeli ste: Že prácu s Riot.im si môžete spríjemníť použitím komunít!", - "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Ak si chcete nastaviť filter, pretiahnite avatara komunity na panel filtrovania úplne na ľavej strane obrazovky. Potom môžete kedykoľvek kliknúť na avatara komunity na tomto panely a Riot.im vám bude zobrazovať len miestnosti a ľudí z komunity, na ktorej avatar ste klikli.", + "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Ak si chcete nastaviť filter, pretiahnite obrázok komunity na panel filtrovania úplne na ľavej strane obrazovky. Potom môžete kedykoľvek kliknúť na obrázok komunity na tomto panely a Riot.im vám bude zobrazovať len miestnosti a ľudí z komunity, na ktorej obrázok ste klikli.", "Clear filter": "Zrušiť filter", "Debug Logs Submission": "Odoslanie ladiacich záznamov", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Ak ste nám poslali hlásenie o chybe cez Github, ladiace záznamy nám môžu pomôcť lepšie identifikovať chybu. Ladiace záznamy obsahujú údaje o používaní aplikácii, vrátane vašeho používateľského mena, názvy a aliasy miestností a komunít, ku ktorým ste sa pripojili a mená ostatných používateľov. Tieto záznamy neobsahujú samotný obsah vašich správ.", "Submit debug logs": "Odoslať ladiace záznamy", - "Opens the Developer Tools dialog": "Otvorí dialóg nástroje pre vývojárov" + "Opens the Developer Tools dialog": "Otvorí dialóg nástroje pre vývojárov", + "Stickerpack": "Balíček nálepiek", + "Sticker Messages": "Správy s nálepkami", + "You don't currently have any stickerpacks enabled": "Momentálne nemáte aktívne žiadne balíčky s nálepkami", + "Add a stickerpack": "Pridať balíček s nálepkami", + "Hide Stickers": "Skryť nálepky", + "Show Stickers": "Zobraziť nálepky", + "Who can join this community?": "Kto môže vstúpiť do tejto komunity?", + "Everyone": "Ktokoľvek", + "Fetching third party location failed": "Nepodarilo sa získať umiestnenie tretej strany", + "A new version of Riot is available.": "Dostupná je nová verzia Riot.", + "Couldn't load home page": "Nie je možné načítať domovskú stránku", + "Send Account Data": "Odoslať Údaje Účtu", + "All notifications are currently disabled for all targets.": "Momentálne sú zakázané všetky oznámenia pre všetky ciele.", + "Uploading report": "Prebieha odovzdanie hlásenia", + "Sunday": "Nedeľa", + "Notification targets": "Ciele oznámení", + "Today": "Dnes", + "Files": "Súbory", + "You are not receiving desktop notifications": "Nedostávate oznámenia na pracovnej ploche", + "Friday": "Piatok", + "Update": "Aktualizovať", + "Unable to fetch notification target list": "Nie je možné získať zoznam cieľov oznámení", + "Add an email address above to configure email notifications": "Ak si chcete nastaviť oznamovanie emailom, pridajte si emailovú adresu vyššie", + "Expand panel": "Rozbaliť panel", + "On": "Povolené", + "%(count)s Members|other": "%(count)s Členov", + "Filter room names": "Filtrovať názvy miestností", + "Changelog": "Zoznam zmien", + "Waiting for response from server": "Čakanie na odpoveď zo servera", + "Uploaded on %(date)s by %(user)s": "Nahral používateľ %(user)s dňa %(date)s", + "Send Custom Event": "Odoslať vlastnú udalosť", + "Advanced notification settings": "Pokročilé nastavenia oznámení", + "Failed to send logs: ": "Nepodarilo sa odoslať záznamy: ", + "delete the alias.": "vymazať alias.", + "To return to your account in future you need to set a password": "Aby ste sa v budúcnosti mohli vrátiť k vašemu účtu mali by ste si teraz nastaviť heslo", + "Forget": "Zabudnuť", + "Hide panel": "Skryť panel", + "You cannot delete this image. (%(code)s)": "Nemôžete vymazať tento obrázok. (%(code)s)", + "Cancel Sending": "Zrušiť odosielanie", + "This Room": "V tejto miestnosti", + "The Home Server may be too old to support third party networks": "Domovský server môže byť natoľko zastaralý, že nepodporuje siete tretíh strán", + "Resend": "Poslať znovu", + "Room not found": "Miestnosť nenájdená", + "Downloading update...": "Sťahovanie aktualizácie...", + "Messages in one-to-one chats": "Správy v priamych konverzáciách", + "Unavailable": "Nedostupné", + "View Decrypted Source": "Zobraziť dešifrovaný zdroj", + "Failed to update keywords": "Nepodarilo sa aktualizovať kľúčové slová", + "Notes:": "Poznámky:", + "remove %(name)s from the directory.": "odstrániť %(name)s z adresára.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Oznámenia nasledujúcich kľúčových slov sa riadia pravidlami, ktoré nie je možné zobraziť na tomto mieste:", + "Safari and Opera work too.": "Správne fungujú aj Safari a Opera.", + "Please set a password!": "Prosím, nastavte si heslo!", + "You have successfully set a password!": "Ǔspešne ste si nastavili heslo!", + "Explore Room State": "Preskúmať Stav Miestnosti", + "Source URL": "Pôvodná URL", + "Messages sent by bot": "Správy odosielané robotmi", + "Filter results": "Filtrovať výsledky", + "Members": "Členovia", + "No update available.": "K dispozícii nie je žiadna aktualizácia.", + "Noisy": "Hlučné", + "Failed to get protocol list from Home Server": "Nepodarilo sa získať zoznam protokolov z domovského servera", + "Collecting app version information": "Získavajú sa informácie o verzii aplikácii", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Vymazať alias %(alias)s a odstrániť miestnosť %(name)s z adresára?", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Toto vám v budúcnosti umožní vrátiť sa k vašemu účtu aj po odhlásení, alebo tiež prihlásiť sa na iných zariadeniach.", + "Keywords": "Kľúčové slová", + "Enable notifications for this account": "Povoliť oznámenia pre tento účet", + "Directory": "Adresár", + "Invite to this community": "Pozvať do tejto komunity", + "Failed to get public room list": "Nepodarilo sa získať zoznam verejných miestností", + "Search…": "Hľadať…", + "Messages containing keywords": "Správy obsahujúce kľúčové slová", + "Error saving email notification preferences": "Chyba pri ukladaní nastavení oznamovania emailom", + "Tuesday": "Utorok", + "Enter keywords separated by a comma:": "Zadajte kľúčové slová oddelené čiarkou:", + "Forward Message": "Preposlať správu", + "Remove %(name)s from the directory?": "Odstrániť miestnosť %(name)s z adresára?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot sa spolieha na mnohé pokročilé vlastnosti prehliadača internetu, a niektoré z nich sú vo vašom prehliadači experimentálne alebo nie sú k dispozícii vôbec.", + "Event sent!": "Udalosť odoslaná!", + "Preparing to send logs": "príprava odoslania záznamov", + "Enable desktop notifications": "Povoliť oznámenia na pracovnej ploche", + "Explore Account Data": "Preskúmať Údaje účtu", + "All messages (noisy)": "Všetky správy (hlučné)", + "Saturday": "Sobota", + "Remember, you can always set an email address in user settings if you change your mind.": "Všimnite si, Emailovú adresu môžete pridať aj neskôr v časti nastavenia, ak zmeníte svoj názor.", + "Direct Chat": "Priama konverzácia", + "The server may be unavailable or overloaded": "Server môže byť nedostupný alebo preťažený", + "Reject": "Odmietnuť", + "Failed to set Direct Message status of room": "Nepodarilo sa nastaviť stav miestnosti priama konverzácia", + "Monday": "Pondelok", + "Remove from Directory": "Odstrániť z adresára", + "Enable them now": "Povolte si ich teraz", + "Messages containing my user name": "Správy obsahujúce moje používateľské meno", + "Toolbox": "Nástroje", + "Collecting logs": "Získavajú sa záznamy", + "more": "viac", + "GitHub issue link:": "Odkaz hlásenia na Github:", + "Search for a room": "Vyhľadať miestnosť", + "You must specify an event type!": "Musíte nastaviť typ udalosti!", + "(HTTP status %(httpStatus)s)": "(HTTP status %(httpStatus)s)", + "All Rooms": "Vo všetkych miestnostiach", + "State Key": "State Key", + "Please install Chrome or Firefox for the best experience.": "Aby ste s používania mali čo možno najlepší dojem, nainštalujte si Chrome alebo Firefox.", + "Wednesday": "Streda", + "Quote": "Citácia", + "Send logs": "Zahrnúť záznamy", + "All messages": "Všetky správy", + "Call invitation": "Audio / Video hovory", + "Messages containing my display name": "Správy obsahujúce moje zobrazované meno", + "You have successfully set a password and an email address!": "Úspešne si si nastavili heslo aj emailovú adresu!", + "Failed to send custom event.": "Odoslanie vlastnej udalosti zlyhalo.", + "What's new?": "Čo je nové?", + "Notify me for anything else": "Oznamovať mi všetko ostatné", + "When I'm invited to a room": "Pozvania vstúpiť do miestnosti", + "Click here to create a GitHub issue.": "Kliknutím sem nám pošlete hlásenie o chybe cez Github.", + "Can't update user notification settings": "Nie je možné aktualizovať používateľské nastavenia oznamovania", + "Notify for all other messages/rooms": "oznamovať všetky ostatné správy / miestnosti", + "Unable to look up room ID from server": "Nie je možné vyhľadať ID miestnosti na servery", + "Couldn't find a matching Matrix room": "Nie je možné nájsť zodpovedajúcu Matrix miestnosť", + "Invite to this room": "Pozvať do tejto miestnosti", + "You cannot delete this message. (%(code)s)": "Nemôžete vymazať túto správu. (%(code)s)", + "Thursday": "Štvrtok", + "I understand the risks and wish to continue": "Rozumiem rizikám a želám si pokračovať", + "Logs sent": "Záznamy boli odoslané", + "Back": "Naspäť", + "Reply": "Odpovedať", + "Show message in desktop notification": "Zobraziť text správy v oznámení na pracovnej ploche", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Ladiace záznamy obsahujú údaje o používaní aplikácii, vrátane vašeho používateľského mena, názvy a aliasy miestností a komunít, ku ktorým ste sa pripojili a mená ostatných používateľov. Tieto záznamy neobsahujú samotný obsah vašich správ.", + "Unhide Preview": "Zobraziť náhľad", + "Unable to join network": "Nie je možné sa pripojiť k sieti", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Tieto nastavenia oznámení sa použijú aj napriek tomu, že ich nemôžete meniť cez Riot. Pravdepodobne ste si ich nastavili v inej aplikácii", + "Sorry, your browser is not able to run Riot.": "Prepáčte, vo vašom prehliadači nie je možné spustiť Riot.", + "Messages in group chats": "Správy v skupinových konverzáciách", + "Yesterday": "Včera", + "Error encountered (%(errorDetail)s).": "Vyskytla sa chyba (%(errorDetail)s).", + "Event Type": "Typ Udalosti", + "Low Priority": "Nízka priorita", + "What's New": "Čo Je Nové", + "Set Password": "Nastaviť Heslo", + "An error occurred whilst saving your email notification preferences.": "Počas ukladania vašich nastavení oznamovania emailom sa vyskytla chyba.", + "Enable audible notifications in web client": "Povoliť zvukové oznámenia vo webovom klientovi", + "Permalink": "Trvalý odkaz", + "Off": "Zakázané", + "Riot does not know how to join a room on this network": "Riot nedokáže vstúpiť do miestnosti na tejto sieti", + "Mentions only": "Len zmienky", + "You can now return to your account after signing out, and sign in on other devices.": "Odteraz sa budete k svojmu účtu vedieť vrátiť aj po odhlásení, alebo tiež prihlásiť na iných zariadeniach.", + "Enable email notifications": "Povoliť oznamovanie emailom", + "Login": "Prihlásiť", + "Download this file": "Stiahnuť tento súbor", + "Pin Message": "Pripnúť správu", + "Failed to change settings": "Nepodarilo sa zmeniť nastavenia", + "View Community": "Zobraziť komunitu", + "%(count)s Members|one": "%(count)s Člen", + "Developer Tools": "Vývojárske Nástroje", + "View Source": "Zobraziť zdroj", + "Event Content": "Obsah Udalosti", + "Thank you!": "Ďakujeme!", + "#example": "#príklad", + "Collapse panel": "Zbaliť panel", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Vo vašom súčasnom prehliadači nemusí Riot vizerať ani fungovať správne a niektoré alebo všetky vlastnosti môžu chýbať. Ak to chcete vyskúšať, môžete pokračovať, no pri riešení problémov s tým spojených si budete musieť poradiť na vlastnú päsť!", + "Checking for an update...": "Kontrola dostupnosti aktualizácie...", + "There are advanced notifications which are not shown here": "Niektoré pokročilé oznámenia nemôžu byť zobrazené" } diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index a6d8ab8540..87d5ec782e 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -172,7 +172,6 @@ "Failed to join room": "Нисам успео да уђем у собу", "Message Replies": "Одговори", "Message Pinning": "Закачене поруке", - "Presence Management": "Управљање присутношћу", "Tag Panel": "Означи површ", "Disable Emoji suggestions while typing": "Онемогући предлагање емоџија приликом куцања", "Use compact timeline layout": "Користи збијени распоред временске линије", @@ -304,8 +303,6 @@ "Hangup": "Спусти слушалицу", "Voice call": "Гласовни позив", "Video call": "Видео позив", - "Hide Apps": "Сакриј апликације", - "Show Apps": "Прикажи апликације", "Upload file": "Отпреми датотеку", "Show Text Formatting Toolbar": "Прикажи алатницу за форматирање текста", "Send an encrypted reply…": "Пошаљи шифровани одговор…", @@ -744,7 +741,6 @@ "Leave Community": "Напусти заједницу", "Leave %(groupName)s?": "Напустити %(groupName)s?", "Leave": "Напусти", - "Unable to leave room": "Не могу да напустим собу", "Community Settings": "Подешавања заједнице", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Ове собе су приказане члановима заједнице на страници заједнице. Чланови заједнице могу приступити собама кликом на њих.", "Add rooms to this community": "Додај собе у ову заједницу", @@ -766,8 +762,6 @@ "Failed to leave room": "Нисам успео да напустим собу", "Signed Out": "Одјављен", "For security, this session has been signed out. Please sign in again.": "Зарад безбедности, одјављени сте из ове сесије. Пријавите се поново.", - "Cryptography data migrated": "Криптографски подаци су пренесени", - "A one-off migration of cryptography data has been performed. End-to-end encryption will not work if you go back to an older version of Riot. If you need to use end-to-end cryptography on an older version, log out of Riot first. To retain message history, export and re-import your keys.": "Једноструко преношење криптографских података је обављено. Шифровање с краја на крај неће радити ако се вратите на старије издање Riot-а. Ако вам треба шифровање с краја на крај на старијем издању, прво се одјавите из Riot-а. Да бисте задржали историјат порука, извезите па поново увезите ваше кључеве.", "Old cryptography data detected": "Нађени су стари криптографски подаци", "The platform you're on": "Платформа коју користите", "The version of Riot.im": "Riot.im издање", @@ -855,9 +849,6 @@ "Device ID:": "ИБ уређаја:", "Device key:": "Кључ уређаја:", "Ignored Users": "Занемарени корисници", - "Bug Report": "Извештај о грешци", - "Found a bug?": "Нашли сте грешку?", - "Report it": "Пријавите је", "Riot collects anonymous analytics to allow us to improve the application.": "Riot прикупља анонимне податке о коришћењу да бисмо побољшали апликацију.", "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Приватност је веома важна нама те не сакупљамо било какве податке личне природе у нашој аналитици.", "Learn more about how we use analytics.": "Сазнајте више о нашем начину употребе аналитике.", @@ -994,5 +985,151 @@ "Key request sent.": "Захтев за дељење кључа послат.", "Re-request encryption keys from your other devices.": "Поново затражи кључеве за шифровање са осталих ваших уређаја.", "%(user)s is a %(userRole)s": "Корисник %(user)s је у улози %(userRole)s", - "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Да бисте поставили филтер, повуците аватар заједнице на површ филтрирања скроз на леву страну екрана. Можете кликнути на аватар у површи филтрирања било када да бисте видели само собе и особе везане за ту заједницу." + "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Да бисте поставили филтер, повуците аватар заједнице на површ филтрирања скроз на леву страну екрана. Можете кликнути на аватар у површи филтрирања било када да бисте видели само собе и особе везане за ту заједницу.", + "Fetching third party location failed": "Добављање локације треће стране није успело", + "A new version of Riot is available.": "Ново издање RIot-а је доступно.", + "Couldn't load home page": "Нисам могао да учитам почетну страну", + "Send Account Data": "Пошаљи податке налога", + "All notifications are currently disabled for all targets.": "Сва обавештења су тренутно онемогућена за све циљеве.", + "Uploading report": "Отпремам извештај", + "Sunday": "Недеља", + "Notification targets": "Циљеви обавештења", + "Today": "Данас", + "Files": "Датотеке", + "You are not receiving desktop notifications": "Не примате стона обавештења", + "Friday": "Петак", + "Update": "Ажурирај", + "Unable to fetch notification target list": "Не могу да досегнем списак циљева за обавештења", + "Add an email address above to configure email notifications": "Додајте мејл адресу изнад да бисте подесили мејл обавештења", + "Expand panel": "Прошири површ", + "On": "Укључено", + "%(count)s Members|other": "%(count)s чланова", + "Filter room names": "Филтрирај називе соба", + "Changelog": "Записник о изменама", + "Waiting for response from server": "Чекам на одговор са сервера", + "Uploaded on %(date)s by %(user)s": "Отпремљено датума %(date)s од корисника %(user)s", + "Send Custom Event": "Пошаљи прилагођени догађај", + "Off": "Искључено", + "Advanced notification settings": "Напредна подешавања обавештења", + "delete the alias.": "обриши алијас.", + "To return to your account in future you need to set a password": "Да бисте се вратили на ваш налог у будућности, морате поставити лозинку", + "Forget": "Заборави", + "Hide panel": "Сакриј површ", + "You cannot delete this image. (%(code)s)": "Не можете обрисати ову слику. (%(code)s)", + "Cancel Sending": "Откажи слање", + "This Room": "Ова соба", + "The Home Server may be too old to support third party networks": "Кућни сервер је можда сувише застарео да би подржао мреже трећих страна", + "Room not found": "Соба није пронађена", + "Downloading update...": "Преузимам ажурирање...", + "Messages in one-to-one chats": "Поруке у један-на-један ћаскањима", + "Unavailable": "Недоступан", + "View Decrypted Source": "Погледај дешифровани извор", + "Failed to update keywords": "Нисам успео да ажурирам кључне речи", + "remove %(name)s from the directory.": "уклони %(name)s из фасцикле.", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Обавештења за следеће кључне речи прате правила која не могу бити приказана овде:", + "Safari and Opera work too.": "Сафари и Опера такође раде.", + "Please set a password!": "Поставите лозинку!", + "You have successfully set a password!": "Успешно сте поставили лозинку!", + "Explore Room State": "Истражи стање собе", + "Source URL": "Адреса извора", + "Messages sent by bot": "Поруке послате од бота", + "Filter results": "Филтрирај резултате", + "Members": "Чланови", + "No update available.": "Нема нових ажурирања.", + "Noisy": "Бучно", + "Failed to get protocol list from Home Server": "Нисам успео да добијем списак протокола од кућног сервера", + "Collecting app version information": "Прикупљам податке о издању апликације", + "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Обрисати алијас собе %(alias)s и уклонити %(name)s из фасцикле?", + "This will allow you to return to your account after signing out, and sign in on other devices.": "Ово ће вам омогућити да се вратите у ваш налог након што се одјавите и пријавите, на другим уређајима.", + "Keywords": "Кључне речи", + "Enable notifications for this account": "Омогући обавештења за овај налог", + "Directory": "Фасцикла", + "Invite to this community": "Позови у ову заједницу", + "Failed to get public room list": "Нисам успео да добавим списак јавних соба", + "Search…": "Претрага…", + "Messages containing keywords": "Поруке које садрже кључне речи", + "Error saving email notification preferences": "Грешка при чувању поставки мејл обавештења", + "Tuesday": "Уторак", + "Enter keywords separated by a comma:": "Унесите кључне речи одвојене зарезима:", + "Forward Message": "Проследи поруку", + "Remove %(name)s from the directory?": "Уклонити %(name)s из фасцикле?", + "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot користи напредне могућности прегледача од којих неке нису доступне или су у пробној фази, у вашем прегледачу.", + "Event sent!": "Догађај је послат!", + "Explore Account Data": "Истражи податке налога", + "All messages (noisy)": "Све поруке (гласно)", + "Saturday": "Субота", + "Remember, you can always set an email address in user settings if you change your mind.": "Запамтите, увек можете поставити мејл адресу у корисничким подешавањима, уколико се предомислите.", + "Direct Chat": "Директно ћаскање", + "The server may be unavailable or overloaded": "Сервер је можда недоступан или преоптерећен", + "Reject": "Одбаци", + "Failed to set Direct Message status of room": "Нисам успео да подесим стање директне поруке собе", + "Monday": "Понедељак", + "Remove from Directory": "Уклони из фасцикле", + "Enable them now": "Омогућите их сада", + "Messages containing my user name": "Поруке које садрже моје корисничко име", + "Toolbox": "Алатница", + "Collecting logs": "Прикупљам записнике", + "more": "више", + "Search for a room": "Потражи собу", + "You must specify an event type!": "Морате навести врсту догађаја!", + "(HTTP status %(httpStatus)s)": "(HTTP стање %(httpStatus)s)", + "All Rooms": "Све собе", + "State Key": "Кључ стања", + "Please install Chrome or Firefox for the best experience.": "Инсталирајте Хром (Chrome) или Фајерфокс (Firefox) за најбољи угођај.", + "Wednesday": "Среда", + "Send logs": "Пошаљи записнике", + "All messages": "Све поруке", + "Call invitation": "Позивница за позив", + "Messages containing my display name": "Поруке које садрже моје приказно име", + "You have successfully set a password and an email address!": "Успешно сте поставили лозинку и мејл адресу!", + "Failed to send custom event.": "Нисам успео да пошаљем прилагођени догађај.", + "What's new?": "Шта је ново?", + "Notify me for anything else": "Обавести ме за било шта друго", + "When I'm invited to a room": "Када сам позван у собу", + "Can't update user notification settings": "Не могу да ажурирам корисничка подешавања обавештења", + "Notify for all other messages/rooms": "Обавести за све друге поруке и собе", + "Unable to look up room ID from server": "Не могу да погледам ИБ собе на серверу", + "Couldn't find a matching Matrix room": "Не могу да нађем одговарајућу Матрикс собу", + "Invite to this room": "Позови у ову собу", + "You cannot delete this message. (%(code)s)": "Не можете обрисати ову поруку. (%(code)s)", + "Thursday": "Четвртак", + "I understand the risks and wish to continue": "Разумем опасност и желим да наставим", + "Back": "Назад", + "Reply": "Одговори", + "Show message in desktop notification": "Прикажи поруку у стоном обавештењу", + "Unhide Preview": "Откриј преглед", + "Unable to join network": "Не могу да приступим мрежи", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Можда сте их подесили у неком другом клијенту а не Riot-у. Не можете их преправљати у Riot-у али се и даље примењују", + "Sorry, your browser is not able to run Riot.": "Нажалост, ваш прегледач не може да покреће Riot.", + "Messages in group chats": "Поруке у групним ћаскањима", + "Yesterday": "Јуче", + "Error encountered (%(errorDetail)s).": "Догодила се грешка (%(errorDetail)s).", + "Event Type": "Врста догађаја", + "Low Priority": "Најмања важност", + "What's New": "Шта је ново", + "Set Password": "Постави лозинку", + "An error occurred whilst saving your email notification preferences.": "Догодила се грешка при чувању ваших поставки мејл обавештења.", + "Enable audible notifications in web client": "Омогући звучна обавештења у веб клијенту", + "Permalink": "Трајна веза", + "Resend": "Поново пошаљи", + "Riot does not know how to join a room on this network": "Riot не зна како да приступи соби на овој мрежи", + "Mentions only": "Само спомињања", + "You can now return to your account after signing out, and sign in on other devices.": "Можете се вратити у ваш налог након што се одјавите и пријавите поново, на другим уређајима.", + "Enable desktop notifications": "Омогући стона обавештења", + "Enable email notifications": "Омогући мејл обавештења", + "Login": "Пријава", + "Download this file": "Преузми ову датотеку", + "Pin Message": "Закачи поруку", + "Failed to change settings": "Нисам успео да променим подешавања", + "View Community": "Погледај заједницу", + "%(count)s Members|one": "%(count)s члан", + "Developer Tools": "Програмерске алатке", + "View Source": "Погледај извор", + "Event Content": "Садржај догађаја", + "Thank you!": "Хвала вам!", + "#example": "#пример", + "Collapse panel": "Скупи површ", + "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Са вашим тренутним прегледачем изглед и угођај ове апликације може бити скроз неправилан и неке могућности можда неће радити. Уколико желите да ипак пробате, можете наставити али ћете бити без подршке за било које проблеме на које налетите!", + "Checking for an update...": "Проверавам ажурирања...", + "There are advanced notifications which are not shown here": "Постоје напредна обавештења која нису приказана овде" } From 0f11bc62cc9014297bbf800f6d9871e0a570524c Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@googlemail.com> Date: Mon, 23 Apr 2018 10:58:39 +0100 Subject: [PATCH 0838/1160] undo code style change --- src/HtmlUtils.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index 17566957c7..8d352eb4f6 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -479,11 +479,9 @@ export function bodyToHtml(content, highlights, opts={}) { 'markdown-body': isHtml, }); - if (isHtml) { - return ; - } - - return { strippedBody }; + return isHtml ? + : + { strippedBody }; } export function emojifyText(text) { From f5956c87f677af268997b8d0af21459d39492b50 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 23 Apr 2018 18:14:59 +0100 Subject: [PATCH 0839/1160] Bind onImageError in constructor Tt uses `this` but wasn't bound anywhere so the error handler was just throwing an exception. --- src/components/views/messages/MImageBody.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index 6a95b3c16e..d5ce533bda 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -49,6 +49,7 @@ export default class extends React.Component { super(props); this.onAction = this.onAction.bind(this); + this.onImageError = this.onImageError.bind(this); this.onImageEnter = this.onImageEnter.bind(this); this.onImageLeave = this.onImageLeave.bind(this); this.onClientSync = this.onClientSync.bind(this); From b6157499a8fc42087319ad044d2582158f4d205d Mon Sep 17 00:00:00 2001 From: Szimszon Date: Mon, 23 Apr 2018 15:40:50 +0000 Subject: [PATCH 0840/1160] Translated using Weblate (Hungarian) Currently translated at 100.0% (1161 of 1161 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 792fa2735f..77b2a2d37d 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -362,7 +362,7 @@ "This email address was not found": "Az e-mail cím nem található", "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": "Titoktartási figyelmeztetés", + "Privacy warning": "Adatvédelmi figyelmeztetés", "The file '%(fileName)s' exceeds this home server's size limit for uploads": "'%(fileName)s' fájl túllépte a Saját 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", From 166474d869d70284a9b864adb27470b875e4ff3e Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Tue, 24 Apr 2018 10:00:40 +0000 Subject: [PATCH 0841/1160] Translated using Weblate (Russian) Currently translated at 100.0% (1161 of 1161 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index e1d2cde38c..94c8a353ae 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -159,7 +159,7 @@ "Failed to lookup current room": "Не удалось выполнить поиск текущий комнаты", "Failed to send request.": "Не удалось отправить запрос.", "Failed to set up conference call": "Не удалось настроить групповой вызов", - "Failed to verify email address: make sure you clicked the link in the email": "Не удалось проверить адрес email: убедитесь, что вы перешли по ссылке в письме", + "Failed to verify email address: make sure you clicked the link in the email": "Не удалось проверить email-адрес: убедитесь, что вы перешли по ссылке в письме", "Failure to create room": "Не удалось создать комнату", "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s с %(fromPowerLevel)s на %(toPowerLevel)s", "click to reveal": "нажмите для открытия", @@ -337,7 +337,7 @@ "Success": "Успех", "The default role for new room members is": "Роль по умолчанию для новых участников комнаты", "The main address for this room is": "Основной адрес для этой комнаты", - "This email address is already in use": "Этот адрес email уже используется", + "This email address is already in use": "Этот email-адрес уже используется", "This email address was not found": "Этот адрес электронной почты не найден", "The email address linked to your account must be entered.": "Необходимо ввести адрес электронной почты, связанный с вашей учетной записью.", "The file '%(fileName)s' failed to upload": "Не удалось отправить файл '%(fileName)s'", @@ -368,7 +368,7 @@ "numbullet": "нумерованный список", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Не удается подключиться к домашнему серверу через HTTP, так как в адресной строке браузера указан URL HTTPS. Используйте HTTPS или либо включите небезопасные сценарии.", "Dismiss": "Отклонить", - "Custom Server Options": "Настраиваемые параметры сервера", + "Custom Server Options": "Выбор другого сервера", "Mute": "Беззвучный", "Operation failed": "Сбой операции", "powered by Matrix": "Основано на Matrix", @@ -960,7 +960,7 @@ "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Если на этой странице содержатся идентифицируемые сведения, например номер, идентификатор пользователя или группы, эти данные удаляются перед отправкой на сервер.", "The platform you're on": "Используемая платформа", "The version of Riot.im": "Версия Riot.im", - "Whether or not you're logged in (we don't record your user name)": "Независимо от того, вошли вы или нет (мы не записываем ваше имя пользователя)", + "Whether or not you're logged in (we don't record your user name)": "Независимо от того, вошли вы или нет (мы не храним ваше имя пользователя)", "Your language of choice": "Выбранный вами язык", "Your homeserver's URL": "URL-адрес домашнего сервера", "Your identity server's URL": "URL-адрес вашего идентификационного сервера", From 5732b3ac0e73248695270f8f160528308e40f9de Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Tue, 24 Apr 2018 10:01:22 +0000 Subject: [PATCH 0842/1160] Translated using Weblate (Russian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (1161 of 1161 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ по аналогии с "the platform you're on" — там нет местоимения --- src/i18n/strings/ru.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 94c8a353ae..eae84df3f8 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -961,7 +961,7 @@ "The platform you're on": "Используемая платформа", "The version of Riot.im": "Версия Riot.im", "Whether or not you're logged in (we don't record your user name)": "Независимо от того, вошли вы или нет (мы не храним ваше имя пользователя)", - "Your language of choice": "Выбранный вами язык", + "Your language of choice": "Выбранный язык", "Your homeserver's URL": "URL-адрес домашнего сервера", "Your identity server's URL": "URL-адрес вашего идентификационного сервера", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s", From 20454b92ab3564f8634b84f8a3176012a0c7853f Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Tue, 24 Apr 2018 10:10:41 +0000 Subject: [PATCH 0843/1160] Translated using Weblate (Russian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (1161 of 1161 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ очень криво, но не могу придумать ничего лучше --- src/i18n/strings/ru.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index eae84df3f8..e667aaaf88 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -960,13 +960,13 @@ "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Если на этой странице содержатся идентифицируемые сведения, например номер, идентификатор пользователя или группы, эти данные удаляются перед отправкой на сервер.", "The platform you're on": "Используемая платформа", "The version of Riot.im": "Версия Riot.im", - "Whether or not you're logged in (we don't record your user name)": "Независимо от того, вошли вы или нет (мы не храним ваше имя пользователя)", + "Whether or not you're logged in (we don't record your user name)": "Вошли вы в систему или нет (мы не храним ваше имя пользователя)", "Your language of choice": "Выбранный язык", "Your homeserver's URL": "URL-адрес домашнего сервера", "Your identity server's URL": "URL-адрес вашего идентификационного сервера", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s", - "Which officially provided instance you are using, if any": "Какую официально выпущенную версию вы используете", - "Whether or not you're using the Richtext mode of the Rich Text Editor": "Независимо от того, используете ли вы режим Richtext в редакторе Rich Text Editor", + "Which officially provided instance you are using, if any": "Каким официально поддерживаемым клиентом вы пользуетесь (если пользуетесь)", + "Whether or not you're using the Richtext mode of the Rich Text Editor": "Используете ли вы режим Richtext в редакторе Rich Text Editor", "This room is not public. You will not be able to rejoin without an invite.": "Эта комната не является публичной. Вы не сможете войти без приглашения.", "Show devices, send anyway or cancel.": "Показать устройства, отправить в любом случае или отменить.", "Community IDs cannot not be empty.": "ID сообществ не могут быть пустыми.", From 4ec1973888e78e2f4d2b324a0736fc6634d26e6e Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Tue, 24 Apr 2018 12:33:06 +0000 Subject: [PATCH 0844/1160] Translated using Weblate (Russian) Currently translated at 100.0% (1161 of 1161 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 206 +++++++++++++++++++-------------------- 1 file changed, 103 insertions(+), 103 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index e667aaaf88..9808a2043a 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -32,14 +32,14 @@ "Deactivate Account": "Деактивировать учетную запись", "Deactivate my account": "Деактивировать мою учетную запись", "Decryption error": "Ошибка расшифровки", - "Default": "По умолчанию", + "Default": "Обычный пользователь", "Deops user with given id": "Снимает полномочия оператора с пользователя с заданным ID", "Device ID": "ID устройства", "Devices will not yet be able to decrypt history from before they joined the room": "Устройства пока не могут дешифровать историю до их входа в комнату", "Display name": "Отображаемое имя", "Displays action": "Отображение действий", "Ed25519 fingerprint": "Ed25519 отпечаток", - "Email, name or matrix ID": "Email, имя или matrix ID", + "Email, name or matrix ID": "Email-адрес, имя или идентификатор", "Emoji": "Смайлы", "Encrypted messages will not be visible on clients that do not yet implement encryption": "Зашифрованные сообщения не будут видны в клиентах, которые еще не подключили шифрование", "Encrypted room": "Зашифрованная комната", @@ -67,7 +67,7 @@ "I have verified my email address": "Я подтвердил свой адрес email", "Import E2E room keys": "Импорт ключей сквозного шифрования", "Invalid Email Address": "Недопустимый адрес email", - "Invite new room members": "Пригласить новых участников в комнату", + "Invite new room members": "Пригласить в комнату новых участников", "Invites": "Приглашает", "Invites user with given id to current room": "Приглашает пользователя с заданным ID в текущую комнату", "Sign in with": "Войти, используя", @@ -101,8 +101,8 @@ "Return to login screen": "Вернуться к экрану входа", "Send Reset Email": "Отправить письмо со ссылкой для сброса пароля", "Settings": "Настройки", - "Start a chat": "Начать чат", - "Start Chat": "Начать чат", + "Start a chat": "Начать разговор", + "Start Chat": "Начать разговор", "Unable to add email address": "Не удается добавить адрес email", "Unable to remove contact information": "Не удалось удалить контактную информацию", "Unable to verify email address.": "Не удалось проверить адрес email.", @@ -123,13 +123,13 @@ "verified": "проверенный", "Video call": "Видеозвонок", "Voice call": "Голосовой вызов", - "VoIP conference finished.": "VoIP-конференция закончилась.", - "VoIP conference started.": "VoIP-конференция началась.", + "VoIP conference finished.": "Конференц-звонок окончен.", + "VoIP conference started.": "Конференц-звонок начался.", "(warning: cannot be disabled again!)": "(предупреждение: отключить будет невозможно!)", "Warning!": "Внимание!", "Who can access this room?": "Кто может получить доступ к этой комнате?", "Who can read history?": "Кто может читать историю?", - "Who would you like to add to this room?": "Кого бы вы хотели добавить в эту комнату?", + "Who would you like to add to this room?": "Кого бы вы хотели пригласить в эту комнату?", "Who would you like to communicate with?": "С кем бы вы хотели связаться?", "You do not have permission to post to this room": "Вы не можете писать в эту комнату", "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": "Вы вышли из всех устройств и больше не будете получать push-уведомления. Чтобы повторно активировать уведомления, войдите снова на каждом из устройств", @@ -141,41 +141,41 @@ "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s принял приглашение от %(displayName)s.", "Active call": "Активный вызов", "%(names)s and %(lastPerson)s are typing": "%(names)s и %(lastPerson)s печатает", - "%(senderName)s answered the call.": "%(senderName)s ответил на звонок.", + "%(senderName)s answered the call.": "%(senderName)s ответил(а) на звонок.", "%(senderName)s banned %(targetName)s.": "%(senderName)s заблокировал(а) %(targetName)s.", - "Call Timeout": "Время ожидания вызова", - "%(senderName)s changed their profile picture.": "%(senderName)s изменил изображение профиля.", - "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s изменил(а) уровень доступа для %(powerLevelDiffText)s.", + "Call Timeout": "Нет ответа", + "%(senderName)s changed their profile picture.": "%(senderName)s изменил(а) свой аватар.", + "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s изменил(а) уровни прав %(powerLevelDiffText)s.", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s изменил(а) название комнаты на %(roomName)s.", - "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s изменил тему на %(topic)s.", - "Conference call failed.": "Не удалось выполнить групповой вызов.", - "Conference calling is in development and may not be reliable.": "Групповые вызовы находятся в разработке и могут быть нестабильны.", - "Conference calls are not supported in encrypted rooms": "Групповые вызовы не поддерживаются в зашифрованных комнатах", - "Conference calls are not supported in this client": "Групповые вызовы в этом клиенте не поддерживаются", - "/ddg is not a command": "/ddg не команда", + "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s изменил(а) тему комнаты на \"%(topic)s\".", + "Conference call failed.": "Сбой конференц-звонка.", + "Conference calling is in development and may not be reliable.": "Конференц-связь находится в разработке и может не работать.", + "Conference calls are not supported in encrypted rooms": "Конференц-связь не поддерживается в зашифрованных комнатах", + "Conference calls are not supported in this client": "Конференц-связь в этом клиенте не поддерживается", + "/ddg is not a command": "/ddg — это не команда", "Drop here to tag %(section)s": "Перетащите сюда для тега %(section)s", - "%(senderName)s ended the call.": "%(senderName)s завершил звонок.", + "%(senderName)s ended the call.": "%(senderName)s завершил(а) звонок.", "Existing Call": "Текущий вызов", - "Failed to lookup current room": "Не удалось выполнить поиск текущий комнаты", + "Failed to lookup current room": "Не удалось найти текущую комнату", "Failed to send request.": "Не удалось отправить запрос.", - "Failed to set up conference call": "Не удалось настроить групповой вызов", + "Failed to set up conference call": "Не удалось сделать конференц-звонок", "Failed to verify email address: make sure you clicked the link in the email": "Не удалось проверить email-адрес: убедитесь, что вы перешли по ссылке в письме", "Failure to create room": "Не удалось создать комнату", - "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s с %(fromPowerLevel)s на %(toPowerLevel)s", + "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "для %(userId)s с %(fromPowerLevel)s на %(toPowerLevel)s", "click to reveal": "нажмите для открытия", "%(senderName)s invited %(targetName)s.": "%(senderName)s приглашает %(targetName)s.", "%(displayName)s is typing": "%(displayName)s печатает", - "%(targetName)s joined the room.": "%(targetName)s вошел(ла) в комнату.", - "%(senderName)s kicked %(targetName)s.": "%(senderName)s выкинул %(targetName)s.", - "%(targetName)s left the room.": "%(targetName)s покинул комнату.", - "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s сделал(а) историю комнаты видимой для всех участников комнаты с момента их приглашения.", - "%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s сделал(а) историю комнаты видимой для всех участников комнаты с момента их входа.", - "%(senderName)s made future room history visible to all room members.": "%(senderName)s сделал(а) историю комнаты видимой для всех участников комнаты.", - "%(senderName)s made future room history visible to anyone.": "%(senderName)s сделал(а) историю комнаты видимой для всех.", - "%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s сделал(а) историю комнаты видимой для неизвестного (%(visibility)s).", + "%(targetName)s joined the room.": "%(targetName)s вошёл(-ла) в комнату.", + "%(senderName)s kicked %(targetName)s.": "%(senderName)s исключил(а) %(targetName)s из комнаты.", + "%(targetName)s left the room.": "%(targetName)s покинул(а) комнату.", + "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s сделал(а) историю разговора видимой для всех собеседников с момента их приглашения.", + "%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s сделал(а) историю разговора видимой для всех собеседников с момента их входа в комнату.", + "%(senderName)s made future room history visible to all room members.": "%(senderName)s сделал(а) историю разговора видимой для всех собеседников.", + "%(senderName)s made future room history visible to anyone.": "%(senderName)s сделал(а) историю разговора видимой для всех.", + "%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s сделал(а) историю комнаты видимой в неизвестном режиме (%(visibility)s).", "Missing room_id in request": "Отсутствует room_id в запросе", "Missing user_id in request": "Отсутствует user_id в запросе", - "Must be viewing a room": "Необходимо посмотреть комнату", + "Must be viewing a room": "Вы должны просматривать комнату", "(not supported by this browser)": "(не поддерживается этим браузером)", "Connectivity to the server has been lost.": "Связь с сервером потеряна.", "Sent messages will be stored until your connection has returned.": "Отправленные сообщения будут сохранены, пока соединение не восстановится.", @@ -197,25 +197,25 @@ "Encrypt room": "Шифрование комнаты", "%(weekDayName)s %(time)s": "%(weekDayName)s %(time)s", "Upload an avatar:": "Загрузите аватар:", - "You need to be logged in.": "Вы должны быть авторизованы.", + "You need to be logged in.": "Вы должны войти в систему.", "You need to be able to invite users to do that.": "Для этого вы должны иметь возможность приглашать пользователей.", - "You cannot place VoIP calls in this browser.": "VoIP звонки не поддерживаются в этом браузере.", - "You are already in a call.": "Вы уже совершаете вызов.", + "You cannot place VoIP calls in this browser.": "Звонки не поддерживаются в этом браузере.", + "You are already in a call.": "Вы уже сделали звонок.", "You are trying to access %(roomName)s.": "Вы пытаетесь получить доступ к %(roomName)s.", - "You cannot place a call with yourself.": "Вы не можете сделать вызов самому себе.", - "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s отозвал %(targetName)s's приглашение.", - "Sep": "Сен.", - "Jan": "Янв.", - "Feb": "Фев.", - "Mar": "Мар.", - "Apr": "Апр.", + "You cannot place a call with yourself.": "Вы не можете позвонить самому себе.", + "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s отозвал(а) своё приглашение %(targetName)s.", + "Sep": "Сен", + "Jan": "Янв", + "Feb": "Фев", + "Mar": "Мар", + "Apr": "Апр", "May": "Май", - "Jun": "Июн.", - "Jul": "Июл.", - "Aug": "Авг.", - "Oct": "Окт.", - "Nov": "Ноя.", - "Dec": "Дек.", + "Jun": "Июн", + "Jul": "Июл", + "Aug": "Авг", + "Oct": "Окт", + "Nov": "Ноя", + "Dec": "Дек", "%(weekDayName)s, %(monthName)s %(day)s %(time)s": "%(weekDayName)s, %(day)s %(monthName)s %(time)s", "Mon": "Пн", "Sun": "Вс", @@ -224,16 +224,16 @@ "Thu": "Чт", "Fri": "Пт", "Sat": "Сб", - "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Ваш адрес email, кажется, не связан с Matrix ID на этом домашнем сервере.", - "To use it, just wait for autocomplete results to load and tab through them.": "Для того, чтобы использовать эту функцию, просто подождите автозаполнения результатов, а затем используйте клавишу TAB для прокрутки.", - "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s включено сквозное шифрование (algorithm %(algorithm)s).", + "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Ваш email-адрес не связан ни с одним пользователем на этом сервере.", + "To use it, just wait for autocomplete results to load and tab through them.": "Чтобы воспользоваться этой функцией, дождитесь загрузки результатов в окне автодополнения, а затем используйте Tab для прокрутки.", + "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s включил(а) в комнате сквозное шифрование (алгоритм %(algorithm)s).", "%(senderName)s unbanned %(targetName)s.": "%(senderName)s разблокировал(а) %(targetName)s.", "Unable to capture screen": "Не удается сделать снимок экрана", "Unable to enable Notifications": "Не удалось включить уведомления", - "Upload Failed": "Сбой при отправке", + "Upload Failed": "Сбой отправки файла", "Usage": "Использование", "Use with caution": "Использовать с осторожностью", - "VoIP is unsupported": "VoIP не поддерживается", + "VoIP is unsupported": "Звонки не поддерживаются", "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Текстовое сообщение было отправлено на +%(msisdn)s. Введите проверочный код, который оно содержит", "and %(count)s others...|other": "и %(count)s других...", "and %(count)s others...|one": "и еще один...", @@ -301,19 +301,19 @@ "OK": "OK", "Only people who have been invited": "Только приглашенные люди", "Passwords can't be empty": "Пароли не могут быть пустыми", - "%(senderName)s placed a %(callType)s call.": "%(senderName)s выполнил %(callType)s вызов.", + "%(senderName)s placed a %(callType)s call.": "%(senderName)s начал(а) %(callType)s-звонок.", "Please check your email and click on the link it contains. Once this is done, click continue.": "Проверьте свою электронную почту и нажмите на содержащуюся ссылку. После этого нажмите кнопку Продолжить.", - "Power level must be positive integer.": "Уровень авторизации должен быть положительным целым числом.", + "Power level must be positive integer.": "Уровень прав должен быть положительным целым числом.", "Profile": "Профиль", "Reason": "Причина", - "%(targetName)s rejected the invitation.": "%(targetName)s отклонил приглашение.", + "%(targetName)s rejected the invitation.": "%(targetName)s отклонил(а) приглашение.", "Reject invitation": "Отклонить приглашение", "Remove Contact Information?": "Удалить контактную информацию?", - "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s удалил свое отображаемое имя (%(oldDisplayName)s).", - "%(senderName)s removed their profile picture.": "%(senderName)s удалил свое изображение профиля.", - "%(senderName)s requested a VoIP conference.": "%(senderName)s хочет начать VoIP-конференцию.", + "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s удалил(а) свое отображаемое имя (%(oldDisplayName)s).", + "%(senderName)s removed their profile picture.": "%(senderName)s удалил(а) свой аватар.", + "%(senderName)s requested a VoIP conference.": "%(senderName)s хочет начать конференц-звонок.", "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.": "Сброс пароля на данный момент сбрасывает ключи шифрования на всех устройствах, делая зашифрованную историю чатов нечитаемой. Чтобы избежать этого, экспортируйте ключи комнат и импортируйте их после сброса пароля. В будущем это будет исправлено.", - "Riot does not have permission to send you notifications - please check your browser settings": "У Riot нет разрешений на отправку уведомлений - проверьте настройки браузера", + "Riot does not have permission to send you notifications - please check your browser settings": "У Riot нет разрешения на отправку уведомлений — проверьте настройки браузера", "Riot was not given permission to send notifications - please try again": "Riot не получил разрешение на отправку уведомлений, пожалуйста, попробуйте снова", "riot-web version:": "версия riot-web:", "Room %(roomId)s not visible": "Комната %(roomId)s невидима", @@ -326,8 +326,8 @@ "Search failed": "Поиск не удался", "Sender device information": "Информация об устройстве отправителя", "Send Invites": "Отправить приглашения", - "%(senderDisplayName)s sent an image.": "%(senderDisplayName)s отправил изображение.", - "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s отправил(а) приглашение для %(targetDisplayName)s войти в комнату.", + "%(senderDisplayName)s sent an image.": "%(senderDisplayName)s отправил(а) изображение.", + "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s пригласил(а) %(targetDisplayName)s в комнату.", "Show panel": "Показать панель", "Sign in": "Войти", "Sign out": "Выйти", @@ -341,7 +341,7 @@ "This email address was not found": "Этот адрес электронной почты не найден", "The email address linked to your account must be entered.": "Необходимо ввести адрес электронной почты, связанный с вашей учетной записью.", "The file '%(fileName)s' failed to upload": "Не удалось отправить файл '%(fileName)s'", - "The remote side failed to pick up": "Вызываемый абонент не ответил", + "The remote side failed to pick up": "Собеседник не ответил на ваш звонок", "This room has no local addresses": "В этой комнате нет локальных адресов", "This room is not recognised.": "Эта комната не опознана.", "These are experimental features that may break in unexpected ways": "Это экспериментальные функции, которые могут себя вести неожиданным образом", @@ -397,7 +397,7 @@ "You may need to manually permit Riot to access your microphone/webcam": "Вам необходимо предоставить Riot доступ к микрофону или веб-камере вручную", "Anyone": "Все", "Are you sure you want to leave the room '%(roomName)s'?": "Вы уверены, что хотите покинуть '%(roomName)s'?", - "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s удалил имя комнаты.", + "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s удалил(а) имя комнаты.", "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Смена пароля на данный момент сбрасывает ключи сквозного шифрования на всех устройствах, делая зашифрованную историю чата нечитаемой. Чтобы избежать этого, экспортируйте ключи комнат и импортируйте их после смены пароля. В будущем это будет исправлено.", "Custom level": "Пользовательский уровень", "Device already verified!": "Устройство уже проверено!", @@ -434,12 +434,12 @@ "Server may be unavailable, overloaded, or you hit a bug.": "Сервер может быть недоступен, перегружен или возникла ошибка.", "Server unavailable, overloaded, or something else went wrong.": "Сервер может быть недоступен, перегружен или что-то пошло не так.", "Session ID": "ID сессии", - "%(senderName)s set a profile picture.": "%(senderName)s установил изображение профиля.", - "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s изменил отображаемое имя на %(displayName)s.", + "%(senderName)s set a profile picture.": "%(senderName)s установил(а) себе аватар.", + "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s изменил(а) отображаемое имя на %(displayName)s.", "Signed Out": "Выполнен выход", "Tagged as: ": "Теги: ", - "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Предоставленный ключ подписи соответствует ключу, полученному от %(userId)s с устройства %(deviceId)s. Устройство помечено как проверенное.", - "The file '%(fileName)s' exceeds this home server's size limit for uploads": "Файл '%(fileName)s' превышает предельный размер, допустимый к отправке на этом домашнем сервере", + "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Предоставленный вами ключ совпадает с ключом, полученным от %(userId)s с устройства %(deviceId)s. Это устройство помечено как проверенное.", + "The file '%(fileName)s' exceeds this home server's size limit for uploads": "Файл '%(fileName)s' слишком большой для отправки на этот сервер", "This Home Server does not support login using email address.": "Этот домашний сервер не поддерживает авторизацию с использованием адреса электронной почты.", "The visibility of existing history will be unchanged": "Видимость существующей истории не изменится", "This room is not accessible by remote Matrix servers": "Это комната недоступна с удаленных серверов Matrix", @@ -447,11 +447,11 @@ "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Попытка загрузить выбранный интервал истории чата этой комнаты не удалась, так как у вас нет разрешений на просмотр.", "Tried to load a specific point in this room's timeline, but was unable to find it.": "Попытка загрузить выбранный интервал истории чата этой комнаты не удалась, так как запрошенный элемент не найден.", "Unable to load device list": "Не удалось загрузить список устройств", - "Unknown (user, device) pair:": "Неизвестная пара (пользователь, устройство):", + "Unknown (user, device) pair:": "Неизвестная пара пользователь-устройство:", "Unmute": "Включить звук", "Unrecognised command:": "Нераспознанная команда:", - "Unrecognised room alias:": "Нераспознанный псевдоним комнаты:", - "Verified key": "Проверенный ключ", + "Unrecognised room alias:": "Нераспознанное имя комнаты:", + "Verified key": "Ключ проверен", "WARNING: Device already verified, but keys do NOT MATCH!": "ВНИМАНИЕ: устройство уже было проверено, однако ключи НЕ СОВПАДАЮТ!", "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "ВНИМАНИЕ: ОШИБКА ПРОВЕРКИ КЛЮЧЕЙ! Ключ подписи пользователя %(userId)s на устройстве %(deviceId)s — \"%(fprint)s\", и он не соответствует предоставленному ключу \"%(fingerprint)s\". Это может означать, что ваше общение перехватывается!", "You have disabled URL previews by default.": "Предварительный просмотр ссылок отключен по-умолчанию.", @@ -477,7 +477,7 @@ "Start new chat": "Начать новый чат", "Failed to invite": "Пригласить не удалось", "Failed to invite user": "Не удалось пригласить пользователя", - "Failed to invite the following users to the %(roomName)s room:": "Не удалось пригласить следующих пользователей в %(roomName)s:", + "Failed to invite the following users to the %(roomName)s room:": "Не удалось пригласить этих пользователей в %(roomName)s:", "Confirm Removal": "Подтвердите удаление", "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Вы действительно хотите удалить это событие? Обратите внимание, что если это смена названия комнаты или темы, то удаление отменит это изменение.", "Unknown error": "Неизвестная ошибка", @@ -621,9 +621,9 @@ "You have been kicked from %(roomName)s by %(userName)s.": "%(userName)s выгнал вас из %(roomName)s.", "You may wish to login with a different account, or add this email to this account.": "При желании вы можете войти в систему с другой учетной записью или добавить этот адрес email в эту учетную запись.", "Your home server does not support device management.": "Ваш домашний сервер не поддерживает управление устройствами.", - "(could not connect media)": "(подключение к СМИ не может быть установлено)", + "(could not connect media)": "(сбой подключения)", "(no answer)": "(нет ответа)", - "(unknown failure: %(reason)s)": "(неизвестная ошибка: %(reason)s", + "(unknown failure: %(reason)s)": "(неизвестная ошибка: %(reason)s)", "Disable Peer-to-Peer for 1:1 calls": "Отключить Peer-to-Peer для 1:1 звонков", "Not a valid Riot keyfile": "Недействительный файл ключа Riot", "Your browser does not support the required cryptography extensions": "Ваш браузер не поддерживает требуемые криптографические расширения", @@ -653,8 +653,8 @@ "Enable automatic language detection for syntax highlighting": "Включить автоматическое определение языка для подсветки синтаксиса", "Hide join/leave messages (invites/kicks/bans unaffected)": "Скрыть сообщения о входе/выходе (не применяется к приглашениям/выкидываниям/банам)", "Integrations Error": "Ошибка интеграции", - "AM": "AM", - "PM": "PM", + "AM": "ДП", + "PM": "ПП", "NOTE: Apps are not end-to-end encrypted": "ПРИМЕЧАНИЕ: приложения не защищены сквозным шифрованием", "Revoke widget access": "Отозвать доступ к виджетам", "Sets the room topic": "Задать тему комнаты", @@ -662,8 +662,8 @@ "To get started, please pick a username!": "Чтобы начать, выберите имя пользователя!", "Unable to create widget.": "Не удалось создать виджет.", "Unbans user with given id": "Разбанить пользователя с заданным ID", - "You are not in this room.": "Вас нет в этой комнате.", - "You do not have permission to do that in this room.": "У вас нет разрешения на это в этой комнате.", + "You are not in this room.": "Вас сейчас нет в этой комнате.", + "You do not have permission to do that in this room.": "У вас нет разрешения на это в данной комнате.", "Verifies a user, device, and pubkey tuple": "Проверка пользователя, устройства и открытого ключа", "Autocomplete Delay (ms):": "Задержка автозаполнения (мс):", "Loading device info...": "Загрузка информации об устройстве...", @@ -674,11 +674,11 @@ "Automatically replace plain text Emoji": "Автоматически заменять обычный текст на Emoji", "Failed to upload image": "Не удалось загрузить изображение", "Hide avatars in user and room mentions": "Скрыть аватары в упоминаниях пользователей и комнат", - "%(widgetName)s widget added by %(senderName)s": "%(widgetName)s виджет, добавленный %(senderName)s", - "%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s виджет, удаленный %(senderName)s", + "%(widgetName)s widget added by %(senderName)s": "Виджет %(widgetName)s был добавлен %(senderName)s", + "%(widgetName)s widget removed by %(senderName)s": "Виджет %(widgetName)s был удалён %(senderName)s", "Robot check is currently unavailable on desktop - please use a web browser": "Проверка робота в настоящее время недоступна на компьютере - пожалуйста, используйте браузер", "Publish this room to the public in %(domain)s's room directory?": "Опубликовать эту комнату для пользователей в %(domain)s каталоге комнат?", - "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s виджет, измененный %(senderName)s", + "%(widgetName)s widget modified by %(senderName)s": "Виджет %(widgetName)s был изменён %(senderName)s", "Copied!": "Скопировано!", "Failed to copy": "Не удалось скопировать", "Advanced options": "Дополнительные параметры", @@ -690,8 +690,8 @@ "User Options": "Параметры пользователя", "You are now ignoring %(userId)s": "Теперь вы игнорируете %(userId)s", "You are no longer ignoring %(userId)s": "Вы больше не игнорируете %(userId)s", - "Unignored user": "Неигнорируемый пользователь", - "Ignored user": "Игнорируемый пользователь", + "Unignored user": "Пользователь убран из списка игнорирования", + "Ignored user": "Пользователь добавлен в список игнорирования", "Stops ignoring a user, showing their messages going forward": "Прекращает игнорирование пользователя, показывая их будущие сообщения", "Ignores a user, hiding their messages from you": "Игнорирует пользователя, скрывая сообщения от вас", "Disable Emoji suggestions while typing": "Отключить предложения Emoji при наборе текста", @@ -712,10 +712,10 @@ "To change the topic, you must be a": "Чтобы изменить тему, необходимо быть", "To modify widgets in the room, you must be a": "Чтобы изменить виджеты в комнате, необходимо быть", "Description": "Описание", - "Name or matrix ID": "Имя или matrix ID", + "Name or matrix ID": "Имя или идентификатор Matrix", "Unable to accept invite": "Невозможно принять приглашение", "Leave": "Покинуть", - "Failed to invite the following users to %(groupId)s:": "Не удалось пригласить следующих пользователей в %(groupId)s:", + "Failed to invite the following users to %(groupId)s:": "Не удалось пригласить этих пользователей в %(groupId)s:", "Failed to remove '%(roomName)s' from %(groupId)s": "Не удалось удалить '%(roomName)s' из %(groupId)s", "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Вы действительно хотите удалить '%(roomName)s' из %(groupId)s?", "Jump to read receipt": "Перейти к подтверждению о прочтении", @@ -731,9 +731,9 @@ "Add to summary": "Добавить в сводку", "Failed to add the following users to the summary of %(groupId)s:": "Не удалось добавить следующих пользователей в сводку %(groupId)s:", "Which rooms would you like to add to this summary?": "Какие комнаты вы хотите добавить в эту сводку?", - "Room name or alias": "Название комнаты или псевдоним", + "Room name or alias": "Название или идентификатор комнаты", "Pinned Messages": "Закрепленные сообщения", - "%(senderName)s changed the pinned messages for the room.": "%(senderName)s изменил закрепленные сообщения для этой комнаты.", + "%(senderName)s changed the pinned messages for the room.": "%(senderName)s изменил(а) закрепленные в этой комнате сообщения.", "Failed to add the following rooms to the summary of %(groupId)s:": "Не удалось добавить следующие комнаты в сводку %(groupId)s:", "Failed to remove the room from the summary of %(groupId)s": "Не удалось удалить комнату из сводки %(groupId)s", "The room '%(roomName)s' could not be removed from the summary.": "Комнату '%(roomName)s' не удалось удалить из сводки.", @@ -742,7 +742,7 @@ "Light theme": "Светлая тема", "Dark theme": "Темная тема", "Unknown": "Неизвестно", - "Failed to add the following rooms to %(groupId)s:": "Не удалось добавить следующие комнаты в %(groupId)s:", + "Failed to add the following rooms to %(groupId)s:": "Не удалось добавить эти комнаты в %(groupId)s:", "Matrix ID": "Matrix ID", "Matrix Room ID": "Matrix ID комнаты", "email address": "адрес email", @@ -760,11 +760,11 @@ "Community Settings": "Настройки сообщества", "Invite to Community": "Пригласить в сообщество", "Add to community": "Добавить в сообщество", - "Add rooms to the community": "Добавление комнат в сообщество", + "Add rooms to the community": "Добавить комнаты в сообщество", "Which rooms would you like to add to this community?": "Какие комнаты вы хотите добавить в это сообщество?", - "Who would you like to add to this community?": "Кого бы вы хотели добавить в это сообщество?", - "Invite new community members": "Пригласить новых членов сообщества", - "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Предупреждение: любой, кого вы добавляете в сообщество, будет виден всем, кто знает ID сообщества", + "Who would you like to add to this community?": "Кого бы вы хотели пригласить в это сообщество?", + "Invite new community members": "Пригласить в сообщество новых участников", + "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Предупреждение: любой, кого вы приглашаете в сообщество, будет виден всем, кто знает имя этого сообщества", "Add rooms to this community": "Добавить комнаты в это сообщество", "Failed to invite users to community": "Не удалось пригласить пользователей в сообщество", "Communities": "Сообщества", @@ -879,7 +879,7 @@ "Community Invites": "Приглашения в сообщества", "Notify the whole room": "Уведомить всю комнату", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Эти комнаты отображаются для участников сообщества на странице сообщества. Участники сообщества могут присоединиться к комнатам, щелкнув на них.", - "Show these rooms to non-members on the community page and room list?": "Следует ли показывать эти комнаты посторонним на странице сообщества и в комнате?", + "Show these rooms to non-members on the community page and room list?": "Следует ли показывать эти комнаты посторонним на странице сообщества и в списке комнат?", "Sign in to get started": "Войдите, чтобы начать", "Visibility in Room List": "Видимость в списке комнат", "Visible to everyone": "Видимый для всех", @@ -890,7 +890,7 @@ "Enable URL previews for this room (only affects you)": "Включить просмотр URL-адресов для этой комнаты (влияет только на вас)", "Enable URL previews by default for participants in this room": "Включить просмотр URL-адресов по умолчанию для участников этой комнаты", "Status.im theme": "Тема status.im", - "Restricted": "Ограничен", + "Restricted": "Ограниченный пользователь", "Username on %(hs)s": "Имя пользователя на %(hs)s", "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "Видимость '%(roomName)s' в %(groupId)s не удалось обновить.", "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)s отклонили приглашения %(count)s раз", @@ -923,11 +923,11 @@ "Select devices": "Выбрать устройства", "This homeserver doesn't offer any login flows which are supported by this client.": "Этот домашний сервер не поддерживает метод входа, поддерживаемый клиентом.", "Call Failed": "Звонок не удался", - "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "В этой комнате есть неизвестные устройства: если вы продолжите без их проверки, имейте в виду, что кто-то посторонний может вас прослушать.", - "Review Devices": "Обзор устройств", + "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "В этой комнате есть неизвестные устройства: если вы решите их не проверять, имейте в виду, что кто-то, возможно, вас прослушивает.", + "Review Devices": "Проверка устройств", "Call Anyway": "Позвонить в любом случае", "Answer Anyway": "Ответить в любом случае", - "Call": "Вызов", + "Call": "Позвонить", "Answer": "Ответить", "Send": "Отправить", "Addresses": "Адреса", @@ -955,23 +955,23 @@ "Minimize apps": "Свернуть приложения", "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Конфиденциальность важна для нас, поэтому мы не собираем никаких личных или идентифицируемых данных для нашей аналитики.", "Learn more about how we use analytics.": "Подробнее о том, как мы используем аналитику.", - "The information being sent to us to help make Riot.im better includes:": "Информация направляемая нам, чтобы помочь сделать Riot.im лучше включает в себя:", - "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "Мы также записываем каждую страницу, которую вы используете в приложении (в данный момент ), ваш пользовательский агент () и разрешение экрана вашего устройства ().", - "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Если на этой странице содержатся идентифицируемые сведения, например номер, идентификатор пользователя или группы, эти данные удаляются перед отправкой на сервер.", + "The information being sent to us to help make Riot.im better includes:": "Информация, отправляемая нам, чтобы помочь нам сделать Riot.im лучше, включает в себя:", + "We also record each page you use in the app (currently ), your User Agent () and your device resolution ().": "Мы также записываем, какими страницами в приложении вы пользуетесь (сейчас — ), ваш User-Agent () и разрешение экрана вашего устройства ().", + "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Если на этой странице встречаются сведения личного характера, например имя комнаты, имя пользователя или группы, они удаляются перед отправкой на сервер.", "The platform you're on": "Используемая платформа", "The version of Riot.im": "Версия Riot.im", "Whether or not you're logged in (we don't record your user name)": "Вошли вы в систему или нет (мы не храним ваше имя пользователя)", "Your language of choice": "Выбранный язык", - "Your homeserver's URL": "URL-адрес домашнего сервера", - "Your identity server's URL": "URL-адрес вашего идентификационного сервера", - "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s", + "Your homeserver's URL": "URL-адрес сервера", + "Your identity server's URL": "URL-адрес сервера идентификации", + "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(day)s %(monthName)s %(fullYear)s", "Which officially provided instance you are using, if any": "Каким официально поддерживаемым клиентом вы пользуетесь (если пользуетесь)", "Whether or not you're using the Richtext mode of the Rich Text Editor": "Используете ли вы режим Richtext в редакторе Rich Text Editor", "This room is not public. You will not be able to rejoin without an invite.": "Эта комната не является публичной. Вы не сможете войти без приглашения.", "Show devices, send anyway or cancel.": "Показать устройства, отправить в любом случае или отменить.", "Community IDs cannot not be empty.": "ID сообществ не могут быть пустыми.", "In reply to ": "В ответ на ", - "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s изменил отображаемое имя на %(displayName)s.", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s изменил(а) отображаемое имя на %(displayName)s.", "Failed to set direct chat tag": "Не удалось установить тег прямого чата", "Failed to remove tag %(tagName)s from room": "Не удалось удалить тег %(tagName)s из комнаты", "Failed to add tag %(tagName)s to room": "Не удалось добавить тег %(tagName)s в комнату", From c097a8239dbd72b0adb935ddb7dee792a860e0f1 Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Tue, 24 Apr 2018 12:35:35 +0000 Subject: [PATCH 0845/1160] Translated using Weblate (Russian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (1161 of 1161 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ "собеседник"/"собеседника"/"собеседников" — выкинул, потому что нет возможности просклонять --- src/i18n/strings/ru.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 9808a2043a..006950e234 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -799,7 +799,7 @@ "Join an existing community": "Присоединиться к существующему сообществу", "To join an existing community you'll have to know its community identifier; this will look something like +example:matrix.org.": "Чтобы присоединиться к существующему сообществу, вам нужно знать его ID; это будет выглядеть примерно так+primer:matrix.org.", "Something went wrong whilst creating your community": "При создании сообщества что-то пошло не так", - "%(names)s and %(count)s others are typing|other": "%(names)s и %(count)s другие печатают", + "%(names)s and %(count)s others are typing|other": "%(names)s и ещё %(count)s печатают", "And %(count)s more...|other": "И более %(count)s...", "Delete Widget": "Удалить виджет", "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Удаление виджета удаляет его для всех пользователей этой комнаты. Вы действительно хотите удалить этот виджет?", From e3ad75cca6bcbbaceeb5a77f3fbb7e79675bf641 Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Tue, 24 Apr 2018 12:49:38 +0000 Subject: [PATCH 0846/1160] Translated using Weblate (Russian) Currently translated at 100.0% (1161 of 1161 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 48 ++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 006950e234..6ef2c177f8 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -140,7 +140,7 @@ "%(targetName)s accepted an invitation.": "%(targetName)s принял приглашение.", "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s принял приглашение от %(displayName)s.", "Active call": "Активный вызов", - "%(names)s and %(lastPerson)s are typing": "%(names)s и %(lastPerson)s печатает", + "%(names)s and %(lastPerson)s are typing": "%(names)s и %(lastPerson)s печатают", "%(senderName)s answered the call.": "%(senderName)s ответил(а) на звонок.", "%(senderName)s banned %(targetName)s.": "%(senderName)s заблокировал(а) %(targetName)s.", "Call Timeout": "Нет ответа", @@ -238,7 +238,7 @@ "and %(count)s others...|other": "и %(count)s других...", "and %(count)s others...|one": "и еще один...", "Are you sure?": "Вы уверены?", - "Autoplay GIFs and videos": "Автовоспроизведение GIF и видео", + "Autoplay GIFs and videos": "Автоматически воспроизводить GIF-анимации и видео", "Click to mute audio": "Щелкните, чтобы выключить звук", "Click to mute video": "Щелкните, чтобы выключить видео", "Click to unmute video": "Щелкните, чтобы включить видео", @@ -248,7 +248,7 @@ "Devices": "Устройства", "Direct chats": "Прямые чаты", "Disinvite": "Отозвать приглашение", - "Don't send typing notifications": "Не оповещать, когда я печатаю", + "Don't send typing notifications": "Не отправлять оповещения о том, когда я печатаю", "Download %(text)s": "Загрузить %(text)s", "Enable encryption": "Включить шифрование", "Enter Code": "Ввести код", @@ -257,7 +257,7 @@ "Failed to forget room %(errCode)s": "Не удалось удалить комнату %(errCode)s", "Failed to join room": "Не удалось войти в комнату", "Access Token:": "Токен доступа:", - "Always show message timestamps": "Всегда показывать временные метки сообщений", + "Always show message timestamps": "Всегда показывать время отправки сообщений", "Authentication": "Аутентификация", "olm version:": "Версия olm:", "%(items)s and %(lastItem)s": "%(items)s и %(lastItem)s", @@ -277,7 +277,7 @@ "Failed to set display name": "Не удалось задать отображаемое имя", "Failed to toggle moderator status": "Не удалось изменить статус модератора", "Fill screen": "Заполнить экран", - "Hide read receipts": "Скрыть отметки о прочтении", + "Hide read receipts": "Скрывать отметки о прочтении", "Hide Text Formatting Toolbar": "Скрыть панель форматирования текста", "Incorrect verification code": "Неверный код подтверждения", "Interface Language": "Язык интерфейса", @@ -373,9 +373,9 @@ "Operation failed": "Сбой операции", "powered by Matrix": "Основано на Matrix", "Add a topic": "Добавить тему", - "Show timestamps in 12 hour format (e.g. 2:30pm)": "Отображать время в 12-часовом формате (напр. 2:30pm)", - "Use compact timeline layout": "Использовать компактный макет временной шкалы", - "Hide removed messages": "Скрыть удаленные сообщения", + "Show timestamps in 12 hour format (e.g. 2:30pm)": "Отображать время в 12-часовом формате (напр. 2:30 ПП)", + "Use compact timeline layout": "Использовать компактный вид списка сообщений", + "Hide removed messages": "Скрывать удалённые сообщения", "No Microphones detected": "Микрофоны не обнаружены", "Unknown devices": "Неизвестное устройство", "Camera": "Камера", @@ -431,7 +431,7 @@ "Server may be unavailable or overloaded": "Сервер может быть недоступен или перегружен", "Server may be unavailable, overloaded, or search timed out :(": "Сервер может быть недоступен, перегружен или поиск прекращен по тайм-ауту :(", "Server may be unavailable, overloaded, or the file too big": "Сервер может быть недоступен, перегружен или размер файла слишком большой", - "Server may be unavailable, overloaded, or you hit a bug.": "Сервер может быть недоступен, перегружен или возникла ошибка.", + "Server may be unavailable, overloaded, or you hit a bug.": "Возможно, сервер недоступен, перегружен или случилась ошибка.", "Server unavailable, overloaded, or something else went wrong.": "Сервер может быть недоступен, перегружен или что-то пошло не так.", "Session ID": "ID сессии", "%(senderName)s set a profile picture.": "%(senderName)s установил(а) себе аватар.", @@ -609,7 +609,7 @@ "Undecryptable": "Невозможно расшифровать", "Unencrypted message": "Незашифрованное сообщение", "unknown caller": "неизвестный абонент", - "Unnamed Room": "Комната без имени", + "Unnamed Room": "Комната без названия", "Unverified": "Не проверено", "Upload new:": "Отправить новый:", "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (уровень доступа %(powerLevelNumber)s)", @@ -625,9 +625,9 @@ "(no answer)": "(нет ответа)", "(unknown failure: %(reason)s)": "(неизвестная ошибка: %(reason)s)", "Disable Peer-to-Peer for 1:1 calls": "Отключить Peer-to-Peer для 1:1 звонков", - "Not a valid Riot keyfile": "Недействительный файл ключа Riot", + "Not a valid Riot keyfile": "Недействительный файл ключей Riot", "Your browser does not support the required cryptography extensions": "Ваш браузер не поддерживает требуемые криптографические расширения", - "Authentication check failed: incorrect password?": "Ошибка аутентификации: неправильный пароль?", + "Authentication check failed: incorrect password?": "Ошибка аутентификации: возможно, неправильный пароль?", "Do you want to set an email address?": "Хотите указать адрес email?", "This will allow you to reset your password and receive notifications.": "Это позволит при необходимости сбросить пароль и получать уведомления.", "Press to start a chat with someone": "Нажмите для начала чата с кем-либо", @@ -650,8 +650,8 @@ "Define the power level of a user": "Определить уровень доступа пользователя", "Do you want to load widget from URL:": "Загрузить виджет из URL-адреса:", "Edit": "Редактировать", - "Enable automatic language detection for syntax highlighting": "Включить автоматическое определение языка для подсветки синтаксиса", - "Hide join/leave messages (invites/kicks/bans unaffected)": "Скрыть сообщения о входе/выходе (не применяется к приглашениям/выкидываниям/банам)", + "Enable automatic language detection for syntax highlighting": "Автоматически определять язык подсветки синтаксиса", + "Hide join/leave messages (invites/kicks/bans unaffected)": "Скрывать уведомления о входе/выходе из комнаты (не применяется к приглашениям/выкидываниям/банам)", "Integrations Error": "Ошибка интеграции", "AM": "ДП", "PM": "ПП", @@ -671,9 +671,9 @@ "Create": "Создать", "Featured Rooms:": "Рекомендуемые комнаты:", "Featured Users:": "Избранные пользователи:", - "Automatically replace plain text Emoji": "Автоматически заменять обычный текст на Emoji", + "Automatically replace plain text Emoji": "Автоматически заменять текстовые смайлики на Emoji", "Failed to upload image": "Не удалось загрузить изображение", - "Hide avatars in user and room mentions": "Скрыть аватары в упоминаниях пользователей и комнат", + "Hide avatars in user and room mentions": "Скрывать аватары в упоминаниях пользователей и комнат", "%(widgetName)s widget added by %(senderName)s": "Виджет %(widgetName)s был добавлен %(senderName)s", "%(widgetName)s widget removed by %(senderName)s": "Виджет %(widgetName)s был удалён %(senderName)s", "Robot check is currently unavailable on desktop - please use a web browser": "Проверка робота в настоящее время недоступна на компьютере - пожалуйста, используйте браузер", @@ -694,7 +694,7 @@ "Ignored user": "Пользователь добавлен в список игнорирования", "Stops ignoring a user, showing their messages going forward": "Прекращает игнорирование пользователя, показывая их будущие сообщения", "Ignores a user, hiding their messages from you": "Игнорирует пользователя, скрывая сообщения от вас", - "Disable Emoji suggestions while typing": "Отключить предложения Emoji при наборе текста", + "Disable Emoji suggestions while typing": "Не предлагать Emoji при наборе текста", "Banned by %(displayName)s": "Запрещено %(displayName)s", "Message removed by %(userId)s": "Сообщение удалено %(userId)s", "To send messages, you must be a": "Для отправки сообщений необходимо быть", @@ -719,8 +719,8 @@ "Failed to remove '%(roomName)s' from %(groupId)s": "Не удалось удалить '%(roomName)s' из %(groupId)s", "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Вы действительно хотите удалить '%(roomName)s' из %(groupId)s?", "Jump to read receipt": "Перейти к подтверждению о прочтении", - "Disable big emoji in chat": "Отключить большие emoji в чате", - "Message Pinning": "Закрепление сообщений", + "Disable big emoji in chat": "Отключить большие Emoji в чате", + "Message Pinning": "Закреплённые сообщения", "Remove avatar": "Удалить аватар", "Failed to invite users to %(groupId)s": "Не удалось пригласить пользователей в %(groupId)s", "Unable to reject invite": "Невозможно отклонить приглашение", @@ -809,7 +809,7 @@ "Mention": "Упоминание", "Failed to withdraw invitation": "Не удалось отозвать приглашение", "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "ID сообществ могут содержать только символы a-z, 0-9, или '=_-./'", - "%(names)s and %(count)s others are typing|one": "%(names)s и еще кто-то печатает", + "%(names)s and %(count)s others are typing|one": "%(names)s и еще один собеседник печатают", "%(senderName)s sent an image": "%(senderName)s отправил(а) изображение", "%(senderName)s sent a video": "%(senderName)s отправил(а) видео", "%(senderName)s uploaded a file": "%(senderName)s загрузил(а) файл", @@ -884,8 +884,8 @@ "Visibility in Room List": "Видимость в списке комнат", "Visible to everyone": "Видимый для всех", "Only visible to community members": "Только участникам сообщества", - "Hide avatar changes": "Скрыть изменения аватара", - "Hide display name changes": "Скрыть изменения отображаемого имени", + "Hide avatar changes": "Скрывать уведомления об изменении аватаров", + "Hide display name changes": "Скрывать уведомления об изменениях имён", "Enable inline URL previews by default": "Включить просмотр URL-адресов по умолчанию", "Enable URL previews for this room (only affects you)": "Включить просмотр URL-адресов для этой комнаты (влияет только на вас)", "Enable URL previews by default for participants in this room": "Включить просмотр URL-адресов по умолчанию для участников этой комнаты", @@ -946,7 +946,7 @@ "%(count)s of your messages have not been sent.|one": "Ваше сообщение не было отправлено.", "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "Отправить все или отменить все сейчас. Можно также выбрать отдельные сообщения для отправки или отмены.", "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Отправить или отменить сообщение сейчас.", - "Message Replies": "Ответы на сообщения", + "Message Replies": "Сообщения-ответы", "Send an encrypted reply…": "Отправить зашифрованный ответ…", "Send a reply (unencrypted)…": "Отправить ответ (незашифрованный)…", "Send an encrypted message…": "Отправить зашифрованное сообщение…", @@ -999,7 +999,7 @@ "Who can join this community?": "Кто может присоединиться к этому сообществу?", "Everyone": "Все", "Stickerpack": "Этикетки", - "Sticker Messages": "Сообщения этикеткой", + "Sticker Messages": "Стикеры", "Add a stickerpack": "Добавить этикетки", "Hide Stickers": "Скрыть этикетки", "Show Stickers": "Показать этикетки", From a3c407992be4d56e176de24acfc9378a1c96ec10 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 24 Apr 2018 13:59:18 +0100 Subject: [PATCH 0847/1160] Don't autocomplete users for single "@" --- src/autocomplete/UserProvider.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/autocomplete/UserProvider.js b/src/autocomplete/UserProvider.js index e636f95751..ce8f1020a1 100644 --- a/src/autocomplete/UserProvider.js +++ b/src/autocomplete/UserProvider.js @@ -101,8 +101,13 @@ export default class UserProvider extends AutocompleteProvider { let completions = []; const {command, range} = this.getCurrentCommand(query, selection, force); - if (command) { - completions = this.matcher.match(command[0]).map((user) => { + + if (!command) return completions; + + const fullMatch = command[0]; + // Don't search if the query is a single "@" + if (fullMatch && fullMatch !== '@') { + completions = this.matcher.match(fullMatch).map((user) => { const displayName = (user.name || user.userId || '').replace(' (IRC)', ''); // FIXME when groups are done return { // Length of completion should equal length of text in decorator. draft-js From ae15db8208d50466f8cf98ee154624df82880ae4 Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Tue, 24 Apr 2018 13:00:10 +0000 Subject: [PATCH 0848/1160] Translated using Weblate (Russian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (1161 of 1161 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ криво, но лучше не могу --- src/i18n/strings/ru.json | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 6ef2c177f8..13b58b877d 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -83,8 +83,8 @@ "Moderator": "Модератор", "%(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": "Никогда не отправлять зашифрованные сообщения на непроверенные устройства в этой комнате с этого устройства", + "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.": "Новые пароли должны совпадать.", "none": "никто", @@ -384,7 +384,7 @@ "Start automatically after system login": "Автозапуск при входе в систему", "Analytics": "Аналитика", "Riot collects anonymous analytics to allow us to improve the application.": "Riot собирает анонимные данные, позволяющие нам улучшить приложение.", - "Opt out of analytics": "Не собирать аналитические данные", + "Opt out of analytics": "Не отправлять данные для аналитики", "Logged in as:": "Вы вошли как:", "Default Device": "Устройство по умолчанию", "No Webcams detected": "Веб-камера не обнаружена", @@ -804,7 +804,7 @@ "Delete Widget": "Удалить виджет", "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Удаление виджета удаляет его для всех пользователей этой комнаты. Вы действительно хотите удалить этот виджет?", "Message removed": "Сообщение удалено", - "Mirror local video feed": "Зеркальное отображение видео", + "Mirror local video feed": "Зеркально отражать видео со своей камеры", "Invite": "Пригласить", "Mention": "Упоминание", "Failed to withdraw invitation": "Не удалось отозвать приглашение", @@ -886,9 +886,9 @@ "Only visible to community members": "Только участникам сообщества", "Hide avatar changes": "Скрывать уведомления об изменении аватаров", "Hide display name changes": "Скрывать уведомления об изменениях имён", - "Enable inline URL previews by default": "Включить просмотр URL-адресов по умолчанию", - "Enable URL previews for this room (only affects you)": "Включить просмотр URL-адресов для этой комнаты (влияет только на вас)", - "Enable URL previews by default for participants in this room": "Включить просмотр URL-адресов по умолчанию для участников этой комнаты", + "Enable inline URL previews by default": "Включить предпросмотр ссылок по умолчанию", + "Enable URL previews for this room (only affects you)": "Включить предпросмотр ссылок в этой комнате (влияет только на вас)", + "Enable URL previews by default for participants in this room": "Включить предпросмотр ссылок для участников этой комнаты по умолчанию", "Status.im theme": "Тема status.im", "Restricted": "Ограниченный пользователь", "Username on %(hs)s": "Имя пользователя на %(hs)s", @@ -978,7 +978,7 @@ "Clear filter": "Очистить фильтр", "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Чтобы настроить фильтр, перетащите аватар сообщества на панель фильтров в левой части экрана. Вы можете нажать на аватар в панели фильтров в любое время, чтобы увидеть только комнаты и людей, связанных с этим сообществом.", "Did you know: you can use communities to filter your Riot.im experience!": "Знаете ли вы: вы можете использовать сообщества, чтобы фильтровать в Riot.im!", - "Disable Community Filter Panel": "Отключить панель фильтра сообщества", + "Disable Community Filter Panel": "Отключить панель сообществ", "If your other devices do not have the key for this message you will not be able to decrypt them.": "Если у других устройств нет ключа для этого сообщения, вы не сможете его расшифровать.", "Key request sent.": "Запрос ключа отправлен.", "Re-request encryption keys from your other devices.": "Повторно запросить ключи шифрования с других устройств.", @@ -1040,7 +1040,7 @@ "The Home Server may be too old to support third party networks": "Домашний сервер может быть слишком старым для поддержки сетей сторонних производителей", "Noisy": "Со звуком", "Room not found": "Комната не найдена", - "Messages containing my display name": "Сообщения, содержащие мое имя", + "Messages containing my display name": "Сообщения, упоминающие моё имя", "Messages in one-to-one chats": "Сообщения в индивидуальных чатах", "Unavailable": "Недоступен", "Error saving email notification preferences": "Ошибка при сохранении настроек уведомлений по email", @@ -1091,7 +1091,7 @@ "Monday": "Понедельник", "Remove from Directory": "Удалить из каталога", "Enable them now": "Включить сейчас", - "Messages containing my user name": "Сообщение, содержащие мое имя пользователя", + "Messages containing my user name": "Сообщение, упоминающие моё имя пользователя", "Toolbox": "Панель инструментов", "Collecting logs": "Сбор журналов", "more": "больше", From 9123ad0659d349a0a46d37d17e164695c23d13f6 Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Tue, 24 Apr 2018 13:04:52 +0000 Subject: [PATCH 0849/1160] Translated using Weblate (Russian) Currently translated at 100.0% (1161 of 1161 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 13b58b877d..860a73ee9b 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -234,7 +234,7 @@ "Usage": "Использование", "Use with caution": "Использовать с осторожностью", "VoIP is unsupported": "Звонки не поддерживаются", - "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Текстовое сообщение было отправлено на +%(msisdn)s. Введите проверочный код, который оно содержит", + "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Текстовое сообщение было отправлено на +%(msisdn)s. Введите проверочный код из сообщения", "and %(count)s others...|other": "и %(count)s других...", "and %(count)s others...|one": "и еще один...", "Are you sure?": "Вы уверены?", @@ -266,7 +266,7 @@ "Ban": "Заблокировать", "Change Password": "Сменить пароль", "Command error": "Ошибка команды", - "Confirm password": "Подтвердите пароль", + "Confirm password": "Подтвердите новый пароль", "Current password": "Текущий пароль", "Email": "Электронная почта", "Failed to kick": "Не удалось выгнать", @@ -398,7 +398,7 @@ "Anyone": "Все", "Are you sure you want to leave the room '%(roomName)s'?": "Вы уверены, что хотите покинуть '%(roomName)s'?", "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s удалил(а) имя комнаты.", - "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Смена пароля на данный момент сбрасывает ключи сквозного шифрования на всех устройствах, делая зашифрованную историю чата нечитаемой. Чтобы избежать этого, экспортируйте ключи комнат и импортируйте их после смены пароля. В будущем это будет исправлено.", + "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Смена пароля на данный момент сбрасывает ключи сквозного шифрования на всех устройствах, делая историю зашифрованных чатов нечитаемой. Чтобы избежать этого, экспортируйте ключи сквозного шифрования и импортируйте их после смены пароля. В будущем это будет исправлено.", "Custom level": "Пользовательский уровень", "Device already verified!": "Устройство уже проверено!", "Device ID:": "ID устройства:", @@ -566,7 +566,7 @@ "If you already have a Matrix account you can log in instead.": "Если у вас уже есть учетная запись Matrix, вы можете войти.", "Home": "Старт", "Accept": "Принять", - "Active call (%(roomName)s)": "Активный вызов (%(roomName)s)", + "Active call (%(roomName)s)": "Текущий вызов (%(roomName)s)", "Admin Tools": "Инструменты администратора", "Alias (optional)": "Псевдоним (опционально)", "Click here to join the discussion!": "Нажмите здесь, чтобы присоединиться к обсуждению!", @@ -578,7 +578,7 @@ "Encrypted by an unverified device": "Зашифровано непроверенным устройством", "Encryption is enabled in this room": "Шифрование в этой комнате включено", "Encryption is not enabled in this room": "Шифрование в этой комнате не включено", - "Failed to upload profile picture!": "Не удалось отправить изображение профиля!", + "Failed to upload profile picture!": "Не удалось загрузить аватар!", "Incoming call from %(name)s": "Входящий вызов от %(name)s", "Incoming video call from %(name)s": "Входящий видеовызов от %(name)s", "Incoming voice call from %(name)s": "Входящий голосовой вызов от %(name)s", @@ -611,7 +611,7 @@ "unknown caller": "неизвестный абонент", "Unnamed Room": "Комната без названия", "Unverified": "Не проверено", - "Upload new:": "Отправить новый:", + "Upload new:": "Загрузить новый:", "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (уровень доступа %(powerLevelNumber)s)", "Verified": "Проверено", "Would you like to accept or decline this invitation?": "Вы хотели бы подтвердить или отклонить это приглашение?", @@ -620,7 +620,7 @@ "You have been banned from %(roomName)s by %(userName)s.": "%(userName)s заблокировал вас в %(roomName)s.", "You have been kicked from %(roomName)s by %(userName)s.": "%(userName)s выгнал вас из %(roomName)s.", "You may wish to login with a different account, or add this email to this account.": "При желании вы можете войти в систему с другой учетной записью или добавить этот адрес email в эту учетную запись.", - "Your home server does not support device management.": "Ваш домашний сервер не поддерживает управление устройствами.", + "Your home server does not support device management.": "Ваш сервер не поддерживает управление устройствами.", "(could not connect media)": "(сбой подключения)", "(no answer)": "(нет ответа)", "(unknown failure: %(reason)s)": "(неизвестная ошибка: %(reason)s)", @@ -628,7 +628,7 @@ "Not a valid Riot keyfile": "Недействительный файл ключей Riot", "Your browser does not support the required cryptography extensions": "Ваш браузер не поддерживает требуемые криптографические расширения", "Authentication check failed: incorrect password?": "Ошибка аутентификации: возможно, неправильный пароль?", - "Do you want to set an email address?": "Хотите указать адрес email?", + "Do you want to set an email address?": "Хотите указать email-адрес?", "This will allow you to reset your password and receive notifications.": "Это позволит при необходимости сбросить пароль и получать уведомления.", "Press to start a chat with someone": "Нажмите для начала чата с кем-либо", "You're not in any rooms yet! Press to make a room or to browse the directory": "Вы еще не вошли ни в одну из комнат! Нажмите , чтобы создать комнату или для просмотра каталога", @@ -1041,7 +1041,7 @@ "Noisy": "Со звуком", "Room not found": "Комната не найдена", "Messages containing my display name": "Сообщения, упоминающие моё имя", - "Messages in one-to-one chats": "Сообщения в индивидуальных чатах", + "Messages in one-to-one chats": "Сообщения в 1:1 чатах", "Unavailable": "Недоступен", "Error saving email notification preferences": "Ошибка при сохранении настроек уведомлений по email", "View Decrypted Source": "Просмотр расшифрованного источника", @@ -1055,7 +1055,7 @@ "An error occurred whilst saving your email notification preferences.": "Возникла ошибка при сохранении настроек оповещения по email.", "Explore Room State": "Просмотр статуса комнаты", "Source URL": "Исходный URL-адрес", - "Messages sent by bot": "Сообщения, отправленные ботом", + "Messages sent by bot": "Сообщения от ботов", "Filter results": "Фильтрация результатов", "Members": "Участники", "No update available.": "Нет доступных обновлений.", @@ -1103,13 +1103,13 @@ "Failed to get public room list": "Не удалось получить список общедоступных комнат", "Send logs": "Отправка журналов", "All messages": "Все сообщения", - "Call invitation": "Пригласительный звонок", + "Call invitation": "Приглашения на звонки", "Downloading update...": "Загрузка обновления...", "State Key": "Ключ состояния", "Failed to send custom event.": "Не удалось отправить индивидуальное мероприятие.", "What's new?": "Что нового?", "Notify me for anything else": "Уведомлять во всех остальных случаях", - "When I'm invited to a room": "Когда меня приглашают в комнату", + "When I'm invited to a room": "Приглашения в комнаты", "Click here to create a GitHub issue.": "Нажмите здесь для создания запроса о проблеме на GitHub.", "Can't update user notification settings": "Не удается обновить пользовательские настройки оповещения", "Notify for all other messages/rooms": "Уведомлять обо всех других сообщениях/комнатах", @@ -1128,7 +1128,7 @@ "Unable to join network": "Не удается подключиться к сети", "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Возможно вы настроили их не в Riot, а в другом Matrix-клиенте. Настроить их в Riot не удастся, но они будут в нем применяться", "Sorry, your browser is not able to run Riot.": "К сожалению, ваш браузер не способен запустить Riot.", - "Messages in group chats": "Сообщения в групповых чатах", + "Messages in group chats": "Сообщения в конференциях", "Yesterday": "Вчера", "Error encountered (%(errorDetail)s).": "Обнаружена ошибка (%(errorDetail)s).", "Login": "Войти", From 04d06d42ce78be41e587a87534e7b879503affbd Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Tue, 24 Apr 2018 13:05:44 +0000 Subject: [PATCH 0850/1160] Translated using Weblate (Russian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (1161 of 1161 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ или "использование"? --- src/i18n/strings/ru.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 860a73ee9b..57d8e2ea88 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -583,7 +583,7 @@ "Incoming video call from %(name)s": "Входящий видеовызов от %(name)s", "Incoming voice call from %(name)s": "Входящий голосовой вызов от %(name)s", "Join as voice or video.": "Войти как голос или видео.", - "Last seen": "Последний визит", + "Last seen": "Последний вход", "Level:": "Уровень:", "No display name": "Нет отображаемого имени", "Otherwise, click here to send a bug report.": "В противном случае, нажмите 2 для отправки отчета об ошибке.", From f53b1e9a3d8a4f37b635e508bb3d1d0e18a89a7f Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Tue, 24 Apr 2018 13:40:03 +0000 Subject: [PATCH 0851/1160] Translated using Weblate (Russian) Currently translated at 100.0% (1161 of 1161 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 58 ++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 57d8e2ea88..d1bab0da76 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -166,7 +166,7 @@ "%(senderName)s invited %(targetName)s.": "%(senderName)s приглашает %(targetName)s.", "%(displayName)s is typing": "%(displayName)s печатает", "%(targetName)s joined the room.": "%(targetName)s вошёл(-ла) в комнату.", - "%(senderName)s kicked %(targetName)s.": "%(senderName)s исключил(а) %(targetName)s из комнаты.", + "%(senderName)s kicked %(targetName)s.": "%(senderName)s выгнал(а) %(targetName)s.", "%(targetName)s left the room.": "%(targetName)s покинул(а) комнату.", "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s сделал(а) историю разговора видимой для всех собеседников с момента их приглашения.", "%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s сделал(а) историю разговора видимой для всех собеседников с момента их входа в комнату.", @@ -246,14 +246,14 @@ "Decrypt %(text)s": "Расшифровать %(text)s", "Delete": "Удалить", "Devices": "Устройства", - "Direct chats": "Прямые чаты", + "Direct chats": "Личные чаты", "Disinvite": "Отозвать приглашение", "Don't send typing notifications": "Не отправлять оповещения о том, когда я печатаю", "Download %(text)s": "Загрузить %(text)s", "Enable encryption": "Включить шифрование", "Enter Code": "Ввести код", "Failed to ban user": "Не удалось заблокировать пользователя", - "Failed to change power level": "Не удалось изменить уровень привилегий", + "Failed to change power level": "Не удалось изменить уровень прав", "Failed to forget room %(errCode)s": "Не удалось удалить комнату %(errCode)s", "Failed to join room": "Не удалось войти в комнату", "Access Token:": "Токен доступа:", @@ -275,7 +275,7 @@ "Failed to reject invite": "Не удалось отклонить приглашение", "Failed to save settings": "Не удалось сохранить настройки", "Failed to set display name": "Не удалось задать отображаемое имя", - "Failed to toggle moderator status": "Не удалось изменить статус модератора", + "Failed to toggle moderator status": "Не удалось переключить статус модератора", "Fill screen": "Заполнить экран", "Hide read receipts": "Скрывать отметки о прочтении", "Hide Text Formatting Toolbar": "Скрыть панель форматирования текста", @@ -458,8 +458,8 @@ "You have enabled URL previews by default.": "Предварительный просмотр ссылок включен по-умолчанию.", "You need to enter a user name.": "Необходимо ввести имя пользователя.", "You seem to be in a call, are you sure you want to quit?": "Звонок не завершен, вы уверены, что хотите выйти?", - "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Вы не сможете отменить это изменение, так как этот пользователь получит уровень доступа, аналогичный вашему.", - "Please select the destination room for this message": "Выберите комнату для отправки этого сообщения", + "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Вы не сможете отменить это действие, так как этот пользователь получит уровень прав, равный вашему.", + "Please select the destination room for this message": "Выберите, куда отправить это сообщение", "Options": "Настройки", "Passphrases must match": "Пароли должны совпадать", "Passphrase must not be empty": "Пароль не должен быть пустым", @@ -532,7 +532,7 @@ "URL Previews": "Предварительный просмотр URL-адресов", "Drop file here to upload": "Перетащите файл сюда для отправки", " (unsupported)": " (не поддерживается)", - "Ongoing conference call%(supportedText)s.": "Установлен групповой вызов %(supportedText)s.", + "Ongoing conference call%(supportedText)s.": "Идёт конференц-звонок%(supportedText)s.", "Online": "Онлайн", "Idle": "Неактивен", "Offline": "Не в сети", @@ -582,7 +582,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": "Нет отображаемого имени", @@ -607,7 +607,7 @@ "To link to a room it must have an address.": "Чтобы связаться с комнатой, она должна иметь адрес.", "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Не удалось установить соответствует ли адрес, по которому этому приглашение было послано, вашей учетной записи.", "Undecryptable": "Невозможно расшифровать", - "Unencrypted message": "Незашифрованное сообщение", + "Unencrypted message": "Нешифрованное сообщение", "unknown caller": "неизвестный абонент", "Unnamed Room": "Комната без названия", "Unverified": "Не проверено", @@ -687,7 +687,7 @@ "Ignored Users": "Игнорируемые пользователи", "Ignore": "Игнорировать", "Unignore": "Перестать игнорировать", - "User Options": "Параметры пользователя", + "User Options": "Действия", "You are now ignoring %(userId)s": "Теперь вы игнорируете %(userId)s", "You are no longer ignoring %(userId)s": "Вы больше не игнорируете %(userId)s", "Unignored user": "Пользователь убран из списка игнорирования", @@ -718,7 +718,7 @@ "Failed to invite the following users to %(groupId)s:": "Не удалось пригласить этих пользователей в %(groupId)s:", "Failed to remove '%(roomName)s' from %(groupId)s": "Не удалось удалить '%(roomName)s' из %(groupId)s", "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Вы действительно хотите удалить '%(roomName)s' из %(groupId)s?", - "Jump to read receipt": "Перейти к подтверждению о прочтении", + "Jump to read receipt": "Перейти к последнему прочтённому им сообщению", "Disable big emoji in chat": "Отключить большие Emoji в чате", "Message Pinning": "Закреплённые сообщения", "Remove avatar": "Удалить аватар", @@ -806,14 +806,14 @@ "Message removed": "Сообщение удалено", "Mirror local video feed": "Зеркально отражать видео со своей камеры", "Invite": "Пригласить", - "Mention": "Упоминание", + "Mention": "Упомянуть", "Failed to withdraw invitation": "Не удалось отозвать приглашение", "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "ID сообществ могут содержать только символы a-z, 0-9, или '=_-./'", "%(names)s and %(count)s others are typing|one": "%(names)s и еще один собеседник печатают", "%(senderName)s sent an image": "%(senderName)s отправил(а) изображение", "%(senderName)s sent a video": "%(senderName)s отправил(а) видео", - "%(senderName)s uploaded a file": "%(senderName)s загрузил(а) файл", - "Disinvite this user?": "Отменить приглашение этого пользователя?", + "%(senderName)s uploaded a file": "%(senderName)s отправил(а) файл", + "Disinvite this user?": "Отозвать приглашение этого пользователя?", "Kick this user?": "Выгнать этого пользователя?", "Unban this user?": "Разблокировать этого пользователя?", "Ban this user?": "Заблокировать этого пользователя?", @@ -942,7 +942,7 @@ "Flair": "Талант", "Flair will not appear": "Талант не отображается", "Display your community flair in rooms configured to show it.": "Покажите свой талант в комнатах, которых это разрешено.", - "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Вы не сможете отменить это изменение после понижения себя, в случае если вы являетесь последним привилегированным пользователем в этой комнате.", + "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "После понижения своих привилегий вы не сможете это отменить. Если вы являетесь последним привилегированным пользователем в этой комнате, выдать права кому-либо заново будет невозможно.", "%(count)s of your messages have not been sent.|one": "Ваше сообщение не было отправлено.", "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "Отправить все или отменить все сейчас. Можно также выбрать отдельные сообщения для отправки или отмены.", "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Отправить или отменить сообщение сейчас.", @@ -979,12 +979,12 @@ "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Чтобы настроить фильтр, перетащите аватар сообщества на панель фильтров в левой части экрана. Вы можете нажать на аватар в панели фильтров в любое время, чтобы увидеть только комнаты и людей, связанных с этим сообществом.", "Did you know: you can use communities to filter your Riot.im experience!": "Знаете ли вы: вы можете использовать сообщества, чтобы фильтровать в Riot.im!", "Disable Community Filter Panel": "Отключить панель сообществ", - "If your other devices do not have the key for this message you will not be able to decrypt them.": "Если у других устройств нет ключа для этого сообщения, вы не сможете его расшифровать.", + "If your other devices do not have the key for this message you will not be able to decrypt them.": "Если на других устройствах тоже нет ключа для этого сообщения, вы не сможете его расшифровать.", "Key request sent.": "Запрос ключа отправлен.", "Re-request encryption keys from your other devices.": "Повторно запросить ключи шифрования с других устройств.", "%(user)s is a %(userRole)s": "%(user)s является %(userRole)s", - "Your key share request has been sent - please check your other devices for key share requests.": "Ваш запрос на передачу ключей отправлен - пожалуйста, проверьте другие ваши устройства на запросы передачи ключей.", - "Key share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, click here to request the keys for this session again.": "Запросы передачи ключей автоматически отправляются на другие устройства. Если вы отклонили или отменили запрос на передачу ключей на других устройствах, нажмите здесь, чтобы запросить ключи для этого сеанса повторно.", + "Your key share request has been sent - please check your other devices for key share requests.": "Запрос на передачу ключей отправлен — проверьте остальные устройства.", + "Key share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, click here to request the keys for this session again.": "Запросы на передачу ключей автоматически отправляются на другие устройства. Если вы отклонили или отменили запрос на другом устройстве, нажмите, чтобы запросить ключи повторно.", "Code": "Код", "Debug Logs Submission": "Отправка журналов отладки", "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Если вы отправили ошибку через GitHub, журналы отладки могут помочь нам выявить проблему. Журналы отладки содержат данные об использовании приложения, включая ваше имя пользователя, идентификаторы или псевдонимы комнат или групп, которые вы посетили, а также имена других пользователей. Они не содержат сообщений.", @@ -1011,14 +1011,14 @@ "All notifications are currently disabled for all targets.": "Все оповещения для всех устройств отключены.", "Uploading report": "Отправка отчета", "Sunday": "Воскресенье", - "Notification targets": "Цели уведомления", + "Notification targets": "Устройства для уведомлений", "Today": "Сегодня", "Files": "Файлы", "You are not receiving desktop notifications": "Вы не получаете уведомления на рабочем столе", "Friday": "Пятница", "Update": "Обновление", "What's New": "Что нового", - "Add an email address above to configure email notifications": "Добавьте email адрес для оповещений", + "Add an email address above to configure email notifications": "Добавьте email-адрес выше для настройки email-уведомлений", "Expand panel": "Развернуть панель", "On": "Включить", "%(count)s Members|other": "%(count)s членов", @@ -1038,21 +1038,21 @@ "Cancel Sending": "Отменить отправку", "This Room": "Эта комната", "The Home Server may be too old to support third party networks": "Домашний сервер может быть слишком старым для поддержки сетей сторонних производителей", - "Noisy": "Со звуком", + "Noisy": "Вкл. (со звуком)", "Room not found": "Комната не найдена", "Messages containing my display name": "Сообщения, упоминающие моё имя", "Messages in one-to-one chats": "Сообщения в 1:1 чатах", "Unavailable": "Недоступен", - "Error saving email notification preferences": "Ошибка при сохранении настроек уведомлений по email", + "Error saving email notification preferences": "Ошибка сохранения настроек email-уведомлений", "View Decrypted Source": "Просмотр расшифрованного источника", "Failed to update keywords": "Не удалось обновить ключевые слова", "Notes:": "Заметки:", "remove %(name)s from the directory.": "удалить %(name)s из каталога.", - "Notifications on the following keywords follow rules which can’t be displayed here:": "Уведомления по следующим ключевым словам соответствуют правилам, которые нельзя отобразить здесь:", + "Notifications on the following keywords follow rules which can’t be displayed here:": "Уведомления по этим ключевым словам соответствуют правилам, которые нельзя отобразить здесь:", "Safari and Opera work too.": "Safari и Opera работают тоже.", "Please set a password!": "Пожалуйста, установите пароль!", "You have successfully set a password!": "Вы успешно установили пароль!", - "An error occurred whilst saving your email notification preferences.": "Возникла ошибка при сохранении настроек оповещения по email.", + "An error occurred whilst saving your email notification preferences.": "Возникла ошибка при сохранении настроек email-уведомлений.", "Explore Room State": "Просмотр статуса комнаты", "Source URL": "Исходный URL-адрес", "Messages sent by bot": "Сообщения от ботов", @@ -1111,8 +1111,8 @@ "Notify me for anything else": "Уведомлять во всех остальных случаях", "When I'm invited to a room": "Приглашения в комнаты", "Click here to create a GitHub issue.": "Нажмите здесь для создания запроса о проблеме на GitHub.", - "Can't update user notification settings": "Не удается обновить пользовательские настройки оповещения", - "Notify for all other messages/rooms": "Уведомлять обо всех других сообщениях/комнатах", + "Can't update user notification settings": "Не удалось обновить пользовательские настройки оповещения", + "Notify for all other messages/rooms": "Уведомлять обо всех остальных сообщениях и комнатах", "Unable to look up room ID from server": "Не удалось найти ID комнаты на сервере", "Couldn't find a matching Matrix room": "Не удалось найти подходящую комнату Matrix", "All Rooms": "Все комнаты", @@ -1122,18 +1122,18 @@ "Logs sent": "Журналы отправлены", "Back": "Назад", "Reply": "Ответить", - "Show message in desktop notification": "Показывать сообщение в уведомлении на рабочем столе", + "Show message in desktop notification": "Показывать текст сообщения в уведомлениях на рабочем столе", "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Журналы отладки содержат данные об использовании приложения, включая ваше имя пользователя, идентификаторы или псевдонимы комнат или групп, которые вы посетили, а также имена других пользователей. Они не содержат сообщений.", "Unhide Preview": "Показать предварительный просмотр", "Unable to join network": "Не удается подключиться к сети", - "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Возможно вы настроили их не в Riot, а в другом Matrix-клиенте. Настроить их в Riot не удастся, но они будут в нем применяться", + "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "Возможно, вы настроили их не в Riot, а в другом Matrix-клиенте. Настроить их в Riot не удастся, но они будут продолжать работать и здесь", "Sorry, your browser is not able to run Riot.": "К сожалению, ваш браузер не способен запустить Riot.", "Messages in group chats": "Сообщения в конференциях", "Yesterday": "Вчера", "Error encountered (%(errorDetail)s).": "Обнаружена ошибка (%(errorDetail)s).", "Login": "Войти", "Low Priority": "Низкий приоритет", - "Unable to fetch notification target list": "Не удалось получить список целей уведомления", + "Unable to fetch notification target list": "Не удалось получить список устройств для уведомлений", "Set Password": "Задать пароль", "Enable audible notifications in web client": "Включить звуковые уведомления в веб-клиенте", "Permalink": "Постоянная ссылка", From d67125d40f653016a84c0a0e709e6c68cbe4459a Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Tue, 24 Apr 2018 13:54:22 +0000 Subject: [PATCH 0852/1160] Translated using Weblate (Russian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (1161 of 1161 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ криво --- src/i18n/strings/ru.json | 50 ++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index d1bab0da76..8753ce8940 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -9,7 +9,7 @@ "Anyone who knows the room's link, apart from guests": "Любой, кто знает ссылку на комнату, кроме гостей", "Anyone who knows the room's link, including guests": "Любой, кто знает ссылку на комнату, включая гостей", "Are you sure you want to reject the invitation?": "Вы уверены что вы хотите отклонить приглашение?", - "Are you sure you want to upload the following files?": "Вы уверены что вы хотите отправить следующие файлы?", + "Are you sure you want to upload the following files?": "Вы уверены, что вы хотите отправить эти файлы?", "Banned users": "Заблокированные пользователи", "Bans user with given id": "Блокирует пользователя с заданным ID", "Blacklisted": "В черном списке", @@ -56,11 +56,11 @@ "Failed to upload file": "Не удалось отправить файл", "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.": "Для обеспечения безопасности ваша сессия была завершена. Пожалуйста, войдите снова.", - "Hangup": "Закончить", + "Hangup": "Повесить трубку", "Historical": "Архив", "Homeserver is": "Домашний сервер это", "Identity Server is": "Сервер идентификации это", @@ -107,13 +107,13 @@ "Unable to remove contact information": "Не удалось удалить контактную информацию", "Unable to verify email address.": "Не удалось проверить адрес email.", "Unban": "Разблокировать", - "Unencrypted room": "Незашифрованная комната", + "Unencrypted room": "Нешифрованная комната", "unencrypted": "без шифрования", "unknown device": "неизвестное устройство", "unknown error code": "неизвестный код ошибки", "Upload avatar": "Загрузить аватар", "Upload Files": "Отправка файлов", - "Upload file": "Отправка файла", + "Upload file": "Отправить файл", "User ID": "ID пользователя", "User Interface": "Пользовательский интерфейс", "User name": "Имя пользователя", @@ -121,7 +121,7 @@ "Verification Pending": "В ожидании подтверждения", "Verification": "Проверка", "verified": "проверенный", - "Video call": "Видеозвонок", + "Video call": "Видеовызов", "Voice call": "Голосовой вызов", "VoIP conference finished.": "Конференц-звонок окончен.", "VoIP conference started.": "Конференц-звонок начался.", @@ -278,7 +278,7 @@ "Failed to toggle moderator status": "Не удалось переключить статус модератора", "Fill screen": "Заполнить экран", "Hide read receipts": "Скрывать отметки о прочтении", - "Hide Text Formatting Toolbar": "Скрыть панель форматирования текста", + "Hide Text Formatting Toolbar": "Скрыть инструменты форматирования текста", "Incorrect verification code": "Неверный код подтверждения", "Interface Language": "Язык интерфейса", "Invalid alias format": "Недопустимый формат псевдонима", @@ -359,17 +359,17 @@ "Room": "Комната", "Cancel": "Отмена", "bold": "жирный", - "italic": "курсивный", + "italic": "курсив", "strike": "перечеркнутый", "underline": "подчеркнутый", "code": "код", "quote": "цитата", - "bullet": "список", - "numbullet": "нумерованный список", + "bullet": "элемент списка", + "numbullet": "элемент нумерованного списка", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Не удается подключиться к домашнему серверу через HTTP, так как в адресной строке браузера указан URL HTTPS. Используйте HTTPS или либо включите небезопасные сценарии.", "Dismiss": "Отклонить", "Custom Server Options": "Выбор другого сервера", - "Mute": "Беззвучный", + "Mute": "Заглушить", "Operation failed": "Сбой операции", "powered by Matrix": "Основано на Matrix", "Add a topic": "Добавить тему", @@ -412,7 +412,7 @@ "Import": "Импорт", "Incorrect username and/or password.": "Неверное имя пользователя и/или пароль.", "Invalid file%(extra)s": "Недопустимый файл%(extra)s", - "Invited": "Приглашен", + "Invited": "Приглашён", "Jump to first unread message.": "Перейти к первому непрочитанному сообщению.", "Message not sent due to unknown devices being present": "Сообщение не отправлено из-за присутствия неизвестных устройств", "Mobile phone number (optional)": "Номер мобильного телефона (не обязательно)", @@ -432,7 +432,7 @@ "Server may be unavailable, overloaded, or search timed out :(": "Сервер может быть недоступен, перегружен или поиск прекращен по тайм-ауту :(", "Server may be unavailable, overloaded, or the file too big": "Сервер может быть недоступен, перегружен или размер файла слишком большой", "Server may be unavailable, overloaded, or you hit a bug.": "Возможно, сервер недоступен, перегружен или случилась ошибка.", - "Server unavailable, overloaded, or something else went wrong.": "Сервер может быть недоступен, перегружен или что-то пошло не так.", + "Server unavailable, overloaded, or something else went wrong.": "Возможно, сервер недоступен, перегружен или что-то ещё пошло не так.", "Session ID": "ID сессии", "%(senderName)s set a profile picture.": "%(senderName)s установил(а) себе аватар.", "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s изменил(а) отображаемое имя на %(displayName)s.", @@ -448,7 +448,7 @@ "Tried to load a specific point in this room's timeline, but was unable to find it.": "Попытка загрузить выбранный интервал истории чата этой комнаты не удалась, так как запрошенный элемент не найден.", "Unable to load device list": "Не удалось загрузить список устройств", "Unknown (user, device) pair:": "Неизвестная пара пользователь-устройство:", - "Unmute": "Включить звук", + "Unmute": "Вернуть право речи", "Unrecognised command:": "Нераспознанная команда:", "Unrecognised room alias:": "Нераспознанное имя комнаты:", "Verified key": "Ключ проверен", @@ -600,9 +600,9 @@ "Room contains unknown devices": "Комната содержит непроверенные устройства", "%(roomName)s does not exist.": "%(roomName)s не существует.", "%(roomName)s is not accessible at this time.": "%(roomName)s на данный момент недоступна.", - "Seen by %(userName)s at %(dateTime)s": "Просмотрено %(userName)s в %(dateTime)s", + "Seen by %(userName)s at %(dateTime)s": "Прочитано %(userName)s в %(dateTime)s", "Send anyway": "Отправить в любом случае", - "Show Text Formatting Toolbar": "Показать панель инструментов форматирования текста", + "Show Text Formatting Toolbar": "Показать инструменты форматирования текста", "This invitation was sent to an email address which is not associated with this account:": "Это приглашение было отправлено на адрес email, не связанный с этой учетной записью:", "To link to a room it must have an address.": "Чтобы связаться с комнатой, она должна иметь адрес.", "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Не удалось установить соответствует ли адрес, по которому этому приглашение было послано, вашей учетной записи.", @@ -612,7 +612,7 @@ "Unnamed Room": "Комната без названия", "Unverified": "Не проверено", "Upload new:": "Загрузить новый:", - "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (уровень доступа %(powerLevelNumber)s)", + "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (уровень прав %(powerLevelNumber)s)", "Verified": "Проверено", "Would you like to accept or decline this invitation?": "Вы хотели бы подтвердить или отклонить это приглашение?", "(~%(count)s results)|one": "(~%(count)s результат)", @@ -755,7 +755,7 @@ "Unnamed room": "Комната без названия", "World readable": "Доступно всем", "Guests can join": "Гости могут присоединиться", - "No rooms to show": "Нет комнат для отображения", + "No rooms to show": "Нет комнат, нечего показывать", "Long Description (HTML)": "Длинное описание (HTML)", "Community Settings": "Настройки сообщества", "Invite to Community": "Пригласить в сообщество", @@ -906,10 +906,10 @@ "Please note you are logging into the %(hs)s server, not matrix.org.": "Обратите внимание, что вы заходите на сервер %(hs)s, а не на matrix.org.", "Custom of %(powerLevel)s": "Пользовательский уровень %(powerLevel)s", "

    HTML for your community's page

    \n

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

    \n

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

    \n": "

    HTML для страницы вашего сообщества

    \n

    \n Используйте подробное описание для представления вашего сообщества новым участникам, или\n поделитесь чем-нибудь важным, например ссылками\n

    \n

    \n Также вы можете использовать теги 'img'\n

    \n", - "%(duration)ss": "%(duration)sсек", - "%(duration)sm": "%(duration)sмин", - "%(duration)sh": "%(duration)sчас", - "%(duration)sd": "%(duration)sдн", + "%(duration)ss": "%(duration)s сек", + "%(duration)sm": "%(duration)s мин", + "%(duration)sh": "%(duration)s ч", + "%(duration)sd": "%(duration)s дн", "Your community hasn't got a Long Description, a HTML page to show to community members.
    Click here to open settings and give it one!": "У вашего сообщества нет подробного описания HTML-страницы для показа участникам.
    Щелкните здесь, чтобы открыть параметры и добавить его!", "Online for %(duration)s": "В сети %(duration)s", "Offline for %(duration)s": "Не в сети %(duration)s", @@ -948,9 +948,9 @@ "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Отправить или отменить сообщение сейчас.", "Message Replies": "Сообщения-ответы", "Send an encrypted reply…": "Отправить зашифрованный ответ…", - "Send a reply (unencrypted)…": "Отправить ответ (незашифрованный)…", + "Send a reply (unencrypted)…": "Отправить ответ (нешифрованный)…", "Send an encrypted message…": "Отправить зашифрованное сообщение…", - "Send a message (unencrypted)…": "Отправить сообщение (незашифрованное)…", + "Send a message (unencrypted)…": "Отправить сообщение (нешифрованное)…", "Replying": "Отвечает", "Minimize apps": "Свернуть приложения", "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Конфиденциальность важна для нас, поэтому мы не собираем никаких личных или идентифицируемых данных для нашей аналитики.", @@ -990,7 +990,7 @@ "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contian messages.": "Если вы отправили ошибку через GitHub, журналы отладки могут помочь нам выявить проблему. Журналы отладки содержат данные об использовании приложения, включая ваше имя пользователя, идентификаторы или псевдонимы комнат или групп, которые вы посетили, а также имена других пользователей. Они не содержат сообщений.", "Submit debug logs": "Отправка журналов отладки", "Opens the Developer Tools dialog": "Открывает Инструменты разработчика", - "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Просмотрено %(displayName)s (%(userName)s) в %(dateTime)s", + "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Прочитано %(displayName)s (%(userName)s) в %(dateTime)s", "Unable to join community": "Не удалось присоединиться к сообществу", "Unable to leave community": "Не удалось покинуть сообщество", "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Изменения имени и аватара, внесенные в ваше сообщество, могут не отображаться другим пользователям в течение 30 минут.", From c4a1fa531ad127316cb0d43cd4479200969927ee Mon Sep 17 00:00:00 2001 From: RainSlide Date: Tue, 24 Apr 2018 11:27:48 +0000 Subject: [PATCH 0853/1160] Translated using Weblate (Chinese (Simplified)) Currently translated at 97.5% (1132 of 1161 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hans/ --- src/i18n/strings/zh_Hans.json | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index ab299837c9..ee61c73c85 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -39,7 +39,7 @@ "Failed to change password. Is your password correct?": "修改密码失败。确认原密码输入正确吗?", "Failed to forget room %(errCode)s": "忘记聊天室失败,错误代码: %(errCode)s", "Failed to join room": "无法加入聊天室", - "Failed to kick": "踢人失败", + "Failed to kick": "移除失败", "Failed to leave room": "无法退出聊天室", "Failed to load timeline position": "无法加载时间轴位置", "Failed to lookup current room": "找不到当前聊天室", @@ -104,7 +104,7 @@ "Server may be unavailable or overloaded": "服务器可能不可用或者超载", "Server may be unavailable, overloaded, or search timed out :(": "服务器可能不可用、超载,或者搜索超时 :(", "Server may be unavailable, overloaded, or the file too big": "服务器可能不可用、超载,或者文件过大", - "Server may be unavailable, overloaded, or you hit a bug.": "服务器可能不可用、超载,或者你遇到了一个漏洞.", + "Server may be unavailable, overloaded, or you hit a bug.": "服务器可能不可用、超载,或者你遇到了一个 bug。", "Server unavailable, overloaded, or something else went wrong.": "服务器可能不可用、超载,或者其他东西出错了.", "Session ID": "会话 ID", "%(senderName)s set a profile picture.": "%(senderName)s 设置了头像。.", @@ -133,7 +133,7 @@ "Advanced": "高级", "Algorithm": "算法", "Always show message timestamps": "总是显示消息时间戳", - "%(names)s and %(lastPerson)s are typing": "%(names)s 和 %(lastPerson)s 正在打字", + "%(names)s and %(lastPerson)s are typing": "%(names)s 和 %(lastPerson)s 正在输入", "A new password must be entered.": "一个新的密码必须被输入。.", "%(senderName)s answered the call.": "%(senderName)s 接了通话。.", "An error has occurred.": "一个错误出现了。", @@ -246,7 +246,7 @@ "Invites user with given id to current room": "按照 ID 邀请指定用户加入当前聊天室", "'%(alias)s' is not a valid format for an address": "'%(alias)s' 不是一个合法的邮箱地址格式", "'%(alias)s' is not a valid format for an alias": "'%(alias)s' 不是一个合法的昵称格式", - "%(displayName)s is typing": "%(displayName)s 正在打字", + "%(displayName)s is typing": "%(displayName)s 正在输入", "Sign in with": "第三方登录", "Message not sent due to unknown devices being present": "消息未发送,因为有未知的设备存在", "Missing room_id in request": "请求中没有 聊天室 ID", @@ -395,7 +395,7 @@ "Drop here to tag %(section)s": "拖拽到这里标记 %(section)s", "Enable automatic language detection for syntax highlighting": "启用自动语言检测用于语法高亮", "Failed to change power level": "修改特权级别失败", - "Kick": "踢出", + "Kick": "移除", "Kicks user with given id": "按照 ID 移除特定的用户", "Last seen": "上次看见", "Level:": "级别:", @@ -449,7 +449,7 @@ "Passwords don't match.": "密码不匹配。", "I already have an account": "我已经有一个帐号", "Unblacklist": "移出黑名单", - "Not a valid Riot keyfile": "不是一个合法的 Riot 密钥文件", + "Not a valid Riot keyfile": "不是一个有效的 Riot 密钥文件", "%(targetName)s accepted an invitation.": "%(targetName)s 接受了一个邀请。", "Do you want to load widget from URL:": "你想从此 URL 加载小组件吗:", "Hide join/leave messages (invites/kicks/bans unaffected)": "隐藏加入/退出消息(邀请/踢出/封禁不受影响)", @@ -547,7 +547,7 @@ "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "警告:密钥验证失败!%(userId)s 和 device %(deviceId)s 的签名密钥是 \"%(fprint)s\",和提供的咪呀 \"%(fingerprint)s\" 不匹配。这可能意味着你的通信正在被窃听!", "%(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 already have existing direct chats with this user:": "你已经有和此用户的直接聊天:", "You're not in any rooms yet! Press to make a room or to browse the directory": "你现在还不再任何聊天室!按下 来创建一个聊天室或者 来浏览目录", "You cannot place a call with yourself.": "你不能和你自己发起一个通话。", "You have been kicked from %(roomName)s by %(userName)s.": "你已经被 %(userName)s 踢出了 %(roomName)s.", @@ -620,7 +620,7 @@ "Ongoing conference call%(supportedText)s.": "正在进行的会议通话 %(supportedText)s.", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s 修改了 %(roomName)s 的头像", "This will be your account name on the homeserver, or you can pick a different server.": "这将会成为你在 主服务器上的账户名,或者你可以选择一个 不同的服务器。", - "Your browser does not support the required cryptography extensions": "你的浏览器不支持所需的密码学扩展", + "Your browser does not support the required cryptography extensions": "你的浏览器不支持 Riot 所需的密码学特性", "Authentication check failed: incorrect password?": "身份验证失败:密码错误?", "This will allow you to reset your password and receive notifications.": "这将允许你重置你的密码和接收通知。", "Share without verifying": "不验证就分享", @@ -650,14 +650,14 @@ "%(senderName)s unbanned %(targetName)s.": "%(senderName)s 解除了 %(targetName)s 的封禁。", "(could not connect media)": "(无法连接媒体)", "%(senderName)s changed the pinned messages for the room.": "%(senderName)s 更改了聊天室的置顶消息。", - "%(names)s and %(count)s others are typing|other": "%(names)s 和另外 %(count)s 个人正在打字", - "%(names)s and %(count)s others are typing|one": "%(names)s 和另一个人正在打字", + "%(names)s and %(count)s others are typing|other": "%(names)s 和另外 %(count)s 个人正在输入", + "%(names)s and %(count)s others are typing|one": "%(names)s 和另一个人正在输入", "Send": "发送", "Message Pinning": "消息置顶", - "Disable Emoji suggestions while typing": "禁用打字时Emoji建议", + "Disable Emoji suggestions while typing": "输入时禁用 Emoji 建议", "Use compact timeline layout": "使用紧凑的时间线布局", "Hide avatar changes": "隐藏头像修改", - "Hide display name changes": "隐藏昵称的修改", + "Hide display name changes": "隐藏昵称修改", "Disable big emoji in chat": "禁用聊天中的大Emoji", "Never send encrypted messages to unverified devices in this room from this device": "在此设备上,在此聊天室中不向未经验证的设备发送加密的消息", "Enable URL previews for this room (only affects you)": "在此聊天室启用链接预览(只影响你)", @@ -754,10 +754,10 @@ "Message Replies": "消息回复", "Disable Peer-to-Peer for 1:1 calls": "在1:1通话中禁用点到点", "Enable inline URL previews by default": "默认启用网址预览", - "Disinvite this user?": "取消邀请这个用户?", - "Kick this user?": "踢出这个用户?", - "Unban this user?": "解除这个用户的封禁?", - "Ban this user?": "封紧这个用户?", + "Disinvite this user?": "取消邀请此用户?", + "Kick this user?": "移除此用户?", + "Unban this user?": "解除此用户的封禁?", + "Ban this user?": "封紧此用户?", "Send an encrypted reply…": "发送加密的回复…", "Send a reply (unencrypted)…": "发送回复(未加密)…", "Send an encrypted message…": "发送加密消息…", From 8c008c244b26494bee2e37fd838bf5f0d812ea91 Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Tue, 24 Apr 2018 14:08:31 +0000 Subject: [PATCH 0854/1160] Translated using Weblate (Russian) Currently translated at 100.0% (1161 of 1161 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 8753ce8940..2cf57d3f60 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -68,7 +68,7 @@ "Import E2E room keys": "Импорт ключей сквозного шифрования", "Invalid Email Address": "Недопустимый адрес email", "Invite new room members": "Пригласить в комнату новых участников", - "Invites": "Приглашает", + "Invites": "Приглашения", "Invites user with given id to current room": "Приглашает пользователя с заданным ID в текущую комнату", "Sign in with": "Войти, используя", "Joins room with given alias": "Входит в комнату с заданным псевдонимом", @@ -77,7 +77,7 @@ "Leave room": "Покинуть комнату", "Login as guest": "Войти как гость", "Logout": "Выйти", - "Low priority": "Низкий приоритет", + "Low priority": "Неважные", "Manage Integrations": "Управление интеграциями", "Mobile phone number": "Номер мобильного телефона", "Moderator": "Модератор", @@ -153,7 +153,7 @@ "Conference calls are not supported in encrypted rooms": "Конференц-связь не поддерживается в зашифрованных комнатах", "Conference calls are not supported in this client": "Конференц-связь в этом клиенте не поддерживается", "/ddg is not a command": "/ddg — это не команда", - "Drop here to tag %(section)s": "Перетащите сюда для тега %(section)s", + "Drop here to tag %(section)s": "Перетащите сюда, чтобы пометить как %(section)s", "%(senderName)s ended the call.": "%(senderName)s завершил(а) звонок.", "Existing Call": "Текущий вызов", "Failed to lookup current room": "Не удалось найти текущую комнату", @@ -201,7 +201,7 @@ "You need to be able to invite users to do that.": "Для этого вы должны иметь возможность приглашать пользователей.", "You cannot place VoIP calls in this browser.": "Звонки не поддерживаются в этом браузере.", "You are already in a call.": "Вы уже сделали звонок.", - "You are trying to access %(roomName)s.": "Вы пытаетесь получить доступ к %(roomName)s.", + "You are trying to access %(roomName)s.": "Вы пытаетесь войти в %(roomName)s.", "You cannot place a call with yourself.": "Вы не можете позвонить самому себе.", "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s отозвал(а) своё приглашение %(targetName)s.", "Sep": "Сен", @@ -352,7 +352,7 @@ "Turn Markdown off": "Выключить Markdown", "Turn Markdown on": "Включить Markdown", "Unknown room %(roomId)s": "Неизвестная комната %(roomId)s", - "You have been invited to join this room by %(inviterName)s": "%(inviterName)s приглашает вас в комнату", + "You have been invited to join this room by %(inviterName)s": "%(inviterName)s приглашает вас в эту комнату", "You seem to be uploading files, are you sure you want to quit?": "Похоже, вы отправляете файлы, вы уверены, что хотите выйти?", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s": "%(weekDayName)s, %(day)s %(monthName)s %(fullYear)s %(time)s", "Make Moderator": "Сделать модератором", @@ -592,8 +592,8 @@ "Reason: %(reasonText)s": "Причина: %(reasonText)s", "Rejoin": "Войти повторно", "Start authentication": "Начать проверку подлинности", - "This room": "В этой комнате", - "(~%(count)s results)|other": "(~%(count)s результаты)", + "This room": "Эта комната", + "(~%(count)s results)|other": "(~%(count)s результатов)", "Device Name": "Имя устройства", "Custom": "Пользовательские", "Decline": "Отклонить", @@ -603,9 +603,9 @@ "Seen by %(userName)s at %(dateTime)s": "Прочитано %(userName)s в %(dateTime)s", "Send anyway": "Отправить в любом случае", "Show Text Formatting Toolbar": "Показать инструменты форматирования текста", - "This invitation was sent to an email address which is not associated with this account:": "Это приглашение было отправлено на адрес email, не связанный с этой учетной записью:", + "This invitation was sent to an email address which is not associated with this account:": "Это приглашение было отправлено на email-адрес, не связанный с вашей учетной записью:", "To link to a room it must have an address.": "Чтобы связаться с комнатой, она должна иметь адрес.", - "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Не удалось установить соответствует ли адрес, по которому этому приглашение было послано, вашей учетной записи.", + "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Не удалось установить, что адрес в этом приглашении соответствует вашей учетной записи.", "Undecryptable": "Невозможно расшифровать", "Unencrypted message": "Нешифрованное сообщение", "unknown caller": "неизвестный абонент", @@ -614,12 +614,12 @@ "Upload new:": "Загрузить новый:", "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (уровень прав %(powerLevelNumber)s)", "Verified": "Проверено", - "Would you like to accept or decline this invitation?": "Вы хотели бы подтвердить или отклонить это приглашение?", + "Would you like to accept or decline this invitation?": "Вы хотите подтвердить или отклонить это приглашение?", "(~%(count)s results)|one": "(~%(count)s результат)", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Не удается подключиться к домашнему серверу - проверьте подключение, убедитесь, что ваш SSL-сертификат домашнего сервера является доверенным и что расширение браузера не блокирует запросы.", - "You have been banned from %(roomName)s by %(userName)s.": "%(userName)s заблокировал вас в %(roomName)s.", - "You have been kicked from %(roomName)s by %(userName)s.": "%(userName)s выгнал вас из %(roomName)s.", - "You may wish to login with a different account, or add this email to this account.": "При желании вы можете войти в систему с другой учетной записью или добавить этот адрес email в эту учетную запись.", + "You have been banned from %(roomName)s by %(userName)s.": "%(userName)s заблокировал(а) вас в %(roomName)s.", + "You have been kicked from %(roomName)s by %(userName)s.": "%(userName)s выгнал(а) вас из %(roomName)s.", + "You may wish to login with a different account, or add this email to this account.": "При желании вы можете войти в систему под другим именем или привязать этот email-адрес к вашей учетной записи.", "Your home server does not support device management.": "Ваш сервер не поддерживает управление устройствами.", "(could not connect media)": "(сбой подключения)", "(no answer)": "(нет ответа)", @@ -630,8 +630,8 @@ "Authentication check failed: incorrect password?": "Ошибка аутентификации: возможно, неправильный пароль?", "Do you want to set an email address?": "Хотите указать email-адрес?", "This will allow you to reset your password and receive notifications.": "Это позволит при необходимости сбросить пароль и получать уведомления.", - "Press to start a chat with someone": "Нажмите для начала чата с кем-либо", - "You're not in any rooms yet! Press to make a room or to browse the directory": "Вы еще не вошли ни в одну из комнат! Нажмите , чтобы создать комнату или для просмотра каталога", + "Press to start a chat with someone": "Нажмите , чтобы начать разговор с кем-либо", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Вы еще не вошли ни в одну из комнат! Нажмите , чтобы создать комнату, или , чтобы посмотреть каталог комнат", "To return to your account in future you need to set a password": "Чтобы вернуться к учетной записи в будущем, необходимо задать пароль", "Skip": "Пропустить", "Start verification": "Начать проверку", @@ -753,8 +753,8 @@ "No pinned messages.": "Нет прикрепленных сообщений.", "Loading...": "Загрузка...", "Unnamed room": "Комната без названия", - "World readable": "Доступно всем", - "Guests can join": "Гости могут присоединиться", + "World readable": "Открыта для чтения", + "Guests can join": "Открыта для участия", "No rooms to show": "Нет комнат, нечего показывать", "Long Description (HTML)": "Длинное описание (HTML)", "Community Settings": "Настройки сообщества", @@ -873,9 +873,9 @@ "%(items)s and %(count)s others|one": "%(items)s и один другой", "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "Сообщение отправлено на %(emailAddress)s. После перехода по ссылке в отправленном вам письме, щелкните ниже.", "Room Notification": "Уведомления комнаты", - "Drop here to tag direct chat": "Перетащите сюда, чтобы отметить как прямой чат", - "Drop here to restore": "Перетащиет сюда для восстановления", - "Drop here to demote": "Перетащите сюда для понижения", + "Drop here to tag direct chat": "Перетащите сюда, чтобы пометить как личный чат", + "Drop here to restore": "Перетащиет сюда, чтобы вернуть", + "Drop here to demote": "Перетащите сюда, чтобы понизить", "Community Invites": "Приглашения в сообщества", "Notify the whole room": "Уведомить всю комнату", "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Эти комнаты отображаются для участников сообщества на странице сообщества. Участники сообщества могут присоединиться к комнатам, щелкнув на них.", From 79c3335765eb9aee0376349076c05ec5c69df580 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 24 Apr 2018 16:05:14 +0100 Subject: [PATCH 0855/1160] Support origin lock in cross-origin renderer This adds a URL parameter to the cross-origin renderer that makes it only accept messages from a given domain. This adds an extra layer of security to the cross-origin iframe and is backwards compatible in both directions. --- src/components/views/messages/MFileBody.js | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/components/views/messages/MFileBody.js b/src/components/views/messages/MFileBody.js index 90efe24df3..fbce53e07a 100644 --- a/src/components/views/messages/MFileBody.js +++ b/src/components/views/messages/MFileBody.js @@ -1,5 +1,6 @@ /* Copyright 2015, 2016 OpenMarket Ltd +Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -99,16 +100,27 @@ Tinter.registerTintable(updateTintedDownloadImage); // overridable so that people running their own version of the client can // choose a different renderer. // -// To that end the first version of the blob generation will be the following +// To that end the current version of the blob generation is the following // html: // // // // This waits to receive a message event sent using the window.postMessage API. // When it receives the event it evals a javascript function in data.code and -// runs the function passing the event as an argument. +// runs the function passing the event as an argument. This version adds +// support for a query parameter controlling the origin from which messages +// will be processed as an extra layer of security (note that the default URL +// is still 'v1' since it is backwards compatible). // // In particular it means that the rendering function can be written as a // ordinary javascript function which then is turned into a string using @@ -325,6 +337,7 @@ module.exports = React.createClass({ if (this.context.appConfig && this.context.appConfig.cross_origin_renderer_url) { renderer_url = this.context.appConfig.cross_origin_renderer_url; } + renderer_url += "?origin=" + encodeURIComponent(document.origin); return (
    From 80837a9199dfc4302de86b60654dd8f56564b2fb Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 24 Apr 2018 17:53:23 +0100 Subject: [PATCH 0856/1160] s/contian/contain/g Fixes https://github.com/vector-im/riot-web/issues/6565 --- src/components/structures/UserSettings.js | 2 +- src/i18n/strings/bg.json | 2 +- src/i18n/strings/de_DE.json | 2 +- src/i18n/strings/en_EN.json | 2 +- src/i18n/strings/eu.json | 2 +- src/i18n/strings/fr.json | 2 +- src/i18n/strings/gl.json | 2 +- src/i18n/strings/hu.json | 2 +- src/i18n/strings/it.json | 2 +- src/i18n/strings/lv.json | 2 +- src/i18n/strings/nl.json | 2 +- src/i18n/strings/ru.json | 2 +- src/i18n/strings/sk.json | 2 +- src/i18n/strings/zh_Hans.json | 2 +- src/i18n/strings/zh_Hant.json | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 85223c4eef..7948f4fb5d 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -801,7 +801,7 @@ module.exports = React.createClass({ "us track down the problem. Debug logs contain application " + "usage data including your username, the IDs or aliases of " + "the rooms or groups you have visited and the usernames of " + - "other users. They do not contian messages.", + "other users. They do not contain messages.", ) }

    { this.props.children } -
    From 18e6d4aea745b38a873bbbc6fa813e5c47585cfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Thu, 26 Apr 2018 16:17:26 +0000 Subject: [PATCH 0894/1160] Translated using Weblate (French) Currently translated at 100.0% (1165 of 1165 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index b839ccb32f..0ff1467c3a 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -1159,5 +1159,9 @@ "Missing roomId.": "Identifiant de salon manquant.", "Picture": "Image", "Click here to create a GitHub issue.": "Cliquez ici pour créer un signalement sur GitHub.", - "Popout widget": "Détacher le widget" + "Popout widget": "Détacher le widget", + "Every page you use in the app": "Toutes les pages que vous utilisez dans l'application", + "e.g. ": "par ex. ", + "Your User Agent": "Votre user agent", + "Your device resolution": "La résolution de votre appareil" } From 64a682ef47545f1644bc4088f7af3dbf2febe0a6 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Thu, 26 Apr 2018 16:19:09 +0000 Subject: [PATCH 0895/1160] Translated using Weblate (Hungarian) Currently translated at 100.0% (1165 of 1165 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 759bf2b295..c29305cffc 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -1159,5 +1159,9 @@ "There are advanced notifications which are not shown here": "Vannak itt nem látható, haladó értesítések", "Missing roomId.": "Hiányzó szoba azonosító.", "Picture": "Kép", - "Popout widget": "Kiugró kisalkalmazás" + "Popout widget": "Kiugró kisalkalmazás", + "Every page you use in the app": "Minden oldal, amit az alkalmazásban használsz", + "e.g. ": "pl.: ", + "Your User Agent": "Felhasználói ügynököd", + "Your device resolution": "Eszközöd felbontása" } From fad20af51ff96f7339711176cf421576ca804c9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D1=80=D0=BA=D0=BE=20=D0=9C=2E=20=D0=9A=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D0=B8=D1=9B?= Date: Thu, 26 Apr 2018 17:01:16 +0000 Subject: [PATCH 0896/1160] Translated using Weblate (Serbian) Currently translated at 100.0% (1165 of 1165 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sr/ --- src/i18n/strings/sr.json | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index 5571d98c87..0f65adf355 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -1130,5 +1130,38 @@ "Collapse panel": "Скупи површ", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Са вашим тренутним прегледачем изглед и угођај ове апликације може бити скроз неправилан и неке могућности можда неће радити. Уколико желите да ипак пробате, можете наставити али ћете бити без подршке за било које проблеме на које налетите!", "Checking for an update...": "Проверавам ажурирања...", - "There are advanced notifications which are not shown here": "Постоје напредна обавештења која нису приказана овде" + "There are advanced notifications which are not shown here": "Постоје напредна обавештења која нису приказана овде", + "Your User Agent": "Ваш кориснички агент", + "Every page you use in the app": "Свака страница коју будете користили у апликацији", + "e.g. ": "Нпр.: ", + "Your device resolution": "Резолуција вашег уређаја", + "Popout widget": "Виџет за искакање", + "Missing roomId.": "Недостаје roomId.", + "Sticker Messages": "Поруке са налепницама", + "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Видео корисник %(displayName)s (%(userName)s) у %(dateTime)s", + "You don't currently have any stickerpacks enabled": "Тренутно немате омогућено било које паковање са налепницама", + "Add a stickerpack": "Додај паковање са налепницама", + "Stickerpack": "Паковање са налепницама", + "Hide Stickers": "Сакриј налепнице", + "Show Stickers": "Прикажи налепнице", + "Code": "Код", + "Picture": "Слика", + "Preparing to send logs": "Припремам се за слање записника", + "Logs sent": "Записници су послати", + "Failed to send logs: ": "Нисам успео да пошаљем записнике: ", + "Submit debug logs": "Пошаљи записнике за поправљање грешака", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Записници за поправљање грешака садрже податке о коришћењу апликације међу којима се налази ваше корисничко име, ИБ-јеви или алијаси посећених соба или група и корисничка имена других корисника. Не садрже саме поруке.", + "Click here to create a GitHub issue.": "Кликните овде да бисте пријавили проблем на Гитхабу (GitHub).", + "GitHub issue link:": "Веза до проблема на Гитхабу:", + "Notes:": "Напомене:", + "Unable to join community": "Не могу да приступим заједници", + "Unable to leave community": "Не могу да напустим заједницу", + "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Измене које сте начинили у имену ваше заједнице и на аватару можда неће бити видљиве другим корисницима највише 30 минута.", + "Join this community": "Приступи овој заједници", + "Leave this community": "Напусти ову заједницу", + "Who can join this community?": "Ко може приступити овој заједници?", + "Everyone": "Свако", + "Debug Logs Submission": "Слање извештаја за поправљање грешака", + "Opens the Developer Tools dialog": "Отвори прозор програмерских алатки", + "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Ако сте пријавили грешку преко Гитхаба, извештаји за поправљање грешака нам могу помоћи да лакше нађемо узрок. Извештаји садрже податке о коришћењу апликације и међу њих спада ваше корисничко име, ИБ-јеви или алијаси посећених соба или група и корисничка имена других корисника. Не садрже саме поруке." } From 71acf87c04e6b3063116cf0c40dc6a8ecb3faba5 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 27 Apr 2018 11:13:09 +0100 Subject: [PATCH 0897/1160] Add comments to _EventTile.scss Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- res/css/views/rooms/_EventTile.scss | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index 9217a64040..2339d92913 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -203,9 +203,10 @@ limitations under the License. text-decoration: none; } +// Explicit relationships so that it doesn't apply to nested EventTile components (e.g in Replies) .mx_EventTile_last > div > a > .mx_MessageTimestamp, .mx_EventTile:hover > div > a > .mx_MessageTimestamp, -.mx_EventTile.menu > div > a > .mx_MessageTimestamp { +.mx_EventTile.menu > div > a > .mx_MessageTimestamp { visibility: visible; } @@ -343,6 +344,7 @@ limitations under the License. border-left: $e2e-unverified-color 5px solid; } +// Explicit relationships so that it doesn't apply to nested EventTile components (e.g in Replies) .mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_line > a > .mx_MessageTimestamp, .mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_line > a > .mx_MessageTimestamp { left: 3px; @@ -355,6 +357,7 @@ limitations under the License. } */ +// Explicit relationships so that it doesn't apply to nested EventTile components (e.g in Replies) .mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_line > .mx_EventTile_e2eIcon, .mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_line > .mx_EventTile_e2eIcon { display: block; From 3de679b08491405493176bdf5e641429f3d7b69f Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 27 Apr 2018 11:14:50 +0100 Subject: [PATCH 0898/1160] Add comment to HtmlUtils.js Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/HtmlUtils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index 17566957c7..7f241310e6 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -186,7 +186,7 @@ const sanitizeHtmlParams = { ], allowedAttributes: { // custom ones first: - blockquote: ['data-mx-reply'], // for reply fallback + blockquote: ['data-mx-reply'], // used to allow explicit removal of a reply fallback blockquote, value ignored font: ['color', 'data-mx-bg-color', 'data-mx-color', 'style'], // custom to matrix span: ['data-mx-bg-color', 'data-mx-color', 'style'], // custom to matrix a: ['href', 'name', 'target', 'rel'], // remote target: custom to matrix From 82d117974f073dfc3eaff7937fe9aef8c7be65f0 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 27 Apr 2018 11:16:29 +0100 Subject: [PATCH 0899/1160] Remove unused import Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/RoomView.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 0a6fd7944f..8e24a75d68 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -45,7 +45,6 @@ import { KeyCode, isOnlyCtrlOrCmdKeyEvent } from '../../Keyboard'; import RoomViewStore from '../../stores/RoomViewStore'; import RoomScrollStateStore from '../../stores/RoomScrollStateStore'; import SettingsStore from "../../settings/SettingsStore"; -import Reply from "../views/elements/ReplyThread"; const DEBUG = false; let debuglog = function() {}; From db1401f48444b08780b1709d67c43f03403e72e3 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 11:19:14 +0100 Subject: [PATCH 0900/1160] Pass false to onFinished from BaseDialog Everywhere else, onFinished takes a boolean indicating whether the dialog was confirmed on cancelled, and had function that were expecting this variable and getting undefined. --- src/components/views/dialogs/BaseDialog.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index 21a2477c37..7959e7cb10 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -36,6 +36,9 @@ export default React.createClass({ propTypes: { // onFinished callback to call when Escape is pressed + // Take a boolean which is true is the dialog was dismissed + // with a positive / confirm action or false if it was + // cancelled (from BaseDialog, this is always false). onFinished: PropTypes.func.isRequired, // called when a key is pressed @@ -77,12 +80,12 @@ export default React.createClass({ if (e.keyCode === KeyCode.ESCAPE) { e.stopPropagation(); e.preventDefault(); - this.props.onFinished(); + this.props.onFinished(false); } }, _onCancelClick: function(e) { - this.props.onFinished(); + this.props.onFinished(false); }, render: function() { From 0323f8ed0c0db59746b98443d6d07250beab6cef Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 11:25:13 +0100 Subject: [PATCH 0901/1160] Wrap exception handling around all of loadSession The user might (probably does) have a session even if we haven't actually tried to load it yet, so wrap the whole loadSession code in the error handler we were using for restoring sessions so we gracefully handle exceptions that happen before trying to restore sessions too. Remove the catch in MatrixChat that sent you to the login screen. This is never the right way to handle an error condition: we should only display the login screen if we successfully determined that the user has no session, or they explicitly chose to blow their sessions away. --- src/Lifecycle.js | 120 +++++++++--------- src/components/structures/MatrixChat.js | 8 +- .../dialogs/SessionRestoreErrorDialog.js | 1 + 3 files changed, 67 insertions(+), 62 deletions(-) diff --git a/src/Lifecycle.js b/src/Lifecycle.js index 793b0f956b..6c35c6ed06 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -1,6 +1,7 @@ /* Copyright 2015, 2016 OpenMarket Ltd Copyright 2017 Vector Creations Ltd +Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -65,32 +66,33 @@ import sdk from './index'; * failed. */ export function loadSession(opts) { - const fragmentQueryParams = opts.fragmentQueryParams || {}; - let enableGuest = opts.enableGuest || false; - const guestHsUrl = opts.guestHsUrl; - const guestIsUrl = opts.guestIsUrl; - const defaultDeviceDisplayName = opts.defaultDeviceDisplayName; + return new Promise.resolve().then(() => { + const fragmentQueryParams = opts.fragmentQueryParams || {}; + let enableGuest = opts.enableGuest || false; + const guestHsUrl = opts.guestHsUrl; + const guestIsUrl = opts.guestIsUrl; + const defaultDeviceDisplayName = opts.defaultDeviceDisplayName; - if (!guestHsUrl) { - console.warn("Cannot enable guest access: can't determine HS URL to use"); - enableGuest = false; - } + if (!guestHsUrl) { + console.warn("Cannot enable guest access: can't determine HS URL to use"); + enableGuest = false; + } - if (enableGuest && - fragmentQueryParams.guest_user_id && - fragmentQueryParams.guest_access_token - ) { - console.log("Using guest access credentials"); - return _doSetLoggedIn({ - userId: fragmentQueryParams.guest_user_id, - accessToken: fragmentQueryParams.guest_access_token, - homeserverUrl: guestHsUrl, - identityServerUrl: guestIsUrl, - guest: true, - }, true).then(() => true); - } - - return _restoreFromLocalStorage().then((success) => { + if (enableGuest && + fragmentQueryParams.guest_user_id && + fragmentQueryParams.guest_access_token + ) { + console.log("Using guest access credentials"); + return _doSetLoggedIn({ + userId: fragmentQueryParams.guest_user_id, + accessToken: fragmentQueryParams.guest_access_token, + homeserverUrl: guestHsUrl, + identityServerUrl: guestIsUrl, + guest: true, + }, true).then(() => true); + } + return _restoreFromLocalStorage(); + }).then((success) => { if (success) { return true; } @@ -101,6 +103,8 @@ export function loadSession(opts) { // fall back to login screen return false; + }).catch((e) => { + return _handleLoadSessionFailure(e); }); } @@ -196,43 +200,43 @@ function _registerAsGuest(hsUrl, isUrl, defaultDeviceDisplayName) { // SessionStore to avoid bugs where the view becomes out-of-sync with // localStorage (e.g. teamToken, isGuest etc.) function _restoreFromLocalStorage() { - if (!localStorage) { - return Promise.resolve(false); - } - const hsUrl = localStorage.getItem("mx_hs_url"); - const isUrl = localStorage.getItem("mx_is_url") || 'https://matrix.org'; - const accessToken = localStorage.getItem("mx_access_token"); - const userId = localStorage.getItem("mx_user_id"); - const deviceId = localStorage.getItem("mx_device_id"); + return Promise.resolve().then(() => { + if (!localStorage) { + return Promise.resolve(false); + } + const hsUrl = localStorage.getItem("mx_hs_url"); + const isUrl = localStorage.getItem("mx_is_url") || 'https://matrix.org'; + const accessToken = localStorage.getItem("mx_access_token"); + const userId = localStorage.getItem("mx_user_id"); + const deviceId = localStorage.getItem("mx_device_id"); - let isGuest; - if (localStorage.getItem("mx_is_guest") !== null) { - isGuest = localStorage.getItem("mx_is_guest") === "true"; - } else { - // legacy key name - isGuest = localStorage.getItem("matrix-is-guest") === "true"; - } + let isGuest; + if (localStorage.getItem("mx_is_guest") !== null) { + isGuest = localStorage.getItem("mx_is_guest") === "true"; + } else { + // legacy key name + isGuest = localStorage.getItem("matrix-is-guest") === "true"; + } - if (accessToken && userId && hsUrl) { - console.log(`Restoring session for ${userId}`); - return _doSetLoggedIn({ - userId: userId, - deviceId: deviceId, - accessToken: accessToken, - homeserverUrl: hsUrl, - identityServerUrl: isUrl, - guest: isGuest, - }, false).catch((e) => { - return _handleRestoreFailure(e); - }).then(() => true); - } else { - console.log("No previous session found."); - return Promise.resolve(false); - } + if (accessToken && userId && hsUrl) { + console.log(`Restoring session for ${userId}`); + return _doSetLoggedIn({ + userId: userId, + deviceId: deviceId, + accessToken: accessToken, + homeserverUrl: hsUrl, + identityServerUrl: isUrl, + guest: isGuest, + }, false).then(() => true); + } else { + console.log("No previous session found."); + return Promise.resolve(false); + } + }); } -function _handleRestoreFailure(e) { - console.log("Unable to restore session", e); +function _handleLoadSessionFailure(e) { + console.log("Unable to load session", e); const def = Promise.defer(); const SessionRestoreErrorDialog = @@ -253,7 +257,7 @@ function _handleRestoreFailure(e) { } // try, try again - return _restoreFromLocalStorage(); + return loadSession(); }); } diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 1eb96c9f11..cdeb99ef53 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -1,7 +1,7 @@ /* Copyright 2015, 2016 OpenMarket Ltd Copyright 2017 Vector Creations Ltd -Copyright 2017 New Vector Ltd +Copyright 2017, 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -351,15 +351,15 @@ export default React.createClass({ guestIsUrl: this.getCurrentIsUrl(), defaultDeviceDisplayName: this.props.defaultDeviceDisplayName, }); - }).catch((e) => { - console.error('Error attempting to load session', e); - return false; }).then((loadedSession) => { if (!loadedSession) { // fall back to showing the login screen dis.dispatch({action: "start_login"}); } }); + // Note we don't catch errors from this: we catch everything within + // loadSession as there's logic there to ask the user if they want + // to try logging out. }).done(); }, diff --git a/src/components/views/dialogs/SessionRestoreErrorDialog.js b/src/components/views/dialogs/SessionRestoreErrorDialog.js index 401550043b..f101381ebf 100644 --- a/src/components/views/dialogs/SessionRestoreErrorDialog.js +++ b/src/components/views/dialogs/SessionRestoreErrorDialog.js @@ -1,5 +1,6 @@ /* Copyright 2017 Vector Creations Ltd +Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From 97fecaedc2d53fd1f0c8f542c4130d45e1706f92 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 27 Apr 2018 11:26:42 +0100 Subject: [PATCH 0902/1160] improve wording Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/context_menus/MessageContextMenu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/context_menus/MessageContextMenu.js b/src/components/views/context_menus/MessageContextMenu.js index dc6f4d45d0..99ec493ced 100644 --- a/src/components/views/context_menus/MessageContextMenu.js +++ b/src/components/views/context_menus/MessageContextMenu.js @@ -40,7 +40,7 @@ module.exports = React.createClass({ /* an optional EventTileOps implementation that can be used to unhide preview widgets */ eventTileOps: PropTypes.object, - /* an optional function which allows to collapse reply thread */ + /* an optional function to be called when the user clicks collapse thread, if not provided hide button */ collapseReplyThread: PropTypes.func, /* callback called when the menu is dismissed */ From 88f48914b41035bd7c4a8cefa9a9ed2c6d12582a Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 27 Apr 2018 11:28:17 +0100 Subject: [PATCH 0903/1160] improve comment Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 57401a03f2..ed284c1da2 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -31,7 +31,7 @@ export default class ReplyThread extends React.Component { static propTypes = { // the latest event in this chain of replies parentEv: PropTypes.instanceOf(MatrixEvent), - // called when the preview's contents has loaded + // called when the ReplyThread contents has changed, including EventTiles thereof onWidgetLoad: PropTypes.func.isRequired, }; From 3ba9f560d44b2c62998f2cc85c1494bf76bfa3ff Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 27 Apr 2018 11:30:47 +0100 Subject: [PATCH 0904/1160] get MatrixClient from context Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index ed284c1da2..51cb53efea 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -18,9 +18,8 @@ import sdk from '../../../index'; import {_t} from '../../../languageHandler'; import PropTypes from 'prop-types'; import dis from '../../../dispatcher'; -import MatrixClientPeg from '../../../MatrixClientPeg'; import {wantsDateSeparator} from '../../../DateUtils'; -import {MatrixEvent} from 'matrix-js-sdk'; +import {MatrixEvent, MatrixClient} from 'matrix-js-sdk'; import {makeEventPermalink, makeUserPermalink} from "../../../matrix-to"; import SettingsStore from "../../../settings/SettingsStore"; @@ -35,6 +34,10 @@ export default class ReplyThread extends React.Component { onWidgetLoad: PropTypes.func.isRequired, }; + static contextTypes = { + matrixClient: PropTypes.instanceOf(MatrixClient).isRequired, + }; + constructor(props, context) { super(props, context); @@ -58,7 +61,7 @@ export default class ReplyThread extends React.Component { componentWillMount() { this.unmounted = false; - this.room = MatrixClientPeg.get().getRoom(this.props.parentEv.getRoomId()); + this.room = this.context.matrixClient.getRoom(this.props.parentEv.getRoomId()); this.initialize(); } @@ -121,7 +124,7 @@ export default class ReplyThread extends React.Component { if (event) return event; try { - await MatrixClientPeg.get().getEventTimeline(room.getUnfilteredTimelineSet(), eventId); + await this.context.matrixClient.getEventTimeline(room.getUnfilteredTimelineSet(), eventId); } catch (e) { return null; } @@ -257,7 +260,7 @@ export default class ReplyThread extends React.Component { } else if (this.state.loadedEv) { const ev = this.state.loadedEv; const Pill = sdk.getComponent('elements.Pill'); - const room = MatrixClientPeg.get().getRoom(ev.getRoomId()); + const room = this.context.matrixClient.getRoom(ev.getRoomId()); header =
    { _t('In reply to ', {}, { From fdf63fd440422acb4b8ace3e647e9987930a8212 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 27 Apr 2018 11:31:04 +0100 Subject: [PATCH 0905/1160] replace concat on comment from review Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 51cb53efea..1e23dfdc8a 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -132,7 +132,7 @@ export default class ReplyThread extends React.Component { } onQuoteClick() { - const events = [this.state.loadedEv].concat(this.state.events); + const events = [this.state.loadedEv, ...this.state.events]; this.setState({ loadedEv: null, From ca766df598ba5594e8512dd3c56e677119f28a79 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 27 Apr 2018 11:32:04 +0100 Subject: [PATCH 0906/1160] call onWidgetLoad on componentDidUpdate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 1e23dfdc8a..d6d6c9fb44 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -65,6 +65,10 @@ export default class ReplyThread extends React.Component { this.initialize(); } + componentDidUpdate() { + this.props.onWidgetLoad(); + } + componentWillUnmount() { this.unmounted = true; } @@ -105,7 +109,7 @@ export default class ReplyThread extends React.Component { if (!inReplyTo) { this.setState({ loading: false, - }, this.props.onWidgetLoad); + }); return; } @@ -113,9 +117,9 @@ export default class ReplyThread extends React.Component { if (this.unmounted) return; if (loadedEv) { - this.setState({loadedEv}, this.props.onWidgetLoad); + this.setState({loadedEv}); } else { - this.setState({err: true}, this.props.onWidgetLoad); + this.setState({err: true}); } } From 3050553fc2880f585e951542336b77af333e3cdf Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 27 Apr 2018 11:44:14 +0100 Subject: [PATCH 0907/1160] rename and change getInReplyTo Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index d6d6c9fb44..a7a026508c 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -83,7 +83,7 @@ export default class ReplyThread extends React.Component { async initialize() { const {parentEv} = this.props; - const inReplyTo = ReplyThread.getInReplyTo(parentEv); + const inReplyTo = ReplyThread.getParentEventId(parentEv); if (!inReplyTo) { this.setState({err: true}); return; @@ -104,7 +104,7 @@ export default class ReplyThread extends React.Component { async loadNextEvent() { if (this.unmounted) return; const ev = this.state.events[0]; - const inReplyTo = ReplyThread.getInReplyTo(ev); + const inReplyTo = ReplyThread.getParentEventId(ev); if (!inReplyTo) { this.setState({ @@ -146,13 +146,13 @@ export default class ReplyThread extends React.Component { dis.dispatch({action: 'focus_composer'}); } - static getInReplyTo(ev) { + static getParentEventId(ev) { if (!ev || ev.isRedacted()) return; const mRelatesTo = ev.getWireContent()['m.relates_to']; if (mRelatesTo && mRelatesTo['m.in_reply_to']) { const mInReplyTo = mRelatesTo['m.in_reply_to']; - if (mInReplyTo['event_id']) return mInReplyTo; + if (mInReplyTo && mInReplyTo['event_id']) return mInReplyTo['event_id']; } } @@ -173,7 +173,7 @@ export default class ReplyThread extends React.Component { if (!ev) return null; let {body, formatted_body: html} = ev.getContent(); - if (this.getInReplyTo(ev)) { + if (this.getParentEventId(ev)) { if (body) body = this.stripPlainReply(body); if (html) html = this.stripHTMLReply(html); } @@ -195,7 +195,6 @@ export default class ReplyThread extends React.Component { } break; } - case 'm.image': html = `
    In reply to ${mxid}` + `
    sent an image.
    `; @@ -245,7 +244,7 @@ export default class ReplyThread extends React.Component { } static getThread(parentEv, onWidgetLoad, ref) { - if (!SettingsStore.isFeatureEnabled("feature_rich_quoting") || !ReplyThread.getInReplyTo(parentEv)) { + if (!SettingsStore.isFeatureEnabled("feature_rich_quoting") || !ReplyThread.getParentEventId(parentEv)) { return
    ; } return ; From 68dd57f56e590c3490444697466b3744fa26a260 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 27 Apr 2018 11:47:18 +0100 Subject: [PATCH 0908/1160] rename two methods Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 4 ++-- src/components/views/rooms/EventTile.js | 4 ++-- src/components/views/rooms/MessageComposerInput.js | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index a7a026508c..473d6ef201 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -232,7 +232,7 @@ export default class ReplyThread extends React.Component { return {body, html}; } - static getReplyEvContent(ev) { + static makeReplyMixIn(ev) { if (!ev) return {}; return { 'm.relates_to': { @@ -243,7 +243,7 @@ export default class ReplyThread extends React.Component { }; } - static getThread(parentEv, onWidgetLoad, ref) { + static makeThread(parentEv, onWidgetLoad, ref) { if (!SettingsStore.isFeatureEnabled("feature_rich_quoting") || !ReplyThread.getParentEventId(parentEv)) { return
    ; } diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 50c0e29ed4..56ac082f2a 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -666,7 +666,7 @@ module.exports = withMatrixClient(React.createClass({ { this._renderE2EPadlock() } { this.props.tileShape === 'reply_preview' - && ReplyThread.getThread(this.props.mxEvent, this.props.onWidgetLoad, 'replyThread') + && ReplyThread.makeThread(this.props.mxEvent, this.props.onWidgetLoad, 'replyThread') } { this._renderE2EPadlock() } - { ReplyThread.getThread(this.props.mxEvent, this.props.onWidgetLoad, 'replyThread') } + { ReplyThread.makeThread(this.props.mxEvent, this.props.onWidgetLoad, 'replyThread') } Date: Fri, 27 Apr 2018 12:12:01 +0100 Subject: [PATCH 0909/1160] improve stripPlainReply comment and fix leading NewLine Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 473d6ef201..b2ea8a90a3 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -158,8 +158,11 @@ export default class ReplyThread extends React.Component { // Part of Replies fallback support static stripPlainReply(body) { + // Removes lines beginning with `> ` until you reach one that doesn't. const lines = body.split('\n'); while (lines.length && lines[0].startsWith('> ')) lines.shift(); + // Reply fallback has a blank line after it, so remove it to prevent leading newline + if (lines[0] === '') lines.shift(); return lines.join('\n'); } From 6d9e07580bab42722e3d0c89bd7e13720845682b Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 12:38:49 +0100 Subject: [PATCH 0910/1160] UI fixes in SessionRestoreErrorDialog * Make the 'delete my data' button not the default * Make it red * Give it a confirmation dialog * Remove the 'cancel' button: what does it mean to cancel an error? In this case, it tried again and almost certainly got the same error. * Remove the top-right 'x' and don't cancel on esc for the same reason. * Move 'send bug report' to a button rather than a 'click here' link * Add a 'refresh' button which, even if it's no more likely to work, will at least look like it's doing something (it's mostly so if you don't have a bug report endpoint, there's still a button other than the one that deletes all your data). --- res/css/_common.scss | 1 + src/components/views/dialogs/BaseDialog.js | 20 +++++- .../dialogs/SessionRestoreErrorDialog.js | 70 +++++++++++-------- .../views/elements/DialogButtons.js | 18 +++-- src/i18n/strings/en_EN.json | 13 ++-- 5 files changed, 79 insertions(+), 43 deletions(-) diff --git a/res/css/_common.scss b/res/css/_common.scss index e81c228430..c4cda6821e 100644 --- a/res/css/_common.scss +++ b/res/css/_common.scss @@ -250,6 +250,7 @@ textarea { .mx_Dialog button.danger, .mx_Dialog input[type="submit"].danger { background-color: $warning-color; border: solid 1px $warning-color; + color: $accent-fg-color; } .mx_Dialog button:disabled, .mx_Dialog input[type="submit"]:disabled { diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index 7959e7cb10..fb116cdffe 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -1,5 +1,6 @@ /* Copyright 2017 Vector Creations Ltd +Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -41,6 +42,13 @@ export default React.createClass({ // cancelled (from BaseDialog, this is always false). onFinished: PropTypes.func.isRequired, + // Whether the dialog should have a 'close' button that will + // cause the dialog to be cancelled. This should only be set + // to true if there is nothing the app can sensibly do if the + // dialog is cancelled, eg. "We can't restore your session and + // the app cannot work". + hasCancel: PropTypes.bool, + // called when a key is pressed onKeyDown: PropTypes.func, @@ -59,6 +67,12 @@ export default React.createClass({ contentId: React.PropTypes.string, }, + getDefaultProps: function() { + return { + hasCancel: true, + }; + }, + childContextTypes: { matrixClient: PropTypes.instanceOf(MatrixClient), }, @@ -77,7 +91,7 @@ export default React.createClass({ if (this.props.onKeyDown) { this.props.onKeyDown(e); } - if (e.keyCode === KeyCode.ESCAPE) { + if (this.props.hasCancel && e.keyCode === KeyCode.ESCAPE) { e.stopPropagation(); e.preventDefault(); this.props.onFinished(false); @@ -104,11 +118,11 @@ export default React.createClass({ // AT users can skip its presentation. aria-describedby={this.props.contentId} > - - + : null }
    { this.props.title }
    diff --git a/src/components/views/dialogs/SessionRestoreErrorDialog.js b/src/components/views/dialogs/SessionRestoreErrorDialog.js index f101381ebf..2e152df4b0 100644 --- a/src/components/views/dialogs/SessionRestoreErrorDialog.js +++ b/src/components/views/dialogs/SessionRestoreErrorDialog.js @@ -31,63 +31,73 @@ export default React.createClass({ onFinished: PropTypes.func.isRequired, }, - componentDidMount: function() { - if (this.refs.bugreportLink) { - this.refs.bugreportLink.focus(); - } - }, - _sendBugReport: function() { const BugReportDialog = sdk.getComponent("dialogs.BugReportDialog"); Modal.createTrackedDialog('Session Restore Error', 'Send Bug Report Dialog', BugReportDialog, {}); }, - _onContinueClick: function() { - this.props.onFinished(true); + _onClearStorageClick: function() { + const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); + Modal.createTrackedDialog('Session Restore Confirm Logout', '', QuestionDialog, { + title: _t("Sign out"), + description: +
    { _t("Log out and remove encryption keys?") }
    , + button: _t("Sign out"), + danger: true, + onFinished: this.props.onFinished, + }); }, - _onCancelClick: function() { - this.props.onFinished(false); + _onRefreshClick: function() { + // Is this likely to help? Probably not, but giving only one button + // that clears your storage seems awful. + window.location.reload(true); }, render: function() { const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); - let bugreport; + let dialogButtons; if (SdkConfig.get().bug_report_endpoint_url) { - bugreport = ( -

    - { _t( - "Otherwise, click here to send a bug report.", - {}, - { 'a': (sub) => { sub } }, - ) } -

    - ); + dialogButtons = + + + } else { + dialogButtons = + + } - const shouldFocusContinueButton =!(bugreport==true); return (
    -

    { _t("We encountered an error trying to restore your previous session. If " + - "you continue, you will need to log in again, and encrypted chat " + - "history will be unreadable.") }

    +

    { _t("We encountered an error trying to restore your previous session.") }

    { _t("If you have previously used a more recent version of Riot, your session " + "may be incompatible with this version. Close this window and return " + "to the more recent version.") }

    - { bugreport } +

    { _t("Clearing your browser's storage may fix the problem, but will sign you " + + "out and cause any encrypted chat history to become unreadable.") }

    - + { dialogButtons }
    ); }, diff --git a/src/components/views/elements/DialogButtons.js b/src/components/views/elements/DialogButtons.js index 537f906a74..73e47cbde2 100644 --- a/src/components/views/elements/DialogButtons.js +++ b/src/components/views/elements/DialogButtons.js @@ -1,5 +1,6 @@ /* Copyright 2017 Aidan Gauland +Copyright 2018 New Vector Ltd. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,8 +15,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; - import React from "react"; import PropTypes from "prop-types"; import { _t } from '../../../languageHandler'; @@ -33,12 +32,21 @@ module.exports = React.createClass({ // onClick handler for the primary button. onPrimaryButtonClick: PropTypes.func.isRequired, + // should there be a cancel button? default: true + hasCancel: PropTypes.bool, + // onClick handler for the cancel button. - onCancel: PropTypes.func.isRequired, + onCancel: PropTypes.func, focus: PropTypes.bool, }, + getDefaultProps: function() { + return { + hasCancel: true, + } + }, + _onCancelClick: function() { this.props.onCancel(); }, @@ -57,9 +65,9 @@ module.exports = React.createClass({ { this.props.primaryButton } { this.props.children } - + : null }
    ); }, diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 33f18e47a4..3c8dd5b66f 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -103,7 +103,6 @@ "You need to be logged in.": "You need to be logged in.", "You need to be able to invite users to do that.": "You need to be able to invite users to do that.", "Unable to create widget.": "Unable to create widget.", - "Popout widget": "Popout widget", "Missing roomId.": "Missing roomId.", "Failed to send request.": "Failed to send request.", "This room is not recognised.": "This room is not recognised.", @@ -655,6 +654,7 @@ "Delete widget": "Delete widget", "Revoke widget access": "Revoke widget access", "Minimize apps": "Minimize apps", + "Popout widget": "Popout widget", "Picture": "Picture", "Edit": "Edit", "Create new room": "Create new room", @@ -807,11 +807,15 @@ "Ignore request": "Ignore request", "Loading device info...": "Loading device info...", "Encryption key request": "Encryption key request", - "Otherwise, click here to send a bug report.": "Otherwise, click here to send a bug report.", + "Sign out": "Sign out", + "Log out and remove encryption keys?": "Log out and remove encryption keys?", + "Send Logs": "Send Logs", + "Clear Storage and Sign Out": "Clear Storage and Sign Out", + "Refresh": "Refresh", "Unable to restore session": "Unable to restore session", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.", + "We encountered an error trying to restore your previous session.": "We encountered an error trying to restore your previous session.", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.", - "Continue anyway": "Continue anyway", + "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.", "Invalid Email Address": "Invalid Email Address", "This doesn't appear to be a valid email address": "This doesn't appear to be a valid email address", "Verification Pending": "Verification Pending", @@ -1015,7 +1019,6 @@ "Status.im theme": "Status.im theme", "Can't load user settings": "Can't load user settings", "Server may be unavailable or overloaded": "Server may be unavailable or overloaded", - "Sign out": "Sign out", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.", "Success": "Success", "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them", From bec81d82d2dba1964d4eb11a54271c12995e7491 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 12:57:01 +0100 Subject: [PATCH 0911/1160] Update version of hoek --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6dd02674be..23ffa68bef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3719,9 +3719,9 @@ "integrity": "sha1-uKnFSTISqTkvAiK2SclhFJfr+4g=" }, "hoek": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", - "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==" + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==" }, "home-or-tmp": { "version": "2.0.0", From 8efac6117e0e757c3a57f32fd7c3636cf264a34a Mon Sep 17 00:00:00 2001 From: RainSlide Date: Fri, 27 Apr 2018 08:03:34 +0000 Subject: [PATCH 0912/1160] Translated using Weblate (Chinese (Simplified)) Currently translated at 97.2% (1133 of 1165 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hans/ --- src/i18n/strings/zh_Hans.json | 52 ++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index 37fb480d98..96d4302b90 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -307,7 +307,7 @@ "Privacy warning": "隐私警告", "Private Chat": "私聊", "Privileged Users": "特权用户", - "Reason": "原因", + "Reason": "理由", "Register": "注册", "%(targetName)s rejected the invitation.": "%(targetName)s 拒绝了邀请。", "Reject invitation": "拒绝邀请", @@ -354,8 +354,8 @@ "Incorrect password": "密码错误", "This action is irreversible.": "此操作不可逆。", "To continue, please enter your password.": "请输入你的密码继续。", - "Device name": "设备名", - "Device Name": "设备名", + "Device name": "设备名称", + "Device Name": "设备名称", "Device key": "设备密钥", "Verify device": "验证设备", "I verify that the keys match": "我验证密钥匹配", @@ -397,12 +397,12 @@ "Failed to change power level": "修改特权级别失败", "Kick": "移除", "Kicks user with given id": "按照 ID 移除特定的用户", - "Last seen": "上次看见", + "Last seen": "最近一次上线", "Level:": "级别:", "Local addresses for this room:": "这个聊天室的本地地址:", "New passwords must match each other.": "新密码必须互相匹配。", "Power level must be positive integer.": "权限级别必须是正整数。", - "Reason: %(reasonText)s": "原因: %(reasonText)s", + "Reason: %(reasonText)s": "理由: %(reasonText)s", "Revoke Moderator": "撤销主持人", "Revoke widget access": "撤销小部件的访问", "Remote addresses for this room:": "这个聊天室的远程地址:", @@ -450,7 +450,7 @@ "I already have an account": "我已经有一个帐号", "Unblacklist": "移出黑名单", "Not a valid Riot keyfile": "不是一个有效的 Riot 密钥文件", - "%(targetName)s accepted an invitation.": "%(targetName)s 接受了一个邀请。", + "%(targetName)s accepted an invitation.": "%(targetName)s 已接受邀请。", "Do you want to load widget from URL:": "你想从此 URL 加载小组件吗:", "Hide join/leave messages (invites/kicks/bans unaffected)": "隐藏加入/退出消息(邀请/踢出/封禁不受影响)", "Integrations Error": "集成错误", @@ -461,7 +461,7 @@ "Please check your email and click on the link it contains. Once this is done, click continue.": "请检查你的电子邮箱并点击里面包含的链接。完成时请点击继续。", "Press to start a chat with someone": "按下 来开始和某个人聊天", "%(senderName)s removed their profile picture.": "%(senderName)s 移除了他们的头像。", - "%(senderName)s requested a VoIP conference.": "%(senderName)s 请求一个 VoIP 会议。", + "%(senderName)s requested a VoIP conference.": "%(senderName)s 请求一次 VoIP 会议。", "Seen by %(userName)s at %(dateTime)s": "在 %(dateTime)s 被 %(userName)s 看到", "Tagged as: ": "标记为: ", "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "验证码将发送至 +%(msisdn)s,请输入收到的验证码", @@ -514,7 +514,7 @@ "You are trying to access %(roomName)s.": "你正在尝试访问 %(roomName)s.", "You cannot place VoIP calls in this browser.": "你不能在这个浏览器中发起 VoIP 通话。", "You do not have permission to post to this room": "你没有发送到这个聊天室的权限", - "You have been invited to join this room by %(inviterName)s": "你已经被 %(inviterName)s 邀请加入这个聊天室", + "You have been invited to join this room by %(inviterName)s": "您已被 %(inviterName)s 邀请加入这个聊天室", "You seem to be in a call, are you sure you want to quit?": "您似乎正在进行通话,确定要退出吗?", "You seem to be uploading files, are you sure you want to quit?": "您似乎正在上传文件,确定要退出吗?", "You should not yet trust it to secure data": "你不应该相信它来保护你的数据", @@ -550,7 +550,7 @@ "You already have existing direct chats with this user:": "你已经有和此用户的直接聊天:", "You're not in any rooms yet! Press to make a room or to browse the directory": "你现在还不再任何聊天室!按下 来创建一个聊天室或者 来浏览目录", "You cannot place a call with yourself.": "你不能和你自己发起一个通话。", - "You have been kicked from %(roomName)s by %(userName)s.": "你已经被 %(userName)s 踢出了 %(roomName)s.", + "You have been kicked from %(roomName)s by %(userName)s.": "您已被 %(userName)s 从聊天室 %(roomName)s 中移除。", "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "你已经登出了所有的设备并不再接收推送通知。要重新启用通知,请再在每个设备上登录", "You have disabled URL previews by default.": "你已经默认 禁用 链接预览。", "You have enabled URL previews by default.": "你已经默认 启用 链接预览。", @@ -599,7 +599,7 @@ "Unknown devices": "未知设备", "Unknown Address": "未知地址", "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s 删除了他们的昵称 (%(oldDisplayName)s).", - "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "你提供的签名密钥和你从 %(userId)s 的设备 %(deviceId)s 收到的签名密钥匹配。设备被标记为已验证。", + "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "您提供的签名密钥和你从 %(userId)s 的设备 %(deviceId)s 收到的签名密钥匹配。设备被标记为已验证。", "These are experimental features that may break in unexpected ways": "这些是可能以意外的方式坏掉的实验性的特性", "The visibility of existing history will be unchanged": "现有历史记录的可见性不会被改变", "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s 打开了端到端加密 (算法 %(algorithm)s).", @@ -784,7 +784,7 @@ "Community Name": "社区名", "Community ID": "社区 ID", "example": "例子", - "This setting cannot be changed later!": "这个设置以后不能被修改!", + "This setting cannot be changed later!": "此设置在未来将无法修改!", "Add a Room": "添加一个聊天室", "Add a User": "添加一个用户", "Unable to accept invite": "无法接受邀请", @@ -911,9 +911,9 @@ "Matrix ID": "Matrix ID", "Matrix Room ID": "Matrix 聊天室 ID", "Block users on other matrix homeservers from joining this room": "禁止其他 Matrix 主服务器上的用户加入此聊天室", - "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "要验证此设备是否可信,请通过其他方式(例如面对面交换或拨打电话)与其拥有者联系,并询问他们该设备的用户设置中的密钥是否与以下密钥匹配:", + "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "为验证此设备是否可信,请通过其他方式(例如面对面交换或拨打电话)与其拥有者联系,并询问他们该设备的用户设置中的密钥是否与以下密钥匹配:", "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "如果匹配,请点击下面的验证按钮。 如果不匹配,那么这可能说明其他人正在盗用此设备,而您应当点击黑名单按钮。", - "In future this verification process will be more sophisticated.": "在未来,这个验证过程将会更加精致、巧妙一些。", + "In future this verification process will be more sophisticated.": "未来,这个验证过程将会变得更加精致、巧妙一些。", "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "我们建议您对每台设备进行验证以保证它们属于其合法所有者,但是您可以在不验证它们的情况下重新发送消息。", "

    HTML for your community's page

    \n

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

    \n

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

    \n": "

    社区页面的 HTML 代码

    \n

    \n 你可以给社区的新成员们写些长长的社区简介来引导他们,或者放置\n 一些重要的链接\n

    \n

    \n 你甚至可以使用 标签\n

    \n", "Add rooms to the community summary": "将聊天室添加到社区简介", @@ -1009,19 +1009,19 @@ "This Room": "此聊天室", "The Home Server may be too old to support third party networks": "主服务器可能太老旧无法支持第三方网络", "Noisy": "吵闹", - "Error saving email notification preferences": "保存电子邮件通知的首选项时出错", + "Error saving email notification preferences": "保存电子邮件通知选项时出错", "Messages containing my display name": "消息中含有我的显示名称", "Messages in one-to-one chats": "一对一聊天种的消息", "Unavailable": "无法获得", "View Decrypted Source": "查看解密的来源", - "Failed to update keywords": "无法更新关键字", + "Failed to update keywords": "无法更新关键词", "Notes:": "记录:", "remove %(name)s from the directory.": "从目录中移除 %(name)s。", - "Notifications on the following keywords follow rules which can’t be displayed here:": "以下关键字依照规则将不会在此显示:", + "Notifications on the following keywords follow rules which can’t be displayed here:": "以下关键词依照规则将不会在此显示:", "Safari and Opera work too.": "SafariOpera 也能工作。", "Please set a password!": "请设置密码!", "You have successfully set a password!": "您已成功设置密码!", - "An error occurred whilst saving your email notification preferences.": "保存邮件通知首选项设定时出现错误。", + "An error occurred whilst saving your email notification preferences.": "保存电子邮件通知选项时出现错误。", "Explore Room State": "探索聊天室状态", "Source URL": "源网址", "Messages sent by bot": "由机器人发出的消息", @@ -1032,16 +1032,16 @@ "Files": "文件", "Collecting app version information": "正在收集应用版本信息", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "确定要删除聊天室别名 %(alias)s 并将 %(name)s 从列表中删除吗?", - "This will allow you to return to your account after signing out, and sign in on other devices.": "这让您可以在注销后回到您的账号,并在其他设备上登录。", - "Keywords": "关键字", + "This will allow you to return to your account after signing out, and sign in on other devices.": "这将允许你可以在注销后回到您的账号,并在其他设备上登录。", + "Keywords": "关键词", "Enable notifications for this account": "为本账号启用通知", "Directory": "聊天室目录", "Invite to this community": "邀请加入此社区", "Failed to get public room list": "无法取得公开的聊天室列表", - "Messages containing keywords": "消息包含 关键字", + "Messages containing keywords": "消息包含 关键词", "Room not found": "找不到聊天室", "Tuesday": "星期二", - "Enter keywords separated by a comma:": "输入以逗号间隔的关键字:", + "Enter keywords separated by a comma:": "输入以逗号间隔的关键词:", "Forward Message": "转发消息", "You have successfully set a password and an email address!": "您已经成功设置了密码和邮箱地址!", "Remove %(name)s from the directory?": "从目录中移除 %(name)s 吗?", @@ -1066,7 +1066,7 @@ "Collecting logs": "正在收集日志", "more": "更多", "GitHub issue link:": "Github issue 链接:", - "You must specify an event type!": "你必须制定一个事件类型!", + "You must specify an event type!": "必须指定事件类型!", "(HTTP status %(httpStatus)s)": "(HTTP 状态 %(httpStatus)s)", "All Rooms": "全部聊天室", "Please install Chrome or Firefox for the best experience.": "请安装 ChromeFirefox 以获得最佳体验。", @@ -1078,7 +1078,7 @@ "Call invitation": "语音邀请", "Downloading update...": "正在下载更新…", "State Key": "状态密钥", - "Failed to send custom event.": "发送自定义事件失败。", + "Failed to send custom event.": "自定义事件发送失败。", "What's new?": "有什么新闻?", "Notify me for anything else": "所有消息都通知我", "When I'm invited to a room": "当我被邀请进入聊天室", @@ -1121,7 +1121,7 @@ "Failed to change settings": "变更设置失败", "View Community": "查看社区", "%(count)s Members|one": "%(count)s 位成员", - "Event sent!": "事件已发出!", + "Event sent!": "事件已发送!", "View Source": "查看源码", "Event Content": "事件内容", "Thank you!": "谢谢!", @@ -1132,5 +1132,7 @@ "There's no one else here! Would you like to invite others or stop warning about the empty room?": "这里没有其他人了!你是想 邀请用户 还是 不再提示?", "You need to be able to invite users to do that.": "你需要有邀请用户的权限才能进行此操作。", "Missing roomId.": "找不到此聊天室 ID 所对应的聊天室。", - "Tag Panel": "标签面板" + "Tag Panel": "标签面板", + "You have been banned from %(roomName)s by %(userName)s.": "您已被 %(userName)s 从聊天室 %(roomName)s 中封禁。", + "You have been banned from this room by %(userName)s.": "您已被 %(userName)s 从此聊天室中封禁。" } From 75ab618c054e8a12ee064c15a493388c8d8eac50 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 14:20:09 +0100 Subject: [PATCH 0913/1160] Fix variable scopes --- src/Lifecycle.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Lifecycle.js b/src/Lifecycle.js index 6c35c6ed06..7e8107c8b7 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -66,12 +66,13 @@ import sdk from './index'; * failed. */ export function loadSession(opts) { + let enableGuest = opts.enableGuest || false; + const guestHsUrl = opts.guestHsUrl; + const guestIsUrl = opts.guestIsUrl; + const fragmentQueryParams = opts.fragmentQueryParams || {}; + const defaultDeviceDisplayName = opts.defaultDeviceDisplayName; + return new Promise.resolve().then(() => { - const fragmentQueryParams = opts.fragmentQueryParams || {}; - let enableGuest = opts.enableGuest || false; - const guestHsUrl = opts.guestHsUrl; - const guestIsUrl = opts.guestIsUrl; - const defaultDeviceDisplayName = opts.defaultDeviceDisplayName; if (!guestHsUrl) { console.warn("Cannot enable guest access: can't determine HS URL to use"); From a1c442422438866fda9371c2128c5dcca63fd5ef Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 27 Apr 2018 14:28:24 +0100 Subject: [PATCH 0914/1160] Add tests for GroupView --- package.json | 1 + test/components/structures/GroupView-test.js | 378 +++++++++++++++++++ test/test-utils.js | 1 + 3 files changed, 380 insertions(+) create mode 100644 test/components/structures/GroupView-test.js diff --git a/package.json b/package.json index de0179c870..1f979369e3 100644 --- a/package.json +++ b/package.json @@ -125,6 +125,7 @@ "karma-spec-reporter": "^0.0.31", "karma-summary-reporter": "^1.3.3", "karma-webpack": "^1.7.0", + "matrix-mock-request": "^1.2.1", "matrix-react-test-utils": "^0.1.1", "mocha": "^5.0.5", "parallelshell": "^3.0.2", diff --git a/test/components/structures/GroupView-test.js b/test/components/structures/GroupView-test.js new file mode 100644 index 0000000000..2df0599f89 --- /dev/null +++ b/test/components/structures/GroupView-test.js @@ -0,0 +1,378 @@ +/* +Copyright 2018 New Vector Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import React from 'react'; +import ReactDOM from 'react-dom'; +import ReactTestUtils from 'react-dom/test-utils'; +import expect from 'expect'; +import Promise from 'bluebird'; + +import MockHttpBackend from 'matrix-mock-request'; +import MatrixClientPeg from '../../../src/MatrixClientPeg'; +import sdk from 'matrix-react-sdk'; +import Matrix from 'matrix-js-sdk'; + +import * as TestUtils from 'test-utils'; + +const GroupView = sdk.getComponent('structures.GroupView'); +const WrappedGroupView = TestUtils.wrapInMatrixClientContext(GroupView); + +const Spinner = sdk.getComponent('elements.Spinner'); + +/** + * Call fn before calling componentDidUpdate on a react component instance, inst. + * @param {React.Component} inst an instance of a React component. + * @returns {Promise} promise that resolves when componentDidUpdate is called on + * given component instance. + */ +function waitForUpdate(inst) { + return new Promise((resolve, reject) => { + const cdu = inst.componentDidUpdate; + + inst.componentDidUpdate = (prevProps, prevState, snapshot) => { + resolve(); + + if (cdu) cdu(prevProps, prevState, snapshot); + + inst.componentDidUpdate = cdu; + }; + }); +} + +describe.only('GroupView', function() { + let root; + let rootElement; + let httpBackend; + let summaryResponse; + let summaryResponseWithComplicatedLongDesc; + let summaryResponseWithNoLongDesc; + let summaryResponseWithBadImg; + let groupId; + let groupIdEncoded; + + // Summary response fields + const user = { + is_privileged: true, // can edit the group + is_public: true, // appear as a member to non-members + is_publicised: true, // display flair + }; + const usersSection = { + roles: {}, + total_user_count_estimate: 0, + users: [], + }; + const roomsSection = { + categories: {}, + rooms: [], + total_room_count_estimate: 0, + }; + + beforeEach(function() { + TestUtils.beforeEach(this); + + httpBackend = new MockHttpBackend(); + + Matrix.request(httpBackend.requestFn); + + MatrixClientPeg.get = () => Matrix.createClient({ + baseUrl: 'https://my.home.server', + userId: '@me:here', + accessToken: '123456789', + }); + + summaryResponse = { + profile: { + avatar_url: "mxc://someavatarurl", + is_openly_joinable: true, + is_public: true, + long_description: "This is a LONG description.", + name: "The name of a community", + short_description: "This is a community", + }, + user, + users_section: usersSection, + rooms_section: roomsSection, + }; + summaryResponseWithNoLongDesc = { + profile: { + avatar_url: "mxc://someavatarurl", + is_openly_joinable: true, + is_public: true, + long_description: null, + name: "The name of a community", + short_description: "This is a community", + }, + user, + users_section: usersSection, + rooms_section: roomsSection, + }; + summaryResponseWithComplicatedLongDesc = { + profile: { + avatar_url: "mxc://someavatarurl", + is_openly_joinable: true, + is_public: true, + long_description: ` +

    This is a more complicated group page

    +

    With paragraphs

    +
      +
    • And lists!
    • +
    • With list items.
    • +
    +

    And also images:

    `, + name: "The name of a community", + short_description: "This is a community", + }, + user, + users_section: usersSection, + rooms_section: roomsSection, + }; + + summaryResponseWithBadImg = { + profile: { + avatar_url: "mxc://someavatarurl", + is_openly_joinable: true, + is_public: true, + long_description: '

    Evil image:

    ', + name: "The name of a community", + short_description: "This is a community", + }, + user, + users_section: usersSection, + rooms_section: roomsSection, + }; + + groupId = "+" + Math.random().toString(16).slice(2) + ':domain'; + groupIdEncoded = encodeURIComponent(groupId); + + rootElement = document.createElement('div'); + root = ReactDOM.render(, rootElement); + }); + + afterEach(function() { + ReactDOM.unmountComponentAtNode(rootElement); + }); + + it('should show a spinner when first displayed', function() { + ReactTestUtils.findRenderedComponentWithType(root, Spinner); + + // If we don't respond here, the rate limiting done to ensure a maximum of + // 3 concurrent network requests for GroupStore will block subsequent requests + // in other tests. + // + // This is a good case for doing the rate limiting somewhere other than the module + // scope of GroupStore.js + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/summary').respond(200, summaryResponse); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/invited_users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/rooms').respond(200, { chunk: [] }); + + return httpBackend.flush(undefined, undefined, 0); + }); + + it('should indicate failure after failed /summary', function() { + const groupView = ReactTestUtils.findRenderedComponentWithType(root, GroupView); + const prom = waitForUpdate(groupView).then(() => { + ReactTestUtils.findRenderedDOMComponentWithClass(root, 'mx_GroupView_error'); + }); + + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/summary').respond(500, {}); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/invited_users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/rooms').respond(200, { chunk: [] }); + + httpBackend.flush(undefined, undefined, 0); + return prom; + }); + + it('should show a group avatar, name, id and short description after successful /summary', function() { + const groupView = ReactTestUtils.findRenderedComponentWithType(root, GroupView); + const prom = waitForUpdate(groupView).then(() => { + ReactTestUtils.findRenderedDOMComponentWithClass(root, 'mx_GroupView'); + + const avatar = ReactTestUtils.findRenderedComponentWithType(root, sdk.getComponent('avatars.GroupAvatar')); + const img = ReactTestUtils.findRenderedDOMComponentWithTag(avatar, 'img'); + const avatarImgElement = ReactDOM.findDOMNode(img); + expect(avatarImgElement).toExist(); + expect(avatarImgElement.src).toInclude( + 'https://my.home.server/_matrix/media/v1/thumbnail/' + + 'someavatarurl?width=48&height=48&method=crop', + ); + + const name = ReactTestUtils.findRenderedDOMComponentWithClass(root, 'mx_GroupView_header_name'); + const nameElement = ReactDOM.findDOMNode(name); + expect(nameElement).toExist(); + expect(nameElement.innerText).toInclude('The name of a community'); + expect(nameElement.innerText).toInclude(groupId); + + const shortDesc = ReactTestUtils.findRenderedDOMComponentWithClass(root, 'mx_GroupView_header_shortDesc'); + const shortDescElement = ReactDOM.findDOMNode(shortDesc); + expect(shortDescElement).toExist(); + expect(shortDescElement.innerText).toBe('This is a community'); + }); + + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/summary').respond(200, summaryResponse); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/invited_users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/rooms').respond(200, { chunk: [] }); + + httpBackend.flush(undefined, undefined, 0); + return prom; + }); + + it('should show a simple long description after successful /summary', function() { + const groupView = ReactTestUtils.findRenderedComponentWithType(root, GroupView); + const prom = waitForUpdate(groupView).then(() => { + ReactTestUtils.findRenderedDOMComponentWithClass(root, 'mx_GroupView'); + + const longDesc = ReactTestUtils.findRenderedDOMComponentWithClass(root, 'mx_GroupView_groupDesc'); + const longDescElement = ReactDOM.findDOMNode(longDesc); + expect(longDescElement).toExist(); + expect(longDescElement.innerText).toBe('This is a LONG description.'); + expect(longDescElement.innerHTML).toBe('
    This is a LONG description.
    '); + }); + + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/summary').respond(200, summaryResponse); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/invited_users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/rooms').respond(200, { chunk: [] }); + + httpBackend.flush(undefined, undefined, 0); + return prom; + }); + + it('should show a placeholder if a long description is not set', function() { + const groupView = ReactTestUtils.findRenderedComponentWithType(root, GroupView); + const prom = waitForUpdate(groupView).then(() => { + const placeholder = ReactTestUtils + .findRenderedDOMComponentWithClass(root, 'mx_GroupView_groupDesc_placeholder'); + const placeholderElement = ReactDOM.findDOMNode(placeholder); + expect(placeholderElement).toExist(); + }); + + httpBackend + .when('GET', '/groups/' + groupIdEncoded + '/summary') + .respond(200, summaryResponseWithNoLongDesc); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/invited_users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/rooms').respond(200, { chunk: [] }); + + httpBackend.flush(undefined, undefined, 0); + return prom; + }); + + it('should show a complicated long description after successful /summary', function() { + const groupView = ReactTestUtils.findRenderedComponentWithType(root, GroupView); + const prom = waitForUpdate(groupView).then(() => { + const longDesc = ReactTestUtils.findRenderedDOMComponentWithClass(root, 'mx_GroupView_groupDesc'); + const longDescElement = ReactDOM.findDOMNode(longDesc); + expect(longDescElement).toExist(); + + expect(longDescElement.innerHTML).toInclude('

    This is a more complicated group page

    '); + expect(longDescElement.innerHTML).toInclude('

    With paragraphs

    '); + expect(longDescElement.innerHTML).toInclude('
      '); + expect(longDescElement.innerHTML).toInclude('
    • And lists!
    • '); + + const imgSrc = "https://my.home.server/_matrix/media/v1/thumbnail/someimageurl?width=800&height=600"; + expect(longDescElement.innerHTML).toInclude(''); + }); + + httpBackend + .when('GET', '/groups/' + groupIdEncoded + '/summary') + .respond(200, summaryResponseWithComplicatedLongDesc); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/invited_users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/rooms').respond(200, { chunk: [] }); + + httpBackend.flush(undefined, undefined, 0); + return prom; + }); + + it('should disallow images with non-mxc URLs', function() { + const groupView = ReactTestUtils.findRenderedComponentWithType(root, GroupView); + const prom = waitForUpdate(groupView).then(() => { + const longDesc = ReactTestUtils.findRenderedDOMComponentWithClass(root, 'mx_GroupView_groupDesc'); + const longDescElement = ReactDOM.findDOMNode(longDesc); + expect(longDescElement).toExist(); + + // If this fails, the URL could be in an img `src`, which is what we care about but + // there's no harm in keeping this simple and checking the entire HTML string. + expect(longDescElement.innerHTML).toExclude('evilimageurl'); + }); + + httpBackend + .when('GET', '/groups/' + groupIdEncoded + '/summary') + .respond(200, summaryResponseWithBadImg); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/invited_users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/rooms').respond(200, { chunk: [] }); + + httpBackend.flush(undefined, undefined, 0); + return prom; + }); + + it('should show a RoomDetailList after a successful /summary & /rooms (no rooms returned)', function() { + const groupView = ReactTestUtils.findRenderedComponentWithType(root, GroupView); + const prom = waitForUpdate(groupView).then(() => { + const roomDetailList = ReactTestUtils.findRenderedDOMComponentWithClass(root, 'mx_RoomDetailList'); + const roomDetailListElement = ReactDOM.findDOMNode(roomDetailList); + expect(roomDetailListElement).toExist(); + }); + + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/summary').respond(200, summaryResponse); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/invited_users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/rooms').respond(200, { chunk: [] }); + + httpBackend.flush(undefined, undefined, 0); + return prom; + }); + + it('should show a RoomDetailList after a successful /summary & /rooms (with a single room)', function() { + const groupView = ReactTestUtils.findRenderedComponentWithType(root, GroupView); + const prom = waitForUpdate(groupView).then(() => { + const roomDetailList = ReactTestUtils.findRenderedDOMComponentWithClass(root, 'mx_RoomDetailList'); + const roomDetailListElement = ReactDOM.findDOMNode(roomDetailList); + expect(roomDetailListElement).toExist(); + + const roomDetailListRoomName = ReactTestUtils.findRenderedDOMComponentWithClass( + root, + 'mx_RoomDirectory_name', + ); + const roomDetailListRoomNameElement = ReactDOM.findDOMNode(roomDetailListRoomName); + + expect(roomDetailListRoomNameElement).toExist(); + expect(roomDetailListRoomNameElement.innerText).toEqual('Some room name'); + }); + + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/summary').respond(200, summaryResponse); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/invited_users').respond(200, { chunk: [] }); + httpBackend.when('GET', '/groups/' + groupIdEncoded + '/rooms').respond(200, { chunk: [{ + avatar_url: "mxc://someroomavatarurl", + canonical_alias: "#somealias:domain", + guest_can_join: true, + is_public: true, + name: "Some room name", + num_joined_members: 123, + room_id: "!someroomid", + topic: "some topic", + world_readable: true, + }] }); + + httpBackend.flush(undefined, undefined, 0); + return prom; + }); +}); diff --git a/test/test-utils.js b/test/test-utils.js index b593761bd4..d2c685b371 100644 --- a/test/test-utils.js +++ b/test/test-utils.js @@ -92,6 +92,7 @@ export function createTestClient() { content: {}, }); }, + mxcUrlToHttp: (mxc) => 'http://this.is.a.url/', setAccountData: sinon.stub(), sendTyping: sinon.stub().returns(Promise.resolve({})), sendTextMessage: () => Promise.resolve({}), From 7915d97ed70cf5cab3f0b83d807db228aa978f10 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 27 Apr 2018 14:56:48 +0100 Subject: [PATCH 0915/1160] Also run other tests --- test/components/structures/GroupView-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/components/structures/GroupView-test.js b/test/components/structures/GroupView-test.js index 2df0599f89..71df26da46 100644 --- a/test/components/structures/GroupView-test.js +++ b/test/components/structures/GroupView-test.js @@ -52,7 +52,7 @@ function waitForUpdate(inst) { }); } -describe.only('GroupView', function() { +describe('GroupView', function() { let root; let rootElement; let httpBackend; From 2cc50d35c680f036f54b3b61dd5f18d19563a9b8 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 15:06:36 +0100 Subject: [PATCH 0916/1160] Lint --- src/Lifecycle.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Lifecycle.js b/src/Lifecycle.js index 7e8107c8b7..a22a5aeebd 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -72,8 +72,7 @@ export function loadSession(opts) { const fragmentQueryParams = opts.fragmentQueryParams || {}; const defaultDeviceDisplayName = opts.defaultDeviceDisplayName; - return new Promise.resolve().then(() => { - + return Promise.resolve().then(() => { if (!guestHsUrl) { console.warn("Cannot enable guest access: can't determine HS URL to use"); enableGuest = false; From efd29193b7e32445c65e0bd396e3a6767f28ead8 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 15:19:08 +0100 Subject: [PATCH 0917/1160] Fix UX issues with bug report dialog * Make it use BaseDialog / DialogButtons (also gives it has a top-right 'x' & escape to cancel works) * Stop misusing the 'danger' CSS class on the buttons. There is nothing dangerous about submitting logs. * Continued campaign against 'Click here' links. Fixes https://github.com/vector-im/riot-web/issues/6622 --- src/components/structures/UserSettings.js | 4 +- .../views/dialogs/BugReportDialog.js | 42 +++++++------------ .../views/elements/DialogButtons.js | 14 +++++-- src/i18n/strings/en_EN.json | 2 +- 4 files changed, 30 insertions(+), 32 deletions(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 7948f4fb5d..44e2f93d63 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -1,7 +1,7 @@ /* Copyright 2015, 2016 OpenMarket Ltd Copyright 2017 Vector Creations Ltd -Copyright 2017 New Vector Ltd +Copyright 2017, 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -804,7 +804,7 @@ module.exports = React.createClass({ "other users. They do not contain messages.", ) }

      -
    diff --git a/src/components/views/dialogs/BugReportDialog.js b/src/components/views/dialogs/BugReportDialog.js index 2025b6fc81..83cdb1f07f 100644 --- a/src/components/views/dialogs/BugReportDialog.js +++ b/src/components/views/dialogs/BugReportDialog.js @@ -1,5 +1,6 @@ /* Copyright 2017 OpenMarket Ltd +Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -105,6 +106,8 @@ export default class BugReportDialog extends React.Component { render() { const Loader = sdk.getComponent("elements.Spinner"); + const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); + const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); let error = null; if (this.state.err) { @@ -113,13 +116,6 @@ export default class BugReportDialog extends React.Component {
    ; } - let cancelButton = null; - if (!this.state.busy) { - cancelButton = ; - } - let progress = null; if (this.state.busy) { progress = ( @@ -131,11 +127,11 @@ export default class BugReportDialog extends React.Component { } return ( -
    -
    - { _t("Submit debug logs") } -
    -
    + +

    { _t( "Debug logs contain application usage data including your " + @@ -146,7 +142,7 @@ export default class BugReportDialog extends React.Component {

    { _t( - "Click here to create a GitHub issue.", + "Riot bugs are tracked on GitHub: create a GitHub issue.", {}, { a: (sub) => -

    -
    + +
    ); } } diff --git a/src/components/views/elements/DialogButtons.js b/src/components/views/elements/DialogButtons.js index 73e47cbde2..c8c90ddc47 100644 --- a/src/components/views/elements/DialogButtons.js +++ b/src/components/views/elements/DialogButtons.js @@ -39,11 +39,14 @@ module.exports = React.createClass({ onCancel: PropTypes.func, focus: PropTypes.bool, + + disabled: PropTypes.bool, }, getDefaultProps: function() { return { hasCancel: true, + disabled: false, } }, @@ -56,18 +59,23 @@ module.exports = React.createClass({ if (this.props.primaryButtonClass) { primaryButtonClassName += " " + this.props.primaryButtonClass; } + let cancelButton; + if (this.props.hasCancel) { + cancelButton = ; + } return (
    { this.props.children } - { this.props.hasCancel ? : null } + { cancelButton }
    ); }, diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 3c8dd5b66f..daf0ce605d 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -745,7 +745,7 @@ "Failed to send logs: ": "Failed to send logs: ", "Submit debug logs": "Submit debug logs", "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.", - "
    Click here to create a GitHub issue.": "Click here to create a GitHub issue.", + "Riot bugs are tracked on GitHub: create a GitHub issue.": "Riot bugs are tracked on GitHub: create a GitHub issue.", "GitHub issue link:": "GitHub issue link:", "Notes:": "Notes:", "Send logs": "Send logs", From 51e5b73ed0e8c1d4869504af700fc87ca18542f8 Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Fri, 27 Apr 2018 14:32:48 +0000 Subject: [PATCH 0918/1160] Translated using Weblate (Russian) Currently translated at 100.0% (1165 of 1165 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 122 +++++++++++++++++++-------------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 441e69c1e1..3c33abee86 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -32,7 +32,7 @@ "Deactivate Account": "Деактивировать учетную запись", "Deactivate my account": "Деактивировать мою учетную запись", "Decryption error": "Ошибка расшифровки", - "Default": "Обычный пользователь", + "Default": "Участник", "Deops user with given id": "Снимает полномочия оператора с пользователя с заданным ID", "Device ID": "ID устройства", "Devices will not yet be able to decrypt history from before they joined the room": "Устройства не смогут расшифровать историю сообщений до момента их входа в комнату (временно)", @@ -342,7 +342,7 @@ "The email address linked to your account must be entered.": "Необходимо ввести адрес электронной почты, связанный с вашей учетной записью.", "The file '%(fileName)s' failed to upload": "Не удалось отправить файл '%(fileName)s'", "The remote side failed to pick up": "Собеседник не ответил на ваш звонок", - "This room has no local addresses": "Эта комната не имеет адресов на вашем сервере", + "This room has no local addresses": "У этой комнаты нет адресов на вашем сервере", "This room is not recognised.": "Эта комната не опознана.", "These are experimental features that may break in unexpected ways": "Это экспериментальные функции, которые могут себя вести неожиданным образом", "This doesn't appear to be a valid email address": "Похоже, это недействительный адрес email", @@ -399,7 +399,7 @@ "Are you sure you want to leave the room '%(roomName)s'?": "Вы уверены, что хотите покинуть '%(roomName)s'?", "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s удалил(а) имя комнаты.", "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Смена пароля на данный момент сбрасывает ключи сквозного шифрования на всех устройствах, делая историю зашифрованных чатов нечитаемой. Чтобы избежать этого, экспортируйте ключи сквозного шифрования и импортируйте их после смены пароля. В будущем это будет исправлено.", - "Custom level": "Пользовательский уровень", + "Custom level": "Специальные права", "Device already verified!": "Устройство уже проверено!", "Device ID:": "ID устройства:", "device id: ": "ID устройства: ", @@ -502,8 +502,8 @@ "Unknown Address": "Неизвестный адрес", "Unblacklist": "Разблокировать", "Blacklist": "Заблокировать", - "Unverify": "Отозвать верификацию", - "Verify...": "Верифицировать...", + "Unverify": "Отозвать доверие", + "Verify...": "Сверить ключи...", "ex. @bob:example.com": "например @bob:example.com", "Add User": "Добавить пользователя", "This Home Server would like to make sure you are not a robot": "Этот сервер хочет убедиться, что вы не робот", @@ -800,7 +800,7 @@ "To join an existing community you'll have to know its community identifier; this will look something like +example:matrix.org.": "Чтобы присоединиться к существующему сообществу, вам нужно знать его ID; это будет выглядеть примерно так+primer:matrix.org.", "Something went wrong whilst creating your community": "При создании сообщества что-то пошло не так", "%(names)s and %(count)s others are typing|other": "%(names)s и еще %(count)s печатают", - "And %(count)s more...|other": "И более %(count)s...", + "And %(count)s more...|other": "Ещё %(count)s…", "Delete Widget": "Удалить виджет", "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Удаление виджета действует для всех участников этой комнаты. Вы действительно хотите удалить этот виджет?", "Message removed": "Сообщение удалено", @@ -829,48 +829,48 @@ "Disinvite this user from community?": "Отозвать приглашение в сообщество этого участника?", "Remove this user from community?": "Исключить этого участника из сообщества?", "%(nameList)s %(transitionList)s": "%(nameList)s %(transitionList)s", - "%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)s присоединились %(count)s раз", - "%(severalUsers)sjoined %(count)s times|one": "%(severalUsers)s присоединились", - "%(oneUser)sjoined %(count)s times|other": "%(oneUser)s присоединился(-лась) %(count)s раз", - "%(oneUser)sjoined %(count)s times|one": "%(oneUser)s присоединился(-лась)", - "%(severalUsers)sleft %(count)s times|other": "%(severalUsers)s покинули %(count)s раз", - "%(severalUsers)sleft %(count)s times|one": "%(severalUsers)s покинули", - "%(oneUser)sleft %(count)s times|other": "%(oneUser)sl покинул(а) %(count)s раз", - "%(oneUser)sleft %(count)s times|one": "%(oneUser)s покинул(а)", - "%(severalUsers)sjoined and left %(count)s times|other": "%(severalUsers)s присоединились и покинули %(count)s раз", - "%(severalUsers)sjoined and left %(count)s times|one": "%(severalUsers)s присоединились и покинули", - "%(oneUser)sjoined and left %(count)s times|other": "%(oneUser)s присоединился(-лась) и покинул(а) %(count)s раз", - "%(oneUser)sjoined and left %(count)s times|one": "%(oneUser)s присоединился(-лась) и покинул(а)", - "%(severalUsers)sleft and rejoined %(count)s times|other": "%(severalUsers)s покинули и снова присоединились %(count)s раз", - "%(severalUsers)sleft and rejoined %(count)s times|one": "%(severalUsers)s покинули и снова присоединились", - "%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)s покинул(а) и снова присоединился(-лась) %(count)s раз", - "%(oneUser)sleft and rejoined %(count)s times|one": "%(oneUser)s покинул(а) и снова присоединился(-лась)", - "were invited %(count)s times|other": "были приглашены %(count)s раз", - "were invited %(count)s times|one": "были приглашены", - "was invited %(count)s times|other": "был(а) приглашен(а) %(count)s раз", - "was invited %(count)s times|one": "был(а) приглашен(а)", - "were banned %(count)s times|other": "были заблокированы %(count)s раз", - "were banned %(count)s times|one": "были заблокированы", - "was banned %(count)s times|other": "был(а) заблокирован(а) %(count)s раз", - "was banned %(count)s times|one": "был(а) заблокирован(а)", - "were unbanned %(count)s times|other": "были разблокированы %(count)s раз", - "were unbanned %(count)s times|one": "были разблокированы", - "was unbanned %(count)s times|other": "был(а) разблокирован(а) %(count)s раз", - "was unbanned %(count)s times|one": "был(а) разблокирован(а)", - "were kicked %(count)s times|other": "были выкинуты %(count)s раз", - "were kicked %(count)s times|one": "были выкинуты", - "was kicked %(count)s times|other": "был(а) выкинут(а) %(count)s раз", - "was kicked %(count)s times|one": "был(а) выкинут(а)", - "%(severalUsers)schanged their name %(count)s times|other": "%(severalUsers)s изменили свое имя %(count)s раз", - "%(severalUsers)schanged their name %(count)s times|one": "%(severalUsers)s изменили свое имя", - "%(oneUser)schanged their name %(count)s times|other": "%(oneUser)s изменил(а) свое имя %(count)s раз", - "%(oneUser)schanged their name %(count)s times|one": "%(oneUser)s изменил(а) свое имя", - "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)s изменили свои аватары %(count)s раз", - "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)s изменили свои аватары", - "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)s изменил(а) свой аватар %(count)s раз", - "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)s изменил(а) свой аватар", - "%(items)s and %(count)s others|other": "%(items)s и %(count)s других", - "%(items)s and %(count)s others|one": "%(items)s и один другой", + "%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)sвошли %(count)s раз", + "%(severalUsers)sjoined %(count)s times|one": "%(severalUsers)sвошли", + "%(oneUser)sjoined %(count)s times|other": "%(oneUser)sвошёл(-ла) %(count)s раз", + "%(oneUser)sjoined %(count)s times|one": "%(oneUser)sвошёл(-ла)", + "%(severalUsers)sleft %(count)s times|other": "%(severalUsers)sушли %(count)s раз", + "%(severalUsers)sleft %(count)s times|one": "%(severalUsers)sушли", + "%(oneUser)sleft %(count)s times|other": "%(oneUser)sушёл(-ла) %(count)s раз", + "%(oneUser)sleft %(count)s times|one": "%(oneUser)sушёл(-ла)", + "%(severalUsers)sjoined and left %(count)s times|other": "%(severalUsers)sвошли и ушли %(count)s раз", + "%(severalUsers)sjoined and left %(count)s times|one": "%(severalUsers)sвошли и ушли", + "%(oneUser)sjoined and left %(count)s times|other": "%(oneUser)sвошёл(-ла) и ушёл(-ла) %(count)s раз", + "%(oneUser)sjoined and left %(count)s times|one": "%(oneUser)sвошёл(-ла) и ушёл(-ла)", + "%(severalUsers)sleft and rejoined %(count)s times|other": "%(severalUsers)sушли и снова вошли %(count)s раз", + "%(severalUsers)sleft and rejoined %(count)s times|one": "%(severalUsers)sушли и снова вошли", + "%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)sушёл(-ла) и снова вошёл(-ла) %(count)s раз", + "%(oneUser)sleft and rejoined %(count)s times|one": "%(oneUser)sушёл(-ла) и снова вошёл(-ла)", + "were invited %(count)s times|other": "приглашены %(count)s раз", + "were invited %(count)s times|one": "приглашены", + "was invited %(count)s times|other": "приглашен(а) %(count)s раз", + "was invited %(count)s times|one": "приглашен(а)", + "were banned %(count)s times|other": "заблокированы %(count)s раз", + "were banned %(count)s times|one": "заблокированы", + "was banned %(count)s times|other": "заблокирован(а) %(count)s раз", + "was banned %(count)s times|one": "заблокирован(а)", + "were unbanned %(count)s times|other": "разблокированы %(count)s раз", + "were unbanned %(count)s times|one": "разблокированы", + "was unbanned %(count)s times|other": "разблокирован(а) %(count)s раз", + "was unbanned %(count)s times|one": "разблокирован(а)", + "were kicked %(count)s times|other": "выгнаны %(count)s раз", + "were kicked %(count)s times|one": "выгнаны", + "was kicked %(count)s times|other": "выгнан(а) %(count)s раз", + "was kicked %(count)s times|one": "выгнан(а)", + "%(severalUsers)schanged their name %(count)s times|other": "%(severalUsers)sпоменяли имя %(count)s раз", + "%(severalUsers)schanged their name %(count)s times|one": "%(severalUsers)sпоменяли имя", + "%(oneUser)schanged their name %(count)s times|other": "%(oneUser)sпоменял(а) имя %(count)s раз", + "%(oneUser)schanged their name %(count)s times|one": "%(oneUser)sпоменял(а) имя", + "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)sпоменяли аватары %(count)s раз", + "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)sпоменяли аватары", + "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)sпоменял(а) аватар %(count)s раз", + "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)sпоменял(а) аватар", + "%(items)s and %(count)s others|other": "%(items)s и ещё %(count)s участника(-ов)", + "%(items)s and %(count)s others|one": "%(items)s и ещё кто-то", "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "Сообщение отправлено на %(emailAddress)s. После перехода по ссылке в отправленном вам письме, щелкните ниже.", "Room Notification": "Уведомления комнаты", "Drop here to tag direct chat": "Перетащите сюда, чтобы пометить как личный чат", @@ -894,17 +894,17 @@ "Username on %(hs)s": "Имя пользователя на %(hs)s", "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "Не удалось изменить видимость '%(roomName)s' в %(groupId)s.", "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)s отклонили приглашения %(count)s раз", - "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)s отклонили приглашения", + "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)sотклонили приглашения", "URL previews are enabled by default for participants in this room.": "Предпросмотр ссылок по умолчанию включен для участников этой комнаты.", "URL previews are disabled by default for participants in this room.": "Предпросмотр ссылок по умолчанию выключен для участников этой комнаты.", - "%(oneUser)srejected their invitation %(count)s times|other": "%(oneUser)sотклонил их приглашение %(count)s раз", - "%(oneUser)srejected their invitation %(count)s times|one": "%(oneUser)sотклонил приглашение", + "%(oneUser)srejected their invitation %(count)s times|other": "%(oneUser)sотклонил(а) приглашение %(count)s раз", + "%(oneUser)srejected their invitation %(count)s times|one": "%(oneUser)sотклонил(а) приглашение", "%(severalUsers)shad their invitations withdrawn %(count)s times|other": "%(severalUsers)sотозвали приглашения %(count)s раз", "%(severalUsers)shad their invitations withdrawn %(count)s times|one": "%(severalUsers)sотозвали приглашения", - "%(oneUser)shad their invitation withdrawn %(count)s times|other": "%(oneUser)sотклонил приглашение %(count)s раз", - "%(oneUser)shad their invitation withdrawn %(count)s times|one": "%(oneUser)sотозвал приглашение", + "%(oneUser)shad their invitation withdrawn %(count)s times|other": "%(oneUser)sотклонил(а) приглашение %(count)s раз", + "%(oneUser)shad their invitation withdrawn %(count)s times|one": "%(oneUser)sотозвал(а) приглашение", "Please note you are logging into the %(hs)s server, not matrix.org.": "Обратите внимание, что вы заходите на сервер %(hs)s, а не на matrix.org.", - "Custom of %(powerLevel)s": "Пользовательский уровень %(powerLevel)s", + "Custom of %(powerLevel)s": "Специальные права: %(powerLevel)s", "

    HTML for your community's page

    \n

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

    \n

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

    \n": "

    HTML для страницы вашего сообщества

    \n

    \n Используйте подробное описание для представления вашего сообщества новым участникам, или\n поделитесь чем-нибудь важным, например ссылками\n

    \n

    \n Также вы можете использовать теги 'img'\n

    \n", "%(duration)ss": "%(duration)s сек", "%(duration)sm": "%(duration)s мин", @@ -918,9 +918,9 @@ "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Здесь никого нет! Хотите пригласить кого-нибудь или выключить предупреждение о пустой комнате?", "Something went wrong when trying to get your communities.": "Что-то пошло не так при попытке получить список ваших сообществ.", "Tag Panel": "Панель тегов", - "Delete %(count)s devices|other": "Удалить %(count)s устройств", - "Delete %(count)s devices|one": "Удалить устройство", - "Select devices": "Выбрать устройства", + "Delete %(count)s devices|other": "Удалить (%(count)s)", + "Delete %(count)s devices|one": "Удалить", + "Select devices": "Выбрать", "This homeserver doesn't offer any login flows which are supported by this client.": "Этот домашний сервер не поддерживает метод входа, поддерживаемый клиентом.", "Call Failed": "Звонок не удался", "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "В этой комнате есть неизвестные устройства: если вы решите их не проверять, имейте в виду, что кто-то, возможно, вас прослушивает.", @@ -1021,7 +1021,7 @@ "Expand panel": "Развернуть панель", "On": "Включить", "%(count)s Members|other": "%(count)s членов", - "Filter room names": "Фильтр по названию комнат", + "Filter room names": "Поиск по комнатам", "Changelog": "История изменений", "Waiting for response from server": "Ожидание ответа от сервера", "Uploaded on %(date)s by %(user)s": "Загружено %(user)s в %(date)s", @@ -1039,7 +1039,7 @@ "The Home Server may be too old to support third party networks": "Домашний сервер может быть слишком старым для поддержки сетей сторонних производителей", "Noisy": "Вкл. (со звуком)", "Room not found": "Комната не найдена", - "Messages containing my display name": "Сообщения, упоминающие мое имя", + "Messages containing my display name": "Сообщения с моим именем", "Messages in one-to-one chats": "Сообщения в 1:1 чатах", "Unavailable": "Недоступен", "Error saving email notification preferences": "Ошибка сохранения настроек email-уведомлений", @@ -1090,7 +1090,7 @@ "Monday": "Понедельник", "Remove from Directory": "Удалить из каталога", "Enable them now": "Включить их сейчас", - "Messages containing my user name": "Сообщение, упоминающие мое имя пользователя", + "Messages containing my user name": "Сообщения с моим идентификатором", "Toolbox": "Панель инструментов", "Collecting logs": "Сбор журналов", "more": "больше", @@ -1102,7 +1102,7 @@ "Failed to get public room list": "Не удалось получить список общедоступных комнат", "Send logs": "Отправка журналов", "All messages": "Все сообщения", - "Call invitation": "Приглашения на звонки", + "Call invitation": "Звонки", "Downloading update...": "Загрузка обновления…", "State Key": "Ключ состояния", "Failed to send custom event.": "Не удалось отправить индивидуальное мероприятие.", From 27b18c457e31605b7d86c4e0b82f463ed60005cf Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 15:56:28 +0100 Subject: [PATCH 0919/1160] Lint --- src/components/views/dialogs/SessionRestoreErrorDialog.js | 4 ++-- src/components/views/elements/DialogButtons.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/views/dialogs/SessionRestoreErrorDialog.js b/src/components/views/dialogs/SessionRestoreErrorDialog.js index 2e152df4b0..779e54cfba 100644 --- a/src/components/views/dialogs/SessionRestoreErrorDialog.js +++ b/src/components/views/dialogs/SessionRestoreErrorDialog.js @@ -68,7 +68,7 @@ export default React.createClass({ - + ; } else { dialogButtons = { _t("Clear Storage and Sign Out") } - + ; } return ( diff --git a/src/components/views/elements/DialogButtons.js b/src/components/views/elements/DialogButtons.js index 73e47cbde2..c99ea10143 100644 --- a/src/components/views/elements/DialogButtons.js +++ b/src/components/views/elements/DialogButtons.js @@ -44,7 +44,7 @@ module.exports = React.createClass({ getDefaultProps: function() { return { hasCancel: true, - } + }; }, _onCancelClick: function() { From fed74646b0eb8b6fa5cc55fff92a613810714e64 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 17:49:53 +0100 Subject: [PATCH 0920/1160] Rewrite to use async / await --- src/Lifecycle.js | 84 +++++++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 43 deletions(-) diff --git a/src/Lifecycle.js b/src/Lifecycle.js index a22a5aeebd..7378e982ef 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -65,14 +65,14 @@ import sdk from './index'; * Resolves to `true` if we ended up starting a session, or `false` if we * failed. */ -export function loadSession(opts) { - let enableGuest = opts.enableGuest || false; - const guestHsUrl = opts.guestHsUrl; - const guestIsUrl = opts.guestIsUrl; - const fragmentQueryParams = opts.fragmentQueryParams || {}; - const defaultDeviceDisplayName = opts.defaultDeviceDisplayName; +export async function loadSession(opts) { + try { + let enableGuest = opts.enableGuest || false; + const guestHsUrl = opts.guestHsUrl; + const guestIsUrl = opts.guestIsUrl; + const fragmentQueryParams = opts.fragmentQueryParams || {}; + const defaultDeviceDisplayName = opts.defaultDeviceDisplayName; - return Promise.resolve().then(() => { if (!guestHsUrl) { console.warn("Cannot enable guest access: can't determine HS URL to use"); enableGuest = false; @@ -91,8 +91,7 @@ export function loadSession(opts) { guest: true, }, true).then(() => true); } - return _restoreFromLocalStorage(); - }).then((success) => { + const success = await _restoreFromLocalStorage(); if (success) { return true; } @@ -103,9 +102,9 @@ export function loadSession(opts) { // fall back to login screen return false; - }).catch((e) => { + } catch (e) { return _handleLoadSessionFailure(e); - }); + } } /** @@ -199,40 +198,39 @@ function _registerAsGuest(hsUrl, isUrl, defaultDeviceDisplayName) { // The plan is to gradually move the localStorage access done here into // SessionStore to avoid bugs where the view becomes out-of-sync with // localStorage (e.g. teamToken, isGuest etc.) -function _restoreFromLocalStorage() { - return Promise.resolve().then(() => { - if (!localStorage) { - return Promise.resolve(false); - } - const hsUrl = localStorage.getItem("mx_hs_url"); - const isUrl = localStorage.getItem("mx_is_url") || 'https://matrix.org'; - const accessToken = localStorage.getItem("mx_access_token"); - const userId = localStorage.getItem("mx_user_id"); - const deviceId = localStorage.getItem("mx_device_id"); +async function _restoreFromLocalStorage() { + if (!localStorage) { + return false; + } + const hsUrl = localStorage.getItem("mx_hs_url"); + const isUrl = localStorage.getItem("mx_is_url") || 'https://matrix.org'; + const accessToken = localStorage.getItem("mx_access_token"); + const userId = localStorage.getItem("mx_user_id"); + const deviceId = localStorage.getItem("mx_device_id"); - let isGuest; - if (localStorage.getItem("mx_is_guest") !== null) { - isGuest = localStorage.getItem("mx_is_guest") === "true"; - } else { - // legacy key name - isGuest = localStorage.getItem("matrix-is-guest") === "true"; - } + let isGuest; + if (localStorage.getItem("mx_is_guest") !== null) { + isGuest = localStorage.getItem("mx_is_guest") === "true"; + } else { + // legacy key name + isGuest = localStorage.getItem("matrix-is-guest") === "true"; + } - if (accessToken && userId && hsUrl) { - console.log(`Restoring session for ${userId}`); - return _doSetLoggedIn({ - userId: userId, - deviceId: deviceId, - accessToken: accessToken, - homeserverUrl: hsUrl, - identityServerUrl: isUrl, - guest: isGuest, - }, false).then(() => true); - } else { - console.log("No previous session found."); - return Promise.resolve(false); - } - }); + if (accessToken && userId && hsUrl) { + console.log(`Restoring session for ${userId}`); + await _doSetLoggedIn({ + userId: userId, + deviceId: deviceId, + accessToken: accessToken, + homeserverUrl: hsUrl, + identityServerUrl: isUrl, + guest: isGuest, + }, false); + return true; + } else { + console.log("No previous session found."); + return false; + } } function _handleLoadSessionFailure(e) { From 0c309c88add295798689fbab993d326bd1549cf0 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 17:52:25 +0100 Subject: [PATCH 0921/1160] Bluebird has no need for your .done() --- src/components/structures/MatrixChat.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index cdeb99ef53..8df46d2f7c 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -360,7 +360,7 @@ export default React.createClass({ // Note we don't catch errors from this: we catch everything within // loadSession as there's logic there to ask the user if they want // to try logging out. - }).done(); + }); }, componentWillUnmount: function() { From d3c368e19fe97d8e429fcb8cef0762638ff1f89a Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 17:53:11 +0100 Subject: [PATCH 0922/1160] typo --- src/components/views/dialogs/BaseDialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index 7959e7cb10..54623e6510 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -36,7 +36,7 @@ export default React.createClass({ propTypes: { // onFinished callback to call when Escape is pressed - // Take a boolean which is true is the dialog was dismissed + // Take a boolean which is true if the dialog was dismissed // with a positive / confirm action or false if it was // cancelled (from BaseDialog, this is always false). onFinished: PropTypes.func.isRequired, From 873993a7cae2ceae8a3207bb9cf6cc10dbf78a38 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 17:56:33 +0100 Subject: [PATCH 0923/1160] Clarify, hopefully --- src/components/views/dialogs/BaseDialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index 54623e6510..51d9180885 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -38,7 +38,7 @@ export default React.createClass({ // onFinished callback to call when Escape is pressed // Take a boolean which is true if the dialog was dismissed // with a positive / confirm action or false if it was - // cancelled (from BaseDialog, this is always false). + // cancelled (BaseDialog itself only calls this with false). onFinished: PropTypes.func.isRequired, // called when a key is pressed From 819059e7a5de638e61b976973b59fa468d62da07 Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Fri, 27 Apr 2018 14:32:48 +0000 Subject: [PATCH 0924/1160] Translated using Weblate (Russian) Currently translated at 100.0% (1165 of 1165 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 3c33abee86..53ea9085f8 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -831,7 +831,7 @@ "%(nameList)s %(transitionList)s": "%(nameList)s %(transitionList)s", "%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)sвошли %(count)s раз", "%(severalUsers)sjoined %(count)s times|one": "%(severalUsers)sвошли", - "%(oneUser)sjoined %(count)s times|other": "%(oneUser)sвошёл(-ла) %(count)s раз", + "%(oneUser)sjoined %(count)s times|other": "%(oneUser)sвошел(-ла) %(count)s раз", "%(oneUser)sjoined %(count)s times|one": "%(oneUser)sвошёл(-ла)", "%(severalUsers)sleft %(count)s times|other": "%(severalUsers)sушли %(count)s раз", "%(severalUsers)sleft %(count)s times|one": "%(severalUsers)sушли", From df30471df0a3d102390f1a7d43ea7e29b0e07401 Mon Sep 17 00:00:00 2001 From: Andrey Date: Sat, 28 Apr 2018 06:31:01 +0000 Subject: [PATCH 0925/1160] Translated using Weblate (Russian) Currently translated at 100.0% (1165 of 1165 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 53ea9085f8..2222dae5b4 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -800,7 +800,7 @@ "To join an existing community you'll have to know its community identifier; this will look something like +example:matrix.org.": "Чтобы присоединиться к существующему сообществу, вам нужно знать его ID; это будет выглядеть примерно так+primer:matrix.org.", "Something went wrong whilst creating your community": "При создании сообщества что-то пошло не так", "%(names)s and %(count)s others are typing|other": "%(names)s и еще %(count)s печатают", - "And %(count)s more...|other": "Ещё %(count)s…", + "And %(count)s more...|other": "Еще %(count)s…", "Delete Widget": "Удалить виджет", "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Удаление виджета действует для всех участников этой комнаты. Вы действительно хотите удалить этот виджет?", "Message removed": "Сообщение удалено", @@ -832,19 +832,19 @@ "%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)sвошли %(count)s раз", "%(severalUsers)sjoined %(count)s times|one": "%(severalUsers)sвошли", "%(oneUser)sjoined %(count)s times|other": "%(oneUser)sвошел(-ла) %(count)s раз", - "%(oneUser)sjoined %(count)s times|one": "%(oneUser)sвошёл(-ла)", + "%(oneUser)sjoined %(count)s times|one": "%(oneUser)sвошел(-ла)", "%(severalUsers)sleft %(count)s times|other": "%(severalUsers)sушли %(count)s раз", "%(severalUsers)sleft %(count)s times|one": "%(severalUsers)sушли", - "%(oneUser)sleft %(count)s times|other": "%(oneUser)sушёл(-ла) %(count)s раз", - "%(oneUser)sleft %(count)s times|one": "%(oneUser)sушёл(-ла)", + "%(oneUser)sleft %(count)s times|other": "%(oneUser)sушел(-ла) %(count)s раз", + "%(oneUser)sleft %(count)s times|one": "%(oneUser)sушел(-ла)", "%(severalUsers)sjoined and left %(count)s times|other": "%(severalUsers)sвошли и ушли %(count)s раз", "%(severalUsers)sjoined and left %(count)s times|one": "%(severalUsers)sвошли и ушли", - "%(oneUser)sjoined and left %(count)s times|other": "%(oneUser)sвошёл(-ла) и ушёл(-ла) %(count)s раз", - "%(oneUser)sjoined and left %(count)s times|one": "%(oneUser)sвошёл(-ла) и ушёл(-ла)", + "%(oneUser)sjoined and left %(count)s times|other": "%(oneUser)sвошел(-ла) и ушел(-ла) %(count)s раз", + "%(oneUser)sjoined and left %(count)s times|one": "%(oneUser)sвошел(-ла) и ушел(-ла)", "%(severalUsers)sleft and rejoined %(count)s times|other": "%(severalUsers)sушли и снова вошли %(count)s раз", "%(severalUsers)sleft and rejoined %(count)s times|one": "%(severalUsers)sушли и снова вошли", - "%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)sушёл(-ла) и снова вошёл(-ла) %(count)s раз", - "%(oneUser)sleft and rejoined %(count)s times|one": "%(oneUser)sушёл(-ла) и снова вошёл(-ла)", + "%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)sушел(-ла) и снова вошел(-ла) %(count)s раз", + "%(oneUser)sleft and rejoined %(count)s times|one": "%(oneUser)sушел(-ла) и снова вошел(-ла)", "were invited %(count)s times|other": "приглашены %(count)s раз", "were invited %(count)s times|one": "приглашены", "was invited %(count)s times|other": "приглашен(а) %(count)s раз", @@ -869,8 +869,8 @@ "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)sпоменяли аватары", "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)sпоменял(а) аватар %(count)s раз", "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)sпоменял(а) аватар", - "%(items)s and %(count)s others|other": "%(items)s и ещё %(count)s участника(-ов)", - "%(items)s and %(count)s others|one": "%(items)s и ещё кто-то", + "%(items)s and %(count)s others|other": "%(items)s и еще %(count)s участника(-ов)", + "%(items)s and %(count)s others|one": "%(items)s и еще кто-то", "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "Сообщение отправлено на %(emailAddress)s. После перехода по ссылке в отправленном вам письме, щелкните ниже.", "Room Notification": "Уведомления комнаты", "Drop here to tag direct chat": "Перетащите сюда, чтобы пометить как личный чат", From 55566b35a25ffa001369a7759e55ed0bbc5532e0 Mon Sep 17 00:00:00 2001 From: Eric Newport Date: Sat, 28 Apr 2018 12:39:25 -0400 Subject: [PATCH 0926/1160] convert attribute to class --- res/css/views/rooms/_EventTile.scss | 6 +++--- src/components/views/rooms/EventTile.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index 3aa1622e05..db62930be2 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -298,13 +298,13 @@ limitations under the License. cursor: pointer; } -.mx_EventTile_e2eIcon[hidden] { +.mx_EventTile_e2eIcon.hidden { display: none; } /* always override hidden attribute for blocked and warning */ -.mx_EventTile_e2eIcon[hidden][src="img/e2e-blocked.svg"], -.mx_EventTile_e2eIcon[hidden][src="img/e2e-warning.svg"] { +.mx_EventTile_e2eIcon.hidden[src="img/e2e-blocked.svg"], +.mx_EventTile_e2eIcon.hidden[src="img/e2e-warning.svg"] { display: block; } diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 565c8b5977..0c85b27162 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -745,7 +745,7 @@ function E2ePadlock(props) { if (SettingsStore.getValue("alwaysShowEncryptionIcons")) { return ; } else { - return ; + return ; } } From daf4a57a9c2f550a6e47c20b47de4dc63f7d96c2 Mon Sep 17 00:00:00 2001 From: Walter Date: Sat, 28 Apr 2018 11:41:05 +0000 Subject: [PATCH 0927/1160] Translated using Weblate (Russian) Currently translated at 100.0% (1165 of 1165 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 2222dae5b4..90b76681b4 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -200,7 +200,7 @@ "You need to be logged in.": "Вы должны войти в систему.", "You need to be able to invite users to do that.": "Для этого вы должны иметь возможность приглашать пользователей.", "You cannot place VoIP calls in this browser.": "Звонки не поддерживаются в этом браузере.", - "You are already in a call.": "Вы уже сделали звонок.", + "You are already in a call.": "Вы уже делаете звонок.", "You are trying to access %(roomName)s.": "Вы пытаетесь войти в %(roomName)s.", "You cannot place a call with yourself.": "Вы не можете позвонить самому себе.", "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s отозвал(а) свое приглашение %(targetName)s.", From 7f74bfde98c138f51e5189992c5e1b23e5f15eba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Sat, 28 Apr 2018 21:33:40 +0000 Subject: [PATCH 0928/1160] Translated using Weblate (Slovak) Currently translated at 100.0% (1165 of 1165 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sk/ --- src/i18n/strings/sk.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index 13cc6ac9aa..fd1280e27f 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -1156,5 +1156,12 @@ "Collapse panel": "Zbaliť panel", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Vo vašom súčasnom prehliadači nemusí Riot vizerať ani fungovať správne a niektoré alebo všetky vlastnosti môžu chýbať. Ak to chcete vyskúšať, môžete pokračovať, no pri riešení problémov s tým spojených si budete musieť poradiť na vlastnú päsť!", "Checking for an update...": "Kontrola dostupnosti aktualizácie...", - "There are advanced notifications which are not shown here": "Niektoré pokročilé oznámenia nemôžu byť zobrazené" + "There are advanced notifications which are not shown here": "Niektoré pokročilé oznámenia nemôžu byť zobrazené", + "Every page you use in the app": "Každú stránku v aplikácii, ktorú navštívite", + "e.g. ": "príklad ", + "Your User Agent": "Reťazec User Agent vašeho zariadenia", + "Your device resolution": "Rozlíšenie obrazovky vašeho zariadenia", + "Popout widget": "Otvoriť widget v novom okne", + "Missing roomId.": "Chýba ID miestnosti.", + "Picture": "Vytvoriť snímku" } From bbf4d3e39f6d52851ed4ca45f9f70d884566f365 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 29 Apr 2018 00:34:27 +0100 Subject: [PATCH 0929/1160] add comment Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/RoomView.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 8e24a75d68..b4735ce0a3 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -917,6 +917,7 @@ module.exports = React.createClass({ ContentMessages.sendContentToRoom( file, this.state.room.roomId, MatrixClientPeg.get(), ).done(() => { + // Send message_sent callback, for things like _checkIfAlone because after all a file is still a message. dis.dispatch({ action: 'message_sent', }); From 5bb15b1002d978715e39fe8e7072530830456c13 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 29 Apr 2018 00:48:44 +0100 Subject: [PATCH 0930/1160] simplify logic Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index b2ea8a90a3..0e9c96f908 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -83,13 +83,8 @@ export default class ReplyThread extends React.Component { async initialize() { const {parentEv} = this.props; - const inReplyTo = ReplyThread.getParentEventId(parentEv); - if (!inReplyTo) { - this.setState({err: true}); - return; - } - - const ev = await ReplyThread.getEvent(this.room, inReplyTo['event_id']); + // at time of making this component we checked that props.parentEv has a parentEventId + const ev = await ReplyThread.getEvent(this.room, ReplyThread.getParentEventId(parentEv)); if (this.unmounted) return; if (ev) { @@ -104,16 +99,16 @@ export default class ReplyThread extends React.Component { async loadNextEvent() { if (this.unmounted) return; const ev = this.state.events[0]; - const inReplyTo = ReplyThread.getParentEventId(ev); + const inReplyToEventId = ReplyThread.getParentEventId(ev); - if (!inReplyTo) { + if (!inReplyToEventId) { this.setState({ loading: false, }); return; } - const loadedEv = await ReplyThread.getEvent(this.room, inReplyTo['event_id']); + const loadedEv = await ReplyThread.getEvent(this.room, inReplyToEventId); if (this.unmounted) return; if (loadedEv) { From 407be88c929c5b8e00caf79d7e9caec5f0b5732e Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 29 Apr 2018 00:51:39 +0100 Subject: [PATCH 0931/1160] add comment Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 0e9c96f908..4268cb86f6 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -123,6 +123,8 @@ export default class ReplyThread extends React.Component { if (event) return event; try { + // ask the client to fetch the event we want using the context API, only interface to do so is to ask + // for a timeline with that event, but once it is loaded we can use findEventById to look up the ev map await this.context.matrixClient.getEventTimeline(room.getUnfilteredTimelineSet(), eventId); } catch (e) { return null; From c00c52e537d3562ecf39f888358faa650a9c8a96 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 29 Apr 2018 00:53:35 +0100 Subject: [PATCH 0932/1160] added another comment Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 4268cb86f6..e40ef4170e 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -127,6 +127,8 @@ export default class ReplyThread extends React.Component { // for a timeline with that event, but once it is loaded we can use findEventById to look up the ev map await this.context.matrixClient.getEventTimeline(room.getUnfilteredTimelineSet(), eventId); } catch (e) { + // if it fails, capture the error and dump it because it'll make findEventById return false, which + // captures a superset of errors. return null; } return room.findEventById(eventId); From 4021fc049c9843cb2301d8bb081acc00d1046610 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 29 Apr 2018 00:54:54 +0100 Subject: [PATCH 0933/1160] re-arrange method order to group statics before instance methods Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 70 ++++++++++---------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index e40ef4170e..249cdcfcb0 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -59,28 +59,6 @@ export default class ReplyThread extends React.Component { this.collapse = this.collapse.bind(this); } - componentWillMount() { - this.unmounted = false; - this.room = this.context.matrixClient.getRoom(this.props.parentEv.getRoomId()); - this.initialize(); - } - - componentDidUpdate() { - this.props.onWidgetLoad(); - } - - componentWillUnmount() { - this.unmounted = true; - } - - canCollapse() { - return this.state.events.length > 1; - } - - collapse() { - this.initialize(); - } - async initialize() { const {parentEv} = this.props; // at time of making this component we checked that props.parentEv has a parentEventId @@ -134,17 +112,6 @@ export default class ReplyThread extends React.Component { return room.findEventById(eventId); } - onQuoteClick() { - const events = [this.state.loadedEv, ...this.state.events]; - - this.setState({ - loadedEv: null, - events, - }, this.loadNextEvent); - - dis.dispatch({action: 'focus_composer'}); - } - static getParentEventId(ev) { if (!ev || ev.isRedacted()) return; @@ -189,7 +156,7 @@ export default class ReplyThread extends React.Component { case 'm.text': case 'm.notice': { html = `
    In reply to ${mxid}` - + `
    ${html || body}
    `; + + `
    ${html || body}
    `; const lines = body.trim().split('\n'); if (lines.length > 0) { lines[0] = `<${mxid}> ${lines[0]}`; @@ -199,7 +166,7 @@ export default class ReplyThread extends React.Component { } case 'm.image': html = `
    In reply to ${mxid}` - + `
    sent an image.
    `; + + `
    sent an image.
    `; body = `> <${mxid}> sent an image.\n\n`; break; case 'm.video': @@ -252,6 +219,39 @@ export default class ReplyThread extends React.Component { return ; } + componentWillMount() { + this.unmounted = false; + this.room = this.context.matrixClient.getRoom(this.props.parentEv.getRoomId()); + this.initialize(); + } + + componentDidUpdate() { + this.props.onWidgetLoad(); + } + + componentWillUnmount() { + this.unmounted = true; + } + + canCollapse() { + return this.state.events.length > 1; + } + + collapse() { + this.initialize(); + } + + onQuoteClick() { + const events = [this.state.loadedEv, ...this.state.events]; + + this.setState({ + loadedEv: null, + events, + }, this.loadNextEvent); + + dis.dispatch({action: 'focus_composer'}); + } + render() { let header = null; From 9701fd32b7b7cf56a85f53ca3af450e6e81af339 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 29 Apr 2018 03:07:31 +0100 Subject: [PATCH 0934/1160] switch back to blob urls for rendering e2e attachments Based on @walle303's work at https://github.com/matrix-org/matrix-react-sdk/pull/1820 Deliberately reverts https://github.com/matrix-org/matrix-react-sdk/commit/8f778f54fd10428836c99d08346cf89f038dd0ce Mitigates XSS by whitelisting the mime-types of the attachments so that malicious ones should not be recognised and executed by the browser. --- src/components/views/messages/MAudioBody.js | 4 +- src/components/views/messages/MImageBody.js | 6 +- src/components/views/messages/MVideoBody.js | 6 +- src/utils/DecryptFile.js | 82 ++++++++++++++++----- 4 files changed, 73 insertions(+), 25 deletions(-) diff --git a/src/components/views/messages/MAudioBody.js b/src/components/views/messages/MAudioBody.js index ab53918987..1e9962846c 100644 --- a/src/components/views/messages/MAudioBody.js +++ b/src/components/views/messages/MAudioBody.js @@ -20,7 +20,7 @@ import React from 'react'; import MFileBody from './MFileBody'; import MatrixClientPeg from '../../../MatrixClientPeg'; -import { decryptFile, readBlobAsDataUri } from '../../../utils/DecryptFile'; +import { decryptFile } from '../../../utils/DecryptFile'; import { _t } from '../../../languageHandler'; export default class MAudioBody extends React.Component { @@ -54,7 +54,7 @@ export default class MAudioBody extends React.Component { let decryptedBlob; decryptFile(content.file).then(function(blob) { decryptedBlob = blob; - return readBlobAsDataUri(decryptedBlob); + return URL.createObjectURL(decryptedBlob); }).done((url) => { this.setState({ decryptedUrl: url, diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index d5ce533bda..bb36e9b1ef 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -25,7 +25,7 @@ import ImageUtils from '../../../ImageUtils'; import Modal from '../../../Modal'; import sdk from '../../../index'; import dis from '../../../dispatcher'; -import { decryptFile, readBlobAsDataUri } from '../../../utils/DecryptFile'; +import { decryptFile } from '../../../utils/DecryptFile'; import Promise from 'bluebird'; import { _t } from '../../../languageHandler'; import SettingsStore from "../../../settings/SettingsStore"; @@ -169,14 +169,14 @@ export default class extends React.Component { thumbnailPromise = decryptFile( content.info.thumbnail_file, ).then(function(blob) { - return readBlobAsDataUri(blob); + return URL.createObjectURL(blob); }); } let decryptedBlob; thumbnailPromise.then((thumbnailUrl) => { return decryptFile(content.file).then(function(blob) { decryptedBlob = blob; - return readBlobAsDataUri(blob); + return URL.createObjectURL(blob); }).then((contentUrl) => { this.setState({ decryptedUrl: contentUrl, diff --git a/src/components/views/messages/MVideoBody.js b/src/components/views/messages/MVideoBody.js index 21edbae9a2..345c3f02e2 100644 --- a/src/components/views/messages/MVideoBody.js +++ b/src/components/views/messages/MVideoBody.js @@ -20,7 +20,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import MFileBody from './MFileBody'; import MatrixClientPeg from '../../../MatrixClientPeg'; -import { decryptFile, readBlobAsDataUri } from '../../../utils/DecryptFile'; +import { decryptFile } from '../../../utils/DecryptFile'; import Promise from 'bluebird'; import { _t } from '../../../languageHandler'; import SettingsStore from "../../../settings/SettingsStore"; @@ -94,14 +94,14 @@ module.exports = React.createClass({ thumbnailPromise = decryptFile( content.info.thumbnail_file, ).then(function(blob) { - return readBlobAsDataUri(blob); + return URL.createObjectURL(blob); }); } let decryptedBlob; thumbnailPromise.then((thumbnailUrl) => { return decryptFile(content.file).then(function(blob) { decryptedBlob = blob; - return readBlobAsDataUri(blob); + return URL.createObjectURL(blob); }).then((contentUrl) => { this.setState({ decryptedUrl: contentUrl, diff --git a/src/utils/DecryptFile.js b/src/utils/DecryptFile.js index cb5e407407..f8327832d1 100644 --- a/src/utils/DecryptFile.js +++ b/src/utils/DecryptFile.js @@ -1,5 +1,6 @@ /* Copyright 2016 OpenMarket Ltd +Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -22,25 +23,62 @@ import 'isomorphic-fetch'; import MatrixClientPeg from '../MatrixClientPeg'; import Promise from 'bluebird'; +// WARNING: We have to be very careful about what mime-types we allow into blobs, +// as for performance reasons these are now rendered via URL.createObjectURL() +// rather than by converting into data: URIs. +// +// This means that the content is rendered using the origin of the script which +// called createObjectURL(), and so if the content contains any scripting then it +// will pose a XSS vulnerability when the browser renders it. This is particularly +// bad if the user right-clicks the URI and pastes it into a new window or tab, +// as the blob will then execute with access to Riot's full JS environment(!) +// +// See https://github.com/matrix-org/matrix-react-sdk/pull/1820#issuecomment-385210647 +// for details. +// +// We mitigate this by only allowing mime-types into blobs which we know don't +// contain any scripting, and instantiate all others as application/octet-stream +// regardless of what mime-type the event claimed. Even if the payload itself +// is some malicious HTML, the fact we instantiate it with a media mimetype or +// application/octet-stream means the browser doesn't try to render it as such. +// +// One interesting edge case is image/svg+xml, which empirically *is* rendered +// correctly if the blob is set to the src attribute of an img tag (for thumbnails) +// *even if the mimetype is application/octet-stream*. However, empirically JS +// in the SVG isn't executed in this scenario, so we seem to be okay. +// +// Tested on Chrome 65 and Firefox 60 +// +// The list below is taken mainly from +// https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats +// N.B. Matrix doesn't currently specify which mimetypes are valid in given +// events, so we pick the ones which HTML5 browsers should be able to display +// +// For the record, mime-types which must NEVER enter this list below include: +// text/html, text/xhtml, image/svg, image/svg+xml, image/pdf, and similar. -/** - * Read blob as a data:// URI. - * @return {Promise} A promise that resolves with the data:// URI. - */ -export function readBlobAsDataUri(file) { - const deferred = Promise.defer(); - const reader = new FileReader(); - reader.onload = function(e) { - deferred.resolve(e.target.result); - }; - reader.onerror = function(e) { - deferred.reject(e); - }; - reader.readAsDataURL(file); - return deferred.promise; +const ALLOWED_BLOB_MIMETYPES = { + 'image/jpeg': true, + 'image/gif': true, + 'image/png': true, + + 'video/mp4': true, + 'video/webm': true, + 'video/ogg': true, + + 'audio/mp4': true, + 'audio/webm': true, + 'audio/aac': true, + 'audio/mpeg': true, + 'audio/ogg': true, + 'audio/wave': true, + 'audio/wav': true, + 'audio/x-wav': true, + 'audio/x-pn-wav': true, + 'audio/flac': true, + 'audio/x-flac': true, } - /** * Decrypt a file attached to a matrix event. * @param file {Object} The json taken from the matrix event. @@ -61,7 +99,17 @@ export function decryptFile(file) { return encrypt.decryptAttachment(responseData, file); }).then(function(dataArray) { // Turn the array into a Blob and give it the correct MIME-type. - const blob = new Blob([dataArray], {type: file.mimetype}); + + // IMPORTANT: we must not allow scriptable mime-types into Blobs otherwise + // they introduce XSS attacks if the Blob URI is viewed directly in the + // browser (e.g. by copying the URI into a new tab or window.) + // See warning at top of file. + const mimetype = file.mimetype ? file.mimetype.split(";")[0].trim() : ''; + if (!ALLOWED_BLOB_MIMETYPES[mimetype]) { + mimetype = 'application/octet-stream'; + } + + const blob = new Blob([dataArray], {type: mimetype}); return blob; }); } From bffd5bb891dfa0a874d28bd24d5ac7ca0ae54eac Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 29 Apr 2018 03:09:17 +0100 Subject: [PATCH 0935/1160] fix constness --- src/utils/DecryptFile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/DecryptFile.js b/src/utils/DecryptFile.js index f8327832d1..92c2e3644d 100644 --- a/src/utils/DecryptFile.js +++ b/src/utils/DecryptFile.js @@ -104,7 +104,7 @@ export function decryptFile(file) { // they introduce XSS attacks if the Blob URI is viewed directly in the // browser (e.g. by copying the URI into a new tab or window.) // See warning at top of file. - const mimetype = file.mimetype ? file.mimetype.split(";")[0].trim() : ''; + let mimetype = file.mimetype ? file.mimetype.split(";")[0].trim() : ''; if (!ALLOWED_BLOB_MIMETYPES[mimetype]) { mimetype = 'application/octet-stream'; } From 9c5407c21ffa9021ed3b746a278d9da5693a6672 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 29 Apr 2018 03:17:55 +0100 Subject: [PATCH 0936/1160] revokeObjectURLs --- src/components/views/messages/MAudioBody.js | 6 ++++++ src/components/views/messages/MImageBody.js | 8 ++++++++ src/components/views/messages/MVideoBody.js | 9 +++++++++ 3 files changed, 23 insertions(+) diff --git a/src/components/views/messages/MAudioBody.js b/src/components/views/messages/MAudioBody.js index 1e9962846c..efc6c4a069 100644 --- a/src/components/views/messages/MAudioBody.js +++ b/src/components/views/messages/MAudioBody.js @@ -69,6 +69,12 @@ export default class MAudioBody extends React.Component { } } + componentWillUnmount() { + if (this.state.decryptedUrl) { + URL.revokeObjectURL(this.state.decryptedUrl); + } + } + render() { const content = this.props.mxEvent.getContent(); diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index bb36e9b1ef..c22832467e 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -71,6 +71,7 @@ export default class extends React.Component { this.context.matrixClient.on('sync', this.onClientSync); } + // FIXME: factor this out and aplpy it to MVideoBody and MAudioBody too! onClientSync(syncState, prevState) { if (this.unmounted) return; // Consider the client reconnected if there is no error with syncing. @@ -206,6 +207,13 @@ export default class extends React.Component { dis.unregister(this.dispatcherRef); this.context.matrixClient.removeListener('sync', this.onClientSync); this._afterComponentWillUnmount(); + + if (this.state.decryptedUrl) { + URL.revokeObjectURL(this.state.decryptedUrl); + } + if (this.state.decryptedThumbnailUrl) { + URL.revokeObjectURL(this.state.decryptedThumbnailUrl); + } } // To be overridden by subclasses (e.g. MStickerBody) for further diff --git a/src/components/views/messages/MVideoBody.js b/src/components/views/messages/MVideoBody.js index 345c3f02e2..5365daee03 100644 --- a/src/components/views/messages/MVideoBody.js +++ b/src/components/views/messages/MVideoBody.js @@ -120,6 +120,15 @@ module.exports = React.createClass({ } }, + componentWillUnmount: function() { + if (this.state.decryptedUrl) { + URL.revokeObjectURL(this.state.decryptedUrl); + } + if (this.state.decryptedThumbnailUrl) { + URL.revokeObjectURL(this.state.decryptedThumbnailUrl); + } + }, + render: function() { const content = this.props.mxEvent.getContent(); From c254d043c5f69838be4feab0fc08fe652a691ddc Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 29 Apr 2018 03:58:17 +0100 Subject: [PATCH 0937/1160] fix ugly img errors and correctly render SVG thumbnails Fixes https://github.com/vector-im/riot-web/issues/6271 Fixes https://github.com/vector-im/riot-web/issues/1341 --- src/components/views/messages/MImageBody.js | 60 ++++++++++----------- 1 file changed, 27 insertions(+), 33 deletions(-) diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index d5ce533bda..7ecbf91365 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -154,7 +154,16 @@ export default class extends React.Component { return this.state.decryptedThumbnailUrl; } return this.state.decryptedUrl; - } else { + } + else if (content.info.mimetype == "image/svg+xml" && content.info.thumbnail_url) { + // special case to return client-generated thumbnails for SVGs, if any, + // given we deliberately don't thumbnail them serverside to prevent + // billion lol attacks and similar + return this.context.matrixClient.mxcUrlToHttp( + content.info.thumbnail_url, 800, 600 + ); + } + else { return this.context.matrixClient.mxcUrlToHttp(content.url, 800, 600); } } @@ -230,6 +239,9 @@ export default class extends React.Component { const maxHeight = 600; // let images take up as much width as they can so long as the height doesn't exceed 600px. // the alternative here would be 600*timelineWidth/800; to scale them down to fit inside a 4:3 bounding box + // FIXME: this will break on clientside generated thumbnails (as per e2e rooms) + // which may well be much smaller than the 800x600 bounding box. + //console.log("trying to fit image into timelineWidth of " + this.refs.body.offsetWidth + " or " + this.refs.body.clientWidth); let thumbHeight = null; if (content.info) { @@ -240,18 +252,22 @@ export default class extends React.Component { } _messageContent(contentUrl, thumbUrl, content) { + const thumbnail = ( + + {content.body} + + ); + return ( - - {content.body} - + { thumbUrl && !this.state.imgError ? thumbnail : '' } - + ); } @@ -286,14 +302,6 @@ export default class extends React.Component { ); } - if (this.state.imgError) { - return ( - - { _t("This image cannot be displayed.") } - - ); - } - const contentUrl = this._getContentUrl(); let thumbUrl; if (this._isGif() && SettingsStore.getValue("autoplayGifsAndVideos")) { @@ -302,20 +310,6 @@ export default class extends React.Component { thumbUrl = this._getThumbUrl(); } - if (thumbUrl) { - return this._messageContent(contentUrl, thumbUrl, content); - } else if (content.body) { - return ( - - { _t("Image '%(Body)s' cannot be displayed.", {Body: content.body}) } - - ); - } else { - return ( - - { _t("This image cannot be displayed.") } - - ); - } + return this._messageContent(contentUrl, thumbUrl, content); } } From 731f1fa7d3a91b90555e9211db692c7bf1c57820 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 29 Apr 2018 04:00:02 +0100 Subject: [PATCH 0938/1160] clarify another scrolljump bug --- src/components/views/messages/MImageBody.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index 7ecbf91365..034e700793 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -242,6 +242,8 @@ export default class extends React.Component { // FIXME: this will break on clientside generated thumbnails (as per e2e rooms) // which may well be much smaller than the 800x600 bounding box. + // FIXME: It will also break really badly for images with broken or missing thumbnails + //console.log("trying to fit image into timelineWidth of " + this.refs.body.offsetWidth + " or " + this.refs.body.clientWidth); let thumbHeight = null; if (content.info) { From 551d3ebda0e78c4a0d505d1cb12705a8edbad71c Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 29 Apr 2018 04:28:15 +0100 Subject: [PATCH 0939/1160] correctly fix up thumbnail height onload. fixes https://github.com/vector-im/riot-web/issues/6492, although popping is inevitable in the current implementation as it only fixes up the thumbnail size once the image has loaded. --- src/components/views/messages/MImageBody.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index 034e700793..99135fdf8c 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -50,6 +50,7 @@ export default class extends React.Component { this.onAction = this.onAction.bind(this); this.onImageError = this.onImageError.bind(this); + this.onImageLoad = this.onImageLoad.bind(this); this.onImageEnter = this.onImageEnter.bind(this); this.onImageLeave = this.onImageLeave.bind(this); this.onClientSync = this.onClientSync.bind(this); @@ -137,6 +138,11 @@ export default class extends React.Component { }); } + onImageLoad() { + this.fixupHeight(); + this.props.onWidgetLoad(); + } + _getContentUrl() { const content = this.props.mxEvent.getContent(); if (content.file !== undefined) { @@ -170,7 +176,6 @@ export default class extends React.Component { componentDidMount() { this.dispatcherRef = dis.register(this.onAction); - this.fixupHeight(); const content = this.props.mxEvent.getContent(); if (content.file !== undefined && this.state.decryptedUrl === null) { let thumbnailPromise = Promise.resolve(null); @@ -192,7 +197,6 @@ export default class extends React.Component { decryptedThumbnailUrl: thumbnailUrl, decryptedBlob: decryptedBlob, }); - this.props.onWidgetLoad(); }); }).catch((err) => { console.warn("Unable to decrypt attachment: ", err); @@ -244,7 +248,7 @@ export default class extends React.Component { // FIXME: It will also break really badly for images with broken or missing thumbnails - //console.log("trying to fit image into timelineWidth of " + this.refs.body.offsetWidth + " or " + this.refs.body.clientWidth); + // console.log("trying to fit image into timelineWidth of " + this.refs.body.offsetWidth + " or " + this.refs.body.clientWidth); let thumbHeight = null; if (content.info) { thumbHeight = ImageUtils.thumbHeight(content.info.w, content.info.h, timelineWidth, maxHeight); @@ -259,7 +263,7 @@ export default class extends React.Component { {content.body} From be523b3edc4259fd19a3fcd306af80fb463744ed Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 29 Apr 2018 04:31:30 +0100 Subject: [PATCH 0940/1160] lint --- src/components/views/messages/MImageBody.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index 99135fdf8c..b02c458642 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -160,16 +160,14 @@ export default class extends React.Component { return this.state.decryptedThumbnailUrl; } return this.state.decryptedUrl; - } - else if (content.info.mimetype == "image/svg+xml" && content.info.thumbnail_url) { + } else if (content.info.mimetype == "image/svg+xml" && content.info.thumbnail_url) { // special case to return client-generated thumbnails for SVGs, if any, // given we deliberately don't thumbnail them serverside to prevent // billion lol attacks and similar return this.context.matrixClient.mxcUrlToHttp( - content.info.thumbnail_url, 800, 600 + content.info.thumbnail_url, 800, 600, ); - } - else { + } else { return this.context.matrixClient.mxcUrlToHttp(content.url, 800, 600); } } From 8538cc1666eaba2d8792ba18b870b554040e6eea Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 29 Apr 2018 04:41:30 +0100 Subject: [PATCH 0941/1160] fix regressions introduced by https://github.com/vector-im/riot-web/commit/00b7cc512b3a9f0e0a36e4ea7d1f4a6c3011ff66 --- res/css/structures/_FilePanel.scss | 4 ++-- src/components/views/messages/MFileBody.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/res/css/structures/_FilePanel.scss b/res/css/structures/_FilePanel.scss index 58e090645f..87dc0aa756 100644 --- a/res/css/structures/_FilePanel.scss +++ b/res/css/structures/_FilePanel.scss @@ -50,13 +50,13 @@ limitations under the License. margin-right: 0px; } -.mx_FilePanel .mx_EventTile .mx_MImageBody_download { +.mx_FilePanel .mx_EventTile .mx_MFileBody_download { display: flex; font-size: 14px; color: $event-timestamp-color; } -.mx_FilePanel .mx_EventTile .mx_MImageBody_downloadLink { +.mx_FilePanel .mx_EventTile .mx_MFileBody_downloadLink { flex: 1 1 auto; color: $light-fg-color; } diff --git a/src/components/views/messages/MFileBody.js b/src/components/views/messages/MFileBody.js index d9ce61582e..246ea6891f 100644 --- a/src/components/views/messages/MFileBody.js +++ b/src/components/views/messages/MFileBody.js @@ -361,7 +361,7 @@ module.exports = React.createClass({ return (
    - + { fileName }
    From 45c0c0eddd0744bb337a18a0d50179802b26658a Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 29 Apr 2018 04:50:44 +0100 Subject: [PATCH 0942/1160] add CSS destroyed by stickerpacks fixing mangling from https://github.com/vector-im/riot-web/commit/9fc7435ea2ef7af161fadf4b3f9abc4a4aadcb73#diff-be2f1d72c9704840ceddf019c825e825 and https://github.com/vector-im/riot-web/commit/38efebb8d3946f321e6814cbd957afd042505538#diff-be2f1d72c9704840ceddf019c825e825 also fixes https://github.com/vector-im/riot-web/issues/6492 --- res/css/views/messages/_MImageBody.scss | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/res/css/views/messages/_MImageBody.scss b/res/css/views/messages/_MImageBody.scss index bf483feda3..1c809f0743 100644 --- a/res/css/views/messages/_MImageBody.scss +++ b/res/css/views/messages/_MImageBody.scss @@ -15,6 +15,10 @@ limitations under the License. */ .mx_MImageBody { - display: block; - margin-right: 34px; + display: block; + margin-right: 34px; } + +.mx_MImageBody_thumbnail { + max-width: 100%; +} \ No newline at end of file From db5fc53853951238dd0b44df833ae9578819f8d4 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 29 Apr 2018 04:53:32 +0100 Subject: [PATCH 0943/1160] final comment --- src/components/views/messages/MImageBody.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index b02c458642..2372c38f4b 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -246,6 +246,10 @@ export default class extends React.Component { // FIXME: It will also break really badly for images with broken or missing thumbnails + // FIXME: Because we don't know what size of thumbnail the server's actually going to send + // us, we can't even really layout the page nicely for it. Instead we have to assume + // it'll target 800x600 and we'll downsize if needed to make things fit. + // console.log("trying to fit image into timelineWidth of " + this.refs.body.offsetWidth + " or " + this.refs.body.clientWidth); let thumbHeight = null; if (content.info) { From 41af9f7a9610e7c75852b8a4bf47591554895ea8 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 29 Apr 2018 08:23:35 +0100 Subject: [PATCH 0944/1160] fix changed method name Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/messages/TextualBody.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index 14e80acec1..a4a4b4ebe8 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -422,7 +422,8 @@ module.exports = React.createClass({ const mxEvent = this.props.mxEvent; const content = mxEvent.getContent(); - const stripReply = SettingsStore.isFeatureEnabled("feature_rich_quoting") && ReplyThread.getInReplyTo(mxEvent); + const stripReply = SettingsStore.isFeatureEnabled("feature_rich_quoting") && + ReplyThread.getParentEventId(mxEvent); let body = HtmlUtils.bodyToHtml(content, this.props.highlights, { disableBigEmoji: SettingsStore.getValue('TextualBody.disableBigEmoji'), // Part of Replies fallback support From 68ca2a94612832aa56d7d288909b83b76cb66367 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 30 Apr 2018 13:33:57 +0100 Subject: [PATCH 0945/1160] Bump js-sdk version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 85b84d8d7e..329e67db11 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "isomorphic-fetch": "^2.2.1", "linkifyjs": "^2.1.3", "lodash": "^4.13.1", - "matrix-js-sdk": "0.10.2-rc.1", + "matrix-js-sdk": "0.10.2", "optimist": "^0.6.1", "pako": "^1.0.5", "prop-types": "^15.5.8", From cb0ae26b54ecbfd7f42ca7f95f58460368b7a9ae Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 30 Apr 2018 13:37:19 +0100 Subject: [PATCH 0946/1160] Prepare changelog for v0.12.3 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fd8630f6d..334461bffb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +Changes in [0.12.3](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.12.3) (2018-04-30) +===================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.12.3-rc.3...v0.12.3) + + * No changes since rc.3 + Changes in [0.12.3-rc.3](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.12.3-rc.3) (2018-04-26) =============================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.12.3-rc.2...v0.12.3-rc.3) From 603826b6622f81b10cca7e9fe49444f8ab01a08c Mon Sep 17 00:00:00 2001 From: Goudarz Jafari Date: Sat, 28 Apr 2018 20:26:52 +0000 Subject: [PATCH 0947/1160] Translated using Weblate (Persian) Currently translated at 12.7% (148 of 1165 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fa/ --- src/i18n/strings/fa.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fa.json b/src/i18n/strings/fa.json index 2e359e21cb..0e532d9483 100644 --- a/src/i18n/strings/fa.json +++ b/src/i18n/strings/fa.json @@ -144,5 +144,7 @@ "Collapse panel": "پنل را ببند", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "با مرورگر کنونی شما، ظاهر و حس استفاده از برنامه ممکن است کاملا اشتباه باشد و برخی یا همه‌ی ویژگی‌ها ممکن است کار نکنند. می‌توانید به استفاده ادامه دهید اما مسئولیت هر مشکلی که به آن بربخورید بر عهده‌ی خودتان است!", "Checking for an update...": "درحال بررسی به‌روزرسانی‌ها...", - "There are advanced notifications which are not shown here": "آگاه‌سازی‌های پیشرفته‌ای هستند که در اینجا نشان داده نشده‌اند" + "There are advanced notifications which are not shown here": "آگاه‌سازی‌های پیشرفته‌ای هستند که در اینجا نشان داده نشده‌اند", + "This email address is already in use": "این آدرس ایمیل در حال حاضر در حال استفاده است", + "This phone number is already in use": "این شماره تلفن در حال استفاده است" } From 19d9c624045b9418a76e9377ccd613cef7c5bf09 Mon Sep 17 00:00:00 2001 From: Andrey Date: Sat, 28 Apr 2018 17:05:25 +0000 Subject: [PATCH 0948/1160] Translated using Weblate (Russian) Currently translated at 100.0% (1165 of 1165 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 90b76681b4..320f834150 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -200,7 +200,7 @@ "You need to be logged in.": "Вы должны войти в систему.", "You need to be able to invite users to do that.": "Для этого вы должны иметь возможность приглашать пользователей.", "You cannot place VoIP calls in this browser.": "Звонки не поддерживаются в этом браузере.", - "You are already in a call.": "Вы уже делаете звонок.", + "You are already in a call.": "Идет разговор.", "You are trying to access %(roomName)s.": "Вы пытаетесь войти в %(roomName)s.", "You cannot place a call with yourself.": "Вы не можете позвонить самому себе.", "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s отозвал(а) свое приглашение %(targetName)s.", From dded89383a531cb27960edaa3a694b5517ea79bf Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 30 Apr 2018 13:37:57 +0100 Subject: [PATCH 0949/1160] v0.12.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 329e67db11..640d66f562 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.12.3-rc.3", + "version": "0.12.3", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From fc136607f107a24351bd44893a370413453dbaea Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 12:38:49 +0100 Subject: [PATCH 0950/1160] UI fixes in SessionRestoreErrorDialog * Make the 'delete my data' button not the default * Make it red * Give it a confirmation dialog * Remove the 'cancel' button: what does it mean to cancel an error? In this case, it tried again and almost certainly got the same error. * Remove the top-right 'x' and don't cancel on esc for the same reason. * Move 'send bug report' to a button rather than a 'click here' link * Add a 'refresh' button which, even if it's no more likely to work, will at least look like it's doing something (it's mostly so if you don't have a bug report endpoint, there's still a button other than the one that deletes all your data). --- res/css/_common.scss | 1 + src/components/views/dialogs/BaseDialog.js | 20 +++++- .../dialogs/SessionRestoreErrorDialog.js | 70 +++++++++++-------- .../views/elements/DialogButtons.js | 18 +++-- src/i18n/strings/en_EN.json | 13 ++-- 5 files changed, 79 insertions(+), 43 deletions(-) diff --git a/res/css/_common.scss b/res/css/_common.scss index e81c228430..c4cda6821e 100644 --- a/res/css/_common.scss +++ b/res/css/_common.scss @@ -250,6 +250,7 @@ textarea { .mx_Dialog button.danger, .mx_Dialog input[type="submit"].danger { background-color: $warning-color; border: solid 1px $warning-color; + color: $accent-fg-color; } .mx_Dialog button:disabled, .mx_Dialog input[type="submit"]:disabled { diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index 51d9180885..2f2d6fe8cb 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -1,5 +1,6 @@ /* Copyright 2017 Vector Creations Ltd +Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -41,6 +42,13 @@ export default React.createClass({ // cancelled (BaseDialog itself only calls this with false). onFinished: PropTypes.func.isRequired, + // Whether the dialog should have a 'close' button that will + // cause the dialog to be cancelled. This should only be set + // to true if there is nothing the app can sensibly do if the + // dialog is cancelled, eg. "We can't restore your session and + // the app cannot work". + hasCancel: PropTypes.bool, + // called when a key is pressed onKeyDown: PropTypes.func, @@ -59,6 +67,12 @@ export default React.createClass({ contentId: React.PropTypes.string, }, + getDefaultProps: function() { + return { + hasCancel: true, + }; + }, + childContextTypes: { matrixClient: PropTypes.instanceOf(MatrixClient), }, @@ -77,7 +91,7 @@ export default React.createClass({ if (this.props.onKeyDown) { this.props.onKeyDown(e); } - if (e.keyCode === KeyCode.ESCAPE) { + if (this.props.hasCancel && e.keyCode === KeyCode.ESCAPE) { e.stopPropagation(); e.preventDefault(); this.props.onFinished(false); @@ -104,11 +118,11 @@ export default React.createClass({ // AT users can skip its presentation. aria-describedby={this.props.contentId} > - - + : null }
    { this.props.title }
    diff --git a/src/components/views/dialogs/SessionRestoreErrorDialog.js b/src/components/views/dialogs/SessionRestoreErrorDialog.js index f101381ebf..2e152df4b0 100644 --- a/src/components/views/dialogs/SessionRestoreErrorDialog.js +++ b/src/components/views/dialogs/SessionRestoreErrorDialog.js @@ -31,63 +31,73 @@ export default React.createClass({ onFinished: PropTypes.func.isRequired, }, - componentDidMount: function() { - if (this.refs.bugreportLink) { - this.refs.bugreportLink.focus(); - } - }, - _sendBugReport: function() { const BugReportDialog = sdk.getComponent("dialogs.BugReportDialog"); Modal.createTrackedDialog('Session Restore Error', 'Send Bug Report Dialog', BugReportDialog, {}); }, - _onContinueClick: function() { - this.props.onFinished(true); + _onClearStorageClick: function() { + const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); + Modal.createTrackedDialog('Session Restore Confirm Logout', '', QuestionDialog, { + title: _t("Sign out"), + description: +
    { _t("Log out and remove encryption keys?") }
    , + button: _t("Sign out"), + danger: true, + onFinished: this.props.onFinished, + }); }, - _onCancelClick: function() { - this.props.onFinished(false); + _onRefreshClick: function() { + // Is this likely to help? Probably not, but giving only one button + // that clears your storage seems awful. + window.location.reload(true); }, render: function() { const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); - let bugreport; + let dialogButtons; if (SdkConfig.get().bug_report_endpoint_url) { - bugreport = ( -

    - { _t( - "Otherwise, click here to send a bug report.", - {}, - { 'a': (sub) => { sub } }, - ) } -

    - ); + dialogButtons = + + + } else { + dialogButtons = + + } - const shouldFocusContinueButton =!(bugreport==true); return (
    -

    { _t("We encountered an error trying to restore your previous session. If " + - "you continue, you will need to log in again, and encrypted chat " + - "history will be unreadable.") }

    +

    { _t("We encountered an error trying to restore your previous session.") }

    { _t("If you have previously used a more recent version of Riot, your session " + "may be incompatible with this version. Close this window and return " + "to the more recent version.") }

    - { bugreport } +

    { _t("Clearing your browser's storage may fix the problem, but will sign you " + + "out and cause any encrypted chat history to become unreadable.") }

    - + { dialogButtons }
    ); }, diff --git a/src/components/views/elements/DialogButtons.js b/src/components/views/elements/DialogButtons.js index 537f906a74..73e47cbde2 100644 --- a/src/components/views/elements/DialogButtons.js +++ b/src/components/views/elements/DialogButtons.js @@ -1,5 +1,6 @@ /* Copyright 2017 Aidan Gauland +Copyright 2018 New Vector Ltd. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,8 +15,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; - import React from "react"; import PropTypes from "prop-types"; import { _t } from '../../../languageHandler'; @@ -33,12 +32,21 @@ module.exports = React.createClass({ // onClick handler for the primary button. onPrimaryButtonClick: PropTypes.func.isRequired, + // should there be a cancel button? default: true + hasCancel: PropTypes.bool, + // onClick handler for the cancel button. - onCancel: PropTypes.func.isRequired, + onCancel: PropTypes.func, focus: PropTypes.bool, }, + getDefaultProps: function() { + return { + hasCancel: true, + } + }, + _onCancelClick: function() { this.props.onCancel(); }, @@ -57,9 +65,9 @@ module.exports = React.createClass({ { this.props.primaryButton } { this.props.children } - + : null }
    ); }, diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 33f18e47a4..3c8dd5b66f 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -103,7 +103,6 @@ "You need to be logged in.": "You need to be logged in.", "You need to be able to invite users to do that.": "You need to be able to invite users to do that.", "Unable to create widget.": "Unable to create widget.", - "Popout widget": "Popout widget", "Missing roomId.": "Missing roomId.", "Failed to send request.": "Failed to send request.", "This room is not recognised.": "This room is not recognised.", @@ -655,6 +654,7 @@ "Delete widget": "Delete widget", "Revoke widget access": "Revoke widget access", "Minimize apps": "Minimize apps", + "Popout widget": "Popout widget", "Picture": "Picture", "Edit": "Edit", "Create new room": "Create new room", @@ -807,11 +807,15 @@ "Ignore request": "Ignore request", "Loading device info...": "Loading device info...", "Encryption key request": "Encryption key request", - "Otherwise, click here to send a bug report.": "Otherwise, click here to send a bug report.", + "Sign out": "Sign out", + "Log out and remove encryption keys?": "Log out and remove encryption keys?", + "Send Logs": "Send Logs", + "Clear Storage and Sign Out": "Clear Storage and Sign Out", + "Refresh": "Refresh", "Unable to restore session": "Unable to restore session", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.", + "We encountered an error trying to restore your previous session.": "We encountered an error trying to restore your previous session.", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.", - "Continue anyway": "Continue anyway", + "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.", "Invalid Email Address": "Invalid Email Address", "This doesn't appear to be a valid email address": "This doesn't appear to be a valid email address", "Verification Pending": "Verification Pending", @@ -1015,7 +1019,6 @@ "Status.im theme": "Status.im theme", "Can't load user settings": "Can't load user settings", "Server may be unavailable or overloaded": "Server may be unavailable or overloaded", - "Sign out": "Sign out", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.", "Success": "Success", "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them", From 37cb8abf13008362875f64fd853e5e17d9b83594 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 15:19:08 +0100 Subject: [PATCH 0951/1160] Fix UX issues with bug report dialog * Make it use BaseDialog / DialogButtons (also gives it has a top-right 'x' & escape to cancel works) * Stop misusing the 'danger' CSS class on the buttons. There is nothing dangerous about submitting logs. * Continued campaign against 'Click here' links. Fixes https://github.com/vector-im/riot-web/issues/6622 --- src/components/structures/UserSettings.js | 4 +- .../views/dialogs/BugReportDialog.js | 42 +++++++------------ .../views/elements/DialogButtons.js | 14 +++++-- src/i18n/strings/en_EN.json | 2 +- 4 files changed, 30 insertions(+), 32 deletions(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 7948f4fb5d..44e2f93d63 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -1,7 +1,7 @@ /* Copyright 2015, 2016 OpenMarket Ltd Copyright 2017 Vector Creations Ltd -Copyright 2017 New Vector Ltd +Copyright 2017, 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -804,7 +804,7 @@ module.exports = React.createClass({ "other users. They do not contain messages.", ) }

    -
    diff --git a/src/components/views/dialogs/BugReportDialog.js b/src/components/views/dialogs/BugReportDialog.js index 2025b6fc81..83cdb1f07f 100644 --- a/src/components/views/dialogs/BugReportDialog.js +++ b/src/components/views/dialogs/BugReportDialog.js @@ -1,5 +1,6 @@ /* Copyright 2017 OpenMarket Ltd +Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -105,6 +106,8 @@ export default class BugReportDialog extends React.Component { render() { const Loader = sdk.getComponent("elements.Spinner"); + const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); + const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); let error = null; if (this.state.err) { @@ -113,13 +116,6 @@ export default class BugReportDialog extends React.Component {
    ; } - let cancelButton = null; - if (!this.state.busy) { - cancelButton = ; - } - let progress = null; if (this.state.busy) { progress = ( @@ -131,11 +127,11 @@ export default class BugReportDialog extends React.Component { } return ( -
    -
    - { _t("Submit debug logs") } -
    -
    + +

    { _t( "Debug logs contain application usage data including your " + @@ -146,7 +142,7 @@ export default class BugReportDialog extends React.Component {

    { _t( - "Click here to create a GitHub issue.", + "Riot bugs are tracked on GitHub: create a GitHub issue.", {}, { a: (sub) => -

    -
    + +
    ); } } diff --git a/src/components/views/elements/DialogButtons.js b/src/components/views/elements/DialogButtons.js index 73e47cbde2..c8c90ddc47 100644 --- a/src/components/views/elements/DialogButtons.js +++ b/src/components/views/elements/DialogButtons.js @@ -39,11 +39,14 @@ module.exports = React.createClass({ onCancel: PropTypes.func, focus: PropTypes.bool, + + disabled: PropTypes.bool, }, getDefaultProps: function() { return { hasCancel: true, + disabled: false, } }, @@ -56,18 +59,23 @@ module.exports = React.createClass({ if (this.props.primaryButtonClass) { primaryButtonClassName += " " + this.props.primaryButtonClass; } + let cancelButton; + if (this.props.hasCancel) { + cancelButton = ; + } return (
    { this.props.children } - { this.props.hasCancel ? : null } + { cancelButton }
    ); }, diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 3c8dd5b66f..daf0ce605d 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -745,7 +745,7 @@ "Failed to send logs: ": "Failed to send logs: ", "Submit debug logs": "Submit debug logs", "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.", - "
    Click here to create a GitHub issue.": "Click here to create a GitHub issue.", + "Riot bugs are tracked on GitHub: create a GitHub issue.": "Riot bugs are tracked on GitHub: create a GitHub issue.", "GitHub issue link:": "GitHub issue link:", "Notes:": "Notes:", "Send logs": "Send logs", From a9b6db3f2ecbd2a9f27d3d2b9f033a95bf303709 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 27 Apr 2018 15:56:28 +0100 Subject: [PATCH 0952/1160] Lint --- src/components/views/dialogs/SessionRestoreErrorDialog.js | 4 ++-- src/components/views/elements/DialogButtons.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/views/dialogs/SessionRestoreErrorDialog.js b/src/components/views/dialogs/SessionRestoreErrorDialog.js index 2e152df4b0..779e54cfba 100644 --- a/src/components/views/dialogs/SessionRestoreErrorDialog.js +++ b/src/components/views/dialogs/SessionRestoreErrorDialog.js @@ -68,7 +68,7 @@ export default React.createClass({ - + ; } else { dialogButtons = { _t("Clear Storage and Sign Out") } - + ; } return ( diff --git a/src/components/views/elements/DialogButtons.js b/src/components/views/elements/DialogButtons.js index c8c90ddc47..267127568d 100644 --- a/src/components/views/elements/DialogButtons.js +++ b/src/components/views/elements/DialogButtons.js @@ -47,7 +47,7 @@ module.exports = React.createClass({ return { hasCancel: true, disabled: false, - } + }; }, _onCancelClick: function() { From 5d46efc3e82a33d02158a7da66fbba5a2f3eb4d0 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 30 Apr 2018 14:17:21 +0100 Subject: [PATCH 0953/1160] Get docs right on hasCancel --- src/components/views/dialogs/BaseDialog.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index 2f2d6fe8cb..71a5da224c 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -44,9 +44,9 @@ export default React.createClass({ // Whether the dialog should have a 'close' button that will // cause the dialog to be cancelled. This should only be set - // to true if there is nothing the app can sensibly do if the + // to false if there is nothing the app can sensibly do if the // dialog is cancelled, eg. "We can't restore your session and - // the app cannot work". + // the app cannot work". Default: true. hasCancel: PropTypes.bool, // called when a key is pressed From 54cccab0c78de06eb89cfb23a711d266390af115 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 30 Apr 2018 14:22:18 +0100 Subject: [PATCH 0954/1160] Factor out clearStorageButton --- .../views/dialogs/SessionRestoreErrorDialog.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/components/views/dialogs/SessionRestoreErrorDialog.js b/src/components/views/dialogs/SessionRestoreErrorDialog.js index 779e54cfba..808c12712f 100644 --- a/src/components/views/dialogs/SessionRestoreErrorDialog.js +++ b/src/components/views/dialogs/SessionRestoreErrorDialog.js @@ -58,6 +58,12 @@ export default React.createClass({ const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); + const clearStorageButton = ( + + ); + let dialogButtons; if (SdkConfig.get().bug_report_endpoint_url) { dialogButtons = - + {clearStorageButton} ; } else { dialogButtons = - + {clearStorageButton} ; } From c3420c37fd5ab748394f6fe55c4a368b586b9a8a Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 30 Apr 2018 14:25:42 +0100 Subject: [PATCH 0955/1160] Indentation --- .../views/dialogs/SessionRestoreErrorDialog.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/components/views/dialogs/SessionRestoreErrorDialog.js b/src/components/views/dialogs/SessionRestoreErrorDialog.js index 808c12712f..bc90788a28 100644 --- a/src/components/views/dialogs/SessionRestoreErrorDialog.js +++ b/src/components/views/dialogs/SessionRestoreErrorDialog.js @@ -92,12 +92,16 @@ export default React.createClass({

    { _t("We encountered an error trying to restore your previous session.") }

    -

    { _t("If you have previously used a more recent version of Riot, your session " + - "may be incompatible with this version. Close this window and return " + - "to the more recent version.") }

    +

    { _t( + "If you have previously used a more recent version of Riot, your session " + + "may be incompatible with this version. Close this window and return " + + "to the more recent version." + ) }

    -

    { _t("Clearing your browser's storage may fix the problem, but will sign you " + - "out and cause any encrypted chat history to become unreadable.") }

    +

    { _t( + "Clearing your browser's storage may fix the problem, but will sign you " + + "out and cause any encrypted chat history to become unreadable." + ) }

    { dialogButtons } From e28a927da9ce8b8d8eb75d1a830886b56583d8bf Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 30 Apr 2018 14:34:14 +0100 Subject: [PATCH 0956/1160] lint --- src/components/views/dialogs/SessionRestoreErrorDialog.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/views/dialogs/SessionRestoreErrorDialog.js b/src/components/views/dialogs/SessionRestoreErrorDialog.js index bc90788a28..60430b995e 100644 --- a/src/components/views/dialogs/SessionRestoreErrorDialog.js +++ b/src/components/views/dialogs/SessionRestoreErrorDialog.js @@ -71,7 +71,7 @@ export default React.createClass({ focus={true} hasCancel={false} > - {clearStorageButton} + { clearStorageButton } ; } else { dialogButtons = - {clearStorageButton} + { clearStorageButton } ; } @@ -95,12 +95,12 @@ export default React.createClass({

    { _t( "If you have previously used a more recent version of Riot, your session " + "may be incompatible with this version. Close this window and return " + - "to the more recent version." + "to the more recent version.", ) }

    { _t( "Clearing your browser's storage may fix the problem, but will sign you " + - "out and cause any encrypted chat history to become unreadable." + "out and cause any encrypted chat history to become unreadable.", ) }

    { dialogButtons } From 60be988025b33f5058f9ff53fd0a94dc3986efc8 Mon Sep 17 00:00:00 2001 From: Krombel Date: Mon, 30 Apr 2018 14:53:37 +0000 Subject: [PATCH 0957/1160] Translated using Weblate (German) Currently translated at 100.0% (1165 of 1165 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 278d915229..0df095f366 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -1158,5 +1158,10 @@ "Checking for an update...": "Nach Updates suchen...", "There are advanced notifications which are not shown here": "Es existieren erweiterte Benachrichtigungen, welche hier nicht angezeigt werden", "Missing roomId.": "Fehlende Raum-ID.", - "Picture": "Bild" + "Picture": "Bild", + "Every page you use in the app": "Jede Seite, die du in der App benutzt", + "e.g. ": "z.B. ", + "Your User Agent": "Deine Browser-Kennung", + "Your device resolution": "Deine Bildschirmauflösung", + "Popout widget": "Widget ausklinken" } From 9f8abc68f743e107bfe07dfc266c767a9fa560e8 Mon Sep 17 00:00:00 2001 From: Klaus Marx Date: Mon, 30 Apr 2018 14:54:38 +0000 Subject: [PATCH 0958/1160] Translated using Weblate (German) Currently translated at 100.0% (1165 of 1165 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 0df095f366..fc897b87a0 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -928,7 +928,7 @@ "Display your community flair in rooms configured to show it.": "Zeige deinen Community-Flair in den Räumen, die es erlauben.", "This homeserver doesn't offer any login flows which are supported by this client.": "Dieser Heimserver verfügt über keinen, von diesem Client unterstütztes Anmeldeverfahren.", "Call Failed": "Anruf fehlgeschlagen", - "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "In diesem Raum befinden sich nicht verifizierte Geräte. Wenn du fortfährst, ohne sie zu verifizieren, könnten Angreifer den Anruf mithören.", + "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "In diesem Raum befinden sich nicht verifizierte Geräte. Wenn du ohne sie zu verifizieren fortfährst, könnten Angreifer den Anruf mithören.", "Review Devices": "Geräte ansehen", "Call Anyway": "Trotzdem anrufen", "Answer Anyway": "Trotzdem annehmen", From 485ea635cff6cae166010bbb3ca7813239756841 Mon Sep 17 00:00:00 2001 From: Krombel Date: Mon, 30 Apr 2018 14:57:09 +0000 Subject: [PATCH 0959/1160] Translated using Weblate (German) Currently translated at 100.0% (1165 of 1165 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index fc897b87a0..4a80002acc 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -702,7 +702,7 @@ "Unignore": "Ignorieren aufheben", "User Options": "Benutzer-Optionen", "Unignored user": "Benutzer nicht mehr ignoriert", - "Ignored user": "Ignorierter Benutzer", + "Ignored user": "Benutzer ignoriert", "Stops ignoring a user, showing their messages going forward": "Beendet das Ignorieren eines Benutzers, nachfolgende Nachrichten werden wieder angezeigt", "Ignores a user, hiding their messages from you": "Ignoriert einen Benutzer und verbirgt dessen Nachrichten", "Disable Emoji suggestions while typing": "Emoji-Vorschläge während des Schreibens deaktivieren", From f1e401bedf64ac7a2f96b6d92f7626c42dfe08d2 Mon Sep 17 00:00:00 2001 From: Bamstam Date: Mon, 30 Apr 2018 14:58:42 +0000 Subject: [PATCH 0960/1160] Translated using Weblate (German) Currently translated at 100.0% (1165 of 1165 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 4a80002acc..72dcae00a6 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -260,7 +260,7 @@ "%(targetName)s left the room.": "%(targetName)s hat den Raum verlassen.", "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s hat den zukünftigen Chatverlauf sichtbar gemacht für alle Raum-Mitglieder (ab dem Zeitpunkt, an dem sie eingeladen wurden).", "%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s hat den zukünftigen Chatverlauf sichtbar gemacht für alle Raum-Mitglieder (ab dem Zeitpunkt, an dem sie beigetreten sind).", - "%(senderName)s made future room history visible to all room members.": "%(senderName)s hat den zukünftigen Chatverlauf sichtbar gemacht für alle Raum-Mitglieder.", + "%(senderName)s made future room history visible to all room members.": "%(senderName)s hat den zukünftigen Chatverlauf sichtbar gemacht für: Alle Raum-Mitglieder.", "%(senderName)s made future room history visible to anyone.": "%(senderName)s hat den zukünftigen Chatverlauf sichtbar gemacht für Alle.", "%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s hat den zukünftigen Chatverlauf sichtbar gemacht für unbekannt (%(visibility)s).", "Missing room_id in request": "Fehlende room_id in Anfrage", @@ -275,7 +275,7 @@ "%(senderName)s removed their profile picture.": "%(senderName)s hat das Profilbild gelöscht.", "%(senderName)s requested a VoIP conference.": "%(senderName)s möchte eine VoIP-Konferenz beginnen.", "Room %(roomId)s not visible": "Raum %(roomId)s ist nicht sichtbar", - "%(senderDisplayName)s sent an image.": "%(senderDisplayName)s hat ein Bild übermittelt.", + "%(senderDisplayName)s sent an image.": "%(senderDisplayName)s hat ein Bild gesendet.", "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s hat %(targetDisplayName)s in diesen Raum eingeladen.", "%(senderName)s set a profile picture.": "%(senderName)s hat ein Profilbild gesetzt.", "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s hat den Anzeigenamen geändert in %(displayName)s.", @@ -625,7 +625,7 @@ "(could not connect media)": "(Medienverbindung konnte nicht hergestellt werden)", "(no answer)": "(keine Antwort)", "(unknown failure: %(reason)s)": "(Unbekannter Fehler: %(reason)s)", - "Your browser does not support the required cryptography extensions": "Dein Browser unterstützt die benötigten Kryptografie-Erweiterungen nicht", + "Your browser does not support the required cryptography extensions": "Dein Browser unterstützt die benötigten Verschlüsselungs-Erweiterungen nicht", "Not a valid Riot keyfile": "Keine gültige Riot-Schlüsseldatei", "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", From 005d3efaf9fe0862c9f632ca72d178b4d208fccd Mon Sep 17 00:00:00 2001 From: Krombel Date: Mon, 30 Apr 2018 15:01:21 +0000 Subject: [PATCH 0961/1160] Translated using Weblate (German) Currently translated at 100.0% (1165 of 1165 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 72dcae00a6..f0103161fb 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -751,7 +751,7 @@ "Long Description (HTML)": "Lange Beschreibung (HTML)", "Jump to message": "Zur Nachricht springen", "No pinned messages.": "Keine angehefteten Nachrichten vorhanden.", - "Loading...": "Lade...", + "Loading...": "Lädt...", "Unpin Message": "Nachricht nicht mehr anheften", "Unnamed room": "Unbenannter Raum", "World readable": "Lesbar für alle", From 8c4a5b15eeae55084ae71863ebaa7c6168e5a2d4 Mon Sep 17 00:00:00 2001 From: Bamstam Date: Mon, 30 Apr 2018 15:07:41 +0000 Subject: [PATCH 0962/1160] Translated using Weblate (German) Currently translated at 100.0% (1165 of 1165 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index f0103161fb..46129c8218 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -80,7 +80,7 @@ "Failed to change password. Is your password correct?": "Passwortänderung fehlgeschlagen. Ist dein Passwort richtig?", "Failed to leave room": "Verlassen des Raums fehlgeschlagen", "Failed to reject invitation": "Einladung konnte nicht abgelehnt werden", - "Failed to set avatar.": "Fehler beim Setzen des Profilbilds.", + "Failed to set avatar.": "Profilbild konnte nicht gesetzt werden.", "Failed to unban": "Aufheben der Verbannung fehlgeschlagen", "Failed to upload file": "Datei-Upload fehlgeschlagen", "Favourite": "Favorit", @@ -446,7 +446,7 @@ "Dismiss": "Ablehnen", "You can also set a custom identity server but this will typically prevent interaction with users based on email address.": "Du kannst auch einen angepassten Idantitätsserver angeben aber dies wird typischerweise Interaktionen mit anderen Nutzern auf Basis der E-Mail-Adresse verhindern.", "Please check your email to continue registration.": "Bitte prüfe deine E-Mails, um mit der Registrierung fortzufahren.", - "Token incorrect": "Token inkorrekt", + "Token incorrect": "Token fehlerhaft", "Please enter the code it contains:": "Bitte gebe den Code ein, den sie enthält:", "powered by Matrix": "betrieben mit Matrix", "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Wenn du keine E-Mail-Adresse angibst, wirst du nicht in der Lage sein, dein Passwort zurückzusetzen. Bist du sicher?", @@ -648,7 +648,7 @@ "Changes colour scheme of current room": "Ändere Farbschema des aktuellen Raumes", "Delete widget": "Widget entfernen", "Define the power level of a user": "Setze das Berechtigungslevel eines Benutzers", - "Edit": "Editieren", + "Edit": "Bearbeiten", "Enable automatic language detection for syntax highlighting": "Automatische Spracherkennung für die Syntax-Hervorhebung aktivieren", "Hide join/leave messages (invites/kicks/bans unaffected)": "Betreten-/Verlassen-Benachrichtigungen verbergen (gilt nicht für Einladungen/Kicks/Bans)", "Revoke widget access": "Ziehe Widget-Zugriff zurück", @@ -698,7 +698,7 @@ "Matrix ID": "Matrix-ID", "Advanced options": "Erweiterte Optionen", "Block users on other matrix homeservers from joining this room": "Benutzern auf anderen Matrix-Heimservern das Betreten dieses Raumes verbieten", - "This setting cannot be changed later!": "Diese Einstellung kann nachträglich nicht mehr geändert werden!", + "This setting cannot be changed later!": "Diese Einstellung kann später nicht mehr geändert werden!", "Unignore": "Ignorieren aufheben", "User Options": "Benutzer-Optionen", "Unignored user": "Benutzer nicht mehr ignoriert", @@ -754,7 +754,7 @@ "Loading...": "Lädt...", "Unpin Message": "Nachricht nicht mehr anheften", "Unnamed room": "Unbenannter Raum", - "World readable": "Lesbar für alle", + "World readable": "Für alle lesbar", "Guests can join": "Gäste können beitreten", "No rooms to show": "Keine anzeigbaren Räume", "Community Settings": "Community-Einstellungen", @@ -796,7 +796,7 @@ "Join an existing community": "Einer bestehenden Community beitreten", "To join an existing community you'll have to know its community identifier; this will look something like +example:matrix.org.": "Um einer bereits bestehenden Community beitreten zu können, musst dir deren Community-ID bekannt sein. Diese sieht z. B. aus wie +example:matrix.org.", "Your Communities": "Deine Communities", - "You're not currently a member of any communities.": "Du bist aktuell kein Mitglied einer Community.", + "You're not currently a member of any communities.": "Du gehörst aktuell keiner Community an.", "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Erstelle eine Community, um Benutzer und Räume miteinander zu verbinden! Erstelle zusätzlich eine eigene Homepage, um deinen individuellen Bereich im Matrix-Universum zu gestalten.", "Something went wrong whilst creating your community": "Beim Erstellen deiner Community ist ein Fehler aufgetreten", "%(names)s and %(count)s others are typing|other": "%(names)s und %(count)s weitere schreiben", @@ -859,9 +859,9 @@ "Ban this user?": "Diesen Benutzer verbannen?", "Drop here to favourite": "Hierher ziehen, um als Favorit zu markieren", "Drop here to tag direct chat": "Hierher ziehen, um als Direkt-Chat zu markieren", - "Drop here to restore": "Hierher ziehen zum Wiederherstellen", + "Drop here to restore": "Hierher ziehen, um wiederherzustellen", "Drop here to demote": "Hierher ziehen, um herabzustufen", - "You have been kicked from this room by %(userName)s.": "Du wurdest von %(userName)s aus diesem Raum gekickt.", + "You have been kicked from this room by %(userName)s.": "%(userName)s hat dich aus diesem Raum gekickt.", "You are trying to access a room.": "Du versuchst, auf einen Raum zuzugreifen.", "Members only (since the point in time of selecting this option)": "Nur Mitglieder (ab dem Zeitpunkt, an dem diese Option ausgewählt wird)", "Members only (since they were invited)": "Nur Mitglieder (ab dem Zeitpunkt, an dem sie eingeladen wurden)", From 73b19dccf9d5eb97bc340e05f61ff3fcd008ceca Mon Sep 17 00:00:00 2001 From: Andreas Marek Date: Mon, 30 Apr 2018 15:07:59 +0000 Subject: [PATCH 0963/1160] Translated using Weblate (German) Currently translated at 100.0% (1165 of 1165 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 46129c8218..6814a7a20a 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -781,7 +781,7 @@ "Community ID": "Community-ID", "example": "Beispiel", "Add rooms to the community summary": "Fügt Räume zur Community-Übersicht hinzu", - "Add users to the community summary": "Fügt Benutzer zur Community-Übersicht hinzu", + "Add users to the community summary": "Füge Benutzer zur Community-Übersicht hinzu", "Failed to update community": "Aktualisieren der Community fehlgeschlagen", "Leave Community": "Community verlassen", "Add rooms to this community": "Räume zu dieser Community hinzufügen", From 461beb6548043303670102b2c50f07b3923fbc09 Mon Sep 17 00:00:00 2001 From: Bamstam Date: Mon, 30 Apr 2018 15:08:51 +0000 Subject: [PATCH 0964/1160] Translated using Weblate (German) Currently translated at 100.0% (1165 of 1165 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 6814a7a20a..222b897560 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -722,7 +722,7 @@ "To change the topic, you must be a": "Notwendiges Berechtigungslevel, um das Thema zu ändern", "To modify widgets in the room, you must be a": "Notwendiges Berechtigungslevel, um Widgets in diesem Raum zu ändern", "Description": "Beschreibung", - "Unable to accept invite": "Einladung kann nicht akzeptiert werden", + "Unable to accept invite": "Einladung kann nicht angenommen werden", "Failed to invite users to %(groupId)s": "Benutzer konnten nicht in %(groupId)s eingeladen werden", "Unable to reject invite": "Einladung konnte nicht abgelehnt werden", "Who would you like to add to this summary?": "Wen möchtest zu dieser Übersicht hinzufügen?", From 6ab30e8d88381c50234695dbb35db9a4875b640b Mon Sep 17 00:00:00 2001 From: Krombel Date: Mon, 30 Apr 2018 15:09:43 +0000 Subject: [PATCH 0965/1160] Translated using Weblate (German) Currently translated at 100.0% (1165 of 1165 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 222b897560..153ced6360 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -890,7 +890,7 @@ "Community Invites": "Community-Einladungen", "Notify the whole room": "Alle im Raum benachrichtigen", "Room Notification": "Raum-Benachrichtigung", - "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Diese Räume werden Community-Mitgliedern auf der Community-Seite angezeigt. Community-Mitglieder können diesen Räumen beitreten, indem sie auf diese klicken.", + "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Diese Räume werden Community-Mitgliedern auf der Community-Seite angezeigt. Community-Mitglieder können diesen Räumen beitreten, indem sie diese anklicken.", "Show these rooms to non-members on the community page and room list?": "Sollen diese Räume Nicht-Mitgliedern auf der Community-Seite und in der Raum-Liste angezeigt werden?", "

    HTML for your community's page

    \n

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

    \n

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

    \n": "

    HTML für deine Community-Seite

    \n

    \n Nutze die ausführliche Beschreibung, um neuen Mitgliedern diese Community vorzustellen\n oder um wichtige Links bereitzustellen.\n

    \n

    \n Du kannst sogar 'img'-Tags (HTML) verwenden\n

    \n", "Your community hasn't got a Long Description, a HTML page to show to community members.
    Click here to open settings and give it one!": "Deine Community hat noch keine ausführliche Beschreibung, d. h. eine HTML-Seite, die Community-Mitgliedern angezeigt wird.
    Hier klicken, um die Einstellungen zu öffnen und eine Beschreibung zu erstellen!", From 3b927a6b93e589d5836874666d5c17f81eb55640 Mon Sep 17 00:00:00 2001 From: zottel Date: Mon, 30 Apr 2018 15:10:58 +0000 Subject: [PATCH 0966/1160] Translated using Weblate (German) Currently translated at 100.0% (1165 of 1165 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 153ced6360..dfd2f1cfa5 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -373,7 +373,7 @@ "bullet": "Aufzählung", "Click to unmute video": "Klicken, um die Video-Stummschaltung zu deaktivieren", "Click to unmute audio": "Klicken, um den Ton wieder einzuschalten", - "Failed to load timeline position": "Laden der Position im Chatverlauf fehlgeschlagen", + "Failed to load timeline position": "Laden der Chat-Position fehlgeschlagen", "Failed to toggle moderator status": "Umschalten des Moderator-Status fehlgeschlagen", "Enable encryption": "Verschlüsselung aktivieren", "The main address for this room is": "Die Hauptadresse für diesen Raum ist", From 4d15392593739ca73c31ce73f18857d3cc5822b1 Mon Sep 17 00:00:00 2001 From: Bamstam Date: Mon, 30 Apr 2018 15:13:00 +0000 Subject: [PATCH 0967/1160] Translated using Weblate (German) Currently translated at 100.0% (1165 of 1165 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index dfd2f1cfa5..8dd6e214d7 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -31,7 +31,7 @@ "Sender device information": "Geräte-Informationen des Absenders", "Displays action": "Zeigt Aktionen an", "Bans user with given id": "Verbannt den Benutzer mit der angegebenen ID", - "Deops user with given id": "Entfernt OP beim Benutzer mit der angegebenen ID", + "Deops user with given id": "Setzt beim Benutzer mit der angegebenen ID das Berechtigungslevel herab", "Invites user with given id to current room": "Lädt den Benutzer mit der angegebenen ID in den aktuellen Raum ein", "Joins room with given alias": "Raum wird mit dem angegebenen Alias betreten", "Kicks user with given id": "Benutzer mit der angegebenen ID kicken", @@ -225,7 +225,7 @@ "%(weekDayName)s %(time)s": "%(weekDayName)s, %(time)s", "Set a display name:": "Anzeigename eingeben:", "Upload an avatar:": "Profilbild hochladen:", - "This server does not support authentication with a phone number.": "Dieser Server unterstützt keine Authentifizierung mittels Telefonnummer.", + "This server does not support authentication with a phone number.": "Dieser Server unterstützt keine Authentifizierung per Telefonnummer.", "Missing password.": "Fehlendes Passwort.", "Passwords don't match.": "Passwörter stimmen nicht überein.", "Password too short (min %(MIN_PASSWORD_LENGTH)s).": "Passwort zu kurz (min. %(MIN_PASSWORD_LENGTH)s).", From 79491764fe130c7560ccd1585534fa62fead09d5 Mon Sep 17 00:00:00 2001 From: Krombel Date: Mon, 30 Apr 2018 15:14:24 +0000 Subject: [PATCH 0968/1160] Translated using Weblate (German) Currently translated at 100.0% (1165 of 1165 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 8dd6e214d7..f4144b13de 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -31,7 +31,7 @@ "Sender device information": "Geräte-Informationen des Absenders", "Displays action": "Zeigt Aktionen an", "Bans user with given id": "Verbannt den Benutzer mit der angegebenen ID", - "Deops user with given id": "Setzt beim Benutzer mit der angegebenen ID das Berechtigungslevel herab", + "Deops user with given id": "Setzt das Berechtigungslevel beim Benutzer mit der angegebenen ID zurück", "Invites user with given id to current room": "Lädt den Benutzer mit der angegebenen ID in den aktuellen Raum ein", "Joins room with given alias": "Raum wird mit dem angegebenen Alias betreten", "Kicks user with given id": "Benutzer mit der angegebenen ID kicken", From e037cf006310609d441d808d8a07be0b3e53a82e Mon Sep 17 00:00:00 2001 From: Eric Newport Date: Mon, 30 Apr 2018 12:22:16 -0400 Subject: [PATCH 0969/1160] namespace CSS better and fix bug --- res/css/views/rooms/_EventTile.scss | 6 +++--- src/components/views/rooms/EventTile.js | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index db62930be2..788940fe0e 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -298,13 +298,13 @@ limitations under the License. cursor: pointer; } -.mx_EventTile_e2eIcon.hidden { +.mx_EventTile_e2eIcon_hidden { display: none; } /* always override hidden attribute for blocked and warning */ -.mx_EventTile_e2eIcon.hidden[src="img/e2e-blocked.svg"], -.mx_EventTile_e2eIcon.hidden[src="img/e2e-warning.svg"] { +.mx_EventTile_e2eIcon_hidden[src="img/e2e-blocked.svg"], +.mx_EventTile_e2eIcon_hidden[src="img/e2e-warning.svg"] { display: block; } diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 0c85b27162..84acfb160e 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -31,6 +31,7 @@ import withMatrixClient from '../../../wrappers/withMatrixClient'; const ContextualMenu = require('../../structures/ContextualMenu'); import dis from '../../../dispatcher'; import {makeEventPermalink} from "../../../matrix-to"; +import SettingsStore from "../../../settings/SettingsStore"; const ObjectUtils = require('../../../ObjectUtils'); @@ -745,7 +746,7 @@ function E2ePadlock(props) { if (SettingsStore.getValue("alwaysShowEncryptionIcons")) { return ; } else { - return ; + return ; } } From b926baf805db13f06baf239a8d787d6f40802abd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Mon, 30 Apr 2018 17:27:24 +0000 Subject: [PATCH 0970/1160] Translated using Weblate (French) Currently translated at 100.0% (1169 of 1169 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 0ff1467c3a..ef023d2f1e 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -1163,5 +1163,13 @@ "Every page you use in the app": "Toutes les pages que vous utilisez dans l'application", "e.g. ": "par ex. ", "Your User Agent": "Votre user agent", - "Your device resolution": "La résolution de votre appareil" + "Your device resolution": "La résolution de votre appareil", + "Always show encryption icons": "Toujours afficher les icônes de chiffrement", + "Riot bugs are tracked on GitHub: create a GitHub issue.": "Les bugs de Riot sont suivis sur GitHub : créer un signalement GitHub.", + "Log out and remove encryption keys?": "Se déconnecter et effacer les clés de chiffrement ?", + "Send Logs": "Envoyer les rapports", + "Clear Storage and Sign Out": "Vider le stockage et se déconnecter", + "Refresh": "Rafraîchir", + "We encountered an error trying to restore your previous session.": "Une erreur est survenue lors de la récupération de la dernière session.", + "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Vider le cache de votre navigateur peut résoudre le problème, mais cela vous déconnectera et tous les historiques de conversation encryptés seront illisibles." } From 9e215433843a11b46a61e8b053ea7e7cb982808f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Mon, 30 Apr 2018 17:30:19 +0000 Subject: [PATCH 0971/1160] Translated using Weblate (French) Currently translated at 100.0% (1169 of 1169 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index ef023d2f1e..cf2f594c74 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -1168,8 +1168,8 @@ "Riot bugs are tracked on GitHub: create a GitHub issue.": "Les bugs de Riot sont suivis sur GitHub : créer un signalement GitHub.", "Log out and remove encryption keys?": "Se déconnecter et effacer les clés de chiffrement ?", "Send Logs": "Envoyer les rapports", - "Clear Storage and Sign Out": "Vider le stockage et se déconnecter", + "Clear Storage and Sign Out": "Effacer le stockage et se déconnecter", "Refresh": "Rafraîchir", "We encountered an error trying to restore your previous session.": "Une erreur est survenue lors de la récupération de la dernière session.", - "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Vider le cache de votre navigateur peut résoudre le problème, mais cela vous déconnectera et tous les historiques de conversation encryptés seront illisibles." + "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Effacer le stockage de votre navigateur peut résoudre le problème, mais cela vous déconnectera et tous les historiques de conversation encryptés seront illisibles." } From 556773e1d635671bfa6b082a26f1e2ea72428699 Mon Sep 17 00:00:00 2001 From: Andrey Date: Mon, 30 Apr 2018 18:13:26 +0000 Subject: [PATCH 0972/1160] Translated using Weblate (Russian) Currently translated at 100.0% (1169 of 1169 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 320f834150..b8a55b32a7 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -1163,5 +1163,13 @@ "Every page you use in the app": "Каждая страница, которую вы используете в приложении", "e.g. ": "напр. ", "Your User Agent": "Ваш пользовательский агент", - "Your device resolution": "Разрешение вашего устройства" + "Your device resolution": "Разрешение вашего устройства", + "Always show encryption icons": "Всегда показывать значки шифрования", + "Riot bugs are tracked on GitHub: create a GitHub issue.": "Ошибки Riot отслеживаются на GitHub: создать проблему на GitHub.", + "Log out and remove encryption keys?": "Выйти и удалить ключи шифрования?", + "Send Logs": "Отправить логи", + "Clear Storage and Sign Out": "Очистить хранилище и выйти", + "Refresh": "Обновить", + "We encountered an error trying to restore your previous session.": "Произошла ошибка при попытке восстановить предыдущий сеанс.", + "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Очистка хранилища вашего браузера может устранить проблему, но при этом ваша сессия будет завершена и зашифрованная история чата станет нечитаемой." } From bbce6eea5be3fb228ee105480efe1dfa1421f478 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 30 Apr 2018 23:28:55 +0100 Subject: [PATCH 0973/1160] update comment Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 249cdcfcb0..40db914941 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -105,8 +105,8 @@ export default class ReplyThread extends React.Component { // for a timeline with that event, but once it is loaded we can use findEventById to look up the ev map await this.context.matrixClient.getEventTimeline(room.getUnfilteredTimelineSet(), eventId); } catch (e) { - // if it fails, capture the error and dump it because it'll make findEventById return false, which - // captures a superset of errors. + // if it fails catch the error and return early, there's no point trying to find the event in this case. + // Return null as it is falsey and thus should be treated as an error (as the event cannot be resolved). return null; } return room.findEventById(eventId); From 1ea004fea8384bf2c7612aaf927ab79a5dae6d41 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Tue, 1 May 2018 08:27:18 +0000 Subject: [PATCH 0974/1160] Translated using Weblate (Hungarian) Currently translated at 100.0% (1169 of 1169 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index c29305cffc..32f56afa29 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -1163,5 +1163,13 @@ "Every page you use in the app": "Minden oldal, amit az alkalmazásban használsz", "e.g. ": "pl.: ", "Your User Agent": "Felhasználói ügynököd", - "Your device resolution": "Eszközöd felbontása" + "Your device resolution": "Eszközöd felbontása", + "Always show encryption icons": "Titkosítási ikon folyamatos megjelenítése", + "Riot bugs are tracked on GitHub: create a GitHub issue.": "Riot hibák a GItHubon követhetők: hiba bejelentés a GitHubon.", + "Log out and remove encryption keys?": "Kijelentkezel és töröljük a titkosítási kulcsokat?", + "Send Logs": "Naplók küldése", + "Clear Storage and Sign Out": "Tárhely törlése és kijelentkezés", + "Refresh": "Frissítés", + "We encountered an error trying to restore your previous session.": "Hibába ütköztünk megpróbáljuk visszaállítani az előző munkamenetet.", + "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "A böngésződ tárhelyének a törlése megoldhatja a problémát, de ezzel kijelentkezel és a titkosított beszélgetések előzményei olvashatatlanná válnak." } From 023daef4b784f1891f83aeca5fc8a427af8df658 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 1 May 2018 11:18:45 +0100 Subject: [PATCH 0975/1160] Refactor GroupStores into one global GroupStore Take a step closer to a flux-like architecture for group data, for the purposes of providing features that require it. Now the app has a single GroupStore that can be poked to fetch updates for a particular group. --- src/GroupAddressPicker.js | 7 +- src/components/structures/GroupView.js | 103 ++++---- src/components/structures/RightPanel.js | 15 +- .../views/dialogs/AddressPickerDialog.js | 5 +- .../views/groups/GroupMemberInfo.js | 26 +- .../views/groups/GroupMemberList.js | 13 +- .../views/groups/GroupPublicityToggle.js | 10 +- src/components/views/groups/GroupRoomInfo.js | 23 +- src/components/views/groups/GroupRoomList.js | 25 +- src/components/views/rooms/RoomList.js | 32 +-- src/stores/GroupStore.js | 223 +++++++++--------- src/stores/GroupStoreCache.js | 38 --- src/utils/MultiInviter.js | 6 +- 13 files changed, 245 insertions(+), 281 deletions(-) delete mode 100644 src/stores/GroupStoreCache.js diff --git a/src/GroupAddressPicker.js b/src/GroupAddressPicker.js index c45a335ab6..91380b6eed 100644 --- a/src/GroupAddressPicker.js +++ b/src/GroupAddressPicker.js @@ -19,7 +19,7 @@ import sdk from './'; import MultiInviter from './utils/MultiInviter'; import { _t } from './languageHandler'; import MatrixClientPeg from './MatrixClientPeg'; -import GroupStoreCache from './stores/GroupStoreCache'; +import GroupStore from './stores/GroupStore'; export function showGroupInviteDialog(groupId) { return new Promise((resolve, reject) => { @@ -116,11 +116,10 @@ function _onGroupInviteFinished(groupId, addrs) { function _onGroupAddRoomFinished(groupId, addrs, addRoomsPublicly) { const matrixClient = MatrixClientPeg.get(); - const groupStore = GroupStoreCache.getGroupStore(groupId); const errorList = []; return Promise.all(addrs.map((addr) => { - return groupStore - .addRoomToGroup(addr.address, addRoomsPublicly) + return GroupStore + .addRoomToGroup(groupId, addr.address, addRoomsPublicly) .catch(() => { errorList.push(addr.address); }) .then(() => { const roomId = addr.address; diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index 62fdb1070a..534d8d3df8 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -27,7 +27,6 @@ import AccessibleButton from '../views/elements/AccessibleButton'; import Modal from '../../Modal'; import classnames from 'classnames'; -import GroupStoreCache from '../../stores/GroupStoreCache'; import GroupStore from '../../stores/GroupStore'; import FlairStore from '../../stores/FlairStore'; import { showGroupAddRoomDialog } from '../../GroupAddressPicker'; @@ -93,8 +92,8 @@ const CategoryRoomList = React.createClass({ if (!success) return; const errorList = []; Promise.all(addrs.map((addr) => { - return this.context.groupStore - .addRoomToGroupSummary(addr.address) + return GroupStore + .addRoomToGroupSummary(this.props.groupId, addr.address) .catch(() => { errorList.push(addr.address); }) .reflect(); })).then(() => { @@ -174,7 +173,8 @@ const FeaturedRoom = React.createClass({ onDeleteClicked: function(e) { e.preventDefault(); e.stopPropagation(); - this.context.groupStore.removeRoomFromGroupSummary( + GroupStore.removeRoomFromGroupSummary( + this.props.groupId, this.props.summaryInfo.room_id, ).catch((err) => { console.error('Error whilst removing room from group summary', err); @@ -269,7 +269,7 @@ const RoleUserList = React.createClass({ if (!success) return; const errorList = []; Promise.all(addrs.map((addr) => { - return this.context.groupStore + return GroupStore .addUserToGroupSummary(addr.address) .catch(() => { errorList.push(addr.address); }) .reflect(); @@ -344,7 +344,8 @@ const FeaturedUser = React.createClass({ onDeleteClicked: function(e) { e.preventDefault(); e.stopPropagation(); - this.context.groupStore.removeUserFromGroupSummary( + GroupStore.removeUserFromGroupSummary( + this.props.groupId, this.props.summaryInfo.user_id, ).catch((err) => { console.error('Error whilst removing user from group summary', err); @@ -390,15 +391,6 @@ const FeaturedUser = React.createClass({ }, }); -const GroupContext = { - groupStore: PropTypes.instanceOf(GroupStore).isRequired, -}; - -CategoryRoomList.contextTypes = GroupContext; -FeaturedRoom.contextTypes = GroupContext; -RoleUserList.contextTypes = GroupContext; -FeaturedUser.contextTypes = GroupContext; - const GROUP_JOINPOLICY_OPEN = "open"; const GROUP_JOINPOLICY_INVITE = "invite"; @@ -415,12 +407,6 @@ export default React.createClass({ groupStore: PropTypes.instanceOf(GroupStore), }, - getChildContext: function() { - return { - groupStore: this._groupStore, - }; - }, - getInitialState: function() { return { summary: null, @@ -440,6 +426,7 @@ export default React.createClass({ }, componentWillMount: function() { + this._unmounted = false; this._matrixClient = MatrixClientPeg.get(); this._matrixClient.on("Group.myMembership", this._onGroupMyMembership); @@ -448,8 +435,8 @@ export default React.createClass({ }, componentWillUnmount: function() { + this._unmounted = true; this._matrixClient.removeListener("Group.myMembership", this._onGroupMyMembership); - this._groupStore.removeAllListeners(); }, componentWillReceiveProps: function(newProps) { @@ -464,8 +451,7 @@ export default React.createClass({ }, _onGroupMyMembership: function(group) { - if (group.groupId !== this.props.groupId) return; - + if (this._unmounted || group.groupId !== this.props.groupId) return; if (group.myMembership === 'leave') { // Leave settings - the user might have clicked the "Leave" button this._closeSettings(); @@ -478,34 +464,11 @@ export default React.createClass({ if (group && group.inviter && group.inviter.userId) { this._fetchInviterProfile(group.inviter.userId); } - this._groupStore = GroupStoreCache.getGroupStore(groupId); - this._groupStore.registerListener(() => { - const summary = this._groupStore.getSummary(); - if (summary.profile) { - // Default profile fields should be "" for later sending to the server (which - // requires that the fields are strings, not null) - ["avatar_url", "long_description", "name", "short_description"].forEach((k) => { - summary.profile[k] = summary.profile[k] || ""; - }); - } - this.setState({ - summary, - summaryLoading: !this._groupStore.isStateReady(GroupStore.STATE_KEY.Summary), - isGroupPublicised: this._groupStore.getGroupPublicity(), - isUserPrivileged: this._groupStore.isUserPrivileged(), - groupRooms: this._groupStore.getGroupRooms(), - groupRoomsLoading: !this._groupStore.isStateReady(GroupStore.STATE_KEY.GroupRooms), - isUserMember: this._groupStore.getGroupMembers().some( - (m) => m.userId === this._matrixClient.credentials.userId, - ), - error: null, - }); - if (this.props.groupIsNew && firstInit) { - this._onEditClick(); - } - }); + GroupStore.registerListener(groupId, this.onGroupStoreUpdated.bind(this, firstInit)); let willDoOnboarding = false; - this._groupStore.on('error', (err) => { + // XXX: This should be more fluxy - let's get the error from GroupStore .getError or something + GroupStore.on('error', (err, errorGroupId) => { + if (this._unmounted || groupId !== errorGroupId) return; if (err.errcode === 'M_GUEST_ACCESS_FORBIDDEN' && !willDoOnboarding) { dis.dispatch({ action: 'do_after_sync_prepared', @@ -524,11 +487,40 @@ export default React.createClass({ }); }, + onGroupStoreUpdated(firstInit) { + if (this._unmounted) return; + const summary = GroupStore.getSummary(this.props.groupId); + if (summary.profile) { + // Default profile fields should be "" for later sending to the server (which + // requires that the fields are strings, not null) + ["avatar_url", "long_description", "name", "short_description"].forEach((k) => { + summary.profile[k] = summary.profile[k] || ""; + }); + } + this.setState({ + summary, + summaryLoading: !GroupStore.isStateReady(this.props.groupId, GroupStore.STATE_KEY.Summary), + isGroupPublicised: GroupStore.getGroupPublicity(this.props.groupId), + isUserPrivileged: GroupStore.isUserPrivileged(this.props.groupId), + groupRooms: GroupStore.getGroupRooms(this.props.groupId), + groupRoomsLoading: !GroupStore.isStateReady(this.props.groupId, GroupStore.STATE_KEY.GroupRooms), + isUserMember: GroupStore.getGroupMembers(this.props.groupId).some( + (m) => m.userId === this._matrixClient.credentials.userId, + ), + error: null, + }); + // XXX: This might not work but this.props.groupIsNew unused anyway + if (this.props.groupIsNew && firstInit) { + this._onEditClick(); + } + }, + _fetchInviterProfile(userId) { this.setState({ inviterProfileBusy: true, }); this._matrixClient.getProfileInfo(userId).then((resp) => { + if (this._unmounted) return; this.setState({ inviterProfile: { avatarUrl: resp.avatar_url, @@ -538,6 +530,7 @@ export default React.createClass({ }).catch((e) => { console.error('Error getting group inviter profile', e); }).finally(() => { + if (this._unmounted) return; this.setState({ inviterProfileBusy: false, }); @@ -677,7 +670,7 @@ export default React.createClass({ // spinner disappearing after we have fetched new group data. await Promise.delay(500); - this._groupStore.acceptGroupInvite().then(() => { + GroupStore.acceptGroupInvite(this.props.groupId).then(() => { // don't reset membershipBusy here: wait for the membership change to come down the sync }).catch((e) => { this.setState({membershipBusy: false}); @@ -696,7 +689,7 @@ export default React.createClass({ // spinner disappearing after we have fetched new group data. await Promise.delay(500); - this._groupStore.leaveGroup().then(() => { + GroupStore.leaveGroup(this.props.groupId).then(() => { // don't reset membershipBusy here: wait for the membership change to come down the sync }).catch((e) => { this.setState({membershipBusy: false}); @@ -715,7 +708,7 @@ export default React.createClass({ // spinner disappearing after we have fetched new group data. await Promise.delay(500); - this._groupStore.joinGroup().then(() => { + GroupStore.joinGroup(this.props.groupId).then(() => { // don't reset membershipBusy here: wait for the membership change to come down the sync }).catch((e) => { this.setState({membershipBusy: false}); @@ -743,7 +736,7 @@ export default React.createClass({ // spinner disappearing after we have fetched new group data. await Promise.delay(500); - this._groupStore.leaveGroup().then(() => { + GroupStore.leaveGroup(this.props.groupId).then(() => { // don't reset membershipBusy here: wait for the membership change to come down the sync }).catch((e) => { this.setState({membershipBusy: false}); diff --git a/src/components/structures/RightPanel.js b/src/components/structures/RightPanel.js index ca1e331d15..18523ceb59 100644 --- a/src/components/structures/RightPanel.js +++ b/src/components/structures/RightPanel.js @@ -27,7 +27,7 @@ import Analytics from '../../Analytics'; import RateLimitedFunc from '../../ratelimitedfunc'; import AccessibleButton from '../../components/views/elements/AccessibleButton'; import { showGroupInviteDialog, showGroupAddRoomDialog } from '../../GroupAddressPicker'; -import GroupStoreCache from '../../stores/GroupStoreCache'; +import GroupStore from '../../stores/GroupStore'; import { formatCount } from '../../utils/FormattingUtils'; @@ -120,7 +120,7 @@ module.exports = React.createClass({ if (this.context.matrixClient) { this.context.matrixClient.removeListener("RoomState.members", this.onRoomStateMember); } - this._unregisterGroupStore(); + this._unregisterGroupStore(this.props.groupId); }, getInitialState: function() { @@ -132,26 +132,23 @@ module.exports = React.createClass({ componentWillReceiveProps(newProps) { if (newProps.groupId !== this.props.groupId) { - this._unregisterGroupStore(); + this._unregisterGroupStore(this.props.groupId); this._initGroupStore(newProps.groupId); } }, _initGroupStore(groupId) { if (!groupId) return; - this._groupStore = GroupStoreCache.getGroupStore(groupId); - this._groupStore.registerListener(this.onGroupStoreUpdated); + GroupStore.registerListener(groupId, this.onGroupStoreUpdated); }, _unregisterGroupStore() { - if (this._groupStore) { - this._groupStore.unregisterListener(this.onGroupStoreUpdated); - } + GroupStore.unregisterListener(this.onGroupStoreUpdated); }, onGroupStoreUpdated: function() { this.setState({ - isUserPrivilegedInGroup: this._groupStore.isUserPrivileged(), + isUserPrivilegedInGroup: GroupStore.isUserPrivileged(this.props.groupId), }); }, diff --git a/src/components/views/dialogs/AddressPickerDialog.js b/src/components/views/dialogs/AddressPickerDialog.js index 685c4fcde3..0d0b7456b5 100644 --- a/src/components/views/dialogs/AddressPickerDialog.js +++ b/src/components/views/dialogs/AddressPickerDialog.js @@ -22,7 +22,7 @@ import sdk from '../../../index'; import MatrixClientPeg from '../../../MatrixClientPeg'; import Promise from 'bluebird'; import { addressTypes, getAddressType } from '../../../UserAddress.js'; -import GroupStoreCache from '../../../stores/GroupStoreCache'; +import GroupStore from '../../../stores/GroupStore'; const TRUNCATE_QUERY_LIST = 40; const QUERY_USER_DIRECTORY_DEBOUNCE_MS = 200; @@ -243,9 +243,8 @@ module.exports = React.createClass({ _doNaiveGroupRoomSearch: function(query) { const lowerCaseQuery = query.toLowerCase(); - const groupStore = GroupStoreCache.getGroupStore(this.props.groupId); const results = []; - groupStore.getGroupRooms().forEach((r) => { + GroupStore.getGroupRooms(this.props.groupId).forEach((r) => { const nameMatch = (r.name || '').toLowerCase().includes(lowerCaseQuery); const topicMatch = (r.topic || '').toLowerCase().includes(lowerCaseQuery); const aliasMatch = (r.canonical_alias || '').toLowerCase().includes(lowerCaseQuery); diff --git a/src/components/views/groups/GroupMemberInfo.js b/src/components/views/groups/GroupMemberInfo.js index 4970a26e5b..4fed293bec 100644 --- a/src/components/views/groups/GroupMemberInfo.js +++ b/src/components/views/groups/GroupMemberInfo.js @@ -23,7 +23,7 @@ import Modal from '../../../Modal'; import sdk from '../../../index'; import { _t } from '../../../languageHandler'; import { GroupMemberType } from '../../../groups'; -import GroupStoreCache from '../../../stores/GroupStoreCache'; +import GroupStore from '../../../stores/GroupStore'; import AccessibleButton from '../elements/AccessibleButton'; module.exports = React.createClass({ @@ -47,33 +47,37 @@ module.exports = React.createClass({ }, componentWillMount: function() { + this._unmounted = false; this._initGroupStore(this.props.groupId); }, componentWillReceiveProps(newProps) { if (newProps.groupId !== this.props.groupId) { - this._unregisterGroupStore(); + this._unregisterGroupStore(this.props.groupId); this._initGroupStore(newProps.groupId); } }, - _initGroupStore(groupId) { - this._groupStore = GroupStoreCache.getGroupStore(this.props.groupId); - this._groupStore.registerListener(this.onGroupStoreUpdated); + componentWillUnmount() { + this._unmounted = true; + this._unregisterGroupStore(this.props.groupId); }, - _unregisterGroupStore() { - if (this._groupStore) { - this._groupStore.unregisterListener(this.onGroupStoreUpdated); - } + _initGroupStore(groupId) { + GroupStore.registerListener(groupId, this.onGroupStoreUpdated); + }, + + _unregisterGroupStore(groupId) { + GroupStore.unregisterListener(this.onGroupStoreUpdated); }, onGroupStoreUpdated: function() { + if (this._unmounted) return; this.setState({ - isUserInvited: this._groupStore.getGroupInvitedMembers().some( + isUserInvited: GroupStore.getGroupInvitedMembers(this.props.groupId).some( (m) => m.userId === this.props.groupMember.userId, ), - isUserPrivilegedInGroup: this._groupStore.isUserPrivileged(), + isUserPrivilegedInGroup: GroupStore.isUserPrivileged(this.props.groupId), }); }, diff --git a/src/components/views/groups/GroupMemberList.js b/src/components/views/groups/GroupMemberList.js index 17a91d83fa..faf172083f 100644 --- a/src/components/views/groups/GroupMemberList.js +++ b/src/components/views/groups/GroupMemberList.js @@ -17,7 +17,7 @@ limitations under the License. import React from 'react'; import { _t } from '../../../languageHandler'; import sdk from '../../../index'; -import GroupStoreCache from '../../../stores/GroupStoreCache'; +import GroupStore from '../../../stores/GroupStore'; import PropTypes from 'prop-types'; const INITIAL_LOAD_NUM_MEMBERS = 30; @@ -42,9 +42,12 @@ export default React.createClass({ this._initGroupStore(this.props.groupId); }, + componentWillUnmount: function() { + this._unmounted = true; + }, + _initGroupStore: function(groupId) { - this._groupStore = GroupStoreCache.getGroupStore(groupId); - this._groupStore.registerListener(() => { + GroupStore.registerListener(groupId, () => { this._fetchMembers(); }); }, @@ -52,8 +55,8 @@ export default React.createClass({ _fetchMembers: function() { if (this._unmounted) return; this.setState({ - members: this._groupStore.getGroupMembers(), - invitedMembers: this._groupStore.getGroupInvitedMembers(), + members: GroupStore.getGroupMembers(this.props.groupId), + invitedMembers: GroupStore.getGroupInvitedMembers(this.props.groupId), }); }, diff --git a/src/components/views/groups/GroupPublicityToggle.js b/src/components/views/groups/GroupPublicityToggle.js index 0fcabb4ef8..0dd35784a0 100644 --- a/src/components/views/groups/GroupPublicityToggle.js +++ b/src/components/views/groups/GroupPublicityToggle.js @@ -17,7 +17,6 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import sdk from '../../../index'; -import GroupStoreCache from '../../../stores/GroupStoreCache'; import GroupStore from '../../../stores/GroupStore'; import { _t } from '../../../languageHandler.js'; @@ -41,11 +40,10 @@ export default React.createClass({ }, _initGroupStore: function(groupId) { - this._groupStore = GroupStoreCache.getGroupStore(groupId); - this._groupStore.registerListener(() => { + GroupStore.registerListener(groupId, () => { this.setState({ - isGroupPublicised: this._groupStore.getGroupPublicity(), - ready: this._groupStore.isStateReady(GroupStore.STATE_KEY.Summary), + isGroupPublicised: GroupStore.getGroupPublicity(groupId), + ready: GroupStore.isStateReady(groupId, GroupStore.STATE_KEY.Summary), }); }); }, @@ -57,7 +55,7 @@ export default React.createClass({ // Optimistic early update isGroupPublicised: !this.state.isGroupPublicised, }); - this._groupStore.setGroupPublicity(!this.state.isGroupPublicised).then(() => { + GroupStore.setGroupPublicity(this.props.groupId, !this.state.isGroupPublicised).then(() => { this.setState({ busy: false, }); diff --git a/src/components/views/groups/GroupRoomInfo.js b/src/components/views/groups/GroupRoomInfo.js index 2d2b4e655c..41e5f68736 100644 --- a/src/components/views/groups/GroupRoomInfo.js +++ b/src/components/views/groups/GroupRoomInfo.js @@ -21,7 +21,7 @@ import dis from '../../../dispatcher'; import Modal from '../../../Modal'; import sdk from '../../../index'; import { _t } from '../../../languageHandler'; -import GroupStoreCache from '../../../stores/GroupStoreCache'; +import GroupStore from '../../../stores/GroupStore'; module.exports = React.createClass({ displayName: 'GroupRoomInfo', @@ -50,29 +50,26 @@ module.exports = React.createClass({ componentWillReceiveProps(newProps) { if (newProps.groupId !== this.props.groupId) { - this._unregisterGroupStore(); + this._unregisterGroupStore(this.props.groupId); this._initGroupStore(newProps.groupId); } }, componentWillUnmount() { - this._unregisterGroupStore(); + this._unregisterGroupStore(this.props.groupId); }, _initGroupStore(groupId) { - this._groupStore = GroupStoreCache.getGroupStore(this.props.groupId); - this._groupStore.registerListener(this.onGroupStoreUpdated); + GroupStore.registerListener(groupId, this.onGroupStoreUpdated); }, - _unregisterGroupStore() { - if (this._groupStore) { - this._groupStore.unregisterListener(this.onGroupStoreUpdated); - } + _unregisterGroupStore(groupId) { + GroupStore.unregisterListener(this.onGroupStoreUpdated); }, _updateGroupRoom() { this.setState({ - groupRoom: this._groupStore.getGroupRooms().find( + groupRoom: GroupStore.getGroupRooms(this.props.groupId).find( (r) => r.roomId === this.props.groupRoomId, ), }); @@ -80,7 +77,7 @@ module.exports = React.createClass({ onGroupStoreUpdated: function() { this.setState({ - isUserPrivilegedInGroup: this._groupStore.isUserPrivileged(), + isUserPrivilegedInGroup: GroupStore.isUserPrivileged(this.props.groupId), }); this._updateGroupRoom(); }, @@ -100,7 +97,7 @@ module.exports = React.createClass({ this.setState({groupRoomRemoveLoading: true}); const groupId = this.props.groupId; const roomId = this.props.groupRoomId; - this._groupStore.removeRoomFromGroup(roomId).then(() => { + GroupStore.removeRoomFromGroup(this.props.groupId, roomId).then(() => { dis.dispatch({ action: "view_group_room_list", }); @@ -134,7 +131,7 @@ module.exports = React.createClass({ const groupId = this.props.groupId; const roomId = this.props.groupRoomId; const roomName = this.state.groupRoom.displayname; - this._groupStore.updateGroupRoomVisibility(roomId, isPublic).catch((err) => { + GroupStore.updateGroupRoomVisibility(this.props.groupId, roomId, isPublic).catch((err) => { console.error(`Error whilst changing visibility of ${roomId} in ${groupId} to ${isPublic}`, err); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); Modal.createTrackedDialog('Failed to remove room from group', '', ErrorDialog, { diff --git a/src/components/views/groups/GroupRoomList.js b/src/components/views/groups/GroupRoomList.js index 0515865c6b..cfd2b806d4 100644 --- a/src/components/views/groups/GroupRoomList.js +++ b/src/components/views/groups/GroupRoomList.js @@ -16,7 +16,7 @@ limitations under the License. import React from 'react'; import { _t } from '../../../languageHandler'; import sdk from '../../../index'; -import GroupStoreCache from '../../../stores/GroupStoreCache'; +import GroupStore from '../../../stores/GroupStore'; import PropTypes from 'prop-types'; const INITIAL_LOAD_NUM_ROOMS = 30; @@ -39,22 +39,31 @@ export default React.createClass({ this._initGroupStore(this.props.groupId); }, + componentWillUnmount() { + this._unmounted = true; + this._unregisterGroupStore(); + }, + + _unregisterGroupStore() { + GroupStore.unregisterListener(this.onGroupStoreUpdated); + }, + _initGroupStore: function(groupId) { - this._groupStore = GroupStoreCache.getGroupStore(groupId); - this._groupStore.registerListener(() => { - this._fetchRooms(); - }); - this._groupStore.on('error', (err) => { + GroupStore.registerListener(groupId, this.onGroupStoreUpdated); + // XXX: This should be more fluxy - let's get the error from GroupStore .getError or something + // XXX: This is also leaked - we should remove it when unmounting + GroupStore.on('error', (err, errorGroupId) => { + if (errorGroupId !== groupId) return; this.setState({ rooms: null, }); }); }, - _fetchRooms: function() { + onGroupStoreUpdated: function() { if (this._unmounted) return; this.setState({ - rooms: this._groupStore.getGroupRooms(), + rooms: GroupStore.getGroupRooms(this.props.groupId), }); }, diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index acf04831e8..5be28ae6fa 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -30,7 +30,7 @@ import DMRoomMap from '../../../utils/DMRoomMap'; const Receipt = require('../../../utils/Receipt'); import TagOrderStore from '../../../stores/TagOrderStore'; import RoomListStore from '../../../stores/RoomListStore'; -import GroupStoreCache from '../../../stores/GroupStoreCache'; +import GroupStore from '../../../stores/GroupStore'; const HIDE_CONFERENCE_CHANS = true; const STANDARD_TAGS_REGEX = /^(m\.(favourite|lowpriority)|im\.vector\.fake\.(invite|recent|direct|archived))$/; @@ -83,8 +83,6 @@ module.exports = React.createClass({ cli.on("Group.myMembership", this._onGroupMyMembership); const dmRoomMap = DMRoomMap.shared(); - this._groupStores = {}; - this._groupStoreTokens = []; // A map between tags which are group IDs and the room IDs of rooms that should be kept // in the room list when filtering by that tag. this._visibleRoomsForGroup = { @@ -96,17 +94,14 @@ module.exports = React.createClass({ // When the selected tags are changed, initialise a group store if necessary this._tagStoreToken = TagOrderStore.addListener(() => { (TagOrderStore.getOrderedTags() || []).forEach((tag) => { - if (tag[0] !== '+' || this._groupStores[tag]) { + if (tag[0] !== '+') { return; } - this._groupStores[tag] = GroupStoreCache.getGroupStore(tag); - this._groupStoreTokens.push( - this._groupStores[tag].registerListener(() => { - // This group's rooms or members may have updated, update rooms for its tag - this.updateVisibleRoomsForTag(dmRoomMap, tag); - this.updateVisibleRooms(); - }), - ); + this.groupStoreToken = GroupStore.registerListener(tag, () => { + // This group's rooms or members may have updated, update rooms for its tag + this.updateVisibleRoomsForTag(dmRoomMap, tag); + this.updateVisibleRooms(); + }); }); // Filters themselves have changed, refresh the selected tags this.updateVisibleRooms(); @@ -183,10 +178,8 @@ module.exports = React.createClass({ this._roomListStoreToken.remove(); } - if (this._groupStoreTokens.length > 0) { - // NB: GroupStore is not a Flux.Store - this._groupStoreTokens.forEach((token) => token.unregister()); - } + // NB: GroupStore is not a Flux.Store + this._groupStoreToken.unregister(); // cancel any pending calls to the rate_limited_funcs this._delayedRefreshRoomList.cancelPendingCall(); @@ -259,12 +252,11 @@ module.exports = React.createClass({ updateVisibleRoomsForTag: function(dmRoomMap, tag) { if (!this.mounted) return; // For now, only handle group tags - const store = this._groupStores[tag]; - if (!store) return; + if (tag[0] !== '+') return; this._visibleRoomsForGroup[tag] = []; - store.getGroupRooms().forEach((room) => this._visibleRoomsForGroup[tag].push(room.roomId)); - store.getGroupMembers().forEach((member) => { + GroupStore.getGroupRooms(tag).forEach((room) => this._visibleRoomsForGroup[tag].push(room.roomId)); + GroupStore.getGroupMembers(tag).forEach((member) => { if (member.userId === MatrixClientPeg.get().credentials.userId) return; dmRoomMap.getDMRoomsForUserId(member.userId).forEach( (roomId) => this._visibleRoomsForGroup[tag].push(roomId), diff --git a/src/stores/GroupStore.js b/src/stores/GroupStore.js index d4f0b09ff9..23ce5314ec 100644 --- a/src/stores/GroupStore.js +++ b/src/stores/GroupStore.js @@ -70,84 +70,90 @@ function limitConcurrency(fn) { } /** - * Stores the group summary for a room and provides an API to change it and - * other useful group APIs that may have an effect on the group summary. + * Global store for tracking group summary, members, invited members and rooms. */ -export default class GroupStore extends EventEmitter { - - static STATE_KEY = { +class GroupStore extends EventEmitter { + STATE_KEY = { GroupMembers: 'GroupMembers', GroupInvitedMembers: 'GroupInvitedMembers', Summary: 'Summary', GroupRooms: 'GroupRooms', }; - constructor(groupId) { + constructor() { super(); - if (!groupId) { - throw new Error('GroupStore needs a valid groupId to be created'); - } - this.groupId = groupId; this._state = {}; - this._state[GroupStore.STATE_KEY.Summary] = {}; - this._state[GroupStore.STATE_KEY.GroupRooms] = []; - this._state[GroupStore.STATE_KEY.GroupMembers] = []; - this._state[GroupStore.STATE_KEY.GroupInvitedMembers] = []; - this._ready = {}; + this._state[this.STATE_KEY.Summary] = {}; + this._state[this.STATE_KEY.GroupRooms] = {}; + this._state[this.STATE_KEY.GroupMembers] = {}; + this._state[this.STATE_KEY.GroupInvitedMembers] = {}; + + this._ready = {}; + this._ready[this.STATE_KEY.Summary] = {}; + this._ready[this.STATE_KEY.GroupRooms] = {}; + this._ready[this.STATE_KEY.GroupMembers] = {}; + this._ready[this.STATE_KEY.GroupInvitedMembers] = {}; + + this._fetchResourcePromise = { + [this.STATE_KEY.Summary]: {}, + [this.STATE_KEY.GroupRooms]: {}, + [this.STATE_KEY.GroupMembers]: {}, + [this.STATE_KEY.GroupInvitedMembers]: {}, + }; - this._fetchResourcePromise = {}; this._resourceFetcher = { - [GroupStore.STATE_KEY.Summary]: () => { + [this.STATE_KEY.Summary]: (groupId) => { return limitConcurrency( - () => MatrixClientPeg.get().getGroupSummary(this.groupId), + () => MatrixClientPeg.get().getGroupSummary(groupId), ); }, - [GroupStore.STATE_KEY.GroupRooms]: () => { + [this.STATE_KEY.GroupRooms]: (groupId) => { return limitConcurrency( - () => MatrixClientPeg.get().getGroupRooms(this.groupId).then(parseRoomsResponse), + () => MatrixClientPeg.get().getGroupRooms(groupId).then(parseRoomsResponse), ); }, - [GroupStore.STATE_KEY.GroupMembers]: () => { + [this.STATE_KEY.GroupMembers]: (groupId) => { return limitConcurrency( - () => MatrixClientPeg.get().getGroupUsers(this.groupId).then(parseMembersResponse), + () => MatrixClientPeg.get().getGroupUsers(groupId).then(parseMembersResponse), ); }, - [GroupStore.STATE_KEY.GroupInvitedMembers]: () => { + [this.STATE_KEY.GroupInvitedMembers]: (groupId) => { return limitConcurrency( - () => MatrixClientPeg.get().getGroupInvitedUsers(this.groupId).then(parseMembersResponse), + () => MatrixClientPeg.get().getGroupInvitedUsers(groupId).then(parseMembersResponse), ); }, }; - this.on('error', (err) => { - console.error(`GroupStore for ${this.groupId} encountered error`, err); + this.on('error', (err, groupId) => { + console.error(`GroupStore encountered error whilst fetching data for ${groupId}`, err); }); } - _fetchResource(stateKey) { + _fetchResource(stateKey, groupId) { // Ongoing request, ignore - if (this._fetchResourcePromise[stateKey]) return; + if (this._fetchResourcePromise[stateKey][groupId]) return; - const clientPromise = this._resourceFetcher[stateKey](); + const clientPromise = this._resourceFetcher[stateKey](groupId); // Indicate ongoing request - this._fetchResourcePromise[stateKey] = clientPromise; + this._fetchResourcePromise[stateKey][groupId] = clientPromise; clientPromise.then((result) => { - this._state[stateKey] = result; - this._ready[stateKey] = true; + this._state[stateKey][groupId] = result; + console.info(this._state); + this._ready[stateKey][groupId] = true; this._notifyListeners(); }).catch((err) => { // Invited users not visible to non-members - if (stateKey === GroupStore.STATE_KEY.GroupInvitedMembers && err.httpStatus === 403) { + if (stateKey === this.STATE_KEY.GroupInvitedMembers && err.httpStatus === 403) { return; } - console.error("Failed to get resource " + stateKey + ":" + err); - this.emit('error', err); + console.error(`Failed to get resource ${stateKey} for ${groupId}`, err); + this.emit('error', err, groupId); }).finally(() => { // Indicate finished request, allow for future fetches - delete this._fetchResourcePromise[stateKey]; + delete this._fetchResourcePromise[stateKey][groupId]; }); return clientPromise; @@ -162,25 +168,26 @@ export default class GroupStore extends EventEmitter { * immediately triggers an update to send the current state of the * store (which could be the initial state). * - * This also causes a fetch of all group data, which might cause - * 4 separate HTTP requests, but only said requests aren't already - * ongoing. + * This also causes a fetch of all data of the specified group, + * which might cause 4 separate HTTP requests, but only if said + * requests aren't already ongoing. * + * @param {string} groupId the ID of the group to fetch data for. * @param {function} fn the function to call when the store updates. * @return {Object} tok a registration "token" with a single * property `unregister`, a function that can * be called to unregister the listener such * that it won't be called any more. */ - registerListener(fn) { + registerListener(groupId, fn) { this.on('update', fn); // Call to set initial state (before fetching starts) this.emit('update'); - this._fetchResource(GroupStore.STATE_KEY.Summary); - this._fetchResource(GroupStore.STATE_KEY.GroupRooms); - this._fetchResource(GroupStore.STATE_KEY.GroupMembers); - this._fetchResource(GroupStore.STATE_KEY.GroupInvitedMembers); + this._fetchResource(this.STATE_KEY.Summary, groupId); + this._fetchResource(this.STATE_KEY.GroupRooms, groupId); + this._fetchResource(this.STATE_KEY.GroupMembers, groupId); + this._fetchResource(this.STATE_KEY.GroupInvitedMembers, groupId); // Similar to the Store of flux/utils, we return a "token" that // can be used to unregister the listener. @@ -195,123 +202,129 @@ export default class GroupStore extends EventEmitter { this.removeListener('update', fn); } - isStateReady(id) { - return this._ready[id]; + isStateReady(groupId, id) { + return this._ready[id][groupId]; } - getSummary() { - return this._state[GroupStore.STATE_KEY.Summary]; + getSummary(groupId) { + return this._state[this.STATE_KEY.Summary][groupId] || {}; } - getGroupRooms() { - return this._state[GroupStore.STATE_KEY.GroupRooms]; + getGroupRooms(groupId) { + return this._state[this.STATE_KEY.GroupRooms][groupId] || []; } - getGroupMembers() { - return this._state[GroupStore.STATE_KEY.GroupMembers]; + getGroupMembers(groupId) { + return this._state[this.STATE_KEY.GroupMembers][groupId] || []; } - getGroupInvitedMembers() { - return this._state[GroupStore.STATE_KEY.GroupInvitedMembers]; + getGroupInvitedMembers(groupId) { + return this._state[this.STATE_KEY.GroupInvitedMembers][groupId] || []; } - getGroupPublicity() { - return this._state[GroupStore.STATE_KEY.Summary].user ? - this._state[GroupStore.STATE_KEY.Summary].user.is_publicised : null; + getGroupPublicity(groupId) { + return (this._state[this.STATE_KEY.Summary][groupId] || {}).user ? + (this._state[this.STATE_KEY.Summary][groupId] || {}).user.is_publicised : null; } - isUserPrivileged() { - return this._state[GroupStore.STATE_KEY.Summary].user ? - this._state[GroupStore.STATE_KEY.Summary].user.is_privileged : null; + isUserPrivileged(groupId) { + return (this._state[this.STATE_KEY.Summary][groupId] || {}).user ? + (this._state[this.STATE_KEY.Summary][groupId] || {}).user.is_privileged : null; } - addRoomToGroup(roomId, isPublic) { + addRoomToGroup(groupId, roomId, isPublic) { return MatrixClientPeg.get() - .addRoomToGroup(this.groupId, roomId, isPublic) - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupRooms)); + .addRoomToGroup(groupId, roomId, isPublic) + .then(this._fetchResource.bind(this, this.STATE_KEY.GroupRooms, groupId)); } - updateGroupRoomVisibility(roomId, isPublic) { + updateGroupRoomVisibility(groupId, roomId, isPublic) { return MatrixClientPeg.get() - .updateGroupRoomVisibility(this.groupId, roomId, isPublic) - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupRooms)); + .updateGroupRoomVisibility(groupId, roomId, isPublic) + .then(this._fetchResource.bind(this, this.STATE_KEY.GroupRooms, groupId)); } - removeRoomFromGroup(roomId) { + removeRoomFromGroup(groupId, roomId) { return MatrixClientPeg.get() - .removeRoomFromGroup(this.groupId, roomId) + .removeRoomFromGroup(groupId, roomId) // Room might be in the summary, refresh just in case - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary)) - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupRooms)); + .then(this._fetchResource.bind(this, this.STATE_KEY.Summary, groupId)) + .then(this._fetchResource.bind(this, this.STATE_KEY.GroupRooms, groupId)); } - inviteUserToGroup(userId) { - return MatrixClientPeg.get().inviteUserToGroup(this.groupId, userId) - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupInvitedMembers)); + inviteUserToGroup(groupId, userId) { + return MatrixClientPeg.get().inviteUserToGroup(groupId, userId) + .then(this._fetchResource.bind(this, this.STATE_KEY.GroupInvitedMembers, groupId)); } - acceptGroupInvite() { - return MatrixClientPeg.get().acceptGroupInvite(this.groupId) + acceptGroupInvite(groupId) { + return MatrixClientPeg.get().acceptGroupInvite(groupId) // The user should now be able to access (personal) group settings - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary)) + .then(this._fetchResource.bind(this, this.STATE_KEY.Summary, groupId)) // The user might be able to see more rooms now - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupRooms)) + .then(this._fetchResource.bind(this, this.STATE_KEY.GroupRooms, groupId)) // The user should now appear as a member - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupMembers)) + .then(this._fetchResource.bind(this, this.STATE_KEY.GroupMembers, groupId)) // The user should now not appear as an invited member - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupInvitedMembers)); + .then(this._fetchResource.bind(this, this.STATE_KEY.GroupInvitedMembers, groupId)); } - joinGroup() { - return MatrixClientPeg.get().joinGroup(this.groupId) + joinGroup(groupId) { + return MatrixClientPeg.get().joinGroup(groupId) // The user should now be able to access (personal) group settings - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary)) + .then(this._fetchResource.bind(this, this.STATE_KEY.Summary, groupId)) // The user might be able to see more rooms now - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupRooms)) + .then(this._fetchResource.bind(this, this.STATE_KEY.GroupRooms, groupId)) // The user should now appear as a member - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupMembers)) + .then(this._fetchResource.bind(this, this.STATE_KEY.GroupMembers, groupId)) // The user should now not appear as an invited member - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupInvitedMembers)); + .then(this._fetchResource.bind(this, this.STATE_KEY.GroupInvitedMembers, groupId)); } - leaveGroup() { - return MatrixClientPeg.get().leaveGroup(this.groupId) + leaveGroup(groupId) { + return MatrixClientPeg.get().leaveGroup(groupId) // The user should now not be able to access group settings - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary)) + .then(this._fetchResource.bind(this, this.STATE_KEY.Summary, groupId)) // The user might only be able to see a subset of rooms now - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupRooms)) + .then(this._fetchResource.bind(this, this.STATE_KEY.GroupRooms, groupId)) // The user should now not appear as a member - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupMembers)); + .then(this._fetchResource.bind(this, this.STATE_KEY.GroupMembers, groupId)); } - addRoomToGroupSummary(roomId, categoryId) { + addRoomToGroupSummary(groupId, roomId, categoryId) { return MatrixClientPeg.get() - .addRoomToGroupSummary(this.groupId, roomId, categoryId) - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary)); + .addRoomToGroupSummary(groupId, roomId, categoryId) + .then(this._fetchResource.bind(this, this.STATE_KEY.Summary, groupId)); } - addUserToGroupSummary(userId, roleId) { + addUserToGroupSummary(groupId, userId, roleId) { return MatrixClientPeg.get() - .addUserToGroupSummary(this.groupId, userId, roleId) - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary)); + .addUserToGroupSummary(groupId, userId, roleId) + .then(this._fetchResource.bind(this, this.STATE_KEY.Summary, groupId)); } - removeRoomFromGroupSummary(roomId) { + removeRoomFromGroupSummary(groupId, roomId) { return MatrixClientPeg.get() - .removeRoomFromGroupSummary(this.groupId, roomId) - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary)); + .removeRoomFromGroupSummary(groupId, roomId) + .then(this._fetchResource.bind(this, this.STATE_KEY.Summary, groupId)); } - removeUserFromGroupSummary(userId) { + removeUserFromGroupSummary(groupId, userId) { return MatrixClientPeg.get() - .removeUserFromGroupSummary(this.groupId, userId) - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary)); + .removeUserFromGroupSummary(groupId, userId) + .then(this._fetchResource.bind(this, this.STATE_KEY.Summary, groupId)); } - setGroupPublicity(isPublished) { + setGroupPublicity(groupId, isPublished) { return MatrixClientPeg.get() - .setGroupPublicity(this.groupId, isPublished) + .setGroupPublicity(groupId, isPublished) .then(() => { FlairStore.invalidatePublicisedGroups(MatrixClientPeg.get().credentials.userId); }) - .then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary)); + .then(this._fetchResource.bind(this, this.STATE_KEY.Summary, groupId)); } } + +let singletonGroupStore = null; +if (!singletonGroupStore) { + singletonGroupStore = new GroupStore(); +} +module.exports = singletonGroupStore; diff --git a/src/stores/GroupStoreCache.js b/src/stores/GroupStoreCache.js deleted file mode 100644 index 8b4286831b..0000000000 --- a/src/stores/GroupStoreCache.js +++ /dev/null @@ -1,38 +0,0 @@ -/* -Copyright 2017 New Vector Ltd - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import GroupStore from './GroupStore'; - -class GroupStoreCache { - constructor() { - this.groupStore = null; - } - - getGroupStore(groupId) { - if (!this.groupStore || this.groupStore.groupId !== groupId) { - // This effectively throws away the reference to any previous GroupStore, - // allowing it to be GCd once the components referencing it have stopped - // referencing it. - this.groupStore = new GroupStore(groupId); - } - return this.groupStore; - } -} - -if (global.singletonGroupStoreCache === undefined) { - global.singletonGroupStoreCache = new GroupStoreCache(); -} -export default global.singletonGroupStoreCache; diff --git a/src/utils/MultiInviter.js b/src/utils/MultiInviter.js index a0f33f5c39..b3e7fc495a 100644 --- a/src/utils/MultiInviter.js +++ b/src/utils/MultiInviter.js @@ -18,7 +18,7 @@ limitations under the License. import MatrixClientPeg from '../MatrixClientPeg'; import {getAddressType} from '../UserAddress'; import {inviteToRoom} from '../RoomInvite'; -import GroupStoreCache from '../stores/GroupStoreCache'; +import GroupStore from '../stores/GroupStore'; import Promise from 'bluebird'; /** @@ -118,9 +118,7 @@ export default class MultiInviter { let doInvite; if (this.groupId !== null) { - doInvite = GroupStoreCache - .getGroupStore(this.groupId) - .inviteUserToGroup(addr); + doInvite = GroupStore.inviteUserToGroup(this.groupId, addr); } else { doInvite = inviteToRoom(this.roomId, addr); } From 28e8ce967fe9d403c9697755f293f1e99ca8698c Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 1 May 2018 11:38:57 +0100 Subject: [PATCH 0976/1160] Correctly unregister group store listener when unmounting RoomList --- src/components/views/rooms/RoomList.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 5be28ae6fa..b70c4a994e 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -97,7 +97,7 @@ module.exports = React.createClass({ if (tag[0] !== '+') { return; } - this.groupStoreToken = GroupStore.registerListener(tag, () => { + this._groupStoreToken = GroupStore.registerListener(tag, () => { // This group's rooms or members may have updated, update rooms for its tag this.updateVisibleRoomsForTag(dmRoomMap, tag); this.updateVisibleRooms(); @@ -179,7 +179,9 @@ module.exports = React.createClass({ } // NB: GroupStore is not a Flux.Store - this._groupStoreToken.unregister(); + if (this._groupStoreToken) { + this._groupStoreToken.unregister(); + } // cancel any pending calls to the rate_limited_funcs this._delayedRefreshRoomList.cancelPendingCall(); From 38d7a5d39405816ed8cbcee3be67f5286b0fce48 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 1 May 2018 11:50:14 +0100 Subject: [PATCH 0977/1160] Remove GroupStore listener when unmounting GroupPublicityToggle --- src/components/views/groups/GroupPublicityToggle.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/views/groups/GroupPublicityToggle.js b/src/components/views/groups/GroupPublicityToggle.js index 0dd35784a0..78522c2f55 100644 --- a/src/components/views/groups/GroupPublicityToggle.js +++ b/src/components/views/groups/GroupPublicityToggle.js @@ -40,7 +40,7 @@ export default React.createClass({ }, _initGroupStore: function(groupId) { - GroupStore.registerListener(groupId, () => { + this._groupStoreToken = GroupStore.registerListener(groupId, () => { this.setState({ isGroupPublicised: GroupStore.getGroupPublicity(groupId), ready: GroupStore.isStateReady(groupId, GroupStore.STATE_KEY.Summary), @@ -48,6 +48,10 @@ export default React.createClass({ }); }, + componentWillUnmount() { + if (this._groupStoreToken) this._groupStoreToken.unregister(); + }, + _onPublicityToggle: function(e) { e.stopPropagation(); this.setState({ From 25690336c3abd18eead0feac37055f480129d4eb Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 1 May 2018 11:52:02 +0100 Subject: [PATCH 0978/1160] Prevent user getting trapped in group settings when an error occurs --- src/components/structures/GroupView.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index 534d8d3df8..ce79ccadfa 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -483,6 +483,7 @@ export default React.createClass({ this.setState({ summary: null, error: err, + editing: false, }); }); }, From e3a07be12790ddade32caa990a7fb40fb95a211f Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 1 May 2018 13:14:01 +0100 Subject: [PATCH 0979/1160] Remove GroupStore logging --- src/stores/GroupStore.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/stores/GroupStore.js b/src/stores/GroupStore.js index 23ce5314ec..49596550ea 100644 --- a/src/stores/GroupStore.js +++ b/src/stores/GroupStore.js @@ -140,7 +140,6 @@ class GroupStore extends EventEmitter { clientPromise.then((result) => { this._state[stateKey][groupId] = result; - console.info(this._state); this._ready[stateKey][groupId] = true; this._notifyListeners(); }).catch((err) => { From f0bd4a54e73ebd2c4a2cdf347263c2431be76c00 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 1 May 2018 13:26:24 +0100 Subject: [PATCH 0980/1160] Refactor tests to understand sendMessage instead of send{Text,Html}Message Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- .../views/rooms/MessageComposerInput-test.js | 82 +++++++++---------- test/test-utils.js | 3 +- 2 files changed, 41 insertions(+), 44 deletions(-) diff --git a/test/components/views/rooms/MessageComposerInput-test.js b/test/components/views/rooms/MessageComposerInput-test.js index 1f0ede6ae2..eadd923726 100644 --- a/test/components/views/rooms/MessageComposerInput-test.js +++ b/test/components/views/rooms/MessageComposerInput-test.js @@ -75,39 +75,37 @@ describe('MessageComposerInput', () => { }); it('should not send messages when composer is empty', () => { - const textSpy = sinon.spy(client, 'sendTextMessage'); - const htmlSpy = sinon.spy(client, 'sendHtmlMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(true); mci.handleReturn(sinon.stub()); - expect(textSpy.calledOnce).toEqual(false, 'should not send text message'); - expect(htmlSpy.calledOnce).toEqual(false, 'should not send html message'); + expect(spy.calledOnce).toEqual(false, 'should not send message'); }); it('should not change content unnecessarily on RTE -> Markdown conversion', () => { - const spy = sinon.spy(client, 'sendTextMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(true); addTextToDraft('a'); mci.handleKeyCommand('toggle-mode'); mci.handleReturn(sinon.stub()); expect(spy.calledOnce).toEqual(true); - expect(spy.args[0][1]).toEqual('a'); + expect(spy.args[0][1].body).toEqual('a'); }); it('should not change content unnecessarily on Markdown -> RTE conversion', () => { - const spy = sinon.spy(client, 'sendTextMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(false); addTextToDraft('a'); mci.handleKeyCommand('toggle-mode'); mci.handleReturn(sinon.stub()); expect(spy.calledOnce).toEqual(true); - expect(spy.args[0][1]).toEqual('a'); + expect(spy.args[0][1].body).toEqual('a'); }); it('should send emoji messages when rich text is enabled', () => { - const spy = sinon.spy(client, 'sendTextMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(true); addTextToDraft('☹'); mci.handleReturn(sinon.stub()); @@ -116,7 +114,7 @@ describe('MessageComposerInput', () => { }); it('should send emoji messages when Markdown is enabled', () => { - const spy = sinon.spy(client, 'sendTextMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(false); addTextToDraft('☹'); mci.handleReturn(sinon.stub()); @@ -149,98 +147,98 @@ describe('MessageComposerInput', () => { // }); it('should insert formatting characters in Markdown mode', () => { - const spy = sinon.spy(client, 'sendTextMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(false); mci.handleKeyCommand('italic'); mci.handleReturn(sinon.stub()); - expect(['__', '**']).toContain(spy.args[0][1]); + expect(['__', '**']).toContain(spy.args[0][1].body); }); it('should not entity-encode " in Markdown mode', () => { - const spy = sinon.spy(client, 'sendTextMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(false); addTextToDraft('"'); mci.handleReturn(sinon.stub()); expect(spy.calledOnce).toEqual(true); - expect(spy.args[0][1]).toEqual('"'); + expect(spy.args[0][1].body).toEqual('"'); }); it('should escape characters without other markup in Markdown mode', () => { - const spy = sinon.spy(client, 'sendTextMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(false); addTextToDraft('\\*escaped\\*'); mci.handleReturn(sinon.stub()); expect(spy.calledOnce).toEqual(true); - expect(spy.args[0][1]).toEqual('*escaped*'); + expect(spy.args[0][1].body).toEqual('*escaped*'); }); it('should escape characters with other markup in Markdown mode', () => { - const spy = sinon.spy(client, 'sendHtmlMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(false); addTextToDraft('\\*escaped\\* *italic*'); mci.handleReturn(sinon.stub()); expect(spy.calledOnce).toEqual(true); - expect(spy.args[0][1]).toEqual('\\*escaped\\* *italic*'); - expect(spy.args[0][2]).toEqual('*escaped* italic'); + expect(spy.args[0][1].body).toEqual('\\*escaped\\* *italic*'); + expect(spy.args[0][1].formatted_body).toEqual('*escaped* italic'); }); it('should not convert -_- into a horizontal rule in Markdown mode', () => { - const spy = sinon.spy(client, 'sendTextMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(false); addTextToDraft('-_-'); mci.handleReturn(sinon.stub()); expect(spy.calledOnce).toEqual(true); - expect(spy.args[0][1]).toEqual('-_-'); + expect(spy.args[0][1].body).toEqual('-_-'); }); it('should not strip tags in Markdown mode', () => { - const spy = sinon.spy(client, 'sendHtmlMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(false); addTextToDraft('striked-out'); mci.handleReturn(sinon.stub()); expect(spy.calledOnce).toEqual(true); - expect(spy.args[0][1]).toEqual('striked-out'); - expect(spy.args[0][2]).toEqual('striked-out'); + expect(spy.args[0][1].body).toEqual('striked-out'); + expect(spy.args[0][1].formatted_body).toEqual('striked-out'); }); it('should not strike-through ~~~ in Markdown mode', () => { - const spy = sinon.spy(client, 'sendTextMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(false); addTextToDraft('~~~striked-out~~~'); mci.handleReturn(sinon.stub()); expect(spy.calledOnce).toEqual(true); - expect(spy.args[0][1]).toEqual('~~~striked-out~~~'); + expect(spy.args[0][1].body).toEqual('~~~striked-out~~~'); }); it('should not mark single unmarkedup paragraphs as HTML in Markdown mode', () => { - const spy = sinon.spy(client, 'sendTextMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(false); addTextToDraft('Lorem ipsum dolor sit amet, consectetur adipiscing elit.'); mci.handleReturn(sinon.stub()); expect(spy.calledOnce).toEqual(true); - expect(spy.args[0][1]).toEqual('Lorem ipsum dolor sit amet, consectetur adipiscing elit.'); + expect(spy.args[0][1].body).toEqual('Lorem ipsum dolor sit amet, consectetur adipiscing elit.'); }); it('should not mark two unmarkedup paragraphs as HTML in Markdown mode', () => { - const spy = sinon.spy(client, 'sendTextMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(false); addTextToDraft('Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nFusce congue sapien sed neque molestie volutpat.'); mci.handleReturn(sinon.stub()); expect(spy.calledOnce).toEqual(true); - expect(spy.args[0][1]).toEqual('Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nFusce congue sapien sed neque molestie volutpat.'); + expect(spy.args[0][1].body).toEqual('Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nFusce congue sapien sed neque molestie volutpat.'); }); it('should strip tab-completed mentions so that only the display name is sent in the plain body in Markdown mode', () => { // Sending a HTML message because we have entities in the composer (because of completions) - const spy = sinon.spy(client, 'sendHtmlMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(false); mci.setDisplayedCompletion({ completion: 'Some Member', @@ -250,11 +248,11 @@ describe('MessageComposerInput', () => { mci.handleReturn(sinon.stub()); - expect(spy.args[0][1]).toEqual( + expect(spy.args[0][1].body).toEqual( 'Some Member', 'the plaintext body should only include the display name', ); - expect(spy.args[0][2]).toEqual( + expect(spy.args[0][1].formatted_body).toEqual( 'Some Member', 'the html body should contain an anchor tag with a matrix.to href and display name text', ); @@ -262,7 +260,7 @@ describe('MessageComposerInput', () => { it('should strip tab-completed mentions so that only the display name is sent in the plain body in RTE mode', () => { // Sending a HTML message because we have entities in the composer (because of completions) - const spy = sinon.spy(client, 'sendHtmlMessage'); + const spy = sinon.spy(client, 'sendMessage'); mci.enableRichtext(true); mci.setDisplayedCompletion({ completion: 'Some Member', @@ -272,33 +270,33 @@ describe('MessageComposerInput', () => { mci.handleReturn(sinon.stub()); - expect(spy.args[0][1]).toEqual('Some Member'); - expect(spy.args[0][2]).toEqual('Some Member'); + expect(spy.args[0][1].body).toEqual('Some Member'); + expect(spy.args[0][1].formatted_body).toEqual('Some Member'); }); it('should not strip non-tab-completed mentions when manually typing MD', () => { // Sending a HTML message because we have entities in the composer (because of completions) - const spy = sinon.spy(client, 'sendHtmlMessage'); + const spy = sinon.spy(client, 'sendMessage'); // Markdown mode enabled mci.enableRichtext(false); addTextToDraft('[My Not-Tab-Completed Mention](https://matrix.to/#/@some_member:domain.bla)'); mci.handleReturn(sinon.stub()); - expect(spy.args[0][1]).toEqual('[My Not-Tab-Completed Mention](https://matrix.to/#/@some_member:domain.bla)'); - expect(spy.args[0][2]).toEqual('My Not-Tab-Completed Mention'); + expect(spy.args[0][1].body).toEqual('[My Not-Tab-Completed Mention](https://matrix.to/#/@some_member:domain.bla)'); + expect(spy.args[0][1].formatted_body).toEqual('My Not-Tab-Completed Mention'); }); it('should not strip arbitrary typed (i.e. not tab-completed) MD links', () => { // Sending a HTML message because we have entities in the composer (because of completions) - const spy = sinon.spy(client, 'sendHtmlMessage'); + const spy = sinon.spy(client, 'sendMessage'); // Markdown mode enabled mci.enableRichtext(false); addTextToDraft('[Click here](https://some.lovely.url)'); mci.handleReturn(sinon.stub()); - expect(spy.args[0][1]).toEqual('[Click here](https://some.lovely.url)'); - expect(spy.args[0][2]).toEqual('Click here'); + expect(spy.args[0][1].body).toEqual('[Click here](https://some.lovely.url)'); + expect(spy.args[0][1].formatted_body).toEqual('Click here'); }); }); diff --git a/test/test-utils.js b/test/test-utils.js index b593761bd4..3acd8bb861 100644 --- a/test/test-utils.js +++ b/test/test-utils.js @@ -94,8 +94,7 @@ export function createTestClient() { }, setAccountData: sinon.stub(), sendTyping: sinon.stub().returns(Promise.resolve({})), - sendTextMessage: () => Promise.resolve({}), - sendHtmlMessage: () => Promise.resolve({}), + sendMessage: () => Promise.resolve({}), getSyncState: () => "SYNCING", generateClientSecret: () => "t35tcl1Ent5ECr3T", isGuest: () => false, From da1a5616eb03dddb7cb31d4c7e33f1b8dd552d62 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 1 May 2018 14:04:13 +0100 Subject: [PATCH 0981/1160] Prevent error responses wedging group request concurrency limit Fixes https://github.com/vector-im/riot-web/issues/6592 --- src/stores/GroupStore.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/stores/GroupStore.js b/src/stores/GroupStore.js index 23ce5314ec..f4a66f432f 100644 --- a/src/stores/GroupStore.js +++ b/src/stores/GroupStore.js @@ -62,6 +62,11 @@ function limitConcurrency(fn) { } }) .then(fn) + .catch((err) => { + ongoingRequestCount--; + checkBacklog(); + throw err; + }) .then((result) => { ongoingRequestCount--; checkBacklog(); From 4d8394954c2db411608608dd9cf3fac57034b788 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 1 May 2018 14:24:58 +0100 Subject: [PATCH 0982/1160] Only create one group store listener in RoomList Instead of creating several and destroying the reference to the one created before. --- src/components/views/rooms/RoomList.js | 19 +++++++++++-------- src/stores/GroupStore.js | 10 ++++++---- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index b70c4a994e..fc1872249f 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -91,19 +91,22 @@ module.exports = React.createClass({ // All rooms that should be kept in the room list when filtering. // By default, show all rooms. this._visibleRooms = MatrixClientPeg.get().getRooms(); - // When the selected tags are changed, initialise a group store if necessary - this._tagStoreToken = TagOrderStore.addListener(() => { + + // Listen to updates to group data. RoomList cares about members and rooms in order + // to filter the room list when group tags are selected. + this._groupStoreToken = GroupStore.registerListener(null, () => { (TagOrderStore.getOrderedTags() || []).forEach((tag) => { if (tag[0] !== '+') { return; } - this._groupStoreToken = GroupStore.registerListener(tag, () => { - // This group's rooms or members may have updated, update rooms for its tag - this.updateVisibleRoomsForTag(dmRoomMap, tag); - this.updateVisibleRooms(); - }); + // This group's rooms or members may have updated, update rooms for its tag + this.updateVisibleRoomsForTag(dmRoomMap, tag); + this.updateVisibleRooms(); }); - // Filters themselves have changed, refresh the selected tags + }); + + this._tagStoreToken = TagOrderStore.addListener(() => { + // Filters themselves have changed this.updateVisibleRooms(); }); diff --git a/src/stores/GroupStore.js b/src/stores/GroupStore.js index 49596550ea..b0c7f8f19f 100644 --- a/src/stores/GroupStore.js +++ b/src/stores/GroupStore.js @@ -183,10 +183,12 @@ class GroupStore extends EventEmitter { // Call to set initial state (before fetching starts) this.emit('update'); - this._fetchResource(this.STATE_KEY.Summary, groupId); - this._fetchResource(this.STATE_KEY.GroupRooms, groupId); - this._fetchResource(this.STATE_KEY.GroupMembers, groupId); - this._fetchResource(this.STATE_KEY.GroupInvitedMembers, groupId); + if (groupId) { + this._fetchResource(this.STATE_KEY.Summary, groupId); + this._fetchResource(this.STATE_KEY.GroupRooms, groupId); + this._fetchResource(this.STATE_KEY.GroupMembers, groupId); + this._fetchResource(this.STATE_KEY.GroupInvitedMembers, groupId); + } // Similar to the Store of flux/utils, we return a "token" that // can be used to unregister the listener. From 56ec7713bb81804a9cda6ae97aa19915ea2e4971 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 1 May 2018 16:54:14 +0100 Subject: [PATCH 0983/1160] Refresh group rooms and members when selecting a tag --- src/components/views/elements/TagTile.js | 12 ++++++++++++ src/stores/GroupStore.js | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/src/components/views/elements/TagTile.js b/src/components/views/elements/TagTile.js index 4ea1b65123..c5fdea0a54 100644 --- a/src/components/views/elements/TagTile.js +++ b/src/components/views/elements/TagTile.js @@ -24,6 +24,7 @@ import { isOnlyCtrlOrCmdIgnoreShiftKeyEvent } from '../../../Keyboard'; import ContextualMenu from '../../structures/ContextualMenu'; import FlairStore from '../../../stores/FlairStore'; +import GroupStore from '../../../stores/GroupStore'; // A class for a child of TagPanel (possibly wrapped in a DNDTagTile) that represents // a thing to click on for the user to filter the visible rooms in the RoomList to: @@ -57,6 +58,8 @@ export default React.createClass({ if (this.props.tag[0] === '+') { FlairStore.addListener('updateGroupProfile', this._onFlairStoreUpdated); this._onFlairStoreUpdated(); + // New rooms or members may have been added to the group, fetch async + this._refreshGroup(this.props.tag); } }, @@ -80,6 +83,11 @@ export default React.createClass({ }); }, + _refreshGroup(groupId) { + GroupStore.refreshGroupRooms(groupId); + GroupStore.refreshGroupMembers(groupId); + }, + onClick: function(e) { e.preventDefault(); e.stopPropagation(); @@ -89,6 +97,10 @@ export default React.createClass({ ctrlOrCmdKey: isOnlyCtrlOrCmdIgnoreShiftKeyEvent(e), shiftKey: e.shiftKey, }); + if (this.props.tag[0] === '+') { + // New rooms or members may have been added to the group, fetch async + this._refreshGroup(this.props.tag); + } }, onContextButtonClick: function(e) { diff --git a/src/stores/GroupStore.js b/src/stores/GroupStore.js index b0c7f8f19f..e750dc1a6b 100644 --- a/src/stores/GroupStore.js +++ b/src/stores/GroupStore.js @@ -233,6 +233,14 @@ class GroupStore extends EventEmitter { (this._state[this.STATE_KEY.Summary][groupId] || {}).user.is_privileged : null; } + refreshGroupRooms(groupId) { + return this._fetchResource(this.STATE_KEY.GroupRooms, groupId); + } + + refreshGroupMembers(groupId) { + return this._fetchResource(this.STATE_KEY.GroupMembers, groupId); + } + addRoomToGroup(groupId, roomId, isPublic) { return MatrixClientPeg.get() .addRoomToGroup(groupId, roomId, isPublic) From bd703b17e58041d6e1cdb886af2939d0e30112b3 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 1 May 2018 16:57:28 +0100 Subject: [PATCH 0984/1160] Update documentation for GroupStore.registerListener --- src/stores/GroupStore.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/stores/GroupStore.js b/src/stores/GroupStore.js index e750dc1a6b..03132cd80f 100644 --- a/src/stores/GroupStore.js +++ b/src/stores/GroupStore.js @@ -167,11 +167,12 @@ class GroupStore extends EventEmitter { * immediately triggers an update to send the current state of the * store (which could be the initial state). * - * This also causes a fetch of all data of the specified group, - * which might cause 4 separate HTTP requests, but only if said - * requests aren't already ongoing. + * If a group ID is specified, this also causes a fetch of all data + * of the specified group, which might cause 4 separate HTTP + * requests, but only if said requests aren't already ongoing. * - * @param {string} groupId the ID of the group to fetch data for. + * @param {string?} groupId the ID of the group to fetch data for. + * Optional. * @param {function} fn the function to call when the store updates. * @return {Object} tok a registration "token" with a single * property `unregister`, a function that can From 11ae0805b07874bb08f6411e304694d92769afe5 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 1 May 2018 17:42:58 +0100 Subject: [PATCH 0985/1160] re-order ReplyThread methods for readability Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 74 ++++++++++---------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 40db914941..138431259f 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -59,43 +59,6 @@ export default class ReplyThread extends React.Component { this.collapse = this.collapse.bind(this); } - async initialize() { - const {parentEv} = this.props; - // at time of making this component we checked that props.parentEv has a parentEventId - const ev = await ReplyThread.getEvent(this.room, ReplyThread.getParentEventId(parentEv)); - if (this.unmounted) return; - - if (ev) { - this.setState({ - events: [ev], - }, this.loadNextEvent); - } else { - this.setState({err: true}); - } - } - - async loadNextEvent() { - if (this.unmounted) return; - const ev = this.state.events[0]; - const inReplyToEventId = ReplyThread.getParentEventId(ev); - - if (!inReplyToEventId) { - this.setState({ - loading: false, - }); - return; - } - - const loadedEv = await ReplyThread.getEvent(this.room, inReplyToEventId); - if (this.unmounted) return; - - if (loadedEv) { - this.setState({loadedEv}); - } else { - this.setState({err: true}); - } - } - static async getEvent(room, eventId) { const event = room.findEventById(eventId); if (event) return event; @@ -233,6 +196,43 @@ export default class ReplyThread extends React.Component { this.unmounted = true; } + async initialize() { + const {parentEv} = this.props; + // at time of making this component we checked that props.parentEv has a parentEventId + const ev = await ReplyThread.getEvent(this.room, ReplyThread.getParentEventId(parentEv)); + if (this.unmounted) return; + + if (ev) { + this.setState({ + events: [ev], + }, this.loadNextEvent); + } else { + this.setState({err: true}); + } + } + + async loadNextEvent() { + if (this.unmounted) return; + const ev = this.state.events[0]; + const inReplyToEventId = ReplyThread.getParentEventId(ev); + + if (!inReplyToEventId) { + this.setState({ + loading: false, + }); + return; + } + + const loadedEv = await ReplyThread.getEvent(this.room, inReplyToEventId); + if (this.unmounted) return; + + if (loadedEv) { + this.setState({loadedEv}); + } else { + this.setState({err: true}); + } + } + canCollapse() { return this.state.events.length > 1; } From 71c1198d12b5028147f69e6117f592e28afbaf36 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 1 May 2018 18:01:25 +0100 Subject: [PATCH 0986/1160] Rewrite limitConcurrency to fix error catching Make sure that we only catch errors that are a result of calling fn() --- src/stores/GroupStore.js | 44 ++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/stores/GroupStore.js b/src/stores/GroupStore.js index f4a66f432f..0e2e8e6b86 100644 --- a/src/stores/GroupStore.js +++ b/src/stores/GroupStore.js @@ -48,30 +48,30 @@ function checkBacklog() { // Limit the maximum number of ongoing promises returned by fn to LIMIT and // use a FIFO queue to handle the backlog. -function limitConcurrency(fn) { - return new Promise((resolve, reject) => { - const item = () => { - ongoingRequestCount++; - resolve(); - }; - if (ongoingRequestCount >= LIMIT) { - // Enqueue this request for later execution - backlogQueue.push(item); - } else { - item(); - } - }) - .then(fn) - .catch((err) => { +async function limitConcurrency(fn) { + if (ongoingRequestCount >= LIMIT) { + // Enqueue this request for later execution + await new Promise((resolve, reject) => { + backlogQueue.push(resolve); + }); + } + + let result; + let error; + + ongoingRequestCount++; + try { + result = await fn(); + } catch (err) { + error = err; + } finally { ongoingRequestCount--; checkBacklog(); - throw err; - }) - .then((result) => { - ongoingRequestCount--; - checkBacklog(); - return result; - }); + } + + if (error) throw error; + + return result; } /** From db55f87699bfa4dd52118e4dfc2525d446d2d3b6 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 1 May 2018 18:14:35 +0100 Subject: [PATCH 0987/1160] avoid `.done` and `.then` anti-pattern Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/RoomView.js | 6 ++---- src/components/views/rooms/MessageComposerInput.js | 6 ++++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index b4735ce0a3..cb6250c2d3 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -914,14 +914,12 @@ module.exports = React.createClass({ return; } - ContentMessages.sendContentToRoom( - file, this.state.room.roomId, MatrixClientPeg.get(), - ).done(() => { + ContentMessages.sendContentToRoom(file, this.state.room.roomId, MatrixClientPeg.get()).then(() => { // Send message_sent callback, for things like _checkIfAlone because after all a file is still a message. dis.dispatch({ action: 'message_sent', }); - }, (error) => { + }).catch((error) => { if (error.name === "UnknownDeviceError") { // Let the status bar handle this return; diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index f7c4215d88..97e8780f0f 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -877,11 +877,13 @@ export default class MessageComposerInput extends React.Component { } - this.client.sendMessage(this.props.room.roomId, content).done((res) => { + this.client.sendMessage(this.props.room.roomId, content).then((res) => { dis.dispatch({ action: 'message_sent', }); - }, (e) => onSendMessageFailed(e, this.props.room)); + }).catch((e) => { + onSendMessageFailed(e, this.props.room); + }); this.setState({ editorState: this.createEditorState(), From ec4ec4717df240fe68df270368332e328a5c6e4f Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 1 May 2018 18:15:12 +0100 Subject: [PATCH 0988/1160] clean up EventTile:onWidgetLoad optional/required mess Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/EventTile.js | 5 +++++ src/components/views/rooms/ReplyPreview.js | 3 --- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 56ac082f2a..c2e51d878b 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -154,6 +154,11 @@ module.exports = withMatrixClient(React.createClass({ isTwelveHour: PropTypes.bool, }, + defaultProps: { + // no-op function because onWidgetLoad is optional yet some subcomponents assume its existence + onWidgetLoad: function() {}, + }, + getInitialState: function() { return { // Whether the context menu is being displayed. diff --git a/src/components/views/rooms/ReplyPreview.js b/src/components/views/rooms/ReplyPreview.js index dd11b0df33..46e2826634 100644 --- a/src/components/views/rooms/ReplyPreview.js +++ b/src/components/views/rooms/ReplyPreview.js @@ -75,11 +75,8 @@ export default class ReplyPreview extends React.Component {
    ; } } - -function dummyOnWidgetLoad() {} From 8326d057ec2a67913bf4ad1bb99489c6cf6b223b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D1=80=D0=BA=D0=BE=20=D0=9C=2E=20=D0=9A=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D0=B8=D1=9B?= Date: Wed, 2 May 2018 06:46:59 +0000 Subject: [PATCH 0989/1160] Translated using Weblate (Serbian) Currently translated at 100.0% (1169 of 1169 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sr/ --- src/i18n/strings/sr.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index 0f65adf355..27c77e3552 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -1163,5 +1163,13 @@ "Everyone": "Свако", "Debug Logs Submission": "Слање извештаја за поправљање грешака", "Opens the Developer Tools dialog": "Отвори прозор програмерских алатки", - "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Ако сте пријавили грешку преко Гитхаба, извештаји за поправљање грешака нам могу помоћи да лакше нађемо узрок. Извештаји садрже податке о коришћењу апликације и међу њих спада ваше корисничко име, ИБ-јеви или алијаси посећених соба или група и корисничка имена других корисника. Не садрже саме поруке." + "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Ако сте пријавили грешку преко Гитхаба, извештаји за поправљање грешака нам могу помоћи да лакше нађемо узрок. Извештаји садрже податке о коришћењу апликације и међу њих спада ваше корисничко име, ИБ-јеви или алијаси посећених соба или група и корисничка имена других корисника. Не садрже саме поруке.", + "Always show encryption icons": "Увек прикажи иконице шифровања", + "Riot bugs are tracked on GitHub: create a GitHub issue.": "Грешке у Riot-у се прате на Гитхабу: направите Гитхаб проблем.", + "Log out and remove encryption keys?": "Желите да се одјавите и уклоните кључеве за шифровање?", + "Send Logs": "Пошаљи записнике", + "Clear Storage and Sign Out": "Очисти складиште и одјави ме", + "Refresh": "Освежи", + "We encountered an error trying to restore your previous session.": "Наишли смо на грешку приликом повраћаја ваше претходне сесије.", + "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Чишћење складишта вашег прегледача може решити проблем али ће вас то одјавити и учинити шифровани историјат ћаскања нечитљивим." } From 2553ec8d14be233fd5423a3b30e3bc2e0e74061a Mon Sep 17 00:00:00 2001 From: Osoitz Date: Wed, 2 May 2018 08:19:02 +0000 Subject: [PATCH 0990/1160] Translated using Weblate (Basque) Currently translated at 100.0% (1169 of 1169 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eu/ --- src/i18n/strings/eu.json | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index 5a7a1312a9..6843f35440 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -1158,5 +1158,18 @@ "Checking for an update...": "Eguneraketarik dagoen egiaztatzen...", "There are advanced notifications which are not shown here": "Hemen erakusten ez diren jakinarazpen aurreratuak daude", "Missing roomId.": "Gelaren ID-a falta da.", - "Picture": "Irudia" + "Picture": "Irudia", + "Every page you use in the app": "Aplikazioan erabilitako orri oro", + "e.g. ": "adib. ", + "Your User Agent": "Zure erabiltzaile-agentea", + "Your device resolution": "Zure gailuaren bereizmena", + "Always show encryption icons": "Beti erakutsi zifratze ikonoak", + "Popout widget": "Laster-leiho trepeta", + "Riot bugs are tracked on GitHub: create a GitHub issue.": "Riot-en akatsak GitHub bidez kudeatzen dira: sortu akats txosten bat GitHub-en.", + "Log out and remove encryption keys?": "Amaitu saioa eta kendu zifratze gakoak?", + "Send Logs": "Bidali egunkariak", + "Clear Storage and Sign Out": "Garbitu biltegiratzea eta amaitu saioa", + "Refresh": "Freskatu", + "We encountered an error trying to restore your previous session.": "Errore bat aurkitu dugu zure aurreko saioa berrezartzen saiatzean.", + "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Zure nabigatzailearen biltegiratzea garbitzeak arazoa konpon lezake, baina saioa amaituko da eta zifratutako txaten historiala ezin izango da berriro irakurri." } From 2dfb3146b00f8d5264dc72b416754c6e7966c3fe Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 2 May 2018 10:39:15 +0100 Subject: [PATCH 0991/1160] Simplify concurrent request error handling --- src/stores/GroupStore.js | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/stores/GroupStore.js b/src/stores/GroupStore.js index 0e2e8e6b86..e7cea5667e 100644 --- a/src/stores/GroupStore.js +++ b/src/stores/GroupStore.js @@ -56,22 +56,16 @@ async function limitConcurrency(fn) { }); } - let result; - let error; - ongoingRequestCount++; try { - result = await fn(); + return await fn(); } catch (err) { - error = err; + // We explicitly do not handle the error here, but let it propogate. + throw err; } finally { ongoingRequestCount--; checkBacklog(); } - - if (error) throw error; - - return result; } /** From cb1b64a5cd21b50fb1dd905d8dc6a3f708741548 Mon Sep 17 00:00:00 2001 From: Lakshya A Agrawal Date: Wed, 2 May 2018 06:12:52 +0000 Subject: [PATCH 0992/1160] Translated using Weblate (Hindi) Currently translated at 1.4% (17 of 1169 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hi/ --- src/i18n/strings/hi.json | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hi.json b/src/i18n/strings/hi.json index f8bfb088a8..eb73d65a78 100644 --- a/src/i18n/strings/hi.json +++ b/src/i18n/strings/hi.json @@ -4,5 +4,16 @@ "All Rooms": "सारे कमरे", "Please set a password!": "कृपया एक पासवर्ड सेट करें!", "Continue": "आगे बढ़ें", - "You have successfully set a password and an email address!": "आपने सफलतापूर्वक एक पासवर्ड और एक ईमेल एड्रेस सेट कर लिया है!" + "You have successfully set a password and an email address!": "आपने सफलतापूर्वक एक पासवर्ड और एक ईमेल एड्रेस सेट कर लिया है!", + "This email address is already in use": "यह ईमेल आईडी पहले से इस्तेमाल में है", + "This phone number is already in use": "यह फ़ोन नंबर पहले से इस्तेमाल में है", + "Failed to verify email address: make sure you clicked the link in the email": "ईमेल आईडी सत्यापित नही हो पाया: कृपया सुनिश्चित कर लें कि आपने ईमेल में मौजूद लिंक पर क्लिक किया है", + "The platform you're on": "आप जिस प्लेटफार्म पर हैं", + "The version of Riot.im": "रायट.आई एम का जो संस्करण", + "Whether or not you're logged in (we don't record your user name)": "चाहे आप लॉग इन हों या ना हों( हम आपका खाता नाम दर्ज नहीं करते )", + "Your language of choice": "आपकी चयन की भाषा", + "Which officially provided instance you are using, if any": "क्या आप कोई अधिकृत संस्करण इस्तेमाल कर रहे हैं? अगर हां, तो कौन सा", + "Your homeserver's URL": "आपके होमसर्वर का यू. आर. एल.", + "Every page you use in the app": "हर पृष्ठ जिसका आप इस एप में इस्तेमाल करते हैं", + "Your User Agent": "आपका उपभोक्ता प्रतिनिधि" } From d87987e8530d46a3ecc2f9c10757c934b5be9541 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D1=80=D0=BA=D0=BE=20=D0=9C=2E=20=D0=9A=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D0=B8=D1=9B?= Date: Wed, 2 May 2018 06:49:15 +0000 Subject: [PATCH 0993/1160] Translated using Weblate (Serbian) Currently translated at 100.0% (1169 of 1169 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sr/ --- src/i18n/strings/sr.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index 27c77e3552..5c91838e3e 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -365,7 +365,7 @@ "Drop here to restore": "Пусти овде да опоравиш", "Drop here to demote": "Пусти овде да унизиш", "Drop here to tag %(section)s": "Пусти овде да означиш %(section)s", - "Press to start a chat with someone": "Притисни за започињање ћаскања са неким", + "Press to start a chat with someone": "Притисни за почетак ћаскања са неким", "You're not in any rooms yet! Press to make a room or to browse the directory": "Још нисте у било којој соби! Притисните да бисте направили собу или да бисте погледали фасциклу", "Community Invites": "Позивнице заједнице", "Invites": "Позивнице", @@ -1116,7 +1116,7 @@ "You can now return to your account after signing out, and sign in on other devices.": "Можете се вратити у ваш налог након што се одјавите и пријавите поново, на другим уређајима.", "Enable desktop notifications": "Омогући стона обавештења", "Enable email notifications": "Омогући мејл обавештења", - "Login": "Пријава", + "Login": "Пријављивање", "Download this file": "Преузми ову датотеку", "Pin Message": "Закачи поруку", "Failed to change settings": "Нисам успео да променим подешавања", From 730512bc3f26d3b0106ce76ce9b29b7f0bc1e128 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 2 May 2018 10:58:43 +0100 Subject: [PATCH 0994/1160] Use the right js-sdk branch when testing On the react-sdk tests not just riot-web --- .travis-test-riot.sh | 9 +-------- scripts/travis.sh | 4 ++++ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/.travis-test-riot.sh b/.travis-test-riot.sh index 87200871a5..eeba4d0b7e 100755 --- a/.travis-test-riot.sh +++ b/.travis-test-riot.sh @@ -9,16 +9,9 @@ set -ev RIOT_WEB_DIR=riot-web REACT_SDK_DIR=`pwd` -curbranch="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}" -echo "Determined branch to be $curbranch" - -git clone https://github.com/vector-im/riot-web.git \ - "$RIOT_WEB_DIR" - +scripts/fetchdep.sh vector-im riot-web cd "$RIOT_WEB_DIR" -git checkout "$curbranch" || git checkout develop - mkdir node_modules npm install diff --git a/scripts/travis.sh b/scripts/travis.sh index c4a06c1bd1..7c96a02eb5 100755 --- a/scripts/travis.sh +++ b/scripts/travis.sh @@ -2,6 +2,10 @@ set -ex +scripts/fetchdep.sh matrix-org matrix-js-sdk +rm -r node_modules/matrix-js-sdk || true +ln -s matrix-js-sdk node_modules/matrix-js-sdk + npm run test ./.travis-test-riot.sh From b44582777bbcf680093955b874867b88783353a9 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 2 May 2018 11:03:40 +0100 Subject: [PATCH 0995/1160] Would if I added the script --- scripts/fetchdep.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100755 scripts/fetchdep.sh diff --git a/scripts/fetchdep.sh b/scripts/fetchdep.sh new file mode 100755 index 0000000000..424a8b034c --- /dev/null +++ b/scripts/fetchdep.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +set -e + +org="$1" +repo="$2" + +curbranch="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}" +echo "Determined branch to be $curbranch" + +git clone https://github.com/$org/$repo.git $repo --branch "$curbranch" || git clone https://github.com/$org/$repo.git $repo --branch develop + From c54198464ba396868a1c76e1f7991c427e398c3f Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 2 May 2018 11:09:28 +0100 Subject: [PATCH 0996/1160] npm install the js-sdk --- scripts/travis.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/travis.sh b/scripts/travis.sh index 7c96a02eb5..5c084145da 100755 --- a/scripts/travis.sh +++ b/scripts/travis.sh @@ -6,6 +6,10 @@ scripts/fetchdep.sh matrix-org matrix-js-sdk rm -r node_modules/matrix-js-sdk || true ln -s matrix-js-sdk node_modules/matrix-js-sdk +pushd node_modules/matrix-js-sdk +npm install +popd + npm run test ./.travis-test-riot.sh From 825d610938bcb30e509639782c1b4ce34ebe785d Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 2 May 2018 11:13:16 +0100 Subject: [PATCH 0997/1160] Bah, no pushd. Also this npm install should now be unnecessary --- .travis.yml | 1 - scripts/travis.sh | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 954f14a4da..ec07243a28 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,6 +15,5 @@ addons: chrome: stable install: - npm install - - (cd node_modules/matrix-js-sdk && npm install) script: ./scripts/travis.sh diff --git a/scripts/travis.sh b/scripts/travis.sh index 5c084145da..b3f87bfed0 100755 --- a/scripts/travis.sh +++ b/scripts/travis.sh @@ -6,9 +6,9 @@ scripts/fetchdep.sh matrix-org matrix-js-sdk rm -r node_modules/matrix-js-sdk || true ln -s matrix-js-sdk node_modules/matrix-js-sdk -pushd node_modules/matrix-js-sdk +cd node_modules/matrix-js-sdk npm install -popd +cd ../.. npm run test ./.travis-test-riot.sh From dc20f32ad7b0dbde599f05ea2ef8986e2711d0ea Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 2 May 2018 11:19:01 +0100 Subject: [PATCH 0998/1160] Move waitForUpdate to test-utils --- test/components/structures/GroupView-test.js | 21 +------------------- test/test-utils.js | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/test/components/structures/GroupView-test.js b/test/components/structures/GroupView-test.js index 71df26da46..76baafe1c8 100644 --- a/test/components/structures/GroupView-test.js +++ b/test/components/structures/GroupView-test.js @@ -26,32 +26,13 @@ import sdk from 'matrix-react-sdk'; import Matrix from 'matrix-js-sdk'; import * as TestUtils from 'test-utils'; +const { waitForUpdate } = TestUtils; const GroupView = sdk.getComponent('structures.GroupView'); const WrappedGroupView = TestUtils.wrapInMatrixClientContext(GroupView); const Spinner = sdk.getComponent('elements.Spinner'); -/** - * Call fn before calling componentDidUpdate on a react component instance, inst. - * @param {React.Component} inst an instance of a React component. - * @returns {Promise} promise that resolves when componentDidUpdate is called on - * given component instance. - */ -function waitForUpdate(inst) { - return new Promise((resolve, reject) => { - const cdu = inst.componentDidUpdate; - - inst.componentDidUpdate = (prevProps, prevState, snapshot) => { - resolve(); - - if (cdu) cdu(prevProps, prevState, snapshot); - - inst.componentDidUpdate = cdu; - }; - }); -} - describe('GroupView', function() { let root; let rootElement; diff --git a/test/test-utils.js b/test/test-utils.js index d2c685b371..e7d3412722 100644 --- a/test/test-utils.js +++ b/test/test-utils.js @@ -302,3 +302,23 @@ export function wrapInMatrixClientContext(WrappedComponent) { } return Wrapper; } + +/** + * Call fn before calling componentDidUpdate on a react component instance, inst. + * @param {React.Component} inst an instance of a React component. + * @returns {Promise} promise that resolves when componentDidUpdate is called on + * given component instance. + */ +export function waitForUpdate(inst) { + return new Promise((resolve, reject) => { + const cdu = inst.componentDidUpdate; + + inst.componentDidUpdate = (prevProps, prevState, snapshot) => { + resolve(); + + if (cdu) cdu(prevProps, prevState, snapshot); + + inst.componentDidUpdate = cdu; + }; + }); +} From 9bccecf449533b5d48552a13f1e845983acc54c1 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 2 May 2018 11:23:57 +0100 Subject: [PATCH 0999/1160] Get symlink right Also No need to cd into the symlink, can just go straight there --- scripts/travis.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/travis.sh b/scripts/travis.sh index b3f87bfed0..48410ea904 100755 --- a/scripts/travis.sh +++ b/scripts/travis.sh @@ -4,11 +4,11 @@ set -ex scripts/fetchdep.sh matrix-org matrix-js-sdk rm -r node_modules/matrix-js-sdk || true -ln -s matrix-js-sdk node_modules/matrix-js-sdk +ln -s ../matrix-js-sdk node_modules/matrix-js-sdk -cd node_modules/matrix-js-sdk +cd matrix-js-sdk npm install -cd ../.. +cd .. npm run test ./.travis-test-riot.sh From 4c3f8110509be237e7287349cf6ec346de18caff Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 2 May 2018 13:14:47 +0100 Subject: [PATCH 1000/1160] switch RoomView:uploadFile to async to clean up then/catch handling Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/RoomView.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index cb6250c2d3..c5f6a75cc5 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -908,18 +908,15 @@ module.exports = React.createClass({ this.setState({ draggingFile: false }); }, - uploadFile: function(file) { + uploadFile: async function(file) { if (MatrixClientPeg.get().isGuest()) { dis.dispatch({action: 'view_set_mxid'}); return; } - ContentMessages.sendContentToRoom(file, this.state.room.roomId, MatrixClientPeg.get()).then(() => { - // Send message_sent callback, for things like _checkIfAlone because after all a file is still a message. - dis.dispatch({ - action: 'message_sent', - }); - }).catch((error) => { + try { + await ContentMessages.sendContentToRoom(file, this.state.room.roomId, MatrixClientPeg.get()); + } catch (error) { if (error.name === "UnknownDeviceError") { // Let the status bar handle this return; @@ -931,6 +928,14 @@ module.exports = React.createClass({ description: ((error && error.message) ? error.message : _t("Server may be unavailable, overloaded, or the file too big")), }); + + // bail early to avoid calling the dispatch below + return; + } + + // Send message_sent callback, for things like _checkIfAlone because after all a file is still a message. + dis.dispatch({ + action: 'message_sent', }); }, From d0141840db15507b7a8cddd12fb60de4a9df5dcb Mon Sep 17 00:00:00 2001 From: Szimszon Date: Wed, 2 May 2018 13:05:56 +0000 Subject: [PATCH 1001/1160] Translated using Weblate (Hungarian) Currently translated at 100.0% (1174 of 1174 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 32f56afa29..6ec430147c 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -1171,5 +1171,10 @@ "Clear Storage and Sign Out": "Tárhely törlése és kijelentkezés", "Refresh": "Frissítés", "We encountered an error trying to restore your previous session.": "Hibába ütköztünk megpróbáljuk visszaállítani az előző munkamenetet.", - "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "A böngésződ tárhelyének a törlése megoldhatja a problémát, de ezzel kijelentkezel és a titkosított beszélgetések előzményei olvashatatlanná válnak." + "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "A böngésződ tárhelyének a törlése megoldhatja a problémát, de ezzel kijelentkezel és a titkosított beszélgetések előzményei olvashatatlanná válnak.", + "At this time it is not possible to reply with a file so this will be sent without being a reply.": "Jelenleg válaszban nem lehet fájlt küldeni, így most úgy lesz elküldve, hogy ez nem egy válasz.", + "Unable to reply": "Nem lehet válaszolni", + "At this time it is not possible to reply with an emote.": "Jelenleg nem lehet emodzsival válaszolni.", + "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Nem lehet betölteni azt az eseményt amire válaszoltál, mert vagy nem létezik, vagy nincs jogod megnézni.", + "Collapse Reply Thread": "Beszélgetés szál becsukása" } From 0040ea0d9f76b27eef56b64db02d6cccc262e532 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 2 May 2018 15:53:38 +0100 Subject: [PATCH 1002/1160] Use develop js-sdk in travis build --- jenkins.sh | 5 +++-- scripts/fetchdep.sh | 14 +++++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/jenkins.sh b/jenkins.sh index 3a2d66739e..0f7a58ee69 100755 --- a/jenkins.sh +++ b/jenkins.sh @@ -11,8 +11,9 @@ set -x # install the other dependencies npm install -# we may be using a dev branch of js-sdk in which case we need to build it -(cd node_modules/matrix-js-sdk && npm install) +scripts/fetchdep.sh matrix-org matrix-js-sdk +ln -s ../matrix-js-sdk node_modules/matrix-js-sdk +(cd matrix-js-sdk && npm install) # run the mocha tests npm run test -- --no-colors diff --git a/scripts/fetchdep.sh b/scripts/fetchdep.sh index 424a8b034c..14111576bf 100755 --- a/scripts/fetchdep.sh +++ b/scripts/fetchdep.sh @@ -5,8 +5,16 @@ set -e org="$1" repo="$2" -curbranch="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}" -echo "Determined branch to be $curbranch" +curbranch="$TRAVIS_PULL_REQUEST_BRANCH" +[ -z "$curbranch" ] && curbranch="$TRAVIS_BRANCH" +[ -z "$curbranch" ] && curbranch="$GIT_BRANCH" # jenkins -git clone https://github.com/$org/$repo.git $repo --branch "$curbranch" || git clone https://github.com/$org/$repo.git $repo --branch develop +if [ -n "$curbranch" ] +then + echo "Determined branch to be $curbranch" + git clone https://github.com/$org/$repo.git $repo --branch "$curbranch" && exit 0 +fi + +echo "Checking out develop branch" +git clone https://github.com/$org/$repo.git $repo --branch develop From 621232db4adabd1be8e374bc5234bb372483e9e3 Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 2 May 2018 13:34:58 +0000 Subject: [PATCH 1003/1160] Translated using Weblate (Russian) Currently translated at 99.7% (1171 of 1174 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index b8a55b32a7..3cf9aa0f7d 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -1171,5 +1171,7 @@ "Clear Storage and Sign Out": "Очистить хранилище и выйти", "Refresh": "Обновить", "We encountered an error trying to restore your previous session.": "Произошла ошибка при попытке восстановить предыдущий сеанс.", - "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Очистка хранилища вашего браузера может устранить проблему, но при этом ваша сессия будет завершена и зашифрованная история чата станет нечитаемой." + "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Очистка хранилища вашего браузера может устранить проблему, но при этом ваша сессия будет завершена и зашифрованная история чата станет нечитаемой.", + "Unable to reply": "Не удается ответить", + "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Не удается загрузить событие, на которое был дан ответ, либо оно не существует, либо у вас нет разрешения на его просмотр." } From 183947615f68083a73813ad671e039e1f8cd5869 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 2 May 2018 16:39:10 +0100 Subject: [PATCH 1004/1160] Fux up jenkins origin/ branches --- scripts/fetchdep.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/fetchdep.sh b/scripts/fetchdep.sh index 14111576bf..9e7e47fe5b 100755 --- a/scripts/fetchdep.sh +++ b/scripts/fetchdep.sh @@ -7,7 +7,7 @@ repo="$2" curbranch="$TRAVIS_PULL_REQUEST_BRANCH" [ -z "$curbranch" ] && curbranch="$TRAVIS_BRANCH" -[ -z "$curbranch" ] && curbranch="$GIT_BRANCH" # jenkins +[ -z "$curbranch" ] && curbranch=`"$GIT_BRANCH" | sed -e 's/^origin\///'` # jenkins if [ -n "$curbranch" ] then From 82349ec933cc369179814931e303602e05e169f4 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 2 May 2018 16:43:51 +0100 Subject: [PATCH 1005/1160] Fix sed --- scripts/fetchdep.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/fetchdep.sh b/scripts/fetchdep.sh index 9e7e47fe5b..a8551cf15d 100755 --- a/scripts/fetchdep.sh +++ b/scripts/fetchdep.sh @@ -7,7 +7,7 @@ repo="$2" curbranch="$TRAVIS_PULL_REQUEST_BRANCH" [ -z "$curbranch" ] && curbranch="$TRAVIS_BRANCH" -[ -z "$curbranch" ] && curbranch=`"$GIT_BRANCH" | sed -e 's/^origin\///'` # jenkins +[ -z "$curbranch" ] && curbranch=`"echo $GIT_BRANCH" | sed -e 's/^origin\///'` # jenkins if [ -n "$curbranch" ] then From 9f8202c8a9f42235b396d62430f75d6b1120ebd6 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 2 May 2018 16:49:08 +0100 Subject: [PATCH 1006/1160] Remove directories if they exist --- jenkins.sh | 1 + scripts/fetchdep.sh | 2 ++ 2 files changed, 3 insertions(+) diff --git a/jenkins.sh b/jenkins.sh index 0f7a58ee69..8cf5ee4a1f 100755 --- a/jenkins.sh +++ b/jenkins.sh @@ -12,6 +12,7 @@ set -x npm install scripts/fetchdep.sh matrix-org matrix-js-sdk +rm -r node_modules/matrix-js-sdk || true ln -s ../matrix-js-sdk node_modules/matrix-js-sdk (cd matrix-js-sdk && npm install) diff --git a/scripts/fetchdep.sh b/scripts/fetchdep.sh index a8551cf15d..73c622133b 100755 --- a/scripts/fetchdep.sh +++ b/scripts/fetchdep.sh @@ -5,6 +5,8 @@ set -e org="$1" repo="$2" +rm -r "$repo" || true + curbranch="$TRAVIS_PULL_REQUEST_BRANCH" [ -z "$curbranch" ] && curbranch="$TRAVIS_BRANCH" [ -z "$curbranch" ] && curbranch=`"echo $GIT_BRANCH" | sed -e 's/^origin\///'` # jenkins From bf8612f8642346fb42cc96b20d3b2597dc9c294b Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 2 May 2018 17:30:37 +0100 Subject: [PATCH 1007/1160] Update eslint-plugin-react Enables jsx-no-bind checking (although we may have to stop erroring on this as we currently break this rule in a few places) --- package-lock.json | 423 +++++++++++++++++++++++++++++----------------- package.json | 2 +- 2 files changed, 270 insertions(+), 155 deletions(-) diff --git a/package-lock.json b/package-lock.json index 23ffa68bef..f183f1635d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.10.7", + "version": "0.12.2", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -268,7 +268,7 @@ "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", "dev": true, "requires": { "fs.realpath": "1.0.0", @@ -1203,10 +1203,7 @@ "boom": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", - "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", - "requires": { - "hoek": "4.2.0" - } + "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=" }, "brace-expansion": { "version": "1.1.8", @@ -1238,6 +1235,12 @@ "resolved": "https://registry.npmjs.org/browser-request/-/browser-request-0.3.3.tgz", "integrity": "sha1-ns5bWsqJopkyJC4Yv5M975h2zBc=" }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, "browserify-aes": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-0.4.0.tgz", @@ -1254,6 +1257,14 @@ "dev": true, "requires": { "pako": "0.2.9" + }, + "dependencies": { + "pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", + "dev": true + } } }, "buffer": { @@ -1449,9 +1460,9 @@ "dev": true }, "commonmark": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/commonmark/-/commonmark-0.27.0.tgz", - "integrity": "sha1-2GwmK5YoIelIPGnFR7xYhAwEezQ=", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/commonmark/-/commonmark-0.28.1.tgz", + "integrity": "sha1-Buq41SM4uDn6Gi11rwCF7tGxvq4=", "requires": { "entities": "1.1.1", "mdurl": "1.0.1", @@ -1580,10 +1591,7 @@ "boom": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", - "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", - "requires": { - "hoek": "4.2.0" - } + "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==" } } }, @@ -1705,12 +1713,6 @@ "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", "dev": true }, - "diff": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", - "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=", - "dev": true - }, "doctrine": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", @@ -2139,7 +2141,7 @@ "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", "dev": true, "requires": { "fs.realpath": "1.0.0", @@ -2183,15 +2185,26 @@ } }, "eslint-plugin-react": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.4.0.tgz", - "integrity": "sha512-tvjU9u3VqmW2vVuYnE8Qptq+6ji4JltjOjJ9u7VAOxVYkUkyBZWRvNYKbDv5fN+L6wiA+4we9+qQahZ0m63XEA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.7.0.tgz", + "integrity": "sha512-KC7Snr4YsWZD5flu6A5c0AcIZidzW3Exbqp7OT67OaD2AppJtlBr/GuPrW/vaQM/yfZotEvKAdrxrO+v8vwYJA==", "dev": true, "requires": { - "doctrine": "2.0.0", + "doctrine": "2.1.0", "has": "1.0.1", "jsx-ast-utils": "2.0.1", "prop-types": "15.6.0" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "2.0.2" + } + } } }, "espree": { @@ -2238,7 +2251,7 @@ "estree-walker": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.5.0.tgz", - "integrity": "sha512-/bEAy+yKAZQrEWUhGmS3H9XpGqSDBtRzX0I2PgMw9kA2n1jN22uV5B5p7MFdZdvWdXCRJztXAfx6ZeRfgkEETg==", + "integrity": "sha1-quO1fELeuAEONJyJJGLw5xxd0ao=", "dev": true }, "esutils": { @@ -2554,6 +2567,22 @@ } } }, + "focus-trap": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-2.4.3.tgz", + "integrity": "sha512-sT5Ip9nyAIxWq8Apt1Fdv6yTci5GotaOtO5Ro1/+F3PizttNBcCYz8j/Qze54PPFK73KUbOqh++HUCiyNPqvhA==", + "requires": { + "tabbable": "1.1.2" + } + }, + "focus-trap-react": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/focus-trap-react/-/focus-trap-react-3.1.2.tgz", + "integrity": "sha512-MoQmONoy9gRPyrC5DGezkcOMGgx7MtIOAQDHe098UtL2sA2vmucJwEmQisb+8LRXNYFHxuw5zJ1oLFeKu4Mteg==", + "requires": { + "focus-trap": "2.4.3" + } + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -2629,7 +2658,7 @@ "fsevents": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.2.tgz", - "integrity": "sha512-Sn44E5wQW4bTHXvQmvSHwqbuiXtduD6Rrjm2ZtUEGbyrig+nUH3t/QD4M4/ZXViY556TBpRgZkHLDx3JxPwxiw==", + "integrity": "sha1-MoK3E/s62A7eDp/PRhG1qm/AM/Q=", "dev": true, "optional": true, "requires": { @@ -3562,6 +3591,11 @@ "assert-plus": "1.0.0" } }, + "gfm.css": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/gfm.css/-/gfm.css-1.1.2.tgz", + "integrity": "sha512-KhK3rqxMj+UTLRxWnfUA5n8XZYMWfHrrcCxtWResYR2B3hWIqBM6v9FPGZSlVuX+ScLewizOvNkjYXuPs95ThQ==" + }, "glob": { "version": "5.0.15", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", @@ -3596,7 +3630,7 @@ "globals": { "version": "9.18.0", "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "integrity": "sha1-qjiWs+abSH8X4x7SFD1pqOMMLYo=", "dev": true }, "globby": { @@ -3616,7 +3650,7 @@ "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", "dev": true, "requires": { "fs.realpath": "1.0.0", @@ -3635,12 +3669,6 @@ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", "dev": true }, - "growl": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", - "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", - "dev": true - }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -3709,19 +3737,24 @@ "requires": { "boom": "4.3.1", "cryptiles": "3.1.2", - "hoek": "4.2.0", "sntp": "2.0.2" } }, - "highlight.js": { - "version": "8.9.1", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-8.9.1.tgz", - "integrity": "sha1-uKnFSTISqTkvAiK2SclhFJfr+4g=" + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true }, - "hoek": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", - "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==" + "highlight.js": { + "version": "9.12.0", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.12.0.tgz", + "integrity": "sha1-5tnb5Xy+/mB1HwKvM2GVhwyQwB4=" + }, + "hoist-non-react-statics": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.0.tgz", + "integrity": "sha512-6Bl6XsDT1ntE0lHbIhr4Kp2PGcleGZ66qu5Jqk8lc0Xc/IeG6gVLmwUGs/K0Us+L8VWoKgj0uWdPMataOsm31w==" }, "home-or-tmp": { "version": "2.0.0", @@ -3862,7 +3895,6 @@ "version": "2.2.2", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", - "dev": true, "requires": { "loose-envify": "1.3.1" } @@ -4137,30 +4169,6 @@ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, - "jade": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz", - "integrity": "sha1-jxDXl32NefL2/4YqgbBRPMslaGw=", - "dev": true, - "requires": { - "commander": "0.6.1", - "mkdirp": "0.3.0" - }, - "dependencies": { - "commander": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz", - "integrity": "sha1-+mihT2qUXVTbvlDYzbMyDp47GgY=", - "dev": true - }, - "mkdirp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", - "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=", - "dev": true - } - } - }, "jquery": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.2.1.tgz", @@ -4303,7 +4311,7 @@ "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", "dev": true, "requires": { "fs.realpath": "1.0.0", @@ -4472,6 +4480,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" }, + "lodash-es": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.10.tgz", + "integrity": "sha512-iesFYPmxYYGTcmQK0sL8bX3TGHyM6b2qREaB4kamHfQyfPJP0xgoGxp19nsH16nsfquLdiyKyX3mQkfiSGV8Rg==" + }, "lodash.assign": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", @@ -4547,17 +4560,28 @@ "dev": true }, "matrix-js-sdk": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-0.8.5.tgz", - "integrity": "sha1-1ZAVTx53ADVyZw+p28rH5APnbk8=", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-0.10.1.tgz", + "integrity": "sha512-BLo+Okn2o///TyWBKtjFXvhlD32vGfr10eTE51hHx/jwaXO82VyGMzMi+IDPS4SDYUbvXI7PpamECeh9TXnV2w==", "requires": { "another-json": "0.2.0", + "babel-runtime": "6.26.0", "bluebird": "3.5.1", "browser-request": "0.3.3", "content-type": "1.0.4", "request": "2.83.0" } }, + "matrix-mock-request": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/matrix-mock-request/-/matrix-mock-request-1.2.1.tgz", + "integrity": "sha1-2aWrqNPYJG6I/3YyWYuZwUE/QjI=", + "dev": true, + "requires": { + "bluebird": "3.5.1", + "expect": "1.20.2" + } + }, "matrix-react-test-utils": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/matrix-react-test-utils/-/matrix-react-test-utils-0.1.1.tgz", @@ -4579,6 +4603,11 @@ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", "dev": true }, + "memoize-one": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-3.1.1.tgz", + "integrity": "sha512-YqVh744GsMlZu6xkhGslPSqSurOv6P+kLN2J3ysBZfagLcL5FdRK/0UpgLoL8hwjjEvvAVkjJZyFP+1T6p1vgA==" + }, "memory-fs": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", @@ -4632,7 +4661,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "requires": { "brace-expansion": "1.1.8" } @@ -4660,75 +4689,73 @@ } }, "mocha": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-2.5.3.tgz", - "integrity": "sha1-FhvlvetJZ3HrmzV0UFC2IrWu/Fg=", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.1.1.tgz", + "integrity": "sha512-kKKs/H1KrMMQIEsWNxGmb4/BGsmj0dkeyotEvbrAuQ01FcWRLssUNXCEUZk6SZtyJBi6EE7SL0zDDtItw1rGhw==", "dev": true, "requires": { - "commander": "2.3.0", - "debug": "2.2.0", - "diff": "1.4.0", - "escape-string-regexp": "1.0.2", - "glob": "3.2.11", - "growl": "1.9.2", - "jade": "0.26.3", + "browser-stdout": "1.3.1", + "commander": "2.11.0", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.3", + "he": "1.1.1", + "minimatch": "3.0.4", "mkdirp": "0.5.1", - "supports-color": "1.2.0", - "to-iso-string": "0.0.2" + "supports-color": "4.4.0" }, "dependencies": { - "commander": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz", - "integrity": "sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM=", - "dev": true - }, "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { - "ms": "0.7.1" + "ms": "2.0.0" } }, - "escape-string-regexp": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz", - "integrity": "sha1-Tbwv5nTnGUnK8/smlc5/LcHZqNE=", + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, "glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", - "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", "inherits": "2.0.3", - "minimatch": "0.3.0" + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } }, - "minimatch": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", - "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", - "dev": true, - "requires": { - "lru-cache": "2.2.4", - "sigmund": "1.0.1" - } + "growl": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", + "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", + "dev": true }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", "dev": true }, "supports-color": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-1.2.0.tgz", - "integrity": "sha1-/x7R5hFp0Gs88tWI4YixjYhH4X4=", - "dev": true + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } } } }, @@ -4979,10 +5006,9 @@ } }, "pako": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", - "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", - "dev": true + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", + "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==" }, "parallelshell": { "version": "3.0.2", @@ -5205,10 +5231,23 @@ "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", "dev": true }, + "raf": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.0.tgz", + "integrity": "sha512-pDP/NMRAXoTfrhCfyfSEwJAKLaxBU9eApMeBPB1TkDouZmvPerIClV8lTAd+uF8ZiTaVl69e1FCxQrAd/VTjGw==", + "requires": { + "performance-now": "2.1.0" + } + }, + "raf-schd": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-2.1.1.tgz", + "integrity": "sha512-ngcBQygUeE3kHlOaBSqgWKv7BT9kx5kQ6fAwFJRNRT7TD54M+hx1kpNHb8sONRskcYQedJg2RC2xKlAHRUQBig==" + }, "randomatic": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", - "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "integrity": "sha1-x6vpzIuHwLqodrGf3oP9RkeX44w=", "dev": true, "requires": { "is-number": "3.0.0", @@ -5287,6 +5326,23 @@ "integrity": "sha1-wStu/cIkfBDae4dw0YUICnsEcVY=", "dev": true }, + "react-beautiful-dnd": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/react-beautiful-dnd/-/react-beautiful-dnd-4.0.1.tgz", + "integrity": "sha512-d73RMu4QOFCyjUELLWFyY/EuclnfqulI9pECx+2gIuJvV0ycf1uR88o+1x0RSB9ILD70inHMzCBKNkWVbbt+vA==", + "requires": { + "babel-runtime": "6.26.0", + "invariant": "2.2.2", + "memoize-one": "3.1.1", + "prop-types": "15.6.0", + "raf-schd": "2.1.1", + "react-motion": "0.5.2", + "react-redux": "5.0.7", + "redux": "3.7.2", + "redux-thunk": "2.2.0", + "reselect": "3.0.1" + } + }, "react-dom": { "version": "15.6.2", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-15.6.2.tgz", @@ -5304,6 +5360,43 @@ "gemini-scrollbar": "github:matrix-org/gemini-scrollbar#b302279810d05319ac5ff1bd34910bff32325c7b" } }, + "react-motion": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/react-motion/-/react-motion-0.5.2.tgz", + "integrity": "sha512-9q3YAvHoUiWlP3cK0v+w1N5Z23HXMj4IF4YuvjvWegWqNPfLXsOBE/V7UvQGpXxHFKRQQcNcVQE31g9SB/6qgQ==", + "requires": { + "performance-now": "0.2.0", + "prop-types": "15.6.0", + "raf": "3.4.0" + }, + "dependencies": { + "performance-now": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", + "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=" + } + } + }, + "react-redux": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-5.0.7.tgz", + "integrity": "sha512-5VI8EV5hdgNgyjfmWzBbdrqUkrVRKlyTKk1sGH3jzM2M2Mhj/seQgPXaz6gVAj2lz/nz688AdTqMO18Lr24Zhg==", + "requires": { + "hoist-non-react-statics": "2.5.0", + "invariant": "2.2.2", + "lodash": "4.17.10", + "lodash-es": "4.17.10", + "loose-envify": "1.3.1", + "prop-types": "15.6.0" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" + } + } + }, "readable-stream": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", @@ -5350,6 +5443,22 @@ "resolve": "1.4.0" } }, + "redux": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/redux/-/redux-3.7.2.tgz", + "integrity": "sha512-pNqnf9q1hI5HHZRBkj3bAngGZW/JMCmexDlOxw4XagXY2o1327nHH54LoTjiPJ0gizoqPDRqWyX/00g0hD6w+A==", + "requires": { + "lodash": "4.17.4", + "lodash-es": "4.17.10", + "loose-envify": "1.3.1", + "symbol-observable": "1.2.0" + } + }, + "redux-thunk": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.2.0.tgz", + "integrity": "sha1-5hWhbha0ehmlFXZhM9Hj6Zt4UuU=" + }, "regenerate": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz", @@ -5498,6 +5607,11 @@ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", "dev": true }, + "reselect": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-3.0.1.tgz", + "integrity": "sha1-79qpjqdFEyTQkrKyFjpqHXqaIUc=" + }, "resolve": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", @@ -5544,7 +5658,7 @@ "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", "dev": true, "requires": { "fs.realpath": "1.0.0", @@ -5642,7 +5756,7 @@ "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", "dev": true, "requires": { "fs.realpath": "1.0.0", @@ -5655,12 +5769,6 @@ } } }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", - "dev": true - }, "sinon": { "version": "1.17.7", "resolved": "https://registry.npmjs.org/sinon/-/sinon-1.17.7.tgz", @@ -5688,10 +5796,7 @@ "sntp": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.0.2.tgz", - "integrity": "sha1-UGQRDwr4X3z9t9a2ekACjOUrSys=", - "requires": { - "hoek": "4.2.0" - } + "integrity": "sha1-UGQRDwr4X3z9t9a2ekACjOUrSys=" }, "socket.io": { "version": "1.7.3", @@ -5848,24 +5953,30 @@ "dev": true }, "source-map-loader": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-0.1.6.tgz", - "integrity": "sha1-wJkD2m1zueU7ftjuUkVZcFHpjpE=", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-0.2.3.tgz", + "integrity": "sha512-MYbFX9DYxmTQFfy2v8FC1XZwpwHKYxg3SK8Wb7VPBKuhDjz8gi9re2819MsG4p49HDyiOSUKlmZ+nQBArW5CGw==", "dev": true, "requires": { - "async": "0.9.2", + "async": "2.6.0", "loader-utils": "0.2.17", - "source-map": "0.1.43" + "source-map": "0.6.1" }, "dependencies": { - "source-map": { - "version": "0.1.43", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", - "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", + "async": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", + "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "dev": true, "requires": { - "amdefine": "1.0.1" + "lodash": "4.17.4" } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } } }, @@ -5917,7 +6028,7 @@ "stream-http": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.2.tgz", - "integrity": "sha512-c0yTD2rbQzXtSsFSVhtpvY/vS6u066PcXOX9kBB3mSO76RiUQzL340uJkGBWnlBg4/HZzqiUXtaVA7wcRcJgEw==", + "integrity": "sha1-QKBQ7I3DtTsz2ZCUFcAsC/Gr+60=", "dev": true, "requires": { "builtin-status-codes": "3.0.0", @@ -5983,6 +6094,16 @@ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true }, + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" + }, + "tabbable": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-1.1.2.tgz", + "integrity": "sha512-77oqsKEPrxIwgRcXUwipkj9W5ItO97L6eUT1Ar7vh+El16Zm4M6V+YU1cbipHEa6q0Yjw8O3Hoh8oRgatV5s7A==" + }, "table": { "version": "3.8.3", "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", @@ -6111,12 +6232,6 @@ "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", "dev": true }, - "to-iso-string": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/to-iso-string/-/to-iso-string-0.0.2.tgz", - "integrity": "sha1-TcGeZk38y+Jb2NtQiwDG2hWCVdE=", - "dev": true - }, "tough-cookie": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", diff --git a/package.json b/package.json index 1f979369e3..47ef08f546 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,7 @@ "eslint-config-google": "^0.7.1", "eslint-plugin-babel": "^4.0.1", "eslint-plugin-flowtype": "^2.30.0", - "eslint-plugin-react": "^7.4.0", + "eslint-plugin-react": "^7.7.0", "estree-walker": "^0.5.0", "expect": "^1.16.0", "flow-parser": "^0.57.3", From adf3e2f376cc5722b6085519b55db94777eca7b6 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 2 May 2018 17:36:29 +0100 Subject: [PATCH 1008/1160] Change jsx-no-bind to warn --- .eslintrc.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.eslintrc.js b/.eslintrc.js index c6aeb0d1be..9c14917e1f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -41,7 +41,8 @@ module.exports = { "react/jsx-uses-react": "error", // bind or arrow function in props causes performance issues - "react/jsx-no-bind": ["error", { + // (but we currently use them in some places) + "react/jsx-no-bind": ["warn", { "ignoreRefs": true, }], "react/jsx-key": ["error"], From 2475295a24e24083cadafa2d499cdbb3aeb636c5 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 2 May 2018 17:42:23 +0100 Subject: [PATCH 1009/1160] Up the max warning count :( --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 47ef08f546..5e58b90264 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "start": "parallelshell \"npm run build:watch\" \"npm run reskindex:watch\"", "lint": "eslint src/", "lintall": "eslint src/ test/", - "lintwithexclusions": "eslint --max-warnings 0 --ignore-path .eslintignore.errorfiles src test", + "lintwithexclusions": "eslint --max-warnings 10 --ignore-path .eslintignore.errorfiles src test", "clean": "rimraf lib", "prepublish": "npm run clean && npm run build && git rev-parse HEAD > git-revision.txt", "test": "karma start --single-run=true --browsers ChromeHeadless", From 7a74decb1c5625ba491553dd28f402f6ac34bfbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Wed, 2 May 2018 20:07:10 +0000 Subject: [PATCH 1010/1160] Translated using Weblate (French) Currently translated at 100.0% (1174 of 1174 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index cf2f594c74..9c0f3f98e8 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -1171,5 +1171,10 @@ "Clear Storage and Sign Out": "Effacer le stockage et se déconnecter", "Refresh": "Rafraîchir", "We encountered an error trying to restore your previous session.": "Une erreur est survenue lors de la récupération de la dernière session.", - "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Effacer le stockage de votre navigateur peut résoudre le problème, mais cela vous déconnectera et tous les historiques de conversation encryptés seront illisibles." + "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Effacer le stockage de votre navigateur peut résoudre le problème, mais cela vous déconnectera et tous les historiques de conversation encryptés seront illisibles.", + "At this time it is not possible to reply with a file so this will be sent without being a reply.": "Pour le moment il n'est pas possible de répondre avec un fichier donc ceci sera envoyé sans être une réponse.", + "Unable to reply": "Impossible de répondre", + "At this time it is not possible to reply with an emote.": "Pour le moment il n'est pas possible de répondre avec un émoji.", + "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Impossible de charger l'événement auquel il a été répondu, soit il n'existe pas, soit vous n'avez pas l'autorisation de le voir.", + "Collapse Reply Thread": "Dévoiler le fil de réponse" } From 09dcfb0a00af06be374218e6aec01fd3607da4f8 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Wed, 2 May 2018 23:27:19 +0100 Subject: [PATCH 1011/1160] relax lint for jsx-curly-spacing and arrow-parens --- .eslintrc.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index c6aeb0d1be..12ccd0e337 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -50,7 +50,12 @@ module.exports = { // // // https://github.com/yannickcr/eslint-plugin-react/blob/HEAD/docs/rules/jsx-curly-spacing.md - "react/jsx-curly-spacing": ["error", {"when": "never", "children": {"when": "always"}}], + // + // Disabled for now - if anything we'd like to *enforce* spacing in JSX + // curly brackets for legibility, but in practice it's not clear that the + // consistency particularly improves legibility here. --Matthew + // + // "react/jsx-curly-spacing": ["error", {"when": "never", "children": {"when": "always"}}], // Assert spacing before self-closing JSX tags, and no spacing before or // after the closing slash, and no spacing after the opening bracket of @@ -88,7 +93,6 @@ module.exports = { "valid-jsdoc": ["warn"], "new-cap": ["warn"], "key-spacing": ["warn"], - "arrow-parens": ["warn"], "prefer-const": ["warn"], // crashes currently: https://github.com/eslint/eslint/issues/6274 From 71a12b6bbbe2cb0e383d7e75a49d32c8e7c17989 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 3 May 2018 11:23:41 +0100 Subject: [PATCH 1012/1160] fix getDefaultProps mixup Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/EventTile.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index c7150da67c..bfcf8ac9d4 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -155,9 +155,11 @@ module.exports = withMatrixClient(React.createClass({ isTwelveHour: PropTypes.bool, }, - defaultProps: { - // no-op function because onWidgetLoad is optional yet some subcomponents assume its existence - onWidgetLoad: function() {}, + getDefaultProps: function() { + return { + // no-op function because onWidgetLoad is optional yet some sub-components assume its existence + onWidgetLoad: function() {}, + }; }, getInitialState: function() { From 4892694e770cb5dea68aea4f19e76f2fd835260e Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 3 May 2018 11:24:10 +0100 Subject: [PATCH 1013/1160] use more explicit reply fallback closing tag construct to fix 6657 Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 138431259f..c7ca4b2d41 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -97,7 +97,7 @@ export default class ReplyThread extends React.Component { // Part of Replies fallback support static stripHTMLReply(html) { - return html.replace(/^
    [\s\S]+?<\/blockquote>/, ''); + return html.replace(/^
    [\s\S]+?<\/blockquote>/, ''); } // Part of Replies fallback support @@ -119,7 +119,7 @@ export default class ReplyThread extends React.Component { case 'm.text': case 'm.notice': { html = `
    In reply to ${mxid}` - + `
    ${html || body}
    `; + + `
    ${html || body}
    `; const lines = body.trim().split('\n'); if (lines.length > 0) { lines[0] = `<${mxid}> ${lines[0]}`; @@ -129,27 +129,27 @@ export default class ReplyThread extends React.Component { } case 'm.image': html = `
    In reply to ${mxid}` - + `
    sent an image.
    `; + + `
    sent an image.
    `; body = `> <${mxid}> sent an image.\n\n`; break; case 'm.video': html = `
    In reply to ${mxid}` - + `
    sent a video.
    `; + + `
    sent a video.`; body = `> <${mxid}> sent a video.\n\n`; break; case 'm.audio': html = `
    In reply to ${mxid}` - + `
    sent an audio file.
    `; + + `
    sent an audio file.`; body = `> <${mxid}> sent an audio file.\n\n`; break; case 'm.file': html = `
    In reply to ${mxid}` - + `
    sent a file.
    `; + + `
    sent a file.`; body = `> <${mxid}> sent a file.\n\n`; break; case 'm.emote': { html = `
    In reply to * ` - + `${mxid}
    ${html || body}
    `; + + `${mxid}
    ${html || body}`; const lines = body.trim().split('\n'); if (lines.length > 0) { lines[0] = `* <${mxid}> ${lines[0]}`; From 22f2d6f292be9a5c4b8b52d973e20ac7b21f688d Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 3 May 2018 14:08:10 +0100 Subject: [PATCH 1014/1160] Fix crash when browser doesn't report page change measurement --- src/Analytics.js | 9 ++++++--- src/components/structures/MatrixChat.js | 4 ++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Analytics.js b/src/Analytics.js index 8b55bdfd64..0d1313f48d 100644 --- a/src/Analytics.js +++ b/src/Analytics.js @@ -164,9 +164,13 @@ class Analytics { } trackPageChange(generationTimeMs) { - if (typeof generationTimeMs !== 'number') { - throw new Error('Analytics.trackPageChange: expected generationTimeMs to be a number'); + if (typeof generationTimeMs === 'number') { + this._paq.push(['setGenerationTimeMs', generationTimeMs]); + } else { + console.warn('Analytics.trackPageChange: expected generationTimeMs to be a number'); + // But continue anyway because we still want to track the change } + if (this.disabled) return; if (this.firstPage) { // De-duplicate first page @@ -175,7 +179,6 @@ class Analytics { return; } this._paq.push(['setCustomUrl', getRedactedUrl()]); - this._paq.push(['setGenerationTimeMs', generationTimeMs]); this._paq.push(['trackPageView']); } diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 8df46d2f7c..3005bc86ad 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -413,6 +413,10 @@ export default React.createClass({ performance.clearMarks('riot_MatrixChat_page_change_start'); performance.clearMarks('riot_MatrixChat_page_change_stop'); const measurement = performance.getEntriesByName('riot_MatrixChat_page_change_delta').pop(); + + // In practice, sometimes the entries list is empty, so we get no measurement + if (!measurement) return null; + return measurement.duration; }, From 97d344483ebec8f622a211c435c6b75686f5fd29 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 3 May 2018 14:32:13 +0100 Subject: [PATCH 1015/1160] fix thinko when changing from ClientPeg to context in static method (DUH Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/ReplyThread.js | 36 ++++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index c7ca4b2d41..cd444fb090 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -59,22 +59,6 @@ export default class ReplyThread extends React.Component { this.collapse = this.collapse.bind(this); } - static async getEvent(room, eventId) { - const event = room.findEventById(eventId); - if (event) return event; - - try { - // ask the client to fetch the event we want using the context API, only interface to do so is to ask - // for a timeline with that event, but once it is loaded we can use findEventById to look up the ev map - await this.context.matrixClient.getEventTimeline(room.getUnfilteredTimelineSet(), eventId); - } catch (e) { - // if it fails catch the error and return early, there's no point trying to find the event in this case. - // Return null as it is falsey and thus should be treated as an error (as the event cannot be resolved). - return null; - } - return room.findEventById(eventId); - } - static getParentEventId(ev) { if (!ev || ev.isRedacted()) return; @@ -199,7 +183,7 @@ export default class ReplyThread extends React.Component { async initialize() { const {parentEv} = this.props; // at time of making this component we checked that props.parentEv has a parentEventId - const ev = await ReplyThread.getEvent(this.room, ReplyThread.getParentEventId(parentEv)); + const ev = await this.getEvent(ReplyThread.getParentEventId(parentEv)); if (this.unmounted) return; if (ev) { @@ -223,7 +207,7 @@ export default class ReplyThread extends React.Component { return; } - const loadedEv = await ReplyThread.getEvent(this.room, inReplyToEventId); + const loadedEv = await this.getEvent(inReplyToEventId); if (this.unmounted) return; if (loadedEv) { @@ -233,6 +217,22 @@ export default class ReplyThread extends React.Component { } } + async getEvent(eventId) { + const event = this.room.findEventById(eventId); + if (event) return event; + + try { + // ask the client to fetch the event we want using the context API, only interface to do so is to ask + // for a timeline with that event, but once it is loaded we can use findEventById to look up the ev map + await this.context.matrixClient.getEventTimeline(this.room.getUnfilteredTimelineSet(), eventId); + } catch (e) { + // if it fails catch the error and return early, there's no point trying to find the event in this case. + // Return null as it is falsey and thus should be treated as an error (as the event cannot be resolved). + return null; + } + return this.room.findEventById(eventId); + } + canCollapse() { return this.state.events.length > 1; } From 3e55a456019a5016b5e196ac5da7cd987af7a71b Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 3 May 2018 15:24:41 +0100 Subject: [PATCH 1016/1160] Mock getGroups on MatrixClient for RoomList _makeGroupInviteTiles --- test/test-utils.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/test-utils.js b/test/test-utils.js index e7d3412722..fb21c62170 100644 --- a/test/test-utils.js +++ b/test/test-utils.js @@ -74,6 +74,7 @@ export function createTestClient() { getPushActionsForEvent: sinon.stub(), getRoom: sinon.stub().returns(mkStubRoom()), getRooms: sinon.stub().returns([]), + getGroups: sinon.stub().returns([]), loginFlows: sinon.stub(), on: sinon.stub(), removeListener: sinon.stub(), From 8fcb530e6f677869a5d06b7a5701b231f41174e3 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 3 May 2018 15:25:14 +0100 Subject: [PATCH 1017/1160] Install lolex for clock mocking in tests --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 1f979369e3..146cb86082 100644 --- a/package.json +++ b/package.json @@ -74,6 +74,7 @@ "isomorphic-fetch": "^2.2.1", "linkifyjs": "^2.1.3", "lodash": "^4.13.1", + "lolex": "^2.3.2", "matrix-js-sdk": "0.10.1", "optimist": "^0.6.1", "pako": "^1.0.5", From 80d251b6223077e03c6cbaf85674e4967e6f6730 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 3 May 2018 15:41:35 +0100 Subject: [PATCH 1018/1160] Add tests for optimistic updates of moving room tiles --- test/components/views/rooms/RoomList-test.js | 185 +++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 test/components/views/rooms/RoomList-test.js diff --git a/test/components/views/rooms/RoomList-test.js b/test/components/views/rooms/RoomList-test.js new file mode 100644 index 0000000000..bb92d59201 --- /dev/null +++ b/test/components/views/rooms/RoomList-test.js @@ -0,0 +1,185 @@ +import React from 'react'; +import ReactTestUtils from 'react-addons-test-utils'; +import ReactDOM from 'react-dom'; +import expect from 'expect'; +import lolex from 'lolex'; + +import * as TestUtils from 'test-utils'; + +import sdk from '../../../../src/index'; +import MatrixClientPeg from '../../../../src/MatrixClientPeg'; +import { DragDropContext } from 'react-beautiful-dnd'; + +import dis from '../../../../src/dispatcher'; +import DMRoomMap from '../../../../src/utils/DMRoomMap.js'; + +import { Room, RoomMember } from 'matrix-js-sdk'; + +describe('RoomList', () => { + let parentDiv = null; + let sandbox = null; + let client = null; + let root = null; + const myUserId = '@me:domain'; + let clock = null; + + beforeEach(function() { + TestUtils.beforeEach(this); + sandbox = TestUtils.stubClient(sandbox); + client = MatrixClientPeg.get(); + client.credentials = {userId: myUserId}; + + clock = lolex.install(); + + DMRoomMap.makeShared(); + + parentDiv = document.createElement('div'); + document.body.appendChild(parentDiv); + + const RoomList = sdk.getComponent('views.rooms.RoomList'); + const WrappedRoomList = TestUtils.wrapInMatrixClientContext(RoomList); + root = ReactDOM.render( + + + + , parentDiv); + ReactTestUtils.findRenderedComponentWithType(root, RoomList); + }); + + afterEach((done) => { + if (parentDiv) { + ReactDOM.unmountComponentAtNode(parentDiv); + parentDiv.remove(); + parentDiv = null; + } + sandbox.restore(); + + clock.uninstall(); + + done(); + }); + + describe('when no tags are selected', () => { + describe('does correct optimistic update when dragging from', () => { + const movingRoomId = '!someroomid'; + const movingRoom = new Room(movingRoomId); + + // Mock joined member + const myMember = new RoomMember(movingRoomId, myUserId); + myMember.membership = 'join'; + movingRoom.getMember = (userId) => ({ + [client.credentials.userId]: myMember, + }[userId]); + + function expectRoomInSubList(room, subListTest) { + const RoomSubList = sdk.getComponent('structures.RoomSubList'); + const RoomTile = sdk.getComponent('views.rooms.RoomTile'); + + const subLists = ReactTestUtils.scryRenderedComponentsWithType(root, RoomSubList); + const containingSubList = subLists.find(subListTest); + + let expectedRoomTile; + try { + expectedRoomTile = ReactTestUtils.findRenderedComponentWithType(containingSubList, RoomTile); + } catch (err) { + // truncate the error message because it's spammy + err.message = 'Error finding RoomTile: ' + err.message.split('componentType')[0] + '...'; + throw err; + } + + expect(expectedRoomTile).toExist(); + expect(expectedRoomTile.props.room).toBe(room); + } + + function expectCorrectMove(oldTag, newTag) { + const getTagSubListTest = (tag) => { + if (tag === undefined) return (s) => s.props.label.endsWith('Rooms'); + return (s) => s.props.tagName === tag; + }; + + // Default to finding the destination sublist with newTag + const destSubListTest = getTagSubListTest(newTag); + const srcSubListTest = getTagSubListTest(oldTag); + + // Mock the matrix client + client.getRooms = () => [movingRoom]; + + if (['m.favourite', 'm.lowpriority'].includes(oldTag)) movingRoom.tags = {[oldTag]: {}}; + if (oldTag === 'im.vector.fake.direct') { + // Mock inverse m.direct + DMRoomMap.shared().roomToUser = { + [movingRoom.roomId]: '@someotheruser:domain', + }; + } + + dis.dispatch({action: 'MatrixActions.sync', prevState: null, state: 'PREPARED', matrixClient: client}); + + clock.runAll(); + + expectRoomInSubList(movingRoom, srcSubListTest); + + dis.dispatch({action: 'RoomListActions.tagRoom.pending', request: { + oldTag, newTag, room: movingRoom, + }}); + + // Run all setTimeouts for dispatches and room list rate limiting + clock.runAll(); + + expectRoomInSubList(movingRoom, destSubListTest); + } + + it('rooms to people', () => { + expectCorrectMove(undefined, 'im.vector.fake.direct'); + }); + + it('rooms to favourites', () => { + expectCorrectMove(undefined, 'm.favourite'); + }); + + it('rooms to low priority', () => { + expectCorrectMove(undefined, 'm.lowpriority'); + }); + + // XXX: Known to fail - the view does not update immediately to reflect the change. + // Whe running the app live, it updates when some other event occurs (likely the + // m.direct arriving) that these tests do not fire. + xit('people to rooms', () => { + expectCorrectMove('im.vector.fake.direct', undefined); + }); + + it('people to favourites', () => { + expectCorrectMove('im.vector.fake.direct', 'm.favourite'); + }); + + it('people to lowpriority', () => { + expectCorrectMove('im.vector.fake.direct', 'm.lowpriority'); + }); + + it('low priority to rooms', () => { + expectCorrectMove('m.lowpriority', undefined); + }); + + it('low priority to people', () => { + expectCorrectMove('m.lowpriority', 'im.vector.fake.direct'); + }); + + it('low priority to low priority', () => { + expectCorrectMove('m.lowpriority', 'm.lowpriority'); + }); + + it('favourites to rooms', () => { + expectCorrectMove('m.favourite', undefined); + }); + + it('favourites to people', () => { + expectCorrectMove('m.favourite', 'im.vector.fake.direct'); + }); + + it('favourites to low priority', () => { + expectCorrectMove('m.favourite', 'm.lowpriority'); + }); + }); + }); +}); + + From e15b39092dd70b0ddb7ba3b3d007ec30d406c379 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 3 May 2018 18:04:01 +0100 Subject: [PATCH 1019/1160] Add tests for testing room tile updates when tags (groups in LLP) are selected --- test/components/views/rooms/RoomList-test.js | 244 +++++++++++++------ 1 file changed, 176 insertions(+), 68 deletions(-) diff --git a/test/components/views/rooms/RoomList-test.js b/test/components/views/rooms/RoomList-test.js index bb92d59201..f40a89777b 100644 --- a/test/components/views/rooms/RoomList-test.js +++ b/test/components/views/rooms/RoomList-test.js @@ -12,9 +12,22 @@ import { DragDropContext } from 'react-beautiful-dnd'; import dis from '../../../../src/dispatcher'; import DMRoomMap from '../../../../src/utils/DMRoomMap.js'; +import GroupStore from '../../../../src/stores/GroupStore.js'; import { Room, RoomMember } from 'matrix-js-sdk'; +function generateRoomId() { + return '!' + Math.random().toString().slice(2, 10) + ':domain'; +} + +function createRoom(opts) { + const room = new Room(generateRoomId()); + if (opts) { + Object.assign(room, opts); + } + return room; +} + describe('RoomList', () => { let parentDiv = null; let sandbox = null; @@ -23,6 +36,13 @@ describe('RoomList', () => { const myUserId = '@me:domain'; let clock = null; + const movingRoomId = '!someroomid'; + let movingRoom; + let otherRoom; + + let myMember; + let myOtherMember; + beforeEach(function() { TestUtils.beforeEach(this); sandbox = TestUtils.stubClient(sandbox); @@ -44,6 +64,40 @@ describe('RoomList', () => { , parentDiv); ReactTestUtils.findRenderedComponentWithType(root, RoomList); + + movingRoom = createRoom({name: 'Moving room'}); + expect(movingRoom.roomId).toNotBe(null); + + // Mock joined member + myMember = new RoomMember(movingRoomId, myUserId); + myMember.membership = 'join'; + movingRoom.getMember = (userId) => ({ + [client.credentials.userId]: myMember, + }[userId]); + + otherRoom = createRoom({name: 'Other room'}); + myOtherMember = new RoomMember(otherRoom.roomId, myUserId); + myOtherMember.membership = 'join'; + otherRoom.getMember = (userId) => ({ + [client.credentials.userId]: myOtherMember, + }[userId]); + + // Mock the matrix client + client.getRooms = () => [ + movingRoom, + otherRoom, + createRoom({tags: {'m.favourite': {order: 0.1}}, name: 'Some other room'}), + createRoom({tags: {'m.favourite': {order: 0.2}}, name: 'Some other room 2'}), + createRoom({tags: {'m.lowpriority': {}}, name: 'Some unimportant room'}), + createRoom({tags: {'custom.tag': {}}, name: 'Some room customly tagged'}), + ]; + + const roomMap = {}; + client.getRooms().forEach((r) => { + roomMap[r.roomId] = r; + }); + + client.getRoom = (roomId) => roomMap[roomId]; }); afterEach((done) => { @@ -59,75 +113,68 @@ describe('RoomList', () => { done(); }); - describe('when no tags are selected', () => { + function expectRoomInSubList(room, subListTest) { + const RoomSubList = sdk.getComponent('structures.RoomSubList'); + const RoomTile = sdk.getComponent('views.rooms.RoomTile'); + + const subLists = ReactTestUtils.scryRenderedComponentsWithType(root, RoomSubList); + const containingSubList = subLists.find(subListTest); + + let expectedRoomTile; + try { + const roomTiles = ReactTestUtils.scryRenderedComponentsWithType(containingSubList, RoomTile); + console.info({roomTiles: roomTiles.length}); + expectedRoomTile = roomTiles.find((tile) => tile.props.room === room); + } catch (err) { + // truncate the error message because it's spammy + err.message = 'Error finding RoomTile for ' + room.roomId + ' in ' + + subListTest + ': ' + + err.message.split('componentType')[0] + '...'; + throw err; + } + + expect(expectedRoomTile).toExist(); + expect(expectedRoomTile.props.room).toBe(room); + } + + function expectCorrectMove(oldTag, newTag) { + const getTagSubListTest = (tag) => { + if (tag === undefined) return (s) => s.props.label.endsWith('Rooms'); + return (s) => s.props.tagName === tag; + }; + + // Default to finding the destination sublist with newTag + const destSubListTest = getTagSubListTest(newTag); + const srcSubListTest = getTagSubListTest(oldTag); + + // Set up the room that will be moved such that it has the correct state for a room in + // the section for oldTag + if (['m.favourite', 'm.lowpriority'].includes(oldTag)) movingRoom.tags = {[oldTag]: {}}; + if (oldTag === 'im.vector.fake.direct') { + // Mock inverse m.direct + DMRoomMap.shared().roomToUser = { + [movingRoom.roomId]: '@someotheruser:domain', + }; + } + + dis.dispatch({action: 'MatrixActions.sync', prevState: null, state: 'PREPARED', matrixClient: client}); + + clock.runAll(); + + expectRoomInSubList(movingRoom, srcSubListTest); + + dis.dispatch({action: 'RoomListActions.tagRoom.pending', request: { + oldTag, newTag, room: movingRoom, + }}); + + // Run all setTimeouts for dispatches and room list rate limiting + clock.runAll(); + + expectRoomInSubList(movingRoom, destSubListTest); + } + + function itDoesCorrectOptimisticUpdatesForDraggedRoomTiles() { describe('does correct optimistic update when dragging from', () => { - const movingRoomId = '!someroomid'; - const movingRoom = new Room(movingRoomId); - - // Mock joined member - const myMember = new RoomMember(movingRoomId, myUserId); - myMember.membership = 'join'; - movingRoom.getMember = (userId) => ({ - [client.credentials.userId]: myMember, - }[userId]); - - function expectRoomInSubList(room, subListTest) { - const RoomSubList = sdk.getComponent('structures.RoomSubList'); - const RoomTile = sdk.getComponent('views.rooms.RoomTile'); - - const subLists = ReactTestUtils.scryRenderedComponentsWithType(root, RoomSubList); - const containingSubList = subLists.find(subListTest); - - let expectedRoomTile; - try { - expectedRoomTile = ReactTestUtils.findRenderedComponentWithType(containingSubList, RoomTile); - } catch (err) { - // truncate the error message because it's spammy - err.message = 'Error finding RoomTile: ' + err.message.split('componentType')[0] + '...'; - throw err; - } - - expect(expectedRoomTile).toExist(); - expect(expectedRoomTile.props.room).toBe(room); - } - - function expectCorrectMove(oldTag, newTag) { - const getTagSubListTest = (tag) => { - if (tag === undefined) return (s) => s.props.label.endsWith('Rooms'); - return (s) => s.props.tagName === tag; - }; - - // Default to finding the destination sublist with newTag - const destSubListTest = getTagSubListTest(newTag); - const srcSubListTest = getTagSubListTest(oldTag); - - // Mock the matrix client - client.getRooms = () => [movingRoom]; - - if (['m.favourite', 'm.lowpriority'].includes(oldTag)) movingRoom.tags = {[oldTag]: {}}; - if (oldTag === 'im.vector.fake.direct') { - // Mock inverse m.direct - DMRoomMap.shared().roomToUser = { - [movingRoom.roomId]: '@someotheruser:domain', - }; - } - - dis.dispatch({action: 'MatrixActions.sync', prevState: null, state: 'PREPARED', matrixClient: client}); - - clock.runAll(); - - expectRoomInSubList(movingRoom, srcSubListTest); - - dis.dispatch({action: 'RoomListActions.tagRoom.pending', request: { - oldTag, newTag, room: movingRoom, - }}); - - // Run all setTimeouts for dispatches and room list rate limiting - clock.runAll(); - - expectRoomInSubList(movingRoom, destSubListTest); - } - it('rooms to people', () => { expectCorrectMove(undefined, 'im.vector.fake.direct'); }); @@ -179,6 +226,67 @@ describe('RoomList', () => { expectCorrectMove('m.favourite', 'm.lowpriority'); }); }); + } + + describe('when no tags are selected', () => { + itDoesCorrectOptimisticUpdatesForDraggedRoomTiles(); + }); + + describe('when tags are selected', () => { + function setupSelectedTag() { + // Simulate a complete sync BEFORE dispatching anything else + dis.dispatch({ + action: 'MatrixActions.sync', + prevState: null, + state: 'PREPARED', + matrixClient: client, + }, true); + + // Simulate joined groups being received + dis.dispatch({ + action: 'GroupActions.fetchJoinedGroups.success', + result: { + groups: ['+group:domain'], + }, + }, true); + + // Simulate receiving tag ordering account data + dis.dispatch({ + action: 'MatrixActions.accountData', + event_type: 'im.vector.web.tag_ordering', + event_content: { + tags: ['+group:domain'], + }, + }, true); + + // GroupStore is not flux, mock and notify + GroupStore.getGroupRooms = (groupId) => { + return [movingRoom]; + }; + GroupStore._notifyListeners(); + + // Select tag + dis.dispatch({action: 'select_tag', tag: '+group:domain'}, true); + } + + beforeEach(() => { + setupSelectedTag(); + }); + + it('displays the correct rooms when the groups rooms are changed', () => { + GroupStore.getGroupRooms = (groupId) => { + return [movingRoom, otherRoom]; + }; + GroupStore._notifyListeners(); + + // Run through RoomList debouncing + clock.runAll(); + + // By default, the test will + expectRoomInSubList(otherRoom, (s) => s.props.label.endsWith('Rooms')); + }); + + itDoesCorrectOptimisticUpdatesForDraggedRoomTiles(); }); }); From c06a04af97de05698e6e15773843c0c237deafd7 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 3 May 2018 18:11:32 +0100 Subject: [PATCH 1020/1160] Fix unrelated linting issue --- test/components/structures/GroupView-test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/components/structures/GroupView-test.js b/test/components/structures/GroupView-test.js index 76baafe1c8..3b3510f26e 100644 --- a/test/components/structures/GroupView-test.js +++ b/test/components/structures/GroupView-test.js @@ -18,7 +18,6 @@ import React from 'react'; import ReactDOM from 'react-dom'; import ReactTestUtils from 'react-dom/test-utils'; import expect from 'expect'; -import Promise from 'bluebird'; import MockHttpBackend from 'matrix-mock-request'; import MatrixClientPeg from '../../../src/MatrixClientPeg'; From 3ba51ba69586f9a015fdb5dc265445ca0b22ad2c Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 3 May 2018 18:25:00 +0100 Subject: [PATCH 1021/1160] Null check before accessing _paq --- src/Analytics.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Analytics.js b/src/Analytics.js index 0d1313f48d..ec8234eb83 100644 --- a/src/Analytics.js +++ b/src/Analytics.js @@ -164,13 +164,6 @@ class Analytics { } trackPageChange(generationTimeMs) { - if (typeof generationTimeMs === 'number') { - this._paq.push(['setGenerationTimeMs', generationTimeMs]); - } else { - console.warn('Analytics.trackPageChange: expected generationTimeMs to be a number'); - // But continue anyway because we still want to track the change - } - if (this.disabled) return; if (this.firstPage) { // De-duplicate first page @@ -178,6 +171,14 @@ class Analytics { this.firstPage = false; return; } + + if (typeof generationTimeMs === 'number') { + this._paq.push(['setGenerationTimeMs', generationTimeMs]); + } else { + console.warn('Analytics.trackPageChange: expected generationTimeMs to be a number'); + // But continue anyway because we still want to track the change + } + this._paq.push(['setCustomUrl', getRedactedUrl()]); this._paq.push(['trackPageView']); } From 91a68822ed8ea96e6f0416228c9a671f627e469c Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Thu, 3 May 2018 23:54:47 +0000 Subject: [PATCH 1022/1160] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (1174 of 1174 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hant/ --- src/i18n/strings/zh_Hant.json | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 883252821d..4279ac4bfa 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -1158,5 +1158,23 @@ "Checking for an update...": "正在檢查更新...", "There are advanced notifications which are not shown here": "有些進階的通知並未在此顯示", "Missing roomId.": "缺少 roomid。", - "Picture": "圖片" + "Picture": "圖片", + "Every page you use in the app": "您在應用程式內使用的每一頁", + "e.g. ": "範例:", + "Your User Agent": "您的使用者代理字串", + "Your device resolution": "您的裝置解析度", + "Always show encryption icons": "總是顯示加密圖示", + "At this time it is not possible to reply with a file so this will be sent without being a reply.": "目前無法使用檔案回覆,所以這次傳送並不會以回覆的形式出現。", + "Unable to reply": "無法回覆", + "At this time it is not possible to reply with an emote.": "目前無法使用表情符號回覆。", + "Popout widget": "彈出式小工具", + "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "無法載入要回覆的活動,它可能不存在或是您沒有權限檢視它。", + "Riot bugs are tracked on GitHub: create a GitHub issue.": "Riot 的臭蟲在 GitHub 上追蹤", + "Log out and remove encryption keys?": "登出或移除加密金鑰?", + "Send Logs": "傳送紀錄", + "Clear Storage and Sign Out": "清除儲存的東西並登出", + "Refresh": "重新整理", + "We encountered an error trying to restore your previous session.": "我們在嘗試復原您先前的工作階段時遇到了一點錯誤。", + "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "清除您瀏覽器的儲存的東西也許可以修復問題,但會將您登出並造成任何已加密的聊天都無法讀取。", + "Collapse Reply Thread": "摺疊回覆討論串" } From 5691b7859175a337f00b7330ed69cfb2a72101d5 Mon Sep 17 00:00:00 2001 From: RainSlide Date: Fri, 4 May 2018 04:14:04 +0000 Subject: [PATCH 1023/1160] Translated using Weblate (Chinese (Simplified)) Currently translated at 97.7% (1148 of 1174 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hans/ --- src/i18n/strings/zh_Hans.json | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index 96d4302b90..a8f6e419bb 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -365,7 +365,7 @@ "Unverify": "取消验证", "ex. @bob:example.com": "例如 @bob:example.com", "Add User": "添加用户", - "This Home Server would like to make sure you are not a robot": "此主服务器想确认你不是机器人", + "This Home Server would like to make sure you are not a robot": "此主服务器想确保您不是机器人", "Token incorrect": "令牌错误", "Default server": "默认服务器", "Custom server": "自定义服务器", @@ -601,7 +601,7 @@ "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s 删除了他们的昵称 (%(oldDisplayName)s).", "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "您提供的签名密钥和你从 %(userId)s 的设备 %(deviceId)s 收到的签名密钥匹配。设备被标记为已验证。", "These are experimental features that may break in unexpected ways": "这些是可能以意外的方式坏掉的实验性的特性", - "The visibility of existing history will be unchanged": "现有历史记录的可见性不会被改变", + "The visibility of existing history will be unchanged": "现有历史记录的可见性不会改变", "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s 打开了端到端加密 (算法 %(algorithm)s).", "Unable to remove contact information": "无法移除联系人信息", "Riot collects anonymous analytics to allow us to improve the application.": "Riot 收集匿名的分析数据来允许我们改善这个应用。", @@ -751,7 +751,7 @@ "Add to community": "添加到社区", "Failed to invite users to community": "邀请用户到社区失败", "Message Replies": "消息回复", - "Disable Peer-to-Peer for 1:1 calls": "在1:1通话中禁用点到点", + "Disable Peer-to-Peer for 1:1 calls": "在一对一通话中禁用 P2P 对等网络", "Enable inline URL previews by default": "默认启用网址预览", "Disinvite this user?": "取消邀请此用户?", "Kick this user?": "移除此用户?", @@ -1134,5 +1134,24 @@ "Missing roomId.": "找不到此聊天室 ID 所对应的聊天室。", "Tag Panel": "标签面板", "You have been banned from %(roomName)s by %(userName)s.": "您已被 %(userName)s 从聊天室 %(roomName)s 中封禁。", - "You have been banned from this room by %(userName)s.": "您已被 %(userName)s 从此聊天室中封禁。" + "You have been banned from this room by %(userName)s.": "您已被 %(userName)s 从此聊天室中封禁。", + "Every page you use in the app": "您在 Riot 中使用的每一个页面", + "e.g. ": "例如:", + "Your User Agent": "您的 User Agent", + "Your device resolution": "您设备的分辨率", + "Must be viewing a room": "必须是在查看一个聊天室时", + "Always show encryption icons": "总是显示加密标志", + "At this time it is not possible to reply with a file so this will be sent without being a reply.": "目前无法以文件作为回复的内容,所以此文件将不作为回复,独立发送。", + "Unable to reply": "无法回复", + "At this time it is not possible to reply with an emote.": "目前无法使用表情符号作为回复内容。", + "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?": "您将被带到一个第三方网站以便验证您的账号以使用 %(integrationsUrl)s 提供的集成。您希望继续吗?", + "Robot check is currently unavailable on desktop - please use a web browser": "目前机器人检查(CAPTCHA)在桌面端不可用——请使用 浏览器", + "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "无法更新聊天室 %(roomName)s 在社区 “%(groupId)s” 中的可见性。", + "Minimize apps": "最小化小部件", + "Popout widget": "在弹出式窗口中打开小部件", + "Picture": "图片", + "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "无法加载被回复的事件,它可能不存在,也可能是您没有权限查看它。", + "And %(count)s more...|other": "和 %(count)s 个其他…", + "Try using one of the following valid address types: %(validTypesList)s.": "请尝试使用以下的有效邮箱地址格式中的一种:%(validTypesList)s", + "Riot bugs are tracked on GitHub: create a GitHub issue.": "Riot 使用 GitHub 追踪 bug:在 GitHub 上创建新 Issue" } From d4f4ebae140546208e231f9d8d389c2494f51586 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Thu, 3 May 2018 23:55:48 +0000 Subject: [PATCH 1024/1160] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (1174 of 1174 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hant/ --- src/i18n/strings/zh_Hant.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 4279ac4bfa..6f5ef68735 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -1169,7 +1169,7 @@ "At this time it is not possible to reply with an emote.": "目前無法使用表情符號回覆。", "Popout widget": "彈出式小工具", "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "無法載入要回覆的活動,它可能不存在或是您沒有權限檢視它。", - "Riot bugs are tracked on GitHub: create a GitHub issue.": "Riot 的臭蟲在 GitHub 上追蹤", + "Riot bugs are tracked on GitHub: create a GitHub issue.": "Riot 的臭蟲在 GitHub 上追蹤:在 GitHub 上建立議題。", "Log out and remove encryption keys?": "登出或移除加密金鑰?", "Send Logs": "傳送紀錄", "Clear Storage and Sign Out": "清除儲存的東西並登出", From 224e905cae693399c20871638bde8fb9f06fd51f Mon Sep 17 00:00:00 2001 From: Kenneth Larsson Date: Thu, 3 May 2018 23:28:34 +0000 Subject: [PATCH 1025/1160] Translated using Weblate (Swedish) Currently translated at 55.3% (650 of 1174 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sv/ --- src/i18n/strings/sv.json | 91 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/sv.json b/src/i18n/strings/sv.json index c55ee40cba..4a2a5f76cc 100644 --- a/src/i18n/strings/sv.json +++ b/src/i18n/strings/sv.json @@ -16,7 +16,7 @@ "Default Device": "Standardenhet", "Microphone": "Mikrofon", "Camera": "Kamera", - "Advanced": "Avancerad", + "Advanced": "Avancerat", "Algorithm": "Algoritm", "Always show message timestamps": "Visa alltid tidsstämpel för meddelanden", "Hide removed messages": "Göm raderade meddelanden", @@ -147,7 +147,7 @@ "Access Token:": "Åtkomsttoken:", "Active call (%(roomName)s)": "Aktiv samtal (%(roomName)s)", "Add": "Lägg till", - "Admin Tools": "Admin verktyg", + "Admin Tools": "Admin-verktyg", "Alias (optional)": "Alias (valfri)", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Det gick inte att ansluta till servern - kontrollera anslutningen, försäkra att din hemservers TLS-certifikat är betrott, och att inget webbläsartillägg blockerar förfrågningar.", "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s ändrade maktnivån av %(powerLevelDiffText)s.", @@ -565,5 +565,90 @@ "Collapse panel": "Kollapsa panel", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Med din nuvarande webbläsare kan appens utseende vara helt fel, och vissa eller alla egenskaper kommer nödvändigtvis inte att fungera. Om du ändå vill försöka så kan du fortsätta, men gör det på egen risk!", "Checking for an update...": "Letar efter uppdateringar...", - "There are advanced notifications which are not shown here": "Det finns avancerade aviseringar som inte visas här" + "There are advanced notifications which are not shown here": "Det finns avancerade aviseringar som inte visas här", + "Who can access this room?": "Vilka kan komma åt detta rum?", + "Who can read history?": "Vilka kan läsa historik?", + "Members only (since the point in time of selecting this option)": "Endast medlemmar (från tidpunkten för när denna inställning valdes)", + "Members only (since they were invited)": "Endast medlemmar (från när de blev inbjudna)", + "Members only (since they joined)": "Endast medlemmar (från när de gick med)", + "This room's internal ID is": "Rummets interna ID är", + "Addresses": "Adresser", + "This room has no local addresses": "Det här rummet har inga lokala adresser", + "Updates": "Uppdateringar", + "Check for update": "Leta efter uppdatering", + "Your language of choice": "Ditt valda språk", + "The platform you're on": "Plattformen du använder", + "Whether or not you're logged in (we don't record your user name)": "Om du är inloggad eller inte (vi sparar inte ditt användarnamn)", + "Your homeserver's URL": "Din hemservers URL", + "Your identity server's URL": "Din identitetsservers URL", + "Every page you use in the app": "Varje sida du använder i appen", + "Whether or not you're using the Richtext mode of the Rich Text Editor": "Om du använder Richtext-läget i Rich-Text-editorn eller inte", + "e.g. ": "t.ex. ", + "Your User Agent": "Din användaragent", + "Your device resolution": "Din enhetsupplösning", + "You cannot place VoIP calls in this browser.": "Du kan inte ringa VoIP-samtal i den här webbläsaren.", + "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Din epostadress verkar inte vara kopplad till något Matrix-ID på den här hemservern.", + "Restricted": "Begränsad", + "Who would you like to communicate with?": "Vem vill du kommunicera med?", + "Failed to invite the following users to the %(roomName)s room:": "Misslyckades med att bjuda in följande användare till %(roomName)s-rummet:", + "Unable to create widget.": "Det går inte att skapa widget.", + "Ignored user": "Ignorerad användare", + "You are now ignoring %(userId)s": "Du ignorerar nu %(userId)s", + "Unignored user": "Oignorerad användare", + "You are no longer ignoring %(userId)s": "Du ignorerar inte längre %(userId)s", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s bytte sitt visningsnamn till %(displayName)s.", + "%(senderName)s unbanned %(targetName)s.": "%(senderName)s avbannade %(targetName)s.", + "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s drog tillbaka inbjudan för %(targetName)s.", + "(no answer)": "(inget svar)", + "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s-widget har modifierats av %(senderName)s", + "%(widgetName)s widget added by %(senderName)s": "%(widgetName)s-widget har lagts till av %(senderName)s", + "%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s-widget har tagits bort av %(senderName)s", + "%(names)s and %(count)s others are typing|other": "%(names)s och %(count)s andra skriver", + "%(names)s and %(count)s others are typing|one": "%(names)s och en till skriver", + "Unnamed Room": "Namnlöst rum", + "Your browser does not support the required cryptography extensions": "Din webbläsare stödjer inte nödvändiga kryptografitillägg", + "Invite": "Bjud in", + "Unignore": "Ignorera inte", + "Ignore": "Ignorera", + "Jump to message": "Hoppa till meddelande", + "Mention": "Nämn", + "Make Moderator": "Gör till moderator", + "Upload Files": "Ladda upp filer", + "Unencrypted room": "Okrypterat rum", + "Voice call": "Röstsamtal", + "Video call": "Videosamtal", + "Upload file": "Ladda upp fil", + "Send an encrypted reply…": "Skicka ett krypterat svar…", + "Send a reply (unencrypted)…": "Skicka ett svar (okrypterat)…", + "Send an encrypted message…": "Skicka ett krypterat meddelande…", + "Send a message (unencrypted)…": "Skicka ett meddelande (okrypterat)…", + "You do not have permission to post to this room": "Du har inte behörighet att posta till detta rum", + "Turn Markdown on": "Sätt på Markdown", + "Turn Markdown off": "Stäng av Markdown", + "Unable to reply": "Det gick inte att svara", + "bold": "fet", + "italic": "kursiv", + "strike": "genomstruken", + "underline": "understruken", + "code": "kod", + "quote": "citat", + "bullet": "punkter", + "numbullet": "numrering", + "Loading...": "Laddar...", + "%(duration)ss": "%(duration)s", + "%(duration)sm": "%(duration)sm", + "%(duration)sh": "%(duration)sh", + "%(duration)sd": "%(duration)sd", + "Online for %(duration)s": "Aktiv i %(duration)s", + "Idle for %(duration)s": "Inaktiv i %(duration)s", + "Offline for %(duration)s": "Offline i %(duration)s", + "Idle": "Inaktiv", + "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Sedd av %(displayName)s (%(userName)s) %(dateTime)s", + "Offline": "Offline", + "(~%(count)s results)|other": "(~%(count)s resultat)", + "(~%(count)s results)|one": "(~%(count)s resultat)", + "Upload avatar": "Ladda upp profilbild", + "Remove avatar": "Ta bort profilbild", + "This invitation was sent to an email address which is not associated with this account:": "Den här inbjudan skickades till en emailadress som inte är kopplad till detta konto:", + "To link to a room it must have an address.": "För att länka till ett rum behöver det en adress." } From 14bcfdd5c60a3dfe069c468c64164ed5ba0065f7 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 5 May 2018 22:08:37 +0100 Subject: [PATCH 1026/1160] fix NPE --- src/components/views/messages/MImageBody.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index a42e45c55d..b50b7a114c 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -161,7 +161,10 @@ export default class extends React.Component { return this.state.decryptedThumbnailUrl; } return this.state.decryptedUrl; - } else if (content.info.mimetype == "image/svg+xml" && content.info.thumbnail_url) { + } else if (content.info && + content.info.mimetype == "image/svg+xml" && + content.info.thumbnail_url) + { // special case to return client-generated thumbnails for SVGs, if any, // given we deliberately don't thumbnail them serverside to prevent // billion lol attacks and similar From ccd99f4a49105359de874af0a3aafd6cddeea31c Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 5 May 2018 22:27:54 +0100 Subject: [PATCH 1027/1160] increase max-warnings temporarily --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index aad9739770..b0f0d26c56 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "start": "parallelshell \"npm run build:watch\" \"npm run reskindex:watch\"", "lint": "eslint src/", "lintall": "eslint src/ test/", - "lintwithexclusions": "eslint --max-warnings 10 --ignore-path .eslintignore.errorfiles src test", + "lintwithexclusions": "eslint --max-warnings 20 --ignore-path .eslintignore.errorfiles src test", "clean": "rimraf lib", "prepublish": "npm run clean && npm run build && git rev-parse HEAD > git-revision.txt", "test": "karma start --single-run=true --browsers ChromeHeadless", From af5be5c36c518627fa40342818efec1e0dd1e938 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 5 May 2018 22:28:09 +0100 Subject: [PATCH 1028/1160] appease the fascist linter --- src/components/views/messages/MImageBody.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index b50b7a114c..6cc492acf8 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -163,8 +163,7 @@ export default class extends React.Component { return this.state.decryptedUrl; } else if (content.info && content.info.mimetype == "image/svg+xml" && - content.info.thumbnail_url) - { + content.info.thumbnail_url) { // special case to return client-generated thumbnails for SVGs, if any, // given we deliberately don't thumbnail them serverside to prevent // billion lol attacks and similar From 500f58a963e0a7cde329ba3a21d79b129f7d42f8 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 5 May 2018 23:25:50 +0100 Subject: [PATCH 1029/1160] fix deeply irritating react warning about viewAvatarOnClick on BaseAvatar --- src/components/views/avatars/RoomAvatar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/avatars/RoomAvatar.js b/src/components/views/avatars/RoomAvatar.js index 499e575227..e37d8d5d19 100644 --- a/src/components/views/avatars/RoomAvatar.js +++ b/src/components/views/avatars/RoomAvatar.js @@ -177,7 +177,7 @@ module.exports = React.createClass({ render: function() { const BaseAvatar = sdk.getComponent("avatars.BaseAvatar"); - const {room, oobData, ...otherProps} = this.props; + const {room, oobData, viewAvatarOnClick, ...otherProps} = this.props; const roomName = room ? room.name : oobData.name; From 8a1bd8da69d7eeb5c31ab34b34640e6ed2fc5069 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 6 May 2018 00:22:14 +0100 Subject: [PATCH 1030/1160] tell eslint to ignore viewAvatarOnClick being unused --- src/components/views/avatars/RoomAvatar.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/views/avatars/RoomAvatar.js b/src/components/views/avatars/RoomAvatar.js index e37d8d5d19..821448207f 100644 --- a/src/components/views/avatars/RoomAvatar.js +++ b/src/components/views/avatars/RoomAvatar.js @@ -177,6 +177,7 @@ module.exports = React.createClass({ render: function() { const BaseAvatar = sdk.getComponent("avatars.BaseAvatar"); + /*eslint no-unused-vars: ["error", { "ignoreRestSiblings": true }]*/ const {room, oobData, viewAvatarOnClick, ...otherProps} = this.props; const roomName = room ? room.name : oobData.name; From f68036a4fb30c0bf067a08365ae86d5e0db1ccdd Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 6 May 2018 19:18:41 +0100 Subject: [PATCH 1031/1160] Replies: un-break click-to-mention on SenderProfile for reply&preview Fixes #6670 Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/EventTile.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index bfcf8ac9d4..b92504d0f1 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -556,11 +556,14 @@ module.exports = withMatrixClient(React.createClass({ if (needsSenderProfile) { let text = null; - if (!this.props.tileShape) { + if (!this.props.tileShape || this.props.tileShape === 'reply' || this.props.tileShape === 'reply_preview') { if (msgtype === 'm.image') text = _td('%(senderName)s sent an image'); else if (msgtype === 'm.video') text = _td('%(senderName)s sent a video'); else if (msgtype === 'm.file') text = _td('%(senderName)s uploaded a file'); - sender = ; + sender = ; } else { sender = ; } From f0b7fd58b950ae8072862fe868225e6d36fbb0f0 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 6 May 2018 19:28:18 +0100 Subject: [PATCH 1032/1160] delint Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/EventTile.js | 30 +++++++++++-------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index b92504d0f1..589524bb9e 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -202,17 +202,12 @@ module.exports = withMatrixClient(React.createClass({ return true; } - if (!this._propsEqual(this.props, nextProps)) { - return true; - } - - return false; + return !this._propsEqual(this.props, nextProps); }, componentWillUnmount: function() { const client = this.props.matrixClient; - client.removeListener("deviceVerificationChanged", - this.onDeviceVerificationChanged); + client.removeListener("deviceVerificationChanged", this.onDeviceVerificationChanged); this.props.mxEvent.removeListener("Event.decrypted", this._onDecrypted); }, @@ -227,7 +222,7 @@ module.exports = withMatrixClient(React.createClass({ }, onDeviceVerificationChanged: function(userId, device) { - if (userId == this.props.mxEvent.getSender()) { + if (userId === this.props.mxEvent.getSender()) { this._verifyEvent(this.props.mxEvent); } }, @@ -262,7 +257,7 @@ module.exports = withMatrixClient(React.createClass({ } // need to deep-compare readReceipts - if (key == 'readReceipts') { + if (key === 'readReceipts') { const rA = objA[key]; const rB = objB[key]; if (rA === rB) { @@ -336,7 +331,7 @@ module.exports = withMatrixClient(React.createClass({ getReadAvatars: function() { // return early if there are no read receipts if (!this.props.readReceipts || this.props.readReceipts.length === 0) { - return (); + return (); } const ReadReceiptMarker = sdk.getComponent('rooms.ReadReceiptMarker'); @@ -360,7 +355,7 @@ module.exports = withMatrixClient(React.createClass({ left = (hidden ? MAX_READ_AVATARS - 1 : i) * -receiptOffset; const userId = receipt.roomMember.userId; - var readReceiptInfo; + let readReceiptInfo; if (this.props.readReceiptMap) { readReceiptInfo = this.props.readReceiptMap[userId]; @@ -502,17 +497,17 @@ module.exports = withMatrixClient(React.createClass({ mx_EventTile: true, mx_EventTile_info: isInfoMessage, mx_EventTile_12hr: this.props.isTwelveHour, - mx_EventTile_encrypting: this.props.eventSendStatus == 'encrypting', + mx_EventTile_encrypting: this.props.eventSendStatus === 'encrypting', mx_EventTile_sending: isSending, - mx_EventTile_notSent: this.props.eventSendStatus == 'not_sent', - mx_EventTile_highlight: this.props.tileShape == 'notif' ? false : this.shouldHighlight(), + mx_EventTile_notSent: this.props.eventSendStatus === 'not_sent', + mx_EventTile_highlight: this.props.tileShape === 'notif' ? false : this.shouldHighlight(), mx_EventTile_selected: this.props.isSelectedEvent, mx_EventTile_continuation: this.props.tileShape ? '' : this.props.continuation, mx_EventTile_last: this.props.last, mx_EventTile_contextual: this.props.contextual, menu: this.state.menu, - mx_EventTile_verified: this.state.verified == true, - mx_EventTile_unverified: this.state.verified == false, + mx_EventTile_verified: this.state.verified === true, + mx_EventTile_unverified: this.state.verified === false, mx_EventTile_bad: isEncryptionFailure, mx_EventTile_emote: msgtype === 'm.emote', mx_EventTile_redacted: isRedacted, @@ -522,7 +517,8 @@ module.exports = withMatrixClient(React.createClass({ const readAvatars = this.getReadAvatars(); - let avatar, sender; + let avatar; + let sender; let avatarSize; let needsSenderProfile; From afb9e1f5f4af7bb502f4813ee81e49dddc2a54d9 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 8 May 2018 09:49:53 +0100 Subject: [PATCH 1033/1160] blind fix to the overlapping sticker bug --- src/components/views/messages/MStickerBody.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/views/messages/MStickerBody.js b/src/components/views/messages/MStickerBody.js index 08ddb6de20..501db5e22b 100644 --- a/src/components/views/messages/MStickerBody.js +++ b/src/components/views/messages/MStickerBody.js @@ -40,6 +40,7 @@ export default class MStickerBody extends MImageBody { } _onImageLoad() { + this.fixupHeight(); this.setState({ placeholderClasses: 'mx_MStickerBody_placeholder_invisible', }); From 03c7b7ef65b5a2c5053f79f776ec263f5dd75dc5 Mon Sep 17 00:00:00 2001 From: RainSlide Date: Tue, 8 May 2018 03:51:50 +0000 Subject: [PATCH 1034/1160] Translated using Weblate (Chinese (Simplified)) Currently translated at 97.7% (1148 of 1174 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hans/ --- src/i18n/strings/zh_Hans.json | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index a8f6e419bb..2bbb5b1cc8 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -33,7 +33,7 @@ "Error": "错误", "Error decrypting attachment": "解密附件时出错", "Event information": "事件信息", - "Existing Call": "现有通话", + "Existing Call": "当前通话", "Export E2E room keys": "导出聊天室的端到端加密密钥", "Failed to ban user": "封禁用户失败", "Failed to change password. Is your password correct?": "修改密码失败。确认原密码输入正确吗?", @@ -461,7 +461,7 @@ "Please check your email and click on the link it contains. Once this is done, click continue.": "请检查你的电子邮箱并点击里面包含的链接。完成时请点击继续。", "Press to start a chat with someone": "按下 来开始和某个人聊天", "%(senderName)s removed their profile picture.": "%(senderName)s 移除了他们的头像。", - "%(senderName)s requested a VoIP conference.": "%(senderName)s 请求一次 VoIP 会议。", + "%(senderName)s requested a VoIP conference.": "%(senderName)s 已请求发起 VoIP 会议。", "Seen by %(userName)s at %(dateTime)s": "在 %(dateTime)s 被 %(userName)s 看到", "Tagged as: ": "标记为: ", "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "验证码将发送至 +%(msisdn)s,请输入收到的验证码", @@ -487,7 +487,7 @@ "Start authentication": "开始认证", "The maximum permitted number of widgets have already been added to this room.": "小部件的最大允许数量已经添加到这个聊天室了。", "The phone number entered looks invalid": "输入的手机号码看起来无效", - "The remote side failed to pick up": "远端未能接收到", + "The remote side failed to pick up": "对方未能接听", "This Home Server does not support login using email address.": "HS不支持使用邮箱地址登陆。", "This invitation was sent to an email address which is not associated with this account:": "此邀请被发送到与此帐户不相关的邮箱地址:", "This room is not recognised.": "无法识别此聊天室。", @@ -509,7 +509,7 @@ "Who can access this room?": "谁可以访问这个聊天室?", "Who would you like to add to this room?": "你想把谁加入这个聊天室?", "Who would you like to communicate with?": "你想和谁交流?", - "You are already in a call.": "你已经在一个通话之中。", + "You are already in a call.": "您正在通话。", "You do not have permission to do that in this room.": "你没有权限在这个聊天室里面做那件事。", "You are trying to access %(roomName)s.": "你正在尝试访问 %(roomName)s.", "You cannot place VoIP calls in this browser.": "你不能在这个浏览器中发起 VoIP 通话。", @@ -567,7 +567,7 @@ "(~%(count)s results)|other": "(~%(count)s 个结果)", "Please select the destination room for this message": "请选择这条消息的目标聊天室", "Start automatically after system login": "在系统登录后自动启动", - "Analytics": "分析", + "Analytics": "统计分析服务", "Reject all %(invitedRooms)s invites": "拒绝所有 %(invitedRooms)s 邀请", "You may wish to login with a different account, or add this email to this account.": "你可能希望用另外一个账户登录,或者添加这个电子邮件到这个账户上。", "Sun": "星期日", @@ -634,10 +634,10 @@ "Unpin Message": "取消置顶消息", "Add rooms to this community": "添加聊天室到此社区", "Call Failed": "呼叫失败", - "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "聊天室里有未知设备:如果你不检查它们而继续,可能有人窃听你的通话。", + "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "聊天室中有未知设备:如果您在不验证它们的情况下继续,您的通话可能会被人窃听。", "Review Devices": "复查设备", - "Call Anyway": "无论如何呼叫", - "Answer Anyway": "无论如何接听", + "Call Anyway": "仍然呼叫", + "Answer Anyway": "仍然接听", "Call": "呼叫", "Answer": "接听", "Invite new community members": "邀请新社区成员", @@ -979,7 +979,7 @@ "A new version of Riot is available.": "Riot 有更新可用。", "Couldn't load home page": "不能加载首页", "Send Account Data": "发送账户数据", - "All notifications are currently disabled for all targets.": "当前所有目标的通知均已禁用。", + "All notifications are currently disabled for all targets.": "目前所有通知都已禁用。", "Uploading report": "上传报告", "Sunday": "星期日", "Notification targets": "通知目标", @@ -1034,11 +1034,11 @@ "Delete the room alias %(alias)s and remove %(name)s from the directory?": "确定要删除聊天室别名 %(alias)s 并将 %(name)s 从列表中删除吗?", "This will allow you to return to your account after signing out, and sign in on other devices.": "这将允许你可以在注销后回到您的账号,并在其他设备上登录。", "Keywords": "关键词", - "Enable notifications for this account": "为本账号启用通知", + "Enable notifications for this account": "对此账号启用通知", "Directory": "聊天室目录", "Invite to this community": "邀请加入此社区", "Failed to get public room list": "无法取得公开的聊天室列表", - "Messages containing keywords": "消息包含 关键词", + "Messages containing keywords": "包含 关键词 的消息", "Room not found": "找不到聊天室", "Tuesday": "星期二", "Enter keywords separated by a comma:": "输入以逗号间隔的关键词:", @@ -1080,7 +1080,7 @@ "State Key": "状态密钥", "Failed to send custom event.": "自定义事件发送失败。", "What's new?": "有什么新闻?", - "Notify me for anything else": "所有消息都通知我", + "Notify me for anything else": "通知所有消息", "When I'm invited to a room": "当我被邀请进入聊天室", "Click here to create a GitHub issue.": "点击这里 创建一个 GitHub issue.", "Can't update user notification settings": "不能更新用户通知设置", From 961dc11a703b67738af2120fa3995a629207f873 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Mon, 7 May 2018 12:21:26 +0000 Subject: [PATCH 1035/1160] Translated using Weblate (Hungarian) Currently translated at 100.0% (1174 of 1174 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 6ec430147c..c2b8af12ee 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -11,7 +11,7 @@ "Notifications": "Értesítések", "Operation failed": "Sikertelen művelet", "powered by Matrix": "Matrix hajtja", - "Remove": "Eltávolítás", + "Remove": "Kitakarás", "Settings": "Beállítások", "unknown error code": "ismeretlen hibakód", "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Elküldtük a szöveges üzenetet ide: +%(msisdn)s. Kérlek add meg az ellenőrző kódot ami benne van", @@ -702,7 +702,7 @@ "To configure the room, you must be a": "A szoba beállításához ilyen szinten kell lenned:", "To kick users, you must be a": "Felhasználó kirúgásához ilyen szinten kell lenned:", "To ban users, you must be a": "Felhasználó kizárásához ilyen szinten kell lenned:", - "To remove other users' messages, you must be a": "Más üzenetének a törléséhez ilyen szinten kell lenned:", + "To remove other users' messages, you must be a": "Más üzenetének a kitakarásához ilyen szinten kell lenned:", "To send events of type , you must be a": " esemény küldéséhez ilyen szinten kell lenned:", "To change the room's avatar, you must be a": "A szoba avatarjának a megváltoztatásához ilyen szinten kell lenned:", "To change the room's name, you must be a": "A szoba nevének megváltoztatásához ilyen szinten kell lenned:", From f76191b0a2445bafdd69ee330158c4c0a327d150 Mon Sep 17 00:00:00 2001 From: strix aluco Date: Mon, 7 May 2018 17:13:56 +0000 Subject: [PATCH 1036/1160] Translated using Weblate (Ukrainian) Currently translated at 22.5% (265 of 1174 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/uk/ --- src/i18n/strings/uk.json | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/uk.json b/src/i18n/strings/uk.json index 02a650ac3a..cb7809814a 100644 --- a/src/i18n/strings/uk.json +++ b/src/i18n/strings/uk.json @@ -84,7 +84,7 @@ "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s змінив(ла) назву кімнати на %(roomName)s.", "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s видалив ім'я кімнати.", "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s змінив тему на %(topic)s.", - "Email": "е-почта", + "Email": "е-пошта", "Email address": "Адреса е-почти", "Email address (optional)": "Адреса е-почти (не обов'язково)", "Email, name or matrix ID": "Е-почта, ім'я або matrix ID", @@ -253,5 +253,17 @@ "Collapse panel": "Згорнути панель", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "У вашому оглядачі вигляд застосунку може бути повністю іншим, а деякі або навіть усі функції можуть не працювати. Якщо ви наполягаєте, то можете продовжити користування, але ви маєте впоратись з усіма можливими проблемами власноруч!", "Checking for an update...": "Перевірка оновлень…", - "There are advanced notifications which are not shown here": "Є додаткові сповіщення, що не показуються тут" + "There are advanced notifications which are not shown here": "Є додаткові сповіщення, що не показуються тут", + "Clear Cache": "Очистити кеш", + "Clear Cache and Reload": "Очистити кеш та перезавантажити", + "Updates": "Оновлення", + "Check for update": "Перевірити на наявність оновлень", + "Reject all %(invitedRooms)s invites": "Відхилити запрошення до усіх %(invitedRooms)s", + "Desktop specific": "Властиві для стільниці", + "Profile": "Профіль", + "Display name": "Відображуване ім'я", + "To return to your account in future you need to set a password": "Щоб мати змогу користуватись обліковкою у майбутньому, треба зазначити пароль", + "Logged in as:": "Ви зайшли як:", + "click to reveal": "натисніть щоб побачити", + "Homeserver is": "Домашній сервер —" } From e5021f368b2c2282b435636e776e6b0d23ac30db Mon Sep 17 00:00:00 2001 From: Osoitz Date: Tue, 8 May 2018 09:26:35 +0000 Subject: [PATCH 1037/1160] Translated using Weblate (Basque) Currently translated at 100.0% (1174 of 1174 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eu/ --- src/i18n/strings/eu.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index 6843f35440..e478c3270b 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -1171,5 +1171,10 @@ "Clear Storage and Sign Out": "Garbitu biltegiratzea eta amaitu saioa", "Refresh": "Freskatu", "We encountered an error trying to restore your previous session.": "Errore bat aurkitu dugu zure aurreko saioa berrezartzen saiatzean.", - "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Zure nabigatzailearen biltegiratzea garbitzeak arazoa konpon lezake, baina saioa amaituko da eta zifratutako txaten historiala ezin izango da berriro irakurri." + "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Zure nabigatzailearen biltegiratzea garbitzeak arazoa konpon lezake, baina saioa amaituko da eta zifratutako txaten historiala ezin izango da berriro irakurri.", + "At this time it is not possible to reply with a file so this will be sent without being a reply.": "Une honetan ezin da fitxategi batekin erantzun, mezu arrunt eta ez erantzun gisa bidaliko da.", + "Unable to reply": "Ezin erantzun", + "At this time it is not possible to reply with an emote.": "Une honetan ezin da irriabartxo batekin erantzun.", + "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Ezin izan da erantzundako gertaera kargatu, edo ez dago edo ez duzu ikusteko baimenik.", + "Collapse Reply Thread": "Tolestu erantzun-haria" } From def6329b6abb8eef53a92a48c22f1abd97092a9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Tue, 8 May 2018 10:29:53 +0000 Subject: [PATCH 1038/1160] Translated using Weblate (Slovak) Currently translated at 100.0% (1174 of 1174 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sk/ --- src/i18n/strings/sk.json | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index fd1280e27f..f807ecd1a9 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -1163,5 +1163,18 @@ "Your device resolution": "Rozlíšenie obrazovky vašeho zariadenia", "Popout widget": "Otvoriť widget v novom okne", "Missing roomId.": "Chýba ID miestnosti.", - "Picture": "Vytvoriť snímku" + "Picture": "Vytvoriť snímku", + "Always show encryption icons": "Vždy zobrazovať ikony stavu šifrovania", + "At this time it is not possible to reply with a file so this will be sent without being a reply.": "Zatiaľ nie je možné k odpovedi pridať súbor. Súbor teda nebude odoslaný ako odpoveď.", + "Unable to reply": "Nie je možné odpovedať", + "At this time it is not possible to reply with an emote.": "V odpovedi zatiaľ nie je možné vijadriť pocit.", + "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Nie je možné načítať udalosť odkazovanú v odpovedi. Takáto udalosť buď neexistuje alebo nemáte oprávnenie na jej zobrazenie.", + "Riot bugs are tracked on GitHub: create a GitHub issue.": "Požiadavky projektu Riot sledujeme na Github: vytvoriť github požiadavku.", + "Log out and remove encryption keys?": "Odhlásiť sa a odstrániť šifrovacie kľúče?", + "Send Logs": "Odoslať záznamy", + "Clear Storage and Sign Out": "Vymazať úložisko a Odhlásiť sa", + "Refresh": "Obnoviť", + "We encountered an error trying to restore your previous session.": "Počas obnovovania vašej predchádzajúcej relácie sa vyskytla chyba.", + "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Vymazaním úložiska prehliadača možno opravíte váš problém, no zároveň sa týmto odhlásite a história vašich šifrovaných konverzácií sa pre vás môže stať nečitateľná.", + "Collapse Reply Thread": "Zbaliť vlákno odpovedí" } From 61343e8a70d3527708efb8de5d783c36ada6cde2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Tue, 8 May 2018 10:40:50 +0000 Subject: [PATCH 1039/1160] Translated using Weblate (Slovak) Currently translated at 100.0% (1174 of 1174 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sk/ --- src/i18n/strings/sk.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index f807ecd1a9..142b5dfea9 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -433,7 +433,7 @@ "Failed to copy": "Nepodarilo sa skopírovať", "Add an Integration": "Pridať integráciu", "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?": "Budete presmerovaní na stránku tretej strany, aby ste mohli overiť svoj účet na použitie s %(integrationsUrl)s. Chcete pokračovať?", - "Removed or unknown message type": "Odstránený alebo neznámy typ udalosti", + "Removed or unknown message type": "Odstránený alebo neznámy typ správy", "Message removed by %(userId)s": "Správu odstránil %(userId)s", "Message removed": "správa odstránená", "Robot check is currently unavailable on desktop - please use a web browser": "Overenie, že nieste robot nie je možné cez aplikáciu na pracovnej ploche - prosím prejdite do prehliadača webu", @@ -1104,7 +1104,7 @@ "All messages": "Všetky správy", "Call invitation": "Audio / Video hovory", "Messages containing my display name": "Správy obsahujúce moje zobrazované meno", - "You have successfully set a password and an email address!": "Úspešne si si nastavili heslo aj emailovú adresu!", + "You have successfully set a password and an email address!": "Úspešne ste si nastavili heslo aj emailovú adresu!", "Failed to send custom event.": "Odoslanie vlastnej udalosti zlyhalo.", "What's new?": "Čo je nové?", "Notify me for anything else": "Oznamovať mi všetko ostatné", From 8d2b5de4ff786ac3a2426ddaa4e2c2dec45d1d27 Mon Sep 17 00:00:00 2001 From: Krombel Date: Tue, 8 May 2018 15:45:05 +0000 Subject: [PATCH 1040/1160] Translated using Weblate (German) Currently translated at 99.9% (1173 of 1174 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index f4144b13de..24f0b4b548 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -1163,5 +1163,17 @@ "e.g. ": "z.B. ", "Your User Agent": "Deine Browser-Kennung", "Your device resolution": "Deine Bildschirmauflösung", - "Popout widget": "Widget ausklinken" + "Popout widget": "Widget ausklinken", + "Always show encryption icons": "Immer Verschlüsselungssymbole zeigen", + "At this time it is not possible to reply with a file so this will be sent without being a reply.": "Aktuell ist es nicht möglich mit einer Datei zu antworten, sodass diese gesendet wird ohne eine Antwort zu sein.", + "Unable to reply": "Antworten nicht möglich", + "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Das Ereignis auf das geantwortet wurde könnte nicht geladen werden, da es entweder nicht existiert oder du keine Berechtigung hast, dieses anzusehen.", + "Riot bugs are tracked on GitHub: create a GitHub issue.": "Riot-Fehler werden auf GitHub festgehalten: Erzeuge ein GitHub-Issue.", + "Log out and remove encryption keys?": "Abmelden und alle Verschlüsselungs-Schlüssel löschen?", + "Send Logs": "Sende Protokoll", + "Clear Storage and Sign Out": "Speicher leeren und abmelden", + "Refresh": "Neu laden", + "We encountered an error trying to restore your previous session.": "Wir haben ein Problem beim Wiederherstellen deiner vorherigen Sitzung festgestellt.", + "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Den Browser-Speicher zu löschen kann das Problem lösen, wird dich aber abmelden und verschlüsselte Chats unlesbar machen.", + "Collapse Reply Thread": "Antwort-Thread zusammenklappen" } From b5320444a905f51d410429353e81e70ed7c08fde Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Tue, 8 May 2018 22:05:53 +0100 Subject: [PATCH 1041/1160] Fix current user and creator user ID properties. --- src/components/views/rooms/Stickerpicker.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/Stickerpicker.js b/src/components/views/rooms/Stickerpicker.js index c055c67cd3..031f93c919 100644 --- a/src/components/views/rooms/Stickerpicker.js +++ b/src/components/views/rooms/Stickerpicker.js @@ -164,8 +164,8 @@ export default class Stickerpicker extends React.Component { room={this.props.room} type={stickerpickerWidget.content.type} fullWidth={true} - userId={stickerpickerWidget.sender || MatrixClientPeg.get().credentials.userId} - creatorUserId={MatrixClientPeg.get().credentials.userId} + userId={MatrixClientPeg.get().credentials.userId} + creatorUserId={stickerpickerWidget.sender || MatrixClientPeg.get().credentials.userId} waitForIframeLoad={true} show={true} showMenubar={true} From 8e1ba6d139253d88a21d4c9efe7a4711734750f7 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Tue, 8 May 2018 22:44:49 +0100 Subject: [PATCH 1042/1160] Always allow users to edit their user widgets. --- src/components/views/elements/AppTile.js | 8 ++++++++ src/components/views/rooms/Stickerpicker.js | 1 + 2 files changed, 9 insertions(+) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 007eb8126c..af754c7d4c 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -274,6 +274,11 @@ export default class AppTile extends React.Component { } _canUserModify() { + // User widgets should always be modifiable by their creator + if (this.props.userWidget && MatrixClientPeg.get().credentials.userId === this.props.creatorUserId) { + return true; + } + // Check if the current user can modify widgets in the current room return WidgetUtils.canUserModifyWidgets(this.props.room.roomId); } @@ -698,6 +703,8 @@ AppTile.propTypes = { // Optional function to be called on widget capability request // Called with an array of the requested capabilities onCapabilityRequest: PropTypes.func, + // Is this an instance of a user widget + userWidget: PropTypes.bool, }; AppTile.defaultProps = { @@ -710,4 +717,5 @@ AppTile.defaultProps = { showPopout: true, handleMinimisePointerEvents: false, whitelistCapabilities: [], + userWidget: false, }; diff --git a/src/components/views/rooms/Stickerpicker.js b/src/components/views/rooms/Stickerpicker.js index 031f93c919..9b489c3e38 100644 --- a/src/components/views/rooms/Stickerpicker.js +++ b/src/components/views/rooms/Stickerpicker.js @@ -178,6 +178,7 @@ export default class Stickerpicker extends React.Component { onMinimiseClick={this._onHideStickersClick} handleMinimisePointerEvents={true} whitelistCapabilities={['m.sticker']} + userWidget={true} />
    From 3d20bd00a227ac5f106300d63567a6050696c9ab Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 9 May 2018 11:43:02 +0100 Subject: [PATCH 1043/1160] Pin lolex at 2.3.2 to avoid bug causing tests to fail See https://github.com/sinonjs/lolex/issues/170 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b0f0d26c56..8ed7ef2558 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,7 @@ "isomorphic-fetch": "^2.2.1", "linkifyjs": "^2.1.3", "lodash": "^4.13.1", - "lolex": "^2.3.2", + "lolex": "2.3.2", "matrix-js-sdk": "0.10.1", "optimist": "^0.6.1", "pako": "^1.0.5", From 8bddbea236a432dbb9faf07bff7637b1f4bc8747 Mon Sep 17 00:00:00 2001 From: Sven Thomsen Date: Tue, 8 May 2018 20:59:27 +0000 Subject: [PATCH 1044/1160] Translated using Weblate (German) Currently translated at 100.0% (1174 of 1174 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 24f0b4b548..21d40dd86d 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -1175,5 +1175,6 @@ "Refresh": "Neu laden", "We encountered an error trying to restore your previous session.": "Wir haben ein Problem beim Wiederherstellen deiner vorherigen Sitzung festgestellt.", "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Den Browser-Speicher zu löschen kann das Problem lösen, wird dich aber abmelden und verschlüsselte Chats unlesbar machen.", - "Collapse Reply Thread": "Antwort-Thread zusammenklappen" + "Collapse Reply Thread": "Antwort-Thread zusammenklappen", + "At this time it is not possible to reply with an emote.": "An dieser Stelle ist es nicht möglich mit einer Umschreibung zu antworten." } From edc70c9f118b5ce796a0bde5f3a4661ccb098843 Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 9 May 2018 08:39:12 +0000 Subject: [PATCH 1045/1160] Translated using Weblate (Russian) Currently translated at 99.7% (1171 of 1174 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 3cf9aa0f7d..2e6bdf45f0 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -369,7 +369,7 @@ "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Не удается подключиться к домашнему серверу через HTTP, так как в адресной строке браузера указан URL HTTPS. Используйте HTTPS или либо включите небезопасные сценарии.", "Dismiss": "Отклонить", "Custom Server Options": "Выбор другого сервера", - "Mute": "Заглушить", + "Mute": "Приглушить", "Operation failed": "Сбой операции", "powered by Matrix": "Основано на Matrix", "Add a topic": "Задать тему", From 6fdd952510e4ed7f0809a42d2b554d0cd9edf91f Mon Sep 17 00:00:00 2001 From: Kenneth Larsson Date: Wed, 9 May 2018 09:58:37 +0000 Subject: [PATCH 1046/1160] Translated using Weblate (Swedish) Currently translated at 55.4% (651 of 1174 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sv/ --- src/i18n/strings/sv.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sv.json b/src/i18n/strings/sv.json index 4a2a5f76cc..42c06615cb 100644 --- a/src/i18n/strings/sv.json +++ b/src/i18n/strings/sv.json @@ -650,5 +650,6 @@ "Upload avatar": "Ladda upp profilbild", "Remove avatar": "Ta bort profilbild", "This invitation was sent to an email address which is not associated with this account:": "Den här inbjudan skickades till en emailadress som inte är kopplad till detta konto:", - "To link to a room it must have an address.": "För att länka till ett rum behöver det en adress." + "To link to a room it must have an address.": "För att länka till ett rum behöver det en adress.", + "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (nivå %(powerLevelNumber)s)" } From ee0e6c5913f2b0202bad6e81fd963e3dd59454ec Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 9 May 2018 11:53:37 +0100 Subject: [PATCH 1047/1160] Remove margins when in a ReplyThread to stop them taking so much space Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- res/css/views/elements/_ReplyThread.scss | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/res/css/views/elements/_ReplyThread.scss b/res/css/views/elements/_ReplyThread.scss index a02f42751c..bf44a11728 100644 --- a/res/css/views/elements/_ReplyThread.scss +++ b/res/css/views/elements/_ReplyThread.scss @@ -14,8 +14,13 @@ See the License for the specific language governing permissions and limitations under the License. */ +.mx_ReplyThread { + margin-top: 0; +} + .mx_ReplyThread .mx_DateSeparator { font-size: 1em !important; + margin-top: 0; margin-bottom: 0; padding-bottom: 1px; bottom: -5px; From b930088b271b32beef565b0bd77ea7a9cd696070 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Wed, 9 May 2018 11:53:56 +0100 Subject: [PATCH 1048/1160] Bump travis-ci rebuild From 76f19787215febec549368c444790c2e16c251e2 Mon Sep 17 00:00:00 2001 From: Kenneth Larsson Date: Wed, 9 May 2018 12:32:02 +0000 Subject: [PATCH 1049/1160] Translated using Weblate (Swedish) Currently translated at 57.4% (674 of 1174 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sv/ --- src/i18n/strings/sv.json | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sv.json b/src/i18n/strings/sv.json index 42c06615cb..fea64b3f27 100644 --- a/src/i18n/strings/sv.json +++ b/src/i18n/strings/sv.json @@ -651,5 +651,28 @@ "Remove avatar": "Ta bort profilbild", "This invitation was sent to an email address which is not associated with this account:": "Den här inbjudan skickades till en emailadress som inte är kopplad till detta konto:", "To link to a room it must have an address.": "För att länka till ett rum behöver det en adress.", - "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (nivå %(powerLevelNumber)s)" + "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (nivå %(powerLevelNumber)s)", + "Unknown Address": "Okänd adress", + "%(nameList)s %(transitionList)s": "%(nameList)s %(transitionList)s", + "%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)s har gått med %(count)s gånger", + "%(severalUsers)sjoined %(count)s times|one": "%(severalUsers)sgick med", + "%(oneUser)sjoined %(count)s times|other": "%(oneUser)s har gått med %(count)s gånger", + "%(oneUser)sjoined %(count)s times|one": "%(oneUser)sgick med", + "%(severalUsers)sleft %(count)s times|other": "%(severalUsers)shar lämnat %(count)s gånger", + "%(severalUsers)sleft %(count)s times|one": "%(severalUsers)slämnade", + "%(oneUser)sleft %(count)s times|other": "%(oneUser)shar lämnat %(count)s gånger", + "%(oneUser)sleft %(count)s times|one": "%(oneUser)slämnade", + "%(severalUsers)sjoined and left %(count)s times|other": "%(severalUsers)shar gått med och lämnat %(count)s gånger", + "%(severalUsers)sjoined and left %(count)s times|one": "%(severalUsers)shar gått med och lämnat", + "%(oneUser)sjoined and left %(count)s times|other": "%(oneUser)shar gått med och lämnat %(count)s gånger", + "%(oneUser)sjoined and left %(count)s times|one": "%(oneUser)shar gått med och lämnat", + "And %(count)s more...|other": "Och %(count)s till...", + "ex. @bob:example.com": "t.ex. @kalle:exempel.com", + "Add User": "Lägg till användare", + "Matrix ID": "Matrix-ID", + "Matrix Room ID": "Matrix-rums-ID", + "email address": "epostadress", + "Try using one of the following valid address types: %(validTypesList)s.": "Prova att använda någon av följande giltiga adresstyper: %(validTypesList)s.", + "You have entered an invalid address.": "Du har angett en ogiltig adress.", + "Preparing to send logs": "Förbereder att skicka loggar" } From 7d0f6532ec69efc0c1c123e7afe3fdcb06c1382f Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 9 May 2018 13:44:41 +0100 Subject: [PATCH 1050/1160] Prepare changelog for v0.12.4-rc.1 --- CHANGELOG.md | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 334461bffb..30099319a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,68 @@ +Changes in [0.12.4-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.12.4-rc.1) (2018-05-09) +=============================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.12.3...v0.12.4-rc.1) + + * Update from Weblate. + [\#1881](https://github.com/matrix-org/matrix-react-sdk/pull/1881) + * Pin lolex at 2.3.2 to avoid bug causing tests to fail + [\#1880](https://github.com/matrix-org/matrix-react-sdk/pull/1880) + * Replies: un-break click-to-mention on SenderProfile for reply&preview + [\#1878](https://github.com/matrix-org/matrix-react-sdk/pull/1878) + * Add tests for RoomList + [\#1877](https://github.com/matrix-org/matrix-react-sdk/pull/1877) + * Fix crash when browser doesn't report page change measurement + [\#1874](https://github.com/matrix-org/matrix-react-sdk/pull/1874) + * fix thinko when changing from ClientPeg to context in static method (DUH) + [\#1875](https://github.com/matrix-org/matrix-react-sdk/pull/1875) + * Fix Replies :D + [\#1873](https://github.com/matrix-org/matrix-react-sdk/pull/1873) + * Update eslint-plugin-react + [\#1871](https://github.com/matrix-org/matrix-react-sdk/pull/1871) + * relax lint for jsx-curly-spacing and arrow-parens + [\#1872](https://github.com/matrix-org/matrix-react-sdk/pull/1872) + * Use develop js-sdk in jenkins build + [\#1870](https://github.com/matrix-org/matrix-react-sdk/pull/1870) + * Replies + [\#1741](https://github.com/matrix-org/matrix-react-sdk/pull/1741) + * Use the right js-sdk branch when testing + [\#1869](https://github.com/matrix-org/matrix-react-sdk/pull/1869) + * Prevent error responses wedging group request concurrency limit + [\#1867](https://github.com/matrix-org/matrix-react-sdk/pull/1867) + * Refresh group rooms and members when selecting a tag + [\#1868](https://github.com/matrix-org/matrix-react-sdk/pull/1868) + * Refactor GroupStores into one global GroupStore + [\#1866](https://github.com/matrix-org/matrix-react-sdk/pull/1866) + * Switch back to using blob URLs for rendering e2e attachments + [\#1864](https://github.com/matrix-org/matrix-react-sdk/pull/1864) + * Hide inline encryption icons except when hovering over a message + [\#1845](https://github.com/matrix-org/matrix-react-sdk/pull/1845) + * UI fixes in SessionRestoreErrorDialog + [\#1860](https://github.com/matrix-org/matrix-react-sdk/pull/1860) + * Fix UX issues with bug report dialog + [\#1863](https://github.com/matrix-org/matrix-react-sdk/pull/1863) + * fix ugly img errors and correctly render SVG thumbnails + [\#1865](https://github.com/matrix-org/matrix-react-sdk/pull/1865) + * Fix error handling on session restore + [\#1859](https://github.com/matrix-org/matrix-react-sdk/pull/1859) + * Add tests for GroupView + [\#1862](https://github.com/matrix-org/matrix-react-sdk/pull/1862) + * Update version of hoek + [\#1861](https://github.com/matrix-org/matrix-react-sdk/pull/1861) + * Fix bug that caused crash when analytics HS/IS whitelists not specified + [\#1858](https://github.com/matrix-org/matrix-react-sdk/pull/1858) + * Fix Analytics to not import DEFAULTS, therefore avoiding NPE + [\#1857](https://github.com/matrix-org/matrix-react-sdk/pull/1857) + * Null check piwik config before using it + [\#1856](https://github.com/matrix-org/matrix-react-sdk/pull/1856) + * Track actual window location origin and hash + [\#1853](https://github.com/matrix-org/matrix-react-sdk/pull/1853) + * Replace document.origin with window.location.origin + [\#1855](https://github.com/matrix-org/matrix-react-sdk/pull/1855) + * Optionally hide widget popout button. + [\#1854](https://github.com/matrix-org/matrix-react-sdk/pull/1854) + * Add a button to 'pop out' widgets in to their own tab. + [\#1851](https://github.com/matrix-org/matrix-react-sdk/pull/1851) + Changes in [0.12.3](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.12.3) (2018-04-30) ===================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.12.3-rc.3...v0.12.3) From ddf98705f2e4fcee3f8449a4613bae6f1c7fbccb Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 9 May 2018 13:44:42 +0100 Subject: [PATCH 1051/1160] v0.12.4-rc.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9c71c1399c..eb6c2e33b3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.12.3", + "version": "0.12.4-rc.1", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From e10e65945771cf38591d9af6f29f23555da18e19 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 9 May 2018 14:59:35 +0100 Subject: [PATCH 1052/1160] Take feature_sticker_messagse out of labs --- src/components/views/rooms/MessageComposer.js | 5 +---- src/settings/Settings.js | 6 ------ 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 24b07eb3bf..28a90b375a 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -338,10 +338,7 @@ export default class MessageComposer extends React.Component { } } - let stickerpickerButton; - if (SettingsStore.isFeatureEnabled('feature_sticker_messages')) { - stickerpickerButton = ; - } + const stickerpickerButton = ; controls.push( Date: Wed, 9 May 2018 13:21:40 +0000 Subject: [PATCH 1053/1160] Translated using Weblate (Swedish) Currently translated at 58.0% (682 of 1174 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sv/ --- src/i18n/strings/sv.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sv.json b/src/i18n/strings/sv.json index fea64b3f27..b2d6ac9ad9 100644 --- a/src/i18n/strings/sv.json +++ b/src/i18n/strings/sv.json @@ -674,5 +674,13 @@ "email address": "epostadress", "Try using one of the following valid address types: %(validTypesList)s.": "Prova att använda någon av följande giltiga adresstyper: %(validTypesList)s.", "You have entered an invalid address.": "Du har angett en ogiltig adress.", - "Preparing to send logs": "Förbereder att skicka loggar" + "Preparing to send logs": "Förbereder att skicka loggar", + "Logs sent": "Loggar skickade", + "Failed to send logs: ": "Det gick inte att skicka loggar: ", + "Submit debug logs": "Skicka felsökningsloggar", + "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Felsökningsloggar innehåller användningsdata för applikationen inklusive ditt användarnamn, ID:n eller alias för de rum och grupper du har besökt och användarnamn för andra användare. De innehåller inte meddelanden.", + "Riot bugs are tracked on GitHub: create a GitHub issue.": "Riot-buggar hanteras på GitHub: skapa en GitHub-issue.", + "GitHub issue link:": "Länk till GitHub-issue:", + "Notes:": "Noteringar:", + "Start new chat": "Starta ny chatt" } From 59cbaf67bbbe24c15c1437916e096b6c1e2e56d2 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 9 May 2018 15:48:53 +0100 Subject: [PATCH 1054/1160] Fix issue incorrect positioning with widget loading indicator by making sure to apply the correct CSS class to the parent --- src/components/views/elements/AppTile.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 007eb8126c..bf24da506b 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -534,7 +534,11 @@ export default class AppTile extends React.Component {
    ); if (this.state.initialising) { - appTileBody = loadingElement; + appTileBody = ( +
    + { loadingElement } +
    + ); } else if (this.state.hasPermissionToLoad == true) { if (this.isMixedContent()) { appTileBody = ( From 0c1846630c1073bef1ce3ac94540a0b06efa3d14 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 9 May 2018 16:41:45 +0100 Subject: [PATCH 1055/1160] Improve appearance of short-lived app loading spinner by hiding it for 500ms - thereby only showing it if the loading is taking a long time. --- res/css/views/rooms/_AppsDrawer.scss | 13 +++++++++++++ src/components/views/elements/AppTile.js | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/res/css/views/rooms/_AppsDrawer.scss b/res/css/views/rooms/_AppsDrawer.scss index 0cf3e7b9cb..28d432686d 100644 --- a/res/css/views/rooms/_AppsDrawer.scss +++ b/res/css/views/rooms/_AppsDrawer.scss @@ -266,6 +266,19 @@ form.mx_Custom_Widget_Form div { right: 0; } +.mx_AppLoading_spinner_fadeIn { + animation-fill-mode: backwards; + animation-duration: 200ms; + animation-delay: 500ms; + animation-name: mx_AppLoading_spinner_fadeIn_animation; +} + +@keyframes mx_AppLoading_spinner_fadeIn_animation { + from { opacity: 0 } + to { opacity: 1 } +} + + .mx_AppLoading iframe { display: none; } diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 1d04eb5196..63cf459987 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -534,7 +534,7 @@ export default class AppTile extends React.Component { if (this.props.show) { const loadingElement = ( -
    +
    ); From 44ea11d386f2ac9be1e2b84d5cd887b2af81d18d Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Wed, 9 May 2018 16:55:49 +0100 Subject: [PATCH 1056/1160] Fix 'state_key' field name. --- src/ScalarMessaging.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index 123d02159e..a163bf7bbd 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -349,7 +349,7 @@ function setWidget(event, roomId) { userWidgets[widgetId] = { content: content, sender: client.getUserId(), - stateKey: widgetId, + state_key: widgetId, type: 'm.widget', id: widgetId, }; From 97b9316ec760376a7ac402e40c2a968e334f2091 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 9 May 2018 15:48:53 +0100 Subject: [PATCH 1057/1160] Fix issue incorrect positioning with widget loading indicator by making sure to apply the correct CSS class to the parent --- src/components/views/elements/AppTile.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 007eb8126c..bf24da506b 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -534,7 +534,11 @@ export default class AppTile extends React.Component {
    ); if (this.state.initialising) { - appTileBody = loadingElement; + appTileBody = ( +
    + { loadingElement } +
    + ); } else if (this.state.hasPermissionToLoad == true) { if (this.isMixedContent()) { appTileBody = ( From 0a326dc6a02c664f58fbe65d21ab568a969a1fd5 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 9 May 2018 14:59:35 +0100 Subject: [PATCH 1058/1160] Take feature_sticker_messagse out of labs --- src/components/views/rooms/MessageComposer.js | 5 +---- src/settings/Settings.js | 6 ------ 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 24b07eb3bf..28a90b375a 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -338,10 +338,7 @@ export default class MessageComposer extends React.Component { } } - let stickerpickerButton; - if (SettingsStore.isFeatureEnabled('feature_sticker_messages')) { - stickerpickerButton = ; - } + const stickerpickerButton = ; controls.push( Date: Wed, 9 May 2018 16:41:45 +0100 Subject: [PATCH 1059/1160] Improve appearance of short-lived app loading spinner by hiding it for 500ms - thereby only showing it if the loading is taking a long time. --- res/css/views/rooms/_AppsDrawer.scss | 13 +++++++++++++ src/components/views/elements/AppTile.js | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/res/css/views/rooms/_AppsDrawer.scss b/res/css/views/rooms/_AppsDrawer.scss index 0cf3e7b9cb..28d432686d 100644 --- a/res/css/views/rooms/_AppsDrawer.scss +++ b/res/css/views/rooms/_AppsDrawer.scss @@ -266,6 +266,19 @@ form.mx_Custom_Widget_Form div { right: 0; } +.mx_AppLoading_spinner_fadeIn { + animation-fill-mode: backwards; + animation-duration: 200ms; + animation-delay: 500ms; + animation-name: mx_AppLoading_spinner_fadeIn_animation; +} + +@keyframes mx_AppLoading_spinner_fadeIn_animation { + from { opacity: 0 } + to { opacity: 1 } +} + + .mx_AppLoading iframe { display: none; } diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index bf24da506b..7c4ab13c5a 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -529,7 +529,7 @@ export default class AppTile extends React.Component { if (this.props.show) { const loadingElement = ( -
    +
    ); From 54fdb234d5e780ab94ab7e33af1f98e5832ec20e Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 9 May 2018 17:34:53 +0100 Subject: [PATCH 1060/1160] Prepare changelog for v0.12.4-rc.2 --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30099319a9..8f8e89250e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +Changes in [0.12.4-rc.2](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.12.4-rc.2) (2018-05-09) +=============================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.12.4-rc.1...v0.12.4-rc.2) + + * Improve appearance of short-lived widget loading spinner + * Make sticker picker fully-fledged feature + * Fix incorrect positioning with widget loading indicator + Changes in [0.12.4-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.12.4-rc.1) (2018-05-09) =============================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.12.3...v0.12.4-rc.1) From 6a0bff6685acd3e68b5b7221310140ed3a9aef48 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 9 May 2018 17:34:54 +0100 Subject: [PATCH 1061/1160] v0.12.4-rc.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index eb6c2e33b3..3958e1b3d0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.12.4-rc.1", + "version": "0.12.4-rc.2", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From 904676913266b2b10cb3f8f20634115e603733ee Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 10 May 2018 16:00:58 +0100 Subject: [PATCH 1062/1160] Factor out ContextualMenu component --- src/components/structures/ContextualMenu.js | 88 +++++++++++---------- 1 file changed, 47 insertions(+), 41 deletions(-) diff --git a/src/components/structures/ContextualMenu.js b/src/components/structures/ContextualMenu.js index 0e2df890f3..99d1f892b9 100644 --- a/src/components/structures/ContextualMenu.js +++ b/src/components/structures/ContextualMenu.js @@ -26,9 +26,21 @@ import PropTypes from 'prop-types'; // of doing reusable widgets like dialog boxes & menus where we go and // pass in a custom control as the actual body. -module.exports = { - ContextualMenuContainerId: "mx_ContextualMenu_Container", +const ContextualMenuContainerId = "mx_ContextualMenu_Container"; +function getOrCreateContainer() { + let container = document.getElementById(ContextualMenuContainerId); + + if (!container) { + container = document.createElement("div"); + container.id = ContextualMenuContainerId; + document.body.appendChild(container); + } + + return container; +} + +class ContextualMenu extends React.Component { propTypes: { top: PropTypes.number, bottom: PropTypes.number, @@ -45,39 +57,14 @@ module.exports = { menuPaddingRight: PropTypes.number, menuPaddingBottom: PropTypes.number, menuPaddingLeft: PropTypes.number, - }, - - getOrCreateContainer: function() { - let container = document.getElementById(this.ContextualMenuContainerId); - - if (!container) { - container = document.createElement("div"); - container.id = this.ContextualMenuContainerId; - document.body.appendChild(container); - } - - return container; - }, - - createMenu: function(Element, props) { - const self = this; - - const closeMenu = function(...args) { - ReactDOM.unmountComponentAtNode(self.getOrCreateContainer()); - - if (props && props.onFinished) { - props.onFinished.apply(null, args); - } - }; - - // Close the menu on window resize - const windowResize = function() { - closeMenu(); - }; + } + render() { const position = {}; let chevronFace = null; + const props = this.props; + if (props.top) { position.top = props.top; } else { @@ -158,20 +145,39 @@ module.exports = { menuStyle["paddingRight"] = props.menuPaddingRight; } + const ElementClass = props.elementClass; + // FIXME: If a menu uses getDefaultProps it clobbers the onFinished // property set here so you can't close the menu from a button click! - const menu = ( -
    -
    - { chevron } - -
    -
    - + return
    +
    + { chevron } +
    - ); +
    + +
    ; + } +} - ReactDOM.render(menu, this.getOrCreateContainer()); +module.exports = { + createMenu: function(ElementClass, props) { + const closeMenu = function(...args) { + ReactDOM.unmountComponentAtNode(getOrCreateContainer()); + + if (props && props.onFinished) { + props.onFinished.apply(null, args); + } + }; + + const menu = ; + + ReactDOM.render(menu, getOrCreateContainer()); return {close: closeMenu}; }, From cbf52e00d29513791a2eb733c8abc00a1a2f179e Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 10 May 2018 16:43:10 +0100 Subject: [PATCH 1063/1160] Update widget 'widgetData' key to 'data' to match spec. --- src/FromWidgetPostMessageApi.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/FromWidgetPostMessageApi.js b/src/FromWidgetPostMessageApi.js index ad1f1acbbd..c9c9d5c3de 100644 --- a/src/FromWidgetPostMessageApi.js +++ b/src/FromWidgetPostMessageApi.js @@ -137,12 +137,12 @@ export default class FromWidgetPostMessageApi { }); } else if (action === 'm.sticker') { // console.warn('Got sticker message from widget', widgetId); - dis.dispatch({action: 'm.sticker', data: event.data.widgetData, widgetId: event.data.widgetId}); + dis.dispatch({action: 'm.sticker', data: event.data.data, widgetId: event.data.widgetId}); } else if (action === 'integration_manager_open') { // Close the stickerpicker dis.dispatch({action: 'stickerpicker_close'}); // Open the integration manager - const data = event.data.widgetData; + const data = event.data.data; const integType = (data && data.integType) ? data.integType : null; const integId = (data && data.integId) ? data.integId : null; IntegrationManager.open(integType, integId); From 2c2eda1f006c1ddcde13e890ae8f5830d7ac9bf1 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 10 May 2018 17:51:49 +0100 Subject: [PATCH 1064/1160] Export ContextualMenu component, with added `hasBackground` property , which is only enabled when `createMenu` is used. --- src/components/structures/ContextualMenu.js | 43 +++++++++++---------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/src/components/structures/ContextualMenu.js b/src/components/structures/ContextualMenu.js index 99d1f892b9..17f1a23e14 100644 --- a/src/components/structures/ContextualMenu.js +++ b/src/components/structures/ContextualMenu.js @@ -40,7 +40,7 @@ function getOrCreateContainer() { return container; } -class ContextualMenu extends React.Component { +export default class ContextualMenu extends React.Component { propTypes: { top: PropTypes.number, bottom: PropTypes.number, @@ -57,6 +57,10 @@ class ContextualMenu extends React.Component { menuPaddingRight: PropTypes.number, menuPaddingBottom: PropTypes.number, menuPaddingLeft: PropTypes.number, + + // If true, insert an invisible screen-sized element behind the + // menu that when clicked will close it. + hasBackground: PropTypes.bool, } render() { @@ -154,31 +158,30 @@ class ContextualMenu extends React.Component { { chevron }
    -
    + { props.hasBackground &&
    }
    ; } } -module.exports = { - createMenu: function(ElementClass, props) { - const closeMenu = function(...args) { - ReactDOM.unmountComponentAtNode(getOrCreateContainer()); +export function createMenu(ElementClass, props) { + const closeMenu = function(...args) { + ReactDOM.unmountComponentAtNode(getOrCreateContainer()); - if (props && props.onFinished) { - props.onFinished.apply(null, args); - } - }; + if (props && props.onFinished) { + props.onFinished.apply(null, args); + } + }; - const menu = ; + const menu = ; - ReactDOM.render(menu, getOrCreateContainer()); + ReactDOM.render(menu, getOrCreateContainer()); - return {close: closeMenu}; - }, -}; + return {close: closeMenu}; +} From 5cb892bf3cb23e1f49e413aeb81b70eecade6aa5 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 10 May 2018 18:06:00 +0100 Subject: [PATCH 1065/1160] Allow use of either 'data' or 'widgetData' fields for the time being. --- src/FromWidgetPostMessageApi.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/FromWidgetPostMessageApi.js b/src/FromWidgetPostMessageApi.js index c9c9d5c3de..13ffb4a74b 100644 --- a/src/FromWidgetPostMessageApi.js +++ b/src/FromWidgetPostMessageApi.js @@ -137,12 +137,15 @@ export default class FromWidgetPostMessageApi { }); } else if (action === 'm.sticker') { // console.warn('Got sticker message from widget', widgetId); - dis.dispatch({action: 'm.sticker', data: event.data.data, widgetId: event.data.widgetId}); + // NOTE -- The widgetData field is deprecated (in favour of the 'data' field) and will be removed eventually + const data = event.data.data || event.data.widgetData; + dis.dispatch({action: 'm.sticker', data: data, widgetId: event.data.widgetId}); } else if (action === 'integration_manager_open') { // Close the stickerpicker dis.dispatch({action: 'stickerpicker_close'}); // Open the integration manager - const data = event.data.data; + // NOTE -- The widgetData field is deprecated (in favour of the 'data' field) and will be removed eventually + const data = event.data.data || event.data.widgetData; const integType = (data && data.integType) ? data.integType : null; const integId = (data && data.integId) ? data.integId : null; IntegrationManager.open(integType, integId); From 1f23809c99274111622dd52582c3dc5580f7225d Mon Sep 17 00:00:00 2001 From: Sotiris Papatheodorou Date: Thu, 10 May 2018 11:31:03 +0000 Subject: [PATCH 1066/1160] Translated using Weblate (Greek) Currently translated at 66.5% (781 of 1174 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/el/ --- src/i18n/strings/el.json | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/el.json b/src/i18n/strings/el.json index b5acd8855e..12d08787d5 100644 --- a/src/i18n/strings/el.json +++ b/src/i18n/strings/el.json @@ -57,7 +57,7 @@ "%(senderDisplayName)s removed the room name.": "Ο %(senderDisplayName)s διέγραψε το όνομα του δωματίου.", "Changes your display nickname": "Αλλάζει το ψευδώνυμο χρήστη", "Conference call failed.": "Η κλήση συνδιάσκεψης απέτυχε.", - "powered by Matrix": "βασισμένο στο πρωτόκολλο Matrix", + "powered by Matrix": "βασισμένο στο Matrix", "Confirm password": "Επιβεβαίωση κωδικού πρόσβασης", "Confirm your new password": "Επιβεβαίωση του νέου κωδικού πρόσβασης", "Continue": "Συνέχεια", @@ -772,5 +772,15 @@ "Collapse panel": "Ελαχιστοποίηση καρτέλας", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Με τον τρέχον περιηγητή, η εμφάνιση και η αίσθηση της εφαρμογής ενδέχεται να είναι εντελώς εσφαλμένη και ορισμένες ή όλες οι λειτουργίες ενδέχεται να μην λειτουργούν. Εάν θέλετε να το δοκιμάσετε ούτως ή άλλως μπορείτε να συνεχίσετε, αλλά είστε μόνοι σας σε ό, τι αφορά τα προβλήματα που μπορεί να αντιμετωπίσετε!", "Checking for an update...": "Γίνεται έλεγχος για ενημέρωση...", - "There are advanced notifications which are not shown here": "Υπάρχουν προχωρημένες ειδοποιήσεις οι οποίες δεν εμφανίζονται εδώ" + "There are advanced notifications which are not shown here": "Υπάρχουν προχωρημένες ειδοποιήσεις οι οποίες δεν εμφανίζονται εδώ", + "Your identity server's URL": "Το URL του διακομιστή ταυτοποίησής σας", + "The platform you're on": "Η πλατφόρμα στην οποία βρίσκεστε", + "The version of Riot.im": "Η έκδοση του Riot.im", + "Your language of choice": "Η γλώσσα επιλογής σας", + "Your homeserver's URL": "Το URL του διακομιστή σας", + "Every page you use in the app": "Κάθε σελίδα που χρησιμοποιείτε στην εφαρμογή", + "e.g. ": "π.χ. ", + "Your device resolution": "Η ανάλυση της συσκευής σας", + "The information being sent to us to help make Riot.im better includes:": "Οι πληροφορίες που στέλνονται σε εμάς με σκοπό την βελτίωση του Riot.im περιλαμβάνουν:", + "Call Failed": "Η κλήση απέτυχε" } From f6a2e8d52ca22ee4ba58cfbfae19e7d288b3304d Mon Sep 17 00:00:00 2001 From: Xose M Date: Fri, 11 May 2018 10:43:02 +0000 Subject: [PATCH 1067/1160] Translated using Weblate (Galician) Currently translated at 100.0% (1174 of 1174 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/gl/ --- src/i18n/strings/gl.json | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/gl.json b/src/i18n/strings/gl.json index 06bff9eb76..7d10ca4ec5 100644 --- a/src/i18n/strings/gl.json +++ b/src/i18n/strings/gl.json @@ -1156,5 +1156,25 @@ "Collapse panel": "Agochar panel", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Co seu navegador actual a apareciencia e uso do aplicativo poderían estar totalmente falseadas, e algunhas características poderían non funcionar. Se quere pode continuar, pero debe ser consciente de que poden haber fallos!", "Checking for an update...": "Comprobando as actualizacións...", - "There are advanced notifications which are not shown here": "Existen notificacións avanzadas que non se mostran aquí" + "There are advanced notifications which are not shown here": "Existen notificacións avanzadas que non se mostran aquí", + "Every page you use in the app": "Cada páxina que vostede utiliza no aplicativo", + "e.g. ": "ex. ", + "Your User Agent": "User Agent", + "Your device resolution": "Resolución do dispositivo", + "Missing roomId.": "Falta o id da sala.", + "Always show encryption icons": "Mostra sempre iconas de cifrado", + "At this time it is not possible to reply with a file so this will be sent without being a reply.": "En este intre non é posible respostar con un ficheiro así que este será enviado sin ser considerado resposta.", + "Unable to reply": "Non puido respostar", + "At this time it is not possible to reply with an emote.": "En este intre non é posible respostar con un emote.", + "Popout widget": "Widget emerxente", + "Picture": "Imaxe", + "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Non se cargou o evento ao que respostaba, ou non existe ou non ten permiso para velo.", + "Riot bugs are tracked on GitHub: create a GitHub issue.": "Os fallos de Riot séguense en GitHub: crear un informe en GitHub.", + "Log out and remove encryption keys?": "Desconectar e eliminar as chaves de cifrado?", + "Send Logs": "Enviar informes", + "Clear Storage and Sign Out": "Limpar o almacenamento e Desconectar", + "Refresh": "Actualizar", + "We encountered an error trying to restore your previous session.": "Atopamos un fallo intentando restablecer a súa sesión anterior.", + "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Limpando o almacenamento do navegador podería resolver o problema, pero desconectarao e non poderá ler o historial cifrado da conversa.", + "Collapse Reply Thread": "Comprimir o fío de respostas" } From 2dc51c516c5328de992c8ccccd634bda6e33e1fb Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 11 May 2018 14:47:57 +0100 Subject: [PATCH 1068/1160] Use new ContextualMenu component in Stickerpicker --- src/components/views/rooms/Stickerpicker.js | 93 +++++++++++++-------- 1 file changed, 56 insertions(+), 37 deletions(-) diff --git a/src/components/views/rooms/Stickerpicker.js b/src/components/views/rooms/Stickerpicker.js index 9b489c3e38..8784599238 100644 --- a/src/components/views/rooms/Stickerpicker.js +++ b/src/components/views/rooms/Stickerpicker.js @@ -17,7 +17,6 @@ import React from 'react'; import { _t } from '../../../languageHandler'; import Widgets from '../../../utils/widgets'; import AppTile from '../elements/AppTile'; -import ContextualMenu from '../../structures/ContextualMenu'; import MatrixClientPeg from '../../../MatrixClientPeg'; import Modal from '../../../Modal'; import sdk from '../../../index'; @@ -36,6 +35,7 @@ export default class Stickerpicker extends React.Component { this._launchManageIntegrations = this._launchManageIntegrations.bind(this); this._removeStickerpickerWidgets = this._removeStickerpickerWidgets.bind(this); this._onWidgetAction = this._onWidgetAction.bind(this); + this._onResize = this._onResize.bind(this); this._onFinished = this._onFinished.bind(this); this.popoverWidth = 300; @@ -44,13 +44,17 @@ export default class Stickerpicker extends React.Component { this.state = { showStickers: false, imError: null, + stickerpickerX: null, + stickerpickerY: null, + stickerpickerWidget: null, + widgetId: null, }; } _removeStickerpickerWidgets() { console.warn('Removing Stickerpicker widgets'); - if (this.widgetId) { - this.scalarClient.disableWidgetAssets(widgetType, this.widgetId).then(() => { + if (this.state.widgetId) { + this.scalarClient.disableWidgetAssets(widgetType, this.state.widgetId).then(() => { console.warn('Assets disabled'); }).catch((err) => { console.error('Failed to disable assets'); @@ -59,8 +63,7 @@ export default class Stickerpicker extends React.Component { console.warn('No widget ID specified, not disabling assets'); } - // Wrap this in a timeout in order to avoid the DOM node from being pulled from under its feet - setTimeout(() => this.stickersMenu.close()); + this.setState({showStickers: false}); Widgets.removeStickerpickerWidgets().then(() => { this.forceUpdate(); }).catch((e) => { @@ -69,6 +72,9 @@ export default class Stickerpicker extends React.Component { } componentDidMount() { + // Close the sticker picker when the window resizes + window.addEventListener('resize', this._onResize); + this.scalarClient = null; if (SdkConfig.get().integrations_ui_url && SdkConfig.get().integrations_rest_url) { this.scalarClient = new ScalarAuthClient(); @@ -82,9 +88,15 @@ export default class Stickerpicker extends React.Component { if (!this.state.imError) { this.dispatcherRef = dis.register(this._onWidgetAction); } + const stickerpickerWidget = Widgets.getStickerpickerWidgets()[0]; + this.setState({ + stickerpickerWidget, + widgetId: stickerpickerWidget ? stickerpickerWidget.id : null, + }); } componentWillUnmount() { + window.removeEventListener('resize', this._onResize); if (this.dispatcherRef) { dis.unregister(this.dispatcherRef); } @@ -102,9 +114,7 @@ export default class Stickerpicker extends React.Component { if (payload.action === "user_widget_updated") { this.forceUpdate(); } else if (payload.action === "stickerpicker_close") { - // Wrap this in a timeout in order to avoid the DOM node from being - // pulled from under its feet - setTimeout(() => this.stickersMenu.close()); + this.setState({showStickers: false}); } } @@ -137,14 +147,13 @@ export default class Stickerpicker extends React.Component { // TODO - Add support for Stickerpickers from multiple app stores. // Render content from multiple stickerpack sources, each within their // own iframe, within the stickerpicker UI element. - const stickerpickerWidget = Widgets.getStickerpickerWidgets()[0]; + const stickerpickerWidget = this.state.stickerpickerWidget; let stickersContent; // Load stickerpack content if (stickerpickerWidget && stickerpickerWidget.content && stickerpickerWidget.content.url) { // Set default name stickerpickerWidget.content.name = stickerpickerWidget.name || _t("Stickerpack"); - this.widgetId = stickerpickerWidget.id; stickersContent = (
    @@ -187,12 +196,7 @@ export default class Stickerpicker extends React.Component { // Default content to show if stickerpicker widget not added console.warn("No available sticker picker widgets"); stickersContent = this._defaultStickerpickerContent(); - this.widgetId = null; - this.forceUpdate(); } - this.setState({ - showStickers: false, - }); return stickersContent; } @@ -202,29 +206,17 @@ export default class Stickerpicker extends React.Component { * @param {Event} e Event that triggered the function */ _onShowStickersClick(e) { - const GenericElementContextMenu = sdk.getComponent('context_menus.GenericElementContextMenu'); const buttonRect = e.target.getBoundingClientRect(); // The window X and Y offsets are to adjust position when zoomed in to page const x = buttonRect.right + window.pageXOffset - 42; const y = (buttonRect.top + (buttonRect.height / 2) + window.pageYOffset) - 19; - // const self = this; - this.stickersMenu = ContextualMenu.createMenu(GenericElementContextMenu, { - chevronOffset: 10, - chevronFace: 'bottom', - left: x, - top: y, - menuWidth: this.popoverWidth, - menuHeight: this.popoverHeight, - element: this._getStickerpickerContent(), - onFinished: this._onFinished, - menuPaddingTop: 0, - menuPaddingLeft: 0, - menuPaddingRight: 0, + + this.setState({ + showStickers: true, + stickerPickerX: x, + stickerPickerY: y, }); - - - this.setState({showStickers: true}); } /** @@ -232,7 +224,14 @@ export default class Stickerpicker extends React.Component { * @param {Event} ev Event that triggered the function call */ _onHideStickersClick(ev) { - setTimeout(() => this.stickersMenu.close()); + this.setState({showStickers: false}); + } + + /** + * Called when the window is resized + */ + _onResize() { + this.setState({showStickers: false}); } /** @@ -251,20 +250,37 @@ export default class Stickerpicker extends React.Component { this.scalarClient.getScalarInterfaceUrlForRoom( this.props.room, 'type_' + widgetType, - this.widgetId, + this.state.widgetId, ) : null; Modal.createTrackedDialog('Integrations Manager', '', IntegrationsManager, { src: src, }, "mx_IntegrationsManager"); - // Wrap this in a timeout in order to avoid the DOM node from being pulled from under its feet - setTimeout(() => this.stickersMenu.close()); + this.setState({showStickers: false}); } render() { const TintableSvg = sdk.getComponent("elements.TintableSvg"); + const ContextualMenu = sdk.getComponent('structures.ContextualMenu'); + const GenericElementContextMenu = sdk.getComponent('context_menus.GenericElementContextMenu'); let stickersButton; + + const stickerPicker = ; + if (this.state.showStickers) { // Show hide-stickers button stickersButton = @@ -289,6 +305,9 @@ export default class Stickerpicker extends React.Component {
    ; } - return stickersButton; + return
    + {stickersButton} + {this.state.showStickers && stickerPicker} +
    ; } } From 6500797d2aa0b7b61e48bc8464605e5e9c4e4242 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 11 May 2018 14:49:50 +0100 Subject: [PATCH 1069/1160] Use correct CSS selector in message composer to stop any last div from having its right-padding removed --- res/css/views/rooms/_MessageComposer.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/rooms/_MessageComposer.scss b/res/css/views/rooms/_MessageComposer.scss index 2e8f07b7ef..0a708a8edc 100644 --- a/res/css/views/rooms/_MessageComposer.scss +++ b/res/css/views/rooms/_MessageComposer.scss @@ -34,7 +34,7 @@ limitations under the License. width: 100%; } -.mx_MessageComposer_row div:last-child{ +.mx_MessageComposer_row > div:last-child{ padding-right: 0; } From 746eeee33cbc0f56061bc7c42d4dd081ae6f2324 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 11 May 2018 15:07:51 +0100 Subject: [PATCH 1070/1160] Make AppTile in Stickerpicker persistent using PersistedElement --- .../views/elements/PersistedElement.js | 116 ++++++++++++++++++ src/components/views/rooms/Stickerpicker.js | 7 ++ 2 files changed, 123 insertions(+) create mode 100644 src/components/views/elements/PersistedElement.js diff --git a/src/components/views/elements/PersistedElement.js b/src/components/views/elements/PersistedElement.js new file mode 100644 index 0000000000..4d8cd4140e --- /dev/null +++ b/src/components/views/elements/PersistedElement.js @@ -0,0 +1,116 @@ +/* +Copyright 2018 New Vector Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +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. +*/ + +const classNames = require('classnames'); +const React = require('react'); +const ReactDOM = require('react-dom'); +import PropTypes from 'prop-types'; + +// Shamelessly ripped off Modal.js. There's probably a better way +// of doing reusable widgets like dialog boxes & menus where we go and +// pass in a custom control as the actual body. + +const ContainerId = "mx_PersistedElement"; + +function getOrCreateContainer() { + let container = document.getElementById(ContainerId); + + if (!container) { + container = document.createElement("div"); + container.id = ContainerId; + document.body.appendChild(container); + } + + return container; +} + +// Greater than that of the ContextualMenu +const PE_Z_INDEX = 3000; + +/* + * Class of component that renders its children in a separate ReactDOM virtual tree + * in a container element appended to document.body. + * + * This prevents the children from being unmounted when the parent of PersistedElement + * unmounts, allowing them to persist. + * + * When PE is unmounted, it hides the children using CSS. When mounted or updated, the + * children are made visible and are positioned into a div that is given the same + * bounding rect as the parent of PE. + */ +export default class PersistedElement extends React.Component { + constructor() { + super(); + this.collectChildContainer = this.collectChildContainer.bind(this); + this.collectChild = this.collectChild.bind(this); + } + + collectChildContainer(ref) { + this.childContainer = ref; + } + + collectChild(ref) { + this.child = ref; + this.updateChild(); + } + + componentDidMount() { + this.updateChild(); + } + + componentDidUpdate() { + this.updateChild(); + } + + componentWillUnmount() { + this.updateChildVisibility(this.child, false); + } + + updateChild() { + this.updateChildPosition(this.child, this.childContainer); + this.updateChildVisibility(this.child, true); + } + + updateChildVisibility(child, visible) { + if (!child) return; + child.style.display = visible ? 'block' : 'none'; + } + + updateChildPosition(child, parent) { + if (!child || !parent) return; + + const parentRect = parent.getBoundingClientRect(); + Object.assign(child.style, { + position: 'absolute', + top: parentRect.top + 'px', + left: parentRect.left + 'px', + width: parentRect.width + 'px', + height: parentRect.height + 'px', + zIndex: PE_Z_INDEX, + }); + } + + render() { + const content =
    + {this.props.children} +
    ; + + ReactDOM.render(content, getOrCreateContainer()); + + return
    ; + } +} + diff --git a/src/components/views/rooms/Stickerpicker.js b/src/components/views/rooms/Stickerpicker.js index 8784599238..36b99b2422 100644 --- a/src/components/views/rooms/Stickerpicker.js +++ b/src/components/views/rooms/Stickerpicker.js @@ -150,6 +150,11 @@ export default class Stickerpicker extends React.Component { const stickerpickerWidget = this.state.stickerpickerWidget; let stickersContent; + // Use a separate ReactDOM tree to render the AppTile separately so that it persists and does + // not unmount when we (a) close the sticker picker (b) switch rooms. It's properties are still + // updated. + const PersistedElement = sdk.getComponent("elements.PersistedElement"); + // Load stickerpack content if (stickerpickerWidget && stickerpickerWidget.content && stickerpickerWidget.content.url) { // Set default name @@ -166,6 +171,7 @@ export default class Stickerpicker extends React.Component { width: this.popoverWidth, }} > + +
    ); From 4b6378a80d5f415c85eba76bce76c00b3d8050c4 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 11 May 2018 16:22:54 +0100 Subject: [PATCH 1071/1160] Add API to send visibiliy actions to widgets --- src/WidgetMessaging.js | 10 ++++++++++ src/components/views/elements/AppTile.js | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/src/WidgetMessaging.js b/src/WidgetMessaging.js index effd96dacf..86eaa0b59b 100644 --- a/src/WidgetMessaging.js +++ b/src/WidgetMessaging.js @@ -94,6 +94,16 @@ export default class WidgetMessaging { }); } + sendVisibility(visible) { + return this.messageToWidget({ + api: OUTBOUND_API_NAME, + action: "visibility", + visible, + }) + .catch((error) => { + console.error("Failed to send visibility: ", error); + }); + } start() { this.fromWidget.addEndpoint(this.widgetId, this.widgetUrl); diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 63cf459987..0701117ab3 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -394,6 +394,10 @@ export default class AppTile extends React.Component { }).catch((err) => { console.log(`Failed to get capabilities for widget type ${this.props.type}`, this.props.id, err); }); + + // Allow parents to access widget messaging + if (this.props.collectWidgetMessaging) this.props.collectWidgetMessaging(this.widgetMessaging); + this.setState({loading: false}); } From 8b049b2182b8425144ed16d3ed1485e2bd33f467 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 11 May 2018 16:23:18 +0100 Subject: [PATCH 1072/1160] When stickerpicker made visible, send visibility over postMessage --- src/components/views/elements/AppTile.js | 19 ++++++++++++++++--- src/components/views/rooms/Stickerpicker.js | 19 ++++++++++++++++++- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 0701117ab3..b5d317ae59 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -167,6 +167,19 @@ export default class AppTile extends React.Component { // Widget action listeners this.dispatcherRef = dis.register(this._onWidgetAction); + + } + + componentDidUpdate() { + // Allow parents to access widget messaging + if (this.props.collectWidgetMessaging) { + this.props.collectWidgetMessaging(new Promise((resolve) => { + if (this.widgetMessaging) resolve(this.widgetMessaging); + + // Expect this to be resolved later + this._exposeWidgetMessaging = resolve; + })); + } } componentWillUnmount() { @@ -357,6 +370,9 @@ export default class AppTile extends React.Component { if (!this.widgetMessaging) { this._onInitialLoad(); } + if (this._exposeWidgetMessaging) { + this._exposeWidgetMessaging(this.widgetMessaging); + } } /** @@ -395,9 +411,6 @@ export default class AppTile extends React.Component { console.log(`Failed to get capabilities for widget type ${this.props.type}`, this.props.id, err); }); - // Allow parents to access widget messaging - if (this.props.collectWidgetMessaging) this.props.collectWidgetMessaging(this.widgetMessaging); - this.setState({loading: false}); } diff --git a/src/components/views/rooms/Stickerpicker.js b/src/components/views/rooms/Stickerpicker.js index 36b99b2422..75d5e3acf4 100644 --- a/src/components/views/rooms/Stickerpicker.js +++ b/src/components/views/rooms/Stickerpicker.js @@ -38,6 +38,8 @@ export default class Stickerpicker extends React.Component { this._onResize = this._onResize.bind(this); this._onFinished = this._onFinished.bind(this); + this._collectWidgetMessaging = this._collectWidgetMessaging.bind(this); + this.popoverWidth = 300; this.popoverHeight = 300; @@ -102,6 +104,14 @@ export default class Stickerpicker extends React.Component { } } + componentDidUpdate(prevProps, prevState) { + if (this._appWidgetMessaging && + prevState.showStickers !== this.state.showStickers + ) { + this._appWidgetMessaging.sendVisibility(this.state.showStickers); + } + } + _imError(errorMsg, e) { console.error(errorMsg, e); this.setState({ @@ -137,6 +147,12 @@ export default class Stickerpicker extends React.Component { ); } + async _collectWidgetMessaging(prom) { + const widgetMessaging = await prom; + this._appWidgetMessaging = widgetMessaging; + this._appWidgetMessaging.sendVisibility(true); + } + _getStickerpickerContent() { // Handle Integration Manager errors if (this.state._imError) { @@ -173,6 +189,7 @@ export default class Stickerpicker extends React.Component { > From 1f2f3474ed6a92b8f1648af8a7dc132a2cbebc80 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 11 May 2018 17:28:12 +0100 Subject: [PATCH 1073/1160] Delinting --- src/components/structures/ContextualMenu.js | 5 +++-- src/components/views/elements/AppTile.js | 1 - src/components/views/elements/PersistedElement.js | 2 -- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/components/structures/ContextualMenu.js b/src/components/structures/ContextualMenu.js index 17f1a23e14..daac294d12 100644 --- a/src/components/structures/ContextualMenu.js +++ b/src/components/structures/ContextualMenu.js @@ -173,12 +173,13 @@ export function createMenu(ElementClass, props) { } }; + // We only reference closeMenu once per call to createMenu const menu = ; ReactDOM.render(menu, getOrCreateContainer()); diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index b5d317ae59..1b58778be4 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -167,7 +167,6 @@ export default class AppTile extends React.Component { // Widget action listeners this.dispatcherRef = dis.register(this._onWidgetAction); - } componentDidUpdate() { diff --git a/src/components/views/elements/PersistedElement.js b/src/components/views/elements/PersistedElement.js index 4d8cd4140e..c4bac27b4e 100644 --- a/src/components/views/elements/PersistedElement.js +++ b/src/components/views/elements/PersistedElement.js @@ -14,10 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -const classNames = require('classnames'); const React = require('react'); const ReactDOM = require('react-dom'); -import PropTypes from 'prop-types'; // Shamelessly ripped off Modal.js. There's probably a better way // of doing reusable widgets like dialog boxes & menus where we go and From 06898394eb044c22422f246e3202f9d378ad5331 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 11 May 2018 18:06:58 +0100 Subject: [PATCH 1074/1160] Send visibility only when changed, and messaging is available --- src/components/views/elements/AppTile.js | 7 +------ src/components/views/rooms/Stickerpicker.js | 21 +++++++++++++-------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 1b58778be4..38b6fc200b 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -172,12 +172,7 @@ export default class AppTile extends React.Component { componentDidUpdate() { // Allow parents to access widget messaging if (this.props.collectWidgetMessaging) { - this.props.collectWidgetMessaging(new Promise((resolve) => { - if (this.widgetMessaging) resolve(this.widgetMessaging); - - // Expect this to be resolved later - this._exposeWidgetMessaging = resolve; - })); + this.props.collectWidgetMessaging(this.widgetMessaging); } } diff --git a/src/components/views/rooms/Stickerpicker.js b/src/components/views/rooms/Stickerpicker.js index 75d5e3acf4..0584cd6b0a 100644 --- a/src/components/views/rooms/Stickerpicker.js +++ b/src/components/views/rooms/Stickerpicker.js @@ -105,11 +105,7 @@ export default class Stickerpicker extends React.Component { } componentDidUpdate(prevProps, prevState) { - if (this._appWidgetMessaging && - prevState.showStickers !== this.state.showStickers - ) { - this._appWidgetMessaging.sendVisibility(this.state.showStickers); - } + this._sendVisibilityToWidget(this.state.showStickers); } _imError(errorMsg, e) { @@ -147,10 +143,19 @@ export default class Stickerpicker extends React.Component { ); } - async _collectWidgetMessaging(prom) { - const widgetMessaging = await prom; + _collectWidgetMessaging(widgetMessaging) { this._appWidgetMessaging = widgetMessaging; - this._appWidgetMessaging.sendVisibility(true); + + // Do this now instead of in componentDidMount because we might not have had the + // reference to widgetMessaging when mounting + this._sendVisibilityToWidget(true); + } + + _sendVisibilityToWidget(visible) { + if (this._appWidgetMessaging && visible !== this._prevSentVisibility) { + this._appWidgetMessaging.sendVisibility(visible); + this._prevSentVisibility = visible; + } } _getStickerpickerContent() { From d503c86576380c4a7bdf1504ea4b8cdb76d3c37c Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 10 May 2018 16:00:58 +0100 Subject: [PATCH 1075/1160] Factor out ContextualMenu component --- src/components/structures/ContextualMenu.js | 88 +++++++++++---------- 1 file changed, 47 insertions(+), 41 deletions(-) diff --git a/src/components/structures/ContextualMenu.js b/src/components/structures/ContextualMenu.js index 0e2df890f3..99d1f892b9 100644 --- a/src/components/structures/ContextualMenu.js +++ b/src/components/structures/ContextualMenu.js @@ -26,9 +26,21 @@ import PropTypes from 'prop-types'; // of doing reusable widgets like dialog boxes & menus where we go and // pass in a custom control as the actual body. -module.exports = { - ContextualMenuContainerId: "mx_ContextualMenu_Container", +const ContextualMenuContainerId = "mx_ContextualMenu_Container"; +function getOrCreateContainer() { + let container = document.getElementById(ContextualMenuContainerId); + + if (!container) { + container = document.createElement("div"); + container.id = ContextualMenuContainerId; + document.body.appendChild(container); + } + + return container; +} + +class ContextualMenu extends React.Component { propTypes: { top: PropTypes.number, bottom: PropTypes.number, @@ -45,39 +57,14 @@ module.exports = { menuPaddingRight: PropTypes.number, menuPaddingBottom: PropTypes.number, menuPaddingLeft: PropTypes.number, - }, - - getOrCreateContainer: function() { - let container = document.getElementById(this.ContextualMenuContainerId); - - if (!container) { - container = document.createElement("div"); - container.id = this.ContextualMenuContainerId; - document.body.appendChild(container); - } - - return container; - }, - - createMenu: function(Element, props) { - const self = this; - - const closeMenu = function(...args) { - ReactDOM.unmountComponentAtNode(self.getOrCreateContainer()); - - if (props && props.onFinished) { - props.onFinished.apply(null, args); - } - }; - - // Close the menu on window resize - const windowResize = function() { - closeMenu(); - }; + } + render() { const position = {}; let chevronFace = null; + const props = this.props; + if (props.top) { position.top = props.top; } else { @@ -158,20 +145,39 @@ module.exports = { menuStyle["paddingRight"] = props.menuPaddingRight; } + const ElementClass = props.elementClass; + // FIXME: If a menu uses getDefaultProps it clobbers the onFinished // property set here so you can't close the menu from a button click! - const menu = ( -
    -
    - { chevron } - -
    -
    - + return
    +
    + { chevron } +
    - ); +
    + +
    ; + } +} - ReactDOM.render(menu, this.getOrCreateContainer()); +module.exports = { + createMenu: function(ElementClass, props) { + const closeMenu = function(...args) { + ReactDOM.unmountComponentAtNode(getOrCreateContainer()); + + if (props && props.onFinished) { + props.onFinished.apply(null, args); + } + }; + + const menu = ; + + ReactDOM.render(menu, getOrCreateContainer()); return {close: closeMenu}; }, From 9ec2570eab2330e6e079fad1537af28f0f1996ee Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 10 May 2018 17:51:49 +0100 Subject: [PATCH 1076/1160] Export ContextualMenu component, with added `hasBackground` property , which is only enabled when `createMenu` is used. --- src/components/structures/ContextualMenu.js | 43 +++++++++++---------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/src/components/structures/ContextualMenu.js b/src/components/structures/ContextualMenu.js index 99d1f892b9..17f1a23e14 100644 --- a/src/components/structures/ContextualMenu.js +++ b/src/components/structures/ContextualMenu.js @@ -40,7 +40,7 @@ function getOrCreateContainer() { return container; } -class ContextualMenu extends React.Component { +export default class ContextualMenu extends React.Component { propTypes: { top: PropTypes.number, bottom: PropTypes.number, @@ -57,6 +57,10 @@ class ContextualMenu extends React.Component { menuPaddingRight: PropTypes.number, menuPaddingBottom: PropTypes.number, menuPaddingLeft: PropTypes.number, + + // If true, insert an invisible screen-sized element behind the + // menu that when clicked will close it. + hasBackground: PropTypes.bool, } render() { @@ -154,31 +158,30 @@ class ContextualMenu extends React.Component { { chevron }
    -
    + { props.hasBackground &&
    }
    ; } } -module.exports = { - createMenu: function(ElementClass, props) { - const closeMenu = function(...args) { - ReactDOM.unmountComponentAtNode(getOrCreateContainer()); +export function createMenu(ElementClass, props) { + const closeMenu = function(...args) { + ReactDOM.unmountComponentAtNode(getOrCreateContainer()); - if (props && props.onFinished) { - props.onFinished.apply(null, args); - } - }; + if (props && props.onFinished) { + props.onFinished.apply(null, args); + } + }; - const menu = ; + const menu = ; - ReactDOM.render(menu, getOrCreateContainer()); + ReactDOM.render(menu, getOrCreateContainer()); - return {close: closeMenu}; - }, -}; + return {close: closeMenu}; +} From 2d2b529f80f8805bdce7d39c27ac0f61397c388d Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 11 May 2018 14:47:57 +0100 Subject: [PATCH 1077/1160] Use new ContextualMenu component in Stickerpicker --- src/components/views/rooms/Stickerpicker.js | 93 +++++++++++++-------- 1 file changed, 56 insertions(+), 37 deletions(-) diff --git a/src/components/views/rooms/Stickerpicker.js b/src/components/views/rooms/Stickerpicker.js index c055c67cd3..a252c0c886 100644 --- a/src/components/views/rooms/Stickerpicker.js +++ b/src/components/views/rooms/Stickerpicker.js @@ -17,7 +17,6 @@ import React from 'react'; import { _t } from '../../../languageHandler'; import Widgets from '../../../utils/widgets'; import AppTile from '../elements/AppTile'; -import ContextualMenu from '../../structures/ContextualMenu'; import MatrixClientPeg from '../../../MatrixClientPeg'; import Modal from '../../../Modal'; import sdk from '../../../index'; @@ -36,6 +35,7 @@ export default class Stickerpicker extends React.Component { this._launchManageIntegrations = this._launchManageIntegrations.bind(this); this._removeStickerpickerWidgets = this._removeStickerpickerWidgets.bind(this); this._onWidgetAction = this._onWidgetAction.bind(this); + this._onResize = this._onResize.bind(this); this._onFinished = this._onFinished.bind(this); this.popoverWidth = 300; @@ -44,13 +44,17 @@ export default class Stickerpicker extends React.Component { this.state = { showStickers: false, imError: null, + stickerpickerX: null, + stickerpickerY: null, + stickerpickerWidget: null, + widgetId: null, }; } _removeStickerpickerWidgets() { console.warn('Removing Stickerpicker widgets'); - if (this.widgetId) { - this.scalarClient.disableWidgetAssets(widgetType, this.widgetId).then(() => { + if (this.state.widgetId) { + this.scalarClient.disableWidgetAssets(widgetType, this.state.widgetId).then(() => { console.warn('Assets disabled'); }).catch((err) => { console.error('Failed to disable assets'); @@ -59,8 +63,7 @@ export default class Stickerpicker extends React.Component { console.warn('No widget ID specified, not disabling assets'); } - // Wrap this in a timeout in order to avoid the DOM node from being pulled from under its feet - setTimeout(() => this.stickersMenu.close()); + this.setState({showStickers: false}); Widgets.removeStickerpickerWidgets().then(() => { this.forceUpdate(); }).catch((e) => { @@ -69,6 +72,9 @@ export default class Stickerpicker extends React.Component { } componentDidMount() { + // Close the sticker picker when the window resizes + window.addEventListener('resize', this._onResize); + this.scalarClient = null; if (SdkConfig.get().integrations_ui_url && SdkConfig.get().integrations_rest_url) { this.scalarClient = new ScalarAuthClient(); @@ -82,9 +88,15 @@ export default class Stickerpicker extends React.Component { if (!this.state.imError) { this.dispatcherRef = dis.register(this._onWidgetAction); } + const stickerpickerWidget = Widgets.getStickerpickerWidgets()[0]; + this.setState({ + stickerpickerWidget, + widgetId: stickerpickerWidget ? stickerpickerWidget.id : null, + }); } componentWillUnmount() { + window.removeEventListener('resize', this._onResize); if (this.dispatcherRef) { dis.unregister(this.dispatcherRef); } @@ -102,9 +114,7 @@ export default class Stickerpicker extends React.Component { if (payload.action === "user_widget_updated") { this.forceUpdate(); } else if (payload.action === "stickerpicker_close") { - // Wrap this in a timeout in order to avoid the DOM node from being - // pulled from under its feet - setTimeout(() => this.stickersMenu.close()); + this.setState({showStickers: false}); } } @@ -137,14 +147,13 @@ export default class Stickerpicker extends React.Component { // TODO - Add support for Stickerpickers from multiple app stores. // Render content from multiple stickerpack sources, each within their // own iframe, within the stickerpicker UI element. - const stickerpickerWidget = Widgets.getStickerpickerWidgets()[0]; + const stickerpickerWidget = this.state.stickerpickerWidget; let stickersContent; // Load stickerpack content if (stickerpickerWidget && stickerpickerWidget.content && stickerpickerWidget.content.url) { // Set default name stickerpickerWidget.content.name = stickerpickerWidget.name || _t("Stickerpack"); - this.widgetId = stickerpickerWidget.id; stickersContent = (
    @@ -186,12 +195,7 @@ export default class Stickerpicker extends React.Component { // Default content to show if stickerpicker widget not added console.warn("No available sticker picker widgets"); stickersContent = this._defaultStickerpickerContent(); - this.widgetId = null; - this.forceUpdate(); } - this.setState({ - showStickers: false, - }); return stickersContent; } @@ -201,29 +205,17 @@ export default class Stickerpicker extends React.Component { * @param {Event} e Event that triggered the function */ _onShowStickersClick(e) { - const GenericElementContextMenu = sdk.getComponent('context_menus.GenericElementContextMenu'); const buttonRect = e.target.getBoundingClientRect(); // The window X and Y offsets are to adjust position when zoomed in to page const x = buttonRect.right + window.pageXOffset - 42; const y = (buttonRect.top + (buttonRect.height / 2) + window.pageYOffset) - 19; - // const self = this; - this.stickersMenu = ContextualMenu.createMenu(GenericElementContextMenu, { - chevronOffset: 10, - chevronFace: 'bottom', - left: x, - top: y, - menuWidth: this.popoverWidth, - menuHeight: this.popoverHeight, - element: this._getStickerpickerContent(), - onFinished: this._onFinished, - menuPaddingTop: 0, - menuPaddingLeft: 0, - menuPaddingRight: 0, + + this.setState({ + showStickers: true, + stickerPickerX: x, + stickerPickerY: y, }); - - - this.setState({showStickers: true}); } /** @@ -231,7 +223,14 @@ export default class Stickerpicker extends React.Component { * @param {Event} ev Event that triggered the function call */ _onHideStickersClick(ev) { - setTimeout(() => this.stickersMenu.close()); + this.setState({showStickers: false}); + } + + /** + * Called when the window is resized + */ + _onResize() { + this.setState({showStickers: false}); } /** @@ -250,20 +249,37 @@ export default class Stickerpicker extends React.Component { this.scalarClient.getScalarInterfaceUrlForRoom( this.props.room, 'type_' + widgetType, - this.widgetId, + this.state.widgetId, ) : null; Modal.createTrackedDialog('Integrations Manager', '', IntegrationsManager, { src: src, }, "mx_IntegrationsManager"); - // Wrap this in a timeout in order to avoid the DOM node from being pulled from under its feet - setTimeout(() => this.stickersMenu.close()); + this.setState({showStickers: false}); } render() { const TintableSvg = sdk.getComponent("elements.TintableSvg"); + const ContextualMenu = sdk.getComponent('structures.ContextualMenu'); + const GenericElementContextMenu = sdk.getComponent('context_menus.GenericElementContextMenu'); let stickersButton; + + const stickerPicker = ; + if (this.state.showStickers) { // Show hide-stickers button stickersButton = @@ -288,6 +304,9 @@ export default class Stickerpicker extends React.Component {
    ; } - return stickersButton; + return
    + {stickersButton} + {this.state.showStickers && stickerPicker} +
    ; } } From fee480289ce4ab31173f55f3a4eec30521e39e0b Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 11 May 2018 14:49:50 +0100 Subject: [PATCH 1078/1160] Use correct CSS selector in message composer to stop any last div from having its right-padding removed --- res/css/views/rooms/_MessageComposer.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/rooms/_MessageComposer.scss b/res/css/views/rooms/_MessageComposer.scss index 2e8f07b7ef..0a708a8edc 100644 --- a/res/css/views/rooms/_MessageComposer.scss +++ b/res/css/views/rooms/_MessageComposer.scss @@ -34,7 +34,7 @@ limitations under the License. width: 100%; } -.mx_MessageComposer_row div:last-child{ +.mx_MessageComposer_row > div:last-child{ padding-right: 0; } From 42c59b59239bacd4a6652986f2338a80d8bd9c5e Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 11 May 2018 15:07:51 +0100 Subject: [PATCH 1079/1160] Make AppTile in Stickerpicker persistent using PersistedElement --- .../views/elements/PersistedElement.js | 116 ++++++++++++++++++ src/components/views/rooms/Stickerpicker.js | 7 ++ 2 files changed, 123 insertions(+) create mode 100644 src/components/views/elements/PersistedElement.js diff --git a/src/components/views/elements/PersistedElement.js b/src/components/views/elements/PersistedElement.js new file mode 100644 index 0000000000..4d8cd4140e --- /dev/null +++ b/src/components/views/elements/PersistedElement.js @@ -0,0 +1,116 @@ +/* +Copyright 2018 New Vector Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +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. +*/ + +const classNames = require('classnames'); +const React = require('react'); +const ReactDOM = require('react-dom'); +import PropTypes from 'prop-types'; + +// Shamelessly ripped off Modal.js. There's probably a better way +// of doing reusable widgets like dialog boxes & menus where we go and +// pass in a custom control as the actual body. + +const ContainerId = "mx_PersistedElement"; + +function getOrCreateContainer() { + let container = document.getElementById(ContainerId); + + if (!container) { + container = document.createElement("div"); + container.id = ContainerId; + document.body.appendChild(container); + } + + return container; +} + +// Greater than that of the ContextualMenu +const PE_Z_INDEX = 3000; + +/* + * Class of component that renders its children in a separate ReactDOM virtual tree + * in a container element appended to document.body. + * + * This prevents the children from being unmounted when the parent of PersistedElement + * unmounts, allowing them to persist. + * + * When PE is unmounted, it hides the children using CSS. When mounted or updated, the + * children are made visible and are positioned into a div that is given the same + * bounding rect as the parent of PE. + */ +export default class PersistedElement extends React.Component { + constructor() { + super(); + this.collectChildContainer = this.collectChildContainer.bind(this); + this.collectChild = this.collectChild.bind(this); + } + + collectChildContainer(ref) { + this.childContainer = ref; + } + + collectChild(ref) { + this.child = ref; + this.updateChild(); + } + + componentDidMount() { + this.updateChild(); + } + + componentDidUpdate() { + this.updateChild(); + } + + componentWillUnmount() { + this.updateChildVisibility(this.child, false); + } + + updateChild() { + this.updateChildPosition(this.child, this.childContainer); + this.updateChildVisibility(this.child, true); + } + + updateChildVisibility(child, visible) { + if (!child) return; + child.style.display = visible ? 'block' : 'none'; + } + + updateChildPosition(child, parent) { + if (!child || !parent) return; + + const parentRect = parent.getBoundingClientRect(); + Object.assign(child.style, { + position: 'absolute', + top: parentRect.top + 'px', + left: parentRect.left + 'px', + width: parentRect.width + 'px', + height: parentRect.height + 'px', + zIndex: PE_Z_INDEX, + }); + } + + render() { + const content =
    + {this.props.children} +
    ; + + ReactDOM.render(content, getOrCreateContainer()); + + return
    ; + } +} + diff --git a/src/components/views/rooms/Stickerpicker.js b/src/components/views/rooms/Stickerpicker.js index a252c0c886..5c411aa56e 100644 --- a/src/components/views/rooms/Stickerpicker.js +++ b/src/components/views/rooms/Stickerpicker.js @@ -150,6 +150,11 @@ export default class Stickerpicker extends React.Component { const stickerpickerWidget = this.state.stickerpickerWidget; let stickersContent; + // Use a separate ReactDOM tree to render the AppTile separately so that it persists and does + // not unmount when we (a) close the sticker picker (b) switch rooms. It's properties are still + // updated. + const PersistedElement = sdk.getComponent("elements.PersistedElement"); + // Load stickerpack content if (stickerpickerWidget && stickerpickerWidget.content && stickerpickerWidget.content.url) { // Set default name @@ -166,6 +171,7 @@ export default class Stickerpicker extends React.Component { width: this.popoverWidth, }} > + +
    ); From bd0301c666686e389b966f9038a494f8f061390e Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 11 May 2018 16:22:54 +0100 Subject: [PATCH 1080/1160] Add API to send visibiliy actions to widgets --- src/WidgetMessaging.js | 10 ++++++++++ src/components/views/elements/AppTile.js | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/src/WidgetMessaging.js b/src/WidgetMessaging.js index effd96dacf..86eaa0b59b 100644 --- a/src/WidgetMessaging.js +++ b/src/WidgetMessaging.js @@ -94,6 +94,16 @@ export default class WidgetMessaging { }); } + sendVisibility(visible) { + return this.messageToWidget({ + api: OUTBOUND_API_NAME, + action: "visibility", + visible, + }) + .catch((error) => { + console.error("Failed to send visibility: ", error); + }); + } start() { this.fromWidget.addEndpoint(this.widgetId, this.widgetUrl); diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 7c4ab13c5a..e1be5b11ee 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -389,6 +389,10 @@ export default class AppTile extends React.Component { }).catch((err) => { console.log(`Failed to get capabilities for widget type ${this.props.type}`, this.props.id, err); }); + + // Allow parents to access widget messaging + if (this.props.collectWidgetMessaging) this.props.collectWidgetMessaging(this.widgetMessaging); + this.setState({loading: false}); } From 06919e22d633a7f0c12b1f91870d2cbe8a1b7126 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 11 May 2018 16:23:18 +0100 Subject: [PATCH 1081/1160] When stickerpicker made visible, send visibility over postMessage --- src/components/views/elements/AppTile.js | 19 ++++++++++++++++--- src/components/views/rooms/Stickerpicker.js | 19 ++++++++++++++++++- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index e1be5b11ee..5bcb418242 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -167,6 +167,19 @@ export default class AppTile extends React.Component { // Widget action listeners this.dispatcherRef = dis.register(this._onWidgetAction); + + } + + componentDidUpdate() { + // Allow parents to access widget messaging + if (this.props.collectWidgetMessaging) { + this.props.collectWidgetMessaging(new Promise((resolve) => { + if (this.widgetMessaging) resolve(this.widgetMessaging); + + // Expect this to be resolved later + this._exposeWidgetMessaging = resolve; + })); + } } componentWillUnmount() { @@ -352,6 +365,9 @@ export default class AppTile extends React.Component { if (!this.widgetMessaging) { this._onInitialLoad(); } + if (this._exposeWidgetMessaging) { + this._exposeWidgetMessaging(this.widgetMessaging); + } } /** @@ -390,9 +406,6 @@ export default class AppTile extends React.Component { console.log(`Failed to get capabilities for widget type ${this.props.type}`, this.props.id, err); }); - // Allow parents to access widget messaging - if (this.props.collectWidgetMessaging) this.props.collectWidgetMessaging(this.widgetMessaging); - this.setState({loading: false}); } diff --git a/src/components/views/rooms/Stickerpicker.js b/src/components/views/rooms/Stickerpicker.js index 5c411aa56e..0bdf5fe5df 100644 --- a/src/components/views/rooms/Stickerpicker.js +++ b/src/components/views/rooms/Stickerpicker.js @@ -38,6 +38,8 @@ export default class Stickerpicker extends React.Component { this._onResize = this._onResize.bind(this); this._onFinished = this._onFinished.bind(this); + this._collectWidgetMessaging = this._collectWidgetMessaging.bind(this); + this.popoverWidth = 300; this.popoverHeight = 300; @@ -102,6 +104,14 @@ export default class Stickerpicker extends React.Component { } } + componentDidUpdate(prevProps, prevState) { + if (this._appWidgetMessaging && + prevState.showStickers !== this.state.showStickers + ) { + this._appWidgetMessaging.sendVisibility(this.state.showStickers); + } + } + _imError(errorMsg, e) { console.error(errorMsg, e); this.setState({ @@ -137,6 +147,12 @@ export default class Stickerpicker extends React.Component { ); } + async _collectWidgetMessaging(prom) { + const widgetMessaging = await prom; + this._appWidgetMessaging = widgetMessaging; + this._appWidgetMessaging.sendVisibility(true); + } + _getStickerpickerContent() { // Handle Integration Manager errors if (this.state._imError) { @@ -173,6 +189,7 @@ export default class Stickerpicker extends React.Component { >
    From a4190560405f96e14913103ac258f0ac09a91e61 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 11 May 2018 17:28:12 +0100 Subject: [PATCH 1082/1160] Delinting --- src/components/structures/ContextualMenu.js | 5 +++-- src/components/views/elements/AppTile.js | 1 - src/components/views/elements/PersistedElement.js | 2 -- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/components/structures/ContextualMenu.js b/src/components/structures/ContextualMenu.js index 17f1a23e14..daac294d12 100644 --- a/src/components/structures/ContextualMenu.js +++ b/src/components/structures/ContextualMenu.js @@ -173,12 +173,13 @@ export function createMenu(ElementClass, props) { } }; + // We only reference closeMenu once per call to createMenu const menu = ; ReactDOM.render(menu, getOrCreateContainer()); diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 5bcb418242..b345adcc1d 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -167,7 +167,6 @@ export default class AppTile extends React.Component { // Widget action listeners this.dispatcherRef = dis.register(this._onWidgetAction); - } componentDidUpdate() { diff --git a/src/components/views/elements/PersistedElement.js b/src/components/views/elements/PersistedElement.js index 4d8cd4140e..c4bac27b4e 100644 --- a/src/components/views/elements/PersistedElement.js +++ b/src/components/views/elements/PersistedElement.js @@ -14,10 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -const classNames = require('classnames'); const React = require('react'); const ReactDOM = require('react-dom'); -import PropTypes from 'prop-types'; // Shamelessly ripped off Modal.js. There's probably a better way // of doing reusable widgets like dialog boxes & menus where we go and From 9c5c5e282b619a726af57b0f3207d80451b2dff8 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 11 May 2018 18:06:58 +0100 Subject: [PATCH 1083/1160] Send visibility only when changed, and messaging is available --- src/components/views/elements/AppTile.js | 7 +------ src/components/views/rooms/Stickerpicker.js | 21 +++++++++++++-------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index b345adcc1d..cd0eb1ce68 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -172,12 +172,7 @@ export default class AppTile extends React.Component { componentDidUpdate() { // Allow parents to access widget messaging if (this.props.collectWidgetMessaging) { - this.props.collectWidgetMessaging(new Promise((resolve) => { - if (this.widgetMessaging) resolve(this.widgetMessaging); - - // Expect this to be resolved later - this._exposeWidgetMessaging = resolve; - })); + this.props.collectWidgetMessaging(this.widgetMessaging); } } diff --git a/src/components/views/rooms/Stickerpicker.js b/src/components/views/rooms/Stickerpicker.js index 0bdf5fe5df..40ce6e6b39 100644 --- a/src/components/views/rooms/Stickerpicker.js +++ b/src/components/views/rooms/Stickerpicker.js @@ -105,11 +105,7 @@ export default class Stickerpicker extends React.Component { } componentDidUpdate(prevProps, prevState) { - if (this._appWidgetMessaging && - prevState.showStickers !== this.state.showStickers - ) { - this._appWidgetMessaging.sendVisibility(this.state.showStickers); - } + this._sendVisibilityToWidget(this.state.showStickers); } _imError(errorMsg, e) { @@ -147,10 +143,19 @@ export default class Stickerpicker extends React.Component { ); } - async _collectWidgetMessaging(prom) { - const widgetMessaging = await prom; + _collectWidgetMessaging(widgetMessaging) { this._appWidgetMessaging = widgetMessaging; - this._appWidgetMessaging.sendVisibility(true); + + // Do this now instead of in componentDidMount because we might not have had the + // reference to widgetMessaging when mounting + this._sendVisibilityToWidget(true); + } + + _sendVisibilityToWidget(visible) { + if (this._appWidgetMessaging && visible !== this._prevSentVisibility) { + this._appWidgetMessaging.sendVisibility(visible); + this._prevSentVisibility = visible; + } } _getStickerpickerContent() { From a0bde2939ed4480110b02a6d9e81ee3c2a6cb94a Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 11 May 2018 18:26:35 +0100 Subject: [PATCH 1084/1160] Prepare changelog for v0.12.4-rc.3 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f8e89250e..89f3741535 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +Changes in [0.12.4-rc.3](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.12.4-rc.3) (2018-05-11) +=============================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.12.4-rc.2...v0.12.4-rc.3) + + * Instant Sticker Picker :zap: + [\#1888](https://github.com/matrix-org/matrix-react-sdk/pull/1888) + Changes in [0.12.4-rc.2](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.12.4-rc.2) (2018-05-09) =============================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.12.4-rc.1...v0.12.4-rc.2) From d90292c6f15ce8fc5b07d8ab3a2a3c0d0635f6ae Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 11 May 2018 18:26:35 +0100 Subject: [PATCH 1085/1160] v0.12.4-rc.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3958e1b3d0..1125dd3980 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.12.4-rc.2", + "version": "0.12.4-rc.3", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From dbbcabfed86d4a155696ebed805cf61000f3b4da Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 12 May 2018 15:57:33 +0100 Subject: [PATCH 1086/1160] switch from asymmetrical fallback form to a cleaner one `mx-reply` Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/HtmlUtils.js | 1 - src/components/views/elements/ReplyThread.js | 26 ++++++++++---------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index 82b6830b78..58572cf144 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -186,7 +186,6 @@ const sanitizeHtmlParams = { ], allowedAttributes: { // custom ones first: - blockquote: ['data-mx-reply'], // used to allow explicit removal of a reply fallback blockquote, value ignored font: ['color', 'data-mx-bg-color', 'data-mx-color', 'style'], // custom to matrix span: ['data-mx-bg-color', 'data-mx-color', 'style'], // custom to matrix a: ['href', 'name', 'target', 'rel'], // remote target: custom to matrix diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index cd444fb090..6714de81a4 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -81,7 +81,7 @@ export default class ReplyThread extends React.Component { // Part of Replies fallback support static stripHTMLReply(html) { - return html.replace(/^
    [\s\S]+?<\/blockquote>/, ''); + return html.replace(/^[\s\S]+?<\/mx-reply>/, ''); } // Part of Replies fallback support @@ -102,8 +102,8 @@ export default class ReplyThread extends React.Component { switch (ev.getContent().msgtype) { case 'm.text': case 'm.notice': { - html = `
    In reply to ${mxid}` - + `
    ${html || body}
    `; + html = `
    In reply to ${mxid}` + + `
    ${html || body}
    `; const lines = body.trim().split('\n'); if (lines.length > 0) { lines[0] = `<${mxid}> ${lines[0]}`; @@ -112,28 +112,28 @@ export default class ReplyThread extends React.Component { break; } case 'm.image': - html = `
    In reply to ${mxid}` - + `
    sent an image.
    `; + html = `
    In reply to ${mxid}` + + `
    sent an image.
    `; body = `> <${mxid}> sent an image.\n\n`; break; case 'm.video': - html = `
    In reply to ${mxid}` - + `
    sent a video.
    `; + html = `
    In reply to ${mxid}` + + `
    sent a video.
    `; body = `> <${mxid}> sent a video.\n\n`; break; case 'm.audio': - html = `
    In reply to ${mxid}` - + `
    sent an audio file.
    `; + html = `
    In reply to ${mxid}` + + `
    sent an audio file.
    `; body = `> <${mxid}> sent an audio file.\n\n`; break; case 'm.file': - html = `
    In reply to ${mxid}` - + `
    sent a file.
    `; + html = `
    In reply to ${mxid}` + + `
    sent a file.
    `; body = `> <${mxid}> sent a file.\n\n`; break; case 'm.emote': { - html = `
    In reply to * ` - + `${mxid}
    ${html || body}
    `; + html = `
    In reply to * ` + + `${mxid}
    ${html || body}
    `; const lines = body.trim().split('\n'); if (lines.length > 0) { lines[0] = `* <${mxid}> ${lines[0]}`; From e856e49fff6dffcb065b93887cfe8b7031f57711 Mon Sep 17 00:00:00 2001 From: Kenneth Larsson Date: Fri, 11 May 2018 23:04:09 +0000 Subject: [PATCH 1087/1160] Translated using Weblate (Swedish) Currently translated at 64.0% (752 of 1174 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sv/ --- src/i18n/strings/sv.json | 78 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 74 insertions(+), 4 deletions(-) diff --git a/src/i18n/strings/sv.json b/src/i18n/strings/sv.json index b2d6ac9ad9..e987ed29e2 100644 --- a/src/i18n/strings/sv.json +++ b/src/i18n/strings/sv.json @@ -19,7 +19,7 @@ "Advanced": "Avancerat", "Algorithm": "Algoritm", "Always show message timestamps": "Visa alltid tidsstämpel för meddelanden", - "Hide removed messages": "Göm raderade meddelanden", + "Hide removed messages": "Dölj borttagna meddelanden", "Authentication": "Autentisering", "%(items)s and %(lastItem)s": "%(items)s och %(lastItem)s", "and %(count)s others...|other": "och %(count)s andra...", @@ -301,7 +301,7 @@ "%(senderName)s requested a VoIP conference.": "%(senderName)s begärde en VoIP-konferens.", "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.": "Om du återställer ditt lösenord kommer alla krypteringsnycklar på alla enheter att återställas, vilket gör krypterad meddelandehistorik oläsbar om du inte först exporterar dina rumsnycklar och sedan importerar dem igen. I framtiden kommer det här att förbättras.", "Results from DuckDuckGo": "Resultat från DuckDuckGo", - "Return to login screen": "TIllbaka till login-skärmen", + "Return to login screen": "Tillbaka till login-skärmen", "Riot does not have permission to send you notifications - please check your browser settings": "Riot har inte tillstånd att skicka aviseringar - kontrollera webbläsarens inställningar", "Riot was not given permission to send notifications - please try again": "Riot fick inte tillstånd att skicka aviseringar - försök igen", "riot-web version:": "riot-web -version:", @@ -649,7 +649,7 @@ "(~%(count)s results)|one": "(~%(count)s resultat)", "Upload avatar": "Ladda upp profilbild", "Remove avatar": "Ta bort profilbild", - "This invitation was sent to an email address which is not associated with this account:": "Den här inbjudan skickades till en emailadress som inte är kopplad till detta konto:", + "This invitation was sent to an email address which is not associated with this account:": "Den här inbjudan skickades till en epostadress som inte är kopplad till detta konto:", "To link to a room it must have an address.": "För att länka till ett rum behöver det en adress.", "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (nivå %(powerLevelNumber)s)", "Unknown Address": "Okänd adress", @@ -682,5 +682,75 @@ "Riot bugs are tracked on GitHub: create a GitHub issue.": "Riot-buggar hanteras på GitHub: skapa en GitHub-issue.", "GitHub issue link:": "Länk till GitHub-issue:", "Notes:": "Noteringar:", - "Start new chat": "Starta ny chatt" + "Start new chat": "Starta ny chatt", + "Default server": "Standardserver", + "Custom server": "Anpassad server", + "Home server URL": "Hemserver-URL", + "Identity server URL": "Identitetsserver-URL", + "What does this mean?": "Vad betyder det här?", + "User name": "Användarnamn", + "Username on %(hs)s": "Användarnamn på %(hs)s", + "An email has been sent to %(emailAddress)s": "Ett epostmeddelande har skickats till %(emailAddress)s", + "To continue, please enter your password.": "För att fortsätta, vänligen ange ditt lösenord.", + "Please check your email to continue registration.": "Vänligen kolla din epost för att fortsätta registreringen.", + "Token incorrect": "Ogiltig token", + "A text message has been sent to %(msisdn)s": "Ett textmeddelande har skickats till %(msisdn)s", + "Please enter the code it contains:": "Vänligen ange koden det innehåller:", + "Code": "Kod", + "I already have an account": "Jag har redan ett konto", + "Sign in to get started": "Logga in för att komma igång", + "Set a display name:": "Ange ett visningsnamn:", + "Upload an avatar:": "Ladda upp en avatar:", + "This server does not support authentication with a phone number.": "Denna server har inte support för autentisering via telefonnummer.", + "Missing password.": "Lösenord saknas.", + "Passwords don't match.": "Lösenorden matchar inte.", + "Password too short (min %(MIN_PASSWORD_LENGTH)s).": "Lösenordet är för kort (min %(MIN_PASSWORD_LENGTH)s).", + "This doesn't look like a valid email address.": "Det här ser inte ut vara en giltig epostadress.", + "This doesn't look like a valid phone number.": "Det här ser inte ut att vara ett giltigt telefonnummer.", + "You need to enter a user name.": "Du måste ange ett användarnamn.", + "An unknown error occurred.": "Ett okänt fel uppstod.", + "Hide avatar changes": "Dölj avatarändringar", + "Hide display name changes": "Dölj visningsnamnsändringar", + "Uploading %(filename)s and %(count)s others|other": "Laddar upp %(filename)s och %(count)s andra", + "Uploading %(filename)s and %(count)s others|zero": "Laddar upp %(filename)s", + "Uploading %(filename)s and %(count)s others|one": "Laddar upp %(filename)s och %(count)s annan", + "Light theme": "Ljust tema", + "Dark theme": "Mörkt tema", + "Status.im theme": "Status.im-tema", + "You already have existing direct chats with this user:": "Du har redan existerande direkt-chattar med den här användaren:", + "Start chatting": "Börja chatta", + "Click on the button below to start chatting!": "Klicka på knappen nedanför för att börja chatta!", + "Start Chatting": "Börja chatta", + "This doesn't appear to be a valid email address": "Det här verkar inte vara en giltig epostadress", + "Verification Pending": "Avvaktar verifiering", + "Unable to add email address": "Det gick inte att lägga till epostadress", + "Unable to verify email address.": "Det gick inte att verifiera epostadressen.", + "Skip": "Hoppa över", + "User names may only contain letters, numbers, dots, hyphens and underscores.": "Användarnamn får endast innehålla bokstäver, siffror, punkter, bindestreck och understreck.", + "Username not available": "Användarnamn inte tillgängligt", + "Username invalid: %(errMessage)s": "Ogiltigt användarnamn: %(errMessage)s", + "An error occurred: %(error_string)s": "Ett fel uppstod: %(error_string)s", + "Username available": "Användarnamn tillgängligt", + "To get started, please pick a username!": "För att komma igång, vänligen välj ett användarnamn!", + "This will be your account name on the homeserver, or you can pick a different server.": "Det här kommer bli ditt kontonamn på hemservern , eller så kan du välja en annan server.", + "If you already have a Matrix account you can log in instead.": "Om du redan har ett Matrix-konto kan du logga in istället.", + "Please install Chrome or Firefox for the best experience.": "Vänligen installera Chrome eller Firefox för den bästa upplevelsen.", + "Safari and Opera work too.": "Safari och Opera funkar också.", + "Topic": "Ämne", + "Make this room private": "Gör det här rummet privat", + "Share message history with new users": "Dela meddelandehistoriken med nya användare", + "Encrypt room": "Kryptera rum", + "You must register to use this functionality": "Du måste registrera dig för att använda den här funktionaliteten", + "You must join the room to see its files": "Du måste gå med i rummet för att se tillhörande filer", + "There are no visible files in this room": "Det finns inga synliga filer i det här rummet", + "Your password has been reset": "Ditt lösenord har återställts", + "To reset your password, enter the email address linked to your account": "För att återställa ditt lösenord, ange epostadressen som är kopplad till ditt konto", + "This Home Server does not support login using email address.": "Den här hemservern har inte support för inloggning med epostadress.", + "Desktop specific": "Skrivbordsspecifikt", + "Start automatically after system login": "Starta automatiskt vid systeminloggning", + "User Interface": "Användargränssnitt", + "This will allow you to reset your password and receive notifications.": "Det här låter dig återställa lösenordet och ta emot aviseringar.", + "You have no visible notifications": "Du har inga synliga aviseringar", + "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Ditt lösenord har ändrats. Du kommer inte att få push-aviseringar på andra enheter förrän du har loggat in på dem igen", + "Failed to upload image": "Det gick inte att ladda upp bild" } From 9e1172019182131ead40560015e06e30bf943072 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sat, 12 May 2018 14:29:37 -0600 Subject: [PATCH 1088/1160] Add setting to enable widget screenshots (if widgets declare support) Fixes the remainder of https://github.com/vector-im/riot-web/issues/6708 Signed-off-by: Travis Ralston --- src/components/structures/UserSettings.js | 1 + src/components/views/elements/AppTile.js | 6 +++--- src/components/views/rooms/AppsDrawer.js | 3 +++ src/i18n/strings/en_EN.json | 1 + src/settings/Settings.js | 5 +++++ 5 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 3bef4e41bb..35a55284fd 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -80,6 +80,7 @@ const SIMPLE_SETTINGS = [ { id: "TextualBody.disableBigEmoji" }, { id: "VideoView.flipVideoHorizontally" }, { id: "TagPanel.disableTagPanel" }, + { id: "enableWidgetScreenshots" }, ]; // These settings must be defined in SettingsStore diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 38b6fc200b..2923d6dceb 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -85,7 +85,7 @@ export default class AppTile extends React.Component { /** * Does the widget support a given capability - * @param {[type]} capability Capability to check for + * @param {string} capability Capability to check for * @return {Boolean} True if capability supported */ _hasCapability(capability) { @@ -607,7 +607,7 @@ export default class AppTile extends React.Component { } // Picture snapshot - only show button when apps are maximised. - const showPictureSnapshotButton = this._hasCapability('screenshot') && this.props.show; + const showPictureSnapshotButton = this._hasCapability('m.capability.screenshot') && this.props.show; const showPictureSnapshotIcon = 'img/camera_green.svg'; const popoutWidgetIcon = 'img/button-new-window.svg'; const windowStateIcon = (this.props.show ? 'img/minimize.svg' : 'img/maximize.svg'); @@ -711,7 +711,7 @@ AppTile.propTypes = { showDelete: PropTypes.bool, // Optionally hide the popout widget icon showPopout: PropTypes.bool, - // Widget apabilities to allow by default (without user confirmation) + // Widget capabilities to allow by default (without user confirmation) // NOTE -- Use with caution. This is intended to aid better integration / UX // basic widget capabilities, e.g. injecting sticker message events. whitelistCapabilities: PropTypes.array, diff --git a/src/components/views/rooms/AppsDrawer.js b/src/components/views/rooms/AppsDrawer.js index 9f57ca51e9..8763ea3d7f 100644 --- a/src/components/views/rooms/AppsDrawer.js +++ b/src/components/views/rooms/AppsDrawer.js @@ -227,6 +227,8 @@ module.exports = React.createClass({ }, render: function() { + const enableScreenshots = SettingsStore.getValue("enableWidgetScreenshots", this.props.room.room_id); + const apps = this.state.apps.map( (app, index, arr) => { return (); }); diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 4adca0cc72..9b932ef2b6 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -217,6 +217,7 @@ "Enable URL previews for this room (only affects you)": "Enable URL previews for this room (only affects you)", "Enable URL previews by default for participants in this room": "Enable URL previews by default for participants in this room", "Room Colour": "Room Colour", + "Enable widget screenshots on supported widgets": "Enable widget screenshots on supported widgets", "Collecting app version information": "Collecting app version information", "Collecting logs": "Collecting logs", "Uploading report": "Uploading report", diff --git a/src/settings/Settings.js b/src/settings/Settings.js index 89a12580d6..663318f990 100644 --- a/src/settings/Settings.js +++ b/src/settings/Settings.js @@ -265,4 +265,9 @@ export const SETTINGS = { default: true, controller: new AudioNotificationsEnabledController(), }, + "enableWidgetScreenshots": { + supportedLevels: LEVELS_ACCOUNT_SETTINGS, + displayName: _td('Enable widget screenshots on supported widgets'), + default: false, + }, }; From 0522ab8fcd2d5e91f91fd698a023d399189d6d3d Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sat, 12 May 2018 13:18:43 -0600 Subject: [PATCH 1089/1160] Expose the requestId fully in the toWidget postMessage API This field is flagged as required in the proposal. Addresses part of https://github.com/vector-im/riot-web/issues/6708 Signed-off-by: Travis Ralston --- src/ToWidgetPostMessageApi.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ToWidgetPostMessageApi.js b/src/ToWidgetPostMessageApi.js index ccaa0207c1..def4af56ae 100644 --- a/src/ToWidgetPostMessageApi.js +++ b/src/ToWidgetPostMessageApi.js @@ -51,11 +51,11 @@ export default class ToWidgetPostMessageApi { if (payload.response === undefined) { return; } - const promise = this._requestMap[payload._id]; + const promise = this._requestMap[payload.requestId]; if (!promise) { return; } - delete this._requestMap[payload._id]; + delete this._requestMap[payload.requestId]; promise.resolve(payload); } @@ -64,21 +64,21 @@ export default class ToWidgetPostMessageApi { targetWindow = targetWindow || window.parent; // default to parent window targetOrigin = targetOrigin || "*"; this._counter += 1; - action._id = Date.now() + "-" + Math.random().toString(36) + "-" + this._counter; + action.requestId = Date.now() + "-" + Math.random().toString(36) + "-" + this._counter; return new Promise((resolve, reject) => { - this._requestMap[action._id] = {resolve, reject}; + this._requestMap[action.requestId] = {resolve, reject}; targetWindow.postMessage(action, targetOrigin); if (this._timeoutMs > 0) { setTimeout(() => { - if (!this._requestMap[action._id]) { + if (!this._requestMap[action.requestId]) { return; } console.error("postMessage request timed out. Sent object: " + JSON.stringify(action), this._requestMap); - this._requestMap[action._id].reject(new Error("Timed out")); - delete this._requestMap[action._id]; + this._requestMap[action.requestId].reject(new Error("Timed out")); + delete this._requestMap[action.requestId]; }, this._timeoutMs); } }); From 1515ca11a8be49e9a000afcc1c94e778faae57b5 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sat, 12 May 2018 13:21:27 -0600 Subject: [PATCH 1090/1160] Add a warning for widget developers when their postMessage is missing a requestId Signed-off-by: Travis Ralston --- src/FromWidgetPostMessageApi.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/FromWidgetPostMessageApi.js b/src/FromWidgetPostMessageApi.js index 13ffb4a74b..792fd73733 100644 --- a/src/FromWidgetPostMessageApi.js +++ b/src/FromWidgetPostMessageApi.js @@ -116,6 +116,12 @@ export default class FromWidgetPostMessageApi { return; // don't log this - debugging APIs like to spam postMessage which floods the log otherwise } + // Although the requestId is required, we don't use it. We'll be nice and process the message + // if the property is missing, but with a warning for widget developers. + if (!event.data.requestId) { + console.warn("fromWidget action '" + event.data.action + "' does not have a requestId"); + } + const action = event.data.action; const widgetId = event.data.widgetId; if (action === 'content_loaded') { From 98da8b35755e2bf00115f3b194de803808795746 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sat, 12 May 2018 13:49:43 -0600 Subject: [PATCH 1091/1160] Send the widgetId as part of all toWidget requests Addresses part of https://github.com/vector-im/riot-web/issues/6708 Signed-off-by: Travis Ralston --- src/WidgetMessaging.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/WidgetMessaging.js b/src/WidgetMessaging.js index 86eaa0b59b..5b722df65f 100644 --- a/src/WidgetMessaging.js +++ b/src/WidgetMessaging.js @@ -44,6 +44,8 @@ export default class WidgetMessaging { } messageToWidget(action) { + action.widgetId = this.widgetId; // Required to be sent for all outbound requests + return this.toWidget.exec(action, this.target).then((data) => { // Check for errors and reject if found if (data.response === undefined) { // null is valid From 210fcf0d52219f767896f242783becaffab9f329 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 13 May 2018 16:41:19 -0600 Subject: [PATCH 1092/1160] Correctly identify sticker picker widgets Widgets added to account data have the `type` of "m.widget", meaning we have to look at the `content.type` which will tell us what it is. This also fixes a bug where all user widgets become sticker picker widgets under the right conditions. Signed-off-by: Travis Ralston --- src/utils/widgets.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/utils/widgets.js b/src/utils/widgets.js index 0d7f5dbf3f..338df184e2 100644 --- a/src/utils/widgets.js +++ b/src/utils/widgets.js @@ -58,8 +58,7 @@ function getUserWidgetsArray() { */ function getStickerpickerWidgets() { const widgets = getUserWidgetsArray(); - const stickerpickerWidgets = widgets.filter((widget) => widget.type='m.stickerpicker'); - return stickerpickerWidgets; + return widgets.filter((widget) => widget.content && widget.content.type === "m.stickerpicker"); } /** @@ -73,7 +72,7 @@ function removeStickerpickerWidgets() { } const userWidgets = client.getAccountData('m.widgets').getContent() || {}; Object.entries(userWidgets).forEach(([key, widget]) => { - if (widget.type === 'm.stickerpicker') { + if (widget.content && widget.content.type === 'm.stickerpicker') { delete userWidgets[key]; } }); From cd034d3c2acc401947cc9f1b55ef275ba2e39531 Mon Sep 17 00:00:00 2001 From: RainSlide Date: Sun, 13 May 2018 12:58:50 +0000 Subject: [PATCH 1093/1160] Translated using Weblate (Chinese (Simplified)) Currently translated at 97.7% (1148 of 1174 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hans/ --- src/i18n/strings/zh_Hans.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index 2bbb5b1cc8..91d80993e4 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -358,7 +358,7 @@ "Device Name": "设备名称", "Device key": "设备密钥", "Verify device": "验证设备", - "I verify that the keys match": "我验证密钥匹配", + "I verify that the keys match": "我验证此密钥匹配", "Unable to restore session": "无法恢复会话", "Continue anyway": "无论如何都继续", "Blacklist": "列入黑名单", @@ -409,7 +409,7 @@ "Remove Contact Information?": "移除联系人信息?", "Remove %(threePid)s?": "移除 %(threePid)s?", "Results from DuckDuckGo": "来自 DuckDuckGo 的结果", - "Room contains unknown devices": "聊天室有未知设备", + "Room contains unknown devices": "聊天室包含未知设备", "%(roomName)s does not exist.": "%(roomName)s 不存在。", "Save": "保存", "Send anyway": "无论任何都发送", From d5d653e37515f65ffebbfb091fea76505da4c5ca Mon Sep 17 00:00:00 2001 From: Sven Thomsen Date: Tue, 8 May 2018 20:59:27 +0000 Subject: [PATCH 1094/1160] Translated using Weblate (German) Currently translated at 100.0% (1175 of 1175 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/de/ --- src/i18n/strings/de_DE.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 21d40dd86d..4464940c69 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -1176,5 +1176,6 @@ "We encountered an error trying to restore your previous session.": "Wir haben ein Problem beim Wiederherstellen deiner vorherigen Sitzung festgestellt.", "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Den Browser-Speicher zu löschen kann das Problem lösen, wird dich aber abmelden und verschlüsselte Chats unlesbar machen.", "Collapse Reply Thread": "Antwort-Thread zusammenklappen", - "At this time it is not possible to reply with an emote.": "An dieser Stelle ist es nicht möglich mit einer Umschreibung zu antworten." + "At this time it is not possible to reply with an emote.": "An dieser Stelle ist es nicht möglich mit einer Umschreibung zu antworten.", + "Enable widget screenshots on supported widgets": "Widget-Screenshots bei unterstützten Widgets aktivieren" } From 9cc89054438d8c25f43f2224843ad24c1707456b Mon Sep 17 00:00:00 2001 From: Szimszon Date: Mon, 7 May 2018 12:21:26 +0000 Subject: [PATCH 1095/1160] Translated using Weblate (Hungarian) Currently translated at 100.0% (1175 of 1175 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index c2b8af12ee..b7d0561c34 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -1176,5 +1176,6 @@ "Unable to reply": "Nem lehet válaszolni", "At this time it is not possible to reply with an emote.": "Jelenleg nem lehet emodzsival válaszolni.", "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Nem lehet betölteni azt az eseményt amire válaszoltál, mert vagy nem létezik, vagy nincs jogod megnézni.", - "Collapse Reply Thread": "Beszélgetés szál becsukása" + "Collapse Reply Thread": "Beszélgetés szál becsukása", + "Enable widget screenshots on supported widgets": "Ahol az a kisalkalmazásban támogatott ott képernyőkép készítés engedélyezése" } From 98c06315cf44121779125a98f7025436c72f11af Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 14 May 2018 11:14:49 +0100 Subject: [PATCH 1096/1160] Update widget state when account data changes --- src/components/views/rooms/Stickerpicker.js | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/components/views/rooms/Stickerpicker.js b/src/components/views/rooms/Stickerpicker.js index 40ce6e6b39..51d4816e59 100644 --- a/src/components/views/rooms/Stickerpicker.js +++ b/src/components/views/rooms/Stickerpicker.js @@ -34,6 +34,7 @@ export default class Stickerpicker extends React.Component { this._onHideStickersClick = this._onHideStickersClick.bind(this); this._launchManageIntegrations = this._launchManageIntegrations.bind(this); this._removeStickerpickerWidgets = this._removeStickerpickerWidgets.bind(this); + this._updateWidget = this._updateWidget.bind(this); this._onWidgetAction = this._onWidgetAction.bind(this); this._onResize = this._onResize.bind(this); this._onFinished = this._onFinished.bind(this); @@ -90,11 +91,12 @@ export default class Stickerpicker extends React.Component { if (!this.state.imError) { this.dispatcherRef = dis.register(this._onWidgetAction); } - const stickerpickerWidget = Widgets.getStickerpickerWidgets()[0]; - this.setState({ - stickerpickerWidget, - widgetId: stickerpickerWidget ? stickerpickerWidget.id : null, - }); + + // Track updates to widget state in account data + MatrixClientPeg.get().on('accountData', this._updateWidget); + + // Initialise widget state from current account data + this._updateWidget(); } componentWillUnmount() { @@ -116,6 +118,14 @@ export default class Stickerpicker extends React.Component { }); } + _updateWidget() { + const stickerpickerWidget = Widgets.getStickerpickerWidgets()[0]; + this.setState({ + stickerpickerWidget, + widgetId: stickerpickerWidget ? stickerpickerWidget.id : null, + }); + } + _onWidgetAction(payload) { if (payload.action === "user_widget_updated") { this.forceUpdate(); From cc16961b438f2267a59dc28598a657530ef7c7b9 Mon Sep 17 00:00:00 2001 From: Andrey Date: Mon, 14 May 2018 09:34:31 +0000 Subject: [PATCH 1097/1160] Translated using Weblate (Russian) Currently translated at 99.8% (1173 of 1175 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 2e6bdf45f0..f766069b16 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -1173,5 +1173,7 @@ "We encountered an error trying to restore your previous session.": "Произошла ошибка при попытке восстановить предыдущий сеанс.", "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Очистка хранилища вашего браузера может устранить проблему, но при этом ваша сессия будет завершена и зашифрованная история чата станет нечитаемой.", "Unable to reply": "Не удается ответить", - "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Не удается загрузить событие, на которое был дан ответ, либо оно не существует, либо у вас нет разрешения на его просмотр." + "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Не удается загрузить событие, на которое был дан ответ, либо оно не существует, либо у вас нет разрешения на его просмотр.", + "Enable widget screenshots on supported widgets": "Включить скриншоты виджета в поддерживаемых виджетах", + "Collapse Reply Thread": "Ответить с цитированием" } From 6345e474f5fea44a5246a264c09a4c6322aabe56 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 14 May 2018 11:38:17 +0100 Subject: [PATCH 1098/1160] Remove unused conditional --- src/components/views/elements/AppTile.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index cd0eb1ce68..cdd77227dc 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -359,9 +359,6 @@ export default class AppTile extends React.Component { if (!this.widgetMessaging) { this._onInitialLoad(); } - if (this._exposeWidgetMessaging) { - this._exposeWidgetMessaging(this.widgetMessaging); - } } /** From cf8077e60577d766bd93a7f659a09c6d3ab091f9 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 14 May 2018 11:42:38 +0100 Subject: [PATCH 1099/1160] Set loading: false when iFrame finishes loading --- src/components/views/elements/AppTile.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index cdd77227dc..55e2b93920 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -359,6 +359,7 @@ export default class AppTile extends React.Component { if (!this.widgetMessaging) { this._onInitialLoad(); } + this.setState({loading: false}); } /** @@ -396,8 +397,6 @@ export default class AppTile extends React.Component { }).catch((err) => { console.log(`Failed to get capabilities for widget type ${this.props.type}`, this.props.id, err); }); - - this.setState({loading: false}); } _onWidgetAction(payload) { From f384c465fd402a6c750aebee625396238364848e Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Thu, 3 May 2018 23:55:48 +0000 Subject: [PATCH 1100/1160] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (1175 of 1175 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hant/ --- src/i18n/strings/zh_Hant.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 6f5ef68735..3e8123dd78 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -1176,5 +1176,6 @@ "Refresh": "重新整理", "We encountered an error trying to restore your previous session.": "我們在嘗試復原您先前的工作階段時遇到了一點錯誤。", "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "清除您瀏覽器的儲存的東西也許可以修復問題,但會將您登出並造成任何已加密的聊天都無法讀取。", - "Collapse Reply Thread": "摺疊回覆討論串" + "Collapse Reply Thread": "摺疊回覆討論串", + "Enable widget screenshots on supported widgets": "在支援的小工具上啟用小工具螢幕快照" } From b6e317647a847041c216bfaf3fc88b82c3b64442 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 14 May 2018 13:41:41 +0100 Subject: [PATCH 1101/1160] Fix stickers briefly being 2x the size fixupHeight was the only thing actually fixing the size of the sticker image to be the size we want it rather than the pixel size of the image, and this was only getting run after the image loaded, causing a flash of 2x image. --- src/components/views/messages/MStickerBody.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/components/views/messages/MStickerBody.js b/src/components/views/messages/MStickerBody.js index 501db5e22b..3a412fc2e2 100644 --- a/src/components/views/messages/MStickerBody.js +++ b/src/components/views/messages/MStickerBody.js @@ -107,6 +107,16 @@ export default class MStickerBody extends MImageBody { placeholderFixupHeight = content.info.h + 'px'; } + // The pixel size of sticker images is generally larger than their intended display + // size so they render at native reolution on HiDPI displays. We therefore need to + // explicity set the size so they render at the intended size. + // XXX: This will be clobberred when we run fixupHeight(), but we need to do it + // here otherwise the stickers are momentarily displayed at the pixel size. + const imageStyle = { + height: content.info.h, + // leave the browser the calculate the width automatically + }; + placeholderSize = placeholderSize + 'px'; // Body 'ref' required by MImageBody @@ -132,6 +142,7 @@ export default class MStickerBody extends MImageBody { {content.body} Date: Mon, 14 May 2018 13:56:39 +0100 Subject: [PATCH 1102/1160] Remove redundant logging (currently shown on every render when no stickerpicker is present). --- src/components/views/rooms/Stickerpicker.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/views/rooms/Stickerpicker.js b/src/components/views/rooms/Stickerpicker.js index 0584cd6b0a..1bb972f67f 100644 --- a/src/components/views/rooms/Stickerpicker.js +++ b/src/components/views/rooms/Stickerpicker.js @@ -223,7 +223,6 @@ export default class Stickerpicker extends React.Component { ); } else { // Default content to show if stickerpicker widget not added - console.warn("No available sticker picker widgets"); stickersContent = this._defaultStickerpickerContent(); } return stickersContent; From dddd1c43cc6648846934d316ad38762bacf3a83e Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Mon, 14 May 2018 14:23:26 +0100 Subject: [PATCH 1103/1160] Remove redundant logging (currently shown on every render when no stickerpicker is present). --- src/components/views/rooms/Stickerpicker.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/views/rooms/Stickerpicker.js b/src/components/views/rooms/Stickerpicker.js index 51d4816e59..2a523e5e82 100644 --- a/src/components/views/rooms/Stickerpicker.js +++ b/src/components/views/rooms/Stickerpicker.js @@ -232,7 +232,6 @@ export default class Stickerpicker extends React.Component { ); } else { // Default content to show if stickerpicker widget not added - console.warn("No available sticker picker widgets"); stickersContent = this._defaultStickerpickerContent(); } return stickersContent; From 5ef0eece9a4ee9134560e9f3757f8138610051f8 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 14 May 2018 16:09:22 +0100 Subject: [PATCH 1104/1160] refactor and sort Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/RoomSettings.js | 65 +++++++++++++++------- 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index 658f99223e..f1aba322e2 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -695,26 +695,51 @@ module.exports = React.createClass({ relatedGroupsEvent={this.props.room.currentState.getStateEvents('m.room.related_groups', '')} />; - let userLevelsSection; + let privilegedUsersSection =
    { _t('No users have specific privileges in this room') }.
    ; // default + let mutedUsersSection; if (Object.keys(userLevels).length) { - userLevelsSection = -
    -

    { _t('Privileged Users') }

    -
      - { Object.keys(userLevels).map(function(user, i) { - return ( -
    • - { _t("%(user)s is a %(userRole)s", { - user: user, - userRole: , - }) } -
    • - ); + const privilegedUsers = []; + const mutedUsers = []; + + Object.keys(userLevels).forEach(function(user) { + if (userLevels[user] > defaultUserLevel) { // privileged + privilegedUsers.push(
    • + { _t("%(user)s is a %(userRole)s", { + user: user, + userRole: , }) } -
    -
    ; - } else { - userLevelsSection =
    { _t('No users have specific privileges in this room') }.
    ; + ); + } else if (userLevels[user] < defaultUserLevel) { // muted + mutedUsers.push(
  • + { _t("%(user)s is a %(userRole)s", { + user: user, + userRole: , + }) } +
  • ); + } + }); + + privilegedUsers.sort((a, b) => userLevels[b.key] - userLevels[a.key]); + mutedUsers.sort((a, b) => userLevels[a.key] - userLevels[b.key]); + + if (privilegedUsers.length) { + privilegedUsersSection = +
    +

    { _t('Privileged Users') }

    +
      + { privilegedUsers } +
    +
    ; + } + if (mutedUsers.length) { + mutedUsersSection = +
    +

    { _t('Muted Users') }

    +
      + { mutedUsers } +
    +
    ; + } } const banned = this.props.room.getMembersWithMembership("ban"); @@ -979,8 +1004,8 @@ module.exports = React.createClass({ { unfederatableSection }
    - { userLevelsSection } - + { privilegedUsersSection } + { mutedUsersSection } { bannedUsersSection }

    { _t('Advanced') }

    From 06e1acdf04f2a91ee25decd443ec5de489cb320c Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 14 May 2018 16:11:42 +0100 Subject: [PATCH 1105/1160] run i18n-gen and i18n-prune Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/i18n/strings/bg.json | 7 ---- src/i18n/strings/ca.json | 6 --- src/i18n/strings/cs.json | 5 --- src/i18n/strings/da.json | 1 - src/i18n/strings/de_DE.json | 7 ---- src/i18n/strings/el.json | 5 --- src/i18n/strings/en_EN.json | 70 +++++++++++++++++------------------ src/i18n/strings/en_US.json | 5 --- src/i18n/strings/eo.json | 6 --- src/i18n/strings/es.json | 3 -- src/i18n/strings/eu.json | 7 ---- src/i18n/strings/fi.json | 4 -- src/i18n/strings/fr.json | 7 ---- src/i18n/strings/gl.json | 7 ---- src/i18n/strings/he.json | 1 - src/i18n/strings/hu.json | 7 ---- src/i18n/strings/it.json | 7 ---- src/i18n/strings/ja.json | 1 - src/i18n/strings/ko.json | 5 --- src/i18n/strings/lv.json | 6 --- src/i18n/strings/nl.json | 7 ---- src/i18n/strings/pl.json | 6 --- src/i18n/strings/pt.json | 5 --- src/i18n/strings/pt_BR.json | 5 --- src/i18n/strings/ru.json | 7 ---- src/i18n/strings/sk.json | 7 ---- src/i18n/strings/sq.json | 1 - src/i18n/strings/sr.json | 7 ---- src/i18n/strings/sv.json | 1 - src/i18n/strings/th.json | 3 -- src/i18n/strings/tr.json | 5 --- src/i18n/strings/uk.json | 1 - src/i18n/strings/zh_Hans.json | 7 ---- src/i18n/strings/zh_Hant.json | 7 ---- 34 files changed, 34 insertions(+), 202 deletions(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index dc48b0ba59..7356b62fda 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -532,8 +532,6 @@ "You should not yet trust it to secure data": "Все още не трябва да се доверявате на това, че ще защити Вашите данни", "Invalid file%(extra)s": "Невалиден файл%(extra)s", "Error decrypting image": "Грешка при разшифроване на снимка", - "This image cannot be displayed.": "Тази снимка не може да бъде показана.", - "Image '%(Body)s' cannot be displayed.": "Снимката '%(Body)s' не може да бъде показана.", "Error decrypting video": "Грешка при разшифроване на видео", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s промени аватара на %(roomName)s", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s премахна аватара на стаята.", @@ -713,9 +711,7 @@ "Ignore request": "Игнорирай поканата", "Loading device info...": "Зареждане на информация за устройството...", "Encryption key request": "Заявка за ключ за шифроване", - "Otherwise, click here to send a bug report.": "В противен случай, натиснете тук, за да изпратите съобщение за грешка.", "Unable to restore session": "Неуспешно възстановяване на сесията", - "Continue anyway": "Продължи въпреки това", "Invalid Email Address": "Невалиден имейл адрес", "This doesn't appear to be a valid email address": "Това не изглежда да е валиден имейл адрес", "Please check your email and click on the link it contains. Once this is done, click continue.": "Моля, проверете своя имейл адрес и натиснете връзката, която той съдържа. След като направите това, натиснете продължи.", @@ -962,7 +958,6 @@ "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Сигурни ли сте, че искате да премахнете (изтриете) това събитие? Забележете, че ако изтриете събитие за промяна на името на стая или тема, това може да обърне промяната.", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "За да потвърдите, че на това устройство може да се вярва, моля свържете се със собственика му по друг начин (напр. на живо или чрез телефонен разговор) и го попитайте дали ключът, който той вижда в неговите настройки на потребителя за това устройство, съвпада с ключа по-долу:", "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Ако съвпада, моля натиснете бутона за потвърждение по-долу. Ако не, то тогава някой друг имитира това устройство и вероятно искате вместо това да натиснете бутона за черен списък.", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Засякохме грешка при опита за възстановяване на предишната Ви сесия. Ако продължите, ще трябва да влезете в профила си отново. Шифрованата история на чата няма да бъде четима.", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Ако преди сте използвали по-нова версия на Riot, Вашата сесия може да не бъде съвместима с текущата версия. Затворете този прозорец и се върнете в по-новата версия.", "This will be your account name on the homeserver, or you can pick a different server.": "Това ще бъде името на профила Ви на Home сървъра, или можете да изберете друг сървър.", "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Препоръчваме Ви да минете през процеса за потвърждение за всяко устройство, за да потвърдите, че принадлежат на легитимен собственик. Ако предпочитате, можете да изпратите съобщение без потвърждение.", @@ -996,7 +991,6 @@ "Join this community": "Присъединете се в тази общност", "Leave this community": "Напуснете тази общност", "Stickerpack": "Пакет със стикери", - "Sticker Messages": "Съобщения със стикери", "You don't currently have any stickerpacks enabled": "В момента нямате включени пакети със стикери", "Add a stickerpack": "Добави пакет със стикери", "Hide Stickers": "Скрий стикери", @@ -1108,7 +1102,6 @@ "Notify me for anything else": "Извести ме за всичко останало", "When I'm invited to a room": "Когато ме поканят в стая", "Keywords": "Ключови думи", - "Click here to create a GitHub issue.": "Натиснете тук, за да създадете GitHub issue.", "Can't update user notification settings": "Неуспешно обновяване на потребителски настройки за известяване", "Notify for all other messages/rooms": "Извести ме за всички други съобщения/стаи", "Unable to look up room ID from server": "Стая с такъв идентификатор не е намерена на сървъра", diff --git a/src/i18n/strings/ca.json b/src/i18n/strings/ca.json index b95c4914b1..514c6e66fe 100644 --- a/src/i18n/strings/ca.json +++ b/src/i18n/strings/ca.json @@ -499,8 +499,6 @@ "Download %(text)s": "Baixa %(text)s", "Invalid file%(extra)s": "Fitxer invàlid%(extra)s", "Error decrypting image": "S'ha produït un error en desencriptar la imatge", - "Image '%(Body)s' cannot be displayed.": "La imatge '%(Body)s' no es pot mostrar.", - "This image cannot be displayed.": "Aquesta imatge no es pot mostrar.", "Error decrypting video": "S'ha produït un error en desencriptar el vídeo", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s ha canviat el seu avatar per a la sala %(roomName)s", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s ha eliminat l'avatar de la sala.", @@ -694,9 +692,7 @@ "Ignore request": "Ignora la sol·licitud", "Loading device info...": "S'està carregant la informació del dispositiu...", "Encryption key request": "Sol·licitud de claus", - "Otherwise, click here to send a bug report.": "D'una altra manera, click here per a enviar un informe d'error.", "Unable to restore session": "No s'ha pogut restaurar la sessió", - "Continue anyway": "Continua de totes maneres", "Invalid Email Address": "El correu electrònic no és vàlid", "This doesn't appear to be a valid email address": "Aquest no sembla ser un correu electrònic vàlid", "Verification Pending": "Verificació pendent", @@ -714,7 +710,6 @@ "This will be your account name on the homeserver, or you can pick a different server.": "Aquest serà el nom del seu compte al servidor amfitrió, o bé trieu-ne un altre different server.", "If you already have a Matrix account you can log in instead.": "Si ja teniu un compte a Matrix, podeu log in.", "Block users on other matrix homeservers from joining this room": "Impedeix als usuaris d'altres servidors de Matrix d'entrar a aquesta sala", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Hem trobat un error en intentar restaurar la vostra sessió anterior. Si continueu, haureu d'iniciar la sessió de nou i l'historial de xat encriptat serà il·legible.", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Si anteriorment heu utilitzat un versió de Riot més recent, la vostra sessió podría ser incompatible amb aquesta versió. Tanqueu aquesta finestra i torneu a la versió més recent.", "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Actualment teniu a la llista negre els dispositius no verificats; per enviar missatges a aquests dispositius, els heu de verificar abans.", "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Recomanem que dugueu a terme el procès de verificació per a cada dispositiu per tal de confirmar que són del legítim propietari, però podeu enviar el missatge sense verificar-ho si ho preferiu.", @@ -986,7 +981,6 @@ "Notify me for anything else": "Notifica'm per a qualsevol altra cosa", "View Source": "Mostra el codi", "Keywords": "Paraules clau", - "Click here to create a GitHub issue.": "Clica aquí per crear una issue a GitHub.", "Can't update user notification settings": "No es poden actualitzar els paràmetres de les notificacions de l'usuari", "Notify for all other messages/rooms": "Notifica per a tots els altres missatges o sales", "Unable to look up room ID from server": "No s'ha pogut cercar l'ID de la sala en el servidor", diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index d19f17e097..a80b9daf64 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -262,7 +262,6 @@ "olm version:": "verze olm:", "Once encryption is enabled for a room it cannot be turned off again (for now)": "Jakmile je jednou šifrování v místnosti zapnuto, nelze už vypnout (prozatím)", "Only people who have been invited": "Pouze lidé, kteří byli pozváni", - "Otherwise, click here to send a bug report.": "V opačném případě klikněte zde a pošlete hlášení o chybě.", "Password": "Heslo", "Password:": "Heslo:", "Passwords can't be empty": "Hesla nemohou být prázdná", @@ -494,8 +493,6 @@ "You need to be able to invite users to do that.": "Pro tuto akci musíte mít právo zvát uživatele.", "Delete Widget": "Smazat widget", "Error decrypting image": "Chyba při dešifrování obrázku", - "Image '%(Body)s' cannot be displayed.": "Obrázek '%(Body)s' nemůže být zobrazen.", - "This image cannot be displayed.": "Tento obrázek nelze zobrazit.", "Error decrypting video": "Chyba při dešifrování videa", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s odstranil/a avatar místnosti.", "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s změnil/a avatar místnosti na ", @@ -808,9 +805,7 @@ "Ignore request": "Ignorovat žádost", "Encryption key request": "Žádost o šifrovací klíč", "Unable to restore session": "Nelze obnovit relaci", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Při pokusu o obnovení vaší předcházející relace se vyskytla chyba. Pokud budete pokračovat musíte se znovu přihlásit a historie šifrovaného rozhovoru nebude již dostupná.", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Pokud jste se v minulosti již přihlásili s novější verzi programu Riot, vaše relace nemusí být kompatibilní s touto verzí. Zavřete prosím toto okno a přihlaste se znovu pomocí nové verze.", - "Continue anyway": "Přesto pokračovat", "Please check your email and click on the link it contains. Once this is done, click continue.": "Prosím, zkontrolujte si email a klikněte na odkaz ve zprávě, kterou jsme vám zaslali. V případě, že jste tak již učinili, klikněte na tlačítko Pokračovat.", "This will allow you to reset your password and receive notifications.": "Toto vám umožní obnovit si heslo a přijímat oznámení emailem.", "Skip": "Přeskočit", diff --git a/src/i18n/strings/da.json b/src/i18n/strings/da.json index 19fc7d06c6..2a59530d5a 100644 --- a/src/i18n/strings/da.json +++ b/src/i18n/strings/da.json @@ -393,7 +393,6 @@ "There are advanced notifications which are not shown here": "Der er avancerede meddelelser, som ikke vises her", "%(count)s Members|other": "%(count)s medlemmer", "Logs sent": "Logfiler sendt", - "Click here to create a GitHub issue.": "Klik her for at oprette et GitHub-issue.", "Reply": "Besvar", "All messages (noisy)": "Alle meddelelser (højlydt)", "GitHub issue link:": "Link til GitHub issue:", diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 21d40dd86d..f2f4e103f7 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -431,7 +431,6 @@ "Verify device": "Gerät verifizieren", "I verify that the keys match": "Ich bestätige, dass die Schlüssel identisch sind", "Unable to restore session": "Sitzungswiederherstellung fehlgeschlagen", - "Continue anyway": "Trotzdem fortfahren", "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Nicht verifizierte Geräte werden aktuell blockiert und auf die Sperrliste gesetzt. Um Nachrichten an diese Geräte senden zu können, müssen diese zunächst verifiziert werden.", "\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" enthält Geräte, die du bislang noch nicht gesehen hast.", "Unknown devices": "Unbekannte Geräte", @@ -458,8 +457,6 @@ "What does this mean?": "Was bedeutet das?", "Error decrypting audio": "Audio-Entschlüsselung fehlgeschlagen", "Error decrypting image": "Bild-Entschlüsselung fehlgeschlagen", - "Image '%(Body)s' cannot be displayed.": "Das Bild '%(Body)s' kann nicht angezeigt werden.", - "This image cannot be displayed.": "Dieses Bild kann nicht angezeigt werden.", "Error decrypting video": "Video-Entschlüsselung fehlgeschlagen", "Import room keys": "Raum-Schlüssel importieren", "File to import": "Zu importierende Datei", @@ -480,7 +477,6 @@ "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Dies wird dein Benutzerkonto dauerhaft unbenutzbar machen. Du wirst nicht in der Lage sein, dich mit derselben Benutzer-ID erneut zu registrieren.", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Um sicherzustellen, dass diesem Gerät vertraut werden kann, kontaktiere bitte den Eigentümer des Geräts über ein anderes Kommunikationsmittel (z.B. im persönlichen Gespräch oder durch einen Telefonanruf) und vergewissere dich, dass der Schlüssel, den der Eigentümer in den Benutzer-Einstellungen für dieses Gerät sieht, mit dem folgenden Schlüssel identisch ist:", "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Wenn er identisch ist, bitte den Bestätigen-Button unten verwenden. Falls er nicht identisch sein sollte, hat eine Fremdperson Kontrolle über dieses Gerät und es sollte gesperrt werden.", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Bei der Wiederherstellung deiner letzten Sitzung ist ein Fehler aufgetreten. Um fortzufahren, musst du dich erneut anmelden. Ein zuvor verschlüsselter Chatverlauf wird in der Folge nicht mehr lesbar sein.", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Wenn du zuvor eine aktuellere Version von Riot verwendet hast, ist deine Sitzung eventuell inkompatibel mit dieser Version. Bitte schließe dieses Fenster und kehre zur aktuelleren Version zurück.", "Blacklist": "Blockieren", "Unblacklist": "Entblockieren", @@ -590,7 +586,6 @@ "Last seen": "Zuletzt gesehen", "Level:": "Berechtigungslevel:", "No display name": "Kein Anzeigename", - "Otherwise, click here to send a bug report.": "Alternativ hier klicken, um einen Fehlerbericht zu senden.", "Private Chat": "Privater Chat", "Public Chat": "Öffentlicher Chat", "Reason: %(reasonText)s": "Grund: %(reasonText)s", @@ -995,7 +990,6 @@ "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Änderungen am Namen und Bild deiner Community werden evtl. erst nach 30 Minuten von anderen Nutzern gesehen werden.", "Join this community": "Community beitreten", "Leave this community": "Community verlassen", - "Sticker Messages": "Sticker-Nachrichten", "You don't currently have any stickerpacks enabled": "Du hast aktuell keine Stickerpacks aktiviert", "Add a stickerpack": "Füge ein Stickerpack hinzu", "Hide Stickers": "Sticker verbergen", @@ -1110,7 +1104,6 @@ "What's new?": "Was ist neu?", "Notify me for anything else": "Über alles andere benachrichtigen", "When I'm invited to a room": "Wenn ich in einen Raum eingeladen werde", - "Click here to create a GitHub issue.": "Klicke hier um ein GithHub-Problem zu erstellen.", "Can't update user notification settings": "Benachrichtigungs-Einstellungen des Benutzers konnten nicht aktualisiert werden", "Notify for all other messages/rooms": "Benachrichtigungen für alle anderen Mitteilungen/Räume aktivieren", "Unable to look up room ID from server": "Es ist nicht möglich, die Raum-ID auf dem Server nachzuschlagen", diff --git a/src/i18n/strings/el.json b/src/i18n/strings/el.json index b5acd8855e..9817010e38 100644 --- a/src/i18n/strings/el.json +++ b/src/i18n/strings/el.json @@ -384,7 +384,6 @@ "Device key": "Κλειδί συσκευής", "Verify device": "Επιβεβαίωση συσκευής", "Unable to restore session": "Αδυναμία επαναφοράς συνεδρίας", - "Continue anyway": "Συνέχεια οπωσδήποτε", "Unknown devices": "Άγνωστες συσκευές", "Unknown Address": "Άγνωστη διεύθυνση", "Blacklist": "Μαύρη λίστα", @@ -402,8 +401,6 @@ "What does this mean?": "Τι σημαίνει αυτό;", "Error decrypting audio": "Σφάλμα κατά την αποκρυπτογράφηση του ήχου", "Error decrypting image": "Σφάλμα κατά την αποκρυπτογράφηση της εικόνας", - "Image '%(Body)s' cannot be displayed.": "Η εικόνα '%(Body)s' δεν μπορεί να εμφανιστεί.", - "This image cannot be displayed.": "Αυτή η εικόνα δεν μπορεί να εμφανιστεί.", "Error decrypting video": "Σφάλμα κατά την αποκρυπτογράφηση του βίντεο", "Add an Integration": "Προσθήκη ενσωμάτωσης", "URL Previews": "Προεπισκόπηση συνδέσμων", @@ -462,7 +459,6 @@ "No users have specific privileges in this room": "Κανένας χρήστης δεν έχει συγκεκριμένα δικαιώματα σε αυτό το δωμάτιο", "Once encryption is enabled for a room it cannot be turned off again (for now)": "Μόλις ενεργοποιηθεί η κρυπτογράφηση για ένα δωμάτιο, δεν μπορεί να απενεργοποιηθεί ξανά (για τώρα)", "Only people who have been invited": "Μόνο άτομα που έχουν προσκληθεί", - "Otherwise, click here to send a bug report.": "Διαφορετικά, κάντε κλικ εδώ για να αποστείλετε μια αναφορά σφάλματος.", "%(senderName)s placed a %(callType)s call.": "Ο %(senderName)s πραγματοποίησε μια %(callType)s κλήση.", "Please check your email and click on the link it contains. Once this is done, click continue.": "Παρακαλούμε ελέγξτε την ηλεκτρονική σας αλληλογραφία και κάντε κλικ στον σύνδεσμο που περιέχει. Μόλις γίνει αυτό, κάντε κλίκ στο κουμπί συνέχεια.", "Refer a friend to Riot:": "Πείτε για το Riot σε έναν φίλο σας:", @@ -621,7 +617,6 @@ "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Με αυτόν τον τρόπο, ο λογαριασμός σας θα είναι μόνιμα αχρησιμοποίητος. Δεν θα μπορείτε να εγγραφείτε ξανά με το ίδιο αναγνωριστικό χρήστη.", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Για να βεβαιωθείτε ότι είναι αξιόπιστη αυτή η συσκευή, επικοινωνήστε με τον κάτοχο της χρησιμοποιώντας άλλα μέσα (π.χ. προσωπικά ή μέσω τηλεφώνου) και ρωτήστε εάν το κλειδί που βλέπετε στις ρυθμίσεις χρήστη για αυτήν τη συσκευή ταιριάζει με το παρακάτω κλειδί:", "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Εάν ταιριάζει, πατήστε το κουμπί επιβεβαίωσης παρακάτω. Εάν όχι, τότε κάποιος άλλος παρακολουθεί αυτή τη συσκευή και ίσως θέλετε να πατήσετε το κουμπί της μαύρης λίστας.", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Παρουσιάστηκε ένα σφάλμα κατά την προσπάθεια επαναφοράς της προηγούμενης συνεδρίας. Αν συνεχίσετε, θα χρειαστεί να συνδεθείτε ξανά και το κρυπτογραφημένο ιστορικό συνομιλιών θα είναι μη αναγνώσιμο.", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Αν χρησιμοποιούσατε προηγουμένως μια πιο πρόσφατη έκδοση του Riot, η συνεδρία σας ίσως είναι μη συμβατή με αυτήν την έκδοση. Κλείστε αυτό το παράθυρο και επιστρέψτε στην πιο πρόσφατη έκδοση.", "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Αυτήν τη στιγμή βάζετε σε μαύρη λίστα μη επιβαιωμένες συσκευές. Για να στείλετε μηνύματα σε αυτές τις συσκευές, πρέπει να τις επιβεβαιώσετε.", "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Σας συνιστούμε να ολοκληρώσετε τη διαδικασία επαλήθευσης για κάθε συσκευή και να επιβεβαιώσετε ότι ανήκουν στον νόμιμο κάτοχό της, αλλά εάν προτιμάτε μπορείτε να στείλετε ξανά το μήνυμα χωρίς επαλήθευση.", diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 9b932ef2b6..d38259cdbf 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -41,6 +41,10 @@ "The file '%(fileName)s' failed to upload": "The file '%(fileName)s' failed to upload", "The file '%(fileName)s' exceeds this home server's size limit for uploads": "The file '%(fileName)s' exceeds this home server's size limit for uploads", "Upload Failed": "Upload Failed", + "Failure to create room": "Failure to create room", + "Server may be unavailable, overloaded, or you hit a bug.": "Server may be unavailable, overloaded, or you hit a bug.", + "Send anyway": "Send anyway", + "Send": "Send", "Sun": "Sun", "Mon": "Mon", "Tue": "Tue", @@ -80,6 +84,7 @@ "Failed to invite users to community": "Failed to invite users to community", "Failed to invite users to %(groupId)s": "Failed to invite users to %(groupId)s", "Failed to add the following rooms to %(groupId)s:": "Failed to add the following rooms to %(groupId)s:", + "Unnamed Room": "Unnamed Room", "Riot does not have permission to send you notifications - please check your browser settings": "Riot does not have permission to send you notifications - please check your browser settings", "Riot was not given permission to send notifications - please try again": "Riot was not given permission to send notifications - please try again", "Unable to enable Notifications": "Unable to enable Notifications", @@ -178,11 +183,6 @@ "%(names)s and %(count)s others are typing|other": "%(names)s and %(count)s others are typing", "%(names)s and %(count)s others are typing|one": "%(names)s and one other is typing", "%(names)s and %(lastPerson)s are typing": "%(names)s and %(lastPerson)s are typing", - "Failure to create room": "Failure to create room", - "Server may be unavailable, overloaded, or you hit a bug.": "Server may be unavailable, overloaded, or you hit a bug.", - "Send anyway": "Send anyway", - "Send": "Send", - "Unnamed Room": "Unnamed Room", "Your browser does not support the required cryptography extensions": "Your browser does not support the required cryptography extensions", "Not a valid Riot keyfile": "Not a valid Riot keyfile", "Authentication check failed: incorrect password?": "Authentication check failed: incorrect password?", @@ -190,7 +190,6 @@ "Message Replies": "Message Replies", "Message Pinning": "Message Pinning", "Tag Panel": "Tag Panel", - "Sticker Messages": "Sticker Messages", "Disable Emoji suggestions while typing": "Disable Emoji suggestions while typing", "Use compact timeline layout": "Use compact timeline layout", "Hide removed messages": "Hide removed messages", @@ -297,6 +296,29 @@ "Off": "Off", "On": "On", "Noisy": "Noisy", + "Invalid alias format": "Invalid alias format", + "'%(alias)s' is not a valid format for an alias": "'%(alias)s' is not a valid format for an alias", + "Invalid address format": "Invalid address format", + "'%(alias)s' is not a valid format for an address": "'%(alias)s' is not a valid format for an address", + "not specified": "not specified", + "not set": "not set", + "Remote addresses for this room:": "Remote addresses for this room:", + "Addresses": "Addresses", + "The main address for this room is": "The main address for this room is", + "Local addresses for this room:": "Local addresses for this room:", + "This room has no local addresses": "This room has no local addresses", + "New address (e.g. #foo:%(localDomain)s)": "New address (e.g. #foo:%(localDomain)s)", + "Invalid community ID": "Invalid community ID", + "'%(groupId)s' is not a valid community ID": "'%(groupId)s' is not a valid community ID", + "Flair": "Flair", + "Showing flair for these communities:": "Showing flair for these communities:", + "This room is not showing flair for any communities": "This room is not showing flair for any communities", + "New community ID (e.g. +foo:%(localDomain)s)": "New community ID (e.g. +foo:%(localDomain)s)", + "You have enabled URL previews by default.": "You have enabled URL previews by default.", + "You have disabled URL previews by default.": "You have disabled URL previews by default.", + "URL previews are enabled by default for participants in this room.": "URL previews are enabled by default for participants in this room.", + "URL previews are disabled by default for participants in this room.": "URL previews are disabled by default for participants in this room.", + "URL Previews": "URL Previews", "Cannot add any more widgets": "Cannot add any more widgets", "The maximum permitted number of widgets have already been added to this room.": "The maximum permitted number of widgets have already been added to this room.", "Add a widget": "Add a widget", @@ -393,11 +415,11 @@ "numbullet": "numbullet", "Markdown is disabled": "Markdown is disabled", "Markdown is enabled": "Markdown is enabled", - "Unpin Message": "Unpin Message", - "Jump to message": "Jump to message", "No pinned messages.": "No pinned messages.", "Loading...": "Loading...", "Pinned Messages": "Pinned Messages", + "Unpin Message": "Unpin Message", + "Jump to message": "Jump to message", "%(duration)ss": "%(duration)ss", "%(duration)sm": "%(duration)sm", "%(duration)sh": "%(duration)sh", @@ -490,9 +512,10 @@ "To kick users, you must be a": "To kick users, you must be a", "To ban users, you must be a": "To ban users, you must be a", "To remove other users' messages, you must be a": "To remove other users' messages, you must be a", - "Privileged Users": "Privileged Users", - "%(user)s is a %(userRole)s": "%(user)s is a %(userRole)s", "No users have specific privileges in this room": "No users have specific privileges in this room", + "%(user)s is a %(userRole)s": "%(user)s is a %(userRole)s", + "Privileged Users": "Privileged Users", + "Muted Users": "Muted Users", "Banned users": "Banned users", "This room is not accessible by remote Matrix servers": "This room is not accessible by remote Matrix servers", "Leave room": "Leave room", @@ -528,29 +551,6 @@ "Scroll to unread messages": "Scroll to unread messages", "Jump to first unread message.": "Jump to first unread message.", "Close": "Close", - "Invalid alias format": "Invalid alias format", - "'%(alias)s' is not a valid format for an alias": "'%(alias)s' is not a valid format for an alias", - "Invalid address format": "Invalid address format", - "'%(alias)s' is not a valid format for an address": "'%(alias)s' is not a valid format for an address", - "not specified": "not specified", - "not set": "not set", - "Remote addresses for this room:": "Remote addresses for this room:", - "Addresses": "Addresses", - "The main address for this room is": "The main address for this room is", - "Local addresses for this room:": "Local addresses for this room:", - "This room has no local addresses": "This room has no local addresses", - "New address (e.g. #foo:%(localDomain)s)": "New address (e.g. #foo:%(localDomain)s)", - "Invalid community ID": "Invalid community ID", - "'%(groupId)s' is not a valid community ID": "'%(groupId)s' is not a valid community ID", - "Flair": "Flair", - "Showing flair for these communities:": "Showing flair for these communities:", - "This room is not showing flair for any communities": "This room is not showing flair for any communities", - "New community ID (e.g. +foo:%(localDomain)s)": "New community ID (e.g. +foo:%(localDomain)s)", - "You have enabled URL previews by default.": "You have enabled URL previews by default.", - "You have disabled URL previews by default.": "You have disabled URL previews by default.", - "URL previews are enabled by default for participants in this room.": "URL previews are enabled by default for participants in this room.", - "URL previews are disabled by default for participants in this room.": "URL previews are disabled by default for participants in this room.", - "URL Previews": "URL Previews", "Sunday": "Sunday", "Monday": "Monday", "Tuesday": "Tuesday", @@ -566,8 +566,6 @@ "Download %(text)s": "Download %(text)s", "Invalid file%(extra)s": "Invalid file%(extra)s", "Error decrypting image": "Error decrypting image", - "This image cannot be displayed.": "This image cannot be displayed.", - "Image '%(Body)s' cannot be displayed.": "Image '%(Body)s' cannot be displayed.", "Error decrypting video": "Error decrypting video", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s changed the avatar for %(roomName)s", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s removed the room avatar.", @@ -815,8 +813,8 @@ "Encryption key request": "Encryption key request", "Sign out": "Sign out", "Log out and remove encryption keys?": "Log out and remove encryption keys?", - "Send Logs": "Send Logs", "Clear Storage and Sign Out": "Clear Storage and Sign Out", + "Send Logs": "Send Logs", "Refresh": "Refresh", "Unable to restore session": "Unable to restore session", "We encountered an error trying to restore your previous session.": "We encountered an error trying to restore your previous session.", diff --git a/src/i18n/strings/en_US.json b/src/i18n/strings/en_US.json index a3184fdc38..e316f72e80 100644 --- a/src/i18n/strings/en_US.json +++ b/src/i18n/strings/en_US.json @@ -509,10 +509,8 @@ "In future this verification process will be more sophisticated.": "In future this verification process will be more sophisticated.", "Verify device": "Verify device", "I verify that the keys match": "I verify that the keys match", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.", "Unable to restore session": "Unable to restore session", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.", - "Continue anyway": "Continue anyway", "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.", "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.", "\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" contains devices that you haven't seen before.", @@ -558,8 +556,6 @@ "What does this mean?": "What does this mean?", "Error decrypting audio": "Error decrypting audio", "Error decrypting image": "Error decrypting image", - "Image '%(Body)s' cannot be displayed.": "Image '%(Body)s' cannot be displayed.", - "This image cannot be displayed.": "This image cannot be displayed.", "Error decrypting video": "Error decrypting video", "Add an Integration": "Add an Integration", "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?": "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?", @@ -608,7 +604,6 @@ "Last seen": "Last seen", "Level:": "Level:", "No display name": "No display name", - "Otherwise, click here to send a bug report.": "Otherwise, click here to send a bug report.", "Private Chat": "Private Chat", "Public Chat": "Public Chat", "Reason: %(reasonText)s": "Reason: %(reasonText)s", diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index cc8de81fa9..fae7d6cfa8 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -475,8 +475,6 @@ "Download %(text)s": "Elŝuti %(text)s", "Invalid file%(extra)s": "Malvalida dosiero%(extra)s", "Error decrypting image": "Eraro malĉifrante bildon", - "Image '%(Body)s' cannot be displayed.": "Bildo ‹%(Body)s› ne montreblas.", - "This image cannot be displayed.": "Ĉi tiu bildo ne montreblas.", "Error decrypting video": "Eraro malĉifrante videon", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s forigis la ĉambran profilbildon.", "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s agordis la ĉambran profilbildon al ", @@ -673,11 +671,8 @@ "Ignore request": "Malatenti peton", "Loading device info...": "Enleganta informojn pri aparato…", "Encryption key request": "Peto por ĉifra ŝlosilo", - "Otherwise, click here to send a bug report.": "Alie, klaku ĉi tie por sendi cimraporton.", "Unable to restore session": "Seanco ne restaŭreblas", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Okazis eraron dum restaŭro de via antaŭa seanco. Se vi daŭrigos, vi devos denove saluti, kaj ĉifrita babila historio estos nelegebla.", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Se vi antaŭe uzis pli novan version de Riot, via seanco eble ne kongruos kun ĉi tiu versio. Fermu ĉi tiun fenestron kaj revenu al la pli nova versio.", - "Continue anyway": "Tamen daŭrigi", "Invalid Email Address": "Malvalida retpoŝtadreso", "This doesn't appear to be a valid email address": "Tio ĉi ne ŝajnas esti valida retpoŝtadreso", "Verification Pending": "Atendanta kontrolon", @@ -1107,7 +1102,6 @@ "Checking for an update...": "Serĉanta ĝisdatigojn…", "There are advanced notifications which are not shown here": "Ekzistas specialaj sciigoj, kiuj ne montriĝas ĉi tie", "Logs sent": "Protokolo sendiĝis", - "Click here to create a GitHub issue.": "Klaku ĉi tie por krei raporton ĉe GitHub.", "GitHub issue link:": "Ligilo al raporto ĉe GitHub:", "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Sencimigaj protokoloj enhavas informojn pri uzo de aplikaĵo, inkluzive vian salutnomon, la identigilojn aŭ nomojn de la ĉambroj aŭ grupoj kiujn vi vizitis, kaj la salutnomojn de aliaj uzantoj. Ili ne enhavas mesaĝojn.", "Failed to send logs: ": "Malsukcesis sendi protokolon: ", diff --git a/src/i18n/strings/es.json b/src/i18n/strings/es.json index 07b38d7566..7ec0e821db 100644 --- a/src/i18n/strings/es.json +++ b/src/i18n/strings/es.json @@ -250,7 +250,6 @@ "Verify device": "Verifique el dispositivo", "I verify that the keys match": "Confirmo que las claves coinciden", "Unable to restore session": "No se puede recuperar la sesión", - "Continue anyway": "Continuar igualmente", "Room Colour": "Color de la sala", "Room contains unknown devices": "La sala contiene dispositivos desconocidos", "Room name (optional)": "Nombre de la sala (opcional)", @@ -344,7 +343,6 @@ "Once encryption is enabled for a room it cannot be turned off again (for now)": "Una vez se active el cifrado en esta sala, no podrá ser desactivado (por ahora)", "Only people who have been invited": "Sólo usuarios que han sido invitados", "Operation failed": "Falló la operación", - "Otherwise, click here to send a bug report.": "También puede pulsar aquí para enviar un informe de fallos.", "Password": "Contraseña", "Password:": "Contraseña:", "Passwords can't be empty": "Las contraseñas no pueden estar en blanco", @@ -696,7 +694,6 @@ "What's new?": "¿Qué hay de nuevo?", "Notify me for anything else": "Notificarme para cualquier otra cosa", "When I'm invited to a room": "Cuando estoy invitado a una sala", - "Click here to create a GitHub issue.": "Haz click aquí para crear una incidencia en Github.", "Can't update user notification settings": "No se puede actualizar la configuración de notificaciones del usuario", "Notify for all other messages/rooms": "Notificar para todos los demás mensajes/salas", "Unable to look up room ID from server": "No se puede buscar el ID de la sala desde el servidor", diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index e478c3270b..4015d703ce 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -327,7 +327,6 @@ "No users have specific privileges in this room": "Ez dago gela honetan baimen zehatzik duen erabiltzailerik", "olm version:": "olm bertsioa:", "Once encryption is enabled for a room it cannot be turned off again (for now)": "Behin gela batean zifratzea gaituta ezin da gero desgaitu (oraingoz)", - "Otherwise, click here to send a bug report.": "Bestela, bidali arazte-txosten bat.", "Server may be unavailable, overloaded, or you hit a bug.": "Agian zerbitzaria ez dago eskuragarri, edo gainezka dago, edo akats bat aurkitu duzu.", "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Oraingoz pasahitza aldatzeak gailu guztietako muturretik muturrerako zifratze-gakoak berrezarriko ditu, eta ezin izango dituzu zifratutako txatetako historialak irakurri ez badituzu aurretik zure gelako gakoak esportatzen eta aldaketa eta gero berriro inportatzen. Etorkizunean hau hobetuko da.", "For security, logging out will delete any end-to-end encryption keys from this browser. If you want to be able to decrypt your conversation history from future Riot sessions, please export your room keys for safe-keeping.": "Segurtasunagatik, saioa amaitzeak nabigatzaile honetako muturretik muturrerako zifratze gako guztiak ezabatuko ditu. Zure elkarrizketen historiala deszifratzeko gai izan nahi baduzu etorkizuneko Riot saioetan, esportatu zure gelako gakoen babes-kopia bat.", @@ -574,10 +573,8 @@ "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Gailu hau fidagarria dela egiaztatzeko, kontaktatu bere jabea beste medio bat erabiliz (adib. aurrez aurre edo telefonoz deituz) eta galdetu beraien erabiltzaile-ezarpenetan bere gailurako ikusten duen gakoa hemen beheko bera den:", "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Bat badator sakatu egiaztatu botoia. Bat ez badator, beste inor gailu hau atzematen dago eta blokeatu beharko zenuke.", "In future this verification process will be more sophisticated.": "etorkizunean egiaztaketa metodoa hobetuko da.", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Errore bat gertatu da zure aurreko saioa berreskuratzen saiatzean. Jarraitzen baduzu berriro hasi beharko duzu saioa eta ezin izango duzu irakurri zifratutako historiala.", "Unable to restore session": "Ezin izan da saioa berreskuratu", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Aurretik Riot bertsio berriago bat erabili baduzu, zure saioa bertsio honekin bateraezina izan daiteke. Itxi leiho hau eta itzuli bertsio berriagora.", - "Continue anyway": "Jarraitu hala ere", "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Gailu bakoitzaren egiaztaketa prozesua jarraitzea aholkatzen dizugu, benetako jabeari dagozkiela baieztatzeko, baina mezua egiaztatu gabe birbidali dezakezu ere.", "\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" gelan aurretik ikusi ez dituzun gailuak daude.", "Unknown devices": "Gailu ezezagunak", @@ -600,8 +597,6 @@ "What does this mean?": "Zer esan nahi du honek?", "Error decrypting audio": "Errorea audioa deszifratzean", "Error decrypting image": "Errorea audioa deszifratzean", - "Image '%(Body)s' cannot be displayed.": "Ezin da '%(Body)s' irudia bistaratu.", - "This image cannot be displayed.": "Irudi hau ezin da bistaratu.", "Error decrypting video": "Errorea bideoa deszifratzean", "Add an Integration": "Gehitu integrazioa", "Removed or unknown message type": "Kenduta edo mezu mota ezezaguna", @@ -996,7 +991,6 @@ "Join this community": "Elkartu komunitate honetara", "Leave this community": "Atera komunitate honetatik", "Stickerpack": "Eranskailu-multzoa", - "Sticker Messages": "Eranskailu mezuak", "You don't currently have any stickerpacks enabled": "Ez duzu eranskailu multzorik aktibatuta", "Add a stickerpack": "Gehitu eranskailu-multzoa", "Hide Stickers": "Ezkutatu eranskailuak", @@ -1110,7 +1104,6 @@ "What's new?": "Zer dago berri?", "Notify me for anything else": "Jakinarazi beste edozer", "When I'm invited to a room": "Gela batetara gonbidatzen nautenean", - "Click here to create a GitHub issue.": "Egin klik hemen GitHub-en arazoaren berri emateko.", "Can't update user notification settings": "Ezin dira erabiltzailearen jakinarazpenen ezarpenak eguneratu", "Notify for all other messages/rooms": "Jakinarazi beste mezu/gela guztiak", "Unable to look up room ID from server": "Ezin izan da gelaren IDa zerbitzarian bilatu", diff --git a/src/i18n/strings/fi.json b/src/i18n/strings/fi.json index 7f7ac9729f..0f05b697a6 100644 --- a/src/i18n/strings/fi.json +++ b/src/i18n/strings/fi.json @@ -440,7 +440,6 @@ "Verify device": "Varmenna laite", "I verify that the keys match": "Totean että avaimet vastaavat toisiaan", "Unable to restore session": "Istunnon palautus epäonnistui", - "Continue anyway": "Jatka kuitenkin", "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s poisti huoneen nimen.", "Changes to who can read history will only apply to future messages in this room": "Muutokset koskien ketkä voivat lukea historian koskevat vain uusia viestejä", "Click here to join the discussion!": "Paina tästä liittyäksesi keskusteluun", @@ -517,7 +516,6 @@ "Failed to change power level": "Oikeustason muuttaminen epäonnistui", "'%(alias)s' is not a valid format for an address": "'%(alias)s' ei ole oikean muotoinen osoitteelle", "'%(alias)s' is not a valid format for an alias": "'%(alias)s' ei ole oikean muotoinen aliakselle", - "Otherwise, click here to send a bug report.": "Paina muutoin tästä lähettääksesi virheraportin.", "Please check your email and click on the link it contains. Once this is done, click continue.": "Ole hyvä ja tarkista sähköpostisi ja seuraa sen sisältämää linkkiä. Kun olet valmis, paina jatka.", "Power level must be positive integer.": "Oikeustason pitää olla positiivinen kokonaisluku.", "Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Salasanan uudelleenalustus uudelleenalustaa myös päästä päähän-salausavaimet kaikilla laitteilla, jolloin vanhojen viestien lukeminen ei ole enään mahdollista, ellet ensin vie huoneavaimet ja tuo ne takaisin jälkeenpäin. Tämä tulee muuttumaan tulevaisuudessa.", @@ -576,8 +574,6 @@ "What does this mean?": "Mitä tämä tarkoittaa?", "Error decrypting audio": "Äänen salauksen purku epäonnistui", "Error decrypting image": "Kuvan salauksen purku epäonnistui", - "Image '%(Body)s' cannot be displayed.": "Kuva '%(Body)s' ei voida näyttää.", - "This image cannot be displayed.": "Tätä kuvaa ei voida näyttää.", "Error decrypting video": "Videon salauksen purku epäonnistui", "Add an Integration": "Lisää integraatio", "Removed or unknown message type": "Poistettu tai tuntematon viestityyppi", diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 9c0f3f98e8..0787a06134 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -443,10 +443,8 @@ "In future this verification process will be more sophisticated.": "À l’avenir ce processus de vérification sera plus sophistiqué.", "Verify device": "Vérifier cet appareil", "I verify that the keys match": "J’ai vérifié que les clés correspondaient", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Nous avons rencontré une erreur en essayant de rétablir votre session précédente. Si vous continuez, vous devrez vous identifier à nouveau et l’historique de vos discussions chiffrées sera illisible.", "Unable to restore session": "Impossible de restaurer la session", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Si vous avez utilisé une version plus récente de Riot précédemment, votre session risque d’être incompatible avec cette version. Fermez cette fenêtre et retournez à la version plus récente.", - "Continue anyway": "Continuer quand même", "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Vous êtes en train d’ajouter à la liste noire des appareils non-vérifiés ; pour envoyer des messages à ces appareils vous devez les vérifier.", "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Nous vous recommandons d’effectuer le processus de vérification pour tous les appareils afin de confirmer qu’ils appartiennent à leurs propriétaires légitimes, mais vous pouvez renvoyer le(s) message(s) sans vérifier si vous préférez.", "\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" contient des appareils que vous n'avez encore jamais vus.", @@ -478,8 +476,6 @@ "What does this mean?": "Qu’est ce que cela signifie ?", "Error decrypting audio": "Erreur lors du déchiffrement de l’audio", "Error decrypting image": "Erreur lors du déchiffrement de l’image", - "Image '%(Body)s' cannot be displayed.": "L'image \"%(Body)s\" ne peut pas être affichée.", - "This image cannot be displayed.": "Cette image ne peut pas être affichée.", "Error decrypting video": "Erreur lors du déchiffrement de la vidéo", "Add an Integration": "Ajouter une intégration", "URL Previews": "Aperçus des liens", @@ -579,7 +575,6 @@ "Incoming video call from %(name)s": "Appel vidéo entrant de %(name)s", "Incoming voice call from %(name)s": "Appel vocal entrant de %(name)s", "No display name": "Pas de nom affiché", - "Otherwise, click here to send a bug report.": "Sinon, cliquer ici pour envoyer un rapport d'erreur.", "Private Chat": "Discussion privée", "Public Chat": "Discussion publique", "Reason: %(reasonText)s": "Raison : %(reasonText)s", @@ -996,7 +991,6 @@ "Join this community": "Rejoindre cette communauté", "Leave this community": "Quitter cette communauté", "Stickerpack": "Pack de stickers", - "Sticker Messages": "Messages sticker", "You don't currently have any stickerpacks enabled": "Vous n'avez activé aucun pack de stickers pour l'instant", "Add a stickerpack": "Ajouter un pack de stickers", "Hide Stickers": "Masquer les stickers", @@ -1158,7 +1152,6 @@ "Preparing to send logs": "Préparation d'envoi des rapports", "Missing roomId.": "Identifiant de salon manquant.", "Picture": "Image", - "Click here to create a GitHub issue.": "Cliquez ici pour créer un signalement sur GitHub.", "Popout widget": "Détacher le widget", "Every page you use in the app": "Toutes les pages que vous utilisez dans l'application", "e.g. ": "par ex. ", diff --git a/src/i18n/strings/gl.json b/src/i18n/strings/gl.json index 06bff9eb76..6c329b5454 100644 --- a/src/i18n/strings/gl.json +++ b/src/i18n/strings/gl.json @@ -475,8 +475,6 @@ "Download %(text)s": "Baixar %(text)s", "Invalid file%(extra)s": "Ficheiro non válido %(extra)s", "Error decrypting image": "Fallo ao descifrar a imaxe", - "Image '%(Body)s' cannot be displayed.": "Imaxe '%(Body)s' non pode ser mostrada.", - "This image cannot be displayed.": "Esta imaxe non se pode ser mostrada.", "Error decrypting video": "Fallo descifrando vídeo", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s cambiou o avatar para %(roomName)s", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s eliminou o avatar da sala.", @@ -674,11 +672,8 @@ "Ignore request": "Ignorar petición", "Loading device info...": "Cargando información do dispositivo...", "Encryption key request": "Petición de chave de cifrado", - "Otherwise, click here to send a bug report.": "Se non, pulse aquí para enviar un informe de fallo.", "Unable to restore session": "Non se puido restaurar a sesión", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Atopamos un erro intentando restablecer a sesión anterior. Si continúa, deberá conectarse de novo, e a parte cifrada do chat non será lexible.", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Si anteriormente utilizou unha versión máis recente de Riot, a súa sesión podería non ser compatible con esta versión. Peche esta ventá e volte a versión máis recente.", - "Continue anyway": "Continuar igualmente", "Invalid Email Address": "Enderezo de email non válido", "This doesn't appear to be a valid email address": "Este non semella ser un enderezo de email válido", "Verification Pending": "Verificación pendente", @@ -996,7 +991,6 @@ "Submit debug logs": "Enviar informes de depuración", "Opens the Developer Tools dialog": "Abre o cadro de Ferramentas de Desenvolvedoras", "Stickerpack": "Peganitas", - "Sticker Messages": "Mensaxes pegadas", "You don't currently have any stickerpacks enabled": "Non ten paquetes de pegatinas habilitados", "Add a stickerpack": "Engadir un paquete de pegatinas", "Hide Stickers": "Agochar pegatinas", @@ -1110,7 +1104,6 @@ "What's new?": "Qué hai de novo?", "Notify me for anything else": "Notificarme todo o demáis", "When I'm invited to a room": "Cando son convidado a unha sala", - "Click here to create a GitHub issue.": "Pulse aquí para crear un reporte en GitHub.", "Can't update user notification settings": "Non se poden actualizar os axutes de notificación", "Notify for all other messages/rooms": "Notificar para todas as outras mensaxes/salas", "Unable to look up room ID from server": "Non se puido atopar o ID da sala do servidor", diff --git a/src/i18n/strings/he.json b/src/i18n/strings/he.json index 7e747428a6..dbae2858a9 100644 --- a/src/i18n/strings/he.json +++ b/src/i18n/strings/he.json @@ -195,7 +195,6 @@ "What's new?": "מה חדש?", "Notify me for anything else": "התראה לי על כל דבר אחר", "When I'm invited to a room": "מתי אני מוזמן לחדר", - "Click here to create a GitHub issue.": "הקלק כאן ליצירת דווח תקלה ‫ב: GitHub .", "Can't update user notification settings": "לא ניתן לעדכן הגדרות התראה למשתמש", "Notify for all other messages/rooms": "התראה לכל שאר ההודעות/החדרים", "Unable to look up room ID from server": "לא ניתן לאתר מזהה חדר על השרת", diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index c2b8af12ee..15691712db 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -279,7 +279,6 @@ "olm version:": "olm verzió:", "Once encryption is enabled for a room it cannot be turned off again (for now)": "Ha egyszer bekapcsolod a titkosítást a szobába utána nem lehet kikapcsolni (egyenlőre)", "Only people who have been invited": "Csak akiket meghívtak", - "Otherwise, click here to send a bug report.": "Különben hiba jelentés küldéséhez kattints ide.", "Password": "Jelszó", "Password:": "Jelszó:", "Passwords can't be empty": "A jelszó nem lehet üres", @@ -562,7 +561,6 @@ "Verify device": "Eszköz ellenőrzése", "I verify that the keys match": "Megerősítem, hogy a kulcsok egyeznek", "Unable to restore session": "A kapcsolatot nem lehet visszaállítani", - "Continue anyway": "Mindenképpen tovább", "\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" szobában olyan eszközök vannak amiket még nem láttál.", "Unknown devices": "Ismeretlen eszköz", "Unknown Address": "Ismeretlen cím", @@ -585,8 +583,6 @@ "What does this mean?": "Ez mit jelent?", "Error decrypting audio": "Hiba a hang visszafejtésénél", "Error decrypting image": "Hiba a kép visszafejtésénél", - "Image '%(Body)s' cannot be displayed.": "'%(Body)s' képet nem lehet megjeleníteni.", - "This image cannot be displayed.": "Ezt a képet nem lehet megjeleníteni.", "Error decrypting video": "Hiba a videó visszafejtésénél", "Add an Integration": "Integráció hozzáadása", "Removed or unknown message type": "Eltávolított üzenet vagy ismeretlen üzenet típus", @@ -621,7 +617,6 @@ "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Biztos hogy eltávolítod (törlöd) ezt az eseményt? Figyelem, ha törlöd vagy megváltoztatod a szoba nevét vagy a témát ez a változtatás érvényét vesztheti.", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Az eszköz megbízhatóságának ellenőrzéséhez, lépj kapcsolatba a tulajdonossal valami más csatornán (pl. személyesen vagy telefon hívással) és kérdezd meg, hogy a kulcs amit a Felhasználói Beállításoknál látnak az eszközhöz megegyezik-e a kulccsal itt:", "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Ha megegyezik, nyomd meg az megerősítő gombot alul. Ha nem akkor valaki más használja az eszközt és inkább a Feketelista gombot szeretnéd használni.", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Az előző kapcsolat visszaállításánál hibára akadtunk. Ha folytatod újra be kell jelentkezned és a titkosított csevegések olvashatatlanok lesznek.", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Ha egy újabb Riot verziót használtál valószínűleg ez kapcsolat nem lesz kompatibilis vele. Zárd be az ablakot és térj vissza az újabb verzióhoz.", "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Jelenleg fekete listára teszel minden ismeretlen eszközt. Ha üzenetet szeretnél küldeni ezekre az eszközökre először ellenőrizned kell őket.", "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Azt javasoljuk, hogy menj végig ellenőrző folyamaton minden eszköznél, hogy meg megerősítsd minden eszköz a jogos tulajdonosához tartozik, de újraküldheted az üzenetet ellenőrzés nélkül, ha úgy szeretnéd.", @@ -996,7 +991,6 @@ "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "A közösséget name és avatar érintő változások legfeljebb 30 percig nem lesznek láthatók más felhasználók számára.", "Leave this community": "Közösség elhagyása", "Stickerpack": "Matrica csomag", - "Sticker Messages": "Matrica üzenetek", "You don't currently have any stickerpacks enabled": "Nincs engedélyezett matrica csomagod", "Add a stickerpack": "Matrica csomag hozzáadása", "Hide Stickers": "Matricák elrejtése", @@ -1109,7 +1103,6 @@ "What's new?": "Mik az újdonságok?", "Notify me for anything else": "Értesíts minden egyéb esetben", "When I'm invited to a room": "Amikor meghívnak egy szobába", - "Click here to create a GitHub issue.": "Kattints ide GitHub hibajegy nyitásához .", "Can't update user notification settings": "Nem lehet frissíteni az értesítési beállításokat", "Notify for all other messages/rooms": "Értesítés minden más üzenethez/szobához", "Unable to look up room ID from server": "Nem lehet a szoba azonosítóját megkeresni a szerveren", diff --git a/src/i18n/strings/it.json b/src/i18n/strings/it.json index ba7417bcc8..b660231915 100644 --- a/src/i18n/strings/it.json +++ b/src/i18n/strings/it.json @@ -521,8 +521,6 @@ "Download %(text)s": "Scarica %(text)s", "Invalid file%(extra)s": "File non valido %(extra)s", "Error decrypting image": "Errore decifratura immagine", - "This image cannot be displayed.": "Questa immagine non può essere visualizzata.", - "Image '%(Body)s' cannot be displayed.": "L'immagine '%(Body)s' non può essere visualizzata.", "Error decrypting video": "Errore decifratura video", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s ha cambiato l'avatar per %(roomName)s", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s ha rimosso l'avatar della stanza.", @@ -714,11 +712,8 @@ "Ignore request": "Ignora la richiesta", "Loading device info...": "Caricamento info dispositivo...", "Encryption key request": "Richiesta chiave di cifratura", - "Otherwise, click here to send a bug report.": "Altrimenti clicca qui per inviare una segnalazione di errore.", "Unable to restore session": "Impossibile ripristinare la sessione", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Abbiamo riscontrato un errore tentando di ripristinare la tua sessione precedente. Se continui, dovrai accedere di nuovo e la cronologia della chat criptata sarà illeggibile.", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Se hai usato precedentemente una versione più recente di Riot, la tua sessione potrebbe essere incompatibile con questa versione. Chiudi questa finestra e torna alla versione più recente.", - "Continue anyway": "Continua comunque", "Invalid Email Address": "Indirizzo email non valido", "This doesn't appear to be a valid email address": "Questo non sembra essere un indirizzo email valido", "Verification Pending": "In attesa di verifica", @@ -993,7 +988,6 @@ "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Le modifiche al nome e all'avatar effettuate alla tua comunità potrebbero non essere visibili agli altri utenti per i prossimi 30 minuti.", "Join this community": "Unisciti a questa comunità", "Leave this community": "Esci da questa comunità", - "Sticker Messages": "Messaggi adesivi", "You don't currently have any stickerpacks enabled": "Non hai ancora alcun pacchetto di adesivi attivato", "Add a stickerpack": "Aggiungi un pacchetto di adesivi", "Who can join this community?": "Chi può unirsi a questa comunità?", @@ -1104,7 +1098,6 @@ "What's new?": "Cosa c'è di nuovo?", "Notify me for anything else": "Notificami per qualsiasi altra cosa", "When I'm invited to a room": "Quando vengo invitato/a in una stanza", - "Click here to create a GitHub issue.": "Clicca qui per creare una segnalazione su GitHub.", "Can't update user notification settings": "Impossibile aggiornare le impostazioni di notifica dell'utente", "Notify for all other messages/rooms": "Notifica per tutti gli altri messaggi/stanze", "Unable to look up room ID from server": "Impossibile consultare l'ID stanza dal server", diff --git a/src/i18n/strings/ja.json b/src/i18n/strings/ja.json index 013790aa80..3908ede0e2 100644 --- a/src/i18n/strings/ja.json +++ b/src/i18n/strings/ja.json @@ -210,7 +210,6 @@ "Failed to send custom event.": "カスタムイベントの送信に失敗しました。", "What's new?": "新着", "Notify me for anything else": "他の場合についても通知する", - "Click here to create a GitHub issue.": "ここをクリック してGithubの問題を報告してください。", "Notify for all other messages/rooms": "他のすべてのメッセージ又は部屋について通知する", "Unable to look up room ID from server": "サーバから部屋IDを検索できません", "Couldn't find a matching Matrix room": "一致するMatrixの部屋を見つけることができませんでした", diff --git a/src/i18n/strings/ko.json b/src/i18n/strings/ko.json index ff5ebd72d7..f0b8cc454f 100644 --- a/src/i18n/strings/ko.json +++ b/src/i18n/strings/ko.json @@ -286,7 +286,6 @@ "Phone": "전화", "Once encryption is enabled for a room it cannot be turned off again (for now)": "방을 암호화하면 암호화를 도중에 끌 수 없어요. (현재로서는)", "Only people who have been invited": "초대받은 사람만", - "Otherwise, click here to send a bug report.": "그 밖에는, 여기를 눌러 오류 보고서를 보내주세요.", "%(senderName)s placed a %(callType)s call.": "%(senderName)s님이 %(callType)s 전화를 걸었어요.", "Please check your email and click on the link it contains. Once this is done, click continue.": "이메일을 확인하시고 그 안에 있는 주소를 누르세요. 이 일을 하고 나서, 계속하기를 누르세요.", "Power level must be positive integer.": "권한 등급은 양의 정수여야만 해요.", @@ -569,10 +568,8 @@ "In future this verification process will be more sophisticated.": "앞으로는 이 확인 과정이 더 정교해질 거에요.", "Verify device": "인증한 장치", "I verify that the keys match": "키가 맞는 걸 확인했어요", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "이전 세션을 복구하는 도중 오류가 일어났어요. 계속하시려면, 다시 로그인하셔야 하고, 암호화한 기록은 읽을 수 없게 될 거에요.", "Unable to restore session": "세션을 복구할 수 없어요", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "이전에 더 최근 버전의 라이엇을 쓰셨다면, 이 버전과 맞지 않을 거에요. 창을 닫고 더 최근 버전으로 돌아가세요.", - "Continue anyway": "무시하고 계속하기", "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "현재 인증하지 않은 장치를 요주의로 지정하셨어요. 이 장치들에 메시지를 보내려면 인증을 해야 해요.", "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "각 장치가 알맞은 소유자에게 속해 있는지 인증 과정을 거치길 추천하지만, 원하신다면 그러지 않고 메시지를 다시 보내실 수 있어요.", "\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\"에 본 적 없는 장치가 있어요.", @@ -601,8 +598,6 @@ "Identity server URL": "ID 서버 URL", "Error decrypting audio": "음성 해독 오류", "Error decrypting image": "사진 해독 오류", - "Image '%(Body)s' cannot be displayed.": "'%(Body)s' 사진을 보여드릴 수 없어요.", - "This image cannot be displayed.": "이 사진을 보여드릴 수 없어요.", "Error decrypting video": "영상 해독 오류", "Add an Integration": "통합 추가", "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?": "타사 사이트로 이동하는데 %(integrationsUrl)s에서 쓰도록 계정을 인증할 수 있어요. 계속하시겠어요?", diff --git a/src/i18n/strings/lv.json b/src/i18n/strings/lv.json index 6282d40daf..17238aa206 100644 --- a/src/i18n/strings/lv.json +++ b/src/i18n/strings/lv.json @@ -272,7 +272,6 @@ "Once encryption is enabled for a room it cannot be turned off again (for now)": "Tiklīdz istabai tiks iespējota šifrēšana, tā vairs nebūs atslēdzama (pašlaik)", "Only people who have been invited": "Vienīgi cilvēki, kuri uzaicināti", "Operation failed": "Darbība neizdevās", - "Otherwise, click here to send a bug report.": "pretējā gadījumā, klikšķini šeit, lai nosūtītu paziņojumu par kļūdu.", "Password": "Parole", "Password:": "Parole:", "Passwords can't be empty": "Paroles nevar būt tukšas", @@ -350,7 +349,6 @@ "Failed to invite the following users to the %(roomName)s room:": "Neizdevās uzaicināt sekojošos lietotājus uz %(roomName)s istabu:", "\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" atrodas ierīces, kuras Tu neesi iepriekš redzējis/usi.", "You are registering with %(SelectedTeamName)s": "Tu reģistrējies ar %(SelectedTeamName)s", - "Image '%(Body)s' cannot be displayed.": "Attēlu '%(Body)s' nav iespējams parādīt.", "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?": "Notiek Tevis novirzīšana uz ārēju trešās puses vietni. Tu vari atļaut savam kontam piekļuvi ar %(integrationsUrl)s. Vai vēlies turpināt?", "Ongoing conference call%(supportedText)s.": "Notiekošs konferences zvans %(supportedText)s.", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s dzēsa istabas avataru.", @@ -515,7 +513,6 @@ "Nov": "Nov.", "Dec": "Dec.", "Set a display name:": "Iestatīt attēloto vārdu:", - "This image cannot be displayed.": "Šo attēlu nav iespējams parādīt.", "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s nomainīja istabas avataru uz ", "Upload an avatar:": "Augšuplādē avataru (profila attēlu):", "This server does not support authentication with a phone number.": "Šis serveris neatbalsta autentifikāciju pēc telefona numura.", @@ -582,10 +579,8 @@ "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Ja tā sakrīt, tad nospied zemāk esošo verifikācijas pogu . Ja nesakrīt, tad kāds cits ir piekļuvis šai ierīcei un šādā gadījumā Tu, iespējams, vēlies izmantot \"melnais saraksts\" iespēju.", "Verify device": "Verificēt ierīci", "I verify that the keys match": "Es apstiprinu, ka atslēgas sakrīt", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Atgadījās kļūda, mēģinot atjaunot tavu iepriekšējo sesiju. Ja vēlies turpināt, Tev ir jāpierakstās no jauna, taču šifrētā čata ziņu vēsture nebūs izlasāma.", "Unable to restore session": "Nav iespējams atjaunot sesiju", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Ja Tu iepriekš izmantoji jaunāku Riot versiju, tava sesija var nebūt saderīga ar šo versiju. Aizver šo logu un atgriezies jaunākajā versijā.", - "Continue anyway": "Turpināt jebkurā gadījumā", "Unknown devices": "Nezināmas ierīces", "Unknown Address": "Nezināma adrese", "Unblacklist": "Atbloķēšanas saraksts", @@ -1097,7 +1092,6 @@ "What's new?": "Kas jauns?", "Notify me for anything else": "Paziņot man par jebko citu", "When I'm invited to a room": "Kad esmu uzaicināts/a istabā", - "Click here to create a GitHub issue.": "Nospied šeit lai izveidotu GitHub problēmpaziņojumu.", "Can't update user notification settings": "Neizdodas atjaunot lietotāja paziņojumu iestatījumus", "Notify for all other messages/rooms": "Paziņot par visām citām ziņām/istabām", "Unable to look up room ID from server": "Nav iespējams no servera iegūt istabas Id", diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index e96280f2e4..1ddcda076e 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -329,7 +329,6 @@ "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 ruimte is ingeschakeld kan het niet meer worden uitgeschakeld (kan later wijzigen)", "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 geheel getal zijn.", "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s heeft zijn of haar weergavenaam (%(oldDisplayName)s) verwijderd.", @@ -573,10 +572,8 @@ "In future this verification process will be more sophisticated.": "In de toekomst zal dit verificatie proces meer geraffineerd zijn.", "Verify device": "Apparaat verifiëren", "I verify that the keys match": "Ik verifieer dat de sleutels overeenkomen", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "We ervaren een fout terwijl er wordt geprobeerd om de vorige sessie te herstellen. Als je doorgaat moet je opnieuw inloggen en versleutelde gespreksgeschiedenis zal onleesbaar zijn.", "Unable to restore session": "Het is niet mogelijk om de sessie te herstellen", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Als je eerst gebruik hebt gemaakt van een recentere versie van Riot, dan is je sessie misschien onverenigbaar met deze versie. Sluit dit scherm en ga terug naar de recentere versie.", - "Continue anyway": "Toch doorgaan", "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "We raden je aan om door het verificatieproces van elk apparaat te gaan om te bevestigen dat ze tot de legitieme eigenaar behoren maar je kan het bericht versturen zonder te verifiëren als je dat liever doet.", "\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" bevat apparaten die je nog niet eerder hebt gezien.", "Unknown devices": "Onbekende apparaten", @@ -602,8 +599,6 @@ "What does this mean?": "Wat betekent dit?", "Error decrypting audio": "Fout met het ontsleutelen van de audio", "Error decrypting image": "Fout met het ontsleutelen van de afbeelding", - "Image '%(Body)s' cannot be displayed.": "Afbeelding '%(Body)s' kan niet worden weergeven.", - "This image cannot be displayed.": "Deze afbeelding kan niet worden weergeven.", "Error decrypting video": "Fout met het ontsleutelen van de video", "Add an Integration": "Voeg een integratie toe", "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?": "Je wordt zo naar een derde-partij-website verbonden zodat je het account kan legitimeren voor gebruik met %(integrationsUrl)s. Wil je doorgaan?", @@ -986,7 +981,6 @@ "Failed to remove tag %(tagName)s from room": "Het is niet gelukt om de label %(tagName)s van de ruimte te verwijderen", "Failed to add tag %(tagName)s to room": "Het is niet gelukt om de label %(tagName)s aan deze ruimte toe te voegen", "Stickerpack": "Stickerpakket", - "Sticker Messages": "Sticker Berichten", "You don't currently have any stickerpacks enabled": "Je hebt momenteel geen stickerpakketten aan staan", "Add a stickerpack": "Stickerpakket toevoegen", "Hide Stickers": "Stickers verbergen", @@ -1151,7 +1145,6 @@ "Checking for an update...": "Aan het kijken voor een update...", "There are advanced notifications which are not shown here": "Er zijn geavanceerde notificaties die hier niet getoond worden", "Logs sent": "Logs verstuurd", - "Click here to create a GitHub issue.": "Klik hier om een Github opgave in te dienen.", "GitHub issue link:": "GitHub opgave link:", "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Debug logs bevatten applicatie-gebruik data inclusief je gebruikersnaam, de ID's of namen van de ruimtes en groepen die je hebt bezocht en de gebruikersnamen van andere gebruikers. Ze bevatten geen berichten.", "Failed to send logs: ": "Het is niet gelukt om de logs te versturen: ", diff --git a/src/i18n/strings/pl.json b/src/i18n/strings/pl.json index 445d3ad025..8d7c5d11da 100644 --- a/src/i18n/strings/pl.json +++ b/src/i18n/strings/pl.json @@ -11,7 +11,6 @@ "Start chatting": "Rozpocznij konwersację", "Start Chatting": "Rozpocznij Konwersację", "Updates": "Aktualizacje", - "This image cannot be displayed.": "Ten obrazek nie może zostać wyświetlony.", "Default server": "Domyślny serwer", "Add User": "Dodaj użytkownika", "Verify...": "Zweryfikuj...", @@ -347,7 +346,6 @@ "olm version:": "wersja olm:", "Once encryption is enabled for a room it cannot be turned off again (for now)": "Po włączeniu szyfrowania w pokoju nie można go ponownie wyłączyć (póki co)", "Only people who have been invited": "Tylko ludzie, którzy zostali zaproszeni", - "Otherwise, click here to send a bug report.": "W przeciwnym razie, kliknij tutaj by wysłać raport o błędzie.", "Password": "Hasło", "Password:": "Hasło:", "Passwords can't be empty": "Hasła nie mogą być puste", @@ -607,10 +605,8 @@ "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Jeśli klucz pasuje, naciśnij na przycisk \"Zweryfikuj\" poniżej. Jeśli nie, to ktoś inny najprawdopodobniej przejmuje lub podszywa się pod to urządzenie i powinieneś nacisnąć przycisk dodania do czarnej listy.", "In future this verification process will be more sophisticated.": "W przyszłości proces weryfikacji będzie bardziej skomplikowany.", "I verify that the keys match": "Upewnię się, że klucze się zgadzają", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Napotkaliśmy błąd podczas próby przywrócenia Twojej poprzedniej sesji. Aby kontynuować, musisz zalogować się ponownie, a zaszyfrowana historia czatu nie będzie do odczytania.", "Unable to restore session": "Przywrócenie sesji jest niemożliwe", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Jeśli wcześniej używałeś/aś nowszej wersji Riot, Twoja sesja może być niekompatybilna z tą wersją. Zamknij to okno i powróć do nowszej wersji.", - "Continue anyway": "Kontynuuj mimo to", "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Aktualnie wpisujesz niezweryfikowane urządzenia na czarną listę; aby wysłać wiadomość do tych urządzeń musisz je zweryfikować.", "Riot collects anonymous analytics to allow us to improve the application.": "Riot zbiera anonimowe dane analityczne, aby umożliwić nam rozwijanie aplikacji.", "Verifies a user, device, and pubkey tuple": "Weryfikuje użytkownika, urządzenie i krotkę kluczy publicznych", @@ -632,7 +628,6 @@ "What does this mean?": "Co to znaczy?", "Error decrypting audio": "Błąd deszyfrowania audio", "Error decrypting image": "Błąd deszyfrowania obrazu", - "Image '%(Body)s' cannot be displayed.": "Obraz '%(Body)s' nie może zostać wyświetlony.", "Error decrypting video": "Błąd deszyfrowania wideo", "Removed or unknown message type": "Usunięto lub nieznany typ wiadomości", "Tried to load a specific point in this room's timeline, but was unable to find it.": "Próbowano załadować konkretny punkt na osi czasu w tym pokoju, ale nie nie można go znaleźć.", @@ -883,7 +878,6 @@ "What's new?": "Co nowego?", "Notify me for anything else": "Powiadom mnie o całej reszcie", "When I'm invited to a room": "Kiedy zostanę zaproszony do pokoju", - "Click here to create a GitHub issue.": "Kliknij tutaj aby założyć wątek na GitHubie dot. problemu.", "Can't update user notification settings": "Nie można zaktualizować ustawień powiadomień użytkownika", "Notify for all other messages/rooms": "Powiadamiaj o wszystkich innych wiadomośsciach/pokojach", "Unable to look up room ID from server": "Nie można wyszukać ID pokoju na serwerze", diff --git a/src/i18n/strings/pt.json b/src/i18n/strings/pt.json index 12339e6757..229d4f32a1 100644 --- a/src/i18n/strings/pt.json +++ b/src/i18n/strings/pt.json @@ -443,10 +443,8 @@ "In future this verification process will be more sophisticated.": "No futuro, este processo de verificação será mais sofisticado.", "Verify device": "Verificar o dispositivo", "I verify that the keys match": "Eu confirmo que as chaves são iguais", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Encontramos um erro tentando restaurar sua sessão anterior. Se você continuar, terá que fazer login novamente, e o histórico da conversa criptografada se tornará ilegível.", "Unable to restore session": "Não foi possível restaurar a sessão", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Se você já usou antes uma versão mais recente do Riot, a sua sessão pode ser incompatível com esta versão. Feche esta janela e tente abrir com a versão mais recente.", - "Continue anyway": "Continuar de qualquer maneira", "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Você está atualmente bloqueando dispositivos não verificados. Para enviar mensagens para estes dispositivos, você necessita antes verificá-los.", "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Nós recomendamos que você passe pelo processo de verificação para cada dispositivo para confirmar que eles pertencem às pessoas que efetivamente são suas donas, mas você pode reenviar a mensagem sem verificar isso, se assim o desejar.", "\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" contém dispositivos que você não viu antes.", @@ -478,8 +476,6 @@ "What does this mean?": "O que isso significa?", "Error decrypting audio": "Erro ao descriptografar o áudio", "Error decrypting image": "Erro ao descriptografar a imagem", - "Image '%(Body)s' cannot be displayed.": "A imagem '%(Body)s' não pode ser exibida.", - "This image cannot be displayed.": "Esta imagem não pode ser exibida.", "Error decrypting video": "Erro ao descriptografar o vídeo", "Add an Integration": "Adicionar uma integração", "Removed or unknown message type": "Mensagem removida ou de tipo desconhecido", @@ -560,7 +556,6 @@ "You have been kicked from %(roomName)s by %(userName)s.": "Você foi removido(a) da sala %(roomName)s por %(userName)s.", "Undecryptable": "Não é possível descriptografar", "Incoming video call from %(name)s": "Chamada de vídeo de %(name)s recebida", - "Otherwise, click here to send a bug report.": "Caso contrário, clique aqui para enviar um relatório de erros.", "To link to a room it must have an address.": "Para produzir um link para uma sala, ela necessita ter um endereço.", "Your home server does not support device management.": "O seu Servidor de Base não suporta o gerenciamento de dispositivos.", "Alias (optional)": "Apelido (opcional)", diff --git a/src/i18n/strings/pt_BR.json b/src/i18n/strings/pt_BR.json index 9a4739357e..a3333de2f2 100644 --- a/src/i18n/strings/pt_BR.json +++ b/src/i18n/strings/pt_BR.json @@ -445,10 +445,8 @@ "In future this verification process will be more sophisticated.": "No futuro, este processo de verificação será mais sofisticado.", "Verify device": "Verificar o dispositivo", "I verify that the keys match": "Eu confirmo que as chaves são iguais", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Encontramos um erro tentando restaurar sua sessão anterior. Se você continuar, terá que fazer login novamente, e o histórico da conversa criptografada se tornará ilegível.", "Unable to restore session": "Não foi possível restaurar a sessão", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Se você já usou antes uma versão mais recente do Riot, a sua sessão pode ser incompatível com esta versão. Feche esta janela e tente abrir com a versão mais recente.", - "Continue anyway": "Continuar de qualquer maneira", "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Você está atualmente bloqueando dispositivos não verificados. Para enviar mensagens para estes dispositivos, você necessita antes verificá-los.", "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Nós recomendamos que você passe pelo processo de verificação para cada dispositivo para confirmar que eles pertencem às pessoas que efetivamente são suas donas, mas você pode reenviar a mensagem sem verificar isso, se assim o desejar.", "\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" contém dispositivos que você não viu antes.", @@ -480,8 +478,6 @@ "What does this mean?": "O que isso significa?", "Error decrypting audio": "Erro ao descriptografar o áudio", "Error decrypting image": "Erro ao descriptografar a imagem", - "Image '%(Body)s' cannot be displayed.": "A imagem '%(Body)s' não pode ser exibida.", - "This image cannot be displayed.": "Esta imagem não pode ser exibida.", "Error decrypting video": "Erro ao descriptografar o vídeo", "Add an Integration": "Adicionar uma integração", "Removed or unknown message type": "Mensagem removida ou de tipo desconhecido", @@ -590,7 +586,6 @@ "Last seen": "Último uso", "Level:": "Nível:", "No display name": "Sem nome público de usuária(o)", - "Otherwise, click here to send a bug report.": "Caso contrário, clique aqui para enviar um relatório de erros.", "Private Chat": "Conversa privada", "Public Chat": "Conversa pública", "Reason: %(reasonText)s": "Justificativa: %(reasonText)s", diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 2e6bdf45f0..c27580979e 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -492,10 +492,8 @@ "In future this verification process will be more sophisticated.": "В будущем процесс проверки будет усовершенствован.", "Verify device": "Проверить устройство", "I verify that the keys match": "Я подтверждаю, что ключи совпадают", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Произошла ошибка при попытке восстановить предыдущий сеанс. Если продолжить, потребуется снова войти в систему, а зашифрованная история чата будет нечитаема.", "Unable to restore session": "Восстановление сессии не удалось", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Если вы использовали более новую версию Riot, то ваша сессия может быть несовместима с текущей. Закройте это окно и вернитесь к использованию более новой версии.", - "Continue anyway": "Все равно продолжить", "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "У вас включено занесение непроверенных устройств в черный список. Для отправки сообщений на эти устройства вам необходимо их проверить.", "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Мы рекомендуем вам выполнить процедуру проверки каждого устройства, чтобы удостовериться, что они принадлежат их законному владельцу, но вы можете переотправить сообщение без проверки, если хотите.", "\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" содержит неподтвержденные устройства.", @@ -523,8 +521,6 @@ "What does this mean?": "Что это значит?", "Error decrypting audio": "Ошибка расшифровки аудиозаписи", "Error decrypting image": "Ошибка расшифровки изображения", - "Image '%(Body)s' cannot be displayed.": "Изображение '%(Body)s' не может быть отображено.", - "This image cannot be displayed.": "Не удается показать изображение.", "Error decrypting video": "Ошибка расшифровки видео", "Add an Integration": "Добавить интеграцию", "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?": "Вы будете перенаправлены на внешний сайт, чтобы войти в свою учетную запись для использования с %(integrationsUrl)s. Продолжить?", @@ -586,7 +582,6 @@ "Last seen": "Последний вход", "Level:": "Уровень:", "No display name": "Нет отображаемого имени", - "Otherwise, click here to send a bug report.": "В противном случае, нажмите 2 для отправки отчета об ошибке.", "Private Chat": "Приватный чат", "Public Chat": "Публичный чат", "Reason: %(reasonText)s": "Причина: %(reasonText)s", @@ -998,7 +993,6 @@ "Who can join this community?": "Кто может присоединиться к этому сообществу?", "Everyone": "Все", "Stickerpack": "Стикеры", - "Sticker Messages": "Стикеры", "Add a stickerpack": "Добавить стикеры", "Hide Stickers": "Скрыть стикеры", "Show Stickers": "Показать стикеры", @@ -1109,7 +1103,6 @@ "What's new?": "Что нового?", "Notify me for anything else": "Уведомлять во всех остальных случаях", "When I'm invited to a room": "Приглашения в комнаты", - "Click here to create a GitHub issue.": "Нажмите здесь для создания запроса о проблеме на GitHub.", "Can't update user notification settings": "Не удалось обновить пользовательские настройки оповещения", "Notify for all other messages/rooms": "Уведомлять обо всех остальных сообщениях и комнатах", "Unable to look up room ID from server": "Не удалось найти ID комнаты на сервере", diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index 142b5dfea9..523cabaa68 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -423,8 +423,6 @@ "Download %(text)s": "Stiahnuť %(text)s", "Invalid file%(extra)s": "Neplatný súbor%(extra)s", "Error decrypting image": "Chyba pri dešifrovaní obrázka", - "Image '%(Body)s' cannot be displayed.": "Nie je možné zobraziť obrázok '%(Body)s'.", - "This image cannot be displayed.": "Tento obrázok nie je možné zobraziť.", "Error decrypting video": "Chyba pri dešifrovaní videa", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s zmenil obrázok miestnosti %(roomName)s", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s odstránil obrázok miestnosti.", @@ -611,11 +609,8 @@ "Ignore request": "Ignorovať žiadosť", "Loading device info...": "Načítanie informácií o zariadení...", "Encryption key request": "Žiadosť o šifrovacie kľúče", - "Otherwise, click here to send a bug report.": "inak kliknutím sem nahláste chybu.", "Unable to restore session": "Nie je možné obnoviť reláciu", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Pri pokuse o obnovenie vašej predchádzajúcej relácie sa vyskytla chyba. Ak budete pokračovať, musíte sa znovu prihlásiť, a história šifrovaných konverzácii nebude viac čitateľná.", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Ak ste sa v minulosti prihlásili s novšou verziou programu Riot, vaša relácia nemusí byť kompatibilná s touto verziou. Zatvorte prosím toto okno a vráťte sa cez najnovšiu verziu Riot.", - "Continue anyway": "Napriek tomu pokračovať", "Invalid Email Address": "Nesprávna emailová adresa", "This doesn't appear to be a valid email address": "Zdá sa, že toto nie je platná emailová adresa", "Verification Pending": "Nedokončené overenie", @@ -996,7 +991,6 @@ "Submit debug logs": "Odoslať ladiace záznamy", "Opens the Developer Tools dialog": "Otvorí dialóg nástroje pre vývojárov", "Stickerpack": "Balíček nálepiek", - "Sticker Messages": "Správy s nálepkami", "You don't currently have any stickerpacks enabled": "Momentálne nemáte aktívne žiadne balíčky s nálepkami", "Add a stickerpack": "Pridať balíček s nálepkami", "Hide Stickers": "Skryť nálepky", @@ -1109,7 +1103,6 @@ "What's new?": "Čo je nové?", "Notify me for anything else": "Oznamovať mi všetko ostatné", "When I'm invited to a room": "Pozvania vstúpiť do miestnosti", - "Click here to create a GitHub issue.": "Kliknutím sem nám pošlete hlásenie o chybe cez Github.", "Can't update user notification settings": "Nie je možné aktualizovať používateľské nastavenia oznamovania", "Notify for all other messages/rooms": "oznamovať všetky ostatné správy / miestnosti", "Unable to look up room ID from server": "Nie je možné vyhľadať ID miestnosti na servery", diff --git a/src/i18n/strings/sq.json b/src/i18n/strings/sq.json index 9dbb76396e..2936695a6d 100644 --- a/src/i18n/strings/sq.json +++ b/src/i18n/strings/sq.json @@ -246,7 +246,6 @@ "Can't update user notification settings": "S’përditësohen dot rregullime njoftimi të përdoruesit", "Notify for all other messages/rooms": "Njoftim për krejt mesazhet/dhomat e tjera", "Unable to look up room ID from server": "S’arrihet të kërkohet ID dhome nga shërbyesi", - "Click here to create a GitHub issue.": "Klikoni këtu që të hapni një çështje në GitHub.", "Couldn't find a matching Matrix room": "S’u gjet dot një dhomë Matrix me përputhje", "Invite to this room": "Ftoje te kjo dhomë", "You cannot delete this message. (%(code)s)": "S’mund ta fshini këtë mesazh. (%(code)s)", diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index 5c91838e3e..dc39bb8cdd 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -480,8 +480,6 @@ "Download %(text)s": "Преузми %(text)s", "Invalid file%(extra)s": "Неисправна датотека %(extra)s", "Error decrypting image": "Грешка при дешифровању слике", - "Image '%(Body)s' cannot be displayed.": "Слика „%(Body)s“ се не може приказати.", - "This image cannot be displayed.": "Ова слика се не може приказати.", "Error decrypting video": "Грешка при дешифровању видеа", "%(senderDisplayName)s changed the avatar for %(roomName)s": "Корисник %(senderDisplayName)s је променио аватара собе %(roomName)s", "%(senderDisplayName)s removed the room avatar.": "Корисник %(senderDisplayName)s је уклонио аватара собе.", @@ -682,11 +680,8 @@ "Ignore request": "Занемари захтев", "Loading device info...": "Учитавам податке о уређају...", "Encryption key request": "Захтев за кључ шифровања", - "Otherwise, click here to send a bug report.": "У супротном, кликните овде да бисте послали извештај о грешци.", "Unable to restore session": "Не могу да повратим сесију", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Наишли смо на грешку приликом опоравка ваше претходне сесије. Ако наставите, мораћете да се пријавите поново и ваш шифровани историјат ћаскања неће бити читљив.", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Ако сте претходно користили новије издање Riot-а, ваша сесија може бити некомпатибилна са овим издањем. Затворите овај прозор и вратите се на новије издање.", - "Continue anyway": "Ипак настави", "Invalid Email Address": "Неисправна мејл адреса", "This doesn't appear to be a valid email address": "Изгледа да ово није исправна мејл адреса", "Verification Pending": "Чека се на проверу", @@ -1137,7 +1132,6 @@ "Your device resolution": "Резолуција вашег уређаја", "Popout widget": "Виџет за искакање", "Missing roomId.": "Недостаје roomId.", - "Sticker Messages": "Поруке са налепницама", "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Видео корисник %(displayName)s (%(userName)s) у %(dateTime)s", "You don't currently have any stickerpacks enabled": "Тренутно немате омогућено било које паковање са налепницама", "Add a stickerpack": "Додај паковање са налепницама", @@ -1151,7 +1145,6 @@ "Failed to send logs: ": "Нисам успео да пошаљем записнике: ", "Submit debug logs": "Пошаљи записнике за поправљање грешака", "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Записници за поправљање грешака садрже податке о коришћењу апликације међу којима се налази ваше корисничко име, ИБ-јеви или алијаси посећених соба или група и корисничка имена других корисника. Не садрже саме поруке.", - "Click here to create a GitHub issue.": "Кликните овде да бисте пријавили проблем на Гитхабу (GitHub).", "GitHub issue link:": "Веза до проблема на Гитхабу:", "Notes:": "Напомене:", "Unable to join community": "Не могу да приступим заједници", diff --git a/src/i18n/strings/sv.json b/src/i18n/strings/sv.json index 42c06615cb..4456cd1c2d 100644 --- a/src/i18n/strings/sv.json +++ b/src/i18n/strings/sv.json @@ -268,7 +268,6 @@ "Once encryption is enabled for a room it cannot be turned off again (for now)": "När kryptering aktiveras i ett rum kan det inte deaktiveras (tills vidare)", "Only people who have been invited": "Endast inbjudna", "Operation failed": "Handlingen misslyckades", - "Otherwise, click here to send a bug report.": "Annars kan du klicka här för att skicka en buggrapport.", "Password": "Lösenord", "Password:": "Lösenord:", "Passwords can't be empty": "Lösenorden kan inte vara tomma", diff --git a/src/i18n/strings/th.json b/src/i18n/strings/th.json index 17ba4d461f..6fa7febabd 100644 --- a/src/i18n/strings/th.json +++ b/src/i18n/strings/th.json @@ -407,7 +407,6 @@ "Custom level": "กำหนดระดับเอง", "No display name": "ไม่มีชื่อที่แสดง", "Only people who have been invited": "เฉพาะบุคคลที่ได้รับเชิญ", - "Otherwise, click here to send a bug report.": "หรือคลิกที่นี่เพื่อรายงานจุดบกพร่อง", "Power level must be positive integer.": "ระดับอำนาจต้องเป็นจำนวนเต็มบวก", "%(roomName)s does not exist.": "ไม่มีห้อง %(roomName)s อยู่จริง", "To link to a room it must have an address.": "ห้องต้องมีที่อยู่ก่อน ถึงจะลิงก์ได้", @@ -430,8 +429,6 @@ "What does this mean?": "นี่แปลว่าอะไร?", "Error decrypting audio": "เกิดข้อผิดพลาดในการถอดรหัสเสียง", "Error decrypting image": "เกิดข้อผิดพลาดในการถอดรหัสรูป", - "Image '%(Body)s' cannot be displayed.": "ไม่สามารถแสดงรูป '%(Body)s' ได้", - "This image cannot be displayed.": "ไม่สามารถแสดงรูปนี้ได้", "Error decrypting video": "เกิดข้อผิดพลาดในการถอดรหัสวิดิโอ", "Fetching third party location failed": "การเรียกข้อมูลตำแหน่งจากบุคคลที่สามล้มเหลว", "A new version of Riot is available.": "มี Riot เวอร์ชั่นใหม่", diff --git a/src/i18n/strings/tr.json b/src/i18n/strings/tr.json index d890ed634e..451383bc02 100644 --- a/src/i18n/strings/tr.json +++ b/src/i18n/strings/tr.json @@ -268,7 +268,6 @@ "Once encryption is enabled for a room it cannot be turned off again (for now)": "Bu oda için şifreleme etkinleştirildikten sonra tekrar kapatılamaz (şimdilik)", "Only people who have been invited": "Sadece davet edilmiş insanlar", "Operation failed": "Operasyon başarısız oldu", - "Otherwise, click here to send a bug report.": "Aksi taktirde , bir hata raporu göndermek için buraya tıklayın .", "Password": "Şifre", "Password:": "Şifre:", "Passwords can't be empty": "Şifreler boş olamaz", @@ -566,10 +565,8 @@ "In future this verification process will be more sophisticated.": "Gelecekte bu doğrulama işlemi daha gelişmiş olacak.", "Verify device": "Cihazı Doğrula", "I verify that the keys match": "Anahtarların uyuştuğunu doğruluyorum", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "Önceki oturumunuzu geri getirmeye çalışırken bir hata ile karşılaşdık . Devam ederseniz , tekrar oturum açmanız gerekecek , ve şifreli sohbet geçmişi okunamıyor hale gelecek.", "Unable to restore session": "Oturum geri yüklenemiyor", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Eğer daha önce Riot'un daha yeni bir versiyonunu kullandıysanız , oturumunuz bu sürümle uyumsuz olabilir . Bu pencereyi kapatın ve daha yeni sürüme geri dönün.", - "Continue anyway": "Her halükarda devam et", "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Şu anda doğrulanmamış cihazları kara listeye alıyorsunuz , bu cihazlara mesaj göndermek için onları doğrulamanız gerekir.", "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Her cihazın yasal sahiplerine ait olduklarını doğrulamak için doğrulama işlemini gerçekleştirmenizi öneririz, ancak tercih edip onaylamadan iletiyi tekrar gönderebilirsiniz.", "\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" daha önce görmediğiniz cihazları içeriyor.", @@ -601,8 +598,6 @@ "What does this mean?": "Bu ne anlama geliyor ?", "Error decrypting audio": "Ses şifre çözme hatası", "Error decrypting image": "Resim şifre çözme hatası", - "Image '%(Body)s' cannot be displayed.": "'%(Body)s' Resmi görüntülenemiyor.", - "This image cannot be displayed.": "Bu görüntü görüntülenemiyor.", "Error decrypting video": "Video şifre çözme hatası", "Add an Integration": "Entegrasyon ekleyin", "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?": "Hesabınızı %(integrationsUrl)s ile kullanmak üzere doğrulayabilmeniz için üçüncü taraf bir siteye götürülmek üzeresiniz. Devam etmek istiyor musunuz ?", diff --git a/src/i18n/strings/uk.json b/src/i18n/strings/uk.json index cb7809814a..bed499adc3 100644 --- a/src/i18n/strings/uk.json +++ b/src/i18n/strings/uk.json @@ -208,7 +208,6 @@ "What's new?": "Що нового?", "Notify me for anything else": "Сповіщати мене про будь-що інше", "View Source": "Переглянути джерело", - "Click here to create a GitHub issue.": "Нажміть тут для створення запитання по проблемі на GitHub.", "Can't update user notification settings": "Неможливо оновити налаштування користувацьких сповіщень", "Notify for all other messages/rooms": "Сповіщати щодо всіх повідомлень/кімнат", "Unable to look up room ID from server": "Неможливо знайти ID кімнати на сервері", diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index 2bbb5b1cc8..3f474cd337 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -303,7 +303,6 @@ "No more results": "没有更多结果", "olm version:": "olm 版本:", "Only people who have been invited": "只有被邀请的人", - "Otherwise, click here to send a bug report.": "否则,点击这里发送一个错误报告。", "Privacy warning": "隐私警告", "Private Chat": "私聊", "Privileged Users": "特权用户", @@ -360,7 +359,6 @@ "Verify device": "验证设备", "I verify that the keys match": "我验证密钥匹配", "Unable to restore session": "无法恢复会话", - "Continue anyway": "无论如何都继续", "Blacklist": "列入黑名单", "Unverify": "取消验证", "ex. @bob:example.com": "例如 @bob:example.com", @@ -595,7 +593,6 @@ "Confirm Removal": "确认移除", "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "这将会导致您的账户永远无法使用。你将无法重新注册同样的用户 ID。", "Verifies a user, device, and pubkey tuple": "验证一个用户、设备和密钥元组", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "我们在尝试恢复你之前的会话时遇到了一个错误。如果你继续,你将需要重新登录,加密的聊天历史将会不可读。", "Unknown devices": "未知设备", "Unknown Address": "未知地址", "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s 删除了他们的昵称 (%(oldDisplayName)s).", @@ -613,8 +610,6 @@ "Home server URL": "主服务器 URL", "Identity server URL": "身份认证服务器 URL", "What does this mean?": "这是什么意思?", - "Image '%(Body)s' cannot be displayed.": "图像 '%(Body)s' 无法显示。", - "This image cannot be displayed.": "图像无法显示。", "Add an Integration": "添加一个集成", "Removed or unknown message type": "被移除或未知的消息类型", "Ongoing conference call%(supportedText)s.": "正在进行的会议通话 %(supportedText)s.", @@ -809,7 +804,6 @@ "Disable Community Filter Panel": "停用社区面板", "Opt out of analytics": "退出统计分析服务", "Stickerpack": "贴图集", - "Sticker Messages": "贴图消息", "You don't currently have any stickerpacks enabled": "您目前没有启用任何贴纸包", "Add a stickerpack": "添加贴图集", "Your key share request has been sent - please check your other devices for key share requests.": "已请求共享密钥 - 请在您的其他设备上进行确认。", @@ -1082,7 +1076,6 @@ "What's new?": "有什么新闻?", "Notify me for anything else": "通知所有消息", "When I'm invited to a room": "当我被邀请进入聊天室", - "Click here to create a GitHub issue.": "点击这里 创建一个 GitHub issue.", "Can't update user notification settings": "不能更新用户通知设置", "Notify for all other messages/rooms": "为所有其他消息/聊天室显示通知", "Unable to look up room ID from server": "无法在服务器上找到聊天室 ID", diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 6f5ef68735..053031c677 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -221,8 +221,6 @@ "What does this mean?": "它代表什麼意思?", "Error decrypting audio": "解密音檔出錯", "Error decrypting image": "解密圖片出錯", - "Image '%(Body)s' cannot be displayed.": "圖片 '%(Body)s' 無法顯示。", - "This image cannot be displayed.": "這張圖片無法顯示。", "Error decrypting video": "解密影片出錯", "Add an Integration": "新增整合器", "Ongoing conference call%(supportedText)s.": "%(supportedText)s 正在進行會議通話。", @@ -360,7 +358,6 @@ "olm version:": "olm 版本:", "Once encryption is enabled for a room it cannot be turned off again (for now)": "這個房間只要啟用加密就不能再關掉了(從現在開始)", "Only people who have been invited": "僅有被邀請的夥伴", - "Otherwise, click here to send a bug report.": "否則,請點選此處來傳送錯誤報告。", "Password": "密碼", "Password:": "密碼:", "Passwords can't be empty": "密碼不能為空", @@ -590,10 +587,8 @@ "In future this verification process will be more sophisticated.": "在未來,這個過程會更加複雜。", "Verify device": "驗證裝置", "I verify that the keys match": "我驗證金鑰相符", - "We encountered an error trying to restore your previous session. If you continue, you will need to log in again, and encrypted chat history will be unreadable.": "我們在嘗試復原您的前一個工作階段中遇到了錯誤。若您繼續,您將會需要再次登入,而加密的聊天歷史也將會無法讀取。", "Unable to restore session": "無法復原工作階段", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "若您先前使用過較新版本的 Riot,您的工作階段可能與此版本不相容。關閉此視窗並回到較新的版本。", - "Continue anyway": "無論如何都繼續", "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "您目前正把未驗證的裝置列入黑名單;要傳送訊息到這些裝置,您必須先驗證它們。", "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "我們建議您對每一個裝置執行驗證過程以確認它們屬於其合法擁有者,但若您想要的話,您也可以重新傳送訊息而不必驗證它們。", "\"%(RoomName)s\" contains devices that you haven't seen before.": "「%(RoomName)s」包含了您先前沒看過的裝置。", @@ -996,7 +991,6 @@ "Join this community": "加入此社群", "Leave this community": "離開此社群", "Stickerpack": "貼圖包", - "Sticker Messages": "貼圖訊息", "You don't currently have any stickerpacks enabled": "您目前未啟用任何貼圖包", "Add a stickerpack": "新增貼圖包", "Hide Stickers": "隱藏貼圖", @@ -1110,7 +1104,6 @@ "Notify me for anything else": "所有消息都通知我", "View Source": "檢視來源", "Keywords": "關鍵字", - "Click here to create a GitHub issue.": "點選這裡來建立 GitHub 問題回報。", "Can't update user notification settings": "無法更新使用者的通知設定", "Notify for all other messages/rooms": "通知其他所有的訊息/聊天室", "Unable to look up room ID from server": "無法從伺服器找到聊天室 ID", From a88cbef331c89d21bc878e31c0e2976d27ce5d81 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 14 May 2018 16:22:28 +0100 Subject: [PATCH 1106/1160] tidy and switch to lexicographic sorting Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/RoomSettings.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index f1aba322e2..059e07ffdb 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -719,8 +719,14 @@ module.exports = React.createClass({ } }); - privilegedUsers.sort((a, b) => userLevels[b.key] - userLevels[a.key]); - mutedUsers.sort((a, b) => userLevels[a.key] - userLevels[b.key]); + // comparator for sorting PL users lexicographically on PL descending, MXID ascending. (case-insensitive) + const comparator = (a, b) => { + const plDiff = userLevels[b.key] - userLevels[a.key]; + return plDiff !== 0 ? plDiff : a.key.toLocaleLowerCase().localeCompare(b.key.toLocaleLowerCase()); + }; + + privilegedUsers.sort(comparator); + mutedUsers.sort(comparator); if (privilegedUsers.length) { privilegedUsersSection = From 3761cd405446891d4c5d0b7319fb163cbe469fcc Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 14 May 2018 16:35:12 +0100 Subject: [PATCH 1107/1160] When panels are shown/hidden, hide sticker picker --- src/components/views/rooms/Stickerpicker.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/components/views/rooms/Stickerpicker.js b/src/components/views/rooms/Stickerpicker.js index 2a523e5e82..1ea5639688 100644 --- a/src/components/views/rooms/Stickerpicker.js +++ b/src/components/views/rooms/Stickerpicker.js @@ -127,10 +127,19 @@ export default class Stickerpicker extends React.Component { } _onWidgetAction(payload) { - if (payload.action === "user_widget_updated") { - this.forceUpdate(); - } else if (payload.action === "stickerpicker_close") { - this.setState({showStickers: false}); + switch (payload.action) { + case "user_widget_updated": + this.forceUpdate(); + break; + case "stickerpicker_close": + this.setState({showStickers: false}); + break; + case "show_right_panel": + case "hide_right_panel": + case "show_left_panel": + case "hide_left_panel": + this.setState({showStickers: false}); + break; } } From 0591963cc1d8920b868ef0af37ddfb5e7c5871d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Wed, 2 May 2018 20:08:49 +0000 Subject: [PATCH 1108/1160] Translated using Weblate (French) Currently translated at 100.0% (1175 of 1175 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 9c0f3f98e8..4ff8900965 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -1176,5 +1176,6 @@ "Unable to reply": "Impossible de répondre", "At this time it is not possible to reply with an emote.": "Pour le moment il n'est pas possible de répondre avec un émoji.", "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Impossible de charger l'événement auquel il a été répondu, soit il n'existe pas, soit vous n'avez pas l'autorisation de le voir.", - "Collapse Reply Thread": "Dévoiler le fil de réponse" + "Collapse Reply Thread": "Dévoiler le fil de réponse", + "Enable widget screenshots on supported widgets": "Activer les captures d'écran des widgets pris en charge" } From e0236c3d3e4f832ab3b1adbc23c15ef64eab7dfa Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 14 May 2018 17:05:23 +0100 Subject: [PATCH 1109/1160] Fix issue with sticker picker rendering off-screen when the RightPanel is collapsed on a small monitor and the sticker picker is opened. --- src/components/views/rooms/Stickerpicker.js | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/Stickerpicker.js b/src/components/views/rooms/Stickerpicker.js index 1ea5639688..8f9e96dd3b 100644 --- a/src/components/views/rooms/Stickerpicker.js +++ b/src/components/views/rooms/Stickerpicker.js @@ -252,16 +252,33 @@ export default class Stickerpicker extends React.Component { * @param {Event} e Event that triggered the function */ _onShowStickersClick(e) { + // XXX: Simplify by using a context menu that is positioned relative to the sticker picker button + const buttonRect = e.target.getBoundingClientRect(); // The window X and Y offsets are to adjust position when zoomed in to page - const x = buttonRect.right + window.pageXOffset - 42; + let x = buttonRect.right + window.pageXOffset - 41; + + // Amount of horizontal space between the right of menu and the right of the viewport + // (10 = amount needed to make chevron centrally aligned) + const rightPad = 10; + + // When the sticker picker would be displayed off of the viewport, adjust x + // (302 = width of context menu, including borders) + x = Math.min(x, document.body.clientWidth - (302 + rightPad)); + + // Offset the chevron location, which is relative to the left of the context menu + // (10 = offset when context menu would not be displayed off viewport) + // (8 = value required in practice (possibly 10 - 2 where the 2 = context menu borders) + const stickerPickerChevronOffset = Math.max(10, 8 + window.pageXOffset + buttonRect.left - x); + const y = (buttonRect.top + (buttonRect.height / 2) + window.pageYOffset) - 19; this.setState({ showStickers: true, stickerPickerX: x, stickerPickerY: y, + stickerPickerChevronOffset, }); } @@ -314,7 +331,7 @@ export default class Stickerpicker extends React.Component { const stickerPicker = Date: Mon, 14 May 2018 14:57:30 +0000 Subject: [PATCH 1110/1160] Translated using Weblate (Bulgarian) Currently translated at 99.1% (1165 of 1175 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index dc48b0ba59..2a2b90f59f 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -62,9 +62,9 @@ "Whether or not you're logged in (we don't record your user name)": "Независимо дали сте влезли с профила си или не (не записваме Вашето потребителско име)", "Your language of choice": "Вашият език по избор", "Which officially provided instance you are using, if any": "Кой официално-предоставен сървър използвате, ако има такъв", - "Whether or not you're using the Richtext mode of the Rich Text Editor": "Независимо дали използвате Richtext режим на Rich Text Editor", - "Your homeserver's URL": "Адрес на Вашия Home сървър", - "Your identity server's URL": "Адрес на Вашия сървър за самоличност", + "Whether or not you're using the Richtext mode of the Rich Text Editor": "Дали използвате Richtext режим на Rich Text Editor", + "Your homeserver's URL": "Адресът на Вашия Home сървър", + "Your identity server's URL": "Адресът на Вашия сървър за самоличност", "Analytics": "Статистика", "The information being sent to us to help make Riot.im better includes:": "За да направим Riot по-добър, информацията изпратена до нас включва:", "Call Failed": "Неуспешно повикване", @@ -796,7 +796,7 @@ "%(count)s new messages|one": "%(count)s ново съобщение", "Active call": "Активен разговор", "Use with caution": "Внимавайте при използване", - "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Няма никой друг тук! Желаете ли да поканите други или да изключите предупреждението, че стаята е празна?", + "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Няма никой друг тук! Поканете други или изключете предупреждението, че стаята е празна?", "You seem to be uploading files, are you sure you want to quit?": "Изглежда, че качвате файлове. Сигурни ли сте, че искате да затворите програмата?", "You seem to be in a call, are you sure you want to quit?": "Изглежда, че сте в разговор. Сигурни ли сте, че искате да излезете от програмата?", "Failed to upload file": "Неуспешно качване на файлове", @@ -1158,5 +1158,14 @@ "Checking for an update...": "Проверяване за нова версия...", "There are advanced notifications which are not shown here": "Съществуват разширени настройки за известия, които не са показани тук", "Missing roomId.": "Липсва идентификатор на стая.", - "Picture": "Изображение" + "Picture": "Изображение", + "Every page you use in the app": "Всяка използвана страница от приложението", + "e.g. ": "например: ", + "Your User Agent": "Вашият браузър", + "Your device resolution": "Разделителната способност на устройството Ви", + "Always show encryption icons": "Винаги показвай икони за шифроване", + "At this time it is not possible to reply with a file so this will be sent without being a reply.": "В момента не може да се отговаря с файл, така че това ще се изпрати без да бъде отговор.", + "Unable to reply": "Не може да се отговори", + "At this time it is not possible to reply with an emote.": "В момента не може да се отговори с емотикона.", + "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Не може да се зареди събитието, на което е отговорено. Или не съществува или нямате достъп да го видите." } From ff0254d3463ffb6fc4263b05525011a8c42d8382 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 14 May 2018 17:36:57 +0100 Subject: [PATCH 1111/1160] Fix ContextualMenu imports for TagTile and code block copy button --- src/components/views/elements/TagTile.js | 2 +- src/components/views/messages/TextualBody.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/elements/TagTile.js b/src/components/views/elements/TagTile.js index c5fdea0a54..fb3ddee093 100644 --- a/src/components/views/elements/TagTile.js +++ b/src/components/views/elements/TagTile.js @@ -21,7 +21,7 @@ import { MatrixClient } from 'matrix-js-sdk'; import sdk from '../../../index'; import dis from '../../../dispatcher'; import { isOnlyCtrlOrCmdIgnoreShiftKeyEvent } from '../../../Keyboard'; -import ContextualMenu from '../../structures/ContextualMenu'; +import * as ContextualMenu from '../../structures/ContextualMenu'; import FlairStore from '../../../stores/FlairStore'; import GroupStore from '../../../stores/GroupStore'; diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index a4a4b4ebe8..bc2a715d31 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -32,7 +32,7 @@ import SdkConfig from '../../../SdkConfig'; import dis from '../../../dispatcher'; import { _t } from '../../../languageHandler'; import MatrixClientPeg from '../../../MatrixClientPeg'; -import ContextualMenu from '../../structures/ContextualMenu'; +import * as ContextualMenu from '../../structures/ContextualMenu'; import SettingsStore from "../../../settings/SettingsStore"; import PushProcessor from 'matrix-js-sdk/lib/pushprocessor'; import ReplyThread from "../elements/ReplyThread"; From aaffe2a3e1fec8305e890eb9acda599eaabb184b Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 14 May 2018 18:23:14 +0100 Subject: [PATCH 1112/1160] Prepare changelog for v0.12.4-rc.4 --- CHANGELOG.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 89f3741535..54664ac124 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,44 @@ +Changes in [0.12.4-rc.4](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.12.4-rc.4) (2018-05-14) +=============================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.12.4-rc.3...v0.12.4-rc.4) + + * Update from Weblate. + [\#1904](https://github.com/matrix-org/matrix-react-sdk/pull/1904) + * Correctly identify sticker picker widgets + [\#1894](https://github.com/matrix-org/matrix-react-sdk/pull/1894) + * Quick fix for sticker picker position + [\#1903](https://github.com/matrix-org/matrix-react-sdk/pull/1903) + * Remove redundant logging (currently shown on every render when no sti… + [\#1901](https://github.com/matrix-org/matrix-react-sdk/pull/1901) + * Fix stickers briefly being 2x the size + [\#1899](https://github.com/matrix-org/matrix-react-sdk/pull/1899) + * Send required properties when making requests to widgets over postMessage + [\#1891](https://github.com/matrix-org/matrix-react-sdk/pull/1891) + * Fix room widget second load infini spinner + [\#1897](https://github.com/matrix-org/matrix-react-sdk/pull/1897) + * Update widget state when account data changes + [\#1896](https://github.com/matrix-org/matrix-react-sdk/pull/1896) + * Remove margins when in a ReplyThread to stop them taking so much space + [\#1882](https://github.com/matrix-org/matrix-react-sdk/pull/1882) + * Add setting to enable widget screenshots (if widgets declare support) + [\#1892](https://github.com/matrix-org/matrix-react-sdk/pull/1892) + * T3chguy/replies html tag + [\#1889](https://github.com/matrix-org/matrix-react-sdk/pull/1889) + * Instant Sticker Picker + [\#1888](https://github.com/matrix-org/matrix-react-sdk/pull/1888) + * Update widget 'widgetData' key to 'data' to match spec. + [\#1887](https://github.com/matrix-org/matrix-react-sdk/pull/1887) + * Fix 'state_key' field name. + [\#1886](https://github.com/matrix-org/matrix-react-sdk/pull/1886) + * Improve appearance of short-lived app loading spinner + [\#1885](https://github.com/matrix-org/matrix-react-sdk/pull/1885) + * Take feature_sticker_messagse out of labs + [\#1883](https://github.com/matrix-org/matrix-react-sdk/pull/1883) + * Fix issue incorrect positioning with widget loading indicator + [\#1884](https://github.com/matrix-org/matrix-react-sdk/pull/1884) + * Users should always be able to edit their user/non-room widgets + [\#1879](https://github.com/matrix-org/matrix-react-sdk/pull/1879) + Changes in [0.12.4-rc.3](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.12.4-rc.3) (2018-05-11) =============================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.12.4-rc.2...v0.12.4-rc.3) From 7bfc50bf429dbe5c1046209306cc12e09b23a38c Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 14 May 2018 18:23:14 +0100 Subject: [PATCH 1113/1160] v0.12.4-rc.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1125dd3980..77ba18ba04 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.12.4-rc.3", + "version": "0.12.4-rc.4", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From 2956c049d62ab8f4416dd9de090f19db5787425c Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 May 2018 11:41:16 +0100 Subject: [PATCH 1114/1160] Wait for echo from server when adding user widgets As hopefully all explained in comments. Fixes https://github.com/vector-im/riot-web/issues/6727 --- src/ScalarMessaging.js | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index a163bf7bbd..906dc6fb0f 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -286,6 +286,30 @@ function inviteUser(event, roomId, userId) { }); } +/** + * Returns a promise that resolves when a widget with the given + * ID has been added as a user widget (ie. the accountData event + * arrives) or rejects after a timeout + */ +function waitForUserWidget(widgetId) { + return new Promise((resolve, reject) => { + let timerId; + function onAccountData(ev) { + if (ev.getContent()[widgetId] !== undefined) { + MatrixClientPeg.get().removeListener('accountData', onAccountData); + clearTimeout(timerId); + resolve(); + } + } + timerId = setTimeout(() => { + console.log("Timed out waiting for widget ID " + widgetId + " to appear"); + MatrixClientPeg.get().removeListener('accountData', onAccountData); + reject(); + }, 10000); + MatrixClientPeg.get().on('accountData', onAccountData); + }); +} + function setWidget(event, roomId) { const widgetId = event.data.widget_id; const widgetType = event.data.type; @@ -355,7 +379,15 @@ function setWidget(event, roomId) { }; } + // This starts listening for when the echo comes back from the server + // since the widget won't appear added until this happens. If we don't + // wait for this, the action will complete but if the user is fast enough, + // the widget still won't actually be there. + // start listening now otherwise we could race + const widgetAddPromise = waitForUserWidget(widgetId); client.setAccountData('m.widgets', userWidgets).then(() => { + return widgetAddPromise; + }).then(() => { sendResponse(event, { success: true, }); @@ -373,6 +405,7 @@ function setWidget(event, roomId) { // TODO - Room widgets need to be moved to 'm.widget' state events // https://docs.google.com/document/d/1uPF7XWY_dXTKVKV7jZQ2KmsI19wn9-kFRgQ1tFQP7wQ/edit?usp=sharing client.sendStateEvent(roomId, "im.vector.modular.widgets", content, widgetId).done(() => { + // XXX: We should probably wait for the echo of the state event to come back from the server, sendResponse(event, { success: true, }); From 142ce4c2567ae1db25d2105c050ecb4b2eec5863 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 May 2018 11:50:24 +0100 Subject: [PATCH 1115/1160] better comment --- src/ScalarMessaging.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index 906dc6fb0f..5b81e7e7bf 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -406,6 +406,7 @@ function setWidget(event, roomId) { // https://docs.google.com/document/d/1uPF7XWY_dXTKVKV7jZQ2KmsI19wn9-kFRgQ1tFQP7wQ/edit?usp=sharing client.sendStateEvent(roomId, "im.vector.modular.widgets", content, widgetId).done(() => { // XXX: We should probably wait for the echo of the state event to come back from the server, + // as we do with user widgets. sendResponse(event, { success: true, }); From f4d69e26e980e5aa58bfe3baa213d3b32d782171 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 May 2018 12:06:23 +0100 Subject: [PATCH 1116/1160] PR feedback --- src/ScalarMessaging.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index 5b81e7e7bf..a229ecf693 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -293,18 +293,22 @@ function inviteUser(event, roomId, userId) { */ function waitForUserWidget(widgetId) { return new Promise((resolve, reject) => { + if (ev.getContent() && ev.getContent()[widgetId] !== undefined) { + resolve(); + return; + } + let timerId; function onAccountData(ev) { - if (ev.getContent()[widgetId] !== undefined) { + if (ev.getContent() && ev.getContent()[widgetId] !== undefined) { MatrixClientPeg.get().removeListener('accountData', onAccountData); clearTimeout(timerId); resolve(); } } timerId = setTimeout(() => { - console.log("Timed out waiting for widget ID " + widgetId + " to appear"); MatrixClientPeg.get().removeListener('accountData', onAccountData); - reject(); + reject(new Error("Timed out waiting for widget ID " + widgetId + " to appear")); }, 10000); MatrixClientPeg.get().on('accountData', onAccountData); }); @@ -383,10 +387,8 @@ function setWidget(event, roomId) { // since the widget won't appear added until this happens. If we don't // wait for this, the action will complete but if the user is fast enough, // the widget still won't actually be there. - // start listening now otherwise we could race - const widgetAddPromise = waitForUserWidget(widgetId); client.setAccountData('m.widgets', userWidgets).then(() => { - return widgetAddPromise; + return waitForUserWidget(widgetId); }).then(() => { sendResponse(event, { success: true, From 272ba5b004f33c444b2c63a419810c479b5cb5fc Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 15 May 2018 13:15:40 +0100 Subject: [PATCH 1117/1160] Implement opt-in analytics with cookie bar --- src/components/structures/LoggedInView.js | 5 +- src/components/structures/MatrixChat.js | 32 +++++++++- src/components/views/globals/CookieBar.js | 73 +++++++++++++++++++++++ src/i18n/strings/en_EN.json | 5 +- src/settings/Settings.js | 9 ++- 5 files changed, 118 insertions(+), 6 deletions(-) create mode 100644 src/components/views/globals/CookieBar.js diff --git a/src/components/structures/LoggedInView.js b/src/components/structures/LoggedInView.js index d9ac9de693..abb2eb92aa 100644 --- a/src/components/structures/LoggedInView.js +++ b/src/components/structures/LoggedInView.js @@ -266,6 +266,7 @@ const LoggedInView = React.createClass({ const GroupView = sdk.getComponent('structures.GroupView'); const MyGroups = sdk.getComponent('structures.MyGroups'); const MatrixToolbar = sdk.getComponent('globals.MatrixToolbar'); + const CookieBar = sdk.getComponent('globals.CookieBar'); const NewVersionBar = sdk.getComponent('globals.NewVersionBar'); const UpdateCheckBar = sdk.getComponent('globals.UpdateCheckBar'); const PasswordNagBar = sdk.getComponent('globals.PasswordNagBar'); @@ -353,7 +354,9 @@ const LoggedInView = React.createClass({ let topBar; const isGuest = this.props.matrixClient.isGuest(); - if (this.props.hasNewVersion) { + if (this.props.showCookieBar) { + topBar = ; + } else if (this.props.hasNewVersion) { topBar = ; diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 3005bc86ad..051b9ed10b 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -165,6 +165,8 @@ export default React.createClass({ newVersionReleaseNotes: null, checkingForUpdate: null, + showCookieBar: false, + // Parameters used in the registration dance with the IS register_client_secret: null, register_session_id: null, @@ -227,8 +229,6 @@ export default React.createClass({ componentWillMount: function() { SdkConfig.put(this.props.config); - if (!SettingsStore.getValue("analyticsOptOut")) Analytics.enable(); - // Used by _viewRoom before getting state from sync this.firstSyncComplete = false; this.firstSyncPromise = Promise.defer(); @@ -361,6 +361,16 @@ export default React.createClass({ // loadSession as there's logic there to ask the user if they want // to try logging out. }); + + if (SettingsStore.getValue("showCookieBar")) { + this.setState({ + showCookieBar: true, + }); + } + + if (SettingsStore.getValue("analyticsOptIn")) { + Analytics.enable(); + } }, componentWillUnmount: function() { @@ -673,6 +683,23 @@ export default React.createClass({ hideToSRUsers: false, }); break; + case 'accept_cookies': + SettingsStore.setValue("analyticsOptIn", null, SettingLevel.DEVICE, true); + SettingsStore.setValue("showCookieBar", null, SettingLevel.DEVICE, false); + + this.setState({ + showCookieBar: false, + }); + Analytics.enable(); + break; + case 'reject_cookies': + SettingsStore.setValue("analyticsOptIn", null, SettingLevel.DEVICE, false); + SettingsStore.setValue("showCookieBar", null, SettingLevel.DEVICE, false); + + this.setState({ + showCookieBar: false, + }); + break; } }, @@ -1621,6 +1648,7 @@ export default React.createClass({ onRegistered={this.onRegistered} currentRoomId={this.state.currentRoomId} teamToken={this._teamToken} + showCookieBar={this.state.showCookieBar} {...this.props} {...this.state} /> diff --git a/src/components/views/globals/CookieBar.js b/src/components/views/globals/CookieBar.js new file mode 100644 index 0000000000..f1fbbcc83a --- /dev/null +++ b/src/components/views/globals/CookieBar.js @@ -0,0 +1,73 @@ +/* +Copyright 2018 New Vector Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import React from 'react'; +import dis from '../../../dispatcher'; +import { _t } from '../../../languageHandler'; +import sdk from '../../../index'; + +const PrivacyLink = (sub) => + + { sub } + ; + +export default React.createClass({ + onAccept: function() { + dis.dispatch({ + action: 'accept_cookies', + }); + }, + + onReject: function() { + dis.dispatch({ + action: 'reject_cookies', + }); + }, + + render: function() { + const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); + const toolbarClasses = "mx_MatrixToolbar"; + return ( +
    + Warning +
    + { _t( + "Help us improve Riot by sending usage data. " + + "This will use a cookie " + + "(see our cookie and " + + "privacy policies)", + {}, + { + // XXX: We need to link to the page that explains our cookies + 'CookieLink': PrivacyLink, + 'PrivacyLink': PrivacyLink, + }, + ) } +
    + + { _t("Send usage data") } + + + + +
    + ); + }, +}); diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 9b932ef2b6..0126661a07 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -210,7 +210,8 @@ "Mirror local video feed": "Mirror local video feed", "Disable Community Filter Panel": "Disable Community Filter Panel", "Disable Peer-to-Peer for 1:1 calls": "Disable Peer-to-Peer for 1:1 calls", - "Opt out of analytics": "Opt out of analytics", + "Send analytics data": "Send analytics data", + "Show cookie bar": "Show cookie bar", "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 from this device": "Never send encrypted messages to unverified devices in this room from this device", "Enable inline URL previews by default": "Enable inline URL previews by default", @@ -637,6 +638,8 @@ "Something went wrong when trying to get your communities.": "Something went wrong when trying to get your communities.", "Display your community flair in rooms configured to show it.": "Display your community flair in rooms configured to show it.", "You're not currently a member of any communities.": "You're not currently a member of any communities.", + "Help us improve Riot by sending usage data. This will use a cookie (see our cookie and privacy policies)": "Help us improve Riot by sending usage data. This will use a cookie (see our cookie and privacy policies)", + "Send usage data": "Send usage data", "You are not receiving desktop notifications": "You are not receiving desktop notifications", "Enable them now": "Enable them now", "What's New": "What's New", diff --git a/src/settings/Settings.js b/src/settings/Settings.js index 663318f990..8f50885c14 100644 --- a/src/settings/Settings.js +++ b/src/settings/Settings.js @@ -213,11 +213,16 @@ export const SETTINGS = { supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, default: "en", }, - "analyticsOptOut": { + "analyticsOptIn": { supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, - displayName: _td('Opt out of analytics'), + displayName: _td('Send analytics data'), default: false, }, + "showCookieBar": { + supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, + displayName: _td('Show cookie bar'), + default: true, + }, "autocompleteDelay": { supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, default: 200, From d0ec467c34d80b9954af28559a7f9e75f4694d73 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 May 2018 14:13:56 +0100 Subject: [PATCH 1118/1160] Oops, actually get account data event. Also ignore any account data events that aren;t widgets. --- src/ScalarMessaging.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index a229ecf693..796252fc1b 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -293,13 +293,20 @@ function inviteUser(event, roomId, userId) { */ function waitForUserWidget(widgetId) { return new Promise((resolve, reject) => { - if (ev.getContent() && ev.getContent()[widgetId] !== undefined) { + const currentAccountDataEvent = MatrixClientPeg.get().getAccountData('m.widgets'); + if ( + currentAccountDataEvent && + currentAccountDataEvent.getContent() && + currentAccountDataEvent.getContent()[widgetId] !== undefined + ) { resolve(); return; } let timerId; function onAccountData(ev) { + if (ev.getType() != 'm.widgets') return; + if (ev.getContent() && ev.getContent()[widgetId] !== undefined) { MatrixClientPeg.get().removeListener('accountData', onAccountData); clearTimeout(timerId); From e9336eab63daa5ad04cac28b50a3ff52bb7ab5cb Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 May 2018 14:18:02 +0100 Subject: [PATCH 1119/1160] lint --- src/ScalarMessaging.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index 796252fc1b..5940565517 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -290,6 +290,9 @@ function inviteUser(event, roomId, userId) { * Returns a promise that resolves when a widget with the given * ID has been added as a user widget (ie. the accountData event * arrives) or rejects after a timeout + * + * @param {string} widgetId The ID of the widget to wait for + * @returns {Promise} that resolves when the widget is available */ function waitForUserWidget(widgetId) { return new Promise((resolve, reject) => { @@ -303,7 +306,6 @@ function waitForUserWidget(widgetId) { return; } - let timerId; function onAccountData(ev) { if (ev.getType() != 'm.widgets') return; @@ -313,7 +315,7 @@ function waitForUserWidget(widgetId) { resolve(); } } - timerId = setTimeout(() => { + const timerId = setTimeout(() => { MatrixClientPeg.get().removeListener('accountData', onAccountData); reject(new Error("Timed out waiting for widget ID " + widgetId + " to appear")); }, 10000); From 7bfe84f8beec1aecd3a6d465f7a0dfc378e3e7a5 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 May 2018 14:53:49 +0100 Subject: [PATCH 1120/1160] Catch errors adding widget --- src/ScalarMessaging.js | 2 ++ src/i18n/strings/en_EN.json | 6 ++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index 5940565517..bc5e6b7fe1 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -404,6 +404,8 @@ function setWidget(event, roomId) { }); dis.dispatch({ action: "user_widget_updated" }); + }).catch((e) => { + sendError(event, _t('Error adding widget')); }); } else { // Room widget if (!roomId) { diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 9b932ef2b6..e78a06cccd 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -103,6 +103,7 @@ "You need to be logged in.": "You need to be logged in.", "You need to be able to invite users to do that.": "You need to be able to invite users to do that.", "Unable to create widget.": "Unable to create widget.", + "Error adding widget": "Error adding widget", "Missing roomId.": "Missing roomId.", "Failed to send request.": "Failed to send request.", "This room is not recognised.": "This room is not recognised.", @@ -190,7 +191,6 @@ "Message Replies": "Message Replies", "Message Pinning": "Message Pinning", "Tag Panel": "Tag Panel", - "Sticker Messages": "Sticker Messages", "Disable Emoji suggestions while typing": "Disable Emoji suggestions while typing", "Use compact timeline layout": "Use compact timeline layout", "Hide removed messages": "Hide removed messages", @@ -566,8 +566,6 @@ "Download %(text)s": "Download %(text)s", "Invalid file%(extra)s": "Invalid file%(extra)s", "Error decrypting image": "Error decrypting image", - "This image cannot be displayed.": "This image cannot be displayed.", - "Image '%(Body)s' cannot be displayed.": "Image '%(Body)s' cannot be displayed.", "Error decrypting video": "Error decrypting video", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s changed the avatar for %(roomName)s", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s removed the room avatar.", @@ -815,8 +813,8 @@ "Encryption key request": "Encryption key request", "Sign out": "Sign out", "Log out and remove encryption keys?": "Log out and remove encryption keys?", - "Send Logs": "Send Logs", "Clear Storage and Sign Out": "Clear Storage and Sign Out", + "Send Logs": "Send Logs", "Refresh": "Refresh", "Unable to restore session": "Unable to restore session", "We encountered an error trying to restore your previous session.": "We encountered an error trying to restore your previous session.", From 5b781043a5b61ec2307a89d212d79faa3750a46c Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 May 2018 15:02:24 +0100 Subject: [PATCH 1121/1160] just use the one if statement --- src/ScalarMessaging.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index bc5e6b7fe1..ba60af29d1 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -307,9 +307,7 @@ function waitForUserWidget(widgetId) { } function onAccountData(ev) { - if (ev.getType() != 'm.widgets') return; - - if (ev.getContent() && ev.getContent()[widgetId] !== undefined) { + if (ev.getType() === 'm.widgets' && ev.getContent() && ev.getContent()[widgetId] !== undefined) { MatrixClientPeg.get().removeListener('accountData', onAccountData); clearTimeout(timerId); resolve(); From 464e093f40b2fdeb2e2c3f374295a20de9d31071 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 May 2018 15:14:33 +0100 Subject: [PATCH 1122/1160] log exception --- src/ScalarMessaging.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index ba60af29d1..961f7a13d8 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -403,6 +403,7 @@ function setWidget(event, roomId) { dis.dispatch({ action: "user_widget_updated" }); }).catch((e) => { + console.log("Error adding widget", e); sendError(event, _t('Error adding widget')); }); } else { // Room widget From 9d5ba25131648ce0121fb15471241eecbbee9a30 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 May 2018 15:19:28 +0100 Subject: [PATCH 1123/1160] oh, sendError does support sending the error --- src/ScalarMessaging.js | 3 +-- src/i18n/strings/en_EN.json | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index 961f7a13d8..0c10642cd7 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -403,8 +403,7 @@ function setWidget(event, roomId) { dis.dispatch({ action: "user_widget_updated" }); }).catch((e) => { - console.log("Error adding widget", e); - sendError(event, _t('Error adding widget')); + sendError(event, _t('Unable to create widget.'), e); }); } else { // Room widget if (!roomId) { diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index e78a06cccd..957deb35c5 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -103,7 +103,6 @@ "You need to be logged in.": "You need to be logged in.", "You need to be able to invite users to do that.": "You need to be able to invite users to do that.", "Unable to create widget.": "Unable to create widget.", - "Error adding widget": "Error adding widget", "Missing roomId.": "Missing roomId.", "Failed to send request.": "Failed to send request.", "This room is not recognised.": "This room is not recognised.", From 0c22343bb895f118df613896d63e4cfd61f08ef0 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 15 May 2018 15:38:47 +0100 Subject: [PATCH 1124/1160] Remove cookie bar setting from UserSettings --- src/i18n/strings/en_EN.json | 1 - src/settings/Settings.js | 1 - 2 files changed, 2 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 0126661a07..448f5e3a1c 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -211,7 +211,6 @@ "Disable Community Filter Panel": "Disable Community Filter Panel", "Disable Peer-to-Peer for 1:1 calls": "Disable Peer-to-Peer for 1:1 calls", "Send analytics data": "Send analytics data", - "Show cookie bar": "Show cookie bar", "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 from this device": "Never send encrypted messages to unverified devices in this room from this device", "Enable inline URL previews by default": "Enable inline URL previews by default", diff --git a/src/settings/Settings.js b/src/settings/Settings.js index 8f50885c14..b1bc4161fd 100644 --- a/src/settings/Settings.js +++ b/src/settings/Settings.js @@ -220,7 +220,6 @@ export const SETTINGS = { }, "showCookieBar": { supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, - displayName: _td('Show cookie bar'), default: true, }, "autocompleteDelay": { From c191464e972f1298e81ebd46e253381e1eb2d6bd Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 15 May 2018 15:39:12 +0100 Subject: [PATCH 1125/1160] Fix UserSettings for new analyticsOptIn --- src/components/structures/UserSettings.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 35a55284fd..c8ce79905d 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -86,9 +86,9 @@ const SIMPLE_SETTINGS = [ // These settings must be defined in SettingsStore const ANALYTICS_SETTINGS = [ { - id: 'analyticsOptOut', + id: 'analyticsOptIn', fn: function(checked) { - Analytics[checked ? 'disable' : 'enable'](); + checked ? Analytics.enable() : Analytics.disable(); }, }, ]; From b64e10a0951031a144b1521bd3c63e9a3b8faae7 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 15 May 2018 15:54:14 +0100 Subject: [PATCH 1126/1160] Prepare changelog for v0.12.4-rc.5 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54664ac124..36e256f10c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +Changes in [0.12.4-rc.5](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.12.4-rc.5) (2018-05-15) +=============================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.12.4-rc.4...v0.12.4-rc.5) + + * Wait for echo from server when adding user widgets + [\#1905](https://github.com/matrix-org/matrix-react-sdk/pull/1905) + Changes in [0.12.4-rc.4](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.12.4-rc.4) (2018-05-14) =============================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.12.4-rc.3...v0.12.4-rc.4) From db092c81d340176d08504012a7cb97ed19874beb Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 15 May 2018 15:54:15 +0100 Subject: [PATCH 1127/1160] v0.12.4-rc.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 77ba18ba04..96c7e94ad1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.12.4-rc.4", + "version": "0.12.4-rc.5", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From bb5ae741bca14dd42064790a6930b470ceed655d Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 May 2018 17:12:59 +0100 Subject: [PATCH 1128/1160] Wait for deletion of widgets as well addition We were previously waiting for them to appear which is silly if we were deleting them. --- src/ScalarMessaging.js | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index 0c10642cd7..14d363894e 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -292,22 +292,30 @@ function inviteUser(event, roomId, userId) { * arrives) or rejects after a timeout * * @param {string} widgetId The ID of the widget to wait for + * @param {boolean} add True to wait for the widget to be added, + * false to wait for it to be deleted. * @returns {Promise} that resolves when the widget is available */ -function waitForUserWidget(widgetId) { +function waitForUserWidget(widgetId, add) { return new Promise((resolve, reject) => { const currentAccountDataEvent = MatrixClientPeg.get().getAccountData('m.widgets'); - if ( - currentAccountDataEvent && - currentAccountDataEvent.getContent() && - currentAccountDataEvent.getContent()[widgetId] !== undefined - ) { + + function satisfiesCondition(ev) { + if (!ev || !currentAccountDataEvent.getContent()) return false; + if (add) { + return ev.getContent()[widgetId] !== undefined; + } else { + return ev.getContent()[widgetId] === undefined; + } + } + + if (satisfiesCondition(currentAccountDataEvent)) { resolve(); return; } function onAccountData(ev) { - if (ev.getType() === 'm.widgets' && ev.getContent() && ev.getContent()[widgetId] !== undefined) { + if (satisfiesCondition(currentAccountDataEvent)) { MatrixClientPeg.get().removeListener('accountData', onAccountData); clearTimeout(timerId); resolve(); @@ -395,7 +403,7 @@ function setWidget(event, roomId) { // wait for this, the action will complete but if the user is fast enough, // the widget still won't actually be there. client.setAccountData('m.widgets', userWidgets).then(() => { - return waitForUserWidget(widgetId); + return waitForUserWidget(widgetId, widgetUrl !== null); }).then(() => { sendResponse(event, { success: true, From e4a221e42ded1641fdc1ef4f067fc17b3555f25a Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 May 2018 17:28:55 +0100 Subject: [PATCH 1129/1160] More helpful function name --- src/ScalarMessaging.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index 14d363894e..01ee140eb3 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -300,7 +300,9 @@ function waitForUserWidget(widgetId, add) { return new Promise((resolve, reject) => { const currentAccountDataEvent = MatrixClientPeg.get().getAccountData('m.widgets'); - function satisfiesCondition(ev) { + // Tests an account data event, returning true if it's in the state + // we're waiting for it to be in + function eventInIntendedState(ev) { if (!ev || !currentAccountDataEvent.getContent()) return false; if (add) { return ev.getContent()[widgetId] !== undefined; From fadf264a1bb763c4ce65be873a8e9d0b204e07b5 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 May 2018 17:34:02 +0100 Subject: [PATCH 1130/1160] Rename uses of function too --- src/ScalarMessaging.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index 01ee140eb3..9457e6ccfb 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -311,13 +311,13 @@ function waitForUserWidget(widgetId, add) { } } - if (satisfiesCondition(currentAccountDataEvent)) { + if (eventInIntendedState(currentAccountDataEvent)) { resolve(); return; } function onAccountData(ev) { - if (satisfiesCondition(currentAccountDataEvent)) { + if (eventInIntendedState(currentAccountDataEvent)) { MatrixClientPeg.get().removeListener('accountData', onAccountData); clearTimeout(timerId); resolve(); From 1a3777ad0c4b34c3c31d49222231841ed695578d Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 May 2018 18:03:40 +0100 Subject: [PATCH 1131/1160] Prepare changelog for v0.12.4-rc.6 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 36e256f10c..225755207a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +Changes in [0.12.4-rc.6](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.12.4-rc.6) (2018-05-15) +=============================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.12.4-rc.5...v0.12.4-rc.6) + + * Wait for deletion of widgets as well addition + [\#1907](https://github.com/matrix-org/matrix-react-sdk/pull/1907) + Changes in [0.12.4-rc.5](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.12.4-rc.5) (2018-05-15) =============================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.12.4-rc.4...v0.12.4-rc.5) From a0b6bd183c35704908476105338990d7f6eabc91 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 May 2018 18:03:40 +0100 Subject: [PATCH 1132/1160] v0.12.4-rc.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 96c7e94ad1..671b0cf92c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.12.4-rc.5", + "version": "0.12.4-rc.6", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From e98b31958be34769f17c7309692b186ff82cbbe9 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 16 May 2018 10:41:18 +0100 Subject: [PATCH 1133/1160] Allow arbitrary hrefs for cookie/privacy links --- src/components/views/globals/CookieBar.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/views/globals/CookieBar.js b/src/components/views/globals/CookieBar.js index f1fbbcc83a..7625518252 100644 --- a/src/components/views/globals/CookieBar.js +++ b/src/components/views/globals/CookieBar.js @@ -19,11 +19,11 @@ import dis from '../../../dispatcher'; import { _t } from '../../../languageHandler'; import sdk from '../../../index'; -const PrivacyLink = (sub) => +const makeLink = (href) => (sub) => { sub } ; @@ -56,8 +56,8 @@ export default React.createClass({ {}, { // XXX: We need to link to the page that explains our cookies - 'CookieLink': PrivacyLink, - 'PrivacyLink': PrivacyLink, + 'CookieLink': makeLink("https://riot.im/privacy"), + 'PrivacyLink': makeLink("https://riot.im/privacy"), }, ) }
    From 7bd9863e6a2784916a3ede759256dff3332c62a5 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 16 May 2018 11:49:05 +0100 Subject: [PATCH 1134/1160] Prepare changelog for v0.12.4 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 225755207a..a20b902a6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +Changes in [0.12.4](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.12.4) (2018-05-16) +===================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.12.4-rc.6...v0.12.4) + + * No changes from rc.5 + Changes in [0.12.4-rc.6](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.12.4-rc.6) (2018-05-15) =============================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.12.4-rc.5...v0.12.4-rc.6) From bf0ec249b686ac89d4344fd654ffd9bc5cfbef62 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 16 May 2018 11:49:06 +0100 Subject: [PATCH 1135/1160] v0.12.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 671b0cf92c..60f65f4c39 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.12.4-rc.6", + "version": "0.12.4", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From ac1cd384e75c1b5c67507e519dca1f6e68592d5e Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 15 May 2018 13:15:40 +0100 Subject: [PATCH 1136/1160] Implement opt-in analytics with cookie bar --- src/components/structures/LoggedInView.js | 5 +- src/components/structures/MatrixChat.js | 32 +++++++++- src/components/views/globals/CookieBar.js | 73 +++++++++++++++++++++++ src/i18n/strings/en_EN.json | 5 +- src/settings/Settings.js | 9 ++- 5 files changed, 118 insertions(+), 6 deletions(-) create mode 100644 src/components/views/globals/CookieBar.js diff --git a/src/components/structures/LoggedInView.js b/src/components/structures/LoggedInView.js index d9ac9de693..abb2eb92aa 100644 --- a/src/components/structures/LoggedInView.js +++ b/src/components/structures/LoggedInView.js @@ -266,6 +266,7 @@ const LoggedInView = React.createClass({ const GroupView = sdk.getComponent('structures.GroupView'); const MyGroups = sdk.getComponent('structures.MyGroups'); const MatrixToolbar = sdk.getComponent('globals.MatrixToolbar'); + const CookieBar = sdk.getComponent('globals.CookieBar'); const NewVersionBar = sdk.getComponent('globals.NewVersionBar'); const UpdateCheckBar = sdk.getComponent('globals.UpdateCheckBar'); const PasswordNagBar = sdk.getComponent('globals.PasswordNagBar'); @@ -353,7 +354,9 @@ const LoggedInView = React.createClass({ let topBar; const isGuest = this.props.matrixClient.isGuest(); - if (this.props.hasNewVersion) { + if (this.props.showCookieBar) { + topBar = ; + } else if (this.props.hasNewVersion) { topBar = ; diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 3005bc86ad..051b9ed10b 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -165,6 +165,8 @@ export default React.createClass({ newVersionReleaseNotes: null, checkingForUpdate: null, + showCookieBar: false, + // Parameters used in the registration dance with the IS register_client_secret: null, register_session_id: null, @@ -227,8 +229,6 @@ export default React.createClass({ componentWillMount: function() { SdkConfig.put(this.props.config); - if (!SettingsStore.getValue("analyticsOptOut")) Analytics.enable(); - // Used by _viewRoom before getting state from sync this.firstSyncComplete = false; this.firstSyncPromise = Promise.defer(); @@ -361,6 +361,16 @@ export default React.createClass({ // loadSession as there's logic there to ask the user if they want // to try logging out. }); + + if (SettingsStore.getValue("showCookieBar")) { + this.setState({ + showCookieBar: true, + }); + } + + if (SettingsStore.getValue("analyticsOptIn")) { + Analytics.enable(); + } }, componentWillUnmount: function() { @@ -673,6 +683,23 @@ export default React.createClass({ hideToSRUsers: false, }); break; + case 'accept_cookies': + SettingsStore.setValue("analyticsOptIn", null, SettingLevel.DEVICE, true); + SettingsStore.setValue("showCookieBar", null, SettingLevel.DEVICE, false); + + this.setState({ + showCookieBar: false, + }); + Analytics.enable(); + break; + case 'reject_cookies': + SettingsStore.setValue("analyticsOptIn", null, SettingLevel.DEVICE, false); + SettingsStore.setValue("showCookieBar", null, SettingLevel.DEVICE, false); + + this.setState({ + showCookieBar: false, + }); + break; } }, @@ -1621,6 +1648,7 @@ export default React.createClass({ onRegistered={this.onRegistered} currentRoomId={this.state.currentRoomId} teamToken={this._teamToken} + showCookieBar={this.state.showCookieBar} {...this.props} {...this.state} /> diff --git a/src/components/views/globals/CookieBar.js b/src/components/views/globals/CookieBar.js new file mode 100644 index 0000000000..f1fbbcc83a --- /dev/null +++ b/src/components/views/globals/CookieBar.js @@ -0,0 +1,73 @@ +/* +Copyright 2018 New Vector Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import React from 'react'; +import dis from '../../../dispatcher'; +import { _t } from '../../../languageHandler'; +import sdk from '../../../index'; + +const PrivacyLink = (sub) => + + { sub } + ; + +export default React.createClass({ + onAccept: function() { + dis.dispatch({ + action: 'accept_cookies', + }); + }, + + onReject: function() { + dis.dispatch({ + action: 'reject_cookies', + }); + }, + + render: function() { + const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); + const toolbarClasses = "mx_MatrixToolbar"; + return ( +
    + Warning +
    + { _t( + "Help us improve Riot by sending usage data. " + + "This will use a cookie " + + "(see our cookie and " + + "privacy policies)", + {}, + { + // XXX: We need to link to the page that explains our cookies + 'CookieLink': PrivacyLink, + 'PrivacyLink': PrivacyLink, + }, + ) } +
    + + { _t("Send usage data") } + + + + +
    + ); + }, +}); diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 957deb35c5..8f7d1c36eb 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -209,7 +209,8 @@ "Mirror local video feed": "Mirror local video feed", "Disable Community Filter Panel": "Disable Community Filter Panel", "Disable Peer-to-Peer for 1:1 calls": "Disable Peer-to-Peer for 1:1 calls", - "Opt out of analytics": "Opt out of analytics", + "Send analytics data": "Send analytics data", + "Show cookie bar": "Show cookie bar", "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 from this device": "Never send encrypted messages to unverified devices in this room from this device", "Enable inline URL previews by default": "Enable inline URL previews by default", @@ -634,6 +635,8 @@ "Something went wrong when trying to get your communities.": "Something went wrong when trying to get your communities.", "Display your community flair in rooms configured to show it.": "Display your community flair in rooms configured to show it.", "You're not currently a member of any communities.": "You're not currently a member of any communities.", + "Help us improve Riot by sending usage data. This will use a cookie (see our cookie and privacy policies)": "Help us improve Riot by sending usage data. This will use a cookie (see our cookie and privacy policies)", + "Send usage data": "Send usage data", "You are not receiving desktop notifications": "You are not receiving desktop notifications", "Enable them now": "Enable them now", "What's New": "What's New", diff --git a/src/settings/Settings.js b/src/settings/Settings.js index 663318f990..8f50885c14 100644 --- a/src/settings/Settings.js +++ b/src/settings/Settings.js @@ -213,11 +213,16 @@ export const SETTINGS = { supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, default: "en", }, - "analyticsOptOut": { + "analyticsOptIn": { supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, - displayName: _td('Opt out of analytics'), + displayName: _td('Send analytics data'), default: false, }, + "showCookieBar": { + supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, + displayName: _td('Show cookie bar'), + default: true, + }, "autocompleteDelay": { supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, default: 200, From aa4bbbc3db3b8b505f1fa78f4b718ad7662e6f10 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 15 May 2018 15:38:47 +0100 Subject: [PATCH 1137/1160] Remove cookie bar setting from UserSettings --- src/i18n/strings/en_EN.json | 1 - src/settings/Settings.js | 1 - 2 files changed, 2 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 8f7d1c36eb..70eccca6f1 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -210,7 +210,6 @@ "Disable Community Filter Panel": "Disable Community Filter Panel", "Disable Peer-to-Peer for 1:1 calls": "Disable Peer-to-Peer for 1:1 calls", "Send analytics data": "Send analytics data", - "Show cookie bar": "Show cookie bar", "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 from this device": "Never send encrypted messages to unverified devices in this room from this device", "Enable inline URL previews by default": "Enable inline URL previews by default", diff --git a/src/settings/Settings.js b/src/settings/Settings.js index 8f50885c14..b1bc4161fd 100644 --- a/src/settings/Settings.js +++ b/src/settings/Settings.js @@ -220,7 +220,6 @@ export const SETTINGS = { }, "showCookieBar": { supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, - displayName: _td('Show cookie bar'), default: true, }, "autocompleteDelay": { From d01e7388393b70e76203964500dec98863056264 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 15 May 2018 15:39:12 +0100 Subject: [PATCH 1138/1160] Fix UserSettings for new analyticsOptIn --- src/components/structures/UserSettings.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 35a55284fd..c8ce79905d 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -86,9 +86,9 @@ const SIMPLE_SETTINGS = [ // These settings must be defined in SettingsStore const ANALYTICS_SETTINGS = [ { - id: 'analyticsOptOut', + id: 'analyticsOptIn', fn: function(checked) { - Analytics[checked ? 'disable' : 'enable'](); + checked ? Analytics.enable() : Analytics.disable(); }, }, ]; From 4e6594d64b58dcd1bc9b0303e0fcef0a2348d057 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 16 May 2018 10:41:18 +0100 Subject: [PATCH 1139/1160] Allow arbitrary hrefs for cookie/privacy links --- src/components/views/globals/CookieBar.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/views/globals/CookieBar.js b/src/components/views/globals/CookieBar.js index f1fbbcc83a..7625518252 100644 --- a/src/components/views/globals/CookieBar.js +++ b/src/components/views/globals/CookieBar.js @@ -19,11 +19,11 @@ import dis from '../../../dispatcher'; import { _t } from '../../../languageHandler'; import sdk from '../../../index'; -const PrivacyLink = (sub) => +const makeLink = (href) => (sub) => { sub } ; @@ -56,8 +56,8 @@ export default React.createClass({ {}, { // XXX: We need to link to the page that explains our cookies - 'CookieLink': PrivacyLink, - 'PrivacyLink': PrivacyLink, + 'CookieLink': makeLink("https://riot.im/privacy"), + 'PrivacyLink': makeLink("https://riot.im/privacy"), }, ) }
    From d15051a635633f95a6e058e1c8c565448ae4fa32 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 16 May 2018 15:49:23 +0100 Subject: [PATCH 1140/1160] Add policyLink configuration to piwik Also: - Make CookieBar ES6 class - Alter phrasing on CookieBar - Conditionaly display longer "...(See our ++cookie and privacy policies++)." if policy link is configured. --- src/components/structures/LoggedInView.js | 3 +- src/components/views/globals/CookieBar.js | 55 ++++++++++++----------- src/i18n/strings/en_EN.json | 5 ++- 3 files changed, 35 insertions(+), 28 deletions(-) diff --git a/src/components/structures/LoggedInView.js b/src/components/structures/LoggedInView.js index abb2eb92aa..c1d30391ab 100644 --- a/src/components/structures/LoggedInView.js +++ b/src/components/structures/LoggedInView.js @@ -355,7 +355,8 @@ const LoggedInView = React.createClass({ let topBar; const isGuest = this.props.matrixClient.isGuest(); if (this.props.showCookieBar) { - topBar = ; + const policyUrl = this.props.config.piwik ? (this.props.config.piwik.policyUrl || null) : null; + topBar = ; } else if (this.props.hasNewVersion) { topBar = (sub) => - - { sub } - ; +export default class CookieBar extends React.Component { + static propTypes = { + policyUrl: PropTypes.string, + } -export default React.createClass({ - onAccept: function() { + constructor() { + super(); + } + + onAccept() { dis.dispatch({ action: 'accept_cookies', }); - }, + } - onReject: function() { + onReject() { dis.dispatch({ action: 'reject_cookies', }); - }, + } - render: function() { + render() { const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); const toolbarClasses = "mx_MatrixToolbar"; return (
    Warning
    - { _t( - "Help us improve Riot by sending usage data. " + - "This will use a cookie " + - "(see our cookie and " + - "privacy policies)", + { this.props.policyUrl ? _t( + "Help improve Riot by sending usage data? " + + "This will use a cookie. " + + "(See our cookie and privacy policies).", {}, { // XXX: We need to link to the page that explains our cookies - 'CookieLink': makeLink("https://riot.im/privacy"), - 'PrivacyLink': makeLink("https://riot.im/privacy"), + 'PolicyLink': (sub) => + { sub } + + , }, - ) } + ) : _t("Help improve Riot by sending usage data? This will use a cookie.") }
    - { _t("Send usage data") } + { _t("Yes please") }
    ); - }, -}); + } +} diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 70eccca6f1..239b45c32e 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -634,8 +634,9 @@ "Something went wrong when trying to get your communities.": "Something went wrong when trying to get your communities.", "Display your community flair in rooms configured to show it.": "Display your community flair in rooms configured to show it.", "You're not currently a member of any communities.": "You're not currently a member of any communities.", - "Help us improve Riot by sending usage data. This will use a cookie (see our cookie and privacy policies)": "Help us improve Riot by sending usage data. This will use a cookie (see our cookie and privacy policies)", - "Send usage data": "Send usage data", + "Help improve Riot by sending usage data? This will use a cookie. (See our cookie and privacy policies).": "Help improve Riot by sending usage data? This will use a cookie. (See our cookie and privacy policies).", + "Help improve Riot by sending usage data? This will use a cookie.": "Help improve Riot by sending usage data? This will use a cookie.", + "Yes please": "Yes please", "You are not receiving desktop notifications": "You are not receiving desktop notifications", "Enable them now": "Enable them now", "What's New": "What's New", From 0bda607bb2fb22eb622cb2d5db253f0a1dd6cbad Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 16 May 2018 15:53:43 +0100 Subject: [PATCH 1141/1160] Only show cookie bar if analytics configured --- src/components/structures/LoggedInView.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/structures/LoggedInView.js b/src/components/structures/LoggedInView.js index c1d30391ab..2dd5a75c47 100644 --- a/src/components/structures/LoggedInView.js +++ b/src/components/structures/LoggedInView.js @@ -354,8 +354,10 @@ const LoggedInView = React.createClass({ let topBar; const isGuest = this.props.matrixClient.isGuest(); - if (this.props.showCookieBar) { - const policyUrl = this.props.config.piwik ? (this.props.config.piwik.policyUrl || null) : null; + if (this.props.showCookieBar && + this.props.config.piwik + ) { + const policyUrl = this.props.config.piwik.policyUrl || null; topBar = ; } else if (this.props.hasNewVersion) { topBar = Date: Wed, 16 May 2018 18:57:53 +0100 Subject: [PATCH 1142/1160] Specify valid address types to "Start a chat" dialog fixes https://github.com/vector-im/riot-web/issues/5459 --- src/RoomInvite.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/RoomInvite.js b/src/RoomInvite.js index 31541148d9..0bcc08eb06 100644 --- a/src/RoomInvite.js +++ b/src/RoomInvite.js @@ -57,6 +57,7 @@ export function showStartChatInviteDialog() { title: _t('Start a chat'), description: _t("Who would you like to communicate with?"), placeholder: _t("Email, name or matrix ID"), + validAddressTypes: ['mx-user-id', 'email'], button: _t("Start Chat"), onFinished: _onStartChatFinished, }); From e53497421e0d0a1974205821619676244ef28802 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 17 May 2018 16:47:17 +0100 Subject: [PATCH 1143/1160] Fix image size jumping regression Fixes https://github.com/vector-im/riot-web/issues/6654 --- src/components/views/messages/MImageBody.js | 3 ++- src/components/views/messages/MStickerBody.js | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index 6cc492acf8..f59b3a9e2c 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -1,5 +1,6 @@ /* Copyright 2015, 2016 OpenMarket Ltd +Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -140,7 +141,6 @@ export default class extends React.Component { } onImageLoad() { - this.fixupHeight(); this.props.onWidgetLoad(); } @@ -208,6 +208,7 @@ export default class extends React.Component { }).done(); } this._afterComponentDidMount(); + this.fixupHeight(); } // To be overridden by subclasses (e.g. MStickerBody) for further diff --git a/src/components/views/messages/MStickerBody.js b/src/components/views/messages/MStickerBody.js index 3a412fc2e2..aaad5ba75e 100644 --- a/src/components/views/messages/MStickerBody.js +++ b/src/components/views/messages/MStickerBody.js @@ -40,7 +40,6 @@ export default class MStickerBody extends MImageBody { } _onImageLoad() { - this.fixupHeight(); this.setState({ placeholderClasses: 'mx_MStickerBody_placeholder_invisible', }); From a7006307bf3631824cd484d3b51cec6d8124ed9c Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 17 May 2018 16:50:16 +0100 Subject: [PATCH 1144/1160] Call afterComponentDidMount() after componentDidMount --- src/components/views/messages/MImageBody.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index f59b3a9e2c..8045d43104 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -207,8 +207,8 @@ export default class extends React.Component { }); }).done(); } - this._afterComponentDidMount(); this.fixupHeight(); + this._afterComponentDidMount(); } // To be overridden by subclasses (e.g. MStickerBody) for further From 43dbf306b057f6415a3ab7bebcebdcbfd16e7ec0 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 17 May 2018 17:04:38 +0100 Subject: [PATCH 1145/1160] Prepare changelog for v0.12.5 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a20b902a6e..b161a9d908 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +Changes in [0.12.5](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.12.5) (2018-05-17) +===================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.12.4...v0.12.5) + + * Fix image size jumping regression + [\#1909](https://github.com/matrix-org/matrix-react-sdk/pull/1909) + Changes in [0.12.4](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.12.4) (2018-05-16) ===================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.12.4-rc.6...v0.12.4) From fa7f6c2c4cd1c938e4365bd2380264b1245cc44f Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 17 May 2018 17:04:39 +0100 Subject: [PATCH 1146/1160] v0.12.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 60f65f4c39..6c34979c43 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.12.4", + "version": "0.12.5", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From 4a9f4ba5eb889be78bba574ef8c3ea6269ef1775 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Sch=C3=BCrmann?= Date: Thu, 17 May 2018 20:12:51 +0200 Subject: [PATCH 1147/1160] Fix vector-im/riot-web#6523 Emoji rendering destroys paragraphs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This regression was probably introduced in 4f4441fb07dcdfb831e4b54b9f8d7e611c172f29 and is caused by the fact that the variable `isHtml` conflates two different meanings: - The event contains an HTML message - The event message is displayed using HTML This is an important difference. Plain text messages that contain emojies are rendered with an HTML string and thus have to be sanitized etc. But they must not use the MarkDown CSS styles for HTML messages. The MarkDown CSS styles include `whitespace: normal` because HTML events use `
    `-tags for line breaks. Plain text messages with emojies obviously don't use `
    `-tags, so these styles must not be applied. Signed-off-by: Jonas Schürmann --- src/HtmlUtils.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index 58572cf144..7ca404be31 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -413,12 +413,13 @@ class TextHighlighter extends BaseHighlighter { * opts.stripReplyFallback: optional argument specifying the event is a reply and so fallback needs removing */ export function bodyToHtml(content, highlights, opts={}) { - let isHtml = content.format === "org.matrix.custom.html" && content.formatted_body; + const isHtmlMessage = content.format === "org.matrix.custom.html" && content.formatted_body; let bodyHasEmoji = false; let strippedBody; let safeBody; + let isDisplayedWithHtml; // XXX: We sanitize the HTML whilst also highlighting its text nodes, to avoid accidentally trying // to highlight HTML tags themselves. However, this does mean that we don't highlight textnodes which // are interrupted by HTML tags (not that we did before) - e.g. foobar won't get highlighted @@ -439,17 +440,18 @@ export function bodyToHtml(content, highlights, opts={}) { if (opts.stripReplyFallback && formattedBody) formattedBody = ReplyThread.stripHTMLReply(formattedBody); strippedBody = opts.stripReplyFallback ? ReplyThread.stripPlainReply(content.body) : content.body; - bodyHasEmoji = containsEmoji(isHtml ? formattedBody : content.body); + bodyHasEmoji = containsEmoji(isHtmlMessage ? formattedBody : content.body); // Only generate safeBody if the message was sent as org.matrix.custom.html - if (isHtml) { + if (isHtmlMessage) { + isDisplayedWithHtml = true; safeBody = sanitizeHtml(formattedBody, sanitizeHtmlParams); } else { // ... or if there are emoji, which we insert as HTML alongside the // escaped plaintext body. if (bodyHasEmoji) { - isHtml = true; + isDisplayedWithHtml = true; safeBody = sanitizeHtml(escape(strippedBody), sanitizeHtmlParams); } } @@ -475,10 +477,10 @@ export function bodyToHtml(content, highlights, opts={}) { const className = classNames({ 'mx_EventTile_body': true, 'mx_EventTile_bigEmoji': emojiBody, - 'markdown-body': isHtml, + 'markdown-body': isHtmlMessage, }); - return isHtml ? + return isDisplayedWithHtml ? : { strippedBody }; } From ae10491f95c7411a3a74c5271df5c1a066a71f8e Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 22 May 2018 09:28:41 +0100 Subject: [PATCH 1148/1160] Space between sentences in 'leave room' warning --- src/components/structures/MatrixChat.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 051b9ed10b..91d5ee8970 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -957,6 +957,7 @@ export default React.createClass({ if (rule !== "public") { warnings.push(( + {' '/* Whitespace, otherwise the sentences get smashed together */ } { _t("This room is not public. You will not be able to rejoin without an invite.") } )); From 31dcd85c08c3f625b4950a353909c80347104114 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 22 May 2018 15:45:58 +0100 Subject: [PATCH 1149/1160] Add customisable cancel button to QuestionDialog --- src/components/views/dialogs/QuestionDialog.js | 1 + src/components/views/elements/DialogButtons.js | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/views/dialogs/QuestionDialog.js b/src/components/views/dialogs/QuestionDialog.js index 7e11677310..21d3a54bc2 100644 --- a/src/components/views/dialogs/QuestionDialog.js +++ b/src/components/views/dialogs/QuestionDialog.js @@ -67,6 +67,7 @@ export default React.createClass({ { this.props.description }
    - { _t("Cancel") } + { this.props.cancelButton || _t("Cancel") } ; } return ( From e602213806980f775e941a1b458fceb7212e962b Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 22 May 2018 15:47:05 +0100 Subject: [PATCH 1150/1160] Add concept of priority modal to modal manager --- src/Modal.js | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/src/Modal.js b/src/Modal.js index 2565d5c73b..06a96824a7 100644 --- a/src/Modal.js +++ b/src/Modal.js @@ -81,7 +81,11 @@ class ModalManager { constructor() { this._counter = 0; - /** list of the modals we have stacked up, with the most recent at [0] */ + // The modal to prioritise over all others. If this is set, only show + // this modal. Remove all other modals from the stack when this modal + // is closed. + this._priorityModal = null; + // A list of the modals we have stacked up, with the most recent at [0] this._modals = [ /* { elem: React component for this dialog @@ -105,18 +109,18 @@ class ModalManager { return container; } - createTrackedDialog(analyticsAction, analyticsInfo, Element, props, className) { + createTrackedDialog(analyticsAction, analyticsInfo, ...rest) { Analytics.trackEvent('Modal', analyticsAction, analyticsInfo); - return this.createDialog(Element, props, className); + return this.createDialog(...rest); } - createDialog(Element, props, className) { - return this.createDialogAsync((cb) => {cb(Element);}, props, className); + createDialog(Element, ...rest) { + return this.createDialogAsync((cb) => {cb(Element);}, ...rest); } - createTrackedDialogAsync(analyticsAction, analyticsInfo, loader, props, className) { + createTrackedDialogAsync(analyticsAction, analyticsInfo, ...rest) { Analytics.trackEvent('Modal', analyticsAction, analyticsInfo); - return this.createDialogAsync(loader, props, className); + return this.createDialogAsync(...rest); } /** @@ -137,8 +141,13 @@ class ModalManager { * component. (We will also pass an 'onFinished' property.) * * @param {String} className CSS class to apply to the modal wrapper + * + * @param {boolean} isPriorityModal if true, this modal will be displayed regardless + * of other modals that are currently in the stack. + * Also, when closed, all modals will be removed + * from the stack. */ - createDialogAsync(loader, props, className) { + createDialogAsync(loader, props, className, isPriorityModal) { const self = this; const modal = {}; @@ -151,6 +160,14 @@ class ModalManager { if (i >= 0) { self._modals.splice(i, 1); } + + if (self._priorityModal === modal) { + self._priorityModal = null; + + // XXX: This is destructive + self._modals = []; + } + self._reRender(); }; @@ -167,7 +184,12 @@ class ModalManager { modal.onFinished = props ? props.onFinished : null; modal.className = className; - this._modals.unshift(modal); + if (isPriorityModal) { + // XXX: This is destructive + this._priorityModal = modal; + } else { + this._modals.unshift(modal); + } this._reRender(); return {close: closeDialog}; @@ -188,7 +210,7 @@ class ModalManager { } _reRender() { - if (this._modals.length == 0) { + if (this._modals.length == 0 && !this._priorityModal) { // If there is no modal to render, make all of Riot available // to screen reader users again dis.dispatch({ @@ -205,7 +227,7 @@ class ModalManager { action: 'aria_hide_main_app', }); - const modal = this._modals[0]; + const modal = this._priorityModal ? this._priorityModal : this._modals[0]; const dialog = (
    From 658e88c30f5521c087f63be5b1e132522e92fdab Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 22 May 2018 15:47:31 +0100 Subject: [PATCH 1151/1160] Implement consent/terms and conditions dialog for /_matrix/consent flow --- src/components/structures/MatrixChat.js | 22 ++++++++++++++++++++++ src/i18n/strings/en_EN.json | 3 +++ 2 files changed, 25 insertions(+) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 91d5ee8970..96e721f7ca 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -1232,6 +1232,28 @@ export default React.createClass({ action: 'logout', }); }); + cli.on('no_consent', function(message, consentUri) { + const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); + Modal.createTrackedDialog('No Consent Dialog', '', QuestionDialog, { + title: _t('Terms and Conditions'), + description:
    +

    { _t( + 'To continue using the %(homeserverDomain)s homeserver ' + + 'you must review and agree to our terms and conditions.', + { homeserverDomain: cli.getDomain() }, + ) } +

    +
    , + button: _t('Review terms and conditions'), + cancelButton: _t('Dismiss'), + onFinished: (confirmed) => { + if (confirmed) { + window.open(consentUri, '_blank'); + } + }, + }, null, true); + }); + cli.on("accountData", function(ev) { if (ev.getType() === 'im.vector.web.settings') { if (ev.getContent() && ev.getContent().theme) { diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 239b45c32e..f3e3d6b097 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -943,6 +943,9 @@ "Failed to leave room": "Failed to leave room", "Signed Out": "Signed Out", "For security, this session has been signed out. Please sign in again.": "For security, this session has been signed out. Please sign in again.", + "Terms and Conditions": "Terms and Conditions", + "To continue using the %(homeserverDomain)s homeserver you must review and agree to our terms and conditions.": "To continue using the %(homeserverDomain)s homeserver you must review and agree to our terms and conditions.", + "Review terms and conditions": "Review terms and conditions", "Old cryptography data detected": "Old cryptography data detected", "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.", "Logout": "Logout", From ef686a966d5c57d74b55c3a1a13a0e9747d56532 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 23 May 2018 10:46:32 +0100 Subject: [PATCH 1152/1160] Add cookie warning to widget warning (AppPermission) --- src/components/views/elements/AppPermission.js | 5 +++++ src/i18n/strings/en_EN.json | 1 + 2 files changed, 6 insertions(+) diff --git a/src/components/views/elements/AppPermission.js b/src/components/views/elements/AppPermission.js index ef08c8355b..c45006be3a 100644 --- a/src/components/views/elements/AppPermission.js +++ b/src/components/views/elements/AppPermission.js @@ -52,6 +52,10 @@ export default class AppPermission extends React.Component { e2eWarningText = { _t('NOTE: Apps are not end-to-end encrypted') }; } + const cookieWarning = + + { _t('Warning: This widget might use cookies.') } + ; return (
    @@ -60,6 +64,7 @@ export default class AppPermission extends React.Component {
    { _t('Do you want to load widget from URL:') } { this.state.curlBase } { e2eWarningText } + { cookieWarning }
    Date: Wed, 23 May 2018 13:35:42 +0100 Subject: [PATCH 1153/1160] Refactor onOk to async function --- .../views/dialogs/DeactivateAccountDialog.js | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/components/views/dialogs/DeactivateAccountDialog.js b/src/components/views/dialogs/DeactivateAccountDialog.js index 87228b4733..f41f37e075 100644 --- a/src/components/views/dialogs/DeactivateAccountDialog.js +++ b/src/components/views/dialogs/DeactivateAccountDialog.js @@ -47,19 +47,17 @@ export default class DeactivateAccountDialog extends React.Component { }); } - _onOk() { + async _onOk() { // This assumes that the HS requires password UI auth // for this endpoint. In reality it could be any UI auth. this.setState({busy: true}); - MatrixClientPeg.get().deactivateAccount({ - type: 'm.login.password', - user: MatrixClientPeg.get().credentials.userId, - password: this._passwordField.value, - }).done(() => { - Analytics.trackEvent('Account', 'Deactivate Account'); - Lifecycle.onLoggedOut(); - this.props.onFinished(false); - }, (err) => { + try { + await MatrixClientPeg.get().deactivateAccount({ + type: 'm.login.password', + user: MatrixClientPeg.get().credentials.userId, + password: this._passwordField.value, + }); + } catch (err) { let errStr = _t('Unknown error'); // https://matrix.org/jira/browse/SYN-744 if (err.httpStatus == 401 || err.httpStatus == 403) { @@ -70,7 +68,11 @@ export default class DeactivateAccountDialog extends React.Component { busy: false, errStr: errStr, }); - }); + return; + } + Analytics.trackEvent('Account', 'Deactivate Account'); + Lifecycle.onLoggedOut(); + this.props.onFinished(false); } _onCancel() { From b1249899680f57448e94ca2df83d834a4c6e5a15 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 23 May 2018 16:33:32 +0100 Subject: [PATCH 1154/1160] Implement erasure option upon deactivation --- .../views/dialogs/DeactivateAccountDialog.js | 103 ++++++++++++++++-- src/i18n/strings/en_EN.json | 9 +- 2 files changed, 101 insertions(+), 11 deletions(-) diff --git a/src/components/views/dialogs/DeactivateAccountDialog.js b/src/components/views/dialogs/DeactivateAccountDialog.js index f41f37e075..104419f2ef 100644 --- a/src/components/views/dialogs/DeactivateAccountDialog.js +++ b/src/components/views/dialogs/DeactivateAccountDialog.js @@ -33,10 +33,21 @@ export default class DeactivateAccountDialog extends React.Component { this._onOk = this._onOk.bind(this); this._onCancel = this._onCancel.bind(this); this._onPasswordFieldChange = this._onPasswordFieldChange.bind(this); + this._onEraseFieldChange = this._onEraseFieldChange.bind(this); + + const deactivationPreferences = + MatrixClientPeg.get().getAccountData('im.riot.account_deactivation_preferences'); + + const shouldErase = ( + deactivationPreferences && + deactivationPreferences.getContent() && + deactivationPreferences.getContent().shouldErase + ) || false; this.state = { confirmButtonEnabled: false, busy: false, + shouldErase, errStr: null, }; } @@ -47,16 +58,54 @@ export default class DeactivateAccountDialog extends React.Component { }); } + _onEraseFieldChange(ev) { + this.setState({ + shouldErase: ev.target.checked, + }); + } + async _onOk() { - // This assumes that the HS requires password UI auth - // for this endpoint. In reality it could be any UI auth. this.setState({busy: true}); + + // Before we deactivate the account insert an event into + // the user's account data indicating that they wish to be + // erased from the homeserver. + // + // We do this because the API for erasing after deactivation + // might not be supported by the connected homeserver. Leaving + // an indication in account data is only best-effort, and + // in the worse case, the HS maintainer would have to run a + // script to erase deactivated accounts that have shouldErase + // set to true in im.riot.account_deactivation_preferences. + // + // Note: The preferences are scoped to Riot, hence the + // "im.riot..." event type. + // + // Note: This may have already been set on previous attempts + // where, for example, the user entered the wrong password. + // This is fine because the UI always indicates the preference + // prior to us calling `deactivateAccount`. try { - await MatrixClientPeg.get().deactivateAccount({ + await MatrixClientPeg.get().setAccountData('im.riot.account_deactivation_preferences', { + shouldErase: this.state.shouldErase, + }); + } catch (err) { + this.setState({ + busy: false, + errStr: _t('Failed to indicate account erasure'), + }); + return; + } + + try { + // This assumes that the HS requires password UI auth + // for this endpoint. In reality it could be any UI auth. + const auth = { type: 'm.login.password', user: MatrixClientPeg.get().credentials.userId, password: this._passwordField.value, - }); + }; + await MatrixClientPeg.get().deactivateAccount(auth, this.state.shouldErase); } catch (err) { let errStr = _t('Unknown error'); // https://matrix.org/jira/browse/SYN-744 @@ -70,6 +119,7 @@ export default class DeactivateAccountDialog extends React.Component { }); return; } + Analytics.trackEvent('Account', 'Deactivate Account'); Lifecycle.onLoggedOut(); this.props.onFinished(false); @@ -107,21 +157,56 @@ export default class DeactivateAccountDialog extends React.Component { onFinished={this.props.onFinished} onEnterPressed={this.onOk} titleClass="danger" - title={_t("Deactivate Account")}> + title={_t("Deactivate Account")} + >
    -

    { _t("This will make your account permanently unusable. You will not be able to re-register the same user ID.") }

    +

    { _t( + "This will make your account permanently unusable. " + + "You will not be able to log in, and no one will be able " + + "to re-register the same user ID. " + + "This action is irreversible.", + {}, + { b: (sub) => { sub } }, + ) }

    -

    { _t("This action is irreversible.") }

    +

    { _t( + "Deactivating your account does not by default erase messages you have sent. " + + "If you would like to erase your messages, please tick the box below.", + {}, + { b: (sub) => { sub } }, + ) }

    -

    { _t("To continue, please enter your password.") }

    +

    { _t( + "Message visibility in Matrix is similar to email. " + + "Erasing your messages means that messages have you sent will not be shared with " + + "any new or unregistered users, but registered users who already had access to " + + "these messages will still have access to their copy.", + ) }

    -

    { _t("Password") }:

    +

    { _t("To continue, please enter your password:") }

    {this._passwordField = e;}} className={passwordBoxClass} /> + +

    + +

    + { error }
    diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 7df8ae2161..a384a7c212 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -781,11 +781,16 @@ "Advanced options": "Advanced options", "Block users on other matrix homeservers from joining this room": "Block users on other matrix homeservers from joining this room", "This setting cannot be changed later!": "This setting cannot be changed later!", + "Failed to indicate account erasure": "Failed to indicate account erasure", "Unknown error": "Unknown error", "Incorrect password": "Incorrect password", "Deactivate Account": "Deactivate Account", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "This will make your account permanently unusable. You will not be able to re-register the same user ID.", - "This action is irreversible.": "This action is irreversible.", + "This will make your account permanently unusable. You will not be able to log in, and no one will be able to re-register the same user ID. This action is irreversible.": "This will make your account permanently unusable. You will not be able to log in, and no one will be able to re-register the same user ID. This action is irreversible.", + "Deactivating your account does not by default erase messages you have sent. If you would like to erase your messages, please tick the box below.": "Deactivating your account does not by default erase messages you have sent. If you would like to erase your messages, please tick the box below.", + "Message visibility in Matrix is similar to email. Erasing your messages means that messages have you sent will not be shared with any new or unregistered users, but registered users who already had access to these messages will still have access to their copy.": "Message visibility in Matrix is similar to email. Erasing your messages means that messages have you sent will not be shared with any new or unregistered users, but registered users who already had access to these messages will still have access to their copy.", + "To continue, please enter your password:": "To continue, please enter your password:", + "password": "password", + "Please erase all messages I have sent when my account is deactivated. (Warning: this will cause future users to see an incomplete view of conversations, which is a bad experience).": "Please erase all messages I have sent when my account is deactivated. (Warning: this will cause future users to see an incomplete view of conversations, which is a bad experience).", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:", "Device name": "Device name", "Device key": "Device key", From cc79384839ddf841744fca5ceaf6e11bfd41d6ba Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Thu, 24 May 2018 01:57:22 +0100 Subject: [PATCH 1155/1160] fix https://github.com/vector-im/riot-web/issues/6643 --- src/components/views/rooms/MemberList.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/rooms/MemberList.js b/src/components/views/rooms/MemberList.js index 3dfcd38cbd..6f6188e0b5 100644 --- a/src/components/views/rooms/MemberList.js +++ b/src/components/views/rooms/MemberList.js @@ -270,7 +270,7 @@ module.exports = React.createClass({ // console.log("comparing " + this.memberString(memberA) + " and " + this.memberString(memberB)); - if (userA.currentlyActive && userB.currentlyActive) { + if ((userA.currentlyActive && userB.currentlyActive) || !this._showPresence) { // console.log(memberA.name + " and " + memberB.name + " are both active"); if (memberA.powerLevel === memberB.powerLevel) { // console.log(memberA + " and " + memberB + " have same power level"); From dca1217a4573b01718afd2b5e4e9ce5e278257a5 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 24 May 2018 11:50:45 +0100 Subject: [PATCH 1156/1160] Change wording and appearance of Deactivate Account dialog --- res/css/_components.scss | 1 + .../dialogs/_DeactivateAccountDialog.scss | 23 +++++++ .../views/dialogs/DeactivateAccountDialog.js | 66 +++++++++++-------- src/i18n/strings/en_EN.json | 8 +-- 4 files changed, 65 insertions(+), 33 deletions(-) create mode 100644 res/css/views/dialogs/_DeactivateAccountDialog.scss diff --git a/res/css/_components.scss b/res/css/_components.scss index 50e8eb11d1..2734939ae3 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -34,6 +34,7 @@ @import "./views/dialogs/_ConfirmUserActionDialog.scss"; @import "./views/dialogs/_CreateGroupDialog.scss"; @import "./views/dialogs/_CreateRoomDialog.scss"; +@import "./views/dialogs/_DeactivateAccountDialog.scss"; @import "./views/dialogs/_DevtoolsDialog.scss"; @import "./views/dialogs/_EncryptedEventDialog.scss"; @import "./views/dialogs/_GroupAddressPicker.scss"; diff --git a/res/css/views/dialogs/_DeactivateAccountDialog.scss b/res/css/views/dialogs/_DeactivateAccountDialog.scss new file mode 100644 index 0000000000..dc76da5b15 --- /dev/null +++ b/res/css/views/dialogs/_DeactivateAccountDialog.scss @@ -0,0 +1,23 @@ +/* +Copyright 2018 New Vector Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_DeactivateAccountDialog .mx_Dialog_content { + margin-bottom: 30px; +} + +.mx_DeactivateAccountDialog .mx_DeactivateAccountDialog_input_section { + margin-top: 60px; +} diff --git a/src/components/views/dialogs/DeactivateAccountDialog.js b/src/components/views/dialogs/DeactivateAccountDialog.js index 104419f2ef..761a1e4209 100644 --- a/src/components/views/dialogs/DeactivateAccountDialog.js +++ b/src/components/views/dialogs/DeactivateAccountDialog.js @@ -162,50 +162,58 @@ export default class DeactivateAccountDialog extends React.Component {

    { _t( "This will make your account permanently unusable. " + - "You will not be able to log in, and no one will be able " + - "to re-register the same user ID. " + + "You will not be able to log in, and no one will be able to re-register the same " + + "user ID. " + + "This will cause your account to leave all rooms it is participating in, and it " + + "will remove your account details from your identity server. " + "This action is irreversible.", {}, { b: (sub) => { sub } }, ) }

    { _t( - "Deactivating your account does not by default erase messages you have sent. " + - "If you would like to erase your messages, please tick the box below.", + "Deactivating your account does not by default cause us to forget messages you " + + "have sent. " + + "If you would like us to forget your messages, please tick the box below.", {}, { b: (sub) => { sub } }, ) }

    { _t( "Message visibility in Matrix is similar to email. " + - "Erasing your messages means that messages have you sent will not be shared with " + - "any new or unregistered users, but registered users who already had access to " + - "these messages will still have access to their copy.", + "Our forgetting your messages means that messages you have sent will not be shared " + + "with any new or unregistered users, but registered users who already have access " + + "to these messages will still have access to their copy.", ) }

    -

    { _t("To continue, please enter your password:") }

    - {this._passwordField = e;}} - className={passwordBoxClass} - /> +
    +

    + +

    -

    - -

    +

    { _t("To continue, please enter your password:") }

    + {this._passwordField = e;}} + className={passwordBoxClass} + /> +
    { error }
    diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index a384a7c212..093073f149 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -785,12 +785,12 @@ "Unknown error": "Unknown error", "Incorrect password": "Incorrect password", "Deactivate Account": "Deactivate Account", - "This will make your account permanently unusable. You will not be able to log in, and no one will be able to re-register the same user ID. This action is irreversible.": "This will make your account permanently unusable. You will not be able to log in, and no one will be able to re-register the same user ID. This action is irreversible.", - "Deactivating your account does not by default erase messages you have sent. If you would like to erase your messages, please tick the box below.": "Deactivating your account does not by default erase messages you have sent. If you would like to erase your messages, please tick the box below.", - "Message visibility in Matrix is similar to email. Erasing your messages means that messages have you sent will not be shared with any new or unregistered users, but registered users who already had access to these messages will still have access to their copy.": "Message visibility in Matrix is similar to email. Erasing your messages means that messages have you sent will not be shared with any new or unregistered users, but registered users who already had access to these messages will still have access to their copy.", + "This will make your account permanently unusable. You will not be able to log in, and no one will be able to re-register the same user ID. This will cause your account to leave all rooms it is participating in, and it will remove your account details from your identity server. This action is irreversible.": "This will make your account permanently unusable. You will not be able to log in, and no one will be able to re-register the same user ID. This will cause your account to leave all rooms it is participating in, and it will remove your account details from your identity server. This action is irreversible.", + "Deactivating your account does not by default cause us to forget messages you have sent. If you would like us to forget your messages, please tick the box below.": "Deactivating your account does not by default cause us to forget messages you have sent. If you would like us to forget your messages, please tick the box below.", + "Message visibility in Matrix is similar to email. Our forgetting your messages means that messages you have sent will not be shared with any new or unregistered users, but registered users who already have access to these messages will still have access to their copy.": "Message visibility in Matrix is similar to email. Our forgetting your messages means that messages you have sent will not be shared with any new or unregistered users, but registered users who already have access to these messages will still have access to their copy.", + "Please forget all messages I have sent when my account is deactivated (Warning: this will cause future users to see an incomplete view of conversations)": "Please forget all messages I have sent when my account is deactivated (Warning: this will cause future users to see an incomplete view of conversations)", "To continue, please enter your password:": "To continue, please enter your password:", "password": "password", - "Please erase all messages I have sent when my account is deactivated. (Warning: this will cause future users to see an incomplete view of conversations, which is a bad experience).": "Please erase all messages I have sent when my account is deactivated. (Warning: this will cause future users to see an incomplete view of conversations, which is a bad experience).", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:", "Device name": "Device name", "Device key": "Device key", From 8dcf43a88dabdb7f316c7e4d9c0750bec63f3edf Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 24 May 2018 12:08:05 +0100 Subject: [PATCH 1157/1160] gen-i18n --- src/i18n/strings/en_EN.json | 60 ++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 093073f149..8dc5b8e630 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -41,10 +41,6 @@ "The file '%(fileName)s' failed to upload": "The file '%(fileName)s' failed to upload", "The file '%(fileName)s' exceeds this home server's size limit for uploads": "The file '%(fileName)s' exceeds this home server's size limit for uploads", "Upload Failed": "Upload Failed", - "Failure to create room": "Failure to create room", - "Server may be unavailable, overloaded, or you hit a bug.": "Server may be unavailable, overloaded, or you hit a bug.", - "Send anyway": "Send anyway", - "Send": "Send", "Sun": "Sun", "Mon": "Mon", "Tue": "Tue", @@ -84,7 +80,6 @@ "Failed to invite users to community": "Failed to invite users to community", "Failed to invite users to %(groupId)s": "Failed to invite users to %(groupId)s", "Failed to add the following rooms to %(groupId)s:": "Failed to add the following rooms to %(groupId)s:", - "Unnamed Room": "Unnamed Room", "Riot does not have permission to send you notifications - please check your browser settings": "Riot does not have permission to send you notifications - please check your browser settings", "Riot was not given permission to send notifications - please try again": "Riot was not given permission to send notifications - please try again", "Unable to enable Notifications": "Unable to enable Notifications", @@ -183,6 +178,11 @@ "%(names)s and %(count)s others are typing|other": "%(names)s and %(count)s others are typing", "%(names)s and %(count)s others are typing|one": "%(names)s and one other is typing", "%(names)s and %(lastPerson)s are typing": "%(names)s and %(lastPerson)s are typing", + "Failure to create room": "Failure to create room", + "Server may be unavailable, overloaded, or you hit a bug.": "Server may be unavailable, overloaded, or you hit a bug.", + "Send anyway": "Send anyway", + "Send": "Send", + "Unnamed Room": "Unnamed Room", "Your browser does not support the required cryptography extensions": "Your browser does not support the required cryptography extensions", "Not a valid Riot keyfile": "Not a valid Riot keyfile", "Authentication check failed: incorrect password?": "Authentication check failed: incorrect password?", @@ -296,29 +296,6 @@ "Off": "Off", "On": "On", "Noisy": "Noisy", - "Invalid alias format": "Invalid alias format", - "'%(alias)s' is not a valid format for an alias": "'%(alias)s' is not a valid format for an alias", - "Invalid address format": "Invalid address format", - "'%(alias)s' is not a valid format for an address": "'%(alias)s' is not a valid format for an address", - "not specified": "not specified", - "not set": "not set", - "Remote addresses for this room:": "Remote addresses for this room:", - "Addresses": "Addresses", - "The main address for this room is": "The main address for this room is", - "Local addresses for this room:": "Local addresses for this room:", - "This room has no local addresses": "This room has no local addresses", - "New address (e.g. #foo:%(localDomain)s)": "New address (e.g. #foo:%(localDomain)s)", - "Invalid community ID": "Invalid community ID", - "'%(groupId)s' is not a valid community ID": "'%(groupId)s' is not a valid community ID", - "Flair": "Flair", - "Showing flair for these communities:": "Showing flair for these communities:", - "This room is not showing flair for any communities": "This room is not showing flair for any communities", - "New community ID (e.g. +foo:%(localDomain)s)": "New community ID (e.g. +foo:%(localDomain)s)", - "You have enabled URL previews by default.": "You have enabled URL previews by default.", - "You have disabled URL previews by default.": "You have disabled URL previews by default.", - "URL previews are enabled by default for participants in this room.": "URL previews are enabled by default for participants in this room.", - "URL previews are disabled by default for participants in this room.": "URL previews are disabled by default for participants in this room.", - "URL Previews": "URL Previews", "Cannot add any more widgets": "Cannot add any more widgets", "The maximum permitted number of widgets have already been added to this room.": "The maximum permitted number of widgets have already been added to this room.", "Add a widget": "Add a widget", @@ -415,11 +392,11 @@ "numbullet": "numbullet", "Markdown is disabled": "Markdown is disabled", "Markdown is enabled": "Markdown is enabled", + "Unpin Message": "Unpin Message", + "Jump to message": "Jump to message", "No pinned messages.": "No pinned messages.", "Loading...": "Loading...", "Pinned Messages": "Pinned Messages", - "Unpin Message": "Unpin Message", - "Jump to message": "Jump to message", "%(duration)ss": "%(duration)ss", "%(duration)sm": "%(duration)sm", "%(duration)sh": "%(duration)sh", @@ -551,6 +528,29 @@ "Scroll to unread messages": "Scroll to unread messages", "Jump to first unread message.": "Jump to first unread message.", "Close": "Close", + "Invalid alias format": "Invalid alias format", + "'%(alias)s' is not a valid format for an alias": "'%(alias)s' is not a valid format for an alias", + "Invalid address format": "Invalid address format", + "'%(alias)s' is not a valid format for an address": "'%(alias)s' is not a valid format for an address", + "not specified": "not specified", + "not set": "not set", + "Remote addresses for this room:": "Remote addresses for this room:", + "Addresses": "Addresses", + "The main address for this room is": "The main address for this room is", + "Local addresses for this room:": "Local addresses for this room:", + "This room has no local addresses": "This room has no local addresses", + "New address (e.g. #foo:%(localDomain)s)": "New address (e.g. #foo:%(localDomain)s)", + "Invalid community ID": "Invalid community ID", + "'%(groupId)s' is not a valid community ID": "'%(groupId)s' is not a valid community ID", + "Flair": "Flair", + "Showing flair for these communities:": "Showing flair for these communities:", + "This room is not showing flair for any communities": "This room is not showing flair for any communities", + "New community ID (e.g. +foo:%(localDomain)s)": "New community ID (e.g. +foo:%(localDomain)s)", + "You have enabled URL previews by default.": "You have enabled URL previews by default.", + "You have disabled URL previews by default.": "You have disabled URL previews by default.", + "URL previews are enabled by default for participants in this room.": "URL previews are enabled by default for participants in this room.", + "URL previews are disabled by default for participants in this room.": "URL previews are disabled by default for participants in this room.", + "URL Previews": "URL Previews", "Sunday": "Sunday", "Monday": "Monday", "Tuesday": "Tuesday", From e0a3debb7ad7f26f035c647e0a3ad1f38e69633e Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 24 May 2018 12:08:22 +0100 Subject: [PATCH 1158/1160] prune-i18n --- src/i18n/strings/bg.json | 3 --- src/i18n/strings/ca.json | 3 --- src/i18n/strings/cs.json | 3 --- src/i18n/strings/de_DE.json | 3 --- src/i18n/strings/el.json | 3 --- src/i18n/strings/en_US.json | 3 --- src/i18n/strings/eo.json | 3 --- src/i18n/strings/es.json | 2 -- src/i18n/strings/eu.json | 3 --- src/i18n/strings/fi.json | 3 --- src/i18n/strings/fr.json | 3 --- src/i18n/strings/gl.json | 3 --- src/i18n/strings/hu.json | 3 --- src/i18n/strings/it.json | 3 --- src/i18n/strings/ja.json | 1 - src/i18n/strings/ko.json | 3 --- src/i18n/strings/lv.json | 3 --- src/i18n/strings/nl.json | 3 --- src/i18n/strings/pl.json | 3 --- src/i18n/strings/pt.json | 3 --- src/i18n/strings/pt_BR.json | 3 --- src/i18n/strings/ru.json | 3 --- src/i18n/strings/sk.json | 3 --- src/i18n/strings/sr.json | 3 --- src/i18n/strings/tr.json | 3 --- src/i18n/strings/zh_Hans.json | 3 --- src/i18n/strings/zh_Hant.json | 3 --- 27 files changed, 78 deletions(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 331581f893..20a0832b38 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -223,7 +223,6 @@ "Automatically replace plain text Emoji": "Автоматично откриване и заместване на емотикони в текста", "Mirror local video feed": "Показвай ми огледално моя видео образ", "Disable Peer-to-Peer for 1:1 calls": "Изключване на Peer-to-Peer в 1:1 разговор", - "Opt out of analytics": "Отказване от събиране на статистически данни", "Never send encrypted messages to unverified devices from this device": "Никога не изпращай шифровани съобщения от това устройство до непотвърдени устройства", "Never send encrypted messages to unverified devices in this room from this device": "Никога не изпращай шифровани съобщения от това устройство до непотвърдени устройства в тази стая", "Enable inline URL previews by default": "Включване по подразбиране на URL прегледи", @@ -695,8 +694,6 @@ "Incorrect password": "Неправилна парола", "Deactivate Account": "Деактивация на профила", "Deactivate my account": "Деактивирай моя профил", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Това ще направи профила Ви перманентно неизползваем. Няма да можете да се регистрирате отново със същия потребителски идентификатор.", - "This action is irreversible.": "Това действие е необратимо.", "Device name": "Име на устройство", "Device key": "Ключ на устройство", "In future this verification process will be more sophisticated.": "В бъдеще този процес на потвърждение ще бъде по-лесен.", diff --git a/src/i18n/strings/ca.json b/src/i18n/strings/ca.json index 514c6e66fe..407b9f61d4 100644 --- a/src/i18n/strings/ca.json +++ b/src/i18n/strings/ca.json @@ -348,7 +348,6 @@ "Hide Text Formatting Toolbar": "Amaga la barra d'eines de format de text", "Server error": "S'ha produït un error al servidor", "Mirror local video feed": "Mostra el vídeo local com un mirall", - "Opt out of analytics": "No acceptis analítiques", "Server unavailable, overloaded, or something else went wrong.": "El servidor no està disponible, està sobrecarregat o alguna altra cosa no ha funcionat correctament.", "Command error": "S'ha produït un error en l'ordre", "bold": "negreta", @@ -675,8 +674,6 @@ "Unknown error": "S'ha produït un error desconegut", "Incorrect password": "Contrasenya incorrecta", "Deactivate Account": "Desactivar el compte", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Això farà que el vostre compte no es pugui utilitzar mai més. No podreu tornar a registrar la mateixa identificació d'usuari.", - "This action is irreversible.": "Aquesta acció és irreversible.", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Per verificar que es pot confiar en aquest dispositiu, poseu-vos en contacte amb el propietari mitjançant altres mitjans (per exemple, en persona o amb una trucada telefònica) i pregunteu-li si la clau que veuen a la configuració del seu usuari, aquest dispositiu coincideix amb la següent clau:", "Device name": "Nom del dispositiu", "Device key": "Clau del dispositiu", diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index a80b9daf64..33c7a3d5f1 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -647,7 +647,6 @@ "Disable big emoji in chat": "Zakázat velké Emoji v konverzaci", "Mirror local video feed": "Zrcadlit lokání video", "Disable Peer-to-Peer for 1:1 calls": "Zakázat Peer-to-Peer pro 1:1 hovory", - "Opt out of analytics": "Odhlásit se z analytiky údajů", "Never send encrypted messages to unverified devices from this device": "Z tohoto zařízení nikdy neodesílat šifrované zprávy na neověřená zařízení", "Enable inline URL previews by default": "Nastavit povolení náhledů URL adres jako výchozí", "Enable URL previews for this room (only affects you)": "Povolit náhledy URL adres pro tuto místnost (ovlivňuje pouze vás)", @@ -789,8 +788,6 @@ "This setting cannot be changed later!": "Toto nastavení nelze v budoucnu změnit!", "Unknown error": "Neznámá chyba", "Incorrect password": "Nesprávné heslo", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Toto způsobí, že váš účet nebude již nikdy použitelný. Zároveň nebude možné se znovu zaregistrovat pod stejným uživatelským ID.", - "This action is irreversible.": "Tuto operaci nebude možné vrátit zpět.", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Pokud si chcete ověřit, zda je zařízení skutečně důvěryhodné, kontaktujte vlastníka jiným způsobem (např. osobně anebo telefonicky) a zeptejte se ho na klíč, který má pro toto zařízení zobrazený v nastavení a zda se shoduje s klíčem zobrazeným níže:", "Device name": "Název zařízení", "Device key": "Klíč zařízení", diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index eaa6781e15..c8e01819bd 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -423,7 +423,6 @@ "Confirm Removal": "Entfernen bestätigen", "Unknown error": "Unbekannter Fehler", "Incorrect password": "Ungültiges Passwort", - "This action is irreversible.": "Diese Aktion kann nicht rückgängig gemacht werden.", "To continue, please enter your password.": "Zum fortfahren bitte Passwort eingeben.", "Device name": "Geräte-Name", "Device key": "Geräte-Schlüssel", @@ -465,7 +464,6 @@ "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Dieser Prozess erlaubt es dir, die Schlüssel für die in verschlüsselten Räumen empfangenen Nachrichten in eine lokale Datei zu exportieren. In Zukunft wird es möglich sein, diese Datei in einen anderen Matrix-Client zu importieren, sodass dieser Client diese Nachrichten ebenfalls entschlüsseln kann.", "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Mit der exportierten Datei kann jeder, der diese Datei lesen kann, jede verschlüsselte Nachricht entschlüsseln, die für dich lesbar ist. Du solltest die Datei also unbedingt sicher verwahren. Um den Vorgang sicherer zu gestalten, solltest du unten eine Passphrase eingeben, die dazu verwendet wird, die exportierten Daten zu verschlüsseln. Anschließend wird es nur möglich sein, die Daten zu importieren, wenn dieselbe Passphrase verwendet wird.", "Analytics": "Anonymisierte Analysedaten", - "Opt out of analytics": "Zustimmung zur Übermittlung von anonymisierten Analysedaten verweigern", "Riot collects anonymous analytics to allow us to improve the application.": "Riot sammelt anonymisierte Analysedaten, um die Anwendung kontinuierlich verbessern zu können.", "Add an Integration": "Eine Integration hinzufügen", "Removed or unknown message type": "Gelöschte Nachricht oder unbekannter Nachrichten-Typ", @@ -474,7 +472,6 @@ "Online": "Online", " (unsupported)": " (nicht unterstützt)", "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Dieser Prozess erlaubt es dir, die zuvor von einem anderen Matrix-Client exportierten Verschlüsselungs-Schlüssel zu importieren. Danach kannst du alle Nachrichten entschlüsseln, die auch bereits auf dem anderen Client entschlüsselt werden konnten.", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Dies wird dein Benutzerkonto dauerhaft unbenutzbar machen. Du wirst nicht in der Lage sein, dich mit derselben Benutzer-ID erneut zu registrieren.", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Um sicherzustellen, dass diesem Gerät vertraut werden kann, kontaktiere bitte den Eigentümer des Geräts über ein anderes Kommunikationsmittel (z.B. im persönlichen Gespräch oder durch einen Telefonanruf) und vergewissere dich, dass der Schlüssel, den der Eigentümer in den Benutzer-Einstellungen für dieses Gerät sieht, mit dem folgenden Schlüssel identisch ist:", "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Wenn er identisch ist, bitte den Bestätigen-Button unten verwenden. Falls er nicht identisch sein sollte, hat eine Fremdperson Kontrolle über dieses Gerät und es sollte gesperrt werden.", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Wenn du zuvor eine aktuellere Version von Riot verwendet hast, ist deine Sitzung eventuell inkompatibel mit dieser Version. Bitte schließe dieses Fenster und kehre zur aktuelleren Version zurück.", diff --git a/src/i18n/strings/el.json b/src/i18n/strings/el.json index 5fa4a114c5..fabd88c74a 100644 --- a/src/i18n/strings/el.json +++ b/src/i18n/strings/el.json @@ -513,11 +513,9 @@ "Please select the destination room for this message": "Παρακαλούμε επιλέξτε ένα δωμάτιο προορισμού για αυτό το μήνυμα", "Desktop specific": "Μόνο για επιφάνεια εργασίας", "Analytics": "Αναλυτικά δεδομένα", - "Opt out of analytics": "Αποκλεισμός αναλυτικών δεδομένων", "Riot collects anonymous analytics to allow us to improve the application.": "Το Riot συλλέγει ανώνυμα δεδομένα επιτρέποντας μας να βελτιώσουμε την εφαρμογή.", "Failed to invite": "Δεν ήταν δυνατή η πρόσκληση", "Failed to invite user": "Δεν ήταν δυνατή η πρόσκληση του χρήστη", - "This action is irreversible.": "Αυτή η ενέργεια είναι μη αναστρέψιμη.", "In future this verification process will be more sophisticated.": "Στο μέλλον η διαδικασία επαλήθευσης θα είναι πιο εξελιγμένη.", "I verify that the keys match": "Επιβεβαιώνω πως ταιριάζουν τα κλειδιά", "\"%(RoomName)s\" contains devices that you haven't seen before.": "Το \"%(RoomName)s\" περιέχει συσκευές που δεν έχετε ξαναδεί.", @@ -614,7 +612,6 @@ "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Το αρχείο εξαγωγής θα επιτρέψει σε οποιονδήποτε που μπορεί να το διαβάσει να αποκρυπτογραφήσει κρυπτογραφημένα μηνύματα που εσείς μπορείτε να δείτε, οπότε θα πρέπει να είστε προσεκτικοί για να το κρατήσετε ασφαλές. Για να βοηθήσετε με αυτό, θα πρέπει να εισαγάγετε ένα συνθηματικό, το οποία θα χρησιμοποιηθεί για την κρυπτογράφηση των εξαγόμενων δεδομένων. Η εισαγωγή δεδομένων θα είναι δυνατή χρησιμοποιώντας μόνο το ίδιο συνθηματικό.", "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Αυτή η διαδικασία σας επιτρέπει να εισαγάγετε κλειδιά κρυπτογράφησης που έχετε προηγουμένως εξάγει από άλλο πρόγραμμα του Matrix. Στη συνέχεια, θα μπορέσετε να αποκρυπτογραφήσετε τυχόν μηνύματα που το άλλο πρόγραμμα θα μπορούσε να αποκρυπτογραφήσει.", "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Το αρχείο εξαγωγής θα είναι προστατευμένο με συνθηματικό. Θα χρειαστεί να πληκτρολογήσετε το συνθηματικό εδώ για να αποκρυπτογραφήσετε το αρχείο.", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Με αυτόν τον τρόπο, ο λογαριασμός σας θα είναι μόνιμα αχρησιμοποίητος. Δεν θα μπορείτε να εγγραφείτε ξανά με το ίδιο αναγνωριστικό χρήστη.", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Για να βεβαιωθείτε ότι είναι αξιόπιστη αυτή η συσκευή, επικοινωνήστε με τον κάτοχο της χρησιμοποιώντας άλλα μέσα (π.χ. προσωπικά ή μέσω τηλεφώνου) και ρωτήστε εάν το κλειδί που βλέπετε στις ρυθμίσεις χρήστη για αυτήν τη συσκευή ταιριάζει με το παρακάτω κλειδί:", "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Εάν ταιριάζει, πατήστε το κουμπί επιβεβαίωσης παρακάτω. Εάν όχι, τότε κάποιος άλλος παρακολουθεί αυτή τη συσκευή και ίσως θέλετε να πατήσετε το κουμπί της μαύρης λίστας.", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Αν χρησιμοποιούσατε προηγουμένως μια πιο πρόσφατη έκδοση του Riot, η συνεδρία σας ίσως είναι μη συμβατή με αυτήν την έκδοση. Κλείστε αυτό το παράθυρο και επιστρέψτε στην πιο πρόσφατη έκδοση.", diff --git a/src/i18n/strings/en_US.json b/src/i18n/strings/en_US.json index e316f72e80..43e2041020 100644 --- a/src/i18n/strings/en_US.json +++ b/src/i18n/strings/en_US.json @@ -474,7 +474,6 @@ "Start automatically after system login": "Start automatically after system login", "Desktop specific": "Desktop specific", "Analytics": "Analytics", - "Opt out of analytics": "Opt out of analytics", "Banned by %(displayName)s": "Banned by %(displayName)s", "Options": "Options", "Riot collects anonymous analytics to allow us to improve the application.": "Riot collects anonymous analytics to allow us to improve the application.", @@ -499,8 +498,6 @@ "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.", "Unknown error": "Unknown error", "Incorrect password": "Incorrect password", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "This will make your account permanently unusable. You will not be able to re-register the same user ID.", - "This action is irreversible.": "This action is irreversible.", "To continue, please enter your password.": "To continue, please enter your password.", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:", "Device name": "Device name", diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index fae7d6cfa8..68645ffd9c 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -192,7 +192,6 @@ "Automatically replace plain text Emoji": "Aŭtomate anstataŭigi tekstajn mienetojn", "Mirror local video feed": "Speguli lokan videon", "Disable Peer-to-Peer for 1:1 calls": "Malŝalti samtavolajn duopajn vokojn", - "Opt out of analytics": "Malpermesi datuman analizon", "Never send encrypted messages to unverified devices from this device": "Neniam sendi neĉifritajn mesaĝojn al nekontrolitaj aparatoj de tiu ĉi aparato", "Never send encrypted messages to unverified devices in this room from this device": "Neniam sendi ĉifritajn mesaĝojn al nekontrolitaj aparatoj en tiu ĉi ĉambro de tiu ĉi aparto", "Enable inline URL previews by default": "Ŝalti entekstan antaŭrigardon al retadresoj", @@ -653,8 +652,6 @@ "Unknown error": "Nekonata eraro", "Incorrect password": "Malĝusta pasvorto", "Deactivate Account": "Malaktivigi konton", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Tio ĉi por ĉiam senuzebligos vian konton. Vi ne povos reregistriĝi kun la sama identigaĵo.", - "This action is irreversible.": "Tiu ĉi ago ne malfareblas.", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Por kontroli ke tiu ĉi aparato estas fidinda, bonvolu kontakti ties posedanton per alia maniero (ekz-e persone aŭ telefone) kaj demandi ĝin ĉu la ŝlosilo, kiun ĝi vidas en agordoj de uzanto ĉe si, kongruas kun la ĉi-suba ŝlosilo:", "Device name": "Aparata nomo", "Device key": "Aparata ŝlosilo", diff --git a/src/i18n/strings/es.json b/src/i18n/strings/es.json index 7ec0e821db..8e7925ba36 100644 --- a/src/i18n/strings/es.json +++ b/src/i18n/strings/es.json @@ -225,7 +225,6 @@ "Start chat": "Comenzar chat", "New Password": "Nueva contraseña", "Analytics": "Analíticas", - "Opt out of analytics": "No participar en las analíticas", "Options": "Opciones", "Passphrases must match": "Las contraseñas deben coincidir", "Passphrase must not be empty": "La contraseña no puede estar en blanco", @@ -241,7 +240,6 @@ "Failed to invite the following users to the %(roomName)s room:": "No se pudo invitar a los siguientes usuarios a la sala %(roomName)s:", "Unknown error": "Error desconocido", "Incorrect password": "Contraseña incorrecta", - "This action is irreversible.": "Esta acción es irreversible.", "To continue, please enter your password.": "Para continuar, introduzca su contraseña.", "Device name": "Nombre del dispositivo", "Device Name": "Nombre del dispositivo", diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index 4015d703ce..0c143bb597 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -548,7 +548,6 @@ "Start automatically after system login": "Hasi automatikoki sisteman saioa hasi eta gero", "Desktop specific": "Mahaigainean besterik ez", "Analytics": "Estatistikak", - "Opt out of analytics": "Ez bidali estatistikak", "Options": "Aukerak", "Riot collects anonymous analytics to allow us to improve the application.": "Riotek estatistika anonimoak jasotzen ditu aplikazioa hobetzeko.", "Passphrases must match": "Pasaesaldiak bat etorri behar dira", @@ -567,8 +566,6 @@ "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Ziur gertaera hau kendu (ezabatu) nahi duzula? Jakin gelaren izenaren edo mintzagaiaren aldaketa ezabatzen baduzu, aldaketa desegin daitekeela.", "Unknown error": "Errore ezezaguna", "Incorrect password": "Pasahitz okerra", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Honek zure kontua behin betiko erabilezin bihurtuko du. Ezin izango duzu ID honekin berriro erregistratu.", - "This action is irreversible.": "Ez dago ekintza hau atzera egiterik.", "To continue, please enter your password.": "Jarraitzeko sartu zure pasahitza.", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Gailu hau fidagarria dela egiaztatzeko, kontaktatu bere jabea beste medio bat erabiliz (adib. aurrez aurre edo telefonoz deituz) eta galdetu beraien erabiltzaile-ezarpenetan bere gailurako ikusten duen gakoa hemen beheko bera den:", "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Bat badator sakatu egiaztatu botoia. Bat ez badator, beste inor gailu hau atzematen dago eta blokeatu beharko zenuke.", diff --git a/src/i18n/strings/fi.json b/src/i18n/strings/fi.json index 0f05b697a6..e5787ab561 100644 --- a/src/i18n/strings/fi.json +++ b/src/i18n/strings/fi.json @@ -414,7 +414,6 @@ "Start automatically after system login": "Käynnistä automaattisesti käyttöjärjestelmään kirjautumisen jälkeen", "Desktop specific": "Työpöytäkäytön asetukset", "Analytics": "Analytiikka", - "Opt out of analytics": "Ota analytiikka pois käytöstä", "Options": "Valinnat", "Riot collects anonymous analytics to allow us to improve the application.": "Riot kerää anonyymisti tilastoja jotta voimme parantaa ohjelmistoa.", "Passphrases must match": "Salasanojen on täsmättävä", @@ -432,7 +431,6 @@ "Confirm Removal": "Varmista poistaminen", "Unknown error": "Tuntematon virhe", "Incorrect password": "Virheellinen salasana", - "This action is irreversible.": "Tätä toimintoa ei voi perua.", "Device name": "Laitenimi", "Device Name": "Laitenimi", "Device key": "Laiteavain", @@ -756,7 +754,6 @@ "Advanced options": "Lisäasetukset", "Block users on other matrix homeservers from joining this room": "Salli vain tämän palvelimen käyttäjät", "This setting cannot be changed later!": "Tätä asetusta ei voi muuttaa myöhemmin!", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Tämä tekee tilistäsi pysyvästi käyttökelvottoman. Et voi rekisteröidä samaa tunnusta uudestaan.", "Add rooms to the community summary": "Lisää huoneita yhteisön yhteenvetoon", "Which rooms would you like to add to this summary?": "Mitkä huoneet haluaisit lisätä tähän yhteenvetoon?", "Add to summary": "Lisää yhteenvetoon", diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 758f2d9948..7dbcff2c9a 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -410,7 +410,6 @@ "Please select the destination room for this message": "Merci de sélectionner le salon de destination pour ce message", "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s a supprimé le nom du salon.", "Analytics": "Collecte de données", - "Opt out of analytics": "Ne pas envoyer ses données", "Riot collects anonymous analytics to allow us to improve the application.": "Riot collecte des données anonymes qui nous permettent d’améliorer l’application.", "Passphrases must match": "Les phrases de passe doivent être identiques", "Passphrase must not be empty": "La phrase de passe ne peut pas être vide", @@ -433,8 +432,6 @@ "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Voulez-vous vraiment supprimer cet événement ? Notez que si vous supprimez le changement du nom ou du sujet d’un salon, il est possible que ce changement soit annulé.", "Unknown error": "Erreur inconnue", "Incorrect password": "Mot de passe incorrect", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Ceci rendra votre compte inutilisable de manière permanente. Vous ne pourrez pas vous réinscrire avec le même identifiant utilisateur.", - "This action is irreversible.": "Cette action est irréversible.", "To continue, please enter your password.": "Pour continuer, veuillez saisir votre mot de passe.", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Pour vérifier que vous pouvez faire confiance à cet appareil, merci de contacter son propriétaire par un autre moyen (par ex. en personne ou par téléphone) et demandez lui si la clé qu’il/elle voit dans ses Paramètres Utilisateur pour cet appareil correspond à la clé ci-dessous :", "Device name": "Nom de l'appareil", diff --git a/src/i18n/strings/gl.json b/src/i18n/strings/gl.json index d08b689a2c..fdab066031 100644 --- a/src/i18n/strings/gl.json +++ b/src/i18n/strings/gl.json @@ -236,7 +236,6 @@ "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(day)s %(monthName)s %(fullYear)s", "Message Replies": "Respostas a mensaxe", "Mirror local video feed": "Copiar fonte de vídeo local", - "Opt out of analytics": "Saírse de analytics", "Cannot add any more widgets": "Non pode engadir máis widgets", "The maximum permitted number of widgets have already been added to this room.": "Xa se engadeu o número máximo de widgets a esta sala.", "Add a widget": "Engadir widget", @@ -653,8 +652,6 @@ "Unknown error": "Fallo descoñecido", "Incorrect password": "Contrasinal incorrecto", "Deactivate Account": "Desactivar conta", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Esto inutilizará a súa conta de xeito permanente. Non poderá voltar a rexistrarse co mesmo ID de usuaria.", - "This action is irreversible.": "Esta acción e irreversible.", "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Non se pode determinar si o enderezo ao que foi enviado este convite coincide con un dos asociados a súa conta.", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Para verificar que se pode confiar en este dispositivo, contacte co seu dono utilizando algún outro medio (ex. en persoa ou chamada de teléfono) e pregúntelle si a chave que ven nos Axustes de Usuaria do se dispositivo coincide coa chave inferior:", "Device name": "Nome do dispositivo", diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 051cd8213b..d63b6055a3 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -532,7 +532,6 @@ "Start automatically after system login": "Rendszerindításkor automatikus elindítás", "Desktop specific": "Asztali használatra jellemző", "Analytics": "Analitika", - "Opt out of analytics": "Ne gyűjtsön analitikai adatokat", "Options": "Opciók", "Riot collects anonymous analytics to allow us to improve the application.": "Riot személytelen analitikai adatokat gyűjt annak érdekében, hogy fejleszteni tudjuk az alkalmazást.", "Passphrases must match": "A jelmondatoknak meg kell egyezniük", @@ -551,8 +550,6 @@ "Confirm Removal": "Törlés megerősítése", "Unknown error": "Ismeretlen hiba", "Incorrect password": "Helytelen jelszó", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "A fiókodat véglegesen használhatatlanná teszi. Ez után ugyanazzal az azonosítóval már nem fogsz tudni vissza regisztrálni.", - "This action is irreversible.": "Ez a művelet visszafordíthatatlan.", "To continue, please enter your password.": "A folytatáshoz, kérlek add meg a jelszavadat.", "Device name": "Eszköz neve", "Device Name": "Eszköz neve", diff --git a/src/i18n/strings/it.json b/src/i18n/strings/it.json index b660231915..50121c7059 100644 --- a/src/i18n/strings/it.json +++ b/src/i18n/strings/it.json @@ -247,7 +247,6 @@ "Automatically replace plain text Emoji": "Sostituisci automaticamente le emoji testuali", "Disable Community Filter Panel": "Disattiva il pannello filtro comunità", "Disable Peer-to-Peer for 1:1 calls": "Disattiva il peer-to-peer per chiamate 1:1", - "Opt out of analytics": "Rifiuta le statistiche", "Never send encrypted messages to unverified devices from this device": "Non inviare mai da questo dispositivo messaggi cifrati a dispositivi non verificati", "Never send encrypted messages to unverified devices in this room from this device": "Non inviare mai da questo dispositivo messaggi cifrati a dispositivi non verificati in questa stanza", "Enable inline URL previews by default": "Attiva le anteprime URL in modo predefinito", @@ -695,8 +694,6 @@ "Unknown error": "Errore sconosciuto", "Incorrect password": "Password sbagliata", "Deactivate Account": "Disattiva l'account", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Ciò renderà il tuo account definitivamente inutilizzabile. Non potrai registrare di nuovo lo stesso ID utente.", - "This action is irreversible.": "Questa azione è irreversibile.", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Per verificare se questo dispositivo è fidato, contatta il suo proprietario usando altri metodi (es. di persona o telefonando) e chiedigli se la chiave che vede nelle sue impostazioni utente per questo dispositivo coincide con la chiave sotto:", "Device name": "Nome del dispositivo", "Device key": "Chiave del dispositivo", diff --git a/src/i18n/strings/ja.json b/src/i18n/strings/ja.json index 3908ede0e2..80bd4f1ff5 100644 --- a/src/i18n/strings/ja.json +++ b/src/i18n/strings/ja.json @@ -43,7 +43,6 @@ "Use compact timeline layout": "会話表示の行間を狭くする", "(warning: cannot be disabled again!)": "(警告: 再び元に戻すことは出来ません!)", "Start Chat": "対話へ招待", - "Opt out of analytics": "匿名分析情報を収集しない", "Riot collects anonymous analytics to allow us to improve the application.": "Riotはアプリケーションを改善するために匿名の分析情報を収集しています。", "Start chatting": "対話開始", "Start Chatting": "対話開始", diff --git a/src/i18n/strings/ko.json b/src/i18n/strings/ko.json index f0b8cc454f..4e0a988223 100644 --- a/src/i18n/strings/ko.json +++ b/src/i18n/strings/ko.json @@ -535,7 +535,6 @@ "Start automatically after system login": "컴퓨터를 시작할 때 자동으로 실행하기", "Desktop specific": "컴퓨터 설정", "Analytics": "정보 수집", - "Opt out of analytics": "정보 수집 거부", "Options": "선택권", "Riot collects anonymous analytics to allow us to improve the application.": "라이엇은 익명의 정보를 수집해 응용 프로그램을 개선한답니다.", "Passphrases must match": "암호가 일치해야 해요", @@ -552,8 +551,6 @@ "Confirm Removal": "삭제 확인", "Unknown error": "알 수 없는 오류", "Incorrect password": "맞지 않는 비밀번호", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "계정을 영원히 쓸 수 없게 할 거에요. 같은 사용자 ID를 다시 등록하실 수 없을 거고요.", - "This action is irreversible.": "되돌릴 수 없는 일이에요.", "To continue, please enter your password.": "계속하시려면, 비밀번호를 입력해주세요.", "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "이 과정으로 암호화한 방에서 받은 메시지의 키를 로컬 파일로 내보낼 수 있어요. 너중에 다른 매트릭스 클라이언트로 파일을 불러올 수 있기 때문에, 그 클라이언트에서 메시지를 해독할 수도 있지요.", "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "내보낸 파일은 누구든지 암호화한 메시지를 해독해서 읽을 수 있게 하므로, 보안에 신경 써 주세요. 이를 위해, 내보낸 파일을 암호화하려하니, 아래에 암호를 입력해주세요. 같은 암호를 쓰셔야만 자료를 불러올 수 있어요.", diff --git a/src/i18n/strings/lv.json b/src/i18n/strings/lv.json index 17238aa206..01e3ae5c6d 100644 --- a/src/i18n/strings/lv.json +++ b/src/i18n/strings/lv.json @@ -548,7 +548,6 @@ "Start automatically after system login": "Startēt pie ierīces ielādes", "Desktop specific": "Darbvirsmai specifiskie", "Analytics": "Analītika", - "Opt out of analytics": "Atteikties no analītikas", "Options": "Opcijas/iestatījumi", "Riot collects anonymous analytics to allow us to improve the application.": "Riot ievāc anonīmus analītikas datus, lai varētu uzlabot aplikācijas darbību.", "Passphrases must match": "Paroles frāzēm ir jāsakrīt", @@ -569,8 +568,6 @@ "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Vai tiešām vēlies dzēst šo notikumu? Ņem vērā, ka istabas nosaukuma vai tēmas nosaukuma maiņa var ietekmēt (atsaukt) izmaiņas.", "Unknown error": "Nezināma kļūda", "Incorrect password": "Nepareiza parole", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Tas uz visiem laikiem padarīs tavu kontu neizmantojamu, un Tu vairs nevarēsi atkārtoti reģistrēt šo pašu lietotāja ID.", - "This action is irreversible.": "Šī darbība ir neatgriezeniska.", "To continue, please enter your password.": "Lai turpinātu, ievadi savu paroli.", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Lai verificētu šīs ierīces uzticamību, lūdzu sazinies ar tās īpašnieku, izmantojot citu saziņas veidu (piemēram, sazinoties personiski vai telefoniski) un pajautā, vai atslēga, kuru īpašnieks redz savos lietotāja iestatījumos, sakrīt ar šo atslēgu:", "Device name": "Ierīces nosaukums", diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index 1ddcda076e..0df2cf1bd7 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -535,7 +535,6 @@ "Start automatically after system login": "Start automatisch na systeem-aanmelding", "Desktop specific": "Desktop-specifiek", "Analytics": "Gegevensanalyse", - "Opt out of analytics": "Uitschrijven voor gegevensanalyse", "Options": "Opties", "Riot collects anonymous analytics to allow us to improve the application.": "Riot verzameld anonieme gegevensanalyse die het mogelijk maakt om de applicatie te verbeteren.", "Passphrases must match": "Wachtzinnen moeten overeenkomen", @@ -558,8 +557,6 @@ "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Weet je zeker dat je deze gebeurtenis wilt verwijderen? Wees er wel van bewust dat als je een ruimtenaam of onderwerp verwijderd je de verandering ongedaan kunt maken.", "Unknown error": "Onbekende fout", "Incorrect password": "Incorrect wachtwoord", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Dit zal je account permanent onbruikbaar maken. Je zal ook niet opnieuw kunnen registreren met hetzelfde gebruikers-ID.", - "This action is irreversible.": "Deze actie is onomkeerbaar.", "To continue, please enter your password.": "Om verder te gaan, voer je wachtwoord in.", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Om te verifiëren dat dit apparaat vertrouwd kan worden, contacteer de eigenaar op een andere manier (bijv. persoonlijk of via een telefoontje) en vraag of de sleutel die ze zien in de Gebruikersinstellingen voor dit apparaat overeenkomt met de onderstaande sleutel:", "Device name": "Apparaat naam", diff --git a/src/i18n/strings/pl.json b/src/i18n/strings/pl.json index 8d7c5d11da..d3dcb72f49 100644 --- a/src/i18n/strings/pl.json +++ b/src/i18n/strings/pl.json @@ -555,7 +555,6 @@ "Offline": "Niedostępny", "Add an Integration": "Dodaj integrację", "Token incorrect": "Niepoprawny token", - "This action is irreversible.": "Ta akcja jest nieodwracalna.", "To link to a room it must have an address.": "Aby móc stworzyć link do pokoju musi on mieć swój adres.", "unencrypted": "niezaszyfrowany", "Unknown (user, device) pair:": "Nieznana para (użytkownik, urządzenie):", @@ -600,7 +599,6 @@ "Failed to invite the following users to the %(roomName)s room:": "Wysłanie zaproszenia do następujących użytkowników do pokoju %(roomName)s nie powiodło się:", "Confirm Removal": "Potwierdź usunięcie", "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Jesteś pewien że chcesz usunąć to wydarzenie? Pamiętaj, że jeśli usuniesz nazwę pokoju lub aktualizację tematu pokoju, zmiana może zostać cofnięta.", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "To sprawi, że Twoje konto będzie permamentnie nieużywalne. Nie będzie można zarejestrować się ponownie z tą samą identyfikacją użytkownika.", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Aby sprawdzić czy to urządzenie jest zaufane, skontaktuj się z jego właścicielem używając innych środków (np. osobiście lub telefonicznie) i zapytaj ich czy klucz, który widzą w ustawieniach użytkownika dla tego urządzenia pasuje do klucza poniżej:", "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Jeśli klucz pasuje, naciśnij na przycisk \"Zweryfikuj\" poniżej. Jeśli nie, to ktoś inny najprawdopodobniej przejmuje lub podszywa się pod to urządzenie i powinieneś nacisnąć przycisk dodania do czarnej listy.", "In future this verification process will be more sophisticated.": "W przyszłości proces weryfikacji będzie bardziej skomplikowany.", @@ -618,7 +616,6 @@ "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Nastąpiła próba załadowania danego punktu w historii tego pokoju, lecz nie masz uprawnień, by zobaczyć określoną wiadomość.", "Use compact timeline layout": "Użyj kompaktowego stylu linii czasu", "You have enabled URL previews by default.": "Masz domyślnie włączone podglądy linków.", - "Opt out of analytics": "Zrezygnuj z analityk", "Please check your email to continue registration.": "Sprawdź swój e-mail, aby kontynuować rejestrację.", "Please enter the code it contains:": "Wpisz kod, który jest tam zawarty:", "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Jeśli nie ustawisz adresu e-mail, nie będzie możliwe zresetowanie Twojego hasła. Kontynuować?", diff --git a/src/i18n/strings/pt.json b/src/i18n/strings/pt.json index 229d4f32a1..d165c6c057 100644 --- a/src/i18n/strings/pt.json +++ b/src/i18n/strings/pt.json @@ -411,7 +411,6 @@ "Please select the destination room for this message": "Por favor, escolha a sala para onde quer encaminhar esta mensagem", "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s apagou o nome da sala.", "Analytics": "Análise", - "Opt out of analytics": "Sair da ferramenta de análise", "Options": "Opções", "Riot collects anonymous analytics to allow us to improve the application.": "Riot coleta informações anônimas de uso para nos permitir melhorar o sistema.", "Passphrases must match": "As senhas têm que ser iguais", @@ -433,8 +432,6 @@ "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Você tem certeza que quer apagar este evento? Note que se você apaga o nome de uma sala ou uma mudança de tópico, esta ação não poderá ser desfeita.", "Unknown error": "Erro desconhecido", "Incorrect password": "Senha incorreta", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Isso tornará a sua conta permanentemente inusável. Você não será capaz de registrar novamente o mesmo ID de usuário.", - "This action is irreversible.": "Esta ação é irreversível.", "To continue, please enter your password.": "Para continuar, por favor insira a sua senha.", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Para verificar que este dispositivo é confiável, por favor entre em contato com a(o) sua(seu) dona(o) usando outros meios, como por exemplo pessoalmente ou por uma chamada telefônica, e pergunte a esta pessoa se a chave que ela está vendo nas suas configurações de usuário para este dispositivo é igual a esta:", "Device name": "Nome do dispositivo", diff --git a/src/i18n/strings/pt_BR.json b/src/i18n/strings/pt_BR.json index a3333de2f2..0a4d847805 100644 --- a/src/i18n/strings/pt_BR.json +++ b/src/i18n/strings/pt_BR.json @@ -413,7 +413,6 @@ "Please select the destination room for this message": "Por favor, escolha a sala para onde quer encaminhar esta mensagem", "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s apagou o nome da sala.", "Analytics": "Análise", - "Opt out of analytics": "Sair da ferramenta de análise", "Options": "Opções", "Riot collects anonymous analytics to allow us to improve the application.": "Riot coleta informações anônimas de uso para nos permitir melhorar o sistema.", "Passphrases must match": "As senhas têm que ser iguais", @@ -435,8 +434,6 @@ "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Você tem certeza que quer apagar este evento? Note que se você apaga o nome de uma sala ou uma mudança de tópico, esta ação não poderá ser desfeita.", "Unknown error": "Erro desconhecido", "Incorrect password": "Senha incorreta", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Isso tornará a sua conta permanentemente inusável. Você não será capaz de registrar novamente o mesmo ID de usuário.", - "This action is irreversible.": "Esta ação é irreversível.", "To continue, please enter your password.": "Para continuar, por favor insira a sua senha.", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Para verificar que este dispositivo é confiável, por favor entre em contato com a(o) sua(seu) dona(o) usando outros meios, como por exemplo pessoalmente ou por uma chamada telefônica, e pergunte a esta pessoa se a chave que ela está vendo nas suas configurações de usuário para este dispositivo é igual a esta:", "Device name": "Nome do dispositivo", diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index ba21f51f10..0514c133be 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -384,7 +384,6 @@ "Start automatically after system login": "Автозапуск при входе в систему", "Analytics": "Аналитика", "Riot collects anonymous analytics to allow us to improve the application.": "Riot собирает анонимные данные, позволяющие нам улучшить приложение.", - "Opt out of analytics": "Не отправлять данные для аналитики", "Logged in as:": "Вы вошли как:", "Default Device": "Устройство по умолчанию", "No Webcams detected": "Веб-камера не обнаружена", @@ -482,8 +481,6 @@ "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Вы действительно хотите удалить это событие? Обратите внимание, что если это смена названия комнаты или темы, то удаление отменит это изменение.", "Unknown error": "Неизвестная ошибка", "Incorrect password": "Неверный пароль", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Ваша учетная запись будет заблокирована навсегда. Вы не сможете повторно зарегистрировать тот же идентификатор пользователя.", - "This action is irreversible.": "Это действие необратимо.", "To continue, please enter your password.": "Чтобы продолжить, введите ваш пароль.", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Чтобы удостовериться, что этому устройству можно доверять, пожалуйста, свяжитесь с владельцем другим способом (например, лично или по телефону) и спросите его, совпадает ли ключ, указанный у него в настройках для этого устройства, с ключом ниже:", "Device name": "Имя устройства", diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index 523cabaa68..c7f38cff35 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -591,8 +591,6 @@ "Unknown error": "Neznáma chyba", "Incorrect password": "Nesprávne heslo", "Deactivate Account": "Deaktivovať účet", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Toto spôsobí, že váš účet nebude viac použiteľný. Tak tiež si nebudete môcť znovu zaregistrovať rovnaké používateľské ID.", - "This action is irreversible.": "Túto akciu nie je možné vrátiť späť.", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Ak chcete overiť, či toto zariadenie je skutočne dôverihodné, kontaktujte jeho vlastníka iným spôsobom (napr. osobne alebo cez telefón) a opýtajte sa ho, či kľúč, ktorý má pre toto zariadenie zobrazený v nastaveniach sa zhoduje s kľúčom zobrazeným nižšie:", "Device name": "Názov zariadenia", "Device key": "Kľúč zariadenia", @@ -740,7 +738,6 @@ "Hide avatars in user and room mentions": "Skryť avatarov pri zmienkach miestností a používateľov", "Disable big emoji in chat": "Zakázať veľké Emoji v konverzácii", "Mirror local video feed": "Zrkadliť lokálne video", - "Opt out of analytics": "Odhlásiť sa zo zberu analytických údajov", "Disable Peer-to-Peer for 1:1 calls": "Zakázať P2P počas priamych volaní", "Never send encrypted messages to unverified devices from this device": "Z tohoto zariadenia nikdy neposielať šifrované správy neovereným zariadeniam", "Light theme": "Svetlá téma", diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json index dc39bb8cdd..ebacd28a5c 100644 --- a/src/i18n/strings/sr.json +++ b/src/i18n/strings/sr.json @@ -190,7 +190,6 @@ "Automatically replace plain text Emoji": "Самостално замени емоџије писане обичним текстом", "Mirror local video feed": "Копирај довод локалног видеа", "Disable Peer-to-Peer for 1:1 calls": "Онемогући парњаке за 1 на 1 позиве", - "Opt out of analytics": "Не учествуј у аналитици", "Never send encrypted messages to unverified devices from this device": "Никада не шаљи шифроване поруке са овог уређаја ка непровереним уређајима", "Never send encrypted messages to unverified devices in this room from this device": "Никада не шаљи шифроване поруке са овог уређаја ка непровереним уређајима у овој соби", "Enable inline URL previews by default": "Подразумевано омогући претпрегледе адреса унутар линије", @@ -662,8 +661,6 @@ "Unknown error": "Непозната грешка", "Incorrect password": "Нетачна лозинка", "Deactivate Account": "Угаси налог", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Ово ће учинити ваш налог трајно неупотребљивим. Нећете моћи да се поново региструјете са истим корисничким ИБ-јем.", - "This action is irreversible.": "Ова радња се не може поништити.", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Да бисте проверили да се овом уређају може веровати, контактирајте власника користећи друге начине (нпр.: лично или преко телефонског позива) и питајте га да ли се кључ који види у корисничким подешавањима подудара са кључем испод:", "Device name": "Назив уређаја", "Device key": "Кључ уређаја", diff --git a/src/i18n/strings/tr.json b/src/i18n/strings/tr.json index 451383bc02..797fed79ce 100644 --- a/src/i18n/strings/tr.json +++ b/src/i18n/strings/tr.json @@ -531,7 +531,6 @@ "Start automatically after system login": "Sisteme giriş yaptıktan sonra otomatik başlat", "Desktop specific": "Masaüstüne özgü", "Analytics": "Analitik", - "Opt out of analytics": "Analytics'ten çıkmak", "Options": "Seçenekler", "Riot collects anonymous analytics to allow us to improve the application.": "Riot , uygulamayı iyileştirmemize izin vermek için anonim analitik toplar.", "Passphrases must match": "Şifrenin eşleşmesi gerekir", @@ -554,8 +553,6 @@ "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Bu etkinliği kaldırmak(silmek) istediğinizden emin misiniz ? Bir odayı ismini silmeniz veya konu değiştirmeniz , geri alınabilir bir durumdur.", "Unknown error": "Bilinmeyen Hata", "Incorrect password": "Yanlış Şifre", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "Bu hesabınızı kalıcı olarak kullanılamaz yapılacak . Aynı kullanıcı ID ile yeniden Kayıt olamazsınız .", - "This action is irreversible.": "Bu eylem geri döndürülemez.", "To continue, please enter your password.": "Devam etmek için , lütfen şifrenizi girin.", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Bu cihazın güvenilir olabileceğini doğrulamak için , lütfen sahibiyle başka yollarla iletişim kurun (örn. şahsen veya telefon görüşmesi) ve bu cihazın Kullanıcı Ayarları'nda gördükleri anahtarın aşağıdaki anahtarla eşleşip eşleşmediğini sorun :", "Device name": "Cihaz ismi", diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index 45b7ea9e46..8e2dc6e0f8 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -351,7 +351,6 @@ "Failed to invite user": "邀请用户失败", "Unknown error": "未知错误", "Incorrect password": "密码错误", - "This action is irreversible.": "此操作不可逆。", "To continue, please enter your password.": "请输入你的密码继续。", "Device name": "设备名称", "Device Name": "设备名称", @@ -591,7 +590,6 @@ "You must join the room to see its files": "你必须加入聊天室以看到它的文件", "Failed to invite the following users to the %(roomName)s room:": "邀请以下用户到 %(roomName)s 聊天室失败:", "Confirm Removal": "确认移除", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "这将会导致您的账户永远无法使用。你将无法重新注册同样的用户 ID。", "Verifies a user, device, and pubkey tuple": "验证一个用户、设备和密钥元组", "Unknown devices": "未知设备", "Unknown Address": "未知地址", @@ -802,7 +800,6 @@ "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s 将他们的昵称修改成了 %(displayName)s 。", "Hide avatars in user and room mentions": "隐藏头像", "Disable Community Filter Panel": "停用社区面板", - "Opt out of analytics": "退出统计分析服务", "Stickerpack": "贴图集", "You don't currently have any stickerpacks enabled": "您目前没有启用任何贴纸包", "Add a stickerpack": "添加贴图集", diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index a2e8d669c9..2f571d3883 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -553,7 +553,6 @@ "Start automatically after system login": "在系統登入後自動開始", "Desktop specific": "桌面版特有", "Analytics": "分析", - "Opt out of analytics": "選擇退出分析", "Options": "選項", "Riot collects anonymous analytics to allow us to improve the application.": "Riot 會收集匿名分析以讓我們可以改進此應用程式。", "Passphrases must match": "通關密語必須符合", @@ -576,8 +575,6 @@ "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "您確定您想要移除(刪除)此活動嗎?注意若您刪除房間名稱或主題變更,還是可以復原變更。", "Unknown error": "未知的錯誤", "Incorrect password": "不正確的密碼", - "This will make your account permanently unusable. You will not be able to re-register the same user ID.": "這將會讓您的帳號永遠無法使用。您將無法重新註冊相同的使用者 ID。", - "This action is irreversible.": "此動作是不可逆的。", "To continue, please enter your password.": "要繼續,請輸入您的密碼。", "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "要驗證此裝置是否可信,請使用其他方式(例如:面對面或是打電話)聯絡它的擁有者並詢問他們在使用者設定中看到此裝置的金鑰是否與下列的金鑰相符:", "Device name": "裝置名稱", From 6f77b8ae26bc939822e75f9bb448d5d257c645e7 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 24 May 2018 12:46:06 +0100 Subject: [PATCH 1159/1160] Modify showDetailsModal to give examples if analytics is not enabled --- src/Analytics.js | 25 ++++++++++++++++++++++--- src/i18n/strings/en_EN.json | 1 + 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/Analytics.js b/src/Analytics.js index ec8234eb83..8ffce7077f 100644 --- a/src/Analytics.js +++ b/src/Analytics.js @@ -49,34 +49,42 @@ const customVariables = { 'App Platform': { id: 1, expl: _td('The platform you\'re on'), + example: 'Electron Platform', }, 'App Version': { id: 2, expl: _td('The version of Riot.im'), + example: '15.0.0', }, 'User Type': { id: 3, expl: _td('Whether or not you\'re logged in (we don\'t record your user name)'), + example: 'Logged In', }, 'Chosen Language': { id: 4, expl: _td('Your language of choice'), + example: 'en', }, 'Instance': { id: 5, expl: _td('Which officially provided instance you are using, if any'), + example: 'app', }, 'RTE: Uses Richtext Mode': { id: 6, expl: _td('Whether or not you\'re using the Richtext mode of the Rich Text Editor'), + example: 'off', }, 'Homeserver URL': { id: 7, expl: _td('Your homeserver\'s URL'), + example: 'https://matrix.org', }, 'Identity Server URL': { id: 8, expl: _td('Your identity server\'s URL'), + example: 'https://vector.im', }, }; @@ -218,8 +226,19 @@ class Analytics { } showDetailsModal() { - const Tracker = window.Piwik.getAsyncTracker(); - const rows = Object.values(customVariables).map((v) => Tracker.getCustomVariable(v.id)).filter(Boolean); + let rows = []; + if (window.Piwik) { + const Tracker = window.Piwik.getAsyncTracker(); + rows = Object.values(customVariables).map((v) => Tracker.getCustomVariable(v.id)).filter(Boolean); + } else { + // Piwik may not have been enabled, so show example values + rows = Object.keys(customVariables).map( + (k) => [ + k, + _t('e.g. %(exampleValue)s', { exampleValue: customVariables[k].example }), + ], + ); + } const resolution = `${window.screen.width}x${window.screen.height}`; const otherVariables = [ @@ -247,7 +266,7 @@ class Analytics { { rows.map((row) => - + { row[1] !== undefined && } ) } { otherVariables.map((item, index) => diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 8dc5b8e630..8bacc3557e 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -10,6 +10,7 @@ "Whether or not you're using the Richtext mode of the Rich Text Editor": "Whether or not you're using the Richtext mode of the Rich Text Editor", "Your homeserver's URL": "Your homeserver's URL", "Your identity server's URL": "Your identity server's URL", + "e.g. %(exampleValue)s": "e.g. %(exampleValue)s", "Every page you use in the app": "Every page you use in the app", "e.g. ": "e.g. ", "Your User Agent": "Your User Agent", From aae89efa017c41a5728d09366cf19ea8712c0ef0 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 24 May 2018 12:47:27 +0100 Subject: [PATCH 1160/1160] Add usage data link to cookie bar this opens the analytics modal --- src/components/views/globals/CookieBar.js | 14 +++++++++++++- src/i18n/strings/en_EN.json | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/components/views/globals/CookieBar.js b/src/components/views/globals/CookieBar.js index 8fab64be67..ad00884dd2 100644 --- a/src/components/views/globals/CookieBar.js +++ b/src/components/views/globals/CookieBar.js @@ -19,6 +19,7 @@ import PropTypes from 'prop-types'; import dis from '../../../dispatcher'; import { _t } from '../../../languageHandler'; import sdk from '../../../index'; +import Analytics from '../../../Analytics'; export default class CookieBar extends React.Component { static propTypes = { @@ -29,6 +30,10 @@ export default class CookieBar extends React.Component { super(); } + onUsageDataClicked() { + Analytics.showDetailsModal(); + } + onAccept() { dis.dispatch({ action: 'accept_cookies', @@ -49,11 +54,18 @@ export default class CookieBar extends React.Component { Warning
    { this.props.policyUrl ? _t( - "Help improve Riot by sending usage data? " + + "Help improve Riot by sending usage data? " + "This will use a cookie. " + "(See our cookie and privacy policies).", {}, { + 'UsageDataLink': (sub) => + { sub } + , // XXX: We need to link to the page that explains our cookies 'PolicyLink': (sub) => cookie and privacy policies).": "Help improve Riot by sending usage data? This will use a cookie. (See our cookie and privacy policies).", + "Help improve Riot by sending usage data? This will use a cookie. (See our cookie and privacy policies).": "Help improve Riot by sending usage data? This will use a cookie. (See our cookie and privacy policies).", "Help improve Riot by sending usage data? This will use a cookie.": "Help improve Riot by sending usage data? This will use a cookie.", "Yes please": "Yes please", "You are not receiving desktop notifications": "You are not receiving desktop notifications",
    { _t(customVariables[row[0]].expl) }{ row[1] }{ row[1] }