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) diff --git a/package.json b/package.json index f81e72e556..bb8db64d28 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": { 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); 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, 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/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, }); 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 }
; } 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/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 diff --git a/src/components/structures/TagPanel.js b/src/components/structures/TagPanel.js index c843c08ce9..6e3bcf521b 100644 --- a/src/components/structures/TagPanel.js +++ b/src/components/structures/TagPanel.js @@ -43,6 +43,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) { @@ -60,6 +61,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(); } @@ -70,6 +72,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; @@ -82,8 +94,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) => { @@ -114,9 +125,9 @@ const TagPanel = React.createClass({
) } - - - +
+ +
; }, }); 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(); }); 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/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index 8e6f944df3..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. @@ -37,6 +40,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, @@ -48,7 +54,24 @@ 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); + } if (e.keyCode === KeyCode.ESCAPE) { e.stopPropagation(); e.preventDefault(); 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/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(), }); diff --git a/src/components/views/voip/IncomingCallBox.js b/src/components/views/voip/IncomingCallBox.js index 8d75029baa..6cbaabe602 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 sdk from '../../../index'; 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, @@ -59,6 +63,7 @@ module.exports = React.createClass({ } } + const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); return (
@@ -67,14 +72,14 @@ module.exports = React.createClass({
-
+ { _t("Decline") } -
+
-
+ { _t("Accept") } -
+
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": "現在重新傳送訊息取消訊息。", 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, ); 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; +}