diff --git a/CHANGELOG.md b/CHANGELOG.md index ed6fb3ba36..22049b6af6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,104 @@ +Changes in [0.9.6](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.9.6) (2017-06-20) +=================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.9.5...v0.9.6) + + * Fix infinite spinner on email registration + [\#1120](https://github.com/matrix-org/matrix-react-sdk/pull/1120) + * Translate help promots in room list + [\#1121](https://github.com/matrix-org/matrix-react-sdk/pull/1121) + * Internationalise the drop targets + [\#1122](https://github.com/matrix-org/matrix-react-sdk/pull/1122) + * Fix another infinite spin on register + [\#1124](https://github.com/matrix-org/matrix-react-sdk/pull/1124) + + +Changes in [0.9.5](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.9.5) (2017-06-19) +=================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.9.5-rc.2...v0.9.5) + + * Don't peek when creating a room + [\#1113](https://github.com/matrix-org/matrix-react-sdk/pull/1113) + * More translations & translation fixes + + +Changes in [0.9.5-rc.2](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.9.5-rc.2) (2017-06-16) +============================================================================================================= +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.9.5-rc.1...v0.9.5-rc.2) + + * Avoid getting stuck in a loop in CAS login + [\#1109](https://github.com/matrix-org/matrix-react-sdk/pull/1109) + * Update from Weblate. + [\#1101](https://github.com/matrix-org/matrix-react-sdk/pull/1101) + * Correctly inspect state when rejecting invite + [\#1108](https://github.com/matrix-org/matrix-react-sdk/pull/1108) + * Make sure to pass the roomAlias to the preview header if we have it + [\#1107](https://github.com/matrix-org/matrix-react-sdk/pull/1107) + * Make sure captcha disappears when container does + [\#1106](https://github.com/matrix-org/matrix-react-sdk/pull/1106) + * Fix URL previews + [\#1105](https://github.com/matrix-org/matrix-react-sdk/pull/1105) + +Changes in [0.9.5-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.9.5-rc.1) (2017-06-15) +============================================================================================================= +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.9.4...v0.9.5-rc.1) + + * Groundwork for tests including a teamserver login + [\#1098](https://github.com/matrix-org/matrix-react-sdk/pull/1098) + * Show a spinner when accepting an invite and waitingForRoom + [\#1100](https://github.com/matrix-org/matrix-react-sdk/pull/1100) + * Display a spinner until new room object after join success + [\#1099](https://github.com/matrix-org/matrix-react-sdk/pull/1099) + * Luke/attempt fix peeking regression + [\#1097](https://github.com/matrix-org/matrix-react-sdk/pull/1097) + * Show correct text in set email password dialog (2) + [\#1096](https://github.com/matrix-org/matrix-react-sdk/pull/1096) + * Don't create a guest login if user went to /login + [\#1092](https://github.com/matrix-org/matrix-react-sdk/pull/1092) + * Give password confirmation correct title, description + [\#1095](https://github.com/matrix-org/matrix-react-sdk/pull/1095) + * Make enter submit change password form + [\#1094](https://github.com/matrix-org/matrix-react-sdk/pull/1094) + * When not specified, remove roomAlias state in RoomViewStore + [\#1093](https://github.com/matrix-org/matrix-react-sdk/pull/1093) + * Update from Weblate. + [\#1091](https://github.com/matrix-org/matrix-react-sdk/pull/1091) + * Fixed pagination infinite loop caused by long messages + [\#1045](https://github.com/matrix-org/matrix-react-sdk/pull/1045) + * Clear persistent storage on login and logout + [\#1085](https://github.com/matrix-org/matrix-react-sdk/pull/1085) + * DM guessing: prefer oldest joined member + [\#1087](https://github.com/matrix-org/matrix-react-sdk/pull/1087) + * Ask for email address after setting password for the first time + [\#1090](https://github.com/matrix-org/matrix-react-sdk/pull/1090) + * i18n for setting password flow + [\#1089](https://github.com/matrix-org/matrix-react-sdk/pull/1089) + * remove mx_filterFlipColor from verified e2e icon so its not purple :/ + [\#1088](https://github.com/matrix-org/matrix-react-sdk/pull/1088) + * width and height must be int otherwise synapse cries + [\#1083](https://github.com/matrix-org/matrix-react-sdk/pull/1083) + * remove RoomViewStore listener from MatrixChat on unmount + [\#1084](https://github.com/matrix-org/matrix-react-sdk/pull/1084) + * Add script to copy translations between files + [\#1082](https://github.com/matrix-org/matrix-react-sdk/pull/1082) + * Only process user_directory response if it's for the current query + [\#1081](https://github.com/matrix-org/matrix-react-sdk/pull/1081) + * Fix regressions with starting a 1-1. + [\#1080](https://github.com/matrix-org/matrix-react-sdk/pull/1080) + * allow forcing of TURN + [\#1079](https://github.com/matrix-org/matrix-react-sdk/pull/1079) + * Remove a bunch of dead code from react-sdk + [\#1077](https://github.com/matrix-org/matrix-react-sdk/pull/1077) + * Improve error logging/reporting in megolm import/export + [\#1061](https://github.com/matrix-org/matrix-react-sdk/pull/1061) + * Delinting + [\#1064](https://github.com/matrix-org/matrix-react-sdk/pull/1064) + * Show reason for a call hanging up unexpectedly. + [\#1071](https://github.com/matrix-org/matrix-react-sdk/pull/1071) + * Add reason for ban in room settings + [\#1072](https://github.com/matrix-org/matrix-react-sdk/pull/1072) + * adds mx_filterFlipColor so that the dark theme will invert this image + [\#1070](https://github.com/matrix-org/matrix-react-sdk/pull/1070) + Changes in [0.9.4](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.9.4) (2017-06-14) =================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.9.3...v0.9.4) diff --git a/package.json b/package.json index 151b6d6170..f49fc04661 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.9.4", + "version": "0.9.6", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { @@ -64,7 +64,7 @@ "isomorphic-fetch": "^2.2.1", "linkifyjs": "^2.1.3", "lodash": "^4.13.1", - "matrix-js-sdk": "0.7.11", + "matrix-js-sdk": "0.7.12", "optimist": "^0.6.1", "prop-types": "^15.5.8", "q": "^1.4.1", diff --git a/src/KeyRequestHandler.js b/src/KeyRequestHandler.js new file mode 100644 index 0000000000..1da4922153 --- /dev/null +++ b/src/KeyRequestHandler.js @@ -0,0 +1,138 @@ +/* +Copyright 2017 Vector Creations Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import sdk from './index'; +import Modal from './Modal'; + +export default class KeyRequestHandler { + constructor(matrixClient) { + this._matrixClient = matrixClient; + + // the user/device for which we currently have a dialog open + this._currentUser = null; + this._currentDevice = null; + + // userId -> deviceId -> [keyRequest] + this._pendingKeyRequests = Object.create(null); + } + + handleKeyRequest(keyRequest) { + const userId = keyRequest.userId; + const deviceId = keyRequest.deviceId; + const requestId = keyRequest.requestId; + + if (!this._pendingKeyRequests[userId]) { + this._pendingKeyRequests[userId] = Object.create(null); + } + if (!this._pendingKeyRequests[userId][deviceId]) { + this._pendingKeyRequests[userId][deviceId] = []; + } + + // check if we already have this request + const requests = this._pendingKeyRequests[userId][deviceId]; + if (requests.find((r) => r.requestId === requestId)) { + console.log("Already have this key request, ignoring"); + return; + } + + requests.push(keyRequest); + + if (this._currentUser) { + // ignore for now + console.log("Key request, but we already have a dialog open"); + return; + } + + this._processNextRequest(); + } + + handleKeyRequestCancellation(cancellation) { + // see if we can find the request in the queue + const userId = cancellation.userId; + const deviceId = cancellation.deviceId; + const requestId = cancellation.requestId; + + if (userId === this._currentUser && deviceId === this._currentDevice) { + console.log( + "room key request cancellation for the user we currently have a" + + " dialog open for", + ); + // TODO: update the dialog. For now, we just ignore the + // cancellation. + return; + } + + if (!this._pendingKeyRequests[userId]) { + return; + } + const requests = this._pendingKeyRequests[userId][deviceId]; + if (!requests) { + return; + } + const idx = requests.findIndex((r) => r.requestId === requestId); + if (idx < 0) { + return; + } + console.log("Forgetting room key request"); + requests.splice(idx, 1); + if (requests.length === 0) { + delete this._pendingKeyRequests[userId][deviceId]; + if (Object.keys(this._pendingKeyRequests[userId]).length === 0) { + delete this._pendingKeyRequests[userId]; + } + } + } + + _processNextRequest() { + const userId = Object.keys(this._pendingKeyRequests)[0]; + if (!userId) { + return; + } + const deviceId = Object.keys(this._pendingKeyRequests[userId])[0]; + if (!deviceId) { + return; + } + console.log(`Starting KeyShareDialog for ${userId}:${deviceId}`); + + const finished = (r) => { + this._currentUser = null; + this._currentDevice = null; + + if (r) { + for (const req of this._pendingKeyRequests[userId][deviceId]) { + req.share(); + } + } + delete this._pendingKeyRequests[userId][deviceId]; + if (Object.keys(this._pendingKeyRequests[userId]).length === 0) { + delete this._pendingKeyRequests[userId]; + } + + this._processNextRequest(); + }; + + const KeyShareDialog = sdk.getComponent("dialogs.KeyShareDialog"); + Modal.createDialog(KeyShareDialog, { + matrixClient: this._matrixClient, + userId: userId, + deviceId: deviceId, + onFinished: finished, + }); + this._currentUser = userId; + this._currentDevice = deviceId; + } +} + diff --git a/src/Lifecycle.js b/src/Lifecycle.js index 39a159869c..59580e7cb6 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -35,26 +35,20 @@ import { _t } from './languageHandler'; * Called at startup, to attempt to build a logged-in Matrix session. It tries * a number of things: * - * 1. if we have a loginToken in the (real) query params, it uses that to log - * in. * - * 2. if we have a guest access token in the fragment query params, it uses + * 1. if we have a guest access token in the fragment query params, it uses * that. * - * 3. if an access token is stored in local storage (from a previous session), + * 2. if an access token is stored in local storage (from a previous session), * it uses that. * - * 4. it attempts to auto-register as a guest user. + * 3. it attempts to auto-register as a guest user. * * If any of steps 1-4 are successful, it will call {_doSetLoggedIn}, which in * turn will raise on_logged_in and will_start_client events. * * @param {object} opts * - * @param {object} opts.realQueryParams: string->string map of the - * query-parameters extracted from the real query-string of the starting - * URI. - * * @param {object} opts.fragmentQueryParams: string->string map of the * query-parameters extracted from the #-fragment of the starting URI. * @@ -68,9 +62,10 @@ import { _t } from './languageHandler'; * true; defines the IS to use. * * @returns {Promise} a promise which resolves when the above process completes. + * Resolves to `true` if we ended up starting a session, or `false` if we + * failed. */ export function loadSession(opts) { - const realQueryParams = opts.realQueryParams || {}; const fragmentQueryParams = opts.fragmentQueryParams || {}; let enableGuest = opts.enableGuest || false; const guestHsUrl = opts.guestHsUrl; @@ -82,14 +77,6 @@ export function loadSession(opts) { enableGuest = false; } - if (realQueryParams.loginToken) { - if (!realQueryParams.homeserver) { - console.warn("Cannot log in with token: can't determine HS URL to use"); - } else { - return _loginWithToken(realQueryParams, defaultDeviceDisplayName); - } - } - if (enableGuest && fragmentQueryParams.guest_user_id && fragmentQueryParams.guest_access_token @@ -101,12 +88,12 @@ export function loadSession(opts) { homeserverUrl: guestHsUrl, identityServerUrl: guestIsUrl, guest: true, - }, true); + }, true).then(() => true); } return _restoreFromLocalStorage().then((success) => { if (success) { - return; + return true; } if (enableGuest) { @@ -114,10 +101,30 @@ export function loadSession(opts) { } // fall back to login screen + return false; }); } -function _loginWithToken(queryParams, defaultDeviceDisplayName) { +/** + * @param {Object} queryParams string->string map of the + * query-parameters extracted from the real query-string of the starting + * URI. + * + * @param {String} defaultDeviceDisplayName + * + * @returns {Promise} promise which resolves to true if we completed the token + * login, else false + */ +export function attemptTokenLogin(queryParams, defaultDeviceDisplayName) { + if (!queryParams.loginToken) { + return q(false); + } + + if (!queryParams.homeserver) { + console.warn("Cannot log in with token: can't determine HS URL to use"); + return q(false); + } + // create a temporary MatrixClient to do the login const client = Matrix.createClient({ baseUrl: queryParams.homeserver, @@ -130,17 +137,21 @@ function _loginWithToken(queryParams, defaultDeviceDisplayName) { }, ).then(function(data) { console.log("Logged in with token"); - return _doSetLoggedIn({ - userId: data.user_id, - deviceId: data.device_id, - accessToken: data.access_token, - homeserverUrl: queryParams.homeserver, - identityServerUrl: queryParams.identityServer, - guest: false, - }, true); - }, (err) => { + return _clearStorage().then(() => { + _persistCredentialsToLocalStorage({ + userId: data.user_id, + deviceId: data.device_id, + accessToken: data.access_token, + homeserverUrl: queryParams.homeserver, + identityServerUrl: queryParams.identityServer, + guest: false, + }); + return true; + }); + }).catch((err) => { console.error("Failed to log in with login token: " + err + " " + err.data); + return false; }); } @@ -168,9 +179,10 @@ function _registerAsGuest(hsUrl, isUrl, defaultDeviceDisplayName) { homeserverUrl: hsUrl, identityServerUrl: isUrl, guest: true, - }, true); + }, true).then(() => true); }, (err) => { console.error("Failed to register as guest: " + err + " " + err.data); + return false; }); } @@ -282,10 +294,12 @@ export function initRtsClient(url) { * storage before starting the new client. * * @param {MatrixClientCreds} credentials The credentials to use + * + * @returns {Promise} promise which resolves to the new MatrixClient once it has been started */ export function setLoggedIn(credentials) { stopMatrixClient(); - _doSetLoggedIn(credentials, true); + return _doSetLoggedIn(credentials, true); } /** @@ -295,7 +309,7 @@ export function setLoggedIn(credentials) { * @param {MatrixClientCreds} credentials * @param {Boolean} clearStorage * - * returns a Promise which resolves once the client has been started + * @returns {Promise} promise which resolves to the new MatrixClient once it has been started */ async function _doSetLoggedIn(credentials, clearStorage) { credentials.guest = Boolean(credentials.guest); @@ -322,23 +336,10 @@ async function _doSetLoggedIn(credentials, clearStorage) { // Resolves by default let teamPromise = Promise.resolve(null); - // persist the session + if (localStorage) { try { - localStorage.setItem("mx_hs_url", credentials.homeserverUrl); - localStorage.setItem("mx_is_url", credentials.identityServerUrl); - localStorage.setItem("mx_user_id", credentials.userId); - localStorage.setItem("mx_access_token", credentials.accessToken); - localStorage.setItem("mx_is_guest", JSON.stringify(credentials.guest)); - - // if we didn't get a deviceId from the login, leave mx_device_id unset, - // rather than setting it to "undefined". - // - // (in this case MatrixClient doesn't bother with the crypto stuff - // - that's fine for us). - if (credentials.deviceId) { - localStorage.setItem("mx_device_id", credentials.deviceId); - } + _persistCredentialsToLocalStorage(credentials); // The user registered as a PWLU (PassWord-Less User), the generated password // is cached here such that the user can change it at a later time. @@ -349,8 +350,6 @@ async function _doSetLoggedIn(credentials, clearStorage) { cachedPassword: credentials.password, }); } - - console.log("Session persisted for %s", credentials.userId); } catch (e) { console.warn("Error using local storage: can't persist session!", e); } @@ -377,6 +376,26 @@ async function _doSetLoggedIn(credentials, clearStorage) { }); startMatrixClient(); + return MatrixClientPeg.get(); +} + +function _persistCredentialsToLocalStorage(credentials) { + localStorage.setItem("mx_hs_url", credentials.homeserverUrl); + localStorage.setItem("mx_is_url", credentials.identityServerUrl); + localStorage.setItem("mx_user_id", credentials.userId); + localStorage.setItem("mx_access_token", credentials.accessToken); + localStorage.setItem("mx_is_guest", JSON.stringify(credentials.guest)); + + // if we didn't get a deviceId from the login, leave mx_device_id unset, + // rather than setting it to "undefined". + // + // (in this case MatrixClient doesn't bother with the crypto stuff + // - that's fine for us). + if (credentials.deviceId) { + localStorage.setItem("mx_device_id", credentials.deviceId); + } + + console.log("Session persisted for %s", credentials.userId); } /** diff --git a/src/components/structures/LoggedInView.js b/src/components/structures/LoggedInView.js index 8fa35e84d7..8b0bcaad68 100644 --- a/src/components/structures/LoggedInView.js +++ b/src/components/structures/LoggedInView.js @@ -239,7 +239,6 @@ export default React.createClass({ page_element = {}, + onTokenLoginCompleted: () => {}, }; }, @@ -266,39 +296,49 @@ module.exports = React.createClass({ const teamServerConfig = this.props.config.teamServerConfig || {}; Lifecycle.initRtsClient(teamServerConfig.teamServerURL); - // if the user has followed a login or register link, don't reanimate - // the old creds, but rather go straight to the relevant page + // the first thing to do is to try the token params in the query-string + Lifecycle.attemptTokenLogin(this.props.realQueryParams).then((loggedIn) => { + if(loggedIn) { + this.props.onTokenLoginCompleted(); - const firstScreen = this.state.screenAfterLogin ? - this.state.screenAfterLogin.screen : null; + // don't do anything else until the page reloads - just stay in + // the 'loading' state. + return; + } - if (firstScreen === 'login' || - firstScreen === 'register' || - firstScreen === 'forgot_password') { - this.props.onLoadCompleted(); - this.setState({loading: false}); - this._showScreenAfterLogin(); - return; - } + // if the user has followed a login or register link, don't reanimate + // the old creds, but rather go straight to the relevant page + const firstScreen = this.state.screenAfterLogin ? + this.state.screenAfterLogin.screen : null; - // the extra q() ensures that synchronous exceptions hit the same codepath as - // asynchronous ones. - q().then(() => { - return Lifecycle.loadSession({ - realQueryParams: this.props.realQueryParams, - fragmentQueryParams: this.props.startingFragmentQueryParams, - enableGuest: this.props.enableGuest, - guestHsUrl: this.getCurrentHsUrl(), - guestIsUrl: this.getCurrentIsUrl(), - defaultDeviceDisplayName: this.props.defaultDeviceDisplayName, + if (firstScreen === 'login' || + firstScreen === 'register' || + firstScreen === 'forgot_password') { + this.setState({loading: false}); + this._showScreenAfterLogin(); + return; + } + + // the extra q() ensures that synchronous exceptions hit the same codepath as + // asynchronous ones. + return q().then(() => { + return Lifecycle.loadSession({ + fragmentQueryParams: this.props.startingFragmentQueryParams, + enableGuest: this.props.enableGuest, + guestHsUrl: this.getCurrentHsUrl(), + guestIsUrl: this.getCurrentIsUrl(), + defaultDeviceDisplayName: this.props.defaultDeviceDisplayName, + }); + }).catch((e) => { + console.error("Unable to load session", e); + return false; + }).then((loadedSession) => { + if (!loadedSession) { + // fall back to showing the login screen + dis.dispatch({action: "start_login"}); + } }); - }).catch((e) => { - console.error("Unable to load session", e); - }).done(()=>{ - // stuff this through the dispatcher so that it happens - // after the on_logged_in action. - dis.dispatch({action: 'load_completed'}); - }); + }).done(); }, componentWillUnmount: function() { @@ -317,18 +357,19 @@ module.exports = React.createClass({ } }, - setStateForNewScreen: function(state) { + setStateForNewView: function(state) { + if (state.view === undefined) { + throw new Error("setStateForNewView with no view!"); + } const newState = { - screen: undefined, viewUserId: null, - loggedIn: false, - ready: false, }; Object.assign(newState, state); this.setState(newState); }, onAction: function(payload) { + // console.log(`MatrixClientPeg.onAction: ${payload.action}`); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); @@ -340,26 +381,19 @@ module.exports = React.createClass({ this._startRegistration(payload.params || {}); break; case 'start_login': - if (MatrixClientPeg.get() && - MatrixClientPeg.get().isGuest() - ) { - this.setState({ - guestCreds: MatrixClientPeg.getCredentials(), - }); - } - this.setStateForNewScreen({ - screen: 'login', + this.setStateForNewView({ + view: VIEWS.LOGIN, }); this.notifyNewScreen('login'); break; case 'start_post_registration': - this.setState({ // don't clobber loggedIn status - screen: 'post_registration', + this.setState({ + view: VIEWS.POST_REGISTRATION, }); break; case 'start_password_recovery': - this.setStateForNewScreen({ - screen: 'forgot_password', + this.setStateForNewView({ + view: VIEWS.FORGOT_PASSWORD, }); this.notifyNewScreen('forgot_password'); break; @@ -500,10 +534,11 @@ module.exports = React.createClass({ break; case 'on_logging_in': // We are now logging in, so set the state to reflect that - // and also that we're not ready (we'll be marked as logged - // in once the login completes, then ready once the sync - // completes). - this.setState({loggingIn: true, ready: false}); + // NB. This does not touch 'ready' since if our dispatches + // are delayed, the sync could already have completed + this.setStateForNewView({ + view: VIEWS.LOGGING_IN, + }); break; case 'on_logged_in': this._onLoggedIn(payload.teamToken); @@ -514,15 +549,15 @@ module.exports = React.createClass({ case 'will_start_client': this._onWillStartClient(); break; - case 'load_completed': - this._onLoadCompleted(); - break; case 'new_version': this.onVersion( payload.currentVersion, payload.newVersion, payload.releaseNotes, ); break; + case 'send_event': + this.onSendEvent(payload.room_id, payload.event); + break; } }, @@ -537,8 +572,8 @@ module.exports = React.createClass({ }, _startRegistration: function(params) { - this.setStateForNewScreen({ - screen: 'register', + this.setStateForNewView({ + 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 @@ -846,14 +881,6 @@ module.exports = React.createClass({ }); }, - /** - * Called when the sessionloader has finished - */ - _onLoadCompleted: function() { - this.props.onLoadCompleted(); - this.setState({loading: false}); - }, - /** * Called whenever someone changes the theme * @@ -906,9 +933,7 @@ module.exports = React.createClass({ */ _onLoggedIn: function(teamToken) { this.setState({ - guestCreds: null, - loggedIn: true, - loggingIn: false, + view: VIEWS.LOGGED_IN, }); if (teamToken) { @@ -970,8 +995,8 @@ module.exports = React.createClass({ _onLoggedOut: function() { this._setPageSubtitle(); this.notifyNewScreen('login'); - this.setStateForNewScreen({ - loggedIn: false, + this.setStateForNewView({ + view: VIEWS.LOGIN, ready: false, collapse_lhs: false, collapse_rhs: false, @@ -987,6 +1012,10 @@ module.exports = React.createClass({ */ _onWillStartClient() { const self = this; + // if the client is about to start, we are, by definition, not ready. + // Set ready to false now, then it'll be set to true when the sync + // listener we set below fires. + this.setState({ready: false}); const cli = MatrixClientPeg.get(); // Allow the JS SDK to reap timeline events. This reduces the amount of @@ -1057,6 +1086,14 @@ module.exports = React.createClass({ } } }); + + const krh = new KeyRequestHandler(cli); + cli.on("crypto.roomKeyRequest", (req) => { + krh.handleKeyRequest(req); + }); + cli.on("crypto.roomKeyRequestCancellation", (req) => { + krh.handleKeyRequestCancellation(req); + }); }, showScreen: function(screen, params) { @@ -1134,7 +1171,7 @@ module.exports = React.createClass({ // we can't view a room unless we're logged in // (a guest account is fine) - if (this.state.loggedIn) { + if (this.state.view === VIEWS.LOGGED_IN) { dis.dispatch(payload); } } else if (screen.indexOf('user/') == 0) { @@ -1232,29 +1269,25 @@ module.exports = React.createClass({ this.showScreen("forgot_password"); }, - onReturnToGuestClick: function() { - // reanimate our guest login - if (this.state.guestCreds) { - // TODO: this is probably a bit broken - we don't want to be - // clearing storage when we reanimate the guest creds. - Lifecycle.setLoggedIn(this.state.guestCreds); - this.setState({guestCreds: null}); - } + onReturnToAppClick: function() { + // treat it the same as if the user had completed the login + this._onLoggedIn(null); }, + // returns a promise which resolves to the new MatrixClient onRegistered: function(credentials, teamToken) { // XXX: These both should be in state or ideally store(s) because we risk not // rendering the most up-to-date view of state otherwise. // teamToken may not be truthy this._teamToken = teamToken; this._is_registered = true; - Lifecycle.setLoggedIn(credentials); + return Lifecycle.setLoggedIn(credentials); }, onFinishPostRegistration: function() { // Don't confuse this with "PageType" which is the middle window to show this.setState({ - screen: undefined, + view: VIEWS.LOGGED_IN, }); this.showScreen("settings"); }, @@ -1268,6 +1301,27 @@ module.exports = React.createClass({ }); }, + onSendEvent: function(roomId, event) { + const cli = MatrixClientPeg.get(); + if (!cli) { + dis.dispatch({action: 'message_send_failed'}); + return; + } + + cli.sendEvent(roomId, event.getType(), event.getContent()).done(() => { + dis.dispatch({action: 'message_sent'}); + }, (err) => { + if (err.name === 'UnknownDeviceError') { + dis.dispatch({ + action: 'unknown_device_error', + err: err, + room: cli.getRoom(roomId), + }); + } + dis.dispatch({action: 'message_send_failed'}); + }); + }, + _setPageSubtitle: function(subtitle='') { document.title = `Riot ${subtitle}`; }, @@ -1326,11 +1380,9 @@ module.exports = React.createClass({ }, render: function() { - // `loading` might be set to false before `loggedIn = true`, causing the default - // (``) to be visible for a few MS (say, whilst a request is in-flight to - // the RTS). So in the meantime, use `loggingIn`, which is true between - // actions `on_logging_in` and `on_logged_in`. - if (this.state.loading || this.state.loggingIn) { + // console.log(`Rendering MatrixChat with view ${this.state.view}`); + + if (this.state.view === VIEWS.LOADING || this.state.view === VIEWS.LOGGING_IN) { const Spinner = sdk.getComponent('elements.Spinner'); return (
@@ -1340,7 +1392,7 @@ module.exports = React.createClass({ } // needs to be before normal PageTypes as you are logged in technically - if (this.state.screen == 'post_registration') { + if (this.state.view === VIEWS.POST_REGISTRATION) { const PostRegistration = sdk.getComponent('structures.login.PostRegistration'); return ( - ); - } else if (this.state.loggedIn) { - // we think we are logged in, but are still waiting for the /sync to complete - const Spinner = sdk.getComponent('elements.Spinner'); - return ( -
- - - { _t('Logout') } - -
- ); - } else if (this.state.screen == 'register') { + if (this.state.view === VIEWS.LOGGED_IN) { + // `ready` and `view==LOGGED_IN` may be set before `page_type` (because the + // latter is set via the dispatcher). If we don't yet have a `page_type`, + // keep showing the spinner for now. + if (this.state.ready && this.state.page_type) { + /* for now, we stuff the entirety of our props and state into the LoggedInView. + * we should go through and figure out what we actually need to pass down, as well + * as using something like redux to avoid having a billion bits of state kicking around. + */ + const LoggedInView = sdk.getComponent('structures.LoggedInView'); + return ( + + ); + } else { + // we think we are logged in, but are still waiting for the /sync to complete + const Spinner = sdk.getComponent('elements.Spinner'); + return ( + + ); + } + } + + if (this.state.view === VIEWS.REGISTER) { const Registration = sdk.getComponent('structures.login.Registration'); return ( ); - } else if (this.state.screen == 'forgot_password') { + } + + + if (this.state.view === VIEWS.FORGOT_PASSWORD) { const ForgotPassword = sdk.getComponent('structures.login.ForgotPassword'); return ( ); - } else { + } + + if (this.state.view === VIEWS.LOGIN) { const Login = sdk.getComponent('structures.login.Login'); return ( ); } + + console.error(`Unknown view ${this.state.view}`); }, }); diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 9306008e71..b29b3579f0 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -93,6 +93,7 @@ module.exports = React.createClass({ roomId: null, roomLoading: true, peekLoading: false, + shouldPeek: true, // The event to be scrolled to initially initialEventId: null, @@ -168,8 +169,14 @@ module.exports = React.createClass({ initialEventId: RoomViewStore.getInitialEventId(), initialEventPixelOffset: RoomViewStore.getInitialEventPixelOffset(), isInitialEventHighlighted: RoomViewStore.isInitialEventHighlighted(), + forwardingEvent: RoomViewStore.getForwardingEvent(), + shouldPeek: RoomViewStore.shouldPeek(), }; + // finished joining, start waiting for a room and show a spinner. See onRoom. + newState.waitingForRoom = this.state.joining && !newState.joining && + !RoomViewStore.getJoinError(); + // Temporary logging to diagnose https://github.com/vector-im/riot-web/issues/4307 console.log( 'RVS update:', @@ -177,12 +184,11 @@ module.exports = React.createClass({ newState.roomAlias, 'loading?', newState.roomLoading, 'joining?', newState.joining, + 'initial?', initial, + 'waiting?', newState.waitingForRoom, + 'shouldPeek?', newState.shouldPeek, ); - // finished joining, start waiting for a room and show a spinner. See onRoom. - newState.waitingForRoom = this.state.joining && !newState.joining && - !RoomViewStore.getJoinError(); - // NB: This does assume that the roomID will not change for the lifetime of // the RoomView instance if (initial) { @@ -238,7 +244,7 @@ module.exports = React.createClass({ if (!this.state.joining && this.state.roomId) { if (this.props.autoJoin) { this.onJoinButtonClicked(); - } else if (!room) { + } else if (!room && this.state.shouldPeek) { console.log("Attempting to peek into room %s", this.state.roomId); this.setState({ peekLoading: true, @@ -452,11 +458,6 @@ module.exports = React.createClass({ callState: callState }); - break; - case 'forward_event': - this.setState({ - forwardingEvent: payload.content, - }); break; } }, @@ -1164,8 +1165,13 @@ module.exports = React.createClass({ this.updateTint(); this.setState({ editingRoomSettings: false, - forwardingEvent: null, }); + if (this.state.forwardingEvent) { + dis.dispatch({ + action: 'forward_event', + event: null, + }); + } dis.dispatch({action: 'focus_composer'}); }, @@ -1576,7 +1582,7 @@ module.exports = React.createClass({ } else if (this.state.uploadingRoomSettings) { aux = ; } else if (this.state.forwardingEvent !== null) { - aux = ; + aux = ; } else if (this.state.searching) { hideCancel = true; // has own cancel aux = ; diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 5ac2e77256..686e63cd75 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -21,6 +21,7 @@ const MatrixClientPeg = require("../../MatrixClientPeg"); const PlatformPeg = require("../../PlatformPeg"); const Modal = require('../../Modal'); const dis = require("../../dispatcher"); +import sessionStore from '../../stores/SessionStore'; const q = require('q'); const packageJson = require('../../../package.json'); const UserSettingsStore = require('../../UserSettingsStore'); @@ -169,9 +170,6 @@ module.exports = React.createClass({ // The base URL to use in the referral link. Defaults to window.location.origin. referralBaseUrl: React.PropTypes.string, - // true if RightPanel is collapsed - collapsedRhs: React.PropTypes.bool, - // Team token for the referral link. If falsy, the referral section will // not appear teamToken: React.PropTypes.string, @@ -246,6 +244,12 @@ module.exports = React.createClass({ this.setState({ language: languageHandler.getCurrentLanguage(), }); + + this._sessionStore = sessionStore; + this._sessionStoreToken = this._sessionStore.addListener( + this._setStateFromSessionStore, + ); + this._setStateFromSessionStore(); }, componentDidMount: function() { @@ -272,6 +276,12 @@ module.exports = React.createClass({ } }, + _setStateFromSessionStore: function() { + this.setState({ + userHasGeneratedPassword: Boolean(this._sessionStore.getCachedPassword()), + }); + }, + _electronSettings: function(ev, settings) { this.setState({ electron_settings: settings }); }, @@ -1164,7 +1174,6 @@ module.exports = React.createClass({
@@ -1205,10 +1214,14 @@ module.exports = React.createClass({

{ _t("Account") }

- { _t("Sign out") } + { this.state.userHasGeneratedPassword ? +
+ { _t("To return to your account in future you need to set a password") } +
: null + } {accountJsx}
diff --git a/src/components/structures/login/Registration.js b/src/components/structures/login/Registration.js index 17fbf445b2..388198bb02 100644 --- a/src/components/structures/login/Registration.js +++ b/src/components/structures/login/Registration.js @@ -218,29 +218,29 @@ module.exports = React.createClass({ } trackPromise.then((teamToken) => { - this.props.onLoggedIn({ + return this.props.onLoggedIn({ userId: response.user_id, deviceId: response.device_id, homeserverUrl: this._matrixClient.getHomeserverUrl(), identityServerUrl: this._matrixClient.getIdentityServerUrl(), accessToken: response.access_token }, teamToken); - }).then(() => { - return this._setupPushers(); + }).then((cli) => { + return this._setupPushers(cli); }); }, - _setupPushers: function() { + _setupPushers: function(matrixClient) { if (!this.props.brand) { return q(); } - return MatrixClientPeg.get().getPushers().then((resp)=>{ + return matrixClient.getPushers().then((resp)=>{ const pushers = resp.pushers; for (let i = 0; i < pushers.length; ++i) { if (pushers[i].kind == 'email') { const emailPusher = pushers[i]; emailPusher.data = { brand: this.props.brand }; - MatrixClientPeg.get().setPusher(emailPusher).done(() => { + matrixClient.setPusher(emailPusher).done(() => { console.log("Set email branding to " + this.props.brand); }, (error) => { console.error("Couldn't set email branding: " + error); diff --git a/src/components/views/dialogs/KeyShareDialog.js b/src/components/views/dialogs/KeyShareDialog.js new file mode 100644 index 0000000000..61391d281c --- /dev/null +++ b/src/components/views/dialogs/KeyShareDialog.js @@ -0,0 +1,172 @@ +/* +Copyright 2017 Vector Creations Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import Modal from '../../../Modal'; +import React from 'react'; +import sdk from '../../../index'; + +import { _t } from '../../../languageHandler'; + +/** + * Dialog which asks the user whether they want to share their keys with + * an unverified device. + * + * onFinished is called with `true` if the key should be shared, `false` if it + * should not, and `undefined` if the dialog is cancelled. (In other words: + * truthy: do the key share. falsy: don't share the keys). + */ +export default React.createClass({ + propTypes: { + matrixClient: React.PropTypes.object.isRequired, + userId: React.PropTypes.string.isRequired, + deviceId: React.PropTypes.string.isRequired, + onFinished: React.PropTypes.func.isRequired, + }, + + getInitialState: function() { + return { + deviceInfo: null, + wasNewDevice: false, + }; + }, + + componentDidMount: function() { + this._unmounted = false; + const userId = this.props.userId; + const deviceId = this.props.deviceId; + + // give the client a chance to refresh the device list + this.props.matrixClient.downloadKeys([userId], false).then((r) => { + if (this._unmounted) { return; } + + const deviceInfo = r[userId][deviceId]; + + if(!deviceInfo) { + console.warn(`No details found for device ${userId}:${deviceId}`); + + this.props.onFinished(false); + return; + } + + const wasNewDevice = !deviceInfo.isKnown(); + + this.setState({ + deviceInfo: deviceInfo, + wasNewDevice: wasNewDevice, + }); + + // if the device was new before, it's not any more. + if (wasNewDevice) { + this.props.matrixClient.setDeviceKnown( + userId, + deviceId, + true, + ); + } + }).done(); + }, + + componentWillUnmount: function() { + this._unmounted = true; + }, + + + _onVerifyClicked: function() { + const DeviceVerifyDialog = sdk.getComponent('views.dialogs.DeviceVerifyDialog'); + + console.log("KeyShareDialog: Starting verify dialog"); + Modal.createDialog(DeviceVerifyDialog, { + userId: this.props.userId, + device: this.state.deviceInfo, + onFinished: (verified) => { + if (verified) { + // can automatically share the keys now. + this.props.onFinished(true); + } + }, + }); + }, + + _onShareClicked: function() { + console.log("KeyShareDialog: User clicked 'share'"); + this.props.onFinished(true); + }, + + _onIgnoreClicked: function() { + console.log("KeyShareDialog: User clicked 'ignore'"); + this.props.onFinished(false); + }, + + _renderContent: function() { + const displayName = this.state.deviceInfo.getDisplayName() || + this.state.deviceInfo.deviceId; + + let text; + if (this.state.wasNewDevice) { + text = "You added a new device '%(displayName)s', which is" + + " requesting encryption keys."; + } else { + text = "Your unverified device '%(displayName)s' is requesting" + + " encryption keys."; + } + text = _t(text, {displayName: displayName}); + + return ( +
+

{text}

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

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

+ +
+ ); + } + + return ( + + {content} + + ); + }, +}); diff --git a/src/components/views/dialogs/SetEmailDialog.js b/src/components/views/dialogs/SetEmailDialog.js index 82256970de..3c38064ee1 100644 --- a/src/components/views/dialogs/SetEmailDialog.js +++ b/src/components/views/dialogs/SetEmailDialog.js @@ -154,7 +154,7 @@ export default React.createClass({ />
diff --git a/src/components/views/rooms/ForwardMessage.js b/src/components/views/rooms/ForwardMessage.js index 33df201d7c..3c97128a02 100644 --- a/src/components/views/rooms/ForwardMessage.js +++ b/src/components/views/rooms/ForwardMessage.js @@ -17,7 +17,6 @@ import React from 'react'; import { _t } from '../../../languageHandler'; -import MatrixClientPeg from '../../../MatrixClientPeg'; import dis from '../../../dispatcher'; import KeyCode from '../../../KeyCode'; @@ -26,11 +25,6 @@ module.exports = React.createClass({ displayName: 'ForwardMessage', propTypes: { - currentRoomId: React.PropTypes.string.isRequired, - - /* the MatrixEvent to be forwarded */ - mxEvent: React.PropTypes.object.isRequired, - onCancelClick: React.PropTypes.func.isRequired, }, @@ -44,7 +38,6 @@ module.exports = React.createClass({ }, componentDidMount: function() { - this.dispatcherRef = dis.register(this.onAction); document.addEventListener('keydown', this._onKeyDown); }, @@ -54,30 +47,9 @@ module.exports = React.createClass({ sideOpacity: 1.0, middleOpacity: 1.0, }); - dis.unregister(this.dispatcherRef); document.removeEventListener('keydown', this._onKeyDown); }, - onAction: function(payload) { - if (payload.action === 'view_room') { - const event = this.props.mxEvent; - const Client = MatrixClientPeg.get(); - Client.sendEvent(payload.room_id, event.getType(), event.getContent()).done(() => { - dis.dispatch({action: 'message_sent'}); - }, (err) => { - if (err.name === "UnknownDeviceError") { - dis.dispatch({ - action: 'unknown_device_error', - err: err, - room: Client.getRoom(payload.room_id), - }); - } - dis.dispatch({action: 'message_send_failed'}); - }); - if (this.props.currentRoomId === payload.room_id) this.props.onCancelClick(); - } - }, - _onKeyDown: function(ev) { switch (ev.keyCode) { case KeyCode.ESCAPE: diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index f90d89c8c1..9f9f030c27 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -18,7 +18,7 @@ limitations under the License. 'use strict'; var React = require("react"); var ReactDOM = require("react-dom"); -import { _t } from '../../../languageHandler'; +import { _t, _tJsx } from '../../../languageHandler'; var GeminiScrollbar = require('react-gemini-scrollbar'); var MatrixClientPeg = require("../../../MatrixClientPeg"); var CallHandler = require('../../../CallHandler'); @@ -33,11 +33,28 @@ var Receipt = require('../../../utils/Receipt'); const HIDE_CONFERENCE_CHANS = true; -const VERBS = { - 'm.favourite': 'favourite', - 'im.vector.fake.direct': 'tag direct chat', - 'im.vector.fake.recent': 'restore', - 'm.lowpriority': 'demote', +function phraseForSection(section) { + // These would probably be better as individual strings, + // but for some reason we have translations for these strings + // as-is, so keeping it like this for now. + let verb; + switch (section) { + case 'm.favourite': + verb = _t('to favourite'); + break; + case 'im.vector.fake.direct': + verb = _t('to tag direct chat'); + break; + case 'im.vector.fake.recent': + verb = _t('to restore'); + break; + case 'm.lowpriority': + verb = _t('to demote'); + break; + default: + return _t('Drop here to tag %(section)s', {section: section}); + } + return _t('Drop here %(toAction)s', {toAction: verb}); }; module.exports = React.createClass({ @@ -478,17 +495,25 @@ module.exports = React.createClass({ switch (section) { case 'im.vector.fake.direct': return
- Press - - to start a chat with someone + {_tJsx( + "Press to start a chat with someone", + [//], + [ + (sub) => + ] + )}
; case 'im.vector.fake.recent': return
- You're not in any rooms yet! Press - - to make a room or - - to browse the directory + {_tJsx( + "You're not in any rooms yet! Press to make a room or"+ + " to browse the directory", + [//, //], + [ + (sub) => , + (sub) => + ] + )}
; } @@ -497,7 +522,7 @@ module.exports = React.createClass({ return null; } - const labelText = 'Drop here to ' + (VERBS[section] || 'tag ' + section); + const labelText = phraseForSection(section); return ; }, diff --git a/src/components/views/rooms/SimpleRoomHeader.js b/src/components/views/rooms/SimpleRoomHeader.js index 44ec7c29aa..8c06d71b6f 100644 --- a/src/components/views/rooms/SimpleRoomHeader.js +++ b/src/components/views/rooms/SimpleRoomHeader.js @@ -14,10 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -'use strict'; - import React from 'react'; -import dis from '../../../dispatcher'; import AccessibleButton from '../elements/AccessibleButton'; import sdk from '../../../index'; import { _t } from '../../../languageHandler'; @@ -45,17 +42,10 @@ export default React.createClass({ title: React.PropTypes.string, onCancelClick: React.PropTypes.func, - // is the RightPanel collapsed? - collapsedRhs: React.PropTypes.bool, - // `src` to a TintableSvg. Optional. icon: React.PropTypes.string, }, - onShowRhsClick: function(ev) { - dis.dispatch({ action: 'show_right_panel' }); - }, - render: function() { let cancelButton; let icon; @@ -70,25 +60,12 @@ export default React.createClass({ />; } - let showRhsButton; - /* // don't bother cluttering things up with this for now. - const TintableSvg = sdk.getComponent("elements.TintableSvg"); - - if (this.props.collapsedRhs) { - showRhsButton = -
- -
- } - */ - return (
{ icon } { this.props.title } - { showRhsButton } { cancelButton }
diff --git a/src/createRoom.js b/src/createRoom.js index 4d7f5792f3..ce83f31c27 100644 --- a/src/createRoom.js +++ b/src/createRoom.js @@ -76,14 +76,11 @@ function createRoom(opts) { } ]; - let modal; - setTimeout(()=>{ - modal = Modal.createDialog(Loader, null, 'mx_Dialog_spinner'); - }, 0); + const modal = Modal.createDialog(Loader, null, 'mx_Dialog_spinner'); let roomId; return client.createRoom(createOpts).finally(function() { - if (modal) modal.close(); + modal.close(); }).then(function(res) { roomId = res.room_id; if (opts.dmUserId) { @@ -100,6 +97,7 @@ function createRoom(opts) { dis.dispatch({ action: 'view_room', room_id: roomId, + should_peek: false, }); } return roomId; diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 47553e8b94..a99671402b 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -28,7 +28,7 @@ "Decryption error": "Entschlüsselungs Fehler", "Session ID": "Sitzungs-ID", "End-to-end encryption information": "Ende-zu-Ende-Verschlüsselungs-Informationen", - "Event information": "Ereignis-Informationen", + "Event information": "Ereignis-Information", "Sender device information": "Absender Geräte Informationen", "Displays action": "Zeigt Aktionen an", "Bans user with given id": "Schließt den Benutzer mit der angegebenen ID dauerhaft aus dem Raum aus", @@ -78,7 +78,7 @@ "Click here": "Hier klicken,", "Confirm your new password": "Neues Passwort bestätigen", "Continue": "Fortfahren", - "Create an account": "Erstelle einen Account", + "Create an account": "Benutzerkonto erstellen", "Create Room": "Raum erstellen", "Cryptography": "Verschlüsselung", "Deactivate Account": "Benutzerkonto deaktivieren", @@ -105,7 +105,7 @@ "Can't load user settings": "Benutzereinstellungen können nicht geladen werden", "changed name": "änderte Namen", "changed the power level of": "änderte Berechtigungslevel von", - "Clear Cache": "Leere Cache", + "Clear Cache": "Cache leeren", "Click here to fix": "Zum reparieren hier klicken", "*️⃣ Commands": "*️⃣ Befehle", "Default": "Standard", @@ -172,7 +172,7 @@ "Permissions": "Berechtigungen", "Phone": "Telefon", "placed a": "plazierte einen", - "Please check your email and click on the link it contains. Once this is done, click continue.": "Bitte prüfen sie ihre E-Mails und klicken sie auf den enthaltenden Link. Anschließend klicke auf \"Fortsetzen\".", + "Please check your email and click on the link it contains. Once this is done, click continue.": "Bitte prüfe deinen E-Mail-Posteingang und klicke auf den in der E-Mail enthaltenen Link. Anschließend auf \"Fortsetzen\" klicken.", "Please Register": "Bitte registrieren", "Privacy warning": "Datenschutzwarnung", "Privileged Users": "Privilegierte Nutzer", @@ -207,7 +207,7 @@ "since they joined": "ab dem Zeitpunkt, an dem sie beigetreten sind", "since they were invited": "ab dem Zeitpunkt, an dem sie eingeladen wurden", "Someone": "Jemand", - "Start a chat": "Starte einen Chat", + "Start a chat": "Chat starten", "Start Chat": "Chat beginnen", "Success": "Erfolg", "tag direct chat": "Zum kennzeichnen als direkten Chat", @@ -219,7 +219,7 @@ "This doesn't appear to be a valid email address": "Dies scheint keine gültige E-Mail-Adresse zu sein", "this invitation?": "diese Einladung?", "This is a preview of this room. Room interactions have been disabled": "Dies ist eine Vorschau dieses Raumes. Raum-Interaktionen wurden deaktiviert", - "This room is not accessible by remote Matrix servers": "Andere Matrix-Server können auf diesen Raum nicht zugreifen", + "This room is not accessible by remote Matrix servers": "Remote-Matrix-Server können auf diesen Raum nicht zugreifen", "This room's internal ID is": "Die interne ID dieses Raumes ist", "To ban users": "Um Benutzer dauerhaft aus dem Raum auszuschließen", "To configure the room": "Um den Raum zu konfigurieren", @@ -252,7 +252,7 @@ "Upload file": "Datei hochladen", "User Interface": "Benutzeroberfläche", "User name": "Nutzername", - "Users": "Nutzer", + "Users": "Benutzer", "User": "Nutzer", "Verification Pending": "Verifizierung ausstehend", "Video call": "Video-Anruf", @@ -319,7 +319,7 @@ "Mar": "Mrz", "Apr": "April", "May": "Mai", - "Jun": "Juni", + "Jun": "Jun", "Jul": "Juli", "Aug": "Aug", "Sep": "Sep", @@ -339,7 +339,7 @@ "User names may only contain letters, numbers, dots, hyphens and underscores.": "Benutzernamen dürfen nur Buchstaben, Nummern, Punkte, Binde- und Unterstriche enthalten.", "An unknown error occurred.": "Ein unbekannter Fehler ist aufgetreten.", "I already have an account": "Ich habe bereits einen Account", - "An error occurred: %(error_string)s": "Ein Fehler trat auf: %(error_string)s", + "An error occurred: %(error_string)s": "Ein Fehler ist aufgetreten: %(error_string)s", "Topic": "Thema", "Make this room private": "Mache diesen Raum privat", "Share message history with new users": "Bisherigen Chatverlauf mit neuen Nutzern teilen", @@ -416,16 +416,16 @@ "Drop here %(toAction)s": "Hierher ziehen: %(toAction)s", "Drop here to tag %(section)s": "Hierher ziehen: %(section)s taggen", "Press": "Drücke", - "tag as %(tagName)s": "als %(tagName)s taggen", + "tag as %(tagName)s": "als %(tagName)s markieren", "to browse the directory": "um das Raum-Verzeichnis zu durchsuchen", "to demote": "um das Berechtigungslevel herabzusetzen", "to favourite": "zum Favorisieren", "to make a room or": "um einen Raum zu erstellen, oder", "to restore": "zum wiederherstellen", "to start a chat with someone": "um einen Chat mit jemandem zu starten", - "to tag direct chat": "als direkten Chat markieren", + "to tag direct chat": "als Direkt-Chat markieren", "You're not in any rooms yet! Press": "Du bist noch keinem Raum beigetreten! Drücke", - "click to reveal": "Klicke zum anzeigen", + "click to reveal": "anzeigen", "To remove other users' messages": "Um Nachrichten anderer Nutzer zu verbergen", "You are trying to access %(roomName)s.": "Du versuchst, auf den Raum \"%(roomName)s\" zuzugreifen.", "af": "Afrikaans", @@ -671,14 +671,14 @@ "%(oneUser)srejected their invitation %(repeats)s times": "%(oneUser)shat die Einladung %(repeats)s mal abgelehnt", "%(severalUsers)srejected their invitations": "%(severalUsers)shaben ihre Einladung abgelehnt", "%(oneUser)srejected their invitation": "%(oneUser)shat die Einladung abgelehnt", - "%(severalUsers)shad their invitations withdrawn %(repeats)s times": "%(severalUsers)szogen ihre Einladungen %(repeats)s mal zurück", - "%(oneUser)shad their invitation withdrawn %(repeats)s times": "%(oneUser)szog seine/ihre Einladung %(repeats)s mal zurück", + "%(severalUsers)shad their invitations withdrawn %(repeats)s times": "%(severalUsers)swurden die ursprünglichen Einladungen %(repeats)s mal wieder entzogen", + "%(oneUser)shad their invitation withdrawn %(repeats)s times": "%(oneUser)swurde die Einladung %(repeats)s mal wieder entzogen", "%(severalUsers)shad their invitations withdrawn": "%(severalUsers)szogen ihre Einladungen zurück", "%(oneUser)shad their invitation withdrawn": "%(oneUser)swurde die ursprüngliche Einladung wieder entzogen", "were invited %(repeats)s times": "wurden %(repeats)s mal eingeladen", "was invited %(repeats)s times": "wurde %(repeats)s mal eingeladen", "were invited": "wurden eingeladen", - "were banned %(repeats)s times": "wurden %(repeats)s mal aus dem Raum ausgeschlossen", + "were banned %(repeats)s times": "wurden %(repeats)s mal dauerhaft aus dem Raum ausgeschlossen", "was banned %(repeats)s times": "wurde %(repeats)s mal aus dem Raum ausgeschlossen", "were banned": "wurden dauerhaft aus dem Raum ausgeschlossen", "were unbanned %(repeats)s times": "wurden %(repeats)s mal vom dauerhaften Ausschluss aus dem Raum befreit", @@ -710,7 +710,7 @@ "New passwords don't match": "Die neuen Passwörter stimmen nicht überein", "olm version:": "Version von olm:", "Passwords can't be empty": "Passwortfelder dürfen nicht leer sein", - "Report it": "Melde ihn", + "Report it": "Melden", "riot-web version:": "Version von riot-web:", "Scroll to bottom of page": "Zum Ende der Seite springen", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Zeitstempel im 12-Stunden-Format anzeigen (z. B. 2:30pm)", @@ -726,7 +726,7 @@ "Remove %(threePid)s?": "%(threePid)s entfernen?", "Please select the destination room for this message": "Bitte den Raum auswählen, an den diese Nachricht gesendet werden soll", "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s hat den Raum-Namen gelöscht.", - "Passphrases must match": "Passphrase muss übereinstimmen", + "Passphrases must match": "Passphrases müssen übereinstimmen", "Passphrase must not be empty": "Passphrase darf nicht leer sein", "Export room keys": "Raum-Schlüssel exportieren", "Enter passphrase": "Passphrase eingeben", @@ -735,12 +735,12 @@ "You must join the room to see its files": "Du musst dem Raum beitreten, um die Raum-Dateien sehen zu können", "Reject all %(invitedRooms)s invites": "Alle %(invitedRooms)s Einladungen ablehnen", "Start new Chat": "Starte neuen Chat", - "Guest users can't invite users. Please register.": "Gäste können keine Nutzer einladen. Bitte registrieren.", + "Guest users can't invite users. Please register.": "Gäste können keine Benutzer einladen. Bitte registrieren.", "Failed to invite": "Einladen fehlgeschlagen", "Failed to invite user": "Einladen des Nutzers fehlgeschlagen", "Confirm Removal": "Entfernen bestätigen", "Unknown error": "Unbekannter Fehler", - "Incorrect password": "Inkorrektes Passwort", + "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", @@ -781,7 +781,7 @@ "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": "Importiere Raum-Schlüssel", + "Import room keys": "Raum-Schlüssel importieren", "File to import": "Zu importierende Datei", "Failed to invite the following users to the %(roomName)s room:": "Das Einladen der folgenden Nutzer in den Raum \"%(roomName)s\" ist fehlgeschlagen:", "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.": "Bist du sicher, dass du dieses Ereignis entfernen (löschen) möchtest? Wenn du die Änderung eines Raum-Namens oder eines Raum-Themas löscht, kann dies dazu führen, dass die ursprüngliche Änderung rückgängig gemacht wird.", @@ -815,14 +815,14 @@ "Ongoing conference call%(supportedText)s.": "Laufendes Konferenzgespräch%(supportedText)s.", "You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "Du wirst jetzt auf die Website eines Drittanbieters weitergeleitet, damit du dein Konto für die Verwendung von %(integrationsUrl)s authentifizieren kannst. Möchtest du fortfahren?", "Disable URL previews for this room (affects only you)": "URL-Vorschau für diesen Raum deaktivieren (betrifft nur dich)", - "Start automatically after system login": "Starte automatisch nach System-Login", + "Start automatically after system login": "Nach System-Login automatisch starten", "Desktop specific": "Desktopspezifisch", "Jump to first unread message.": "Zur ersten ungelesenen Nachricht springen.", "Options": "Optionen", "disabled": "deaktiviert", "enabled": "aktiviert", "Invited": "Eingeladen", - "Set a Display Name": "Setze einen Anzeigenamen", + "Set a Display Name": "Anzeigenamen festlegen", "for %(amount)ss": "für %(amount)ss", "for %(amount)sm": "seit %(amount)smin", "for %(amount)sh": "für %(amount)sh", @@ -849,7 +849,7 @@ "Anyone": "Jeder", "Are you sure you want to leave the room '%(roomName)s'?": "Bist du sicher, dass du den Raum '%(roomName)s' verlassen willst?", "Custom level": "Benutzerdefiniertes Berechtigungslevel", - "Device ID:": "Geräte-ID:", + "Device ID:": "Geräte-Kennung:", "device id: ": "Geräte-ID: ", "Device key:": "Geräte-Schlüssel:", "Email address (optional)": "E-Mail-Adresse (optional)", @@ -861,9 +861,9 @@ "Setting a user name will create a fresh account": "Die Eingabe eines Benutzernamens wird ein neues Konto erzeugen", "Tagged as: ": "Markiert als: ", "This Home Server does not support login using email address.": "Dieser Heimserver unterstützt den Login mittels E-Mail-Adresse nicht.", - "There was a problem logging in.": "Es gab ein Problem beim anmelden.", + "There was a problem logging in.": "Beim Anmelden ist ein Problem aufgetreten.", "Unknown (user, device) pair:": "Unbekanntes (Nutzer-/Gerät-)Paar:", - "Remote addresses for this room:": "Entfernte Raum-Adressen für diesen Raum:", + "Remote addresses for this room:": "Remote-Adressen für diesen Raum:", "Unrecognised command:": "Unbekannter Befehl:", "Unrecognised room alias:": "Unbekannter Raum-Alias:", "Use compact timeline layout": "Nutze kompaktes Zeitstrahl-Layout", @@ -872,7 +872,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!": "WARNUNG: SCHLÜSSEL-VERIFIZIERUNG FEHLGESCHLAGEN! Der Signatur-Schlüssel für %(userId)s und Gerät %(deviceId)s ist \"%(fprint)s\" welche nicht dem bereitgestellten Schlüssel \"%(fingerprint)s\" übereinstimmen. Dies kann bedeuten, dass deine Kommunikation abgefangen wird!", "You have disabled URL previews by default.": "Du hast die URL-Vorschau standardmäßig deaktiviert.", "You have enabled URL previews by default.": "Du hast die URL-Vorschau standardmäßig aktiviert.", - "You have entered an invalid contact. Try using their Matrix ID or email address.": "Du hast einen ungültigen Kontakt eingegeben. Versuche es mit der Matrix-ID oder der E-Mail-Adresse.", + "You have entered an invalid contact. Try using their Matrix ID or email address.": "Du hast einen ungültigen Kontakt eingegeben. Versuche es mit der Matrix-Kennung oder der E-Mail-Adresse des Kontakts.", "$senderDisplayName changed the room avatar to ": "$senderDisplayName hat das Raum-Bild geändert zu ", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s hat das Raum-Bild für %(roomName)s geändert", "Hide removed messages": "Gelöschte Nachrichten verbergen", @@ -922,12 +922,12 @@ "Drop File Here": "Lasse Datei hier los", "Enable Notifications": "Benachrichtigungen aktivieren", "Encrypted by a verified device": "Von einem vertrauten Gerät verschlüsselt", - "Encrypted by an unverified device": "Von einem nicht vertrauten Gerät verschlüsselt", + "Encrypted by an unverified device": "Von einem nicht verifizierten Gerät verschlüsselt", "Failed to upload profile picture!": "Hochladen des Profilbild's fehlgeschlagen!", "Incoming call from %(name)s": "Eingehender Anruf von %(name)s", "Incoming video call from %(name)s": "Eingehender Video-Anruf von %(name)s", "Incoming voice call from %(name)s": "Eingehender Sprach-Anruf von %(name)s", - "Join as voice or video.": "Mit Sprache oder Video beitreten.", + "Join as voice or video.": "Per Sprachanruf oder Videoanruf beitreten.", "Last seen": "Zuletzt gesehen", "Level:": "Level:", "No display name": "Kein Anzeigename", @@ -961,7 +961,7 @@ "Would you like to accept or decline this invitation?": "Möchtest du diese Einladung akzeptieren oder ablehnen?", "You have been banned from %(roomName)s by %(userName)s.": "Du wurdest von %(userName)s dauerhaft aus dem Raum %(roomName)s ausgeschlossen.", "You have been kicked from %(roomName)s by %(userName)s.": "Du wurdest von %(userName)s aus dem Raum %(roomName)s entfernt.", - "You may wish to login with a different account, or add this email to this account.": "Du möchtest dich evtl. mit einem anderen Konto anmelden oder diese E-Mail-Adresse diesem Konto hinzufügen.", + "You may wish to login with a different account, or add this email to this account.": "Du möchtest dich eventuell mit einem anderen Konto anmelden oder alternativ diese E-Mail-Adresse diesem Konto hinzufügen.", "Your home server does not support device management.": "Dein Heimserver unterstützt kein Geräte-Management.", "(~%(count)s results).one": "(~%(count)s Ergebnis)", "(~%(count)s results).other": "(~%(count)s Ergebnis)", @@ -974,5 +974,7 @@ "Authentication check failed: incorrect password?": "Authentifizierung fehlgeschlagen: Falsches Passwort?", "Disable Peer-to-Peer for 1:1 calls": "Peer-to-Peer-Verbindung für 1-zu-1-Anrufe deaktivieren", "Do you want to set an email address?": "Möchtest du eine E-Mail-Adresse setzen?", - "This will allow you to reset your password and receive notifications.": "Dies erlaubt dir dein Passwort zurückzusetzen und Benachrichtigungen zu empfangen." + "This will allow you to reset your password and receive notifications.": "Dies erlaubt dir dein Passwort zurückzusetzen und Benachrichtigungen zu empfangen.", + "Press to start a chat with someone": "Klicke auf um einen Chat mit jemanden zu starten", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Du bist bisher in keinem Raum! Klicke auf um einen Raum zu erstellen oder um das Verzeichnis zu durchsuchen" } diff --git a/src/i18n/strings/el.json b/src/i18n/strings/el.json index eb25cd9e16..4e09fd7f2a 100644 --- a/src/i18n/strings/el.json +++ b/src/i18n/strings/el.json @@ -839,13 +839,13 @@ "Share message history with new users": "Διαμοιρασμός ιστορικού μηνυμάτων με τους νέους χρήστες", "numbullet": "απαρίθμηση", "%(severalUsers)sleft and rejoined %(repeats)s times": "%(severalUsers)s έφυγαν και ξανασυνδέθηκαν %(repeats)s φορές", - "%(oneUser)sleft and rejoined %(repeats)s times": "%(severalUsers)s έφυγε και ξανασυνδέθηκε %(repeats)s φορές", + "%(oneUser)sleft and rejoined %(repeats)s times": "%(oneUser)s έφυγε και ξανασυνδέθηκε %(repeats)s φορές", "%(severalUsers)sleft and rejoined": "%(severalUsers)s έφυγαν και ξανασυνδέθηκαν", - "%(oneUser)sleft and rejoined": "%(severalUsers)s έφυγε και ξανασυνδέθηκε", + "%(oneUser)sleft and rejoined": "%(oneUser)s έφυγε και ξανασυνδέθηκε", "%(severalUsers)shad their invitations withdrawn %(repeats)s times": "Οι %(severalUsers)s απέσυραν τις προσκλήσεις τους %(repeats)s φορές", - "%(oneUser)shad their invitation withdrawn %(repeats)s times": "Ο %(severalUsers)s απέσυρε την πρόσκληση του %(repeats)s φορές", + "%(oneUser)shad their invitation withdrawn %(repeats)s times": "Ο %(oneUser)s απέσυρε την πρόσκληση του %(repeats)s φορές", "%(severalUsers)shad their invitations withdrawn": "Οι %(severalUsers)s απέσυραν τις προσκλήσεις τους", - "%(oneUser)shad their invitation withdrawn": "Ο %(severalUsers)s απέσυρε την πρόσκληση του", + "%(oneUser)shad their invitation withdrawn": "Ο %(oneUser)s απέσυρε την πρόσκληση του", "You must join the room to see its files": "Πρέπει να συνδεθείτε στο δωμάτιο για να δείτε τα αρχεία του", "Reject all %(invitedRooms)s invites": "Απόρριψη όλων των προσκλήσεων %(invitedRooms)s", "Failed to invite the following users to the %(roomName)s room:": "Δεν ήταν δυνατή η πρόσκληση των χρηστών στο δωμάτιο %(roomName)s:", @@ -914,5 +914,7 @@ "were unbanned %(repeats)s times": "ξεμπλοκαρίστηκαν %(repeats)s φορές", "was unbanned %(repeats)s times": "ξεμπλοκαρίστηκε %(repeats)s φορές", "were unbanned": "ξεμπλοκαρίστηκαν", - "was unbanned": "ξεμπλοκαρίστηκε" + "was unbanned": "ξεμπλοκαρίστηκε", + "Press to start a chat with someone": "Πατήστε για να ξεκινήσετε μια συνομιλία", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Δεν είστε σε κανένα δωμάτιο! Πατήστε για να δημιουργήσετε ένα δωμάτιο ή για να δείτε το ευρετήριο" } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index ad00ea9275..6334c797e8 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -440,6 +440,7 @@ "Please Register": "Please Register", "Power level must be positive integer.": "Power level must be positive integer.", "Press": "Press", + "Press to start a chat with someone": "Press to start a chat with someone", "Privacy warning": "Privacy warning", "Private Chat": "Private Chat", "Privileged Users": "Privileged Users", @@ -648,7 +649,7 @@ "Would you like to accept or decline this invitation?": "Would you like to accept or decline this invitation?", "You already have existing direct chats with this user:": "You already have existing direct chats with this user:", "You are already in a call.": "You are already in a call.", - "You're not in any rooms yet! Press": "You're not in any rooms yet! Press", + "You're not in any rooms yet! Press to make a room or to browse the directory": "You're not in any rooms yet! Press to make a room or to browse the directory", "You are trying to access %(roomName)s.": "You are trying to access %(roomName)s.", "You cannot place a call with yourself.": "You cannot place a call with yourself.", "You cannot place VoIP calls in this browser.": "You cannot place VoIP calls in this browser.", @@ -910,5 +911,13 @@ "Authentication check failed: incorrect password?": "Authentication check failed: incorrect password?", "Disable Peer-to-Peer for 1:1 calls": "Disable Peer-to-Peer for 1:1 calls", "Do you want to set an email address?": "Do you want to set an email address?", - "This will allow you to reset your password and receive notifications.": "This will allow you to reset your password and receive notifications." + "This will allow you to reset your password and receive notifications.": "This will allow you to reset your password and receive notifications.", + "To return to your account in future you need to set a password": "To return to your account in future you need to set a password", + "Skip":"Skip", + "Start verification": "Start verification", + "Share without verifying": "Share without verifying", + "Ignore request": "Ignore request", + "You added a new device '%(displayName)s', which is requesting encryption keys.": "You added a new device '%(displayName)s', which is requesting encryption keys.", + "Your unverified device '%(displayName)s' is requesting encryption keys.": "Your unverified device '%(displayName)s' is requesting encryption keys.", + "Encryption key request": "Encryption key request" } diff --git a/src/i18n/strings/en_US.json b/src/i18n/strings/en_US.json index c3df1f90a6..5233111065 100644 --- a/src/i18n/strings/en_US.json +++ b/src/i18n/strings/en_US.json @@ -913,5 +913,11 @@ "Username not available": "Username not available", "Something went wrong!": "Something went wrong!", "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." + "If you already have a Matrix account you can log in instead.": "If you already have a Matrix account you can log in instead.", + "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?", + "Disable Peer-to-Peer for 1:1 calls": "Disable Peer-to-Peer for 1:1 calls", + "Do you want to set an email address?": "Do you want to set an email address?", + "This will allow you to reset your password and receive notifications.": "This will allow you to reset your password and receive notifications." } diff --git a/src/i18n/strings/es.json b/src/i18n/strings/es.json index 5f20f8113e..f7506b946d 100644 --- a/src/i18n/strings/es.json +++ b/src/i18n/strings/es.json @@ -1,5 +1,5 @@ { - "af": "Africano", + "af": "Afrikáans", "ar-ae": "Árabe (Emiratos Árabes Unidos)", "ar-bh": "Árabe (Baréin)", "ar-dz": "Árabe (Argelia)", @@ -267,7 +267,7 @@ "Failed to unban": "Falló al desbloquear", "Failed to upload file": "Error en el envío del fichero", "Failed to verify email address: make sure you clicked the link in the email": "Falló al verificar el correo electrónico: Asegúrese hacer clic en el enlace del correo", - "Failure to create room": "Falló al crear sala", + "Failure to create room": "Fallo al crear la sala", "Favourite": "Favorito", "favourite": "favorito", "Favourites": "Favoritos", @@ -483,5 +483,153 @@ "Tagged as: ": "Etiquetado como: ", "The default role for new room members is": "El nivel por defecto para los nuevos miembros de esta sala es", "The main address for this room is": "La dirección principal de esta sala es", - "The phone number entered looks invalid": "El número de teléfono indicado parece erróneo" + "The phone number entered looks invalid": "El número de teléfono indicado parece erróneo", + "Active call (%(roomName)s)": "Llamada activa (%(roomName)s)", + "Add a topic": "Añadir un tema", + "Missing Media Permissions, click here to request.": "Faltan permisos para el medio, pulse aquí para solicitarlos.", + "No media permissions": "Sin permisos para el medio", + "You may need to manually permit Riot to access your microphone/webcam": "Probablemente necesite dar permisos manualmente a Riot para su micrófono/cámara", + "Are you sure you want to leave the room '%(roomName)s'?": "¿Está seguro de que desea abandonar la sala '%(roomName)s'?", + "Are you sure you want to upload the following files?": "¿Está seguro que desea enviar los siguientes archivos?", + "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.": "No se puede conectar al servidor - compruebe su conexión, asegúrese de que el certificado SSL del servidor es de confiaza, y compruebe que no hay extensiones del navegador bloqueando las peticiones.", + "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s ha quitado el nombre de la sala.", + "Device key:": "Clave del dispositivo:", + "Disable markdown formatting": "Desactivar el formato Markdown", + "Drop File Here": "Deje el fichero aquí", + "Guest access is disabled on this Home Server.": "El acceso de invitados está desactivado en este servidor.", + "Join as voice or video.": "Conecte con voz o vídeo.", + "List this room in %(domain)s's room directory?": "¿Mostrar esta sala en el directorio de %(domain)s?", + "Manage Integrations": "Gestionar integraciones", + "Markdown is disabled": "Markdown está desactivado", + "Markdown is enabled": "Markdown está activado", + "matrix-react-sdk version:": "Versión de matrix-react-sdk:", + "Members only": "Sólo para miembros", + "Message not sent due to unknown devices being present": "Mensaje no enviado debido a la presencia de dispositivos desconocidos", + "Missing room_id in request": "Falta el ID de sala en la petición", + "Missing user_id in request": "Falta el ID de usuario en la petición", + "Mobile phone number": "Número de teléfono móvil", + "Mobile phone number (optional)": "Número de teléfono móvil (opcional)", + "Moderator": "Moderador", + "Must be viewing a room": "Debe estar viendo una sala", + "Mute": "Silenciar", + "my Matrix ID": "Mi ID de Matrix", + "Name": "Nombre", + "Never send encrypted messages to unverified devices from this device": "No enviar nunca mensajes cifrados, desde este dispositivo, a dispositivos sin verificar", + "Never send encrypted messages to unverified devices in this room": "No enviar nunca mensajes cifrados a dispositivos no verificados, en esta sala", + "Never send encrypted messages to unverified devices in this room from this device": "No enviar nunca mensajes cifrados a dispositivos no verificados, en esta sala, desde este dispositivo", + "New address (e.g. #foo:%(localDomain)s)": "Nueva dirección (ej: #foo:%(localDomain)s)", + "New password": "Nueva contraseña", + "New passwords don't match": "Las nuevas contraseñas no coinciden", + "New passwords must match each other.": "Las nuevas contraseñas deben coincidir.", + "none": "ninguno", + "not set": "sin configurar", + "not specified": "sin especificar", + "Notifications": "Notificaciones", + "(not supported by this browser)": "(no soportado por este navegador)", + "": "", + "NOT verified": "NO verificado", + "No devices with registered encryption keys": "No hay dispositivos con claves de cifrado registradas", + "No display name": "Sin nombre para mostrar", + "No more results": "No hay más resultados", + "No results": "Sin resultados", + "No users have specific privileges in this room": "Ningún usuario tiene permisos específicos en esta sala", + "OK": "Correcto", + "olm version:": "versión de olm:", + "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", + "People": "Gente", + "Permissions": "Permisos", + "Phone": "Teléfono", + "%(senderName)s placed a %(callType)s call.": "%(senderName)s ha hecho una llamada de tipo %(callType)s.", + "Please check your email and click on the link it contains. Once this is done, click continue.": "Por favor, compruebe su e-mail y pulse el enlace que contiene. Una vez esté hecho, pulse continuar.", + "Please Register": "Por favor, regístrese", + "Power level must be positive integer.": "El nivel debe ser un entero positivo.", + "Press": "Pulse", + "Privacy warning": "Alerta de privacidad", + "Private Chat": "Conversación privada", + "Privileged Users": "Usuarios con privilegios", + "Profile": "Perfil", + "Public Chat": "Sala pública", + "Reason": "Razón", + "Reason: %(reasonText)s": "Razón: %(reasonText)s", + "Revoke Moderator": "Eliminar Moderador", + "Refer a friend to Riot:": "Informar a un amigo sobre Riot:", + "Register": "Registrarse", + "rejected": "rechazado", + "%(targetName)s rejected the invitation.": "%(targetName)s ha rechazado la invitación.", + "Reject invitation": "Rechazar invitación", + "Rejoin": "Volver a unirse", + "Remote addresses for this room:": "Dirección remota de esta sala:", + "Remove Contact Information?": "¿Eliminar información del contacto?", + "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s ha suprimido su nombre para mostar (%(oldDisplayName)s).", + "%(senderName)s removed their profile picture.": "%(senderName)s ha eliminado su foto de perfil.", + "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.", + "restore": "restaurar", + "Results from DuckDuckGo": "Resultados desde DuckDuckGo", + "Return to app": "Volver a la aplicación", + "Return to login screen": "Volver a la pantalla de inicio de sesión", + "Riot does not have permission to send you notifications - please check your browser settings": "Riot no tiene permisos para enviarle notificaciones - por favor, revise la configuración del navegador", + "Riot was not given permission to send notifications - please try again": "Riot no pudo obtener permisos para enviar notificaciones - por favor, inténtelo de nuevo", + "riot-web version:": "versión riot-web:", + "Room %(roomId)s not visible": "La sala %(roomId)s no es visible", + "Searches DuckDuckGo for results": "Busca en DuckDuckGo", + "Server may be unavailable or overloaded": "El servidor podría estar saturado o desconectado", + "Show timestamps in 12 hour format (e.g. 2:30pm)": "Mostrar el tiempo en formato 12h (am/pm)", + "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "La clave de firma que usted ha proporcionado coincide con la recibida del dispositivo %(deviceId)s de %(userId)s. Dispositivo verificado.", + "This action cannot be performed by a guest user. Please register to be able to do this.": "Esto no puede ser hecho por un invitado. Por favor, regístrese para poder hacerlo.", + "This email address is already in use": "Dirección e-mail en uso", + "This email address was not found": "Dirección e-mail no encontrada", + "%(actionVerb)s this person?": "¿%(actionVerb)s a esta persona?", + "The email address linked to your account must be entered.": "Debe introducir el e-mail asociado a su cuenta.", + "The file '%(fileName)s' exceeds this home server's size limit for uploads": "El fichero '%(fileName)s' excede el tamaño máximo permitido en este servidor", + "The file '%(fileName)s' failed to upload": "Se produjo un fallo al enviar '%(fileName)s'", + "The remote side failed to pick up": "El sitio remoto falló al sincronizar", + "This Home Server does not support login using email address.": "Este servidor no permite identificarse con direcciones e-mail.", + "This invitation was sent to an email address which is not associated with this account:": "Se envió la invitación a un e-mail no asociado con esta cuenta:", + "There was a problem logging in.": "Hubo un problema identificándose.", + "This room has no local addresses": "Esta sala no tiene direcciones locales", + "This room is not recognised.": "Esta sala no se reconoce.", + "These are experimental features that may break in unexpected ways": "Estas son funcionalidades experimentales, podrían fallar de formas imprevistas", + "The visibility of existing history will be unchanged": "La visibilidad del historial previo no se verá afectada", + "This doesn't appear to be a valid email address": "Esto no parece un e-mail váido", + "This is a preview of this room. Room interactions have been disabled": "Esto es una vista previa de la sala. Las interacciones con la sala están desactivadas", + "This phone number is already in use": "Este número de teléfono ya se está usando", + "This room": "Esta sala", + "This room is not accessible by remote Matrix servers": "Esta sala no es accesible por otros servidores Matrix", + "This room's internal ID is": "El ID interno de la sala es", + "times": "veces", + "To ban users": "Expulsar usuarios", + "to browse the directory": "navegar el directorio", + "To configure the room": "Configurar la sala", + "to demote": "degradar", + "to favourite": "marcar como favorito", + "To invite users into the room": "Invitar usuarios a la sala", + "To kick users": "Patear usuarios", + "To link to a room it must have an address.": "Para enlazar una sala, debe tener una dirección.", + "to make a room or": "hacer una sala o", + "To remove other users' messages": "Eliminar los mensajes de otros usuarios", + "To reset your password, enter the email address linked to your account": "Para reiniciar su contraseña, introduzca el e-mail asociado a su cuenta", + "to restore": "restaurar", + "Cancel": "Cancelar", + "Dismiss": "Omitir", + "powered by Matrix": "con el poder de Matrix", + "Room directory": "Directorio de salas", + "Custom Server Options": "Opciones de Servidor Personalizado", + "unknown error code": "Código de error desconocido", + "Sunday": "Domingo", + "Monday": "Lunes", + "Tuesday": "Martes", + "Wednesday": "Miércoles", + "Thursday": "Jueves", + "Friday": "Viernes", + "Saturday": "Sábado" } diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 0d33ad711f..039198f0cf 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -557,7 +557,7 @@ "You're not in any rooms yet! Press": "Vous n’êtes dans aucun salon ! Cliquez", "You are trying to access %(roomName)s.": "Vous essayez d'accéder à %(roomName)s.", "You cannot place a call with yourself.": "Vous ne pouvez pas passer d'appel avec vous-même.", - "You cannot place VoIP calls in this browser.": "Vous ne pouvez pas passer d'appel voix dans cet explorateur.", + "You cannot place VoIP calls in this browser.": "Vous ne pouvez pas passer d'appel vocal dans ce navigateur.", "You do not have permission to post to this room": "Vous n’avez pas la permission de poster dans ce salon", "You have been invited to join this room by %(inviterName)s": "Vous avez été invité à joindre ce salon par %(inviterName)s", "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Vous avez été déconnecté de tous vos appareils et ne recevrez plus de notifications. Pour réactiver les notifications, identifiez vous à nouveau sur tous les appareils", @@ -922,5 +922,7 @@ "Authentication check failed: incorrect password?": "Erreur d’identification: mot de passe incorrect ?", "Disable Peer-to-Peer for 1:1 calls": "Désactiver les appels 1:1 pair-à-pair", "Do you want to set an email address?": "Souhaitez-vous configurer une adresse e-mail ?", - "This will allow you to reset your password and receive notifications.": "Ceci va vous permettre de réinitialiser votre mot de passe et de recevoir des notifications." + "This will allow you to reset your password and receive notifications.": "Ceci va vous permettre de réinitialiser votre mot de passe et de recevoir des notifications.", + "Press to start a chat with someone": "Cliquez sur pour entamer une discussion avec quelqu'un", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Vous n'avez pas encore rejoint de salle ! Cliquez sur pour créer une salle ou sur pour explorer l'annuaire" } diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index c6a86347f5..f2fa3bb63e 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -27,21 +27,21 @@ "Saturday": "Szombat", "af": "Afrikaans", "ar-ae": "Arabic (U.A.E.)", - "ar-bh": "Arabic (Bahrain)", - "ar-dz": "Arabic (Algeria)", - "ar-eg": "Arabic (Egypt)", - "ar-iq": "Arabic (Iraq)", - "ar-jo": "Arabic (Jordan)", - "ar-kw": "Arabic (Kuwait)", - "ar-lb": "Arabic (Lebanon)", - "ar-ly": "Arabic (Libya)", - "ar-ma": "Arabic (Morocco)", - "ar-om": "Arabic (Oman)", - "ar-qa": "Arabic (Qatar)", - "ar-sa": "Arabic (Saudi Arabia)", - "ar-sy": "Arabic (Syria)", - "ar-tn": "Arabic (Tunisia)", - "ar-ye": "Arabic (Yemen)", + "ar-bh": "Arab (Bahrain)", + "ar-dz": "Arab (Algeria)", + "ar-eg": "Arab (Egypt)", + "ar-iq": "Arab (Iraq)", + "ar-jo": "Arab (Jordan)", + "ar-kw": "Arab (Kuwait)", + "ar-lb": "Arab (Lebanon)", + "ar-ly": "Arab (Libya)", + "ar-ma": "Arab (Morocco)", + "ar-om": "Arab (Oman)", + "ar-qa": "Arab (Qatar)", + "ar-sa": "Arab (Saudi Arabia)", + "ar-sy": "Arab (Syria)", + "ar-tn": "Arab (Tunisia)", + "ar-ye": "Arab (Yemen)", "be": "Belorusz", "bg": "Bolgár", "ca": "Katalán", @@ -179,5 +179,504 @@ "Create new room": "Új szoba létrehozása", "sb": "Szorb", "rm": "Rétoromán", - "tn": "Tswana" + "tn": "Tswana", + "Close": "Bezár", + "Room directory": "Szobák listája", + "Start chat": "Csevegés indítása", + "Welcome page": "Üdvözlő oldal", + "all room members, from the point they are invited": "minden résztvevő a szobában, amióta meg van hívva", + "all room members, from the point they joined": "minden résztvevő a szobában, amióta csatlakozott", + "and": "és", + "%(items)s and %(remaining)s others": "%(items)s és még: %(remaining)s", + "%(items)s and one other": "%(items)s és még egy", + "%(items)s and %(lastItem)s": "%(items)s és %(lastItem)s", + "and %(overflowCount)s others...": "és még: %(overflowCount)s ...", + "and one other...": "és még egy...", + "%(names)s and %(lastPerson)s are typing": "%(names)s és %(lastPerson)s írnak", + "%(names)s and one other are typing": "%(names)s és még valaki ír", + "%(names)s and %(count)s others are typing": "%(names)s és %(count)s ember ír", + "An email has been sent to": "Az e-mail ide lett küldve:", + "A new password must be entered.": "Új jelszót kell megadni.", + "%(senderName)s answered the call.": "%(senderName)s felvette a telefont.", + "anyone": "bárki", + "An error has occurred.": "Hiba történt.", + "Anyone": "Bárki", + "Anyone who knows the room's link, apart from guests": "A vendégeken kívül bárki aki ismeri a szoba link-jét", + "Anyone who knows the room's link, including guests": "Bárki aki tudja a szoba link-jét, még a vendégek is", + "Are you sure?": "Biztos?", + "Are you sure you want to leave the room '%(roomName)s'?": "Biztos elhagyod a szobát '%(roomName)s'?", + "Are you sure you want to reject the invitation?": "Biztos elutasítod a meghívást?", + "Are you sure you want to upload the following files?": "Biztos feltöltöd ezeket a fájlokat?", + "Attachment": "Csatolmány", + "Autoplay GIFs and videos": "GIF-ek és videók automatikus lejátszása", + "%(senderName)s banned %(targetName)s.": "%(senderName)s kitiltotta őt: %(targetName)s.", + "Ban": "Kitilt", + "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.", + "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.", + "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s törölte a szoba nevét.", + "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s megváltoztatta a témát erre \"%(topic)s\".", + "Changes to who can read history will only apply to future messages in this room": "Változtatások a napló olvasási jogosultságon csak a szoba új üzeneteire fog vonatkozni", + "Changes your display nickname": "Becenév megváltoztatása", + "changing room on a RoomView is not supported": "Szoba nézetben nem lehet szobát váltani", + "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.": "Jelszó megváltoztatása jelenleg alaphelyzetbe állítja a titkosításnál használt kulcsokat minden készüléken, ezzel a régi titkosított üzenetek olvashatatlanok lesznek hacsak először nem mented ki a kulcsokat és újra betöltöd. A jövőben ezen javítunk.", + "Claimed Ed25519 fingerprint key": "Igényelt Ed25519 ujjlenyomat kulcs", + "Clear Cache and Reload": "Gyorsítótár törlése és újratöltés", + "Clear Cache": "Gyorsítótár törlése", + "Click here to join the discussion!": "A beszélgetéshez való csatlakozáshoz kattints ide!", + "Click here to fix": "A javításhoz kattints ide", + "Click to mute audio": "Hang némításhoz kattints ide", + "Click to mute video": "A videó kikapcsoláshoz kattints ide", + "click to reveal": "Megjelenítéshez kattints ide", + "Click to unmute video": "Videó bekapcsoláshoz kattints ide", + "Click to unmute audio": "Hang visszakapcsoláshoz kattints ide", + "Command error": "Parancs hiba", + "Commands": "Parancsok", + "Conference call failed.": "Sikertelen konferencia hívás.", + "Conference calling is in development and may not be reliable.": "Konferencia hívás meg fejlesztés alatt és lehet, hogy nem elég stabil.", + "Conference calls are not supported in encrypted rooms": "Titkosított szobákban a konferencia hívás nem támogatott", + "Conference calls are not supported in this client": "Ez a kliens nem támogatja a konferencia hívást", + "Confirm password": "Jelszó megerősítése", + "Confirm your new password": "Új jelszó megerősítése", + "Could not connect to the integration server": "Az integrációs szerverhez nem lehet kapcsolódni", + "%(count)s new messages.one": "%(count)s új üzenet", + "%(count)s new messages.other": "%(count)s új üzenet", + "Create a new chat or reuse an existing one": "Új csevegés indítása vagy egy meglévő használata", + "Create an account": "Fiók készítése", + "Create Room": "Szoba készítése", + "Cryptography": "Titkosítás", + "Current password": "Jelenlegi jelszó", + "Curve25519 identity key": "Curve25519 azonosítási kulcs", + "Custom": "Egyedi", + "Custom level": "Egyedi szint", + "/ddg is not a command": "/ddg nem egy parancs", + "Deactivate Account": "Fiók zárolása", + "Deactivate my account": "Fiókom felfüggesztése", + "Decline": "Elutasít", + "Decrypt %(text)s": "%(text)s visszafejtése", + "Decryption error": "Visszafejtési hiba", + "Delete": "Töröl", + "demote": "hozzáférési szint csökkentése", + "Default": "Alapértelmezett", + "Device already verified!": "Készülék már ellenőrizve!", + "Device ID": "Készülék azonosító", + "Device ID:": "Készülék azonosító:", + "device id: ": "készülék azonosító: ", + "Device key:": "Készülék kulcs:", + "Devices": "Készülékek", + "Devices will not yet be able to decrypt history from before they joined the room": "A készülékek nem tudják egyenlőre visszafejteni a régebbi üzeneteket mint mikor csatlakoztak a szobához", + "Direct chats": "Közvetlen csevegés", + "Disable Notifications": "Értesítések tiltása", + "disabled": "letiltva", + "Disable inline URL previews by default": "Beágyazott URL előnézet alapértelmezetten tiltva", + "Disable markdown formatting": "Markdown formázás tiltva", + "Disinvite": "Meghívás visszavonása", + "Display name": "Megjelenített név", + "Displays action": "Tevékenységek megjelenítése", + "Don't send typing notifications": "Ne küldjön írás értesítést", + "Download %(text)s": "%(text)s letöltése", + "Drop File Here": "Ide húzd a fájlt", + "Drop here to tag %(section)s": "Húzd ide a címkézéshez: %(section)s", + "Ed25519 fingerprint": "Ed25519 ujjlenyomat", + "Email": "E-mail", + "Email address": "E-mail cím", + "Email address (optional)": "E-mail cím (opcionális)", + "Email, name or matrix ID": "E-mail, név vagy matrix azonosító", + "Emoji": "Emoji", + "Enable encryption": "Titkosítás bekapcsolása", + "Enable Notifications": "Értesítések bekapcsolása", + "enabled": "bekapcsolva", + "Encrypted by a verified device": "Ellenőrzött eszköz által titkosítva", + "Encrypted by an unverified device": "Nem ellenőrzött eszköz által titkosítva", + "Encrypted messages will not be visible on clients that do not yet implement encryption": "A titkosított üzenetek nem láthatók azokon a klienseken amik még nem támogatják a titkosítást", + "Encrypted room": "Titkosított szoba", + "Encryption is enabled in this room": "Ebben a szobában a titkosítás be van kapcsolva", + "Encryption is not enabled in this room": "Ebben a szobában a titkosítás nincs bekapcsolva", + "%(senderName)s ended the call.": "%(senderName)s befejezte a hívást.", + "End-to-end encryption information": "Végponttól végpontig való titkosítási információk", + "End-to-end encryption is in beta and may not be reliable": "Végponttól végpontig tartó titkosítás béta állapotú és lehet, hogy nem megbízható", + "Enter Code": "Kód megadása", + "Enter passphrase": "Jelmondat megadása", + "Error decrypting attachment": "Csatolmány visszafejtése sikertelen", + "Error: Problem communicating with the given homeserver.": "Hiba: Probléma van a saját szerverrel való kommunikációval.", + "Event information": "Esemény információ", + "Existing Call": "Hívás folyamatban", + "Export": "Mentés", + "Export E2E room keys": "E2E szoba kulcsok mentése", + "Failed to ban user": "A felhasználót nem sikerült kizárni", + "Failed to change power level": "A hozzáférési szintet nem sikerült megváltoztatni", + "Failed to delete device": "Eszközt nem sikerült törölni", + "Failed to fetch avatar URL": "Avatar képet nem sikerült letölteni", + "Failed to join room": "A szobába nem sikerült belépni", + "Failed to kick": "Kirúgás nem sikerült", + "Failed to leave room": "A szobát nem sikerült elhagyni", + "Failed to load timeline position": "Az idővonal pozíciót nem sikerült betölteni", + "Failed to lookup current room": "Az aktuális szoba felkeresése sikertelen", + "Failed to mute user": "A felhasználót nem sikerült hallgatásra bírni", + "Failed to register as guest:": "Nem sikerült vendégként regisztrálni:", + "Failed to reject invite": "A meghívót nem sikerült elutasítani", + "Failed to reject invitation": "A meghívót nem sikerült elutasítani", + "Failed to save settings": "A beállításokat nem sikerült elmenteni", + "Failed to send email": "E-mail nem sikerült elküldeni", + "Failed to send request.": "A kérést nem sikerült elküldeni.", + "Failed to set avatar.": "Avatar képet nem sikerült beállítani.", + "Failed to set display name": "Megjelenítési nevet nem sikerült beállítani", + "Failed to set up conference call": "Konferencia hívást nem sikerült elindítani", + "Failed to toggle moderator status": "Moderátor státuszt nem sikerült átállítani", + "Failed to unban": "Kizárás visszavonása sikertelen", + "Failed to upload file": "Fájl feltöltés sikertelen", + "Failed to upload profile picture!": "Profil kép feltöltése sikertelen!", + "Failed to verify email address: make sure you clicked the link in the email": "E-mail cím ellenőrzése sikertelen: ellenőrizd, hogy az e-mailnél lévő linkre rákattintottál", + "Failure to create room": "Szoba létrehozása sikertelen", + "favourite": "kedvenc", + "Favourites": "Kedvencek", + "Fill screen": "Képernyő kitöltése", + "Filter room members": "Szoba tagság szűrése", + "Forget room": "Szoba elfelejtése", + "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 végponttól végpontig 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 can't set avatars. Please register.": "A vendégek nem tudnak avatar képet beállítani. Kérlek regisztrálj.", + "Guest users can't create new rooms. Please register to create room and start a chat.": "Vendégek nem készíthetnek szobákat. Kérlek regisztrálj, hogy szobát tudják nyitni és el tudj kezdeni csevegni.", + "Guest users can't upload files. Please register to upload.": "Vendégek nem tölthetnek fel fájlokat. A feltöltéshez kérlek regisztrálj.", + "Guests can't use labs features. Please register.": "Vendégek nem használhatnak labor funkciókat. Kérlek regisztrálj.", + "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.", + "had": "van", + "Hangup": "Megszakít", + "Hide read receipts": "Olvasási visszajelzés elrejtése", + "Hide Text Formatting Toolbar": "Szövegformázási menü elrejtése", + "Historical": "Archív", + "Home": "Kezdőlap", + "Homeserver is": "Saját szerver:", + "Identity Server is": "Azonosítási szerver:", + "I have verified my email address": "Ellenőriztem az e-mail címemet", + "Import": "Betöltés", + "Import E2E room keys": "E2E szoba kulcsok betöltése", + "Incoming call from %(name)s": "Beérkező hivás: %(name)s", + "Incoming video call from %(name)s": "Bejövő videóhívás: %(name)s", + "Incoming voice call from %(name)s": "Bejövő hívás: %(name)s", + "Incorrect username and/or password.": "Helytelen felhasználó és/vagy jelszó.", + "Incorrect verification code": "Hibás azonosítási kód", + "Interface Language": "Felhasználói felület nyelve", + "Invalid alias format": "Hibás alternatív név formátum", + "Invalid address format": "Hibás cím formátum", + "Invalid Email Address": "Hibás e-mail cím", + "Invalid file%(extra)s": "Hibás fájl%(extra)s", + "%(senderName)s invited %(targetName)s.": "%(senderName)s meghívta: %(targetName)s.", + "Invite new room members": "Új tagok meghívása", + "Invited": "Meghívva", + "Invites": "Meghívók", + "Invites user with given id to current room": "Felhasználó meghívása ebbe a szobába megadott azonosítóval", + "'%(alias)s' is not a valid format for an address": "'%(alias)s' nem megfelelő formátum egy címhez", + "'%(alias)s' is not a valid format for an alias": "'%(alias)s' nem megfelelő formátum egy alternatív névhez", + "%(displayName)s is typing": "%(displayName)s ír", + "Sign in with": "Belépés ezzel:", + "Join as voice or video.": "Csatlakozás hanggal vagy videóval.", + "Join Room": "Belépés a szobába", + "joined and left": "be-, és kilépett", + "joined": "belépett", + "%(targetName)s joined the room.": "%(targetName)s belépett a szobába.", + "Joins room with given alias": "A megadott becenévvel belépett a szobába", + "Jump to first unread message.": "Ugrás az első olvasatlan üzenetre.", + "%(senderName)s kicked %(targetName)s.": "%(senderName)s kizárta: %(targetName)s.", + "Kick": "Kizár", + "Kicks user with given id": "Az adott azonosítójú felhasználó kizárása", + "Labs": "Labor", + "Last seen": "Utoljára láttuk", + "Leave room": "Szoba elhagyása", + "left and rejoined": "ki-, és belépett", + "left": "kilépett", + "%(targetName)s left the room.": "%(targetName)s elhagyta a szobát.", + "Level:": "Szint:", + "List this room in %(domain)s's room directory?": "%(domain)s szobát feltüntessük a szobák listájában?", + "Local addresses for this room:": "A szoba helyi címe:", + "Logged in as:": "Bejelentkezve mint:", + "Login as guest": "Belépés vendégként", + "Logout": "Kilép", + "Low priority": "Alacsony prioritás", + "%(senderName)s made future room history visible to": "%(senderName)s elérhetővé tette a szoba új üzeneteit nekik:", + "Manage Integrations": "Integrációk kezelése", + "Markdown is disabled": "Markdown kikapcsolva", + "Markdown is enabled": "Markdown engedélyezett", + "matrix-react-sdk version:": "matrix-react-sdk verzió:", + "Members only": "Csak tagoknak", + "Message not sent due to unknown devices being present": "Ismeretlen eszköz miatt az üzenet nem küldhető el", + "Missing room_id in request": "Hiányzó room_id a kérésben", + "Missing user_id in request": "Hiányzó user_id a kérésben", + "Mobile phone number": "Mobil telefonszám", + "Mobile phone number (optional)": "Mobill telefonszám (opcionális)", + "Moderator": "Moderátor", + "Must be viewing a room": "Meg kell nézni a szobát", + "my Matrix ID": "Matrix azonosítóm", + "Name": "Név", + "Never send encrypted messages to unverified devices from this device": "Soha ne küldj titkosított üzenetet ellenőrizetlen eszközre erről az eszközről", + "Never send encrypted messages to unverified devices in this room": "Soha ne küldj titkosított üzenetet ebből a szobából ellenőrizetlen eszközre", + "Never send encrypted messages to unverified devices in this room from this device": "Soha ne küldj titkosított üzenetet ebből a szobából ellenőrizetlen eszközre erről az eszközről", + "New address (e.g. #foo:%(localDomain)s)": "Új cím (e.g. #foo:%(localDomain)s)", + "New Composer & Autocomplete": "Új szerkesztő és automatikus kiegészítés", + "New password": "Új jelszó", + "New passwords don't match": "Az új jelszavak nem egyeznek", + "New passwords must match each other.": "Az új jelszavaknak meg kell egyezniük egymással.", + "none": "semmi", + "not set": "nincs beállítva", + "not specified": "nincs meghatározva", + "(not supported by this browser)": "(ebben a böngészőben nem támogatott)", + "": "", + "NOT verified": "NEM ellenőrzött", + "No devices with registered encryption keys": "Nincs eszköz a regisztrált titkosítási kulcsokhoz", + "No display name": "Nincs megjelenítési név", + "No more results": "Nincs több találat", + "No results": "Nincs találat", + "No users have specific privileges in this room": "Egy felhasználónak sincsenek specifikus jogosultságai ebben a szobában", + "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)", + "Once you've followed the link it contains, click below": "Miután a linket követted, kattints alulra", + "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", + "People": "Emberek", + "Permissions": "Jogosultságok", + "Phone": "Telefon", + "%(senderName)s placed a %(callType)s call.": "%(senderName)s %(callType)s hívást kezdeményezett.", + "Please check your email and click on the link it contains. Once this is done, click continue.": "Ellenőrizd az e-mail-edet és kattints a benne lévő linkre. Ha ez megvan, kattints a folytatásra.", + "Power level must be positive integer.": "A szintnek pozitív egésznek kell lennie.", + "Press": "Nyomd meg", + "Private Chat": "Privát csevegés", + "Privileged Users": "Privilegizált felhasználók", + "Profile": "Profil", + "Public Chat": "Nyilvános csevegés", + "Reason": "Ok", + "Reason: %(reasonText)s": "Ok: %(reasonText)s", + "Revoke Moderator": "Moderátor visszahívása", + "Refer a friend to Riot:": "Ismerős meghívása a Riotba:", + "Register": "Regisztráció", + "rejected": "elutasítva", + "%(targetName)s rejected the invitation.": "%(targetName)s elutasította a meghívót.", + "Reject invitation": "Meghívó elutasítása", + "Rejoin": "Újracsatlakozás", + "Remote addresses for this room:": "A szoba távoli címei:", + "Remove Contact Information?": "Kapcsolat információk törlése?", + "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s törölte a megjelenítési nevet (%(oldDisplayName)s).", + "%(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", + "restore": "visszaállít", + "Results from DuckDuckGo": "Eredmények a DuckDuckGo-ból", + "Return to app": "Vissza az alkalmazáshoz", + "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", + "Riot was not given permission to send notifications - please try again": "Riotnak nincs jogosultsága értesítést küldeni neked - próbáld újra", + "riot-web version:": "riot-web verzió:", + "Room %(roomId)s not visible": "%(roomId)s szoba nem látható", + "Room Colour": "Szoba színe", + "Room contains unknown devices": "A szobában ellenőrizetlen eszközök vannak", + "Room name (optional)": "Szoba neve (opcionális)", + "%(roomName)s does not exist.": "%(roomName)s nem létezik.", + "%(roomName)s is not accessible at this time.": "%(roomName)s jelenleg nem érhető el.", + "Rooms": "Szobák", + "Save": "Mentés", + "Scroll to bottom of page": "Az oldal aljára görget", + "Scroll to unread messages": "Olvasatlan üzenetekhez görget", + "Search failed": "Keresés sikertelen", + "Searches DuckDuckGo for results": "Keresés DuckDuckGo-val", + "Searching known users": "Ismert felhasználók keresése", + "Seen by %(userName)s at %(dateTime)s": "%(userName)s %(dateTime)s időpontban látta", + "Send a message (unencrypted)": "Üzenet küldése (titkosítás nélkül)", + "Send an encrypted message": "Titkosított üzenet küldése", + "Send anyway": "Küld mindenképpen", + "Sender device information": "Küldő eszközének információja", + "Send Invites": "Meghívók elküldése", + "Send Reset Email": "Visszaállítási e-mail küldése", + "sent an image": "kép küldése", + "%(senderDisplayName)s sent an image.": "%(senderDisplayName)s képet küldött.", + "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s meghívót küldött %(targetDisplayName)s felhasználónak, hogy lépjen be a szobába.", + "sent a video": "videó küldve", + "Server error": "Szerver hiba", + "Server may be unavailable or overloaded": "A szerver elérhetetlen vagy túlterhelt", + "Server may be unavailable, overloaded, or search timed out :(": "A szerver elérhetetlen, túlterhelt vagy a keresés túllépte az időkorlátot :(", + "Server may be unavailable, overloaded, or the file too big": "A szerver elérhetetlen, túlterhelt vagy a fájl túl nagy", + "Server may be unavailable, overloaded, or you hit a bug.": "A szerver elérhetetlen, túlterhelt vagy hibára futott.", + "Server unavailable, overloaded, or something else went wrong.": "A szerver elérhetetlen, túlterhelt vagy valami más probléma van.", + "Session ID": "Kapcsolat azonosító", + "%(senderName)s set a profile picture.": "%(senderName)s profil képet állított be.", + "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s a megjelenítési nevét megváltoztatta erre: %(displayName)s.", + "Set": "Beállít", + "Show panel": "Panel megjelenítése", + "Show Text Formatting Toolbar": "Szöveg formázási eszköztár megjelenítése", + "Show timestamps in 12 hour format (e.g. 2:30pm)": "Az időbélyegek 12 órás formátumban mutatása (pl.: 2:30pm)", + "Signed Out": "Kijelentkezett", + "Sign in": "Bejelentkezett", + "Sign out": "Kijelentkezés", + "since the point in time of selecting this option": "onnantól, hogy ez az opció kiválasztásra került", + "since they joined": "onnantól, hogy csatlakozott", + "since they were invited": "onnantól, hogy meg lett hívva", + "Some of your messages have not been sent.": "Néhány üzeneted nem lett elküldve.", + "Someone": "Valaki", + "Sorry, this homeserver is using a login which is not recognised ": "Bocs, ez a saját szerver olyan beléptetést használ ami nem ismert ", + "Start a chat": "Csevegés indítása", + "Start authentication": "Azonosítás indítása", + "Start Chat": "Csevegés indítása", + "Submit": "Elküld", + "Success": "Sikeres", + "tag as %(tagName)s": "címke beállítása: %(tagName)s", + "tag direct chat": "megjelölés közvetlen csevegésnek", + "Tagged as: ": "Címkék: ", + "The default role for new room members is": "Az alapértelmezett szerep új tagoknak:", + "The main address for this room is": "A szoba elsődleges címe:", + "The phone number entered looks invalid": "A megadott telefonszám érvénytelennek tűnik", + "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Az általad megadott aláíró kulcs megegyezik %(userId)s felhasználótól kapott kulccsal amit %(deviceId)s eszközhöz használ. Az eszköz ellenőrzöttnek jelölve.", + "This action cannot be performed by a guest user. Please register to be able to do this.": "Ezt nem teheti vendég felhasználó. Kérlek regisztrálj, hogy megtehesd.", + "This email address is already in use": "Ez az e-mail cím már használatban van", + "This email address was not found": "Az e-mail cím nem található", + "%(actionVerb)s this person?": "Ezt a felhasználót %(actionVerb)s?", + "The email address linked to your account must be entered.": "A fiókodhoz kötött e-mail címet add meg.", + "Press to start a chat with someone": "Nyomd meg a gombot ha szeretnél csevegni valakivel", + "Privacy warning": "Magánéleti figyelmeztetés", + "The file '%(fileName)s' exceeds this home server's size limit for uploads": "'%(fileName)s' fájl túllépte az egyedi szerverben beállított feltöltési méret határt", + "The file '%(fileName)s' failed to upload": "'%(fileName)s' fájl feltöltése sikertelen", + "The remote side failed to pick up": "A hívott fél nem vette fel", + "This Home Server does not support login using email address.": "Az egyedi szerver nem támogatja a belépést e-mail címmel.", + "This invitation was sent to an email address which is not associated with this account:": "A meghívó olyan e-mail címre lett küldve ami nincs összekötve ezzel a fiókkal:", + "There was a problem logging in.": "Hiba történt a bejelentkezésnél.", + "This room has no local addresses": "Ennek a szobának nincs helyi címe", + "This room is not recognised.": "Ez a szoba nem ismerős.", + "These are experimental features that may break in unexpected ways": "Ezek kísérleti funkciók amik kiszámíthatatlanok lehetnek", + "The visibility of existing history will be unchanged": "A már meglévő csevegés előzmények láthatósága nem változik", + "This doesn't appear to be a valid email address": "Ez nem tűnik helyes e-mail címnek", + "This is a preview of this room. Room interactions have been disabled": "Ez a szoba előnézete. Minden tevékenység ezzel a szobával ki van kapcsolva", + "This phone number is already in use": "Ez a telefonszám már használatban van", + "This room": "Ez a szoba", + "This room is not accessible by remote Matrix servers": "Ez a szoba távoli Matrix szerverről nem érhető el", + "This room's internal ID is": "A szoba belső azonosítója:", + "times": "alkalommal", + "To ban users": "Felhasználó kizárásához", + "to browse the directory": "a könyvtárban való kereséshez", + "To configure the room": "A szoba beállításához", + "to favourite": "kedvencekhez", + "To invite users into the room": "Felhasználó szobába való meghívásához", + "To kick users": "Felhasználó kirúgásához", + "To link to a room it must have an address.": "Szobához való kötéshez szükséges egy cím.", + "to make a room or": "szoba létrehozásához vagy", + "To remove other users' messages": "Más felhasználók üzeneteinek törléséhez", + "To reset your password, enter the email address linked to your account": "A jelszó alaphelyzetbe állításához add meg a fiókodhoz kötött e-mail címet", + "to restore": "visszaállításhoz", + "To send events of type": "Az alábbi típusú üzenetek küldéséhez", + "To send messages": "Üzenetek küldéséhez", + "to start a chat with someone": "csevegés indításához valakivel", + "to tag as %(tagName)s": "megjelölni mint: %(tagName)s", + "to tag direct chat": "megjelölni közvetlen csevegésnek", + "To use it, just wait for autocomplete results to load and tab through them.": "A használatához csak várd meg az automatikus kiegészítéshez a találatok betöltését és TAB-bal választhatsz közülük.", + "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Megpróbáltam betölteni a szoba megadott időpontjának megfelelő adatait, de nincs jogod a kérdéses üzenetek megjelenítéséhez.", + "Tried to load a specific point in this room's timeline, but was unable to find it.": "Megpróbáltam betölteni a szoba megadott időpontjának megfelelő adatait, de nem találom.", + "Turn Markdown off": "Markdown kikapcsolása", + "Turn Markdown on": "Markdown bekapcsolása", + "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s bekapcsolta a titkosítást végponttól végpontig (algoritmus %(algorithm)s).", + "Unable to add email address": "Az e-mail címet nem sikerült hozzáadni", + "Unable to remove contact information": "A névjegy információkat nem sikerült törölni", + "Unable to restore previous session": "Az előző kapcsolat visszaállítása sikertelen", + "Unable to verify email address.": "Az e-mail cím ellenőrzése sikertelen.", + "Unban": "Kitiltás visszavonása", + "%(senderName)s unbanned %(targetName)s.": "%(senderName)s visszaengedte %(targetName)s felhasználót.", + "Unable to capture screen": "A képernyő felvétele sikertelen", + "Unable to enable Notifications": "Az értesítések engedélyezése sikertelen", + "Unable to load device list": "Az eszközlista betöltése sikertelen", + "Undecryptable": "Visszafejthetetlen", + "Unencrypted room": "Titkosítatlan szoba", + "unencrypted": "titkosítatlan", + "Unencrypted message": "Titkosítatlan üzenet", + "unknown caller": "ismeretlen hívó", + "Unknown command": "Ismeretlen parancs", + "unknown device": "ismeretlen eszköz", + "Unknown room %(roomId)s": "Ismeretlen szoba %(roomId)s", + "Unknown (user, device) pair:": "Ismeretlen (felhasználó, eszköz) pár:", + "unknown": "ismeretlen", + "Unmute": "Némítás kikapcsolása", + "Unnamed Room": "Névtelen szoba", + "Unrecognised command:": "Ismeretlen parancs:", + "Unrecognised room alias:": "Ismeretlen szoba becenév:", + "Unverified": "Nem ellenőrzött", + "Uploading %(filename)s and %(count)s others.zero": "%(filename)s feltöltése", + "Uploading %(filename)s and %(count)s others.one": "%(filename)s és még %(count)s db másik feltöltése", + "Uploading %(filename)s and %(count)s others.other": "%(filename)s és még %(count)s db másik feltöltése", + "uploaded a file": "fájl feltöltése", + "Upload avatar": "Avatar kép feltöltése", + "Upload Failed": "Feltöltés sikertelen", + "Upload Files": "Fájlok feltöltése", + "Upload file": "Fájl feltöltése", + "Upload new:": "Új feltöltése:", + "Usage": "Használat", + "Use compact timeline layout": "Egyszerű idővonal séma használata", + "Use with caution": "Használd körültekintéssel", + "User ID": "Felhasználói azonosító", + "User Interface": "Felhasználói felület", + "%(user)s is a": "%(user)s egy", + "User name": "Felhasználói név", + "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (szint: %(powerLevelNumber)s)", + "Username invalid: %(errMessage)s": "Felhasználói név érvénytelen: %(errMessage)s", + "Users": "Felhasználók", + "User": "Felhasználó", + "Verification Pending": "Ellenőrzés függőben", + "Verification": "Ellenőrzés", + "verified": "ellenőrizve", + "Verified": "Ellenőrizve", + "Verified key": "Ellenőrzött kulcs", + "Video call": "Videó hívás", + "Voice call": "Hang hívás", + "VoIP conference finished.": "VoIP konferencia befejeződött.", + "VoIP conference started.": "VoIP konferencia elkezdődött.", + "VoIP is unsupported": "VoIP nem támogatott", + "(could not connect media)": "(média kapcsolat nem hozható létre)", + "(no answer)": "(nincs válasz)", + "(unknown failure: %(reason)s)": "(ismeretlen hiba: %(reason)s)", + "(warning: cannot be disabled again!)": "(figyelmeztetés: nem lehet újra kikapcsolni!)", + "Warning!": "Figyelem!", + "WARNING: Device already verified, but keys do NOT MATCH!": "Figyelem: Az eszköz már ellenőrzött, de a kulcsok NEM EGYEZNEK!", + "Who can access this room?": "Ki éri el ezt a szobát?", + "Who can read history?": "Ki olvashatja a régi üzeneteket?", + "Who would you like to add to this room?": "Kit szeretnél hozzáadni ehhez a szobához?", + "Who would you like to communicate with?": "Kivel szeretnél beszélgetni?", + "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s visszavonta %(targetName)s meghívóját.", + "Would you like to accept or decline this invitation?": "Ezt a meghívót szeretnéd elfogadni vagy elutasítani?", + "You already have existing direct chats with this user:": "Már van közvetlen csevegésed ezzel a felhasználóval:", + "You are already in a call.": "Már hívásban vagy.", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Még egyetlen szobába sem léptél be! Szoba létrehozáshoz nyomd meg: vagy a szobák közötti kereséshez nyomd meg: ", + "You are trying to access %(roomName)s.": "%(roomName)s szobába próbálsz belépni.", + "You cannot place a call with yourself.": "Nem hívhatod fel saját magadat.", + "You cannot place VoIP calls in this browser.": "Nem indíthatsz VoIP hívást ebben a böngészőben.", + "You do not have permission to post to this room": "Nincs jogod írni ebben a szobában", + "You have been banned from %(roomName)s by %(userName)s.": "%(userName)s kitiltott a szobából: %(roomName)s.", + "You have been invited to join this room by %(inviterName)s": "%(inviterName)s meghívott ebbe a szobába", + "You have been kicked from %(roomName)s by %(userName)s.": "%(userName)s kirúgott ebből a szobából: %(roomName)s.", + "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device": "Kijelentkeztél minden eszközről így nem fogsz \"push\" értesítéseket kapni. Az értesítések engedélyezéséhez jelentkezz vissza mindegyik eszközön", + "You have disabled URL previews by default.": "Az URL előnézet alapból tiltva van.", + "You have enabled URL previews by default.": "Az URL előnézet alapból engedélyezve van.", + "You have entered an invalid contact. Try using their Matrix ID or email address.": "Érvénytelen kapcsolatot adtál meg. Próbáld meg a Matrix azonosítóját vagy e-mail címét használni.", + "You have no visible notifications": "Nincsenek látható értesítéseid", + "You may wish to login with a different account, or add this email to this account.": "Lehet, hogy más fiókba szeretnél belépni vagy ezt az e-mail címet szeretnéd ehhez a fiókhoz kötni.", + "you must be a": "szükséges szerep:", + "You must register to use this functionality": "Regisztrálnod kell hogy ezt használhasd", + "You need to be able to invite users to do that.": "Hogy ezt csinálhasd meg kell tudnod hívni felhasználókat.", + "You need to be logged in.": "Be kell jelentkezz.", + "You need to enter a user name.": "Be kell írnod a felhasználói nevet.", + "You need to log back in to generate end-to-end encryption keys for this device and submit the public key to your homeserver. This is a once off; sorry for the inconvenience.": "Ahhoz, hogy kulcsot tudjál készíteni a végponttól végpontig való titkosításhoz ehhez az eszközhöz és elküld a kulcsot a egyéni szerverhez vissza kell jelentkezned. Ez egyszeri alkalom, elnézést a kellemetlenségér.", + "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Ez az e-mail cím, úgy néz ki, nincs összekötve a Matrix azonosítóval ezen az egyedi szerveren.", + "Your password has been reset": "A jelszavad visszaállítottuk", + "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "A jelszavadat sikeresen megváltoztattuk. Nem kapsz \"push\" értesítéseket amíg a többi eszközön vissza nem jelentkezel" } diff --git a/src/i18n/strings/ko.json b/src/i18n/strings/ko.json index 151acc7d3c..c2969ad966 100644 --- a/src/i18n/strings/ko.json +++ b/src/i18n/strings/ko.json @@ -533,7 +533,7 @@ "since they joined": "들어온 이후", "since they were invited": "초대받은 이후", "Some of your messages have not been sent.": "일부 메시지는 보내지 못했어요.", - "Someone": "누군가", + "Someone": "다른 사람", "Sorry, this homeserver is using a login which is not recognised ": "죄송해요, 이 홈 서버는 인식할 수 없는 로그인을 쓰고 있네요 ", "Start a chat": "이야기하기", "Start authentication": "인증하기", @@ -570,15 +570,105 @@ "This room's internal ID is": "방의 내부 ID", "times": "번", "To ban users": "사용자를 차단하기", - "to browse the directory": "목록에서 찾기", + "to browse the directory": "목록에서 찾으려면", "To configure the room": "방을 구성하기", - "to demote": "등급을 낮추기", - "to favourite": "즐겨찾기하기", + "to demote": "등급을 낮추려면", + "to favourite": "즐겨찾기하려면", "To invite users into the room": "방으로 사용자를 초대하기", "To kick users": "사용자를 내쫓기", "To link to a room it must have an address.": "방에 연결하려면 주소가 있어야 해요.", "to make a room or": "방을 만들거나 혹은", "To remove other users' messages": "다른 사용자의 메시지를 지우기", "To reset your password, enter the email address linked to your account": "비밀번호을 다시 설정하려면, 계정과 연결한 이메일 주소를 입력해주세요", - "to restore": "복구하기" + "to restore": "복구하려면", + "To send events of type": "유형 이벤트 보내기", + "To send messages": "메시지 보내기", + "to start a chat with someone": "다른 사람과 이야기하기", + "to tag as %(tagName)s": "%(tagName)s로 지정하려면", + "to tag direct chat": "직접 이야기를 지정하려면", + "To use it, just wait for autocomplete results to load and tab through them.": "이 기능을 사용하시려면, 자동완성 결과가 나오길 기다리신 뒤에 탭으로 움직여주세요.", + "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.": "이 방의 타임라인에서 특정 시점을 불러오려고 했지만, 찾을 수 없었어요.", + "Turn Markdown off": "마크다운 끄기", + "Turn Markdown on": "마크다운 켜기", + "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s님이 종단간 암호화를 켜셨어요 (알고리즘 %(algorithm)s).", + "Unable to add email address": "이메일 주소를 추가할 수 없어요", + "Unable to remove contact information": "연락처를 지울 수 없어요", + "Unable to restore previous session": "이전 세션을 복구할 수 없어요", + "Unable to verify email address.": "이메일 주소를 인증할 수 없어요.", + "Unban": "차단풀기", + "%(senderName)s unbanned %(targetName)s.": "%(senderName)s님이 %(targetName)s님의 차단을 푸셨어요.", + "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "이 이매알 주소가 초대를 받은 계정과 연결된 주소가 맞는지 확인할 수 없어요.", + "Unable to capture screen": "화면을 찍을 수 없어요", + "Unable to enable Notifications": "알림을 켤 수 없어요", + "Unable to load device list": "장치 목록을 불러올 수 없어요", + "Undecryptable": "해독할 수 없는", + "Unencrypted room": "암호화하지 않은 방", + "unencrypted": "암호화하지 않음", + "Unencrypted message": "암호화하지 않은 메시지", + "unknown caller": "알 수 없는 발신자", + "Unknown command": "알 수 없는 명령", + "unknown device": "알 수 없는 장치", + "Unknown room %(roomId)s": "알 수 없는 방 %(roomId)s", + "Unknown (user, device) pair:": "알 수 없는 (사용자, 장치) 연결:", + "unknown": "알 수 없음", + "Unmute": "소리 켜기", + "Unnamed Room": "이름 없는 방", + "Unrecognised command:": "인식 할 수 없는 명령:", + "Unrecognised room alias:": "인식할 수 없는 방 가명:", + "Unverified": "인증하지 않음", + "Uploading %(filename)s and %(count)s others.zero": "%(filename)s 올리는 중", + "Uploading %(filename)s and %(count)s others.one": "%(filename)s 외 %(count)s 올리는 중", + "Uploading %(filename)s and %(count)s others.other": "%(filename)s 외 %(count)s 올리는 중", + "uploaded a file": "파일을 올렸어요", + "Upload avatar": "아바타 올리기", + "Upload Failed": "파일을 올리지 못했어요", + "Upload Files": "파일 올리기", + "Upload file": "파일 올리기", + "Upload new:": "새로 올리기:", + "Usage": "사용", + "Use compact timeline layout": "간단한 타임라인 구성 사용", + "Use with caution": "조심해서 사용", + "User ID": "사용자 ID", + "User Interface": "사용자 인터페이스", + "%(user)s is a": "%(user)s는", + "User name": "사용자 이름", + "Username invalid: %(errMessage)s": "사용자 이름을 인식할 수 없어요: %(errMessage)s", + "Users": "사용자들", + "User": "사용자", + "Verification Pending": "인증을 기다리는 중", + "Verification": "인증", + "verified": "인증함", + "Verified": "인증함", + "Verified key": "인증한 키", + "Video call": "영상통화", + "Voice call": "음성통화", + "VoIP conference finished.": "인터넷전화 회의를 마쳤어요.", + "VoIP conference started.": "인터넷전화 회의를 시작했어요.", + "VoIP is unsupported": "인터넷전화를 지원하지 않아요", + "(could not connect media)": "(미디어에 연결할 수 없어요)", + "(no answer)": "(응답 없음)", + "(unknown failure: %(reason)s)": "(알 수 없는 오류: %(reason)s)", + "(warning: cannot be disabled again!)": "(주의: 다시 끌 수 없어요!)", + "Warning!": "주의!", + "WARNING: Device already verified, but keys do NOT MATCH!": "주의: 장치는 이미 인증했지만, 키가 맞지 않아요!", + "Who can access this room?": "누가 이 방에 들어올 수 있나요?", + "Who can read history?": "누가 기록을 읽을 수 있나요?", + "Who would you like to add to this room?": "이 방에 누구를 초대하고 싶으세요?", + "Who would you like to communicate with?": "누구와 이야기하고 싶으세요?", + "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s님이 %(targetName)s니의 초대를 취소하셨어요.", + "Would you like to accept or decline this invitation?": "초대를 받아들이거나 거절하시겠어요?", + "You already have existing direct chats with this user:": "이미 이 사용자와 직접 이야기하는 중이에요:", + "You are already in a call.": "이미 자신이 통화 중이네요.", + "You're not in any rooms yet! Press": "어떤 방에도 들어가 있지 않으세요! 누르세요", + "Press to start a chat with someone": "다른 사람과 이야기하려면 을 누르세요", + "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "주의: 키 확인 실패! %(userId)s와 장치 %(deviceId)s의 서명 키 \"%(fprint)s\"는 주어진 키 \"%(fingerprint)s\"와 맞지 않아요. 누가 이야기를 가로채는 중일 수도 있어요!", + "You're not in any rooms yet! Press to make a room or to browse the directory": "어떤 방에도 들어가 있지 않으세요! 을 눌러서 방을 만들거나 를 눌러 목록에서 방을 찾아보세요", + "You are trying to access %(roomName)s.": "%(roomName)s에 들어가려고 하는 중이에요.", + "You cannot place a call with yourself.": "자신에게 전화를 걸 수는 없어요.", + "You cannot place VoIP calls in this browser.": "이 브라우저에서는 인터넷전화를 걸 수 없어요.", + "You do not have permission to post to this room": "이 방에서 글을 올릴 권한이 없어요", + "You have been banned from %(roomName)s by %(userName)s.": "%(userName)s님이 %(roomName)s에서 차단하셨어요.", + "You have been invited to join this room by %(inviterName)s": "%(inviterName)s님이 이 방에 초대하셨어요", + "You have been kicked from %(roomName)s by %(userName)s.": "%(userName)s님이 %(roomName)s에서 추방하셨어요." } diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index 7a04d4ca38..eae3d7bc87 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -228,13 +228,13 @@ "Dismiss": "Afwijzen", "Drop here %(toAction)s": "%(toAction)s hier naartoe verplaatsen", "Error": "Fout", - "Failed to forget room %(errCode)s": "Kamer vergeten mislukt %(errCode)s", + "Failed to forget room %(errCode)s": "Ruimte vergeten mislukt %(errCode)s", "Failed to join the room": "Kamer binnengaan mislukt", "Favourite": "Favoriet", "Mute": "Dempen", "Notifications": "Meldingen", "Operation failed": "Actie mislukt", - "Please Register": "Registreer alstublieft", + "Please Register": "Registreer Alstublieft", "powered by Matrix": "mogelijk gemaakt door Matrix", "Remove": "Verwijderen", "Room directory": "Kamerlijst", @@ -268,8 +268,8 @@ "No display name": "Geen weergavenaam", "No more results": "Geen resultaten meer", "No results": "Geen resultaten", - "No users have specific privileges in this room": "Geen gebruikers me specifieke privileges in deze kamer", - "olm version:": "olm-versie:", + "No users have specific privileges in this room": "Geen gebruikers hebben specifieke privileges in deze ruimte", + "olm version:": "olm versie:", "Password": "Wachtwoord", "Password:": "Wachtwoord:", "Passwords can't be empty": "Wachtwoorden kunnen niet leeg zijn", @@ -279,10 +279,10 @@ "%(senderName)s placed a %(callType)s call.": "%(senderName)s heeft een %(callType)s-gesprek gestart.", "Press": "Druk", "Privacy warning": "Privacywaarschuwing", - "Private Chat": "Direct chatten", + "Private Chat": "Privégesprek", "Privileged Users": "Gebruikers met rechten", "Profile": "Profiel", - "Public Chat": "Publiek gesprek", + "Public Chat": "Publiek Gesprek", "Reason": "Reden", "Reason: %(reasonText)s": "Reden: %(reasonText)s", "Revoke Moderator": "Beheerder terugtrekken", @@ -291,9 +291,9 @@ "rejected": "verworpen", "%(targetName)s rejected the invitation.": "%(targetName)s heeft de uitnodiging geweigerd.", "Reject invitation": "Uitnodiging weigeren", - "Rejoin": "Opnieuw lid wordne", + "Rejoin": "Opnieuw toetreden", "Remote addresses for this room:": "Adres op afstand voor deze ruimte:", - "Remove Contact Information?": "Contactinformatie verwijderen?", + "Remove Contact Information?": "Contactinformatie Verwijderen?", "Send Invites": "Uitnodigingen versturen", "Start a chat": "Gesprek starten", "Start authentication": "Authenticatie starten", @@ -327,5 +327,202 @@ "%(weekDayName)s %(time)s": "%(weekDayName)s %(time)s", "Set a display name:": "Weergavenaam instellen:", "Set a Display Name": "Weergavenaam instellen", - "Upload an avatar:": "Een avatar uploaden:" + "Upload an avatar:": "Een avatar uploaden:", + "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.": "Geen verbinding met de thuisserver - controleer je verbinding. Controleer het SSL-certificaat van de thuisserver en browser-extensies die verzoeken kunnen blokkeren.", + "%(count)s new messages.other": "%(count)s nieuwe berichten", + "Create an account": "Open een account", + "Cryptography": "Cryptografie", + "Current password": "Huidig wachtwoord", + "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s heeft de naam van de kamer verwijderd.", + "Create a new chat or reuse an existing one": "Maak een nieuwe chat aan of gebruik een reeds bestaande", + "Create Room": "Maak een kamer", + "Curve25519 identity key": "Curve25519 identiteitssleutel", + "/ddg is not a command": "/ddg is geen commando", + "Deactivate Account": "Account Deactiveren", + "Deactivate my account": "Mijn account deactiveren", + "Decline": "Weigeren", + "Decrypt %(text)s": "Ontsleutel %(text)s", + "Decryption error": "Fout bij het ontsleutelen", + "Delete": "Verwijderen", + "demote": "degraderen", + "Device already verified!": "Apparaat reeds geverifieerd!", + "Device ID": "Apparaat ID", + "Device ID:": "Apparaat ID:", + "device id: ": "apparaat id: ", + "Device key:": "Apparaat sleutel:", + "Devices": "Apparaten", + "Devices will not yet be able to decrypt history from before they joined the room": "Apparaten kunnen nog niet de geschiedenis van voordat ze de ruimte betraden ontsleutelen", + "Direct chats": "Privégesprekken", + "Disable Notifications": "Notificaties uitschakelen", + "Disable markdown formatting": "Opmaak formatering uitschakelen", + "Disinvite": "Uitnodiging terugtrekken", + "Display name": "Weergavenaam", + "Don't send typing notifications": "Geen notificatie sturen bij het typen", + "Download %(text)s": "%(text)s Downloaden", + "Drop File Here": "Plaats Bestand Hier", + "Ed25519 fingerprint": "Ed25519 vingerafdruk", + "Email": "E-mail", + "Email address": "E-mailadres", + "Email address (optional)": "E-mailadres (optioneel)", + "Claimed Ed25519 fingerprint key": "Vereiste Ed25519 vingerafdruk sleutel", + "Custom": "Aangepast", + "Custom level": "Aangepast niveau", + "Deops user with given id": "Ontmachtigd gebruiker met het gegeven id", + "Default": "Standaard", + "Disable inline URL previews by default": "URL voorvertoning standaard uitschakelen", + "Displays action": "Weergeeft actie", + "Drop here to tag %(section)s": "Hiernaartoe verplaatsen om %(section)s te etiketteren", + "Email, name or matrix ID": "E-mail, naam of matrix ID", + "Emoji": "Emoticon", + "Enable encryption": "Versleuteling inschakelen", + "Enable Notifications": "Notificaties inschakelen", + "enabled": "ingeschakeld", + "Encrypted by a verified device": "Versleuteld bij een geverifieerd apparaat", + "Encrypted by an unverified device": "Versleuteld bij een niet geverifieerd apparaat", + "Encrypted messages will not be visible on clients that do not yet implement encryption": "Versleutelde berichten zullen nog niet zichtbaar zijn op applicaties die geen versleuteling ondersteunen", + "Encrypted room": "Versleutelde ruimte", + "Encryption is enabled in this room": "Versleuteling is ingeschakeld in deze ruimte", + "Encryption is not enabled in this room": "Versleuteling is niet ingeschakeld in deze ruimte", + "%(senderName)s ended the call.": "%(senderName)s heeft opgehangen.", + "End-to-end encryption information": "Eind-tot-eind versleuteling informatie", + "End-to-end encryption is in beta and may not be reliable": "Eind-tot-eind versleuteling is nog in beta en kan onbetrouwbaar zijn", + "Enter Code": "Voer code in", + "Enter passphrase": "Voer wachtzin in", + "Error decrypting attachment": "Fout tijdens het ontsleutelen van de bijlage", + "Error: Problem communicating with the given homeserver.": "Fout: Er doet zich een probleem voor met het communiceren met de gegeven thuisserver.", + "Event information": "Gebeurtenis informatie", + "Existing Call": "Bestaande oproep", + "Export": "Exporteren", + "Export E2E room keys": "Exporteer E2E ruimte sleutels", + "Failed to ban user": "Niet gelukt om de gebruiker te verbannen", + "Failed to change power level": "Niet gelukt om het machtsniveau te wijzigen", + "Failed to delete device": "Niet gelukt om het apparaat te verwijderen", + "Failed to fetch avatar URL": "Niet gelukt om de avatar URL op te halen", + "Failed to join room": "Niet gelukt om tot de ruimte toe te treden", + "Failed to leave room": "Niet gelukt om de ruimte te verlaten", + "Failed to load timeline position": "Niet gelukt om de tijdlijn positie te laden", + "Failed to lookup current room": "Niet gelukt om de huidige ruimte op te zoeken", + "Failed to mute user": "Niet gelukt om de gebruiker te dempen", + "Failed to register as guest:": "Niet gelukt om als gast te registreren:", + "Failed to reject invite": "Niet gelukt om de uitnodiging te weigeren", + "Failed to reject invitation": "Niet gelukt om de uitnodiging te weigeren", + "Failed to save settings": "Niet gelukt om de instellingen op te slaan", + "Failed to send email": "Niet gelukt om de e-mail te versturen", + "Failed to send request.": "Niet gelukt om het verzoek te versturen.", + "Failed to set avatar.": "Niet gelukt om de avatar in te stellen.", + "Failed to set display name": "Niet gelukt om de weergavenaam in te stellen", + "Failed to set up conference call": "Niet gelukt om een vergadergesprek te maken", + "Failed to toggle moderator status": "Niet gelukt om de moderator status te veranderen", + "Failed to unban": "Niet gelukt om te ontbannen", + "Failed to upload file": "Niet gelukt om het bestand te uploaden", + "Failed to upload profile picture!": "Niet gelukt om een profiel foto te uploaden!", + "Failed to verify email address: make sure you clicked the link in the email": "Niet gelukt om het e-mailadres te verifiëren: wees er zeker van dat je de link in de e-mail hebt aangeklikt", + "Failure to create room": "Het aanmaken van een ruimte is mislukt", + "favourite": "favoriet", + "Favourites": "Favorieten", + "Fill screen": "Scherm vullen", + "Filter room members": "Ruimte leden filteren", + "Forget room": "Ruimte vergeten", + "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 eind-tot-eind versleutelingssleutels 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.": "Gast toegang is uitgeschakeld op deze thuisserver.", + "Guests can't set avatars. Please register.": "Gasten kunnen geen avatars instellen. Registreer je alsjeblieft.", + "Guest users can't create new rooms. Please register to create room and start a chat.": "Gast gebruikers kunnen geen nieuwe ruimtes aanmaken. Registreer je om een nieuwe ruimte aan te maken en een gesprek te starten.", + "Guest users can't upload files. Please register to upload.": "Gast gebruikers kunnen geen bestanden uploaden. Registreer je om te uploaden.", + "Guests can't use labs features. Please register.": "Gasten kunnen geen labs mogelijkheden gebruiken. Registreer je alsjeblieft.", + "Guests cannot join this room even if explicitly invited.": "Gasten kunnen niet tot deze ruimte toetreden, zelfs als ze expliciet uitgenodigd zijn.", + "had": "had", + "Hangup": "Ophangen", + "Hide read receipts": "Leesbewijzen verbergen", + "Hide Text Formatting Toolbar": "Tekst formaterings-gereedschapsbalk verbergen", + "Historical": "Historische", + "Home": "Home", + "Homeserver is": "Thuisserver is", + "Identity Server is": "Identiteitsserver is", + "I have verified my email address": "Ik heb mijn e-mailadres geverifieerd", + "Import": "Importeren", + "Import E2E room keys": "E2E ruimte sleutels importeren", + "Incoming call from %(name)s": "Inkomende oproep van %(name)s", + "Incoming video call from %(name)s": "Inkomende video-oproep van %(name)s", + "Incoming voice call from %(name)s": "Inkomende spraakoproep van %(name)s", + "Incorrect username and/or password.": "Incorrecte gebruikersnaam en/of wachtwoord.", + "Incorrect verification code": "Incorrecte verificatie code", + "Interface Language": "Interface Taal", + "Invalid alias format": "Ongeldig naam formaat", + "Invalid address format": "Ongeldig adres formaat", + "Invalid Email Address": "Ongeldig e-mailadres", + "Invalid file%(extra)s": "Ongeldig bestand%(extra)s", + "%(senderName)s invited %(targetName)s.": "%(senderName)s heeft %(targetName)s uitgenodigd.", + "Invite new room members": "Nieuwe ruimte leden uitnodigen", + "Invited": "Uitgenodigd", + "Invites": "Uitnodigingen", + "Invites user with given id to current room": "Nodigt de gebruiker met het gegeven id uit in de huidige ruimte", + "'%(alias)s' is not a valid format for an address": "'%(alias)s' is niet een geldig formaat voor een adres", + "'%(alias)s' is not a valid format for an alias": "'%(alias)s' is niet een geldig formaat voor een naam", + "%(displayName)s is typing": "%(displayName)s is aan het typen", + "Sign in with": "Inloggen met", + "Join as voice or video.": "Toetreden als spraak of video.", + "Join Room": "Ruimte toetreden", + "joined and left": "Toegetreden en verlaten", + "joined": "Toegetreden", + "%(targetName)s joined the room.": "%(targetName)s in de ruimte toegetreden.", + "Joins room with given alias": "Treed de ruimte toe met een gegeven naam", + "Jump to first unread message.": "Spring naar het eerste ongelezen bericht.", + "Labs": "Labs", + "Last seen": "Laatst gezien", + "Leave room": "Ruimte verlaten", + "left and rejoined": "verlaten en opnieuw toegetreden", + "left": "verlaten", + "%(targetName)s left the room.": "%(targetName)s heeft de ruimte verlaten.", + "Level:": "Niveau:", + "List this room in %(domain)s's room directory?": "Deze ruimte in %(domain)s's ruimte catalogus vermelden?", + "Local addresses for this room:": "Lokale adressen voor deze ruimte:", + "Logged in as:": "Ingelogd als:", + "Login as guest": "Als gast inloggen", + "Logout": "Uitloggen", + "Low priority": "Lage prioriteit", + "%(senderName)s made future room history visible to": "%(senderName)s heeft de toekomstige ruimte geschiedenis zichtbaar gemaakt voor", + "Manage Integrations": "Integraties beheren", + "Markdown is disabled": "Opmaak is uitgeschakeld", + "Markdown is enabled": "Opmaak ingeschakeld", + "matrix-react-sdk version:": "matrix-react-sdk versie:", + "Members only": "Alleen leden", + "Message not sent due to unknown devices being present": "Bericht niet verzonden doordat er een onbekende apparaten aanwezig zijn", + "Missing room_id in request": "Het room_id mist in het verzoek", + "Missing user_id in request": "De user_id mist in het verzoek", + "Mobile phone number": "Mobiel telefoonnummer", + "Mobile phone number (optional)": "Mobiel telefoonnummer (optioneel)", + "Never send encrypted messages to unverified devices from this device": "Nooit versleutelde berichten vanaf dit apparaat naar niet geverifieerde apparaten versturen", + "Never send encrypted messages to unverified devices in this room": "Nooit versleutelde berichten naar niet geverifieerde apparaten sturen in deze ruimte", + "Never send encrypted messages to unverified devices in this room from this device": "Nooit vanaf dit apparaat versleutelde berichten naar niet geverifieerde apparaten in deze ruimte sturen", + "New address (e.g. #foo:%(localDomain)s)": "Nieuw adres (bijv. #foo:%(localDomain)s)", + "New Composer & Autocomplete": "Nieuwe Componist & Automatisch Aanvullen", + "New passwords don't match": "Nieuwe wachtwoorden komen niet overeen", + "New passwords must match each other.": "Nieuwe wachtwoorden moeten overeenkomen.", + "Once encryption is enabled for a room it cannot be turned off again (for now)": "Zodra versleuteling in een kamer is ingeschakeld kan het niet meer worden uitgeschakeld (voor nu)", + "Once you've followed the link it contains, click below": "Zodra je de link dat het bevat hebt gevolgd, klik hieronder", + "Only people who have been invited": "Alleen personen die zijn uitgenodigd", + "Otherwise, click here to send a bug report.": "Klik anders hier om een foutmelding te versturen.", + "Please check your email and click on the link it contains. Once this is done, click continue.": "Bekijk je e-mail en klik op de link die het bevat. Zodra dit klaar is, klik op verder gaan.", + "Power level must be positive integer.": "Machtsniveau moet een positief heel getal zijn.", + "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s heeft zijn of haar weergavenaam (%(oldDisplayName)s) verwijderd.", + "%(senderName)s removed their profile picture.": "%(senderName)s heeft zijn of haar profielfoto verwijderd.", + "Failed to kick": "Niet gelukt om te kicken", + "Press to start a chat with someone": "Druk op om een gesprek met iemand te starten", + "Remove %(threePid)s?": "%(threePid)s verwijderen?", + "%(senderName)s requested a VoIP conference.": "%(senderName)s heeft een VoIP gesprek aangevraagd.", + "Report it": "Melden", + "Resetting password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Het wachtwoord veranderen betekent momenteel dat alle eind-tot-eind versleutelingssleutels op alle apparaten veranderen waardoor versleutelde gespreksgeschiedenis onleesbaar wordt, behalve als je eerst de ruimte sleutels exporteert en daarna opnieuw importeert. Dit zal in de toekomst verbeterd worden.", + "restore": "herstellen", + "Results from DuckDuckGo": "Resultaten van DuckDuckGo", + "Return to app": "Naar de app terugkeren", + "Return to login screen": "Naar het inlogscherm terugkeren", + "Riot does not have permission to send you notifications - please check your browser settings": "Riot heeft geen permissie om je notificaties te versturen - controleer je browser instellingen", + "Riot was not given permission to send notifications - please try again": "Riot heeft geen permissie gekregen om notificaties te versturen - probeer het opnieuw", + "riot-web version:": "riot-web versie:", + "Room %(roomId)s not visible": "Ruimte %(roomId)s is niet zichtbaar", + "Room Colour": "Ruimte Kleur" } diff --git a/src/i18n/strings/pt_BR.json b/src/i18n/strings/pt_BR.json index 2c18b0507d..1e915a5491 100644 --- a/src/i18n/strings/pt_BR.json +++ b/src/i18n/strings/pt_BR.json @@ -356,6 +356,7 @@ "%(senderName)s placed a %(callType)s call.": "%(senderName)s fez uma chamada de %(callType)s.", "Power level must be positive integer.": "O nível de permissões tem que ser um número inteiro e positivo.", "Press": "Aperte", + "Press to start a chat with someone": "Clique em para iniciar a conversa com alguém", "Reason": "Razão", "%(targetName)s rejected the invitation.": "%(targetName)s recusou o convite.", "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s removeu o seu nome público (%(oldDisplayName)s).", @@ -398,7 +399,7 @@ "VoIP is unsupported": "Chamada de voz não permitida", "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s desfez o convite a %(targetName)s.", "You are already in a call.": "Você já está em uma chamada.", - "You're not in any rooms yet! Press": "Você ainda não está em nenhuma sala! Pressione", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Você ainda não está em nenhuma sala! Clique em para criar uma sala ou em para navegar pela lista pública de salas", "You are trying to access %(roomName)s.": "Você está tentando acessar a sala %(roomName)s.", "You cannot place a call with yourself.": "Você não pode iniciar uma chamada.", "You cannot place VoIP calls in this browser.": "Você não pode fazer chamadas de voz neste navegador.", @@ -960,5 +961,14 @@ "Your home server does not support device management.": "O seu Servidor de Base não suporta o gerenciamento de dispositivos.", "(~%(count)s results).one": "(~%(count)s resultado)", "(~%(count)s results).other": "(~%(count)s resultados)", - "Device Name": "Nome do dispositivo" + "Device Name": "Nome do dispositivo", + "(could not connect media)": "(não foi possível conectar-se à mídia)", + "(no answer)": "(sem resposta)", + "(unknown failure: %(reason)s)": "(falha desconhecida: %(reason)s)", + "Your browser does not support the required cryptography extensions": "O seu navegador não suporta as extensões de criptografia necessárias", + "Not a valid Riot keyfile": "Não é um arquivo de chaves Riot válido", + "Authentication check failed: incorrect password?": "Falha ao checar a autenticação: senha incorreta?", + "Disable Peer-to-Peer for 1:1 calls": "Desabilitar as chamadas 1:1 par-a-par", + "Do you want to set an email address?": "Você deseja definir um endereço de e-mail?", + "This will allow you to reset your password and receive notifications.": "Isso permitirá que você redefina sua senha e receba notificações." } diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index 26c2986948..6b6eadf928 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -50,7 +50,7 @@ "Create Room": "Создайте Комнату", "Cryptography": "Шифрование", "Curve25519 identity key": "Curve25519 идентификационный ключ", - "Deactivate Account": "Деактивировать Учётную запись", + "Deactivate Account": "Деактивировать учётную запись", "Deactivate my account": "Деактивировать мою учётную запись", "decline": "отказаться", "Decryption error": "Ошибка дешифрования", @@ -85,7 +85,7 @@ "Favourite": "Избранное", "favourite": "Избранное", "Favourites": "Избранное", - "Filter room members": "Фильтр участников комнаты", + "Filter room members": "Поиск участников комнаты", "Forget room": "Забыть комнату", "Forgot your password?": "Вы забыли пароль?", "For security, this session has been signed out. Please sign in again.": "Для обеспечения безопасности эта сессия была завершена. Войдите в систему еще раз.", @@ -100,14 +100,14 @@ "Invalid Email Address": "Недействительный адрес электронной почты", "invited": "invited", "Invite new room members": "Пригласить новых участников в комнату", - "Invites": "Приглашать", - "Invites user with given id to current room": "Пригласить пользователя с данным id в текущую комнату", + "Invites": "Приглашает", + "Invites user with given id to current room": "Приглашает пользователя с этим ID в текущую комнату", "is a": "является", "Sign in with": "Я хочу регистрироваться с", - "joined and left": "присоединенный и оставленный", - "joined": "присоединенный", + "joined and left": "зашёл и ушёл", + "joined": "зашёл", "joined the room": "joined the room", - "Joins room with given alias": "Присоединяется к комнате с данным псевдонимом", + "Joins room with given alias": "зашёл в комнату с этим именем", "Kicks user with given id": "Выгнать пользователя с заданным id", "Labs": "Лаборатория", "Leave room": "Уйти из комнаты", @@ -116,7 +116,7 @@ "left the room": "left the room", "Logged in as": "Зарегистрированный как", "Login as guest": "Вход в систему как гость", - "Logout": "Выход из системы", + "Logout": "Выйти", "Low priority": "Низкий приоритет", "made future room history visible to": "made future room history visible to", "Manage Integrations": "Управление Интеграциями", @@ -128,7 +128,7 @@ "Never send encrypted messages to unverified devices from this device": "Никогда не отправлять зашифрованные сообщения на не верифицированные устройства с этого устройства", "Never send encrypted messages to unverified devices in this room from this device": "Никогда не отправляйте зашифрованные сообщения на непроверенные устройства в этой комнате из вашего устройства", "New password": "Новый пароль", - "New passwords must match each other.": "Новые пароли должны соответствовать друг другу.", + "New passwords must match each other.": "Новые пароли должны совпадать.", "none": "никто", "Notifications": "Уведомления", " (not supported by this browser)": " (not supported by this browser)", @@ -193,7 +193,7 @@ "(warning: cannot be disabled again!)": "(предупреждение: не может быть отключено!)", "Warning!": "Предупреждение!", "was banned": "запрещен", - "was invited": "приглашенный", + "was invited": "был приглашён", "was kicked": "выброшен", "was unbanned": "незапрещенный", "was": "был", @@ -246,7 +246,7 @@ "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) изменил %(fromPowerLevel) на %(toPowerLevel)", + "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s изменил %(fromPowerLevel)s на %(toPowerLevel)s", "Guest users can't create new rooms. Please register to create room and start a chat.": "Гостевые пользователи не могут создавать новые комнаты. Зарегистрируйтесь для создания комнаты и чата.", "click to reveal": "нажать для открытия", "%(senderName)s invited %(targetName)s.": "%(senderName)s приглашает %(targetName)s.", @@ -355,7 +355,7 @@ "Friday": "Пятница", "Saturday": "Суббота", "Sunday": "Воскресенье", - "%(weekDayName)s %(time)s": "%(weekDayName) %(time)", + "%(weekDayName)s %(time)s": "%(weekDayName)s %(time)s", "Upload an avatar:": "Загрузите аватар:", "You need to be logged in.": "Вы должны быть авторизованы.", "You need to be able to invite users to do that.": "Вам необходимо пригласить пользователей чтобы сделать это.", @@ -470,7 +470,7 @@ "Failed to ban user": "Не удалось забанить пользователя", "Failed to change power level": "Не удалось изменить уровень привилегий", "Failed to delete device": "Не удалось удалить устройство", - "Failed to forget room %(errCode)s": "Не удалось забыть комнату %(errCode)s", + "Failed to forget room %(errCode)s": "Не удалось удалить комнату %(errCode)s", "Failed to join room": "Не удалось присоединиться к комнате", "Failed to join the room": "Не удалось войти в комнату", "Access Token:": "Токен:", @@ -523,8 +523,8 @@ "No results": "Нет результатов", "OK": "ОК", "Only people who have been invited": "Только приглашённые люди", - "Passwords can't be empty": "Пароли не могут быть пустыми", - "%(senderName)s placed a %(callType)s call.": "%(senderName) выполнил %(callType) вызов.", + "Passwords can't be empty": "Поля паролей не могут быть пустыми", + "%(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.": "Уровень силы должен быть положительным числом.", "Press": "Нажать", @@ -650,10 +650,10 @@ "%(oneUser)schanged their avatar": "%(oneUser)sизменил своё изображение", "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Не возможно подключиться к серверу через HTTP, когда в строке браузера HTTPS. Используйте HTTPS или включив небезопасные скрипты.", "Dismiss": "Отказ", - "Custom Server Options": "Расширенные настройки сервера", + "Custom Server Options": "Собственные настройки сервера", "Mute": "Беззвучный", "Operation failed": "Действие не удалось", - "powered by Matrix": "управляемый с Matrix", + "powered by Matrix": "Основано на Matrix", "Add a topic": "Добавить тему", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Время отображать в 12 часовом формате (напр. 2:30pm)", "Use compact timeline layout": "Компактное отображение", @@ -686,7 +686,7 @@ "Custom level": "Пользовательский уровень", "Device already verified!": "Устройство уже верифицировано!", "Device ID:": "ID устройства:", - "device id: ": "id устройства: ", + "device id: ": "ID устройства: ", "Device key:": "Ключ устройства:", "disabled": "отключено", "Disable markdown formatting": "Отключить форматирование Markdown", @@ -700,7 +700,7 @@ "Import": "Импорт", "Incorrect username and/or password.": "Неверное имя пользователя и/или пароль.", "Invalid file%(extra)s": "Неправильный файл%(extra)s", - "Invited": "Приглашен", + "Invited": "Приглашён", "Jump to first unread message.": "Перейти к первому непрочитанному сообщению.", "List this room in %(domain)s's room directory?": "Показывать эту комнату в списке комнат %(domain)s?", "Message not sent due to unknown devices being present": "Сообщение не было отправлено из-за присутствия неизвестного устройства", @@ -896,7 +896,7 @@ "Admin tools": "Админ утилита", "And %(count)s more...": "И %(count)s больше...", "Alias (optional)": "Псевдоним (опционально)", - "Click here to join the discussion!": " Нажми здесь чтоб присоединиться к обсуждению!", + "Click here to join the discussion!": "Нажмите здесь, чтобы присоединиться к обсуждению!", "Close": "Закрыть", "Disable Notifications": "Отключить оповещение", "Drop File Here": "Вставить сюда файл", @@ -909,7 +909,7 @@ "Incoming call from %(name)s": "Входящий вызов от %(name)s", "Incoming video call from %(name)s": "Входящий видио вызов от %(name)s", "Incoming voice call from %(name)s": "Входящий голосовой вызов от %(name)s", - "Join as voice or video.": "Присоединен как голос или видио .", + "Join as voice or video.": "Войти как голос или видео.", "Last seen": "В последний раз видели", "Level:": "Уровень:", "No display name": "Нет отображаемое имя", @@ -946,8 +946,8 @@ "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 homeserver's SSL certificate действителен, и расширение браузера не блокирует запросы.", - "You have been banned from %(roomName)s by %(userName)s.": "%(userName) забанил Вас в % (roomName).", - "You have been kicked from %(roomName)s by %(userName)s.": "%(userName) выгнал Вас из %(roomName).", + "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)": "(не удается подключиться к медиа)", @@ -958,5 +958,7 @@ "Your browser does not support the required cryptography extensions": "Ваш браузер не поддерживает требуемые расширения для криптографии", "Authentication check failed: incorrect password?": "Ошибка авторизации: неверный пароль?", "Do you want to set an email address?": "Вы хотите указать адрес электронной почты?", - "This will allow you to reset your password and receive notifications.": "Это позволит вам сбросить пароль и получить уведомления." + "This will allow you to reset your password and receive notifications.": "Это позволит вам сбросить пароль и получить уведомления.", + "Press to start a chat with someone": "Нажмите для начала чата с кем либо", + "You're not in any rooms yet! Press to make a room or to browse the directory": "Вы еще не в комнатах! Нажмите , чтобы создать комнату или , чтобы просмотреть каталог" } diff --git a/src/i18n/strings/sv.json b/src/i18n/strings/sv.json index fe8b1ffee1..21bda3b741 100644 --- a/src/i18n/strings/sv.json +++ b/src/i18n/strings/sv.json @@ -296,7 +296,7 @@ "Active call (%(roomName)s)": "Aktiv samtal (%(roomName)s)", "Add": "Lägg till", "Admin tools": "Admin verktyg", - "And %(count)s more...": "Och %(count) till...", + "And %(count)s more...": "Och %(count)s till...", "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.", diff --git a/src/i18n/strings/uk.json b/src/i18n/strings/uk.json index dd8112fa11..4af2a6e311 100644 --- a/src/i18n/strings/uk.json +++ b/src/i18n/strings/uk.json @@ -151,5 +151,9 @@ "zh-hk": "традиційна китайська (Гонконг)", "zh-sg": "спрощена китайська (Сингапур)", "zh-tw": "традиційна китайська (Тайвань)", - "zu": "зулу" + "zu": "зулу", + "a room": "кімната", + "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Текстове повідомлення було надіслано +%(msisdn)s. Введіть, будь ласка, код підтвердження з цього повідомлення", + "Accept": "Прийняти", + "Account": "Обліковка" } diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json index ad37ce9430..9fdc7a0b42 100644 --- a/src/i18n/strings/zh_Hans.json +++ b/src/i18n/strings/zh_Hans.json @@ -352,5 +352,9 @@ "Password:": "密码:", "Passwords can't be empty": "密码不能为空", "Permissions": "权限", - "Phone": "电话" + "Phone": "电话", + "Cancel": "取消", + "Create new room": "创建新房间", + "Custom Server Options": "自定义服务器选项", + "Dismiss": "设为已读" } diff --git a/src/stores/RoomViewStore.js b/src/stores/RoomViewStore.js index ac06d41e81..2f7d55b71f 100644 --- a/src/stores/RoomViewStore.js +++ b/src/stores/RoomViewStore.js @@ -55,6 +55,8 @@ const INITIAL_STATE = { // pixelOffset: the number of pixels the window is scrolled down // from the focussedEvent. scrollStateMap: {}, + + forwardingEvent: null, }; /** @@ -116,6 +118,11 @@ class RoomViewStore extends Store { case 'update_scroll_state': this._updateScrollState(payload); break; + case 'forward_event': + this._setState({ + forwardingEvent: payload.event, + }); + break; } } @@ -127,8 +134,11 @@ class RoomViewStore extends Store { initialEventId: payload.event_id, initialEventPixelOffset: undefined, isInitialEventHighlighted: payload.highlighted, + forwardingEvent: null, roomLoading: false, roomLoadError: null, + // should peek by default + shouldPeek: payload.should_peek === undefined ? true : payload.should_peek, }; // If an event ID wasn't specified, default to the one saved for this room @@ -141,6 +151,14 @@ class RoomViewStore extends Store { } } + if (this._state.forwardingEvent) { + dis.dispatch({ + action: 'send_event', + room_id: newState.roomId, + event: this._state.forwardingEvent, + }); + } + this._setState(newState); } else if (payload.room_alias) { // Resolve the alias and then do a second dispatch with the room ID acquired @@ -276,6 +294,15 @@ class RoomViewStore extends Store { getJoinError() { return this._state.joinError; } + + // The mxEvent if one is about to be forwarded + getForwardingEvent() { + return this._state.forwardingEvent; + } + + shouldPeek() { + return this._state.shouldPeek; + } } let singletonRoomViewStore = null;